Skip to content

Commit

Permalink
#64716 - wmf display error
Browse files Browse the repository at this point in the history
change hatch image preparation

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1883934 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
kiwiwings committed Nov 29, 2020
1 parent 20c883b commit 17592b0
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 108 deletions.
70 changes: 24 additions & 46 deletions src/examples/src/org/apache/poi/examples/hwmf/ROP3Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ Licensed to the Apache Software Foundation (ASF) under one or more
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;

Expand All @@ -44,28 +44,17 @@ Licensed to the Apache Software Foundation (ASF) under one or more
* 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);

Expand All @@ -77,29 +66,23 @@ public static void main(String[] args) throws IOException {

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) {
Expand All @@ -109,7 +92,7 @@ public static void main(String[] args) throws IOException {

fillDest(g);
fillPattern(g, op, pattern, source);
fillLabel(g, op);
fillLabel(g, op.name());
idx++;
}

Expand All @@ -118,20 +101,17 @@ public static void main(String[] args) throws IOException {
}

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;
}
Expand All @@ -154,15 +134,13 @@ private static void fillPattern(Graphics2D g, HwmfTernaryRasterOp op, BufferedIm
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));
}

}
17 changes: 9 additions & 8 deletions src/scratchpad/src/org/apache/poi/hemf/draw/HemfGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -390,18 +390,19 @@ public void updateWindowMapMode() {
@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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,13 @@ public void draw(Graphics2D ctx, Rectangle2D graphicsBounds) {

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Licensed to the Apache Software Foundation (ASF) under one or more
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;
Expand Down Expand Up @@ -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();
Expand All @@ -92,7 +94,8 @@ public 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();
Expand Down Expand Up @@ -128,6 +131,7 @@ public HwmfDrawProperties(HwmfDrawProperties other) {
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;
Expand Down Expand Up @@ -284,7 +288,7 @@ public void setBrushBitmap(ImageRenderer brushBitmap) {
}

public void setBrushBitmap(BufferedImage brushBitmap) {
this.brushBitmap = new BufferedImageRenderer(brushBitmap);
this.brushBitmap = (brushBitmap == null) ? null : new BufferedImageRenderer(brushBitmap);
}

/**
Expand Down Expand Up @@ -423,4 +427,11 @@ public void setBrushTransform(AffineTransform brushTransform) {
this.brushTransform.setTransform(brushTransform);
}
}
public HwmfBinaryRasterOp getRasterOp2() {
return rasterOp2;
}

public void setRasterOp2(HwmfBinaryRasterOp rasterOp2) {
this.rasterOp2 = rasterOp2;
}
}
63 changes: 30 additions & 33 deletions src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Licensed to the Apache Software Foundation (ASF) under one or more
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;
Expand All @@ -60,7 +62,6 @@ Licensed to the Apache Software Foundation (ASF) under one or more
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;
Expand Down Expand Up @@ -190,18 +191,18 @@ public void draw(Shape shape) {
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);
}
Expand Down Expand Up @@ -253,31 +254,27 @@ protected Paint getSolidFill() {
}

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() {
Expand Down
29 changes: 16 additions & 13 deletions src/scratchpad/src/org/apache/poi/hwmf/record/HwmfHatchStyle.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,37 @@ Licensed to the Apache Software Foundation (ASF) under one or more
*/
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) {
Expand Down
Loading

0 comments on commit 17592b0

Please sign in to comment.