]> source.dussan.org Git - poi.git/commitdiff
#59004 - HSLF rendering - adjust values for presetShapeDefinition differs in HSLF...
authorAndreas Beeker <kiwiwings@apache.org>
Fri, 10 May 2019 20:55:24 +0000 (20:55 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Fri, 10 May 2019 20:55:24 +0000 (20:55 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1859102 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/sl/draw/DrawSimpleShape.java
src/java/org/apache/poi/sl/draw/geom/Context.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java

index eacc6ed80666b1652b6edf9ce406f75938ee9154..d535d71fa6615b5d868458efcd9f0b3d302ee60e 100644 (file)
@@ -307,98 +307,39 @@ public class DrawSimpleShape extends DrawShape {
       , Paint fill
       , Paint line
     ) {
-          Shadow<?,?> shadow = getShape().getShadow();
-          if (shadow == null || (fill == null && line == null)) {
-              return;
-          }
-
-          SolidPaint shadowPaint = shadow.getFillStyle();
-          Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor());
-
-          double shapeRotation = getShape().getRotation();
-          if(getShape().getFlipVertical()) {
-              shapeRotation += 180;
-          }
-          double angle = shadow.getAngle() - shapeRotation;
-          double dist = shadow.getDistance();
-          double dx = dist * Math.cos(Math.toRadians(angle));
-          double dy = dist * Math.sin(Math.toRadians(angle));
-
-          graphics.translate(dx, dy);
-
-          for(Outline o : outlines){
-              java.awt.Shape s = o.getOutline();
-              Path p = o.getPath();
-              graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
-              graphics.setPaint(shadowColor);
-
-              if(fill != null && p.isFilled()){
-                  fillPaintWorkaround(graphics, s);
-              } else if (line != null && p.isStroked()) {
-                  graphics.draw(s);
-              }
-          }
-
-          graphics.translate(-dx, -dy);
-      }
-
-    protected static CustomGeometry getCustomGeometry(String name) {
-        return getCustomGeometry(name, null);
-    }
+        Shadow<?,?> shadow = getShape().getShadow();
+        if (shadow == null || (fill == null && line == null)) {
+            return;
+        }
 
-    protected static CustomGeometry getCustomGeometry(String name, Graphics2D graphics) {
-        @SuppressWarnings("unchecked")
-        Map<String, CustomGeometry> presets = (graphics == null)
-            ? null
-            : (Map<String, CustomGeometry>)graphics.getRenderingHint(Drawable.PRESET_GEOMETRY_CACHE);
+        SolidPaint shadowPaint = shadow.getFillStyle();
+        Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor());
 
-        if (presets == null) {
-            presets = new HashMap<>();
-            if (graphics != null) {
-                graphics.setRenderingHint(Drawable.PRESET_GEOMETRY_CACHE, presets);
-            }
+        double shapeRotation = getShape().getRotation();
+        if (getShape().getFlipVertical()) {
+            shapeRotation += 180;
+        }
+        double angle = shadow.getAngle() - shapeRotation;
+        double dist = shadow.getDistance();
+        double dx = dist * Math.cos(Math.toRadians(angle));
+        double dy = dist * Math.sin(Math.toRadians(angle));
 
-            String packageName = "org.apache.poi.sl.draw.binding";
-            InputStream presetIS = Drawable.class.getResourceAsStream("presetShapeDefinitions.xml");
+        graphics.translate(dx, dy);
 
-            // StAX:
-            EventFilter startElementFilter = new EventFilter() {
-                @Override
-                public boolean accept(XMLEvent event) {
-                    return event.isStartElement();
-                }
-            };
-
-            try {
-                XMLInputFactory staxFactory = StaxHelper.newXMLInputFactory();
-                XMLEventReader staxReader = staxFactory.createXMLEventReader(presetIS);
-                XMLEventReader staxFiltRd = staxFactory.createFilteredReader(staxReader, startElementFilter);
-                // Ignore StartElement:
-                staxFiltRd.nextEvent();
-                // JAXB:
-                JAXBContext jaxbContext = JAXBContext.newInstance(packageName);
-                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
-
-                while (staxFiltRd.peek() != null) {
-                    StartElement evRoot = (StartElement)staxFiltRd.peek();
-                    String cusName = evRoot.getName().getLocalPart();
-                    // XMLEvent ev = staxReader.nextEvent();
-                    JAXBElement<org.apache.poi.sl.draw.binding.CTCustomGeometry2D> el = unmarshaller.unmarshal(staxReader, CTCustomGeometry2D.class);
-                    CTCustomGeometry2D cusGeom = el.getValue();
-
-                    presets.put(cusName, new CustomGeometry(cusGeom));
-                }
+        for (Outline o : outlines) {
+            java.awt.Shape s = o.getOutline();
+            Path p = o.getPath();
+            graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, s);
+            graphics.setPaint(shadowColor);
 
-                staxFiltRd.close();
-                staxReader.close();
-            } catch (Exception e) {
-                throw new RuntimeException("Unable to load preset geometries.", e);
-            } finally {
-                IOUtils.closeQuietly(presetIS);
+            if (fill != null && p.isFilled()) {
+                fillPaintWorkaround(graphics, s);
+            } else if (line != null && p.isStroked()) {
+                graphics.draw(s);
             }
         }
 
-        return presets.get(name);
+        graphics.translate(-dx, -dy);
     }
 
     protected Collection<Outline> computeOutlines(Graphics2D graphics) {
index 3ed84b3d184dcc923773fb72ec25b3d0b95084ab..3ac449592941dea0b7bf56f49c3f2dd1c0ed596f 100644 (file)
@@ -51,8 +51,7 @@ public class Context {
     }
 
     Guide getAdjustValue(String name){
-        // ignore HSLF props for now ... the results with default value are usually better - see #59004
-        return (_props.getClass().getName().contains("hslf")) ? null : _props.getAdjustValue(name);
+        return _props.getAdjustValue(name);
     }
 
     public double getValue(String key){
index acabc68715ca10d9a00c54e65285675eb42e3451..55d3932d0224d54fe7189a6452c31c1ea2edbfa5 100644 (file)
@@ -321,8 +321,10 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
             name = "1";
         }
 
+        final int adjInt = Integer.parseInt(name);
+
         short escherProp;
-        switch (Integer.parseInt(name)) {
+        switch (adjInt) {
             case 1: escherProp = EscherProperties.GEOMETRY__ADJUSTVALUE; break;
             case 2: escherProp = EscherProperties.GEOMETRY__ADJUST2VALUE; break;
             case 3: escherProp = EscherProperties.GEOMETRY__ADJUST3VALUE; break;
@@ -336,14 +338,36 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
             default: throw new HSLFException();
         }
 
-        // TODO: the adjust values need to be corrected somehow depending on the shape width/height
-        // see https://social.msdn.microsoft.com/Forums/en-US/3f69ebb3-62a0-4fdd-b367-64790dfb2491/presetshapedefinitionsxml-does-not-specify-width-and-height-form-some-autoshapes?forum=os_binaryfile
-        
-        // the adjust value can be format dependent, e.g. hexagon has different values,
-        // other shape types have the same adjust values in OOXML and native
         int adjval = getEscherProperty(escherProp, -1);
 
-        return (adjval == -1) ? null : new Guide(name, "val "+adjval);
+        if (adjval == -1) {
+            return null;
+        }
+
+        // Bug 59004
+        // the adjust value are format dependent, we scale them up so they match the OOXML ones.
+        // see https://social.msdn.microsoft.com/Forums/en-US/33e458e6-58df-48fe-9a10-e303ab08991d/preset-shapes-for-ppt?forum=os_binaryfile
+
+        // usually we deal with length units and only very few degree units:
+        boolean isDegreeUnit = false;
+        switch (getShapeType()) {
+            case ARC:
+            case BLOCK_ARC:
+            case CHORD:
+            case PIE:
+                isDegreeUnit = (adjInt == 1 || adjInt == 2);
+                break;
+            case CIRCULAR_ARROW:
+            case LEFT_CIRCULAR_ARROW:
+            case LEFT_RIGHT_CIRCULAR_ARROW:
+                isDegreeUnit = (adjInt == 2 || adjInt == 3 || adjInt == 4);
+                break;
+            case MATH_NOT_EQUAL:
+                isDegreeUnit = (adjInt == 2);
+                break;
+        }
+
+        return new Guide(name, "val "+Math.rint(adjval * (isDegreeUnit ? 65536. : 100000./21000.)));
     }
 
     @Override