123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- /*
- * ====================================================================
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * ====================================================================
- */
-
- package org.apache.poi.xslf.usermodel;
-
- import java.awt.Font;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
-
- import org.apache.poi.common.usermodel.fonts.FontCharset;
- import org.apache.poi.common.usermodel.fonts.FontFacet;
- import org.apache.poi.common.usermodel.fonts.FontFamily;
- import org.apache.poi.common.usermodel.fonts.FontHeader;
- import org.apache.poi.common.usermodel.fonts.FontInfo;
- import org.apache.poi.common.usermodel.fonts.FontPitch;
- import org.apache.poi.ooxml.POIXMLDocumentPart;
- import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
- import org.apache.poi.util.IOUtils;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;
- import org.openxmlformats.schemas.presentationml.x2006.main.CTEmbeddedFontDataId;
- import org.openxmlformats.schemas.presentationml.x2006.main.CTEmbeddedFontList;
- import org.openxmlformats.schemas.presentationml.x2006.main.CTEmbeddedFontListEntry;
- import org.openxmlformats.schemas.presentationml.x2006.main.CTPresentation;
-
- @SuppressWarnings("WeakerAccess")
- public class XSLFFontInfo implements FontInfo {
- final XMLSlideShow ppt;
- final String typeface;
- final CTEmbeddedFontListEntry fontListEntry;
-
- public XSLFFontInfo(XMLSlideShow ppt, String typeface) {
- this.ppt = ppt;
- this.typeface = typeface;
-
- final CTPresentation pres = ppt.getCTPresentation();
- CTEmbeddedFontList fontList = pres.isSetEmbeddedFontLst()
- ? pres.getEmbeddedFontLst() : pres.addNewEmbeddedFontLst();
-
- for (CTEmbeddedFontListEntry fe : fontList.getEmbeddedFontArray()) {
- if (typeface.equalsIgnoreCase(fe.getFont().getTypeface())) {
- fontListEntry = fe;
- return;
- }
- }
-
- fontListEntry = fontList.addNewEmbeddedFont();
- fontListEntry.addNewFont().setTypeface(typeface);
- }
-
- public XSLFFontInfo(XMLSlideShow ppt, CTEmbeddedFontListEntry fontListEntry) {
- this.ppt = ppt;
- this.typeface = fontListEntry.getFont().getTypeface();
- this.fontListEntry = fontListEntry;
- }
-
- @Override
- public String getTypeface() {
- return getFont().getTypeface();
- }
-
- @Override
- public void setTypeface(String typeface) {
- getFont().setTypeface(typeface);
- }
-
- @Override
- public FontCharset getCharset() {
- return FontCharset.valueOf(getFont().getCharset());
- }
-
- @Override
- public void setCharset(FontCharset charset) {
- getFont().setCharset((byte)charset.getNativeId());
- }
-
- @Override
- public FontFamily getFamily() {
- return FontFamily.valueOfPitchFamily(getFont().getPitchFamily());
- }
-
- @Override
- public void setFamily(FontFamily family) {
- byte pitchAndFamily = getFont().getPitchFamily();
- FontPitch pitch = FontPitch.valueOfPitchFamily(pitchAndFamily);
- getFont().setPitchFamily(FontPitch.getNativeId(pitch, family));
- }
-
- @Override
- public FontPitch getPitch() {
- return FontPitch.valueOfPitchFamily(getFont().getPitchFamily());
- }
-
- @Override
- public void setPitch(FontPitch pitch) {
- byte pitchAndFamily = getFont().getPitchFamily();
- FontFamily family = FontFamily.valueOfPitchFamily(pitchAndFamily);
- getFont().setPitchFamily(FontPitch.getNativeId(pitch, family));
- }
-
- @Override
- public byte[] getPanose() {
- return getFont().getPanose();
- }
-
- @Override
- public List<FontFacet> getFacets() {
- List<FontFacet> facetList = new ArrayList<>();
- if (fontListEntry.isSetRegular()) {
- facetList.add(new XSLFFontFacet((fontListEntry.getRegular())));
- }
- if (fontListEntry.isSetItalic()) {
- facetList.add(new XSLFFontFacet((fontListEntry.getItalic())));
- }
- if (fontListEntry.isSetBold()) {
- facetList.add(new XSLFFontFacet((fontListEntry.getBold())));
- }
- if (fontListEntry.isSetBoldItalic()) {
- facetList.add(new XSLFFontFacet((fontListEntry.getBoldItalic())));
- }
- return facetList;
- }
-
- public FontFacet addFacet(InputStream fontData) throws IOException {
- FontHeader header = new FontHeader();
- InputStream is = header.bufferInit(fontData);
-
- final CTPresentation pres = ppt.getCTPresentation();
- pres.setEmbedTrueTypeFonts(true);
- pres.setSaveSubsetFonts(true);
-
- final CTEmbeddedFontDataId dataId;
- final int style =
- (header.getWeight() > 400 ? Font.BOLD : Font.PLAIN) |
- (header.isItalic() ? Font.ITALIC : Font.PLAIN);
- switch (style) {
- case Font.PLAIN:
- dataId = fontListEntry.isSetRegular()
- ? fontListEntry.getRegular() : fontListEntry.addNewRegular();
- break;
- case Font.BOLD:
- dataId = fontListEntry.isSetBold()
- ? fontListEntry.getBold() : fontListEntry.addNewBold();
- break;
- case Font.ITALIC:
- dataId = fontListEntry.isSetItalic()
- ? fontListEntry.getItalic() : fontListEntry.addNewItalic();
- break;
- default:
- dataId = fontListEntry.isSetBoldItalic()
- ? fontListEntry.getBoldItalic() : fontListEntry.addNewBoldItalic();
- break;
- }
-
- XSLFFontFacet facet = new XSLFFontFacet(dataId);
- facet.setFontData(is);
- return facet;
- }
-
- private final class XSLFFontFacet implements FontFacet {
- private final CTEmbeddedFontDataId fontEntry;
- private final FontHeader header = new FontHeader();
-
- private XSLFFontFacet(CTEmbeddedFontDataId fontEntry) {
- this.fontEntry = fontEntry;
- }
-
- @Override
- public int getWeight() {
- init();
- return header.getWeight();
- }
-
- @Override
- public boolean isItalic() {
- init();
- return header.isItalic();
- }
-
- @Override
- public XSLFFontData getFontData() {
- return ppt.getRelationPartById(fontEntry.getId()).getDocumentPart();
- }
-
- void setFontData(InputStream is) throws IOException {
- final XSLFRelation fntRel = XSLFRelation.FONT;
- final String relId = fontEntry.getId();
- final XSLFFontData fntData;
- if (relId == null || relId.isEmpty()) {
- final int fntDataIdx;
- try {
- fntDataIdx = ppt.getPackage().getUnusedPartIndex(fntRel.getDefaultFileName());
- } catch (InvalidFormatException e) {
- throw new RuntimeException(e);
- }
-
- POIXMLDocumentPart.RelationPart rp = ppt.createRelationship(fntRel, XSLFFactory.getInstance(), fntDataIdx, false);
- fntData = rp.getDocumentPart();
- fontEntry.setId(rp.getRelationship().getId());
- } else {
- fntData = (XSLFFontData)ppt.getRelationById(relId);
- }
-
- assert (fntData != null);
- try (OutputStream os = fntData.getOutputStream()) {
- IOUtils.copy(is, os);
- }
- }
-
- private void init() {
- if (header.getFamilyName() == null) {
- try (InputStream is = getFontData().getInputStream()) {
- byte[] buf = IOUtils.toByteArray(is, 1000);
- header.init(buf, 0, buf.length);
- } catch (IOException e) {
- // TODO: better exception class
- throw new RuntimeException(e);
- }
- }
- }
- }
-
-
- private CTTextFont getFont() {
- return fontListEntry.getFont();
- }
-
-
-
- /**
- * Adds or updates a (MTX-) font
- * @param ppt the slideshow which will contain the font
- * @param fontStream the (MTX) font data as stream
- * @return a font data object
- * @throws IOException if the font data can't be stored
- *
- * @since POI 4.1.0
- */
- public static XSLFFontInfo addFontToSlideShow(XMLSlideShow ppt, InputStream fontStream)
- throws IOException {
- FontHeader header = new FontHeader();
- InputStream is = header.bufferInit(fontStream);
-
- XSLFFontInfo fontInfo = new XSLFFontInfo(ppt, header.getFamilyName());
- fontInfo.addFacet(is);
- return fontInfo;
- }
-
- /**
- * Return all registered fonts
- * @param ppt the slideshow containing the fonts
- * @return the list of registered fonts
- */
- public static List<XSLFFontInfo> getFonts(XMLSlideShow ppt) {
- final CTPresentation pres = ppt.getCTPresentation();
-
- //noinspection deprecation
- return pres.isSetEmbeddedFontLst()
- ? Stream.of(pres.getEmbeddedFontLst().getEmbeddedFontArray())
- .map(fe -> new XSLFFontInfo(ppt, fe)).collect(Collectors.toList())
- : Collections.emptyList();
- }
-
- }
|