#59004 - HSLF rendering - adjust values for presetShapeDefinition differs in HSLF/XSLF

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1859102 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2019-05-10 20:55:24 +00:00
parent 4e663c4b5d
commit 049baa86d7
3 changed files with 57 additions and 93 deletions

View File

@ -316,7 +316,7 @@ public class DrawSimpleShape extends DrawShape {
Color shadowColor = DrawPaint.applyColorTransform(shadowPaint.getSolidColor());
double shapeRotation = getShape().getRotation();
if(getShape().getFlipVertical()) {
if (getShape().getFlipVertical()) {
shapeRotation += 180;
}
double angle = shadow.getAngle() - shapeRotation;
@ -326,13 +326,13 @@ public class DrawSimpleShape extends DrawShape {
graphics.translate(dx, dy);
for(Outline o : outlines){
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()){
if (fill != null && p.isFilled()) {
fillPaintWorkaround(graphics, s);
} else if (line != null && p.isStroked()) {
graphics.draw(s);
@ -342,65 +342,6 @@ public class DrawSimpleShape extends DrawShape {
graphics.translate(-dx, -dy);
}
protected static CustomGeometry getCustomGeometry(String name) {
return getCustomGeometry(name, null);
}
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);
if (presets == null) {
presets = new HashMap<>();
if (graphics != null) {
graphics.setRenderingHint(Drawable.PRESET_GEOMETRY_CACHE, presets);
}
String packageName = "org.apache.poi.sl.draw.binding";
InputStream presetIS = Drawable.class.getResourceAsStream("presetShapeDefinitions.xml");
// 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));
}
staxFiltRd.close();
staxReader.close();
} catch (Exception e) {
throw new RuntimeException("Unable to load preset geometries.", e);
} finally {
IOUtils.closeQuietly(presetIS);
}
}
return presets.get(name);
}
protected Collection<Outline> computeOutlines(Graphics2D graphics) {
final SimpleShape<?,?> sh = getShape();

View 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){

View 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