You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2016/02/24 23:43:52 UTC
svn commit: r1732236 [2/2] - in /poi/trunk/src:
integrationtest/org/apache/poi/stress/ java/org/apache/poi/ddf/
java/org/apache/poi/sl/draw/ java/org/apache/poi/sl/draw/geom/
java/org/apache/poi/sl/usermodel/ ooxml/java/org/apache/poi/xslf/usermodel/
o...
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFHyperlink.java Wed Feb 24 22:43:51 2016
@@ -363,6 +363,9 @@ public final class HSLFHyperlink impleme
InteractiveInfo hldr = (InteractiveInfo)r;
InteractiveInfoAtom info = hldr.getInteractiveInfoAtom();
+ if (info == null) {
+ continue;
+ }
int id = info.getHyperlinkID();
ExHyperlink exHyper = exobj.get(id);
if (exHyper == null) {
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFPictureShape.java Wed Feb 24 22:43:51 2016
@@ -209,6 +209,13 @@ public class HSLFPictureShape extends HS
? null
: new Insets((int)(top*100000), (int)(left*100000), (int)(bottom*100000), (int)(right*100000));
}
+
+ @Override
+ public ShapeType getShapeType() {
+ // this is kind of a hack, as picture/ole shapes can have a shape type of "frame"
+ // but rendering is handled like a rectangle
+ return ShapeType.RECT;
+ }
/**
* @return the fractional property or 0 if not defined
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShape.java Wed Feb 24 22:43:51 2016
@@ -346,7 +346,13 @@ public abstract class HSLFShape implemen
int val = (p == null) ? defaultColor : p.getPropertyValue();
EscherColorRef ecr = new EscherColorRef(val);
-
+ Color col = getColor(ecr);
+
+ double alpha = getAlpha(opacityProperty);
+ return new Color(col.getRed(), col.getGreen(), col.getBlue(), (int)(alpha*255.0));
+ }
+
+ Color getColor(EscherColorRef ecr) {
boolean fPaletteIndex = ecr.hasPaletteIndexFlag();
boolean fPaletteRGB = ecr.hasPaletteRGBFlag();
boolean fSystemRGB = ecr.hasSystemRGBFlag();
@@ -373,11 +379,10 @@ public abstract class HSLFShape implemen
} else if (fSysIndex){
//TODO
}
-
- double alpha = getAlpha(opacityProperty);
- return new Color(rgb[0], rgb[1], rgb[2], (int)(alpha*255.0));
+
+ return new Color(rgb[0], rgb[1], rgb[2]);
}
-
+
double getAlpha(short opacityProperty) {
AbstractEscherOptRecord opt = getEscherOptRecord();
EscherSimpleProperty op = getEscherProperty(opt, opacityProperty);
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFShapeFactory.java Wed Feb 24 22:43:51 2016
@@ -111,8 +111,15 @@ public final class HSLFShapeFactory {
shape = createNonPrimitive(spContainer, parent);
break;
default:
- EscherTextboxRecord etr = spContainer.getChildById(EscherTextboxRecord.RECORD_ID);
- if (parent instanceof HSLFTable && etr != null) {
+ if (parent instanceof HSLFTable) {
+ EscherTextboxRecord etr = spContainer.getChildById(EscherTextboxRecord.RECORD_ID);
+ if (etr == null) {
+ logger.log(POILogger.WARN, "invalid ppt - add EscherTextboxRecord to cell");
+ etr = new EscherTextboxRecord();
+ etr.setRecordId(EscherTextboxRecord.RECORD_ID);
+ etr.setOptions((short)15);
+ spContainer.addChildRecord(etr);
+ }
shape = new HSLFTableCell(spContainer, (HSLFTable)parent);
} else {
shape = new HSLFAutoShape(spContainer, parent);
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java Wed Feb 24 22:43:51 2016
@@ -275,7 +275,8 @@ public abstract class HSLFSimpleShape ex
public Guide getAdjustValue(String name) {
if (name == null || !name.matches("adj([1-9]|10)?")) {
- throw new IllegalArgumentException("Adjust value '"+name+"' not supported.");
+ logger.log(POILogger.INFO, "Adjust value '"+name+"' not supported. Using default value.");
+ return null;
}
name = name.replace("adj", "");
@@ -296,7 +297,13 @@ public abstract class HSLFSimpleShape ex
default: throw new RuntimeException();
}
+ // 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);
}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFTextParagraph.java Wed Feb 24 22:43:51 2016
@@ -717,9 +717,25 @@ public final class HSLFTextParagraph imp
String propNames[] = propName.split(",");
for (String pn : propNames) {
TextProp prop = props.findByName(pn);
- if (prop != null) return prop;
- }
+ if (prop == null) {
+ continue;
+ }
+ // Font properties (maybe other too???) can have an index of -1
+ // so we check the master for this font index then
+ if (pn.contains("font") && prop.getValue() == -1) {
+ return getMasterPropVal(props, pn, paragraph);
+ }
+
+ return prop;
+ }
+
+ return getMasterPropVal(props, propName, paragraph);
+ }
+
+ private static TextProp getMasterPropVal(TextPropCollection props, String propName, HSLFTextParagraph paragraph) {
+ String propNames[] = propName.split(",");
+
BitMaskTextProp maskProp = (BitMaskTextProp) props.findByName(ParagraphFlagsTextProp.NAME);
boolean hardAttribute = (maskProp != null && maskProp.getValue() == 0);
if (hardAttribute) return null;
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java Wed Feb 24 22:43:51 2016
@@ -115,6 +115,9 @@ public class HwmfDrawProperties {
}
public void setViewportOrg(double x, double y) {
+ if (viewport == null) {
+ viewport = (Rectangle2D)window.clone();
+ }
double w = viewport.getWidth();
double h = viewport.getHeight();
viewport.setRect(x, y, w, h);
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java Wed Feb 24 22:43:51 2016
@@ -27,7 +27,6 @@ import java.awt.Shape;
import java.awt.TexturePaint;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
-import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.text.AttributedString;
@@ -35,6 +34,7 @@ import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
+import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.poi.hwmf.record.HwmfBrushStyle;
@@ -45,6 +45,9 @@ import org.apache.poi.hwmf.record.HwmfMi
import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
import org.apache.poi.hwmf.record.HwmfPenStyle;
import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
+import org.apache.poi.sl.draw.DrawFactory;
+import org.apache.poi.sl.draw.DrawFontManager;
+import org.apache.poi.sl.draw.Drawable;
public class HwmfGraphics {
private final Graphics2D graphicsCtx;
@@ -65,6 +68,7 @@ public class HwmfGraphics {
this.graphicsCtx = graphicsCtx;
this.bbox = (Rectangle2D)bbox.clone();
this.initialAT = graphicsCtx.getTransform();
+ DrawFactory.getInstance(graphicsCtx).fixFonts(graphicsCtx);
}
public HwmfDrawProperties getProperties() {
@@ -96,8 +100,8 @@ public class HwmfGraphics {
public void fill(Shape shape) {
if (prop.getBrushStyle() != HwmfBrushStyle.BS_NULL) {
- GeneralPath gp = new GeneralPath(shape);
- gp.setWindingRule(prop.getPolyfillMode().awtFlag);
+// GeneralPath gp = new GeneralPath(shape);
+// gp.setWindingRule(prop.getPolyfillMode().awtFlag);
graphicsCtx.setPaint(getFill());
graphicsCtx.fill(shape);
}
@@ -111,7 +115,12 @@ public class HwmfGraphics {
if (view == null) {
view = win;
}
- float width = (float)(prop.getPenWidth() * view.getWidth() / win.getWidth());
+
+ // TODO: fix line width calculation
+ float width = (float)prop.getPenWidth();
+ if (width == 0) {
+ width = 1;
+ }
HwmfPenStyle ps = prop.getPenStyle();
int cap = ps.getLineCap().awtFlag;
int join = ps.getLineJoin().awtFlag;
@@ -261,6 +270,10 @@ public class HwmfGraphics {
}
stackIndex = curIdx + index;
}
+ if (stackIndex == -1) {
+ // roll to last when curIdx == 0
+ stackIndex = propStack.size()-1;
+ }
prop = propStack.get(stackIndex);
}
@@ -306,34 +319,47 @@ public class HwmfGraphics {
}
public void drawString(String text, Rectangle2D bounds) {
+ drawString(text, bounds, null);
+ }
+
+ public void drawString(String text, Rectangle2D bounds, int dx[]) {
HwmfFont font = prop.getFont();
- if (font == null) {
+ if (font == null || text == null || text.isEmpty()) {
return;
}
+
+ double fontH = getFontHeight(font);
+ // TODO: another approx. ...
+ double fontW = fontH/1.8;
+
+ int len = text.length();
AttributedString as = new AttributedString(text);
- as.addAttribute(TextAttribute.FAMILY, font.getFacename());
- // TODO: fix font height calculation
- as.addAttribute(TextAttribute.SIZE, Math.abs(font.getHeight()));
- as.addAttribute(TextAttribute.STRIKETHROUGH, font.isStrikeOut());
- if (font.isUnderline()) {
- as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
- }
- if (font.isItalic()) {
- as.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+ if (dx == null || dx.length == 0) {
+ addAttributes(as, font, 0, len);
+ } else {
+ for (int i=0; i<len; i++) {
+ addAttributes(as, font, i, i+1);
+ // Tracking works as a prefix/advance space on characters whereas
+ // dx[...] is the complete width of the current char
+ // therefore we need to add the additional/suffix width to the next char
+ if (i<len-1) {
+ as.addAttribute(TextAttribute.TRACKING, (dx[i]-fontW)/fontH, i+1, i+2);
+ }
+ }
}
- as.addAttribute(TextAttribute.WEIGHT, font.getWeight());
+
double angle = Math.toRadians(-font.getEscapement()/10.);
final AffineTransform at = graphicsCtx.getTransform();
try {
- graphicsCtx.translate(bounds.getX(), bounds.getY());
+ graphicsCtx.translate(bounds.getX(), bounds.getY()+fontH);
graphicsCtx.rotate(angle);
if (prop.getBkMode() == HwmfBkMode.OPAQUE) {
// TODO: validate bounds
graphicsCtx.setBackground(prop.getBackgroundColor().getColor());
- graphicsCtx.fill(bounds);
+ graphicsCtx.fill(new Rectangle2D.Double(0, 0, bounds.getWidth(), bounds.getHeight()));
}
graphicsCtx.setColor(prop.getTextColor().getColor());
graphicsCtx.drawString(as.getIterator(), 0, 0); // (float)bounds.getX(), (float)bounds.getY());
@@ -341,4 +367,46 @@ public class HwmfGraphics {
graphicsCtx.setTransform(at);
}
}
+
+ private void addAttributes(AttributedString as, HwmfFont font, int start, int end) {
+ DrawFontManager fontHandler = (DrawFontManager)graphicsCtx.getRenderingHint(Drawable.FONT_HANDLER);
+ String fontFamily = null;
+ @SuppressWarnings("unchecked")
+ Map<String,String> fontMap = (Map<String,String>)graphicsCtx.getRenderingHint(Drawable.FONT_MAP);
+ if (fontMap != null && fontMap.containsKey(font.getFacename())) {
+ fontFamily = fontMap.get(font.getFacename());
+ }
+ if (fontHandler != null) {
+ fontFamily = fontHandler.getRendererableFont(font.getFacename(), font.getPitchAndFamily());
+ }
+ if (fontFamily == null) {
+ fontFamily = font.getFacename();
+ }
+
+ as.addAttribute(TextAttribute.FAMILY, fontFamily);
+ as.addAttribute(TextAttribute.SIZE, getFontHeight(font));
+ as.addAttribute(TextAttribute.STRIKETHROUGH, font.isStrikeOut());
+ if (font.isUnderline()) {
+ as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+ }
+ if (font.isItalic()) {
+ as.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+ }
+ as.addAttribute(TextAttribute.WEIGHT, font.getWeight());
+ }
+
+ private double getFontHeight(HwmfFont font) {
+ // see HwmfFont#height for details
+ double fontHeight = font.getHeight();
+ if (fontHeight == 0) {
+ return 12;
+ } else if (fontHeight < 0) {
+ return -fontHeight;
+ } else {
+ // TODO: fix font height calculation
+ // the height is given as font size + ascent + descent
+ // as an approximation we reduce the height by a static factor
+ return fontHeight*3/4;
+ }
+ }
}
Added: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBinaryRasterOp.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBinaryRasterOp.java?rev=1732236&view=auto
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBinaryRasterOp.java (added)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBinaryRasterOp.java Wed Feb 24 22:43:51 2016
@@ -0,0 +1,112 @@
+/* ====================================================================
+ 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.hwmf.record;
+
+/**
+ * The BinaryRasterOperation Enumeration section lists the binary raster-operation codes.
+ * Rasteroperation codes define how metafile processing combines the bits from the selected
+ * pen with the bits in the destination bitmap.
+ *
+ * Each raster-operation code represents a Boolean operation in which the values of the pixels in the
+ * selected pen and the destination bitmap are combined. Following are the two operands used in these
+ * operations.
+ *
+ * <table>
+ * <tr><th>Operand</th><th>Meaning</th></tr>
+ * <tr><td>P</td><td>Selected pen</td></tr>
+ * <tr><td>D</td><td>Destination bitmap</td></tr>
+ * </table>
+ *
+ * Following are the Boolean operators used in these operations.
+ * <table>
+ * <tr><th>Operand</th><th>Meaning</th></tr>
+ * <tr><td>a</td><td>Bitwise AND</td></tr>
+ * <tr><td>n</td><td>Bitwise NOT (inverse)</td></tr>
+ * <tr><td>o</td><td>Bitwise OR</td></tr>
+ * <tr><td>x</td><td>Bitwise exclusive OR (XOR)</td></tr>
+ * </table>
+ *
+ * All Boolean operations are presented in reverse Polish notation. For example, the following
+ * operation replaces the values of the pixels in the destination bitmap with a combination of the pixel
+ * values of the pen and the selected brush: DPo.
+ *
+ * Each raster-operation code is a 32-bit integer whose high-order word is a Boolean operation index and
+ * whose low-order word is the operation code. The 16-bit operation index is a zero-extended, 8-bit
+ * value that represents all possible outcomes resulting from the Boolean operation on two parameters
+ * (in this case, the pen and destination values). For example, the operation indexes for the DPo and
+ * DPan operations are shown in the following list.
+ *
+ * <table>
+ * <tr><th>P</th><th>D</th><th>DPo</th><th>DPan</th></tr>
+ * <tr><td>0</td><td>0</td><td>0</td><td>1</td></tr>
+ * <tr><td>0</td><td>1</td><td>1</td><td>1</td></tr>
+ * <tr><td>1</td><td>0</td><td>1</td><td>1</td></tr>
+ * <tr><td>1</td><td>1</td><td>1</td><td>0</td></tr>
+ * </table>
+ *
+ */
+public enum HwmfBinaryRasterOp {
+ /** 0, Pixel is always 0 */
+ R2_BLACK(0x0001),
+ /** DPon, Pixel is the inverse of the R2_MERGEPEN color. */
+ R2_NOTMERGEPEN(0x0002),
+ /** DPna, Pixel is a combination of the screen color and the inverse of the pen color. */
+ R2_MASKNOTPEN(0x0003),
+ /** Pn, Pixel is the inverse of the pen color. */
+ R2_NOTCOPYPEN(0x0004),
+ /** PDna, Pixel is a combination of the colors common to both the pen and the inverse of the screen. */
+ R2_MASKPENNOT(0x0005),
+ /** Dn, Pixel is the inverse of the screen color. */
+ R2_NOT(0x0006),
+ /** DPx, Pixel is a combination of the colors in the pen or in the screen, but not in both. */
+ R2_XORPEN(0x0007),
+ /** DPan, Pixel is the inverse of the R2_MASKPEN color. */
+ R2_NOTMASKPEN(0x0008),
+ /** DPa, Pixel is a combination of the colors common to both the pen and the screen. */
+ R2_MASKPEN(0x0009),
+ /** DPxn, Pixel is the inverse of the R2_XORPEN color. */
+ R2_NOTXORPEN(0x000A),
+ /** D, Pixel remains unchanged. */
+ R2_NOP(0x000B),
+ /** DPno, Pixel is a combination of the colors common to both the screen and the inverse of the pen. */
+ R2_MERGENOTPEN(0x000C),
+ /** P, Pixel is the pen color. */
+ R2_COPYPEN(0x000D),
+ /** PDno, Pixel is a combination of the pen color and the inverse of the screen color.*/
+ R2_MERGEPENNOT(0x000E),
+ /** DPo, Pixel is a combination of the pen color and the screen color. */
+ R2_MERGEPEN(0x000F),
+ /** 1, Pixel is always 1 */
+ R2_WHITE(0x0010);
+
+ int opIndex;
+
+ HwmfBinaryRasterOp(int opIndex) {
+ this.opIndex=opIndex;
+ }
+
+ public static HwmfBinaryRasterOp valueOf(int opIndex) {
+ for (HwmfBinaryRasterOp bb : HwmfBinaryRasterOp.values()) {
+ if (bb.opIndex == opIndex) {
+ return bb;
+ }
+ }
+ return null;
+ }
+
+}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfBitmapDib.java Wed Feb 24 22:43:51 2016
@@ -18,13 +18,11 @@
package org.apache.poi.hwmf.record;
import java.awt.Color;
+import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
-import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
import javax.imageio.ImageIO;
@@ -32,6 +30,8 @@ import org.apache.poi.hssf.record.Record
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
/**
* The DeviceIndependentBitmap Object defines an image in device-independent bitmap (DIB) format.
@@ -188,6 +188,7 @@ public class HwmfBitmapDib {
}
}
+ private static POILogger logger = POILogFactory.getLogger(HwmfBitmapDib.class);
private static final int BMP_HEADER_SIZE = 14;
private int headerSize;
@@ -204,8 +205,6 @@ public class HwmfBitmapDib {
private long headerColorUsed = -1;
@SuppressWarnings("unused")
private long headerColorImportant = -1;
-
- @SuppressWarnings("unused")
private Color colorTable[];
@SuppressWarnings("unused")
private int colorMaskR=0,colorMaskG=0,colorMaskB=0;
@@ -360,22 +359,24 @@ public class HwmfBitmapDib {
protected int readRGBQuad(LittleEndianInputStream leis, int count) throws IOException {
int size = 0;
- List<Color> colorList = new ArrayList<Color>();
+ colorTable = new Color[count];
for (int i=0; i<count; i++) {
int blue = leis.readUByte();
int green = leis.readUByte();
int red = leis.readUByte();
@SuppressWarnings("unused")
int reserved = leis.readUByte();
- Color c = new Color(red, green, blue);
- colorList.add(c);
+ colorTable[i] = new Color(red, green, blue);
size += 4 * LittleEndianConsts.BYTE_SIZE;
}
- colorTable = colorList.toArray(new Color[colorList.size()]);
return size;
}
public InputStream getBMPStream() {
+ return new ByteArrayInputStream(getBMPData());
+ }
+
+ private byte[] getBMPData() {
if (imageData == null) {
throw new RecordFormatException("bitmap not initialized ... need to call init() before");
}
@@ -398,14 +399,20 @@ public class HwmfBitmapDib {
// fill the "known" image data
System.arraycopy(imageData, 0, buf, BMP_HEADER_SIZE, imageData.length);
- return new ByteArrayInputStream(buf);
+ return buf;
}
public BufferedImage getImage() {
try {
return ImageIO.read(getBMPStream());
} catch (IOException e) {
- throw new RecordFormatException("invalid bitmap data", e);
+ logger.log(POILogger.ERROR, "invalid bitmap data - returning black opaque image");
+ BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = bi.createGraphics();
+ g.setPaint(Color.black);
+ g.fillRect(0, 0, headerWidth, headerHeight);
+ g.dispose();
+ return bi;
}
}
}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfDraw.java Wed Feb 24 22:43:51 2016
@@ -17,6 +17,7 @@
package org.apache.poi.hwmf.record;
+import java.awt.Color;
import java.awt.Shape;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
@@ -146,9 +147,10 @@ public class HwmfDraw {
@Override
public void draw(HwmfGraphics ctx) {
- Path2D p = getShape();
- p.closePath();
- p.setWindingRule(ctx.getProperties().getPolyfillMode().awtFlag);
+ Path2D shape = getShape();
+// shape.closePath();
+ Path2D p = (Path2D)shape.clone();
+ p.setWindingRule(getWindingRule(ctx));
ctx.fill(p);
}
@@ -170,8 +172,9 @@ public class HwmfDraw {
@Override
public void draw(HwmfGraphics ctx) {
- Path2D p = getShape();
- p.setWindingRule(ctx.getProperties().getPolyfillMode().awtFlag);
+ Path2D shape = getShape();
+ Path2D p = (Path2D)shape.clone();
+ p.setWindingRule(getWindingRule(ctx));
ctx.draw(p);
}
}
@@ -320,12 +323,13 @@ public class HwmfDraw {
for (int nPoints : pointsPerPolygon) {
/**
- * An array of 16-bit unsigned integers that define the coordinates of the polygons.
+ * An array of 16-bit signed integers that define the coordinates of the polygons.
+ * (Note: MS-WMF wrongly says unsigned integers ...)
*/
Path2D poly = new Path2D.Double();
for (int i=0; i<nPoints; i++) {
- int x = leis.readUShort();
- int y = leis.readUShort();
+ int x = leis.readShort();
+ int y = leis.readShort();
size += 2*LittleEndianConsts.SHORT_SIZE;
if (i == 0) {
poly.moveTo(x, y);
@@ -342,14 +346,23 @@ public class HwmfDraw {
@Override
public void draw(HwmfGraphics ctx) {
- int windingRule = ctx.getProperties().getPolyfillMode().awtFlag;
- Area area = new Area();
+ if (polyList.isEmpty()) {
+ return;
+ }
+
+ int windingRule = getWindingRule(ctx);
+ Area area = null;
for (Path2D poly : polyList) {
Path2D p = (Path2D)poly.clone();
p.setWindingRule(windingRule);
- area.add(new Area(p));
+ Area newArea = new Area(p);
+ if (area == null) {
+ area = newArea;
+ } else {
+ area.exclusiveOr(newArea);
+ }
}
- ctx.draw(area);
+ ctx.fill(area);
}
}
@@ -679,4 +692,8 @@ public class HwmfDraw {
ctx.applyObjectTableEntry(objectIndex);
}
}
+
+ private static int getWindingRule(HwmfGraphics ctx) {
+ return ctx.getProperties().getPolyfillMode().awtFlag;
+ }
}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfEscape.java Wed Feb 24 22:43:51 2016
@@ -24,13 +24,155 @@ import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
+/**
+ * The MetafileEscapes specifies printer driver functionality that
+ * might not be directly accessible through WMF records
+ */
public class HwmfEscape implements HwmfRecord {
+ public enum EscapeFunction {
+ /** Notifies the printer driver that the application has finished writing to a page. */
+ NEWFRAME(0x0001),
+ /** Stops processing the current document. */
+ ABORTDOC(0x0002),
+ /** Notifies the printer driver that the application has finished writing to a band. */
+ NEXTBAND(0x0003),
+ /** Sets color table values. */
+ SETCOLORTABLE(0x0004),
+ /** Gets color table values. */
+ GETCOLORTABLE(0x0005),
+ /** Causes all pending output to be flushed to the output device. */
+ FLUSHOUT(0x0006),
+ /** Indicates that the printer driver SHOULD print text only, and no graphics. */
+ DRAFTMODE(0x0007),
+ /** Queries a printer driver to determine whether a specific escape function is supported on the output device it drives. */
+ QUERYESCSUPPORT(0x0008),
+ /** Sets the application-defined function that allows a print job to be canceled during printing. */
+ SETABORTPROC(0x0009),
+ /** Notifies the printer driver that a new print job is starting. */
+ STARTDOC(0x000A),
+ /** Notifies the printer driver that the current print job is ending. */
+ ENDDOC(0x000B),
+ /** Retrieves the physical page size currently selected on an output device. */
+ GETPHYSPAGESIZE(0x000C),
+ /** Retrieves the offset from the upper-left corner of the physical page where the actual printing or drawing begins. */
+ GETPRINTINGOFFSET(0x000D),
+ /** Retrieves the scaling factors for the x-axis and the y-axis of a printer. */
+ GETSCALINGFACTOR(0x000E),
+ /** Used to embed an enhanced metafile format (EMF) metafile within a WMF metafile. */
+ META_ESCAPE_ENHANCED_METAFILE(0x000F),
+ /** Sets the width of a pen in pixels. */
+ SETPENWIDTH(0x0010),
+ /** Sets the number of copies. */
+ SETCOPYCOUNT(0x0011),
+ /** Sets the source, such as a particular paper tray or bin on a printer, for output forms. */
+ SETPAPERSOURCE(0x0012),
+ /** This record passes through arbitrary data. */
+ PASSTHROUGH(0x0013),
+ /** Gets information concerning graphics technology that is supported on a device. */
+ GETTECHNOLOGY(0x0014),
+ /** Specifies the line-drawing mode to use in output to a device. */
+ SETLINECAP(0x0015),
+ /** Specifies the line-joining mode to use in output to a device. */
+ SETLINEJOIN(0x0016),
+ /** Sets the limit for the length of miter joins to use in output to a device. */
+ SETMITERLIMIT(0x0017),
+ /** Retrieves or specifies settings concerning banding on a device, such as the number of bands. */
+ BANDINFO(0x0018),
+ /** Draws a rectangle with a defined pattern. */
+ DRAWPATTERNRECT(0x0019),
+ /** Retrieves the physical pen size currently defined on a device. */
+ GETVECTORPENSIZE(0x001A),
+ /** Retrieves the physical brush size currently defined on a device. */
+ GETVECTORBRUSHSIZE(0x001B),
+ /** Enables or disables double-sided (duplex) printing on a device. */
+ ENABLEDUPLEX(0x001C),
+ /** Retrieves or specifies the source of output forms on a device. */
+ GETSETPAPERBINS(0x001D),
+ /** Retrieves or specifies the paper orientation on a device. */
+ GETSETPRINTORIENT(0x001E),
+ /** Retrieves information concerning the sources of different forms on an output device. */
+ ENUMPAPERBINS(0x001F),
+ /** Specifies the scaling of device-independent bitmaps (DIBs). */
+ SETDIBSCALING(0x0020),
+ /** Indicates the start and end of an encapsulated PostScript (EPS) section. */
+ EPSPRINTING(0x0021),
+ /** Queries a printer driver for paper dimensions and other forms data. */
+ ENUMPAPERMETRICS(0x0022),
+ /** Retrieves or specifies paper dimensions and other forms data on an output device. */
+ GETSETPAPERMETRICS(0x0023),
+ /** Sends arbitrary PostScript data to an output device. */
+ POSTSCRIPT_DATA(0x0025),
+ /** Notifies an output device to ignore PostScript data. */
+ POSTSCRIPT_IGNORE(0x0026),
+ /** Gets the device units currently configured on an output device. */
+ GETDEVICEUNITS(0x002A),
+ /** Gets extended text metrics currently configured on an output device. */
+ GETEXTENDEDTEXTMETRICS(0x0100),
+ /** Gets the font kern table currently defined on an output device. */
+ GETPAIRKERNTABLE(0x0102),
+ /** Draws text using the currently selected font, background color, and text color. */
+ EXTTEXTOUT(0x0200),
+ /** Gets the font face name currently configured on a device. */
+ GETFACENAME(0x0201),
+ /** Sets the font face name on a device. */
+ DOWNLOADFACE(0x0202),
+ /** Queries a printer driver about the support for metafiles on an output device. */
+ METAFILE_DRIVER(0x0801),
+ /** Queries the printer driver about its support for DIBs on an output device. */
+ QUERYDIBSUPPORT(0x0C01),
+ /** Opens a path. */
+ BEGIN_PATH(0x1000),
+ /** Defines a clip region that is bounded by a path. The input MUST be a 16-bit quantity that defines the action to take. */
+ CLIP_TO_PATH(0x1001),
+ /** Ends a path. */
+ END_PATH(0x1002),
+ /** The same as STARTDOC specified with a NULL document and output filename, data in raw mode, and a type of zero. */
+ OPEN_CHANNEL(0x100E),
+ /** Instructs the printer driver to download sets of PostScript procedures. */
+ DOWNLOADHEADER(0x100F),
+ /** The same as ENDDOC. See OPEN_CHANNEL. */
+ CLOSE_CHANNEL(0x1010),
+ /** Sends arbitrary data directly to a printer driver, which is expected to process this data only when in PostScript mode. */
+ POSTSCRIPT_PASSTHROUGH(0x1013),
+ /** Sends arbitrary data directly to the printer driver. */
+ ENCAPSULATED_POSTSCRIPT(0x1014),
+ /** Sets the printer driver to either PostScript or GDI mode. */
+ POSTSCRIPT_IDENTIFY(0x1015),
+ /** Inserts a block of raw data into a PostScript stream. The input MUST be
+ a 32-bit quantity specifying the number of bytes to inject, a 16-bit quantity specifying the
+ injection point, and a 16-bit quantity specifying the page number, followed by the bytes to
+ inject. */
+ POSTSCRIPT_INJECTION(0x1016),
+ /** Checks whether the printer supports a JPEG image. */
+ CHECKJPEGFORMAT(0x1017),
+ /** Checks whether the printer supports a PNG image */
+ CHECKPNGFORMAT(0x1018),
+ /** Gets information on a specified feature setting for a PostScript printer driver. */
+ GET_PS_FEATURESETTING(0x1019),
+ /** Enables applications to write documents to a file or to a printer in XML Paper Specification (XPS) format. */
+ MXDC_ESCAPE(0x101A),
+ /** Enables applications to include private procedures and other arbitrary data in documents. */
+ SPCLPASSTHROUGH2(0x11D8);
+
+ int flag;
+ EscapeFunction(int flag) {
+ this.flag = flag;
+ }
+
+ static EscapeFunction valueOf(int flag) {
+ for (EscapeFunction hs : values()) {
+ if (hs.flag == flag) return hs;
+ }
+ return null;
+ }
+ }
+
/**
* A 16-bit unsigned integer that defines the escape function. The
* value MUST be from the MetafileEscapes enumeration.
*/
- private int escapeFunction;
+ private EscapeFunction escapeFunction;
/**
* A 16-bit unsigned integer that specifies the size, in bytes, of the
* EscapeData field.
@@ -48,7 +190,7 @@ public class HwmfEscape implements HwmfR
@Override
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- escapeFunction = leis.readUShort();
+ escapeFunction = EscapeFunction.valueOf(leis.readUShort());
byteCount = leis.readUShort();
escapeData = new byte[byteCount];
leis.read(escapeData);
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfFill.java Wed Feb 24 22:43:51 2016
@@ -20,13 +20,9 @@ package org.apache.poi.hwmf.record;
import java.awt.Shape;
import java.awt.geom.Path2D;
import java.awt.image.BufferedImage;
-import java.io.File;
import java.io.IOException;
-import javax.imageio.ImageIO;
-
import org.apache.poi.hwmf.draw.HwmfGraphics;
-import org.apache.poi.hwmf.record.HwmfWindowing.WmfCreateRegion;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
@@ -240,7 +236,7 @@ public class HwmfFill {
@Override
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- polyfillMode = HwmfPolyfillMode.valueOf(leis.readUShort());
+ polyfillMode = HwmfPolyfillMode.valueOf(leis.readUShort() & 3);
return LittleEndianConsts.SHORT_SIZE;
}
@@ -402,6 +398,15 @@ public class HwmfFill {
}
/**
+ * The META_STRETCHBLT record specifies the transfer of a block of pixels according to a raster
+ * operation, with possible expansion or contraction.
+ * The destination of the transfer is the current output region in the playback device context.
+ * There are two forms of META_STRETCHBLT, one which specifies a bitmap as the source, and the other
+ * which uses the playback device context as the source. Definitions follow for the fields that are the
+ * same in the two forms of META_STRETCHBLT are defined below. The subsections that follow specify
+ * the packet structures of the two forms of META_STRETCHBLT.
+ * The expansion or contraction is performed according to the stretching mode currently set in the
+ * playback device context, which MUST be a value from the StretchMode.
*/
public static class WmfStretchBlt implements HwmfRecord {
/**
@@ -502,12 +507,12 @@ public class HwmfFill {
/**
* The META_STRETCHDIB record specifies the transfer of color data from a
- * block of pixels in deviceindependent format according to a raster operation,
+ * block of pixels in device independent format according to a raster operation,
* with possible expansion or contraction.
* The source of the color data is a DIB, and the destination of the transfer is
* the current output region in the playback device context.
*/
- public static class WmfStretchDib implements HwmfRecord, HwmfImageRecord {
+ public static class WmfStretchDib implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
/**
* A 32-bit unsigned integer that defines how the source pixels, the current brush in
* the playback device context, and the destination pixels are to be combined to
@@ -599,6 +604,11 @@ public class HwmfFill {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
@@ -706,7 +716,7 @@ public class HwmfFill {
* using deviceindependent color data.
* The source of the color data is a DIB
*/
- public static class WmfSetDibToDev implements HwmfRecord, HwmfImageRecord {
+ public static class WmfSetDibToDev implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
/**
* A 16-bit unsigned integer that defines whether the Colors field of the
@@ -783,6 +793,11 @@ public class HwmfFill {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
@@ -793,7 +808,7 @@ public class HwmfFill {
}
- public static class WmfDibBitBlt implements HwmfRecord, HwmfImageRecord {
+ public static class WmfDibBitBlt implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
/**
* A 32-bit unsigned integer that defines how the source pixels, the current brush
@@ -877,6 +892,11 @@ public class HwmfFill {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
@@ -886,7 +906,7 @@ public class HwmfFill {
}
}
- public static class WmfDibStretchBlt implements HwmfRecord, HwmfImageRecord {
+ public static class WmfDibStretchBlt implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
/**
* A 32-bit unsigned integer that defines how the source pixels, the current brush
* in the playback device context, and the destination pixels are to be combined to form the
@@ -978,6 +998,11 @@ public class HwmfFill {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
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=1732236&r1=1732235&r2=1732236&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 Wed Feb 24 22:43:51 2016
@@ -449,6 +449,13 @@ public class HwmfFont {
WmfFontQuality quality;
/**
+ * A PitchAndFamily object that defines the pitch and the family of the font.
+ * Font families specify the look of fonts in a general way and are intended for
+ * specifying fonts when the exact typeface wanted is not available.
+ */
+ int pitchAndFamily;
+
+ /**
* Font families specify the look of fonts in a general way and are
* intended for specifying fonts when the exact typeface wanted is not available.
* (LSB 4 bits)
@@ -480,9 +487,7 @@ public class HwmfFont {
outPrecision = WmfOutPrecision.valueOf(leis.readUByte());
clipPrecision = WmfClipPrecision.valueOf(leis.readUByte());
quality = WmfFontQuality.valueOf(leis.readUByte());
- int pitchAndFamily = leis.readUByte();
- family = WmfFontFamilyClass.valueOf(pitchAndFamily & 0xF);
- pitch = WmfFontPitch.valueOf((pitchAndFamily >>> 6) & 3);
+ pitchAndFamily = leis.readUByte();
byte buf[] = new byte[32], b, readBytes = 0;
do {
@@ -546,12 +551,16 @@ public class HwmfFont {
return quality;
}
+ public int getPitchAndFamily() {
+ return pitchAndFamily;
+ }
+
public WmfFontFamilyClass getFamily() {
- return family;
+ return WmfFontFamilyClass.valueOf(pitchAndFamily & 0xF);
}
public WmfFontPitch getPitch() {
- return pitch;
+ return WmfFontPitch.valueOf((pitchAndFamily >>> 6) & 3);
}
public String getFacename() {
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java Wed Feb 24 22:43:51 2016
@@ -109,6 +109,6 @@ public enum HwmfMapMode {
for (HwmfMapMode mm : values()) {
if (mm.flag == flag) return mm;
}
- return null;
+ return MM_ISOTROPIC;
}
}
\ No newline at end of file
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java Wed Feb 24 22:43:51 2016
@@ -265,25 +265,9 @@ public class HwmfMisc {
/**
* A 16-bit unsigned integer that defines the foreground binary raster
- * operation mixing mode. This MUST be one of the values:
- * R2_BLACK = 0x0001,
- * R2_NOTMERGEPEN = 0x0002,
- * R2_MASKNOTPEN = 0x0003,
- * R2_NOTCOPYPEN = 0x0004,
- * R2_MASKPENNOT = 0x0005,
- * R2_NOT = 0x0006,
- * R2_XORPEN = 0x0007,
- * R2_NOTMASKPEN = 0x0008,
- * R2_MASKPEN = 0x0009,
- * R2_NOTXORPEN = 0x000A,
- * R2_NOP = 0x000B,
- * R2_MERGENOTPEN = 0x000C,
- * R2_COPYPEN = 0x000D,
- * R2_MERGEPENNOT = 0x000E,
- * R2_MERGEPEN = 0x000F,
- * R2_WHITE = 0x0010
+ * operation mixing mode
*/
- private int drawMode;
+ private HwmfBinaryRasterOp drawMode;
@Override
public HwmfRecordType getRecordType() {
@@ -292,7 +276,7 @@ public class HwmfMisc {
@Override
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- drawMode = leis.readUShort();
+ drawMode = HwmfBinaryRasterOp.valueOf(leis.readUShort());
return LittleEndianConsts.SHORT_SIZE;
}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPalette.java Wed Feb 24 22:43:51 2016
@@ -93,7 +93,7 @@ public class HwmfPalette {
}
}
- public static abstract class WmfPaletteParent implements HwmfRecord {
+ public static abstract class WmfPaletteParent implements HwmfRecord, HwmfObjectTableEntry {
/**
* Start (2 bytes): A 16-bit unsigned integer that defines the offset into the Palette Object when
@@ -121,6 +121,11 @@ public class HwmfPalette {
return size;
}
+ @Override
+ public final void draw(HwmfGraphics ctx) {
+ ctx.addObjectTableEntry(this);
+ }
+
protected List<PaletteEntry> getPaletteCopy() {
List<PaletteEntry> newPalette = new ArrayList<PaletteEntry>();
for (PaletteEntry et : palette) {
@@ -144,11 +149,6 @@ public class HwmfPalette {
}
@Override
- public void draw(HwmfGraphics ctx) {
- ctx.addObjectTableEntry(this);
- }
-
- @Override
public void applyObject(HwmfGraphics ctx) {
ctx.getProperties().setPalette(getPaletteCopy());
}
@@ -165,7 +165,7 @@ public class HwmfPalette {
}
@Override
- public void draw(HwmfGraphics ctx) {
+ public void applyObject(HwmfGraphics ctx) {
HwmfDrawProperties props = ctx.getProperties();
List<PaletteEntry> palette = props.getPalette();
if (palette == null) {
@@ -192,7 +192,7 @@ public class HwmfPalette {
* The META_RESIZEPALETTE record redefines the size of the logical palette that is defined in the
* playback device context.
*/
- public static class WmfResizePalette implements HwmfRecord {
+ public static class WmfResizePalette implements HwmfRecord, HwmfObjectTableEntry {
/**
* A 16-bit unsigned integer that defines the number of entries in
* the logical palette.
@@ -212,6 +212,11 @@ public class HwmfPalette {
@Override
public void draw(HwmfGraphics ctx) {
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
HwmfDrawProperties props = ctx.getProperties();
List<PaletteEntry> palette = props.getPalette();
if (palette == null) {
@@ -292,7 +297,7 @@ public class HwmfPalette {
}
@Override
- public void draw(HwmfGraphics ctx) {
+ public void applyObject(HwmfGraphics ctx) {
HwmfDrawProperties props = ctx.getProperties();
List<PaletteEntry> dest = props.getPalette();
List<PaletteEntry> src = getPaletteCopy();
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java Wed Feb 24 22:43:51 2016
@@ -17,6 +17,68 @@
package org.apache.poi.hwmf.record;
+/**
+ * Each ternary raster operation code represents a Boolean operation in which the values of the pixels in
+ * the source, the selected brush, and the destination are combined. Following are the three operands
+ * used in these operations.
+ *
+ * <table>
+ * <tr><th>Operand</th><th>Meaning</th></tr>
+ * <tr><td>D</td><td>Destination bitmap</td></tr>
+ * <tr><td>P</td><td>Selected brush (also called pattern)</td></tr>
+ * <tr><td>S</td><td>Source bitmap</td></tr>
+ * </table>
+ *
+ * Following are the Boolean operators used in these operations.
+ * <table>
+ * <tr><th>Operand</th><th>Meaning</th></tr>
+ * <tr><td>a</td><td>Bitwise AND</td></tr>
+ * <tr><td>n</td><td>Bitwise NOT (inverse)</td></tr>
+ * <tr><td>o</td><td>Bitwise OR</td></tr>
+ * <tr><td>x</td><td>Bitwise exclusive OR (XOR)</td></tr>
+ * </table>
+ *
+ * All Boolean operations are presented in reverse Polish notation. For example, the following operation
+ * replaces the values of the pixels in the destination bitmap with a combination of the pixel values of the
+ * source and brush: PSo.
+ *
+ * The following operation combines the values of the pixels in the source and brush with the pixel values
+ * of the destination bitmap: DPSoo (there are alternative spellings of some functions, so although a
+ * particular spelling MAY NOT be listed in the enumeration, an equivalent form SHOULD be).
+ *
+ * Each raster operation code is a 32-bit integer whose high-order word is a Boolean operation index and
+ * whose low-order word is the operation code. The 16-bit operation index is a zero-extended, 8-bit
+ * value that represents the result of the Boolean operation on predefined brush, source, and destination
+ * values. For example, the operation indexes for the PSo and DPSoo operations are shown in the
+ * following list.
+ *
+ * <table>
+ * <tr><th>P</th><th>S</th><th>D</th><th>DPo</th><th>DPan</th></tr>
+ * <tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
+ * <tr><td>0</td><td>0</td><td>1</td><td>0</td><td>1</td></tr>
+ * <tr><td>0</td><td>1</td><td>0</td><td>1</td><td>1</td></tr>
+ * <tr><td>0</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
+ * <tr><td>1</td><td>0</td><td>0</td><td>1</td><td>1</td></tr>
+ * <tr><td>1</td><td>0</td><td>1</td><td>1</td><td>1</td></tr>
+ * <tr><td>1</td><td>1</td><td>0</td><td>1</td><td>1</td></tr>
+ * <tr><td>1</td><td>1</td><td>1</td><td>1</td><td>1</td></tr>
+ * </table>
+ *
+ * The operation indexes are determined by reading the binary values in a column of the table from the
+ * bottom up. For example, in the PSo column, the binary value is 11111100, which is equivalent to 00FC
+ * (hexadecimal is implicit for these values), which is the operation index for PSo.
+ *
+ * Using this method, DPSoo can be seen to have the operation index 00FE. Operation indexes define the
+ * locations of corresponding raster operation codes in the preceding enumeration. The PSo operation is
+ * in line 252 (0x00FC) of the enumeration; DPSoo is in line 254 (0x00FE).
+ *
+ * The most commonly used raster operations have been given explicit enumeration names, which
+ * SHOULD be used; examples are PATCOPY and WHITENESS.
+ *
+ * When the source and destination bitmaps are monochrome, a bit value of 0 represents a black pixel
+ * and a bit value of 1 represents a white pixel. When the source and the destination bitmaps are color,
+ * those colors are represented with red green blue (RGB) values.
+ */
public enum HwmfTernaryRasterOp {
BLACKNESS(0x0000,0x0042,"0"),
DPSOON(0x0001,0x0289,"DPSoon"),
@@ -274,17 +336,17 @@ public enum HwmfTernaryRasterOp {
PSDNOO(0x00FD,0x0A0A,"PSDnoo"),
DPSOO(0x00FE,0x02A9,"DPSoo"),
WHITENESS(0x00FF,0x0062,"1");
-
+
int opIndex;
int opCode;
String opCmd;
-
+
HwmfTernaryRasterOp(int opIndex, int opCode, String opCmd) {
this.opIndex=opIndex;
this.opCode=opCode;
this.opCmd=opCmd;
}
-
+
public static HwmfTernaryRasterOp valueOf(int opIndex) {
for (HwmfTernaryRasterOp bb : HwmfTernaryRasterOp.values()) {
if (bb.opIndex == opIndex) {
@@ -293,11 +355,11 @@ public enum HwmfTernaryRasterOp {
}
return null;
}
-
+
public String describeCmd() {
String stack[] = new String[10];
int stackPnt = 0;
-
+
for (char c : opCmd.toCharArray()) {
switch (c) {
case 'S':
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfText.java Wed Feb 24 22:43:51 2016
@@ -19,7 +19,6 @@ package org.apache.poi.hwmf.record;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
-import java.text.AttributedString;
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.hwmf.draw.HwmfGraphics;
@@ -29,10 +28,13 @@ import org.apache.poi.util.BitFieldFacto
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
import org.apache.poi.util.LocaleUtil;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
import org.apache.poi.util.RecordFormatException;
public class HwmfText {
-
+ private static final POILogger logger = POILogFactory.getLogger(HwmfText.class);
+
/**
* The META_SETTEXTCHAREXTRA record defines inter-character spacing for text justification in the
* playback device context. Spacing is added to the white space between each character, including
@@ -186,6 +188,48 @@ public class HwmfText {
public static class WmfExtTextOut implements HwmfRecord {
/**
+ * Indicates that the background color that is defined in the playback device context
+ * SHOULD be used to fill the rectangle.
+ */
+ private static final BitField ETO_OPAQUE = BitFieldFactory.getInstance(0x0002);
+
+ /**
+ * Indicates that the text SHOULD be clipped to the rectangle.
+ */
+ private static final BitField ETO_CLIPPED = BitFieldFactory.getInstance(0x0004);
+
+ /**
+ * Indicates that the string to be output SHOULD NOT require further processing
+ * with respect to the placement of the characters, and an array of character
+ * placement values SHOULD be provided. This character placement process is
+ * useful for fonts in which diacritical characters affect character spacing.
+ */
+ private static final BitField ETO_GLYPH_INDEX = BitFieldFactory.getInstance(0x0010);
+
+ /**
+ * Indicates that the text MUST be laid out in right-to-left reading order, instead of
+ * the default left-to-right order. This SHOULD be applied only when the font that is
+ * defined in the playback device context is either Hebrew or Arabic.
+ */
+ private static final BitField ETO_RTLREADING = BitFieldFactory.getInstance(0x0080);
+
+ /**
+ * Indicates that to display numbers, digits appropriate to the locale SHOULD be used.
+ */
+ private static final BitField ETO_NUMERICSLOCAL = BitFieldFactory.getInstance(0x0400);
+
+ /**
+ * Indicates that to display numbers, European digits SHOULD be used.
+ */
+ private static final BitField ETO_NUMERICSLATIN = BitFieldFactory.getInstance(0x0800);
+
+ /**
+ * Indicates that both horizontal and vertical character displacement values
+ * SHOULD be provided.
+ */
+ private static final BitField ETO_PDY = BitFieldFactory.getInstance(0x2000);
+
+ /**
* A 16-bit signed integer that defines the y-coordinate, in logical units, where the
text string is to be located.
*/
@@ -199,40 +243,12 @@ public class HwmfText {
* A 16-bit signed integer that defines the length of the string.
*/
private int stringLength;
- /**
- * A 16-bit unsigned integer that defines the use of the application-defined
- * rectangle. This member can be a combination of one or more values in the
- * ExtTextOutOptions Flags:
- *
- * ETO_OPAQUE (0x0002):
- * Indicates that the background color that is defined in the playback device context
- * SHOULD be used to fill the rectangle.
- *
- * ETO_CLIPPED (0x0004):
- * Indicates that the text SHOULD be clipped to the rectangle.
- *
- * ETO_GLYPH_INDEX (0x0010):
- * Indicates that the string to be output SHOULD NOT require further processing
- * with respect to the placement of the characters, and an array of character
- * placement values SHOULD be provided. This character placement process is
- * useful for fonts in which diacritical characters affect character spacing.
- *
- * ETO_RTLREADING (0x0080):
- * Indicates that the text MUST be laid out in right-to-left reading order, instead of
- * the default left-to-right order. This SHOULD be applied only when the font that is
- * defined in the playback device context is either Hebrew or Arabic. <37>
- *
- * ETO_NUMERICSLOCAL (0x0400):
- * Indicates that to display numbers, digits appropriate to the locale SHOULD be
- * used.
- *
- * ETO_NUMERICSLATIN (0x0800):
- * Indicates that to display numbers, European digits SHOULD be used. <39>
- *
- * ETO_PDY (0x2000):
- * Indicates that both horizontal and vertical character displacement values
- * SHOULD be provided.
- */
+
+ /**
+ * A 16-bit unsigned integer that defines the use of the application-defined
+ * rectangle. This member can be a combination of one or more values in the
+ * ExtTextOutOptions Flags (ETO_*)
+ */
private int fwOpts;
/**
* An optional 8-byte Rect Object (section 2.2.2.18) that defines the
@@ -275,7 +291,8 @@ public class HwmfText {
int size = 4*LittleEndianConsts.SHORT_SIZE;
- if (fwOpts != 0 && size+8<=remainingRecordSize) {
+ // Check if we have a rectangle
+ if ((ETO_OPAQUE.isSet(fwOpts) || ETO_CLIPPED.isSet(fwOpts)) && size+8<=remainingRecordSize) {
// the bounding rectangle is optional and only read when fwOpts are given
left = leis.readShort();
top = leis.readShort();
@@ -289,16 +306,20 @@ public class HwmfText {
text = new String(buf, 0, stringLength, LocaleUtil.CHARSET_1252);
size += buf.length;
- if (size < remainingRecordSize) {
- if (size + stringLength*LittleEndianConsts.SHORT_SIZE < remainingRecordSize) {
- throw new RecordFormatException("can't read Dx array - given recordSize doesn't contain enough values for string length "+stringLength);
- }
-
- dx = new int[stringLength];
- for (int i=0; i<dx.length; i++) {
- dx[i] = leis.readShort();
- }
- size += dx.length*LittleEndianConsts.SHORT_SIZE;
+ if (size >= remainingRecordSize) {
+ logger.log(POILogger.INFO, "META_EXTTEXTOUT doesn't contain character tracking info");
+ return size;
+ }
+
+ int dxLen = Math.min(stringLength, (remainingRecordSize-size)/LittleEndianConsts.SHORT_SIZE);
+ if (dxLen < stringLength) {
+ logger.log(POILogger.WARN, "META_EXTTEXTOUT tracking info doesn't cover all characters");
+ }
+
+ dx = new int[stringLength];
+ for (int i=0; i<dxLen; i++) {
+ dx[i] = leis.readShort();
+ size += LittleEndianConsts.SHORT_SIZE;
}
return size;
@@ -306,7 +327,8 @@ public class HwmfText {
@Override
public void draw(HwmfGraphics ctx) {
-
+ Rectangle2D bounds = new Rectangle2D.Double(x, y, 0, 0);
+ ctx.drawString(text, bounds, dx);
}
}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfWindowing.java Wed Feb 24 22:43:51 2016
@@ -376,7 +376,7 @@ public class HwmfWindowing {
* The META_OFFSETCLIPRGN record moves the clipping region in the playback device context by the
* specified offsets.
*/
- public static class WmfOffsetClipRgn implements HwmfRecord {
+ public static class WmfOffsetClipRgn implements HwmfRecord, HwmfObjectTableEntry {
/**
* A 16-bit signed integer that defines the number of logical units to move up or down.
@@ -402,7 +402,11 @@ public class HwmfWindowing {
@Override
public void draw(HwmfGraphics ctx) {
-
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
}
@@ -410,7 +414,7 @@ public class HwmfWindowing {
* The META_EXCLUDECLIPRECT record sets the clipping region in the playback device context to the
* existing clipping region minus the specified rectangle.
*/
- public static class WmfExcludeClipRect implements HwmfRecord {
+ public static class WmfExcludeClipRect implements HwmfRecord, HwmfObjectTableEntry {
/**
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
@@ -452,7 +456,11 @@ public class HwmfWindowing {
@Override
public void draw(HwmfGraphics ctx) {
-
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
}
@@ -461,7 +469,7 @@ public class HwmfWindowing {
* The META_INTERSECTCLIPRECT record sets the clipping region in the playback device context to the
* intersection of the existing clipping region and the specified rectangle.
*/
- public static class WmfIntersectClipRect implements HwmfRecord {
+ public static class WmfIntersectClipRect implements HwmfRecord, HwmfObjectTableEntry {
/**
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
@@ -503,7 +511,11 @@ public class HwmfWindowing {
@Override
public void draw(HwmfGraphics ctx) {
-
+ ctx.addObjectTableEntry(this);
+ }
+
+ @Override
+ public void applyObject(HwmfGraphics ctx) {
}
}
Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwmf/usermodel/HwmfPicture.java Wed Feb 24 22:43:51 2016
@@ -19,10 +19,8 @@ package org.apache.poi.hwmf.usermodel;
import java.awt.Dimension;
import java.awt.Graphics2D;
-import java.awt.GraphicsConfiguration;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
-import java.awt.geom.Rectangle2D.Double;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -38,9 +36,13 @@ import org.apache.poi.hwmf.record.HwmfRe
import org.apache.poi.hwmf.record.HwmfWindowing.WmfSetWindowExt;
import org.apache.poi.hwmf.record.HwmfWindowing.WmfSetWindowOrg;
import org.apache.poi.util.LittleEndianInputStream;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
import org.apache.poi.util.Units;
public class HwmfPicture {
+ private static final POILogger logger = POILogFactory.getLogger(HwmfPicture.class);
+
final List<HwmfRecord> records = new ArrayList<HwmfRecord>();
final HwmfPlaceableHeader placeableHeader;
final HwmfHeader header;
@@ -52,6 +54,10 @@ public class HwmfPicture {
header = new HwmfHeader(leis);
for (;;) {
+ if (leis.available() < 6) {
+ logger.log(POILogger.ERROR, "unexpected eof - wmf file was truncated");
+ break;
+ }
// recordSize in DWORDs
long recordSize = leis.readUInt()*2;
int recordFunction = leis.readShort();
Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/model/TestFreeform.java Wed Feb 24 22:43:51 2016
@@ -20,7 +20,10 @@ package org.apache.poi.hslf.model;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import java.awt.geom.*;
+import java.awt.geom.Area;
+import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
+import java.awt.geom.Rectangle2D;
import org.apache.poi.hslf.usermodel.HSLFFreeformShape;
import org.junit.Test;
@@ -38,7 +41,7 @@ public final class TestFreeform {
@Test
public void testClosedPath() {
- GeneralPath path1 = new GeneralPath();
+ Path2D.Double path1 = new Path2D.Double();
path1.moveTo(100, 100);
path1.lineTo(200, 100);
path1.lineTo(200, 200);
@@ -55,7 +58,7 @@ public final class TestFreeform {
@Test
public void testLine() {
- GeneralPath path1 = new GeneralPath(new Line2D.Double(100, 100, 200, 100));
+ Path2D.Double path1 = new Path2D.Double(new Line2D.Double(100, 100, 200, 100));
HSLFFreeformShape p = new HSLFFreeformShape();
p.setPath(path1);
@@ -67,7 +70,7 @@ public final class TestFreeform {
@Test
public void testRectangle() {
- GeneralPath path1 = new GeneralPath(new Rectangle2D.Double(100, 100, 200, 50));
+ Path2D.Double path1 = new Path2D.Double(new Rectangle2D.Double(100, 100, 200, 50));
HSLFFreeformShape p = new HSLFFreeformShape();
p.setPath(path1);
@@ -84,8 +87,8 @@ public final class TestFreeform {
public void test54188() {
HSLFFreeformShape p = new HSLFFreeformShape();
- GeneralPath path = p.getPath();
- GeneralPath emptyPath = new GeneralPath();
+ Path2D.Double path = p.getPath();
+ Path2D.Double emptyPath = new Path2D.Double();
assertEquals(emptyPath.getBounds2D(), path.getBounds2D());
}
}
Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestPicture.java Wed Feb 24 22:43:51 2016
@@ -30,23 +30,22 @@ import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.util.BitSet;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.imageio.ImageIO;
import org.apache.poi.POIDataSamples;
import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.hssf.usermodel.DummyGraphics2d;
-import org.apache.poi.sl.draw.Drawable;
+import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.sl.usermodel.SlideShow;
-import org.apache.poi.util.JvmBugs;
import org.junit.Ignore;
import org.junit.Test;
@@ -64,7 +63,7 @@ public final class TestPicture {
*
*/
@Test
- public void multiplePictures() throws Exception {
+ public void multiplePictures() throws IOException {
HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide s = ppt.createSlide();
@@ -92,6 +91,8 @@ public final class TestPicture {
EscherBSERecord bse3 = pict.getEscherBSERecord();
assertSame(bse2, bse3);
assertEquals(3, bse1.getRef());
+
+ ppt.close();
}
/**
@@ -99,7 +100,7 @@ public final class TestPicture {
* was not found. The correct behaviour is to return null.
*/
@Test
- public void bug46122() {
+ public void bug46122() throws IOException {
HSLFSlideShow ppt = new HSLFSlideShow();
HSLFSlide slide = ppt.createSlide();
HSLFPictureData pd = HSLFPictureData.create(PictureType.PNG);
@@ -112,10 +113,12 @@ public final class TestPicture {
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
pict.draw(graphics);
+
+ ppt.close();
}
@Test
- public void macImages() throws Exception {
+ public void macImages() throws IOException {
HSLFSlideShowImpl hss = new HSLFSlideShowImpl(_slTests.openResourceAsStream("53446.ppt"));
List<HSLFPictureData> pictures = hss.getPictureData();
@@ -154,11 +157,14 @@ public final class TestPicture {
break;
}
}
+
+ hss.close();
}
@Test
@Ignore("Just for visual validation - antialiasing is different on various systems")
- public void bug54541() throws Exception {
+ public void bug54541()
+ throws IOException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
String files[] = {
// "sample_pptx_grouping_issues.pptx",
// "54542_cropped_bitmap.pptx",
@@ -196,7 +202,7 @@ public final class TestPicture {
} else {
BufferedImage img = new BufferedImage(pg.width, pg.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = img.createGraphics();
- fixFonts(graphics);
+ DrawFactory.getInstance(graphics).fixFonts(graphics);
slide.draw(graphics);
graphics.setColor(Color.BLACK);
graphics.setStroke(new BasicStroke(1));
@@ -204,16 +210,8 @@ public final class TestPicture {
ImageIO.write(img, "PNG", new File(file.replaceFirst(".pptx?", "-")+slideNo+".png"));
}
}
+
+ ss.close();
}
}
-
- @SuppressWarnings("unchecked")
- private void fixFonts(Graphics2D graphics) {
- if (!JvmBugs.hasLineBreakMeasurerBug()) return;
- Map<String,String> fontMap = (Map<String,String>)graphics.getRenderingHint(Drawable.FONT_MAP);
- if (fontMap == null) fontMap = new HashMap<String,String>();
- fontMap.put("Calibri", "Lucida Sans");
- fontMap.put("Cambria", "Lucida Bright");
- graphics.setRenderingHint(Drawable.FONT_MAP, fontMap);
- }
}
Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hwmf/TestHwmfParsing.java Wed Feb 24 22:43:51 2016
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEqu
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileFilter;
@@ -64,7 +65,7 @@ public class TestHwmfParsing {
@Ignore("This is work-in-progress and not a real unit test ...")
public void paint() throws IOException {
File f = POIDataSamples.getSlideShowInstance().getFile("santa.wmf");
-// File f = new File("E:\\project\\poi\\misc\\govdocs-ppt", "000133-0001.wmf");
+ // File f = new File("bla.wmf");
FileInputStream fis = new FileInputStream(f);
HwmfPicture wmf = new HwmfPicture(fis);
fis.close();
@@ -73,6 +74,11 @@ public class TestHwmfParsing {
int width = Units.pointsToPixel(dim.getWidth());
// keep aspect ratio for height
int height = Units.pointsToPixel(dim.getHeight());
+ double max = Math.max(width, height);
+ if (max > 1500) {
+ width *= 1500/max;
+ height *= 1500/max;
+ }
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufImg.createGraphics();
@@ -81,7 +87,7 @@ public class TestHwmfParsing {
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
- wmf.draw(g);
+ wmf.draw(g, new Rectangle2D.Double(0,0,width,height));
g.dispose();
Modified: poi/trunk/src/testcases/org/apache/poi/sl/draw/geom/TestPresetGeometries.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/sl/draw/geom/TestPresetGeometries.java?rev=1732236&r1=1732235&r2=1732236&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/sl/draw/geom/TestPresetGeometries.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/sl/draw/geom/TestPresetGeometries.java Wed Feb 24 22:43:51 2016
@@ -22,7 +22,7 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import java.awt.geom.GeneralPath;
+import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.net.URL;
import java.util.Enumeration;
@@ -44,7 +44,7 @@ public class TestPresetGeometries {
}
});
for(Path p : geom){
- GeneralPath path = p.getPath(ctx);
+ Path2D path = p.getPath(ctx);
assertNotNull(path);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org