diff options
author | Andreas Beeker <kiwiwings@apache.org> | 2020-11-29 17:23:21 +0000 |
---|---|---|
committer | Andreas Beeker <kiwiwings@apache.org> | 2020-11-29 17:23:21 +0000 |
commit | 17592b0a88a0a588ac5f4f4dcd405d42ddd9f28e (patch) | |
tree | 6a7114e7ebf3a73871233fe8b80e2915910dbea6 /src | |
parent | 20c883b201b799899e7c1d8f4d781e567e9ad08b (diff) | |
download | poi-17592b0a88a0a588ac5f4f4dcd405d42ddd9f28e.tar.gz poi-17592b0a88a0a588ac5f4f4dcd405d42ddd9f28e.zip |
#64716 - wmf display error
change hatch image preparation
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1883934 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
8 files changed, 101 insertions, 108 deletions
diff --git a/src/examples/src/org/apache/poi/examples/hwmf/ROP3Table.java b/src/examples/src/org/apache/poi/examples/hwmf/ROP3Table.java index 13d49468e8..2e680a0aa3 100644 --- a/src/examples/src/org/apache/poi/examples/hwmf/ROP3Table.java +++ b/src/examples/src/org/apache/poi/examples/hwmf/ROP3Table.java @@ -29,12 +29,12 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; -import java.awt.image.IndexColorModel; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; +import org.apache.poi.hwmf.draw.HwmfGraphics; import org.apache.poi.hwmf.draw.HwmfROP3Composite; import org.apache.poi.hwmf.record.HwmfTernaryRasterOp; @@ -44,28 +44,17 @@ import org.apache.poi.hwmf.record.HwmfTernaryRasterOp; * inspired from http://www.evmsoft.net/en/roptest.html */ public final class ROP3Table { - private ROP3Table() { - } - - private static byte[] PATTERN = { - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 1, 1, 0, 1, 1, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, 1, 0, 1, - 1, 0, 1, 1, 1, 0, 1, 1, - 0, 1, 0, 1, 0, 1, 0, 1, - }; + private ROP3Table() {} + private static final long PATTERN = 0xAADDAA55AADDAA55L; private static final HwmfTernaryRasterOp[] OPS = HwmfTernaryRasterOp.values(); - private static final int COLS = 16; - private static final double BOX = 100, SCALE = 1, HEADER = 1.1; + private static final int COLS = 16, BOX = 100; + private static final double SCALE = 2, HEADER = 1.1; - private static final Rectangle2D RECT = new Rectangle2D.Double(0.05* BOX, 0.05* BOX, 0.90* BOX, 0.90* BOX); - private static final Shape CIRCLE_BIG = new Ellipse2D.Double(0.15* BOX, 0.15* BOX, 0.70* BOX, 0.70* BOX); - private static final Shape CIRCLE_SMALL = new Ellipse2D.Double(0.40* BOX, 0.40* BOX, 0.20* BOX, 0.20* BOX); - private static final Shape LABEL_BOX = new Rectangle.Double(0.06* BOX, 0.85* BOX, 0.88* BOX, 0.10* BOX); + private static final Rectangle2D RECT = new Rectangle2D.Double(0.05*BOX, 0.05*BOX, 0.90*BOX, 0.90*BOX); + private static final Shape CIRCLE_BIG = new Ellipse2D.Double(0.15*BOX, 0.15*BOX, 0.70*BOX, 0.70*BOX); + private static final Shape CIRCLE_SMALL = new Ellipse2D.Double(0.40*BOX, 0.40*BOX, 0.20*BOX, 0.20*BOX); + private static final Shape LABEL_BOX = new Rectangle.Double(0.06*BOX, 0.85*BOX, 0.88*BOX, 0.10*BOX); private static final AlphaComposite SRC_OVER = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); @@ -77,29 +66,23 @@ public final class ROP3Table { BufferedImage dest = new BufferedImage( (int)(BOX * COLS * SCALE), - (int)(BOX *(Math.max(OPS.length/COLS,1) + HEADER)* SCALE), + (int)(BOX * (Math.max(OPS.length/COLS,1) + HEADER) * SCALE), BufferedImage.TYPE_INT_ARGB); Graphics2D g = dest.createGraphics(); - - g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 10)); - g.setTransform(INIT_AT); + g.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 10)); + g.translate(BOX * (COLS-5) / 2., 0); g.setColor(Color.BLACK); - for (int i=0; i<3; i++) { - String str = new String[]{"Dest:","Source:","Pattern:"}[i]; - TextLayout t = new TextLayout(str, g.getFont(), g.getFontRenderContext()); - Rectangle2D b = t.getBounds(); - g.drawString(str, (float)(((i*2+0.95)*BOX - b.getWidth())), (float)(0.55 * BOX)); - } - - g.translate(BOX, 0); fillDest(g); + fillLabel(g, "Dest"); g.translate(2*BOX, 0); g.drawImage(source, 0, 0, null); + fillLabel(g, "Source"); g.translate(2*BOX, 0); g.setPaint(new TexturePaint(pattern, RECT)); g.fill(RECT); + fillLabel(g, "Pattern"); int idx=0; for (HwmfTernaryRasterOp op : OPS) { @@ -109,7 +92,7 @@ public final class ROP3Table { fillDest(g); fillPattern(g, op, pattern, source); - fillLabel(g, op); + fillLabel(g, op.name()); idx++; } @@ -118,20 +101,17 @@ public final class ROP3Table { } private static BufferedImage getPattern() { - byte[] bw = { 0, -1 }; - BufferedImage pattern = new BufferedImage(8, 8, BufferedImage.TYPE_BYTE_INDEXED, new IndexColorModel(1, 2, bw, bw, bw)); - pattern.getRaster().setDataElements(0, 0, 8, 8, PATTERN); - return pattern; + return HwmfGraphics.getPatternFromLong(PATTERN, Color.BLACK, Color.WHITE, false); } private static BufferedImage getSource() { - BufferedImage checker = new BufferedImage((int) BOX, (int) BOX, BufferedImage.TYPE_INT_ARGB); + BufferedImage checker = new BufferedImage(BOX, BOX, BufferedImage.TYPE_INT_ARGB); Graphics2D cg = checker.createGraphics(); cg.setColor(Color.PINK); - cg.fill(new Rectangle2D.Double(0.05* BOX, 0.05* BOX, 0.90* BOX, 0.90* BOX)); + cg.fill(RECT); cg.setColor(new Color(0xE6E6FA, false)); - cg.fill(new Rectangle2D.Double(0.05* BOX, 0.05* BOX, 0.45* BOX, 0.45* BOX)); - cg.fill(new Rectangle2D.Double(0.50* BOX, 0.50* BOX, 0.45* BOX, 0.45* BOX)); + cg.fill(new Rectangle2D.Double(0.05*BOX, 0.05*BOX, 0.45*BOX, 0.45*BOX)); + cg.fill(new Rectangle2D.Double(0.50*BOX, 0.50*BOX, 0.45*BOX, 0.45*BOX)); cg.dispose(); return checker; } @@ -154,15 +134,13 @@ public final class ROP3Table { g.setComposite(SRC_OVER); } - private static void fillLabel(Graphics2D g, HwmfTernaryRasterOp op) { + private static void fillLabel(Graphics2D g, String str) { g.setColor(Color.WHITE); g.fill(LABEL_BOX); g.setColor(Color.BLACK); - TextLayout t = new TextLayout(op.name(), g.getFont(), g.getFontRenderContext()); + TextLayout t = new TextLayout(str, g.getFont(), g.getFontRenderContext()); Rectangle2D b = t.getBounds(); - g.drawString(op.name(), (float)((BOX -b.getWidth())/2.), (float)(0.94* BOX)); - + g.drawString(str, (float)((BOX -b.getWidth())/2.), (float)(0.94*BOX)); } - } diff --git a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java index 41aa52aea8..113f8ede25 100644 --- a/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java +++ b/src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java @@ -390,18 +390,19 @@ public class HemfGraphics extends HwmfGraphics { @Override public void fill(Shape shape) { HemfDrawProperties prop = getProperties(); + if (prop.getBrushStyle() == HwmfBrushStyle.BS_NULL) { + return; + } Composite old = graphicsCtx.getComposite(); graphicsCtx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); - if (prop.getBrushStyle() != HwmfBrushStyle.BS_NULL) { - if (prop.getBkMode() == HwmfMisc.WmfSetBkMode.HwmfBkMode.OPAQUE) { - graphicsCtx.setPaint(prop.getBackgroundColor().getColor()); - graphicsCtx.fill(shape); - } +// if (prop.getBkMode() == HwmfMisc.WmfSetBkMode.HwmfBkMode.OPAQUE) { +// graphicsCtx.setPaint(prop.getBackgroundColor().getColor()); +// graphicsCtx.fill(shape); +// } - graphicsCtx.setPaint(getFill()); - graphicsCtx.fill(shape); - } + graphicsCtx.setPaint(getFill()); + graphicsCtx.fill(shape); graphicsCtx.setComposite(old); } diff --git a/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java b/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java index deae850ceb..e5964ae871 100644 --- a/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java +++ b/src/scratchpad/src/org/apache/poi/hemf/usermodel/HemfPicture.java @@ -197,11 +197,13 @@ public class HemfPicture implements Iterable<HemfRecord>, GenericRecord { HemfGraphics g = new HemfGraphics(ctx, b); + int idx=0; for (HemfRecord r : getRecords()) { try { g.draw(r); } catch (RuntimeException ignored) { } + idx++; } } finally { ctx.setTransform(at); diff --git a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java index f37bf79784..f0993b24da 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfDrawProperties.java @@ -28,6 +28,7 @@ import java.awt.image.BufferedImage; import java.util.List; import org.apache.poi.hwmf.draw.HwmfGraphics.BufferedImageRenderer; +import org.apache.poi.hwmf.record.HwmfBinaryRasterOp; import org.apache.poi.hwmf.record.HwmfBrushStyle; import org.apache.poi.hwmf.record.HwmfColorRef; import org.apache.poi.hwmf.record.HwmfFill.WmfSetPolyfillMode.HwmfPolyfillMode; @@ -68,6 +69,7 @@ public class HwmfDrawProperties { private HwmfTextVerticalAlignment textVAlignLatin; private HwmfTextAlignment textAlignAsian; private HwmfTextVerticalAlignment textVAlignAsian; + private HwmfBinaryRasterOp rasterOp2; private HwmfTernaryRasterOp rasterOp3; protected Shape clip; protected final AffineTransform transform = new AffineTransform(); @@ -92,7 +94,8 @@ public class HwmfDrawProperties { textVAlignLatin = HwmfTextVerticalAlignment.TOP; textAlignAsian = HwmfTextAlignment.RIGHT; textVAlignAsian = HwmfTextVerticalAlignment.TOP; - rasterOp3 = HwmfTernaryRasterOp.PATCOPY; + rasterOp2 = HwmfBinaryRasterOp.R2_COPYPEN; + rasterOp3 = null; // default: PATCOPY? clip = null; font = new HwmfFont(); font.initDefaults(); @@ -128,6 +131,7 @@ public class HwmfDrawProperties { this.textVAlignLatin = other.textVAlignLatin; this.textAlignAsian = other.textAlignAsian; this.textVAlignAsian = other.textVAlignAsian; + this.rasterOp2 = other.rasterOp2; this.rasterOp3 = other.rasterOp3; this.transform.setTransform(other.transform); this.clip = other.clip; @@ -284,7 +288,7 @@ public class HwmfDrawProperties { } public void setBrushBitmap(BufferedImage brushBitmap) { - this.brushBitmap = new BufferedImageRenderer(brushBitmap); + this.brushBitmap = (brushBitmap == null) ? null : new BufferedImageRenderer(brushBitmap); } /** @@ -423,4 +427,11 @@ public class HwmfDrawProperties { this.brushTransform.setTransform(brushTransform); } } + public HwmfBinaryRasterOp getRasterOp2() { + return rasterOp2; + } + + public void setRasterOp2(HwmfBinaryRasterOp rasterOp2) { + this.rasterOp2 = rasterOp2; + } } diff --git a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java index 8e888313f9..4c49216c30 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java @@ -40,6 +40,8 @@ import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.awt.image.DataBuffer; +import java.awt.image.IndexColorModel; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.text.AttributedString; @@ -60,7 +62,6 @@ import org.apache.poi.common.usermodel.fonts.FontCharset; import org.apache.poi.common.usermodel.fonts.FontInfo; import org.apache.poi.hwmf.record.HwmfBrushStyle; import org.apache.poi.hwmf.record.HwmfFont; -import org.apache.poi.hwmf.record.HwmfHatchStyle; import org.apache.poi.hwmf.record.HwmfMapMode; import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode; import org.apache.poi.hwmf.record.HwmfObjectTableEntry; @@ -190,18 +191,18 @@ public class HwmfGraphics implements HwmfCharsetAware { public void fill(Shape shape) { HwmfDrawProperties prop = getProperties(); - Composite old = graphicsCtx.getComposite(); - graphicsCtx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); if (prop.getBrushStyle() != HwmfBrushStyle.BS_NULL) { - if (prop.getBkMode() == HwmfBkMode.OPAQUE) { - graphicsCtx.setPaint(prop.getBackgroundColor().getColor()); - graphicsCtx.fill(shape); - } + Composite old = graphicsCtx.getComposite(); + graphicsCtx.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); +// if (prop.getBkMode() == HwmfBkMode.OPAQUE) { +// graphicsCtx.setPaint(prop.getBackgroundColor().getColor()); +// graphicsCtx.fill(shape); +// } graphicsCtx.setPaint(getFill()); graphicsCtx.fill(shape); + graphicsCtx.setComposite(old); } - graphicsCtx.setComposite(old); draw(shape); } @@ -253,31 +254,27 @@ public class HwmfGraphics implements HwmfCharsetAware { } protected Paint getHatchedFill() { - int dim = 7, mid = 3; - BufferedImage bi = new BufferedImage(dim, dim, BufferedImage.TYPE_4BYTE_ABGR); - Graphics2D g = bi.createGraphics(); - Color c = (getProperties().getBkMode() == HwmfBkMode.TRANSPARENT) - ? new Color(0, true) - : getProperties().getBackgroundColor().getColor(); - g.setColor(c); - g.fillRect(0, 0, dim, dim); - g.setColor(getProperties().getBrushColor().getColor()); - HwmfHatchStyle h = getProperties().getBrushHatch(); - if (h == HwmfHatchStyle.HS_HORIZONTAL || h == HwmfHatchStyle.HS_CROSS) { - g.drawLine(0, mid, dim, mid); - } - if (h == HwmfHatchStyle.HS_VERTICAL || h == HwmfHatchStyle.HS_CROSS) { - g.drawLine(mid, 0, mid, dim); - } - if (h == HwmfHatchStyle.HS_FDIAGONAL || h == HwmfHatchStyle.HS_DIAGCROSS) { - g.drawLine(0, 0, dim, dim); - } - if (h == HwmfHatchStyle.HS_BDIAGONAL || h == HwmfHatchStyle.HS_DIAGCROSS) { - g.drawLine(0, dim, dim, 0); - } - // TODO: handle new HS_* enumeration values - g.dispose(); - return new TexturePaint(bi, new Rectangle(0,0,dim,dim)); + HwmfDrawProperties prop = getProperties(); + BufferedImage pattern = getPatternFromLong( + prop.getBrushHatch().pattern, + prop.getBackgroundColor().getColor(), + prop.getBrushColor().getColor(), + prop.getBkMode() == HwmfBkMode.TRANSPARENT + ); + return new TexturePaint(pattern, new Rectangle(0,0,8,8)); + } + + public static BufferedImage getPatternFromLong(long patternLng, Color background, Color foreground, boolean hasAlpha) { + final int[] cmap = {background.getRGB(), foreground.getRGB()}; + final IndexColorModel icm = new IndexColorModel(1, 2, cmap, 0, hasAlpha, hasAlpha ? 0 : -1, DataBuffer.TYPE_BYTE); + final BufferedImage pattern = new BufferedImage(8, 8, BufferedImage.TYPE_BYTE_INDEXED, icm); + + byte[] pt = new byte[64]; + for (int i=0; i<pt.length; i++) { + pt[i] = (byte)((patternLng >>> i) & 1); + } + pattern.getRaster().setDataElements(0, 0, 8, 8, pt); + return pattern; } protected Paint getPatternPaint() { diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java index 6574deaed3..2d1a065670 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java @@ -22,34 +22,37 @@ package org.apache.poi.hwmf.record; */ public enum HwmfHatchStyle { /** ----- - A horizontal hatch */ - HS_HORIZONTAL(0x0000), + HS_HORIZONTAL(0x0000, 0x000000FF000000FFL), /** ||||| - A vertical hatch */ - HS_VERTICAL(0x0001), + HS_VERTICAL(0x0001, 0x8888888888888888L), /** \\\\\ - A 45-degree downward, left-to-right hatch. */ - HS_FDIAGONAL(0x0002), + HS_FDIAGONAL(0x0002, 0x0804020180402010L), /** ///// - A 45-degree upward, left-to-right hatch. */ - HS_BDIAGONAL(0x0003), + HS_BDIAGONAL(0x0003, 0x1020408001020408L), /** +++++ - A horizontal and vertical cross-hatch. */ - HS_CROSS(0x0004), + HS_CROSS(0x0004, 0x111111FF111111FFL), /** xxxxx - A 45-degree crosshatch. */ - HS_DIAGCROSS(0x0005), + HS_DIAGCROSS(0x0005, 0x1824428181422418L), /** The hatch is not a pattern, but is a solid color. */ - HS_SOLIDCLR(0x0006), + HS_SOLIDCLR(0x0006, 0xFFFFFFFFFFFFFFFFL), /** The hatch is not a pattern, but is a dithered color. */ - HS_DITHEREDCLR(0x0007), + HS_DITHEREDCLR(0x0007, 0xAA55AA55AA55AA55L), /** The hatch is not a pattern, but is a solid color, defined by the current text (foreground) color. */ - HS_SOLIDTEXTCLR(0x0008), + HS_SOLIDTEXTCLR(0x0008, 0xFFFFFFFFFFFFFFFFL), /** The hatch is not a pattern, but is a dithered color, defined by the current text (foreground) color. */ - HS_DITHEREDTEXTCLR(0x0009), + HS_DITHEREDTEXTCLR(0x0009, 0xAA55AA55AA55AA55L), /** The hatch is not a pattern, but is a solid color, defined by the current background color. */ - HS_SOLIDBKCLR(0x000A), + HS_SOLIDBKCLR(0x000A, 0x0000000000000000L), /** The hatch is not a pattern, but is a dithered color, defined by the current background color. */ - HS_DITHEREDBKCLR(0x000B) + HS_DITHEREDBKCLR(0x000B, 0xAA55AA55AA55AA55L) ; int flag; - HwmfHatchStyle(int flag) { + public long pattern; + + HwmfHatchStyle(int flag, long pattern) { this.flag = flag; + this.pattern = pattern; } public static HwmfHatchStyle valueOf(int flag) { diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java index b9fb9cc229..b4ecc2fc3c 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMisc.java @@ -373,7 +373,8 @@ public class HwmfMisc { @Override public void draw(HwmfGraphics ctx) { - + HwmfDrawProperties prop = ctx.getProperties(); + prop.setRasterOp2(drawMode); } @Override @@ -532,7 +533,7 @@ public class HwmfMisc { public void draw(HwmfGraphics ctx) { ctx.addObjectTableEntry(this); } - + @Override public void applyObject(HwmfGraphics ctx) { if (patternDib != null && !patternDib.isValid()) { @@ -658,7 +659,7 @@ public class HwmfMisc { public void draw(HwmfGraphics ctx) { ctx.addObjectTableEntry(this); } - + @Override public void applyObject(HwmfGraphics ctx) { HwmfDrawProperties dp = ctx.getProperties(); @@ -708,7 +709,7 @@ public class HwmfMisc { public void draw(HwmfGraphics ctx) { ctx.addObjectTableEntry(this); } - + @Override public void applyObject(HwmfGraphics ctx) { HwmfDrawProperties p = ctx.getProperties(); @@ -814,7 +815,7 @@ public class HwmfMisc { public void draw(HwmfGraphics ctx) { ctx.addObjectTableEntry(this); } - + @Override public void applyObject(HwmfGraphics ctx) { HwmfDrawProperties p = ctx.getProperties(); diff --git a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java index f8e410633c..b4c0b6ce42 100644 --- a/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java +++ b/src/scratchpad/src/org/apache/poi/hwmf/record/HwmfTernaryRasterOp.java @@ -390,7 +390,7 @@ public enum HwmfTernaryRasterOp { } public int getOpCode() { - return opValue & 0xFF; + return opValue & 0xFFFF; } public String describeCmd() { |