]> source.dussan.org Git - poi.git/commitdiff
more progress with PPTX2PNG
authorYegor Kozlov <yegor@apache.org>
Mon, 14 Nov 2011 13:00:13 +0000 (13:00 +0000)
committerYegor Kozlov <yegor@apache.org>
Mon, 14 Nov 2011 13:00:13 +0000 (13:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1201687 13f79535-47bb-0310-9956-ffa450edef68

32 files changed:
src/ooxml/java/org/apache/poi/xslf/model/CharacterPropertyFetcher.java
src/ooxml/java/org/apache/poi/xslf/usermodel/RenderableShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFConnectorShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFGroupShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFRenderingHint.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFSimpleShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextParagraph.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextRun.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
src/ooxml/testcases/org/apache/poi/xslf/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/XSLFTestDataSamples.java
src/ooxml/testcases/org/apache/poi/xslf/extractor/TestXSLFPowerPointExtractor.java
src/ooxml/testcases/org/apache/poi/xslf/geom/TestFormulaParser.java
src/ooxml/testcases/org/apache/poi/xslf/geom/TestPresetGeometries.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXMLSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFAutoShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFConnectorShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFFreeformShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFGroupShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFHyperlink.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFPictureShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSheet.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSimpleShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlide.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFSlideShow.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTable.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTableStyles.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextParagraph.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTextShape.java
src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFTheme.java

index 09674abfe86e5020b62ff60938966e34f7a32bb2..ced941ccb33b5f5cd681cac07e83bcf85a1faf53 100644 (file)
@@ -27,6 +27,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties
  * @author Yegor Kozlov\r
  */\r
 public abstract class CharacterPropertyFetcher<T> extends ParagraphPropertyFetcher<T> {\r
+    public boolean isFetchingFromMaster = false;\r
 \r
     public CharacterPropertyFetcher(int level) {\r
         super(level);\r
index 82a29756a4bb6cfd75609c53e0cf5f4e728cc947..27ba5d701bfdbd78c1e9bf57450a42ab1b376704 100644 (file)
@@ -430,6 +430,8 @@ class RenderableShape {
     public Stroke applyStroke(Graphics2D graphics) {\r
 \r
         float lineWidth = (float) _shape.getLineWidth();\r
+        if(lineWidth == 0.0f) lineWidth = 0.25f; // Both PowerPoint and OOo draw zero-length lines as 0.25pt\r
+\r
         LineDash lineDash = _shape.getLineDash();\r
         float[] dash = null;\r
         float dash_phase = 0;\r
@@ -559,8 +561,6 @@ class RenderableShape {
             lst.add(new Outline(canvasShape, p));\r
         }\r
 \r
-        // add any shape-specific stuff here (line decorations, etc.)\r
-        lst.addAll(_shape.getCustomOutlines());\r
         return lst;\r
     }\r
 \r
index b7f1f3d389fee00aeeb44c08c30be97afeb288e8..cd3a925d544892a1dd3c8cc9e72ea896edd9baa5 100644 (file)
@@ -35,12 +35,13 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTConnectorNonVisual;\r
 \r
 import java.awt.Shape;\r
+import java.awt.Graphics2D;\r
+import java.awt.Color;\r
 import java.awt.geom.AffineTransform;\r
 import java.awt.geom.Ellipse2D;\r
 import java.awt.geom.GeneralPath;\r
 import java.awt.geom.Rectangle2D;\r
 import java.util.ArrayList;\r
-import java.util.Collections;\r
 import java.util.List;\r
 \r
 /**\r
@@ -206,7 +207,8 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
         LineEndLength tailLength = getLineTailLength();\r
         LineEndWidth tailWidth = getLineTailWidth();\r
 \r
-        double lineWidth = getLineWidth();\r
+        double lineWidth = Math.max(2.5, getLineWidth());\r
+\r
         Rectangle2D anchor = getAnchor();\r
         double x2 = anchor.getX() + anchor.getWidth(),\r
                 y2 = anchor.getY() + anchor.getHeight();\r
@@ -264,7 +266,7 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
         LineEndLength headLength = getLineHeadLength();\r
         LineEndWidth headWidth = getLineHeadWidth();\r
 \r
-        double lineWidth = getLineWidth();\r
+        double lineWidth = Math.max(2.5, getLineWidth());\r
         Rectangle2D anchor = getAnchor();\r
         double x1 = anchor.getX(),\r
                 y1 = anchor.getY();\r
@@ -287,7 +289,7 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
                 break;\r
             case STEALTH:\r
             case ARROW:\r
-                p = new Path();\r
+                p = new Path(false, true);\r
                 GeneralPath arrow = new GeneralPath();\r
                 arrow.moveTo((float) (lineWidth * 3 * scaleX), (float) (-lineWidth * scaleY * 2));\r
                 arrow.lineTo(0, 0);\r
@@ -319,8 +321,7 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
         return shape == null ? null : new Outline(shape, p);\r
     }\r
 \r
-    @Override\r
-    List<Outline> getCustomOutlines(){\r
+    private List<Outline> getDecorationOutlines(){\r
         List<Outline> lst = new ArrayList<Outline>();\r
 \r
         Outline head = getHeadDecoration();\r
@@ -339,4 +340,23 @@ public class XSLFConnectorShape extends XSLFSimpleShape {
     public XSLFShadow getShadow() {\r
         return null;\r
     }\r
+\r
+    @Override\r
+    public void draw(Graphics2D graphics){\r
+        super.draw(graphics);\r
+\r
+        // draw line decorations\r
+        Color lineColor = getLineColor();\r
+        if(lineColor != null) {\r
+            graphics.setPaint(lineColor);\r
+            for(Outline o : getDecorationOutlines()){\r
+                if(o.getPath().isFilled()){\r
+                    graphics.fill(o.getOutline());\r
+                }            \r
+                if(o.getPath().isStroked()){\r
+                    graphics.draw(o.getOutline());\r
+                }\r
+            }\r
+        }\r
+    }\r
 }
\ No newline at end of file
index 3159ee98a49e00a326b7fb8ea1f0a2c602ab0daf..1c681934766cc893c8d73279c79eecb747a64417 100644 (file)
@@ -281,6 +281,11 @@ public class XSLFGroupShape extends XSLFShape {
         graphics.translate(exterior.getX(), exterior.getY());\r
         double scaleX = exterior.getWidth() / interior.getWidth();\r
         double scaleY = exterior.getHeight() / interior.getHeight();\r
+\r
+        // group transform scales shapes but not fonts\r
+        Number prevFontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.FONT_SCALE);\r
+        graphics.setRenderingHint(XSLFRenderingHint.FONT_SCALE, Math.abs(1/scaleY));\r
+\r
         graphics.scale(scaleX, scaleY);\r
         graphics.translate(-interior.getX(), -interior.getY());\r
 \r
@@ -296,6 +301,9 @@ public class XSLFGroupShape extends XSLFShape {
             graphics.setTransform(at);\r
             graphics.setRenderingHint(XSLFRenderingHint.GRESTORE, true);\r
         }\r
+\r
+        graphics.setRenderingHint(XSLFRenderingHint.FONT_SCALE, prevFontScale);\r
+        \r
     }\r
 \r
 }
\ No newline at end of file
index 345d57c4b36a4869a264541a476d9d6e7640bee6..e8d70437cea205210647b252f67c42e16e4b72a8 100644 (file)
@@ -19,6 +19,8 @@
 \r
 package org.apache.poi.xslf.usermodel;\r
 \r
+import org.apache.poi.util.Internal;\r
+\r
 import java.awt.RenderingHints;\r
 \r
 /**\r
@@ -71,4 +73,7 @@ public class XSLFRenderingHint extends RenderingHints.Key {
      * draw text via {@link java.awt.font.TextLayout#draw(java.awt.Graphics2D, float, float)}\r
      */\r
     public static final int TEXT_MODE_GLYPHS = 2;\r
+\r
+    @Internal\r
+    public static final XSLFRenderingHint FONT_SCALE = new XSLFRenderingHint(5);\r
 }
\ No newline at end of file
index 5e62ec87eab8a13ae360436f01b984580c621f3d..92adf446e06e03b85784aa7b6c37312b5e483c38 100644 (file)
@@ -642,14 +642,6 @@ public abstract class XSLFSimpleShape extends XSLFShape {
     }\r
 \r
 \r
-    /**\r
-     * @return any shape-specific geometry that is not included in presetShapeDefinitions.xml\r
-     * (line decorations, etc)\r
-     */\r
-    List<Outline>  getCustomOutlines(){\r
-        return Collections.emptyList();\r
-    }\r
-\r
     /**\r
      * draw any content within this shape (image, text, etc.).\r
      *\r
index 4358288ee009bb3b049d5874a36e0804ad2211fd..46087363989febf7cc050a6b837ef3acfa7cdfa7 100644 (file)
@@ -26,6 +26,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextSpacing;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStop;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextTabStopList;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextAlignType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextFont;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharBullet;\r
@@ -33,6 +35,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBulletSizePoint;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextLineBreak;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
 \r
@@ -242,7 +246,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
         CTTextParagraphProperties pr = _p.isSetPPr() ? _p.getPPr() : _p.addNewPPr();\r
         CTColor c = pr.isSetBuClr() ? pr.getBuClr() : pr.addNewBuClr();\r
         CTSRgbColor clr = c.isSetSrgbClr() ? c.getSrgbClr() : c.addNewSrgbClr();\r
-        clr.setVal(new byte[]{(byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()});\r
+        clr.setVal(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()});\r
     }\r
 \r
     public double getBulletFontSize(){\r
@@ -333,7 +337,45 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
         };\r
         fetchParagraphProperty(fetcher);\r
         // if the marL attribute is omitted, then a value of 347663 is implied\r
-        return fetcher.getValue() == null ? Units.toPoints(347663) : fetcher.getValue();\r
+        return fetcher.getValue() == null ? 0 : fetcher.getValue();\r
+    }\r
+\r
+    /**\r
+     *\r
+     * @return the default size for a tab character within this paragraph\r
+     */\r
+    public double getDefaultTabSize(){\r
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){\r
+            public boolean fetch(CTTextParagraphProperties props){\r
+                if(props.isSetDefTabSz()){\r
+                    double val = Units.toPoints(props.getDefTabSz());\r
+                    setValue(val);\r
+                    return true;\r
+                }\r
+                return false;\r
+            }\r
+        };\r
+        fetchParagraphProperty(fetcher);\r
+        return fetcher.getValue() == null ? 0 : fetcher.getValue();\r
+    }\r
+\r
+    public double getTabStop(final int idx){\r
+        ParagraphPropertyFetcher<Double> fetcher = new ParagraphPropertyFetcher<Double>(getLevel()){\r
+            public boolean fetch(CTTextParagraphProperties props){\r
+                if(props.isSetTabLst()){\r
+                    CTTextTabStopList tabStops = props.getTabLst();\r
+                    if(idx < tabStops.sizeOfTabArray() ) {\r
+                        CTTextTabStop ts = tabStops.getTabArray(idx);\r
+                        double val = Units.toPoints(ts.getPos());\r
+                        setValue(val);\r
+                        return true;\r
+                    }\r
+                }\r
+                return false;\r
+            }\r
+        };\r
+        fetchParagraphProperty(fetcher);\r
+        return fetcher.getValue() == null ? getDefaultTabSize() : fetcher.getValue();\r
     }\r
 \r
     /**\r
@@ -389,7 +431,18 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
             }\r
         };\r
         fetchParagraphProperty(fetcher);\r
-        return fetcher.getValue() == null ? 100 : fetcher.getValue();\r
+\r
+        double lnSpc = fetcher.getValue() == null ? 100 : fetcher.getValue();\r
+        if(lnSpc > 0) {\r
+            // check if the percentage value is scaled\r
+            CTTextNormalAutofit normAutofit = getParentShape().getTextBodyPr().getNormAutofit();\r
+            if(normAutofit != null) {\r
+                double scale = 1 - (double)normAutofit.getLnSpcReduction() / 100000;\r
+                lnSpc *= scale;\r
+            }\r
+        }\r
+        \r
+        return lnSpc;\r
     }\r
 \r
     /**\r
@@ -443,7 +496,9 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
             }\r
         };\r
         fetchParagraphProperty(fetcher);\r
-        return fetcher.getValue() == null ? 0 : fetcher.getValue();\r
+\r
+        double spcBef = fetcher.getValue() == null ? 0 : fetcher.getValue();\r
+        return spcBef;\r
     }\r
 \r
     /**\r
@@ -535,7 +590,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
                     setValue(false);\r
                     return true;\r
                 }\r
-                if(props.isSetBuFont()){\r
+                if(props.isSetBuFont() || props.isSetBuChar()){\r
                     setValue(true);\r
                     return true;\r
                 }\r
@@ -596,7 +651,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
             width = anchor.getWidth() -  leftInset - rightInset - leftMargin;\r
             if(firstLine) {\r
                 if(isBullet()){\r
-                    width -= Math.abs(indent);\r
+                    if(indent > 0) width -= indent;\r
                 } else {\r
                     if(indent > 0) width -= indent; // first line indentation\r
                     else if (indent < 0) { // hanging indentation: the first line start at the left margin\r
@@ -618,28 +673,25 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
         double leftMargin = getLeftMargin();\r
         boolean firstLine = true;\r
         double indent = getIndent();\r
+\r
+        //The vertical line spacing\r
+        double spacing = getLineSpacing();\r
         for(TextFragment line : _lines){\r
-            double penX = x;\r
+            double penX = x + leftMargin;\r
 \r
             if(firstLine) {\r
-\r
                 if(_bullet != null){\r
                     if(indent < 0) {\r
                         // a negative value means "Hanging" indentation and\r
                         // indicates the position of the actual bullet character.\r
                         // (the bullet is shifted to right relative to the text)\r
-                        _bullet.draw(graphics, penX,  penY);\r
-                        penX -= indent;\r
+                        _bullet.draw(graphics, penX + indent,  penY);\r
                     } else if(indent > 0){\r
-                        penX += leftMargin;\r
                         // a positive value means the "First Line" indentation:\r
                         // the first line is indented and other lines start at the bullet ofset\r
                         _bullet.draw(graphics, penX,  penY);\r
                         penX += indent;\r
                     } else {\r
-                        // no special indent. The first line behaves like all others\r
-                        penX += leftMargin;\r
-\r
                         // a zero indent means that the bullet and text have the same offset\r
                         _bullet.draw(graphics, penX,  penY);\r
 \r
@@ -647,19 +699,8 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
                         penX += _bullet._layout.getAdvance() + 1;\r
                     }\r
                 } else {\r
-                    if(indent < 0) {\r
-                        // if bullet=false and indentation=hanging then the first line\r
-                        // starts at the left offset (penX is not incremented)\r
-                    } else if(indent > 0) {\r
-                        // first line indent shifts penX\r
-                        penX += indent + leftMargin;\r
-                    }  else {\r
-                        // no special indent. The first line behaves like all others\r
-                        penX += leftMargin;\r
-                    }\r
+                    penX += indent;\r
                 }\r
-            } else {\r
-                penX += leftMargin;\r
             }\r
 \r
 \r
@@ -671,14 +712,11 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
                     penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);\r
                     break;\r
                 default:\r
-                    //penX += leftInset;\r
                     break;\r
             }\r
 \r
             line.draw(graphics, penX,  penY);\r
 \r
-            //The vertical line spacing\r
-            double spacing = getLineSpacing();\r
             if(spacing > 0) {\r
                 // If linespacing >= 0, then linespacing is a percentage of normal line height.\r
                 penY += spacing*0.01* _maxLineHeight;\r
@@ -689,6 +727,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
 \r
             firstLine = false;\r
         }\r
+        \r
         return penY - y;\r
     }\r
 \r
@@ -722,6 +761,7 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
     }\r
 \r
     AttributedString getAttributedString(Graphics2D graphics){\r
+\r
         String text = getRenderableText();\r
 \r
         AttributedString string = new AttributedString(text);\r
@@ -740,7 +780,11 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
             // user can pass an object to convert fonts via a rendering hint\r
             string.addAttribute(TextAttribute.FAMILY, run.getFontFamily(), startIndex, endIndex);\r
 \r
-            string.addAttribute(TextAttribute.SIZE, (float)run.getFontSize(), startIndex, endIndex);\r
+            float fontSz = (float)run.getFontSize();\r
+            Number fontScale = (Number)graphics.getRenderingHint(XSLFRenderingHint.FONT_SCALE);\r
+            if(fontScale != null) fontSz *= fontScale.floatValue();\r
+\r
+            string.addAttribute(TextAttribute.SIZE, fontSz , startIndex, endIndex);\r
             if(run.isBold()) {\r
                 string.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIndex, endIndex);\r
             }\r
@@ -768,30 +812,48 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
         return string;\r
     }\r
 \r
+    /**\r
+     *  ensure that the paragraph contains at least one character\r
+     */\r
+    private void ensureNotEmpty(){\r
+        XSLFTextRun r = addNewTextRun();\r
+        r.setText(" ");\r
+        CTTextCharacterProperties endPr = _p.getEndParaRPr();\r
+        if(endPr != null) {\r
+            if(endPr.isSetSz()) r.setFontSize(endPr.getSz() / 100);\r
+        }\r
+    }\r
+\r
     void breakText(Graphics2D graphics){\r
         _lines = new ArrayList<TextFragment>();\r
 \r
+        // does this paragraph contain text?\r
+        boolean emptyParagraph = _runs.size() == 0;\r
+\r
+        // ensure that the paragraph contains at least one character\r
+        if(_runs.size() == 0) ensureNotEmpty();\r
+\r
         String text = getRenderableText();\r
+        if(text.length() == 0) return;\r
+\r
         AttributedString at = getAttributedString(graphics);\r
         AttributedCharacterIterator it = at.getIterator();\r
-        if(it.getBeginIndex() == it.getEndIndex()) {\r
-            return;\r
-        }\r
         LineBreakMeasurer measurer = new LineBreakMeasurer(it, graphics.getFontRenderContext());\r
         for (;;) {\r
             int startIndex = measurer.getPosition();\r
             double wrappingWidth = getWrappingWidth(_lines.size() == 0) + 1; // add a pixel to compensate rounding errors\r
-\r
+            // shape width can be smaller that the sum of insets (proved by a test file)\r
+            if(wrappingWidth < 0) wrappingWidth = 1;\r
 \r
             int nextBreak = text.indexOf('\n', startIndex + 1);\r
             if(nextBreak == -1) nextBreak = it.getEndIndex();\r
 \r
             TextLayout layout = measurer.nextLayout((float)wrappingWidth, nextBreak, true);\r
-             if (layout == null) {\r
+            if (layout == null) {\r
                  // layout can be null if the entire word at the current position\r
                  // does not fit within the wrapping width. Try with requireNextWord=false.\r
                  layout = measurer.nextLayout((float)wrappingWidth, nextBreak, false);\r
-             }\r
+            }\r
 \r
             int endIndex = measurer.getPosition();\r
 \r
@@ -809,9 +871,10 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
             if(endIndex == it.getEndIndex()) break;\r
         }\r
 \r
-        if(isBullet()) {\r
+        if(isBullet() && !emptyParagraph) {\r
             String buCharacter = getBulletCharacter();\r
             String buFont = getBulletFont();\r
+            if(buFont == null) buFont = getTextRuns().get(0).getFontFamily();\r
             if(buCharacter != null && buFont != null && _lines.size() > 0) {\r
                 AttributedString str = new AttributedString(buCharacter);\r
 \r
@@ -954,4 +1017,5 @@ public class XSLFTextParagraph implements Iterable<XSLFTextRun>{
             r2.copy(r1);\r
         }\r
     }\r
+\r
 }\r
index dc79e73c68f121d1ad8d4c05bb824faa8d0480ed..4f05caec95a0b4d8839633ce1968e05b85111022 100644 (file)
@@ -29,8 +29,13 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTTextNormalAutofit;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraphProperties;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;\r
 \r
 import java.awt.Color;\r
+import java.awt.font.FontRenderContext;\r
+import java.awt.font.TextLayout;\r
+import java.awt.font.TextAttribute;\r
+import java.text.AttributedString;\r
 \r
 /**\r
  * Represents a run of text within the containing text body. The run element is the\r
@@ -58,21 +63,54 @@ public class XSLFTextRun {
 \r
     String getRenderableText(){\r
         String txt = _r.getT();\r
-        switch (getTextCap()){\r
-            case ALL:\r
-                txt = txt.toUpperCase();\r
-                break;\r
-            case SMALL:\r
-                txt = txt.toLowerCase();\r
-                break;\r
+\r
+        StringBuffer buf = new StringBuffer();\r
+        for(int i = 0; i < txt.length(); i++) {\r
+            char c = txt.charAt(i);\r
+            if(c == '\t') {\r
+                // replace tab with the effective number of white spaces\r
+                buf.append("  ");\r
+            } else {\r
+                switch (getTextCap()){\r
+                    case ALL:\r
+                        buf.append(Character.toUpperCase(c));\r
+                        break;\r
+                    case SMALL:\r
+                        buf.append(Character.toLowerCase(c));\r
+                        break;\r
+                    default:\r
+                        buf.append(c);\r
+                }\r
+            }\r
         }\r
-        // TODO-1 is is the place to convert wingdings to unicode\r
-        \r
-        // TODO-2 this is a temporary hack. Rendering text with tabs is not yet supported.\r
-        // for now tabs are replaced with some number of spaces.\r
-        return txt.replace("\t", " ");\r
+\r
+        return buf.toString();\r
     }\r
 \r
+    /**\r
+     * Replace a tab with the effective number of white spaces.\r
+     *\r
+     * @return\r
+     */\r
+    private String tab2space(){\r
+        AttributedString string = new AttributedString(" ");\r
+        // user can pass an object to convert fonts via a rendering hint\r
+        string.addAttribute(TextAttribute.FAMILY, getFontFamily());\r
+\r
+        string.addAttribute(TextAttribute.SIZE, (float)getFontSize());\r
+        TextLayout l = new TextLayout(string.getIterator(), new FontRenderContext(null, true, true));\r
+        double wspace = l.getAdvance();\r
+\r
+        double tabSz = _p.getDefaultTabSize();\r
+\r
+        int numSpaces = (int)Math.ceil(tabSz / wspace);\r
+        StringBuffer buf = new StringBuffer();\r
+        for(int i = 0; i < numSpaces; i++) {\r
+            buf.append(' ');\r
+        }\r
+        return buf.toString();\r
+    }\r
+    \r
     public void setText(String text){\r
         _r.setT(text);\r
     }\r
@@ -98,13 +136,16 @@ public class XSLFTextRun {
     public Color getFontColor(){\r
         final XSLFTheme theme = _p.getParentShape().getSheet().getTheme();\r
         CTShapeStyle style = _p.getParentShape().getSpStyle();\r
-        final CTSchemeColor shapeStyle = style == null ? null : style.getFontRef().getSchemeClr();\r
+        final CTSchemeColor phClr = style == null ? null : style.getFontRef().getSchemeClr();\r
 \r
         CharacterPropertyFetcher<Color> fetcher = new CharacterPropertyFetcher<Color>(_p.getLevel()){\r
             public boolean fetch(CTTextCharacterProperties props){\r
                 CTSolidColorFillProperties solidFill = props.getSolidFill();\r
                 if(solidFill != null) {\r
-                    Color c = new XSLFColor(solidFill, theme, shapeStyle).getColor();\r
+                    boolean useCtxColor =\r
+                            (solidFill.isSetSchemeClr() && solidFill.getSchemeClr().getVal() == STSchemeColorVal.PH_CLR)\r
+                            || isFetchingFromMaster;\r
+                    Color c = new XSLFColor(solidFill, theme, useCtxColor ? phClr : null).getColor();\r
                     setValue(c);\r
                     return true;\r
                 }\r
@@ -410,7 +451,10 @@ public class XSLFTextRun {
             ok = shape.fetchShapeProperty(fetcher);\r
             if(!ok) {\r
                 CTTextParagraphProperties defaultProps = _p.getDefaultStyle();\r
-                if(defaultProps != null) ok = fetcher.fetch(defaultProps);\r
+                if(defaultProps != null) {\r
+                    fetcher.isFetchingFromMaster = true;\r
+                    ok = fetcher.fetch(defaultProps);\r
+                }\r
             }\r
         }\r
 \r
index 455ceae9095f6266182d510f7e45557d0c433c75..bc3ae8619b22699be339f797ea9290b9ec055eb3 100644 (file)
 ==================================================================== */
 package org.apache.poi.xslf;
 
-import java.net.URI;
-import java.util.List;
-
 import junit.framework.TestCase;
-
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.xslf.usermodel.XMLSlideShow;
@@ -28,6 +24,9 @@ import org.apache.poi.xslf.usermodel.XSLFRelation;
 import org.apache.poi.xslf.usermodel.XSLFSlide;
 import org.apache.poi.xslf.usermodel.XSLFSlideLayout;
 
+import java.net.URI;
+import java.util.List;
+
 public class TestXSLFBugs extends TestCase {
 
     public void test51187() throws Exception {
index 25f7012d3722788aaed59a4ba9c97713a9a17949..f82ed00ce01dca1b947b4593735009054f8ebd17 100644 (file)
@@ -17,7 +17,6 @@
 package org.apache.poi.xslf;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
index b6966d06ef5c6008f2bb1e6489c06a612bcf8a37..b307144ff3e02d4c089586862fd156a4b255b995 100644 (file)
 ==================================================================== */\r
 package org.apache.poi.xslf;\r
 \r
-import java.io.ByteArrayInputStream;\r
-import java.io.ByteArrayOutputStream;\r
-import java.io.InputStream;\r
-\r
 import org.apache.poi.POIDataSamples;\r
 import org.apache.poi.openxml4j.opc.OPCPackage;\r
 import org.apache.poi.xslf.usermodel.XMLSlideShow;\r
 \r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.InputStream;\r
+\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
index f030f3b1013b985579e0293003156896eeb4f5f4..e2183a72465d8a44a932c1b933345b18afeb3359 100644 (file)
 ==================================================================== */
 package org.apache.poi.xslf.extractor;
 
+import junit.framework.TestCase;
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.xslf.XSLFSlideShow;
 
-import junit.framework.TestCase;
-
 /**
  * Tests for HXFPowerPointExtractor
  */
index 1168003c947b51cea0f2037eb1d76ade6010ab1b..47d2277712f963808b60b60a0edba8da605be496 100644 (file)
 package org.apache.poi.xslf.geom;
 
 import junit.framework.TestCase;
-import org.apache.poi.xslf.model.geom.*;
+import org.apache.poi.xslf.model.geom.Context;
+import org.apache.poi.xslf.model.geom.CustomGeometry;
+import org.apache.poi.xslf.model.geom.Formula;
+import org.apache.poi.xslf.model.geom.Guide;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTCustomGeometry2D;
 
 /**
index eefdd91b4182779a97972af1b923bd8fc4c8132e..7f5e967ccc964378ba3974770af778c0cd548272 100644 (file)
 package org.apache.poi.xslf.geom;
 
 import junit.framework.TestCase;
-import org.apache.poi.xslf.model.geom.*;
+import org.apache.poi.xslf.model.geom.Context;
+import org.apache.poi.xslf.model.geom.CustomGeometry;
+import org.apache.poi.xslf.model.geom.Guide;
+import org.apache.poi.xslf.model.geom.IAdjustableShape;
+import org.apache.poi.xslf.model.geom.Path;
+import org.apache.poi.xslf.model.geom.PresetGeometries;
 
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Rectangle2D;
index e522c375df8e7d0c07612b9b08a57956047e0143..0fc4b20aaa7f408647df0c850aa5df5f98519650 100644 (file)
 package org.apache.poi.xslf.usermodel;
 
 import junit.framework.TestCase;
-
 import org.apache.poi.POIDataSamples;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
-import org.apache.poi.xslf.usermodel.XMLSlideShow;
-import org.apache.poi.xslf.usermodel.XSLFRelation;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMasterIdListEntry;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideIdListEntry;
 import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMasterIdListEntry;
index d29cb30662afd2c12355ac505b4447fc9aa36423..0ca30a3b948fd39cc8dbd8aaf8369cfd9d342ce7 100755 (executable)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
 import org.apache.poi.util.Units;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextStrikeType;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index 108fca327b6b4424f2ef738123d9018674038e5b..a08faf0e38eb92f577cb317038fb88864330fd8c 100755 (executable)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STPresetColorVal;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;\r
 \r
-import java.awt.*;\r
+import java.awt.Color;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index dcfd479cc9f48ef173a35f640bea6bc9770b86d5..7ff45f5c8b4008bc70468c28ba81ed4a88d7bd4b 100644 (file)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
-import org.apache.poi.util.Units;\r
-import org.apache.poi.xslf.usermodel.LineCap;\r
-import org.apache.poi.xslf.usermodel.LineDash;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;\r
-\r
-import java.awt.*;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index f52cc83dde9fe262fcf0d5443432f93179443c35..f212abeae4db409abcd250009189a3ded8147c9a 100755 (executable)
@@ -18,7 +18,7 @@ package org.apache.poi.xslf.usermodel;
 \r
 import junit.framework.TestCase;\r
 \r
-import java.awt.*;\r
+import java.awt.Rectangle;\r
 import java.awt.geom.Ellipse2D;\r
 import java.awt.geom.GeneralPath;\r
 \r
index 13e8eb84d46b1992890a8f93fd5a63644e8a54c4..7f11ecc762be7df2b7d62e841ccdf197d90e7d61 100755 (executable)
@@ -18,7 +18,7 @@ package org.apache.poi.xslf.usermodel;
 \r
 import junit.framework.TestCase;\r
 \r
-import java.awt.*;\r
+import java.awt.Dimension;\r
 import java.awt.geom.Rectangle2D;\r
 \r
 /**\r
index fe968b0b7feff6fda639fe101041b739375d4527..33cf3225e71eccc372f57318b866a424e530f9ef 100644 (file)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
-import java.awt.*;\r
-import java.awt.geom.Ellipse2D;\r
-import java.awt.geom.GeneralPath;\r
-import java.util.*;\r
-import java.util.List;\r
-import java.net.URI;\r
-\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
-import org.apache.poi.xssf.usermodel.XSSFTable;\r
 import org.apache.poi.openxml4j.opc.PackageRelationship;\r
 import org.apache.poi.openxml4j.opc.TargetMode;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
+\r
+import java.net.URI;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index 9bd41025fbc98a4fe44695d757edbfbef23ac734..61692dba40bc34eed137f7c24849f675d71a0ea0 100644 (file)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
 \r
-import java.awt.*;\r
-import java.awt.geom.Ellipse2D;\r
-import java.awt.geom.GeneralPath;\r
-import java.util.*;\r
+import java.util.Arrays;\r
 import java.util.List;\r
 \r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
-\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
index ecdcdd032d19105a06a48cac62294413e20e3b18..e6c4728474321a642ee518415ec1539966e84e18 100755 (executable)
@@ -17,7 +17,6 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;\r
 \r
index 88af770fef1cee036b6f408be1d899ebecbc7afc..d605a051982fc28e7423679033230ec475d1b92c 100644 (file)
@@ -17,7 +17,6 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 \r
 /**\r
index e4d4d553b010599f7089f1331020dc5b323cb29d..f5839fd778b4fce77d08560f906e4720b62e832f 100644 (file)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
 import org.apache.poi.util.Units;\r
-import org.apache.poi.xslf.usermodel.LineCap;\r
-import org.apache.poi.xslf.usermodel.LineDash;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;\r
-import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;\r
 \r
-import java.awt.*;\r
+import java.awt.Color;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index d5e7c61c2bf40fe0a1da951845bc89c3f60e4bec..f658e6b555da1c75b467489fcc9fdce335c07002 100755 (executable)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
-import org.apache.poi.openxml4j.opc.PackagePart;\r
 \r
 import java.awt.Color;\r
-import java.util.List;\r
 import java.util.Arrays;\r
-import java.util.regex.Pattern;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index 46e10e45d8f1dd8475fc6d5c3e9b1e97498cdb6c..c3057d590fd5e47a3ee5112dd59a127de25eafe6 100755 (executable)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
+import org.apache.poi.POIXMLDocumentPart;\r
+import org.apache.poi.xslf.XSLFTestDataSamples;\r
 \r
 import java.awt.Dimension;\r
 import java.util.List;\r
 \r
-import org.apache.poi.POIXMLDocumentPart;\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
-\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
index a5cdb0d6ca02413fbc39ecc579e796d611d1502b..9a4144752ab6ec3035993ea1e6329500d3d51e36 100644 (file)
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
-import java.awt.*;\r
-import java.awt.geom.Ellipse2D;\r
-import java.awt.geom.GeneralPath;\r
-import java.util.*;\r
-import java.util.List;\r
-\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;\r
 \r
+import java.awt.Color;\r
+import java.util.List;\r
+\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
index d1ca86be34c346e0807dc3791adb5d19e9dffb97..0feff27d2596fef4575a4614c26c789bedebb4bb 100644 (file)
@@ -18,15 +18,6 @@ package org.apache.poi.xslf.usermodel;
 \r
 import junit.framework.TestCase;\r
 \r
-import java.awt.*;\r
-import java.awt.geom.Ellipse2D;\r
-import java.awt.geom.GeneralPath;\r
-import java.util.*;\r
-import java.util.List;\r
-\r
-import org.apache.poi.xslf.XSLFTestDataSamples;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;\r
-\r
 /**\r
  * @author Yegor Kozlov\r
  */\r
index c426fd15c0630edf0a7148cfc2a1ee8121232d32..6b9cf596e7a3e2347a2f7a9edf50f52dee99fc8a 100755 (executable)
@@ -2,13 +2,9 @@ package org.apache.poi.xslf.usermodel;
 \r
 import junit.framework.TestCase;\r
 \r
-import java.awt.Rectangle;\r
 import java.awt.Color;\r
+import java.awt.Rectangle;\r
 import java.awt.geom.Rectangle2D;\r
-import java.io.FileOutputStream;\r
-\r
-import org.apache.poi.xssf.dev.XSSFDump;\r
-import org.apache.poi.xslf.util.PPTX2PNG;\r
 \r
 /**\r
  * Created by IntelliJ IDEA.\r
index 6347b63ccfd3fab8f29faa64bc3aa7df3c332185..07e64de1eb6337bb772526b53269d907e305b3da 100644 (file)
@@ -18,11 +18,11 @@ package org.apache.poi.xslf.usermodel;
 \r
 import junit.framework.TestCase;\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
-import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBodyProperties;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;\r
+import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;\r
 \r
-import java.awt.*;\r
+import java.awt.Color;\r
 \r
 /**\r
  * @author Yegor Kozlov\r
index b01c25e1d5ef8ae25687d971b05f0dacfb00d4ee..650bfcd0cf24ef8789f7e2c79f4dc2c891280b60 100644 (file)
@@ -17,8 +17,6 @@
 package org.apache.poi.xslf.usermodel;\r
 \r
 import junit.framework.TestCase;\r
-\r
-\r
 import org.apache.poi.xslf.XSLFTestDataSamples;\r
 \r
 import java.awt.Color;\r