import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
+import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.hwmf.draw.HwmfGraphics;
public class HemfGraphics extends HwmfGraphics {
public HemfGraphics(Graphics2D graphicsCtx, Rectangle2D bbox) {
super(graphicsCtx,bbox);
}
+
+ @Override
+ public HemfDrawProperties getProperties() {
+ if (prop == null) {
+ prop = new HemfDrawProperties();
+ }
+ return (HemfDrawProperties)prop;
+ }
+
+ @Override
+ public void saveProperties() {
+ assert(prop != null);
+ propStack.add(prop);
+ prop = new HemfDrawProperties((HemfDrawProperties)prop);
+ }
}
package org.apache.poi.hemf.record.emf;
-import java.awt.geom.AffineTransform;
+import static org.apache.poi.hwmf.record.HwmfBrushStyle.BS_NULL;
+import static org.apache.poi.hwmf.record.HwmfBrushStyle.BS_SOLID;
+
+import java.awt.Color;
import java.awt.geom.Dimension2D;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
+import org.apache.poi.hemf.draw.HemfDrawProperties;
import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hwmf.draw.HwmfGraphics;
+import org.apache.poi.hwmf.record.HwmfColorRef;
import org.apache.poi.hwmf.record.HwmfDraw;
import org.apache.poi.hwmf.record.HwmfDraw.WmfSelectObject;
+import org.apache.poi.hwmf.record.HwmfPenStyle;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
*/
public static class EmfSelectObject extends WmfSelectObject implements HemfRecord {
+ private static final HwmfColorRef WHITE = new HwmfColorRef(Color.WHITE);
+ private static final HwmfColorRef LTGRAY = new HwmfColorRef(new Color(0x00C0C0C0));
+ private static final HwmfColorRef GRAY = new HwmfColorRef(new Color(0x00808080));
+ private static final HwmfColorRef DKGRAY = new HwmfColorRef(new Color(0x00404040));
+ private static final HwmfColorRef BLACK = new HwmfColorRef(Color.BLACK);
+
@Override
public HemfRecordType getEmfRecordType() {
return HemfRecordType.selectObject;
objectIndex = leis.readInt();
return LittleEndianConsts.INT_SIZE;
}
+
+ @Override
+ public void draw(HemfGraphics ctx) {
+ if ((objectIndex & 0x80000000) != 0) {
+ selectStockObject(ctx);
+ } else {
+ super.draw(ctx);
+ }
+ }
+
+ private void selectStockObject(HemfGraphics ctx) {
+ final HemfDrawProperties prop = ctx.getProperties();
+ switch (objectIndex) {
+ case 0x80000000:
+ // WHITE_BRUSH - A white, solid-color brush
+ // BrushStyle: BS_SOLID
+ // Color: 0x00FFFFFF
+ prop.setBrushColor(WHITE);
+ prop.setBrushStyle(BS_SOLID);
+ break;
+ case 0x80000001:
+ // LTGRAY_BRUSH - A light gray, solid-color brush
+ // BrushStyle: BS_SOLID
+ // Color: 0x00C0C0C0
+ prop.setBrushColor(LTGRAY);
+ prop.setBrushStyle(BS_SOLID);
+ break;
+ case 0x80000002:
+ // GRAY_BRUSH - A gray, solid-color brush
+ // BrushStyle: BS_SOLID
+ // Color: 0x00808080
+ prop.setBrushColor(GRAY);
+ prop.setBrushStyle(BS_SOLID);
+ break;
+ case 0x80000003:
+ // DKGRAY_BRUSH - A dark gray, solid color brush
+ // BrushStyle: BS_SOLID
+ // Color: 0x00404040
+ prop.setBrushColor(DKGRAY);
+ prop.setBrushStyle(BS_SOLID);
+ break;
+ case 0x80000004:
+ // BLACK_BRUSH - A black, solid color brush
+ // BrushStyle: BS_SOLID
+ // Color: 0x00000000
+ prop.setBrushColor(BLACK);
+ prop.setBrushStyle(BS_SOLID);
+ break;
+ case 0x80000005:
+ // NULL_BRUSH - A null brush
+ // BrushStyle: BS_NULL
+ prop.setBrushStyle(BS_NULL);
+ break;
+ case 0x80000006:
+ // WHITE_PEN - A white, solid-color pen
+ // PenStyle: PS_COSMETIC + PS_SOLID
+ // ColorRef: 0x00FFFFFF
+ prop.setPenStyle(HwmfPenStyle.valueOf(0));
+ prop.setPenWidth(1);
+ prop.setPenColor(WHITE);
+ break;
+ case 0x80000007:
+ // BLACK_PEN - A black, solid-color pen
+ // PenStyle: PS_COSMETIC + PS_SOLID
+ // ColorRef: 0x00000000
+ prop.setPenStyle(HwmfPenStyle.valueOf(0));
+ prop.setPenWidth(1);
+ prop.setPenColor(BLACK);
+ break;
+ case 0x80000008:
+ // NULL_PEN - A null pen
+ // PenStyle: PS_NULL
+ prop.setPenStyle(HwmfPenStyle.valueOf(HwmfPenStyle.HwmfLineDash.NULL.wmfFlag));
+ break;
+ case 0x8000000A:
+ // OEM_FIXED_FONT - A fixed-width, OEM character set
+ // Charset: OEM_CHARSET
+ // PitchAndFamily: FF_DONTCARE + FIXED_PITCH
+ break;
+ case 0x8000000B:
+ // ANSI_FIXED_FONT - A fixed-width font
+ // Charset: ANSI_CHARSET
+ // PitchAndFamily: FF_DONTCARE + FIXED_PITCH
+ break;
+ case 0x8000000C:
+ // ANSI_VAR_FONT - A variable-width font
+ // Charset: ANSI_CHARSET
+ // PitchAndFamily: FF_DONTCARE + VARIABLE_PITCH
+ break;
+ case 0x8000000D:
+ // SYSTEM_FONT - A font that is guaranteed to be available in the operating system
+ break;
+ case 0x8000000E:
+ // DEVICE_DEFAULT_FONT
+ // The default font that is provided by the graphics device driver for the current output device
+ break;
+ case 0x8000000F:
+ // DEFAULT_PALETTE
+ // The default palette that is defined for the current output device.
+ break;
+ case 0x80000010:
+ // SYSTEM_FIXED_FONT
+ // A fixed-width font that is guaranteed to be available in the operating system.
+ break;
+ case 0x80000011:
+ // DEFAULT_GUI_FONT
+ // The default font that is used for user interface objects such as menus and dialog boxes.
+ break;
+ case 0x80000012:
+ // DC_BRUSH
+ // The solid-color brush that is currently selected in the playback device context.
+ break;
+ case 0x80000013:
+ // DC_PEN
+ // The solid-color pen that is currently selected in the playback device context.
+ break;
+ }
+ }
+
}
protected long readPoint(LittleEndianInputStream leis, Point2D point) {
return readPointS(leis, point);
}
+ }
+
+ public static class EmfBeginPath implements HemfRecord {
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.beginPath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return 0;
+ }
+ }
+
+ public static class EmfEndPath implements HemfRecord {
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.endPath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return 0;
+ }
+ }
+
+ public static class EmfAbortPath implements HemfRecord {
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.abortPath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return 0;
+ }
+ }
+
+ public static class EmfCloseFigure implements HemfRecord {
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.closeFigure;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return 0;
+ }
+ }
+
+ public static class EmfFlattenPath implements HemfRecord {
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.flattenPath;
+ }
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return 0;
+ }
}
+
+ public static class EmfWidenPath implements HemfRecord {
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.widenPath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return 0;
+ }
+ }
+
+ /**
+ * The EMR_STROKEPATH record renders the specified path by using the current pen.
+ */
+ public static class EmfStrokePath implements HemfRecord {
+ protected final Rectangle2D bounds = new Rectangle2D.Double();
+
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.strokePath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ // A 128-bit WMF RectL object, which specifies bounding rectangle, in device units
+ return readRectL(leis, bounds);
+ }
+ }
+
static long readRectL(LittleEndianInputStream leis, Rectangle2D bounds) {
/* A 32-bit signed integer that defines the x coordinate, in logical coordinates,
* of the ... corner of the rectangle.
return 6 * LittleEndian.INT_SIZE;
}
+
+ /**
+ * The EMR_FILLPATH record closes any open figures in the current path and fills the path's interior by
+ * using the current brush and polygon-filling mode.
+ */
+ public static class EmfFillPath implements HemfRecord {
+ protected final Rectangle2D bounds = new Rectangle2D.Double();
+
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.fillPath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ // A 128-bit WMF RectL object, which specifies bounding rectangle, in device units
+ return readRectL(leis, bounds);
+ }
+ }
}
package org.apache.poi.hemf.record.emf;
-import static org.apache.poi.hemf.record.emf.HemfDraw.readDimensionInt;
+import static org.apache.poi.hemf.record.emf.HemfDraw.readPointL;
import static org.apache.poi.hemf.record.emf.HemfFill.readBitmap;
import static org.apache.poi.hemf.record.emf.HemfRecordIterator.HEADER_SIZE;
+import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hwmf.record.HwmfPalette.PaletteEntry;
import org.apache.poi.hwmf.record.HwmfPenStyle;
import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
-import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
// A 32-bit unsigned integer that specifies the number of palette entries.
- int nPalEntries = (int)leis.readUInt();
+ int nPalEntries = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the offset to the palette entries from the start of this record.
- int offPalEntries = (int)leis.readUInt();
+ int offPalEntries = (int) leis.readUInt();
- int size = 2*LittleEndianConsts.INT_SIZE;
- int undefinedSpace1 = (int)(offPalEntries - size - HEADER_SIZE);
+ int size = 2 * LittleEndianConsts.INT_SIZE;
+ int undefinedSpace1 = (int) (offPalEntries - size - HEADER_SIZE);
assert (undefinedSpace1 >= 0);
leis.skipFully(undefinedSpace1);
size += undefinedSpace1;
- for (int i=0; i<nPalEntries; i++) {
+ for (int i = 0; i < nPalEntries; i++) {
PaletteEntry pe = new PaletteEntry();
size += pe.init(leis);
}
- int undefinedSpace2 = (int)(recordSize - size - LittleEndianConsts.INT_SIZE);
+ int undefinedSpace2 = (int) (recordSize - size - LittleEndianConsts.INT_SIZE);
assert (undefinedSpace2 >= 0);
leis.skipFully(undefinedSpace2);
size += undefinedSpace2;
// LogPaletteEntry objects, if they exist, MUST precede this field.
long sizeLast = leis.readUInt();
size += LittleEndianConsts.INT_SIZE;
- assert ((sizeLast-HEADER_SIZE) == recordSize && recordSize == size);
+ assert ((sizeLast - HEADER_SIZE) == recordSize && recordSize == size);
return size;
}
* A 32-bit unsigned integer that specifies the background mode
* and MUST be in the BackgroundMode (section 2.1.4) enumeration
*/
- bkMode = HwmfBkMode.valueOf((int)leis.readUInt());
+ bkMode = HwmfBkMode.valueOf((int) leis.readUInt());
return LittleEndianConsts.INT_SIZE;
}
}
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- return super.init(leis, recordSize, (int)recordId);
+ return super.init(leis, recordSize, (int) recordId);
}
}
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
// A 32-bit unsigned integer whose definition MUST be in the MapMode enumeration
- mapMode = HwmfMapMode.valueOf((int)leis.readUInt());
+ mapMode = HwmfMapMode.valueOf((int) leis.readUInt());
return LittleEndianConsts.INT_SIZE;
}
}
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
// A 32-bit unsigned integer that specifies the raster operation mode and
// MUST be in the WMF Binary Raster Op enumeration
- drawMode = HwmfBinaryRasterOp.valueOf((int)leis.readUInt());
+ drawMode = HwmfBinaryRasterOp.valueOf((int) leis.readUInt());
return LittleEndianConsts.INT_SIZE;
}
}
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
// A 32-bit unsigned integer that specifies the stretch mode and MAY be
// in the StretchMode enumeration.
- stretchBltMode = StretchBltMode.valueOf((int)leis.readUInt());
+ stretchBltMode = StretchBltMode.valueOf((int) leis.readUInt());
return LittleEndianConsts.INT_SIZE;
}
}
- /** The EMR_CREATEBRUSHINDIRECT record defines a logical brush for graphics operations. */
+ /**
+ * The EMR_CREATEBRUSHINDIRECT record defines a logical brush for graphics operations.
+ */
public static class EmfCreateBrushIndirect extends HwmfMisc.WmfCreateBrushIndirect implements HemfRecord {
/**
* A 32-bit unsigned integer that specifies the index of the logical brush object in the
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- brushIdx = (int)leis.readUInt();
+ brushIdx = (int) leis.readUInt();
- brushStyle = HwmfBrushStyle.valueOf((int)leis.readUInt());
+ brushStyle = HwmfBrushStyle.valueOf((int) leis.readUInt());
colorRef = new HwmfColorRef();
int size = colorRef.init(leis);
- brushHatch = HwmfHatchStyle.valueOf((int)leis.readUInt());
- return size+3*LittleEndianConsts.INT_SIZE;
+ brushHatch = HwmfHatchStyle.valueOf((int) leis.readUInt());
+ return size + 3 * LittleEndianConsts.INT_SIZE;
}
}
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- objectIndex = (int)leis.readUInt();
+ objectIndex = (int) leis.readUInt();
return LittleEndianConsts.INT_SIZE;
}
}
- /** The EMR_CREATEPEN record defines a logical pen for graphics operations. */
+ /**
+ * The EMR_CREATEPEN record defines a logical pen for graphics operations.
+ */
public static class EmfCreatePen extends HwmfMisc.WmfCreatePenIndirect implements HemfRecord {
/**
* A 32-bit unsigned integer that specifies the index of the logical palette object
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- penIndex = (int)leis.readUInt();
+ penIndex = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the PenStyle.
// The value MUST be defined from the PenStyle enumeration table
- penStyle = HwmfPenStyle.valueOf((int)leis.readUInt());
+ penStyle = HwmfPenStyle.valueOf((int) leis.readUInt());
int widthX = leis.readInt();
int widthY = leis.readInt();
int size = colorRef.init(leis);
- return size + 4*LittleEndianConsts.INT_SIZE;
+ return size + 4 * LittleEndianConsts.INT_SIZE;
}
}
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
final int startIdx = leis.getReadIndex();
- penIndex = (int)leis.readUInt();
+ penIndex = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the offset from the start of this
// record to the DIB header, if the record contains a DIB.
- int offBmi = (int)leis.readUInt();
+ int offBmi = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the size of the DIB header, if the
// record contains a DIB.
- int cbBmi = (int)leis.readUInt();
+ int cbBmi = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the offset from the start of this
// record to the DIB bits, if the record contains a DIB.
- int offBits = (int)leis.readUInt();
+ int offBits = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the size of the DIB bits, if the record
// contains a DIB.
- int cbBits = (int)leis.readUInt();
+ int cbBits = (int) leis.readUInt();
// A 32-bit unsigned integer that specifies the PenStyle.
// The value MUST be defined from the PenStyle enumeration table
- penStyle = HwmfPenStyle.valueOf((int)leis.readUInt());
+ penStyle = HwmfPenStyle.valueOf((int) leis.readUInt());
// A 32-bit unsigned integer that specifies the width of the line drawn by the pen.
// If the pen type in the PenStyle field is PS_GEOMETRIC, this value is the width in logical
// If the pen type in the PenStyle field is PS_GEOMETRIC, this value MUST be either BS_SOLID or BS_HATCHED.
// The value of this field can be BS_NULL, but only if the line style specified in PenStyle is PS_NULL.
// The BS_NULL style SHOULD be used to specify a brush that has no effect
- brushStyle = HwmfBrushStyle.valueOf((int)leis.readUInt());
+ brushStyle = HwmfBrushStyle.valueOf((int) leis.readUInt());
int size = 8 * LittleEndianConsts.INT_SIZE;
// The number of elements in the array specified in the StyleEntry
// field. This value SHOULD be zero if PenStyle does not specify PS_USERSTYLE.
- final int numStyleEntries = (int)leis.readUInt();
- size += 2*LittleEndianConsts.INT_SIZE;
+ final int numStyleEntries = (int) leis.readUInt();
+ size += 2 * LittleEndianConsts.INT_SIZE;
- assert(numStyleEntries == 0 || penStyle.getLineDash() == HwmfLineDash.USERSTYLE);
+ assert (numStyleEntries == 0 || penStyle.getLineDash() == HwmfLineDash.USERSTYLE);
// An optional array of 32-bit unsigned integers that defines the lengths of
// dashes and gaps in the line drawn by this pen, when the value of PenStyle is
styleEntry = new int[numStyleEntries];
- for (int i=0; i<numStyleEntries; i++) {
- styleEntry[i] = (int)leis.readUInt();
+ for (int i = 0; i < numStyleEntries; i++) {
+ styleEntry[i] = (int) leis.readUInt();
}
size += numStyleEntries * LittleEndianConsts.INT_SIZE;
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- miterLimit = (int)leis.readUInt();
+ miterLimit = (int) leis.readUInt();
return LittleEndianConsts.INT_SIZE;
}
ctx.getProperties().setPenMiterLimit(miterLimit);
}
}
+
+
+ public static class EmfSetBrushOrgEx implements HemfRecord {
+ protected final Point2D origin = new Point2D.Double();
+
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.setBrushOrgEx;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ return readPointL(leis, origin);
+ }
+ }
}
setWindowOrgEx(0x0000000A, HemfWindowing.EmfSetWindowOrgEx::new),
setViewportExtEx(0x0000000B, HemfWindowing.EmfSetViewportExtEx::new),
setViewportOrgEx(0x0000000C, HemfWindowing.EmfSetViewportOrgEx::new),
- setbrushorgex(0x0000000D, UnimplementedHemfRecord::new),
+ setBrushOrgEx(0x0000000D, HemfMisc.EmfSetBrushOrgEx::new),
eof(0x0000000E, HemfMisc.EmfEof::new),
setPixelV(0x0000000F, HemfDraw.EmfSetPixelV::new),
setMapperFlags(0x00000010, HemfMisc.EmfSetMapperFlags::new),
polyDraw(0x00000038, HemfDraw.EmfPolyDraw::new),
setarcdirection(0x00000039, UnimplementedHemfRecord::new),
setMiterLimit(0x0000003A, HemfMisc.EmfSetMiterLimit::new),
- beginpath(0x0000003B, UnimplementedHemfRecord::new),
- endpath(0x0000003C, UnimplementedHemfRecord::new),
- closefigure(0x0000003D, UnimplementedHemfRecord::new),
- fillpath(0x0000003E, UnimplementedHemfRecord::new),
+ beginPath(0x0000003B, HemfDraw.EmfBeginPath::new),
+ endPath(0x0000003C, HemfDraw.EmfEndPath::new),
+ closeFigure(0x0000003D, HemfDraw.EmfCloseFigure::new),
+ fillPath(0x0000003E, HemfFill.EmfFillPath::new),
strokeandfillpath(0x0000003F, UnimplementedHemfRecord::new),
- strokepath(0x00000040, UnimplementedHemfRecord::new),
- flattenpath(0x00000041, UnimplementedHemfRecord::new),
- widenpath(0x00000042, UnimplementedHemfRecord::new),
- selectclippath(0x00000043, UnimplementedHemfRecord::new),
- abortpath(0x00000044, UnimplementedHemfRecord::new),
+ strokePath(0x00000040, HemfDraw.EmfStrokePath::new),
+ flattenPath(0x00000041, HemfDraw.EmfFlattenPath::new),
+ widenPath(0x00000042, HemfDraw.EmfWidenPath::new),
+ selectClipPath(0x00000043, HemfWindowing.EmfSelectClipPath::new),
+ abortPath(0x00000044, HemfDraw.EmfAbortPath::new),
// no 45 ?!
comment(0x00000046, HemfComment.EmfComment::new),
fillRgn(0x00000047, HemfFill.EmfFillRgn::new),
import java.io.IOException;
+import org.apache.poi.hemf.record.emf.HemfFill.HemfRegionMode;
import org.apache.poi.hwmf.record.HwmfWindowing;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;
return 4*LittleEndianConsts.INT_SIZE;
}
}
-}
+
+ /**
+ * The EMR_SELECTCLIPPATH record specifies the current path as a clipping region for a playback
+ * device context, combining the new region with any existing clipping region using the specified mode.
+ */
+ public static class EmfSelectClipPath implements HemfRecord {
+ protected HemfRegionMode regionMode;
+
+ @Override
+ public HemfRecordType getEmfRecordType() {
+ return HemfRecordType.selectClipPath;
+ }
+
+ @Override
+ public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
+ // A 32-bit unsigned integer that specifies the way to use the path.
+ // The value MUST be in the RegionMode enumeration
+ regionMode = HemfRegionMode.valueOf(leis.readInt());
+
+ return LittleEndianConsts.INT_SIZE;
+ }
+ }
+
+}
\ No newline at end of file
@Internal
public class UnimplementedHemfRecord implements HemfRecord {
- private long recordId;
- public UnimplementedHemfRecord() {
-
- }
+ private HemfRecordType recordType;
@Override
public HemfRecordType getEmfRecordType() {
- return HemfRecordType.getById(recordId);
+ return recordType;
}
@Override
public long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException {
- this.recordId = recordId;
+ recordType = HemfRecordType.getById(recordId);
long skipped = IOUtils.skipFully(leis, recordSize);
if (skipped < recordSize) {
throw new IOException("End of stream reached before record read");
private long logicalDpiY;
@Override
- public HemfPlusRecordType getRecordType() {
+ public HemfPlusRecordType getEmfPlusRecordType() {
return HemfPlusRecordType.header;
}
@Internal
public interface HemfPlusRecord {
- HemfPlusRecordType getRecordType();
+ HemfPlusRecordType getEmfPlusRecordType();
int getFlags();
}
private HemfPlusRecord _next() {
- if (currentRecord != null && HemfPlusRecordType.eof == currentRecord.getRecordType()) {
+ if (currentRecord != null && HemfPlusRecordType.eof == currentRecord.getEmfPlusRecordType()) {
return null;
}
// A 16-bit unsigned integer that identifies this record type
private static final int MAX_RECORD_LENGTH = 1_000_000;
- private long recordId;
+ private HemfPlusRecordType recordType;
private int flags;
private byte[] recordBytes;
@Override
- public HemfPlusRecordType getRecordType() {
- return HemfPlusRecordType.getById(recordId);
+ public HemfPlusRecordType getEmfPlusRecordType() {
+ return recordType;
}
@Override
@Override
public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException {
- this.recordId = recordId;
+ recordType = HemfPlusRecordType.getById(recordId);
this.flags = flags;
recordBytes = IOUtils.safelyAllocate(dataSize, MAX_RECORD_LENGTH);
leis.readFully(recordBytes);
public class HwmfGraphics {
+ protected final List<HwmfDrawProperties> propStack = new LinkedList<>();
+ protected HwmfDrawProperties prop;
+
private static final Charset DEFAULT_CHARSET = LocaleUtil.CHARSET_1252;
private final Graphics2D graphicsCtx;
- private final List<HwmfDrawProperties> propStack = new LinkedList<>();
- private HwmfDrawProperties prop = new HwmfDrawProperties();
- private List<HwmfObjectTableEntry> objectTable = new ArrayList<>();
+ private final List<HwmfObjectTableEntry> objectTable = new ArrayList<>();
/** Bounding box from the placeable header */
private final Rectangle2D bbox;
private final AffineTransform initialAT;
}
public HwmfDrawProperties getProperties() {
+ if (prop == null) {
+ prop = new HwmfDrawProperties();
+ }
return prop;
}
public void draw(Shape shape) {
- HwmfLineDash lineDash = prop.getPenStyle().getLineDash();
+ HwmfLineDash lineDash = getProperties().getPenStyle().getLineDash();
if (lineDash == HwmfLineDash.NULL) {
// line is not drawn
return;
// first draw a solid background line (depending on bkmode)
// only makes sense if the line is not solid
- if (prop.getBkMode() == HwmfBkMode.OPAQUE && (lineDash != HwmfLineDash.SOLID && lineDash != HwmfLineDash.INSIDEFRAME)) {
+ if (getProperties().getBkMode() == HwmfBkMode.OPAQUE && (lineDash != HwmfLineDash.SOLID && lineDash != HwmfLineDash.INSIDEFRAME)) {
graphicsCtx.setStroke(new BasicStroke(stroke.getLineWidth()));
- graphicsCtx.setColor(prop.getBackgroundColor().getColor());
+ graphicsCtx.setColor(getProperties().getBackgroundColor().getColor());
graphicsCtx.draw(shape);
}
// then draw the (dashed) line
graphicsCtx.setStroke(stroke);
- graphicsCtx.setColor(prop.getPenColor().getColor());
+ graphicsCtx.setColor(getProperties().getPenColor().getColor());
graphicsCtx.draw(shape);
}
public void fill(Shape shape) {
- if (prop.getBrushStyle() != HwmfBrushStyle.BS_NULL) {
+ if (getProperties().getBrushStyle() != HwmfBrushStyle.BS_NULL) {
// GeneralPath gp = new GeneralPath(shape);
-// gp.setWindingRule(prop.getPolyfillMode().awtFlag);
+// gp.setWindingRule(getProperties().getPolyfillMode().awtFlag);
graphicsCtx.setPaint(getFill());
graphicsCtx.fill(shape);
}
protected BasicStroke getStroke() {
// TODO: fix line width calculation
- float width = (float)prop.getPenWidth();
+ float width = (float)getProperties().getPenWidth();
if (width == 0) {
width = 1;
}
- HwmfPenStyle ps = prop.getPenStyle();
+ HwmfPenStyle ps = getProperties().getPenStyle();
int cap = ps.getLineCap().awtFlag;
int join = ps.getLineJoin().awtFlag;
- float miterLimit = (float)prop.getPenMiterLimit();
+ float miterLimit = (float)getProperties().getPenMiterLimit();
float dashes[] = ps.getLineDash().dashes;
boolean dashAlt = ps.isAlternateDash();
// This value is not an integer index into the dash pattern array.
}
protected Paint getFill() {
- switch (prop.getBrushStyle()) {
+ switch (getProperties().getBrushStyle()) {
default:
case BS_INDEXED:
case BS_PATTERN8X8:
}
protected Paint getSolidFill() {
- return prop.getBrushColor().getColor();
+ return getProperties().getBrushColor().getColor();
}
protected Paint getHatchedFill() {
int dim = 7, mid = 3;
BufferedImage bi = new BufferedImage(dim, dim, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = bi.createGraphics();
- Color c = (prop.getBkMode() == HwmfBkMode.TRANSPARENT)
+ Color c = (getProperties().getBkMode() == HwmfBkMode.TRANSPARENT)
? new Color(0, true)
- : prop.getBackgroundColor().getColor();
+ : getProperties().getBackgroundColor().getColor();
g.setColor(c);
g.fillRect(0, 0, dim, dim);
- g.setColor(prop.getBrushColor().getColor());
- HwmfHatchStyle h = prop.getBrushHatch();
+ g.setColor(getProperties().getBrushColor().getColor());
+ HwmfHatchStyle h = getProperties().getBrushHatch();
if (h == HwmfHatchStyle.HS_HORIZONTAL || h == HwmfHatchStyle.HS_CROSS) {
g.drawLine(0, mid, dim, mid);
}
}
protected Paint getPatternPaint() {
- BufferedImage bi = prop.getBrushBitmap();
+ BufferedImage bi = getProperties().getBrushBitmap();
return (bi == null) ? null
: new TexturePaint(bi, new Rectangle(0,0,bi.getWidth(),bi.getHeight()));
}
* Saves the current properties to the stack
*/
public void saveProperties() {
+ assert(prop != null);
propStack.add(prop);
- prop = new HwmfDrawProperties(prop);
+ prop = new HwmfDrawProperties(prop);
}
/**
}
int stackIndex = index;
if (stackIndex < 0) {
- int curIdx = propStack.indexOf(prop);
+ int curIdx = propStack.indexOf(getProperties());
if (curIdx == -1) {
// the current element is not pushed to the stacked, i.e. it's the last
curIdx = propStack.size();
* This methods gathers and sets the corresponding graphics transformations.
*/
public void updateWindowMapMode() {
- Rectangle2D win = prop.getWindow();
- HwmfMapMode mapMode = prop.getMapMode();
+ Rectangle2D win = getProperties().getWindow();
+ HwmfMapMode mapMode = getProperties().getMapMode();
graphicsCtx.setTransform(initialAT);
switch (mapMode) {
}
public void drawString(byte[] text, Rectangle2D bounds, int dx[]) {
- HwmfFont font = prop.getFont();
+ HwmfFont font = getProperties().getFont();
if (font == null || text == null || text.length == 0) {
return;
}
try {
graphicsCtx.translate(bounds.getX(), bounds.getY()+fontH);
graphicsCtx.rotate(angle);
- if (prop.getBkMode() == HwmfBkMode.OPAQUE) {
+ if (getProperties().getBkMode() == HwmfBkMode.OPAQUE) {
// TODO: validate bounds
- graphicsCtx.setBackground(prop.getBackgroundColor().getColor());
+ graphicsCtx.setBackground(getProperties().getBackgroundColor().getColor());
graphicsCtx.fill(new Rectangle2D.Double(0, 0, bounds.getWidth(), bounds.getHeight()));
}
- graphicsCtx.setColor(prop.getTextColor().getColor());
+ graphicsCtx.setColor(getProperties().getTextColor().getColor());
graphicsCtx.drawString(as.getIterator(), 0, 0); // (float)bounds.getX(), (float)bounds.getY());
} finally {
graphicsCtx.setTransform(at);
EmfCommentDataPlus emfPlus = getCommentRecord("SimpleEMF_windows.emf", 0);
List<HemfPlusRecord> records = emfPlus.getRecords();
assertEquals(1, records.size());
- assertEquals(HemfPlusRecordType.header, records.get(0).getRecordType());
+ assertEquals(HemfPlusRecordType.header, records.get(0).getEmfPlusRecordType());
HemfPlusHeader header = (HemfPlusHeader)records.get(0);
assertEquals(240, header.getLogicalDpiX());
assertEquals(expected.size(), records.size());
for (int i = 0; i < expected.size(); i++) {
- assertEquals(expected.get(i), records.get(i).getRecordType());
+ assertEquals(expected.get(i), records.get(i).getEmfPlusRecordType());
}
}