Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontCollection.java 
Fri Dec 28 23:43:31 2018
@@ -18,13 +18,19 @@
 package org.apache.poi.hslf.record;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 
+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.hslf.usermodel.HSLFFontInfo;
 import org.apache.poi.hslf.usermodel.HSLFFontInfoPredefined;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.POILogger;
 
 /**
@@ -32,11 +38,12 @@ import org.apache.poi.util.POILogger;
  * about all the fonts in the presentation.
  */
 
+@SuppressWarnings("WeakerAccess")
 public final class FontCollection extends RecordContainer {
     private final Map<String,HSLFFontInfo> fonts = new LinkedHashMap<>();
     private byte[] _header;
 
-       protected FontCollection(byte[] source, int start, int len) {
+       /* package */ FontCollection(byte[] source, int start, int len) {
                _header = new byte[8];
                System.arraycopy(source,start,_header,0,8);
 
@@ -44,8 +51,13 @@ public final class FontCollection extend
 
                for (Record r : _children){
                        if(r instanceof FontEntityAtom) {
-                           HSLFFontInfo fi = new 
HSLFFontInfo((FontEntityAtom)r);
-                   fonts.put(fi.getTypeface(), fi);
+                HSLFFontInfo fi = new HSLFFontInfo((FontEntityAtom) r);
+                fonts.put(fi.getTypeface(), fi);
+            } else if (r instanceof FontEmbeddedData) {
+                FontEmbeddedData fed = (FontEmbeddedData)r;
+                           FontHeader fontHeader = fed.getFontHeader();
+                           HSLFFontInfo fi = addFont(fontHeader);
+                           fi.addFacet(fed);
                        } else {
                                logger.log(POILogger.WARN, "Warning: 
FontCollection child wasn't a FontEntityAtom, was " + 
r.getClass().getSimpleName());
                        }
@@ -88,7 +100,7 @@ public final class FontCollection extend
         fi = new HSLFFontInfo(fontInfo);
         fi.setIndex(fonts.size());
         fonts.put(fi.getTypeface(), fi);
-        
+
         FontEntityAtom fnt = fi.createRecord();
 
         // Append new child to the end
@@ -98,6 +110,58 @@ public final class FontCollection extend
         return fi;
     }
 
+    public HSLFFontInfo addFont(InputStream fontData) throws IOException {
+        FontHeader fontHeader = new FontHeader();
+        InputStream is = fontHeader.bufferInit(fontData);
+
+        HSLFFontInfo fi = addFont(fontHeader);
+
+        // always overwrite the font info properties when a font data given
+        // as the font info properties are assigned generically when only a 
typeface is given
+        FontEntityAtom fea = fi.getFontEntityAtom();
+        assert (fea != null);
+        fea.setCharSet(fontHeader.getCharsetByte());
+        
fea.setPitchAndFamily(FontPitch.getNativeId(fontHeader.getPitch(),fontHeader.getFamily()));
+
+        // always activate subsetting
+        fea.setFontFlags(1);
+        // true type font and no font substitution
+        fea.setFontType(12);
+
+        Record after = fea;
+
+        final int insertIdx = getFacetIndex(fontHeader.isItalic(), 
fontHeader.isBold());
+
+        FontEmbeddedData newChild = null;
+        for (FontEmbeddedData fed : fi.getFacets()) {
+            FontHeader fh = fed.getFontHeader();
+            final int curIdx = getFacetIndex(fh.isItalic(), fh.isBold());
+
+            if (curIdx == insertIdx) {
+                newChild = fed;
+                break;
+            } else if (curIdx > insertIdx) {
+                // the new facet needs to be inserted before the current facet
+                break;
+            }
+
+            after = fed;
+        }
+
+        if (newChild == null) {
+            newChild = new FontEmbeddedData();
+            addChildAfter(newChild, after);
+            fi.addFacet(newChild);
+        }
+
+        newChild.setFontData(IOUtils.toByteArray(is));
+        return fi;
+    }
+
+    private static int getFacetIndex(boolean isItalic, boolean isBold) {
+        return (isItalic ? 2 : 0) | (isBold ? 1 : 0);
+    }
+
 
     /**
      * Lookup a FontInfo object by its typeface
@@ -132,4 +196,8 @@ public final class FontCollection extend
     public int getNumberOfFonts() {
         return fonts.size();
     }
+
+    public List<HSLFFontInfo> getFonts() {
+        return new ArrayList<>(fonts.values());
+    }
 }

Added: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEmbeddedData.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEmbeddedData.java?rev=1849898&view=auto
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEmbeddedData.java 
(added)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEmbeddedData.java 
Fri Dec 28 23:43:31 2018
@@ -0,0 +1,116 @@
+/* ====================================================================
+   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.hslf.record;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.poi.common.usermodel.fonts.FontFacet;
+import org.apache.poi.common.usermodel.fonts.FontHeader;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.LittleEndian;
+
+@SuppressWarnings("WeakerAccess")
+public class FontEmbeddedData extends RecordAtom implements FontFacet {
+    //arbitrarily selected; may need to increase
+    private static final int MAX_RECORD_LENGTH = 1_000_000;
+
+    /**
+     * Record header.
+     */
+    private byte[] _header;
+
+    /**
+     * Record data - An EOT Font
+     */
+    private byte[] _data;
+
+    /**
+     * Constructs a brand new font embedded record.
+     */
+    /* package */ FontEmbeddedData() {
+        _header = new byte[8];
+        _data = new byte[4];
+
+        LittleEndian.putShort(_header, 2, (short)getRecordType());
+        LittleEndian.putInt(_header, 4, _data.length);
+    }
+
+    /**
+     * Constructs the font embedded record from its source data.
+     *
+     * @param source the source data as a byte array.
+     * @param start the start offset into the byte array.
+     * @param len the length of the slice in the byte array.
+     */
+    /* package */ FontEmbeddedData(byte[] source, int start, int len) {
+        // Get the header.
+        _header = new byte[8];
+        System.arraycopy(source,start,_header,0,8);
+
+        // Get the record data.
+        _data = IOUtils.safelyAllocate(len-8, MAX_RECORD_LENGTH);
+        System.arraycopy(source,start+8,_data,0,len-8);
+
+        // Must be at least 4 bytes long
+        if(_data.length < 4) {
+            throw new IllegalArgumentException("The length of the data for a 
ExObjListAtom must be at least 4 bytes, but was only " + _data.length);
+        }
+    }
+
+    @Override
+    public long getRecordType() {
+        return RecordTypes.FontEmbeddedData.typeID;
+    }
+
+    @Override
+    public void writeOut(OutputStream out) throws IOException {
+        out.write(_header);
+        out.write(_data);
+    }
+
+    public void setFontData(byte[] fontData) {
+        _data = fontData.clone();
+        LittleEndian.putInt(_header, 4, _data.length);
+    }
+
+    public FontHeader getFontHeader() {
+        FontHeader h = new FontHeader();
+        h.init(_data, 0, _data.length);
+        return h;
+    }
+
+    @Override
+    public int getWeight() {
+        return getFontHeader().getWeight();
+    }
+
+    @Override
+    public boolean isItalic() {
+        return getFontHeader().isItalic();
+    }
+
+    public String getTypeface() {
+        return getFontHeader().getFamilyName();
+    }
+
+    @Override
+    public Object getFontData() {
+        return this;
+    }
+}

Propchange: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEmbeddedData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/FontEntityAtom.java 
Fri Dec 28 23:43:31 2018
@@ -43,7 +43,7 @@ public final class FontEntityAtom extend
     /**
      * record header
      */
-    private byte[] _header;
+    private final byte[] _header = new byte[8];
 
        /**
      * record data
@@ -53,9 +53,8 @@ public final class FontEntityAtom extend
     /**
      * Build an instance of <code>FontEntityAtom</code> from on-disk data
      */
-       protected FontEntityAtom(byte[] source, int start, int len) {
+       /* package */ FontEntityAtom(byte[] source, int start, int len) {
                // Get the header
-               _header = new byte[8];
                System.arraycopy(source,start,_header,0,8);
 
                // Grab the record data
@@ -69,7 +68,6 @@ public final class FontEntityAtom extend
     public FontEntityAtom() {
         _recdata = new byte[68];
 
-        _header = new byte[8];
         LittleEndian.putShort(_header, 2, (short)getRecordType());
         LittleEndian.putInt(_header, 4, _recdata.length);
     }
@@ -108,7 +106,7 @@ public final class FontEntityAtom extend
         byte[] bytes = StringUtil.getToUnicodeLE(name);
         System.arraycopy(bytes, 0, _recdata, 0, bytes.length);
         // null the remaining bytes
-        Arrays.fill(_recdata, 64-bytes.length, 64, (byte)0);
+        Arrays.fill(_recdata, bytes.length, 64, (byte)0);
     }
 
     public void setFontIndex(int idx){

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java 
Fri Dec 28 23:43:31 2018
@@ -62,7 +62,18 @@ public enum RecordTypes {
     NamedShow(1041,null),
     NamedShowSlides(1042,null),
     SheetProperties(1044,null),
-    RoundTripCustomTableStyles12Atom(1064,null),
+    OriginalMainMasterId(1052,null),
+    CompositeMasterId(1052,null),
+    RoundTripContentMasterInfo12(1054,null),
+    RoundTripShapeId12(1055,null),
+    RoundTripHFPlaceholder12(1056,RoundTripHFPlaceholder12::new),
+    RoundTripContentMasterId(1058,null),
+    RoundTripOArtTextStyles12(1059,null),
+    RoundTripShapeCheckSumForCustomLayouts12(1062,null),
+    RoundTripNotesMasterTextStyles12(1063,null),
+    RoundTripCustomTableStyles12(1064,null),
+
+
     List(2000,DocInfoListContainer::new),
     FontCollection(2005,FontCollection::new),
     BookmarkCollection(2019,null),
@@ -92,7 +103,7 @@ public enum RecordTypes {
     DefaultRulerAtom(4011,null),
     StyleTextProp9Atom(4012, StyleTextProp9Atom::new), //0x0FAC 
RT_StyleTextProp9Atom
     FontEntityAtom(4023,FontEntityAtom::new),
-    FontEmbeddedData(4024,null),
+    FontEmbeddedData(4024,FontEmbeddedData::new),
     CString(4026,CString::new),
     MetaFile(4033,null),
     ExOleObjAtom(4035,ExOleObjAtom::new),
@@ -159,17 +170,6 @@ public enum RecordTypes {
     // Records ~12050 seem to be related to Document Encryption
     DocumentEncryptionAtom(12052,DocumentEncryptionAtom::new),
 
-    OriginalMainMasterId(1052,null),
-    CompositeMasterId(1052,null),
-    RoundTripContentMasterInfo12(1054,null),
-    RoundTripShapeId12(1055,null),
-    RoundTripHFPlaceholder12(1056,RoundTripHFPlaceholder12::new),
-    RoundTripContentMasterId(1058,null),
-    RoundTripOArtTextStyles12(1059,null),
-    RoundTripShapeCheckSumForCustomLayouts12(1062,null),
-    RoundTripNotesMasterTextStyles12(1063,null),
-    RoundTripCustomTableStyles12(1064,null),
-
     // records greater then 0xF000 belong to with Microsoft Office Drawing 
format also known as Escher
     EscherDggContainer(0xF000,null),
     EscherDgg(0xf006,null),

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfo.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfo.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfo.java 
(original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfo.java 
Fri Dec 28 23:43:31 2018
@@ -17,13 +17,18 @@
 
 package org.apache.poi.hslf.usermodel;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.poi.common.usermodel.fonts.FontCharset;
 import org.apache.poi.common.usermodel.fonts.FontFamily;
 import org.apache.poi.common.usermodel.fonts.FontInfo;
 import org.apache.poi.common.usermodel.fonts.FontPitch;
+import org.apache.poi.hslf.record.FontEmbeddedData;
 import org.apache.poi.hslf.record.FontEntityAtom;
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
+import org.apache.poi.util.Internal;
 
 /**
  * Represents a Font used in a presentation.<p>
@@ -32,6 +37,7 @@ import org.apache.poi.util.BitFieldFacto
  * 
  * @since POI 3.17-beta2
  */
+@SuppressWarnings("WeakerAccess")
 public class HSLFFontInfo implements FontInfo {
 
     public enum FontRenderType {
@@ -53,6 +59,8 @@ public class HSLFFontInfo implements Fon
     private FontPitch pitch = FontPitch.VARIABLE;
     private boolean isSubsetted;
     private boolean isSubstitutable = true;
+    private final List<FontEmbeddedData> facets = new ArrayList<>();
+    private FontEntityAtom fontEntityAtom;
 
     /**
      * Creates a new instance of HSLFFontInfo with more or sensible 
defaults.<p>
@@ -70,6 +78,7 @@ public class HSLFFontInfo implements Fon
      * Creates a new instance of HSLFFontInfo and initialize it from the 
supplied font atom
      */
     public HSLFFontInfo(FontEntityAtom fontAtom){
+        fontEntityAtom = fontAtom;
         setIndex(fontAtom.getFontIndex());
         setTypeface(fontAtom.getFontName());
         setCharset(FontCharset.valueOf(fontAtom.getCharSet()));
@@ -187,7 +196,11 @@ public class HSLFFontInfo implements Fon
     }
     
     public FontEntityAtom createRecord() {
+        assert(fontEntityAtom == null);
+
         FontEntityAtom fnt = new FontEntityAtom();
+        fontEntityAtom = fnt;
+
         fnt.setFontIndex(getIndex() << 4);
         fnt.setFontName(getTypeface());
         fnt.setCharSet(getCharset().getNativeId());
@@ -212,4 +225,18 @@ public class HSLFFontInfo implements Fon
         fnt.setPitchAndFamily(FontPitch.getNativeId(pitch, family));
         return fnt;
     }
+
+    public void addFacet(FontEmbeddedData facet) {
+        facets.add(facet);
+    }
+
+    @Override
+    public List<FontEmbeddedData> getFacets() {
+        return facets;
+    }
+
+    @Internal
+    public FontEntityAtom getFontEntityAtom() {
+        return fontEntityAtom;
+    }
 }

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfoPredefined.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfoPredefined.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfoPredefined.java
 (original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFontInfoPredefined.java
 Fri Dec 28 23:43:31 2018
@@ -44,16 +44,6 @@ public enum HSLFFontInfoPredefined imple
         this.pitch = pitch;
         this.family = family;
     }
-    
-    @Override
-    public Integer getIndex() {
-        return -1;
-    }
-
-    @Override
-    public void setIndex(int index) {
-        throw new UnsupportedOperationException("Predefined enum can't be 
changed.");
-    }
 
     @Override
     public String getTypeface() {
@@ -61,37 +51,17 @@ public enum HSLFFontInfoPredefined imple
     }
 
     @Override
-    public void setTypeface(String typeface) {
-        throw new UnsupportedOperationException("Predefined enum can't be 
changed.");
-    }
-
-    @Override
     public FontCharset getCharset() {
         return charset;
     }
 
     @Override
-    public void setCharset(FontCharset charset) {
-        throw new UnsupportedOperationException("Predefined enum can't be 
changed.");
-    }
-
-    @Override
     public FontFamily getFamily() {
         return family;
     }
 
     @Override
-    public void setFamily(FontFamily family) {
-        throw new UnsupportedOperationException("Predefined enum can't be 
changed.");
-    }
-
-    @Override
     public FontPitch getPitch() {
         return pitch;
     }
-
-    @Override
-    public void setPitch(FontPitch pitch) {
-        throw new UnsupportedOperationException("Predefined enum can't be 
changed.");
-    }
 }

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java 
(original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java 
Fri Dec 28 23:43:31 2018
@@ -50,7 +50,6 @@ import org.apache.poi.poifs.filesystem.O
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.sl.usermodel.MasterSheet;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
-import org.apache.poi.sl.usermodel.Resources;
 import org.apache.poi.sl.usermodel.SlideShow;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
@@ -892,6 +891,21 @@ public final class HSLFSlideShow impleme
        }
 
        /**
+        * Add a font in this presentation and also embed its font data
+        *
+        * @param fontData the EOT font data as stream
+        *
+        * @return the registered HSLFFontInfo - the font info object is unique 
based on the typeface
+        *
+        * @since POI 4.1.0
+        */
+       public HSLFFontInfo addFont(InputStream fontData) throws IOException {
+               Document doc = getDocumentRecord();
+               doc.getDocumentAtom().setSaveWithFonts(true);
+               return 
doc.getEnvironment().getFontCollection().addFont(fontData);
+       }
+
+       /**
         * Get a font by index
         *
         * @param idx
@@ -912,6 +926,11 @@ public final class HSLFSlideShow impleme
                return 
getDocumentRecord().getEnvironment().getFontCollection().getNumberOfFonts();
        }
 
+       @Override
+       public List<HSLFFontInfo> getFonts() {
+               return 
getDocumentRecord().getEnvironment().getFontCollection().getFonts();
+       }
+
        /**
         * Return Header / Footer settings for slides
         *
@@ -1127,12 +1146,6 @@ public final class HSLFSlideShow impleme
         return null;
     }
 
-    @Override
-    public Resources getResources() {
-        // TODO implement or throw exception if not supported
-        return null;
-    }
-
     /**
      * @return the handler class which holds the hslf records
      */

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextRun.java 
Fri Dec 28 23:43:31 2018
@@ -44,8 +44,9 @@ import org.apache.poi.util.POILogger;
  * Represents a run of text, all with the same style
  *
  */
+@SuppressWarnings({"WeakerAccess", "Duplicates", "unused"})
 public final class HSLFTextRun implements TextRun {
-       protected POILogger logger = POILogFactory.getLogger(this.getClass());
+       private static final POILogger logger = 
POILogFactory.getLogger(HSLFTextRun.class);
 
        /** The TextRun we belong to */
        private HSLFTextParagraph parentParagraph;
@@ -132,17 +133,17 @@ public final class HSLFTextRun implement
                return getFlag(index);
        }
 
-       protected boolean getFlag(int index) {
+       boolean getFlag(int index) {
                BitMaskTextProp prop = (characterStyle == null) ? null : 
characterStyle.findByName(CharFlagsTextProp.NAME);
 
                if (prop == null || !prop.getSubPropMatches()[index]) {
-                   prop = getMasterProp(CharFlagsTextProp.NAME);
+                   prop = getMasterProp();
                }
 
-               return prop == null ? false : prop.getSubValue(index);
+               return prop != null && prop.getSubValue(index);
        }
 
-       private <T extends TextProp> T getMasterProp(final String name) {
+       private <T extends TextProp> T getMasterProp() {
         final int txtype = parentParagraph.getRunType();
         final HSLFSheet sheet = parentParagraph.getSheet();
         if (sheet == null) {
@@ -155,7 +156,8 @@ public final class HSLFTextRun implement
             logger.log(POILogger.WARN, "MasterSheet is not available");
             return null;
         }
-        
+
+        String name = CharFlagsTextProp.NAME;
         final TextPropCollection col = master.getPropCollection(txtype, 
parentParagraph.getIndentLevel(), name, true);
         return (col == null) ? null : col.findByName(name);
        }
@@ -302,7 +304,7 @@ public final class HSLFTextRun implement
 
        @Override
        public void setFontFamily(String typeface) {
-           setFontInfo(new HSLFFontInfo(typeface), FontGroup.LATIN);
+               setFontFamily(typeface, FontGroup.LATIN);
        }
 
     @Override
@@ -330,7 +332,7 @@ public final class HSLFTextRun implement
         switch (fg) {
         default:
         case LATIN:
-            propName = "font.index";
+            propName = "ansi.font.index";
             break;
         case COMPLEX_SCRIPT:
             // TODO: implement TextCFException10 structure
@@ -350,6 +352,7 @@ public final class HSLFTextRun implement
         }
 
 
+               setCharTextPropVal("font.index", fontIdx);
         setCharTextPropVal(propName, fontIdx);
     }
 
@@ -435,8 +438,8 @@ public final class HSLFTextRun implement
                setFontColor(rgb);
        }
 
-    protected void setFlag(int index, boolean value) {
-        BitMaskTextProp prop = 
(BitMaskTextProp)characterStyle.addWithName(CharFlagsTextProp.NAME);
+    private void setFlag(int index, boolean value) {
+        BitMaskTextProp prop = 
characterStyle.addWithName(CharFlagsTextProp.NAME);
         prop.setSubValue(value, index);
     }
 
@@ -469,7 +472,7 @@ public final class HSLFTextRun implement
      *
      * @param link the hyperlink
      */
-    protected void setHyperlink(HSLFHyperlink link) {
+    /* package */ void setHyperlink(HSLFHyperlink link) {
         this.link = link;
     }
 
@@ -521,4 +524,9 @@ public final class HSLFTextRun implement
     private FontGroup safeFontGroup(FontGroup fontGroup) {
         return (fontGroup != null) ? fontGroup : 
FontGroup.getFontGroupFirst(getRawText());
     }
+
+       @Override
+       public HSLFTextParagraph getParagraph() {
+               return parentParagraph;
+       }
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFont.java Fri 
Dec 28 23:43:31 2018
@@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets
 
 import org.apache.poi.common.usermodel.fonts.FontCharset;
 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.util.BitField;
@@ -32,6 +33,7 @@ import org.apache.poi.util.LittleEndianI
 /**
  * The Font object specifies the attributes of a logical font
  */
+@SuppressWarnings({"unused", "Duplicates"})
 public class HwmfFont implements FontInfo {
 
     /**
@@ -289,7 +291,7 @@ public class HwmfFont implements FontInf
 
     /**
      * An 8-bit unsigned integer that defines the character set.
-     * It SHOULD be set to a value in the {@link WmfCharset} Enumeration.
+     * It SHOULD be set to a value in the {@link FontCharset} Enumeration.
      *
      * The DEFAULT_CHARSET value MAY be used to allow the name and size of a 
font to fully
      * describe the logical font. If the specified font name does not exist, a 
font in another character
@@ -373,7 +375,7 @@ public class HwmfFont implements FontInf
         height = -12;
         width = 0;
         escapement = 0;
-        weight = 400;
+        weight = FontHeader.REGULAR_WEIGHT;
         italic = false;
         underline = false;
         strikeOut = false;
@@ -438,51 +440,21 @@ public class HwmfFont implements FontInf
     }
 
     @Override
-    public void setFamily(FontFamily family) {
-        throw new UnsupportedOperationException("setCharset not supported by 
HwmfFont.");
-    }
-
-    @Override
     public FontPitch getPitch() {
         return FontPitch.valueOf((pitchAndFamily >>> 6) & 3);
     }
 
     @Override
-    public void setPitch(FontPitch pitch) {
-        throw new UnsupportedOperationException("setPitch not supported by 
HwmfFont.");
-    }
-
-    @Override
-    public Integer getIndex() {
-        return null;
-    }
-
-    @Override
-    public void setIndex(int index) {
-        throw new UnsupportedOperationException("setIndex not supported by 
HwmfFont.");
-    }
-
-    @Override
     public String getTypeface() {
         return facename;
     }
 
     @Override
-    public void setTypeface(String typeface) {
-        throw new UnsupportedOperationException("setTypeface not supported by 
HwmfFont.");
-    }
-
-    @Override
     public FontCharset getCharset() {
         return charSet;
     }
 
     @Override
-    public void setCharset(FontCharset charset) {
-        throw new UnsupportedOperationException("setCharset not supported by 
HwmfFont.");
-    }
-
-    @Override
     public String toString() {
         return "{ height: "+height+
                 ", width: "+width+

Modified: 
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java
 (original)
+++ 
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/extractor/TestExtractor.java
 Fri Dec 28 23:43:31 2018
@@ -29,7 +29,9 @@ import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.BitSet;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.hslf.usermodel.HSLFObjectShape;
@@ -52,12 +54,22 @@ public final class TestExtractor {
     /**
      * Extractor primed on the 2 page basic test data
      */
-    private static final String expectText = "This is a test title\nThis is a 
test subtitle\nThis is on page 1\nThis is the title on page 2\nThis is page 
two\nIt has several blocks of text\nNone of them have formatting\n";
+    private static final String EXPECTED_PAGE1 =
+        "This is a test title\n" +
+        "This is a test subtitle\n\n" +
+        "This is on page 1\n";
+
+    private static final String EXPECTED_PAGE2 =
+        "This is the title on page 2\n" +
+        "This is page two\n\n" +
+        "It has several blocks of text\n\n" +
+        "None of them have formatting\n";
 
-    /**
-     * Extractor primed on the 1 page but text-box'd test data
-     */
-    private static final String expectText2 = "Hello, World!!!\nI am just a 
poor boy\nThis is Times New Roman\nPlain Text \n";
+    private static final String NOTES_PAGE1 =
+        "\nThese are the notes for page 1\n";
+
+    private static final String NOTES_PAGE2 =
+        "\nThese are the notes on page two, again lacking formatting\n";
 
     /**
      * Where our embeded files live
@@ -75,9 +87,16 @@ public final class TestExtractor {
     public void testReadSheetText() throws IOException {
         // Basic 2 page example
         try (SlideShowExtractor ppe = 
openExtractor("basic_test_ppt_file.ppt")) {
-            assertEquals(expectText, ppe.getText());
+            assertEquals(EXPECTED_PAGE1+EXPECTED_PAGE2, ppe.getText());
         }
 
+        // Extractor primed on the 1 page but text-box'd test data
+        final String expectText2 =
+            "Hello, World!!!\n" +
+            "I am just a poor boy\n" +
+            "This is Times New Roman\n" +
+            "Plain Text \n";
+
         // 1 page example with text boxes
         try (SlideShowExtractor ppe = openExtractor("with_textbox.ppt")) {
             assertEquals(expectText2, ppe.getText());
@@ -92,8 +111,7 @@ public final class TestExtractor {
             ppe.setSlidesByDefault(false);
             ppe.setMasterByDefault(false);
             String notesText = ppe.getText();
-            String expText = "\nThese are the notes for page 1\n\nThese are 
the notes on page two, again lacking formatting\n";
-            assertEquals(expText, notesText);
+            assertEquals(NOTES_PAGE1+NOTES_PAGE2, notesText);
         }
 
         // Other one doesn't have notes
@@ -109,14 +127,8 @@ public final class TestExtractor {
 
     @Test
     public void testReadBoth() throws IOException {
-        String[] slText = new String[]{
-                "This is a test title\nThis is a test subtitle\nThis is on 
page 1\n",
-                "This is the title on page 2\nThis is page two\nIt has several 
blocks of text\nNone of them have formatting\n"
-        };
-        String[] ntText = new String[]{
-                "\nThese are the notes for page 1\n",
-                "\nThese are the notes on page two, again lacking formatting\n"
-        };
+        String[] slText = { EXPECTED_PAGE1, EXPECTED_PAGE2 };
+        String[] ntText = { NOTES_PAGE1, NOTES_PAGE2 };
 
         try (SlideShowExtractor ppe = 
openExtractor("basic_test_ppt_file.ppt")) {
             ppe.setSlidesByDefault(true);
@@ -165,8 +177,8 @@ public final class TestExtractor {
             final DirectoryNode root = fs.getRoot();
 
             final String[] TEST_SET = {
-                "MBD0000A3B6", "Sample PowerPoint file\nThis is the 1st 
file\nNot much too it\n",
-                "MBD0000A3B3", "Sample PowerPoint file\nThis is the 2nd 
file\nNot much too it either\n"
+                "MBD0000A3B6", "Sample PowerPoint file\nThis is the 1st 
file\n\nNot much too it\n",
+                "MBD0000A3B3", "Sample PowerPoint file\nThis is the 2nd 
file\n\nNot much too it either\n"
             };
 
             for (int i=0; i<TEST_SET.length; i+=2) {
@@ -386,7 +398,7 @@ public final class TestExtractor {
             // Open directly
             try (SlideShow<?,?> ppt = 
SlideShowFactory.create(npoifs.getRoot());
                 SlideShowExtractor<?,?> extractor = new 
SlideShowExtractor<>(ppt)) {
-                assertEquals(expectText, extractor.getText());
+                assertEquals(EXPECTED_PAGE1+EXPECTED_PAGE2, 
extractor.getText());
             }
         }
     }
@@ -457,4 +469,19 @@ public final class TestExtractor {
     private static int countMatches(final String base, final String find) {
         return base.split(find).length-1;
     }
+
+    @Test
+    public void glyphCounting() throws IOException {
+        String[] expected = {
+            "Times New Roman", "\t\n 
,-./01234679:ABDEFGILMNOPRSTVWabcdefghijklmnoprstuvwxyz\u00F3\u201C\u201D",
+            "Arial", " Lacdilnost"
+        };
+        try (SlideShowExtractor ppt = openExtractor("45543.ppt")) {
+            for (int i=0; i<expected.length; i+=2) {
+                BitSet l = ppt.getCodepoints(expected[i], null, null);
+                String s = 
l.stream().mapToObj(Character::toChars).map(String::valueOf).collect(Collectors.joining());
+                assertEquals(expected[i+1], s);
+            }
+        }
+    }
 }

Modified: 
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java
 (original)
+++ 
poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestHSLFSlideShow.java
 Fri Dec 28 23:43:31 2018
@@ -27,7 +27,7 @@ import org.apache.poi.sl.usermodel.BaseT
 import org.apache.poi.sl.usermodel.SlideShow;
 import org.junit.Test;
 
-public class TestHSLFSlideShow extends BaseTestSlideShow {
+public class TestHSLFSlideShow extends 
BaseTestSlideShow<HSLFShape,HSLFTextParagraph> {
     @Override
     public HSLFSlideShow createSlideShow() {
         return new HSLFSlideShow();
@@ -39,11 +39,7 @@ public class TestHSLFSlideShow extends B
         assertNotNull(createSlideShow());
     }
 
-    public SlideShow<?, ?> reopen(SlideShow<?, ?> show) {
-        return reopen((HSLFSlideShow)show);
-    }
-
-    public static HSLFSlideShow reopen(HSLFSlideShow show) {
+    public HSLFSlideShow reopen(SlideShow<HSLFShape,HSLFTextParagraph> show) {
         try {
             BufAccessBAOS bos = new BufAccessBAOS();
             show.write(bos);
@@ -55,7 +51,7 @@ public class TestHSLFSlideShow extends B
     }
 
     private static class BufAccessBAOS extends ByteArrayOutputStream {
-        public byte[] getBuf() {
+        byte[] getBuf() {
             return buf;
         }
     }

Modified: 
poi/trunk/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java?rev=1849898&r1=1849897&r2=1849898&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java 
(original)
+++ poi/trunk/src/testcases/org/apache/poi/sl/usermodel/BaseTestSlideShow.java 
Fri Dec 28 23:43:31 2018
@@ -17,6 +17,7 @@
 package org.apache.poi.sl.usermodel;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
@@ -29,20 +30,24 @@ import java.io.InputStream;
 import java.util.List;
 
 import org.apache.poi.POIDataSamples;
+import org.apache.poi.common.usermodel.fonts.FontInfo;
 import org.apache.poi.sl.usermodel.PictureData.PictureType;
 import org.apache.poi.sl.usermodel.TabStop.TabStopType;
 import org.junit.Test;
 
-public abstract class BaseTestSlideShow {
+public abstract class BaseTestSlideShow<
+        S extends Shape<S,P>,
+        P extends TextParagraph<S,P,? extends TextRun>
+> {
     protected static final POIDataSamples slTests = 
POIDataSamples.getSlideShowInstance();
     
-    public abstract SlideShow<?, ?> createSlideShow();
+    public abstract SlideShow<S,P> createSlideShow();
 
-    public abstract SlideShow<?, ?> reopen(SlideShow<?, ?> show);
+    public abstract SlideShow<S,P> reopen(SlideShow<S,P> show);
     
     @Test
     public void addPicture_File() throws IOException {
-        SlideShow<?,?> show = createSlideShow();
+        SlideShow<S,P> show = createSlideShow();
         File f = slTests.getFile("clock.jpg");
         
         assertEquals(0, show.getPictureData().size());
@@ -55,26 +60,18 @@ public abstract class BaseTestSlideShow
     
     @Test
     public void addPicture_Stream() throws IOException {
-        SlideShow<?,?> show = createSlideShow();
-        try {
-            InputStream stream = slTests.openResourceAsStream("clock.jpg");
-            try {
-                assertEquals(0, show.getPictureData().size());
-                PictureData picture = show.addPicture(stream, 
PictureType.JPEG);
-                assertEquals(1, show.getPictureData().size());
-                assertSame(picture, show.getPictureData().get(0));
-
-            } finally {
-                stream.close();
-            }
-        } finally {
-            show.close();
+        try (SlideShow<S,P> show = createSlideShow();
+             InputStream stream = slTests.openResourceAsStream("clock.jpg")) {
+            assertEquals(0, show.getPictureData().size());
+            PictureData picture = show.addPicture(stream, PictureType.JPEG);
+            assertEquals(1, show.getPictureData().size());
+            assertSame(picture, show.getPictureData().get(0));
         }
     }
     
     @Test
     public void addPicture_ByteArray() throws IOException {
-        SlideShow<?,?> show = createSlideShow();
+        SlideShow<S,P> show = createSlideShow();
         byte[] data = slTests.readFile("clock.jpg");
         
         assertEquals(0, show.getPictureData().size());
@@ -87,7 +84,7 @@ public abstract class BaseTestSlideShow
     
     @Test
     public void findPicture() throws IOException {
-        SlideShow<?,?> show = createSlideShow();
+        SlideShow<S,P> show = createSlideShow();
         byte[] data = slTests.readFile("clock.jpg");
         
         assertNull(show.findPictureData(data));
@@ -101,11 +98,11 @@ public abstract class BaseTestSlideShow
     
     @Test
     public void addTabStops() throws IOException {
-        try (final SlideShow<?,?> show1 = createSlideShow()) {
+        try (final SlideShow<S,P> show1 = createSlideShow()) {
             // first set the TabStops in the Master sheet
-            final MasterSheet<?, ?> master1 = show1.getSlideMasters().get(0);
-            final AutoShape<?, ?> master1_as = 
(AutoShape<?,?>)master1.getPlaceholder(Placeholder.BODY);
-            final TextParagraph<?, ?, ? extends TextRun> master1_tp = 
master1_as.getTextParagraphs().get(0);
+            final MasterSheet<S,P> master1 = show1.getSlideMasters().get(0);
+            final AutoShape<S,P> master1_as = 
(AutoShape<S,P>)master1.getPlaceholder(Placeholder.BODY);
+            final P master1_tp = master1_as.getTextParagraphs().get(0);
             master1_tp.clearTabStops();
             int i1 = 0;
             for (final TabStopType tst : TabStopType.values()) {
@@ -114,11 +111,11 @@ public abstract class BaseTestSlideShow
             }
             
             // then set it on a normal slide
-            final Slide<?,?> slide1 = show1.createSlide();
-            final AutoShape<?, ?> slide1_as = slide1.createAutoShape();
+            final Slide<S,P> slide1 = show1.createSlide();
+            final AutoShape<S,P> slide1_as = slide1.createAutoShape();
             slide1_as.setText("abc");
             slide1_as.setAnchor(new Rectangle2D.Double(100,100,100,100));
-            final TextParagraph<?, ?, ? extends TextRun> slide1_tp = 
slide1_as.getTextParagraphs().get(0);
+            final P slide1_tp = slide1_as.getTextParagraphs().get(0);
             slide1_tp.getTextRuns().get(0).setFontColor(new Color(0x563412));
             slide1_tp.clearTabStops();
             int i2 = 0;
@@ -127,10 +124,10 @@ public abstract class BaseTestSlideShow
                 i2++;
             }
             
-            try (final SlideShow<?, ?> show2 = reopen(show1)) {
-                final MasterSheet<?, ?> master2 = 
show2.getSlideMasters().get(0);
-                final AutoShape<?, ?> master2_as = 
(AutoShape<?,?>)master2.getPlaceholder(Placeholder.BODY);
-                final TextParagraph<?, ?, ? extends TextRun> master2_tp = 
master2_as.getTextParagraphs().get(0);
+            try (final SlideShow<S,P> show2 = reopen(show1)) {
+                final MasterSheet<S,P> master2 = 
show2.getSlideMasters().get(0);
+                final AutoShape<S,P> master2_as = 
(AutoShape<S,P>)master2.getPlaceholder(Placeholder.BODY);
+                final P master2_tp = master2_as.getTextParagraphs().get(0);
                 final List<? extends TabStop> master2_tabStops = 
master2_tp.getTabStops();
                 assertNotNull(master2_tabStops);
                 int i3 = 0;
@@ -142,9 +139,10 @@ public abstract class BaseTestSlideShow
                 }
                 
                 
-                final Slide<?,?> slide2 = show2.getSlides().get(0);
-                final AutoShape<?,?> slide2_as = 
(AutoShape<?,?>)slide2.getShapes().get(0);
-                final TextParagraph<?, ?, ? extends TextRun> slide2_tp = 
slide2_as.getTextParagraphs().get(0);
+                final Slide<S,P> slide2 = show2.getSlides().get(0);
+                @SuppressWarnings("unchecked")
+                final AutoShape<S,P> slide2_as = 
(AutoShape<S,P>)slide2.getShapes().get(0);
+                final P slide2_tp = slide2_as.getTextParagraphs().get(0);
                 final List<? extends TabStop> slide2_tabStops = 
slide2_tp.getTabStops();
                 assertNotNull(slide2_tabStops);
                 int i4 = 0;
@@ -162,18 +160,35 @@ public abstract class BaseTestSlideShow
     public void shapeAndSlideName() throws IOException {
         final String file = 
"SampleShow.ppt"+(getClass().getSimpleName().contains("XML")?"x":"");
         try (final InputStream is = slTests.openResourceAsStream(file);
-             final SlideShow<? extends Shape, ?> ppt = 
SlideShowFactory.create(is)) {
-            final List<? extends Shape> shapes1 = 
ppt.getSlides().get(0).getShapes();
+             final SlideShow<S,P> ppt = SlideShowFactory.create(is)) {
+            final List<S> shapes1 = ppt.getSlides().get(0).getShapes();
             assertEquals("The Title", shapes1.get(0).getShapeName());
             assertEquals("Another Subtitle", shapes1.get(1).getShapeName());
-            final List<? extends Shape> shapes2 = 
ppt.getSlides().get(1).getShapes();
+            final List<S> shapes2 = ppt.getSlides().get(1).getShapes();
             assertEquals("Title 1", shapes2.get(0).getShapeName());
             assertEquals("Content Placeholder 2", 
shapes2.get(1).getShapeName());
 
-            for (final Slide<?,?> slide : ppt.getSlides()) {
+            for (final Slide<S,P> slide : ppt.getSlides()) {
                 final String expected = slide.getSlideNumber()==1 ? 
"FirstSlide" : "Slide2";
                 assertEquals(expected, slide.getSlideName());
             }
         }
     }
+
+    @Test
+    public void addFont() throws IOException {
+        try (SlideShow<S,P> ppt = createSlideShow()) {
+            ppt.createSlide();
+            try (InputStream fontData = 
slTests.openResourceAsStream("font.fntdata")) {
+                ppt.addFont(fontData);
+            }
+
+            try (SlideShow<S, P> ppt2 = reopen(ppt)) {
+                List<? extends FontInfo> fonts = ppt2.getFonts();
+                assertFalse(fonts.isEmpty());
+                FontInfo fi = fonts.get(fonts.size()-1);
+                assertEquals("Harlow Solid Italic", fi.getTypeface());
+            }
+        }
+    }
 }

Added: poi/trunk/test-data/slideshow/font.fntdata
URL: 
http://svn.apache.org/viewvc/poi/trunk/test-data/slideshow/font.fntdata?rev=1849898&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/test-data/slideshow/font.fntdata
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to