]> source.dussan.org Git - poi.git/commitdiff
#61169 - Text with Japanese characters overflows textbox
authorAndreas Beeker <kiwiwings@apache.org>
Sat, 17 Jun 2017 00:00:49 +0000 (00:00 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Sat, 17 Jun 2017 00:00:49 +0000 (00:00 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1798986 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/sl/draw/DrawTextFragment.java
src/java/org/apache/poi/sl/draw/DrawTextParagraph.java
src/java/org/apache/poi/sl/draw/DrawTextShape.java
src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFTextShape.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextShape.java

index 178983d5e12eeb36515260665bba47a5049d4949..0eceb93643c3844d7d87a524fbf686afc45bd9eb 100644 (file)
@@ -69,11 +69,20 @@ public class DrawTextFragment implements Drawable  {
     /**
      * @return full height of this text run which is sum of ascent, descent and leading
      */
-    public float getHeight(){
-        double h = Math.ceil(layout.getAscent()) + Math.ceil(layout.getDescent()) + layout.getLeading();
+    public float getHeight(){ 
+        double h = Math.ceil(layout.getAscent()) + Math.ceil(layout.getDescent()) + getLeading();
         return (float)h;
     }
 
+    /**
+     * @return the leading height before/after a text line
+     */
+    public float getLeading() {
+        // fix invalid leadings (leading == 0) by fallback to descent
+        double l = layout.getLeading();
+        return (float)(l == 0 ? layout.getDescent() : l);
+    }
+    
     /**
      *
      * @return width if this text run
index d978b3c371f8528e11c73cba23427b6b508e8315..10d4edfd6283f29ebe6c9e541bf5090e7db06e84 100644 (file)
@@ -215,6 +215,10 @@ public class DrawTextParagraph implements Drawable {
         y = penY - y;
     }
 
+    public float getFirstLineLeading() {
+        return (lines.isEmpty()) ? 0 : lines.get(0).getLeading();
+    }
+
     public float getFirstLineHeight() {
         return (lines.isEmpty()) ? 0 : lines.get(0).getHeight();
     }
@@ -253,7 +257,8 @@ public class DrawTextParagraph implements Drawable {
         for (;;) {
             int startIndex = measurer.getPosition();
 
-            double wrappingWidth = getWrappingWidth(lines.size() == 0, graphics) + 1; // add a pixel to compensate rounding errors
+            // add a pixel to compensate rounding errors
+            double wrappingWidth = getWrappingWidth(lines.isEmpty(), graphics) + 1;
             // shape width can be smaller that the sum of insets (this was proved by a test file)
             if(wrappingWidth < 0) {
                 wrappingWidth = 1;
index 89f85a2f02b2fd3e26cf20658302c3ad2f3b309c..cffffb4a88ad8c671006d9d9b12db254cd7882a2 100644 (file)
@@ -137,10 +137,7 @@ public class DrawTextShape extends DrawSimpleShape {
         DrawFactory fact = DrawFactory.getInstance(graphics);
 
         double y0 = y;
-        //noinspection RedundantCast
-        @SuppressWarnings("cast")
-        Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs =
-            (Iterator<? extends TextParagraph<?,?,? extends TextRun>>) getShape().iterator();
+        Iterator<? extends TextParagraph<?,?,? extends TextRun>> paragraphs = getShape().iterator();
         
         boolean isFirstLine = true;
         for (int autoNbrIdx=0; paragraphs.hasNext(); autoNbrIdx++){
@@ -158,7 +155,9 @@ public class DrawTextShape extends DrawSimpleShape {
             dp.setAutoNumberingIdx(autoNbrIdx);
             dp.breakText(graphics);
 
-            if (!isFirstLine) {
+            if (isFirstLine) {
+                y += dp.getFirstLineLeading();
+            } else {
                 // the amount of vertical white space before the paragraph
                 Double spaceBefore = p.getSpaceBefore();
                 if (spaceBefore == null) spaceBefore = 0d;
@@ -221,7 +220,7 @@ public class DrawTextShape extends DrawSimpleShape {
     }
     
     @Override
-    protected TextShape<?,?> getShape() {
-        return (TextShape<?,?>)shape;
+    protected TextShape<?,? extends TextParagraph<?,?,? extends TextRun>> getShape() {
+        return (TextShape<?,? extends TextParagraph<?,?,? extends TextRun>>)shape;
     }
 }
index 91b0869b89cd02d3a115eccc1a443481f07b8423..ad979f1d6d412a36f00a76d8e5d14f30c48e56d1 100644 (file)
@@ -67,6 +67,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
         }
     }
 
+    @Override
     public Iterator<XSLFTextParagraph> iterator(){
         return getTextParagraphs().iterator();
     }
@@ -75,7 +76,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public String getText() {
         StringBuilder out = new StringBuilder();
         for (XSLFTextParagraph p : _paragraphs) {
-            if (out.length() > 0) out.append('\n');
+            if (out.length() > 0) {
+                out.append('\n');
+            }
             out.append(p.getText());
         }
         return out.toString();
@@ -109,7 +112,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
 
     @Override
     public XSLFTextRun appendText(String text, boolean newParagraph) {
-        if (text == null) return null;
+        if (text == null) {
+            return null;
+        }
 
         // copy properties from last paragraph / textrun or paragraph end marker
         CTTextParagraphProperties otherPPr = null;
@@ -202,7 +207,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
              if(anchor == null) {
-                if(bodyPr.isSetAnchor()) bodyPr.unsetAnchor();
+                if(bodyPr.isSetAnchor()) {
+                    bodyPr.unsetAnchor();
+                }
             } else {
                 bodyPr.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
             }
@@ -212,6 +219,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     @Override
     public VerticalAlignment getVerticalAlignment(){
         PropertyFetcher<VerticalAlignment> fetcher = new TextBodyPropertyFetcher<VerticalAlignment>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                 if(props.isSetAnchor()){
                     int val = props.getAnchor().intValue();
@@ -230,7 +238,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
              if (isCentered == null) {
-                if (bodyPr.isSetAnchorCtr()) bodyPr.unsetAnchorCtr();
+                if (bodyPr.isSetAnchorCtr()) {
+                    bodyPr.unsetAnchorCtr();
+                }
             } else {
                 bodyPr.setAnchorCtr(isCentered);
             }
@@ -240,6 +250,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     @Override
     public boolean isHorizontalCentered(){
         PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                 if(props.isSetAnchorCtr()){
                     setValue(props.getAnchorCtr());
@@ -257,7 +268,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
             if(orientation == null) {
-                if(bodyPr.isSetVert()) bodyPr.unsetVert();
+                if(bodyPr.isSetVert()) {
+                    bodyPr.unsetVert();
+                }
             } else {
                 bodyPr.setVert(STTextVerticalType.Enum.forInt(orientation.ordinal() + 1));
             }
@@ -315,6 +328,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      */
     public double getBottomInset(){
         PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                 if(props.isSetBIns()){
                     double val = Units.toPoints(props.getBIns());
@@ -338,6 +352,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      */
     public double getLeftInset(){
         PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                 if(props.isSetLIns()){
                     double val = Units.toPoints(props.getLIns());
@@ -361,6 +376,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      */
     public double getRightInset(){
         PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                 if(props.isSetRIns()){
                     double val = Units.toPoints(props.getRIns());
@@ -383,6 +399,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      */
     public double getTopInset(){
         PropertyFetcher<Double> fetcher = new TextBodyPropertyFetcher<Double>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                 if(props.isSetTIns()){
                     double val = Units.toPoints(props.getTIns());
@@ -406,8 +423,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public void setBottomInset(double margin){
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
-            if(margin == -1) bodyPr.unsetBIns();
-            else bodyPr.setBIns(Units.toEMU(margin));
+            if(margin == -1) {
+                bodyPr.unsetBIns();
+            } else {
+                bodyPr.setBIns(Units.toEMU(margin));
+            }
         }
     }
 
@@ -420,8 +440,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public void setLeftInset(double margin){
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
-            if(margin == -1) bodyPr.unsetLIns();
-            else bodyPr.setLIns(Units.toEMU(margin));
+            if(margin == -1) {
+                bodyPr.unsetLIns();
+            } else {
+                bodyPr.setLIns(Units.toEMU(margin));
+            }
         }
     }
 
@@ -434,8 +457,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public void setRightInset(double margin){
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
-            if(margin == -1) bodyPr.unsetRIns();
-            else bodyPr.setRIns(Units.toEMU(margin));
+            if(margin == -1) {
+                bodyPr.unsetRIns();
+            } else {
+                bodyPr.setRIns(Units.toEMU(margin));
+            }
         }
     }
 
@@ -448,8 +474,11 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public void setTopInset(double margin){
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
-            if(margin == -1) bodyPr.unsetTIns();
-            else bodyPr.setTIns(Units.toEMU(margin));
+            if(margin == -1) {
+                bodyPr.unsetTIns();
+            } else {
+                bodyPr.setTIns(Units.toEMU(margin));
+            }
         }
     }
 
@@ -470,6 +499,7 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     @Override
     public boolean getWordWrap(){
         PropertyFetcher<Boolean> fetcher = new TextBodyPropertyFetcher<Boolean>(){
+            @Override
             public boolean fetch(CTTextBodyProperties props){
                if(props.isSetWrap()){
                     setValue(props.getWrap() == STTextWrappingType.SQUARE);
@@ -500,9 +530,15 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public void setTextAutofit(TextAutofit value){
         CTTextBodyProperties bodyPr = getTextBodyPr(true);
         if (bodyPr != null) {
-            if(bodyPr.isSetSpAutoFit()) bodyPr.unsetSpAutoFit();
-            if(bodyPr.isSetNoAutofit()) bodyPr.unsetNoAutofit();
-            if(bodyPr.isSetNormAutofit()) bodyPr.unsetNormAutofit();
+            if(bodyPr.isSetSpAutoFit()) {
+                bodyPr.unsetSpAutoFit();
+            }
+            if(bodyPr.isSetNoAutofit()) {
+                bodyPr.unsetNoAutofit();
+            }
+            if(bodyPr.isSetNormAutofit()) {
+                bodyPr.unsetNormAutofit();
+            }
 
             switch(value){
                 case NONE: bodyPr.addNewNoAutofit(); break;
@@ -519,9 +555,13 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     public TextAutofit getTextAutofit(){
         CTTextBodyProperties bodyPr = getTextBodyPr();
         if (bodyPr != null) {
-            if(bodyPr.isSetNoAutofit()) return TextAutofit.NONE;
-            else if (bodyPr.isSetNormAutofit()) return TextAutofit.NORMAL;
-            else if (bodyPr.isSetSpAutoFit()) return TextAutofit.SHAPE;
+            if(bodyPr.isSetNoAutofit()) {
+                return TextAutofit.NONE;
+            } else if (bodyPr.isSetNormAutofit()) {
+                return TextAutofit.NORMAL;
+            } else if (bodyPr.isSetSpAutoFit()) {
+                return TextAutofit.SHAPE;
+            }
         }
         return TextAutofit.NORMAL;
     }
@@ -551,7 +591,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
 
     public Placeholder getTextType(){
         CTPlaceholder ph = getCTPlaceholder();
-        if (ph == null) return null;
+        if (ph == null) {
+            return null;
+        }
 
         int val = ph.getType().intValue();
         return Placeholder.lookupOoxml(val);
@@ -571,12 +613,15 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      */
     public Rectangle2D resizeToFitText(){
         Rectangle2D anchor = getAnchor();
-        if(anchor.getWidth() == 0.)  throw new POIXMLException(
-                "Anchor of the shape was not set.");
+
+        if(anchor.getWidth() == 0.) {
+            throw new POIXMLException("Anchor of the shape was not set.");
+        }
         double height = getTextHeight();
         height += 1; // add a pixel to compensate rounding errors
 
-        anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height);
+        Insets2D insets = getInsets();
+        anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height+insets.top+insets.bottom);
         setAnchor(anchor);
 
         return anchor;
@@ -596,7 +641,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
 
         thisTB.setBodyPr((CTTextBodyProperties)otherTB.getBodyPr().copy());
 
-        if (thisTB.isSetLstStyle()) thisTB.unsetLstStyle();
+        if (thisTB.isSetLstStyle()) {
+            thisTB.unsetLstStyle();
+        }
         if (otherTB.isSetLstStyle()) {
             thisTB.setLstStyle((CTTextListStyle)otherTB.getLstStyle().copy());
         }
@@ -665,7 +712,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
     @Override
     public TextPlaceholder getTextPlaceholder() {
         Placeholder ph = getTextType();
-        if (ph == null) return TextPlaceholder.BODY;
+        if (ph == null) {
+            return TextPlaceholder.BODY;
+        }
         switch (ph) {
         case BODY: return TextPlaceholder.BODY;
         case TITLE: return TextPlaceholder.TITLE;
@@ -679,9 +728,9 @@ public abstract class XSLFTextShape extends XSLFSimpleShape
      * Helper method to allow subclasses to provide their own text paragraph
      *
      * @param p the xml reference
-     * 
+     *
      * @return a new text paragraph
-     * 
+     *
      * @since POI 3.15-beta2
      */
     protected XSLFTextParagraph newTextParagraph(CTTextParagraph p) {
index d7b4e2773465db492f82ff571dd7c191dc1b0d4b..96cea8034977036e9607f207bc3dfba342c6c534 100644 (file)
@@ -329,7 +329,8 @@ implements TextShape<HSLFShape,HSLFTextParagraph> {
         double height = getTextHeight();
         height += 1; // add a pixel to compensate rounding errors
 
-        anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height);
+        Insets2D insets = getInsets();
+        anchor.setRect(anchor.getX(), anchor.getY(), anchor.getWidth(), height+insets.top+insets.bottom);
         setAnchor(anchor);
 
         return anchor;