import java.awt.Font;
import java.awt.Graphics2D;
import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import org.apache.poi.common.usermodel.fonts.FontInfo;
import org.apache.poi.sl.draw.Drawable.DrawableHint;
*/
public class DrawFontManagerDefault implements DrawFontManager {
+ protected final Set<String> knownSymbolFonts = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
+
+ public DrawFontManagerDefault() {
+ knownSymbolFonts.add("Wingdings");
+ knownSymbolFonts.add("Symbol");
+ }
+
@Override
public FontInfo getMappedFont(Graphics2D graphics, FontInfo fontInfo) {
return getFontWithFallback(graphics, Drawable.FONT_MAP, fontInfo);
public String mapFontCharset(Graphics2D graphics, FontInfo fontInfo, String text) {
// TODO: find a real charset mapping solution instead of hard coding for Wingdings
- String attStr = text;
- if (fontInfo != null && "Wingdings".equalsIgnoreCase(fontInfo.getTypeface())) {
- // wingdings doesn't contain high-surrogates, so chars are ok
- boolean changed = false;
- char chrs[] = attStr.toCharArray();
- for (int i=0; i<chrs.length; i++) {
- // only change valid chars
- if ((0x20 <= chrs[i] && chrs[i] <= 0x7f) ||
- (0xa0 <= chrs[i] && chrs[i] <= 0xff)) {
- chrs[i] |= 0xf000;
- changed = true;
- }
- }
+ return (fontInfo != null && knownSymbolFonts.contains(fontInfo.getTypeface()))
+ ? mapSymbolChars(text)
+ : text;
+ }
- if (changed) {
- attStr = new String(chrs);
+ /**
+ * Symbol fonts like "Wingdings" or "Symbol" have glyphs mapped to a Unicode private use range via the Java font loader,
+ * although a system font viewer might show you the glyphs in the ASCII range.
+ * This helper function maps the chars of the text string to the corresponding private use range chars.
+ *
+ * @param text the input string, typically consists of ASCII chars
+ * @return the mapped string, typically consists of chars in the range of 0xf000 to 0xf0ff
+ *
+ * @since POI 4.0.0
+ */
+ public static String mapSymbolChars(String text) {
+ // wingdings doesn't contain high-surrogates, so chars are ok
+ boolean changed = false;
+ char chrs[] = text.toCharArray();
+ for (int i=0; i<chrs.length; i++) {
+ // only change valid chars
+ if ((0x20 <= chrs[i] && chrs[i] <= 0x7f) ||
+ (0xa0 <= chrs[i] && chrs[i] <= 0xff)) {
+ chrs[i] |= 0xf000;
+ changed = true;
}
}
- return attStr;
+
+ return changed ? new String(chrs) : text;
}
@Override
Point2D pnt[] = { new Point2D.Double(), new Point2D.Double(), new Point2D.Double() };
- // points-1 because of the first point
- final int pointCnt = hasStartPoint() ? points-2 : points;
- for (int i=0; i+2<pointCnt; i+=3) {
- // x (4 bytes): A 32-bit signed integer that defines the horizontal (x) coordinate of the point.
- // y (4 bytes): A 32-bit signed integer that defines the vertical (y) coordinate of the point.
- if (i==0) {
- if (hasStartPoint()) {
- size += readPoint(leis, pnt[0]);
- poly.moveTo(pnt[0].getX(), pnt[0].getY());
- } else {
- poly.moveTo(0, 0);
- }
+ int i=0;
+ if (hasStartPoint()) {
+ if (i < points) {
+ size += readPoint(leis, pnt[0]);
+ poly.moveTo(pnt[0].getX(), pnt[0].getY());
+ i++;
}
+ } else {
+ poly.moveTo(0, 0);
+ }
+ for (; i+2<points; i+=3) {
size += readPoint(leis, pnt[0]);
size += readPoint(leis, pnt[1]);
size += readPoint(leis, pnt[2]);
size += LittleEndianConsts.INT_SIZE;
Point2D points[] = new Point2D[count];
for (int i=0; i<count; i++) {
- size += readPoint(leis, points[i]);
+ points[i] = new Point2D.Double();
+ size += readPoint(leis, points[i]);
}
poly = new Path2D.Double(Path2D.WIND_EVEN_ODD, count);
case 0x04:
int mode2 = leis.readUByte();
int mode3 = leis.readUByte();
- assert(mode2 == 0x04 && mode3 == 0x04);
+ assert(mode2 == 0x04 && (mode3 == 0x04 || mode3 == 0x05));
poly.curveTo(
points[i].getX(), points[i].getY(),
points[i+1].getX(), points[i+1].getY(),
points[i+2].getX(), points[i+2].getY()
);
+ // update mode for closePath handling below
+ mode = mode3;
i+=2;
break;
// PT_MOVETO
}
static int readXForm(LittleEndianInputStream leis, AffineTransform xform) {
- // mapping <java AffineTransform> = <xform>:
- // m00 (scaleX) = eM11 (Horizontal scaling component)
- // m11 (scaleY) = eM22 (Vertical scaling component)
- // m01 (shearX) = eM12 (Horizontal proportionality constant)
- // m10 (shearY) = eM21 (Vertical proportionality constant)
- // m02 (translateX) = eDx (The horizontal translation component, in logical units.)
- // m12 (translateY) = eDy (The vertical translation component, in logical units.)
+ // mapping <java AffineTransform> = <xform>
- // A 32-bit floating-point value of the transform matrix.
- double eM11 = leis.readFloat();
+ // m00 (scaleX) = eM11 (Horizontal scaling component)
+ double m00 = leis.readFloat();
- // A 32-bit floating-point value of the transform matrix.
- double eM12 = leis.readFloat();
+ // m01 (shearX) = eM12 (Horizontal proportionality constant)
+ double m01 = leis.readFloat();
- // A 32-bit floating-point value of the transform matrix.
- double eM21 = leis.readFloat();
+ // m10 (shearY) = eM21 (Vertical proportionality constant)
+ double m10 = leis.readFloat();
- // A 32-bit floating-point value of the transform matrix.
- double eM22 = leis.readFloat();
+ // m11 (scaleY) = eM22 (Vertical scaling component)
+ double m11 = leis.readFloat();
- // A 32-bit floating-point value that contains a horizontal translation component, in logical units.
- double eDx = leis.readFloat();
+ // m02 (translateX) = eDx (The horizontal translation component, in logical units.)
+ double m02 = leis.readFloat();
- // A 32-bit floating-point value that contains a vertical translation component, in logical units.
- double eDy = leis.readFloat();
+ // m12 (translateY) = eDy (The vertical translation component, in logical units.)
+ double m12 = leis.readFloat();
- xform.setTransform(eM11, eM21, eM12, eM22, eDx, eDy);
+ xform.setTransform(m00, m10, m01, m11, m02, m12);
return 6 * LittleEndian.INT_SIZE;
}
// An 8-bit unsigned integer that specifies an italic font if set to 0x01;
// otherwise, it MUST be set to 0x00.
- italic = (leis.readUByte() == 0x01);
+ italic = (leis.readUByte() != 0x00);
// An 8-bit unsigned integer that specifies an underlined font if set to 0x01;
// otherwise, it MUST be set to 0x00.
- underline = (leis.readUByte() == 0x01);
+ underline = (leis.readUByte() != 0x00);
// An 8-bit unsigned integer that specifies a strikeout font if set to 0x01;
// otherwise, it MUST be set to 0x00.
- strikeOut = (leis.readUByte() == 0x01);
+ strikeOut = (leis.readUByte() != 0x00);
// An 8-bit unsigned integer that specifies the set of character glyphs.
// It MUST be a value in the WMF CharacterSet enumeration.
// A 32-bit unsigned integer that MUST be set to the value 0x08007664.
int signature = leis.readInt();
- assert (signature == 0x08007664);
+ // some non-conformant applications don't write the magic code in
+ // assert (signature == 0x08007664);
// A 32-bit unsigned integer that specifies the number of elements in the
// Values array. It MUST be in the range 0 to 16, inclusive.
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.function.Function;
import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
protected HwmfBrushStyle brushStyle;
protected HwmfHatchStyle hatchStyle;
- protected int[] styleEntry;
-
protected final HwmfBitmapDib bitmap = new HwmfBitmapDib();
// 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());
+ final HemfPenStyle emfPS = HemfPenStyle.valueOf((int) leis.readUInt());
+ penStyle = emfPS;
// 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, the lengths are specified in logical
// units; otherwise, the lengths are specified in device units.
- styleEntry = new int[numStyleEntries];
+ float[] dashPattern = new float[numStyleEntries];
for (int i = 0; i < numStyleEntries; i++) {
- styleEntry[i] = (int) leis.readUInt();
+ dashPattern[i] = (int) leis.readUInt();
+ }
+
+ if (penStyle.getLineDash() == HwmfLineDash.USERSTYLE) {
+ emfPS.setLineDashes(dashPattern);
}
size += numStyleEntries * LittleEndianConsts.INT_SIZE;
@Override
public String toString() {
// TODO: add style entries + bmp
- return super.toString().replaceFirst("\\{",
- "{ brushStyle: '"+brushStyle+"', hatchStyle: '"+hatchStyle+"', ");
+ return
+ "{ brushStyle: '"+brushStyle+"'"+
+ ", hatchStyle: '"+hatchStyle+"'"+
+ ", dashPattern: "+ Arrays.toString(penStyle.getLineDashes())+
+ ", "+super.toString().substring(1);
}
}
@Override
public void draw(HemfGraphics ctx) {
- AffineTransform tx = ctx.getInitTransform();
+ ctx.updateWindowMapMode();
+ AffineTransform tx = ctx.getTransform();
tx.concatenate(xForm);
ctx.setTransform(tx);
}
return;
}
+ final AffineTransform tx;
switch (modifyWorldTransformMode) {
- case MWT_IDENTITY:
- ctx.setTransform(ctx.getInitTransform());
+ case MWT_LEFTMULTIPLY:
+ tx = ctx.getTransform();
+ tx.concatenate(adaptXForm(tx));
break;
- case MWT_LEFTMULTIPLY: {
- AffineTransform tx = new AffineTransform(xForm);
- tx.concatenate(ctx.getTransform());
- ctx.setTransform(tx);
+ case MWT_RIGHTMULTIPLY:
+ tx = ctx.getTransform();
+ tx.preConcatenate(adaptXForm(tx));
break;
- }
- case MWT_RIGHTMULTIPLY: {
- AffineTransform tx = new AffineTransform(xForm);
- tx.preConcatenate(ctx.getTransform());
- ctx.setTransform(tx);
+ case MWT_IDENTITY:
+ ctx.updateWindowMapMode();
+ tx = ctx.getTransform();
break;
- }
default:
- case MWT_SET: {
- AffineTransform tx = ctx.getInitTransform();
- tx.concatenate(xForm);
- ctx.setTransform(tx);
+ case MWT_SET:
+ ctx.updateWindowMapMode();
+ tx = ctx.getTransform();
+ tx.concatenate(adaptXForm(tx));
break;
- }
}
+ ctx.setTransform(tx);
+ }
+
+ /**
+ * adapt xform depending on the base transformation (... experimental ...)
+ */
+ private AffineTransform adaptXForm(AffineTransform other) {
+ // normalize signed zero
+ Function<Double,Double> nn = (d) -> (d == 0. ? 0. : d);
+ double yDiff = Math.signum(nn.apply(xForm.getTranslateY())) == Math.signum(nn.apply(other.getTranslateY())) ? 1. : -1.;
+ double xDiff = Math.signum(nn.apply(xForm.getTranslateX())) == Math.signum(nn.apply(other.getTranslateX())) ? 1. : -1.;
+ return new AffineTransform(
+ xForm.getScaleX() == 0 ? 1. : xForm.getScaleX(),
+ yDiff * xForm.getShearY(),
+ xDiff * xForm.getShearX(),
+ xForm.getScaleY() == 0. ? 1. : xForm.getScaleY(),
+ xForm.getTranslateX(),
+ xForm.getTranslateY()
+ );
}
@Override
--- /dev/null
+/* ====================================================================
+ 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.hemf.record.emf;
+
+import org.apache.poi.hwmf.record.HwmfPenStyle;
+
+public class HemfPenStyle extends HwmfPenStyle {
+
+ private float[] dashPattern;
+
+ public static HemfPenStyle valueOf(int flag) {
+ HemfPenStyle ps = new HemfPenStyle();
+ ps.flag = flag;
+ return ps;
+ }
+
+ @Override
+ public float[] getLineDashes() {
+ return (getLineDash() == HwmfLineDash.USERSTYLE) ? dashPattern : super.getLineDashes();
+ }
+
+ public void setLineDashes(float[] dashPattern) {
+ this.dashPattern = (dashPattern == null) ? null : dashPattern.clone();
+ }
+
+ @Override
+ public HemfPenStyle clone() {
+ return (HemfPenStyle)super.clone();
+ }
+}
*/
long init(LittleEndianInputStream leis, long recordSize, long recordId) throws IOException;
+ /**
+ * Draws the record, the default redirects to the parent WMF record drawing
+ * @param ctx the drawing context
+ */
default void draw(HemfGraphics ctx) {
if (this instanceof HwmfRecord) {
((HwmfRecord) this).draw(ctx);
return null;
}
+ final int readIndex = stream.getReadIndex();
+
final long recordId, recordSize;
try {
recordId = stream.readUInt();
HemfRecordType type = HemfRecordType.getById(recordId);
if (type == null) {
- throw new RecordFormatException("Undefined record of type:"+recordId);
+ throw new RecordFormatException("Undefined record of type: "+recordId+" at "+Integer.toHexString(readIndex));
}
final HemfRecord record = type.constructor.get();
dx.add((int) leis.readUInt());
size += LittleEndianConsts.INT_SIZE;
}
- } else {
- // if there are no dx entries, reset the string end
- strEnd = (int)recordSize;
}
if (dx.size() < stringLength) {
// invalid dx array
dx.clear();
}
+ strEnd = (int)recordSize;
break;
}
default:
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Dimension2D;
+import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.TreeMap;
import org.apache.commons.codec.Charsets;
+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.HwmfText.WmfExtTextOutOptions;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.DrawFontManager;
+import org.apache.poi.sl.draw.DrawFontManagerDefault;
import org.apache.poi.util.LocaleUtil;
public class HwmfGraphics {
int cap = ps.getLineCap().awtFlag;
int join = ps.getLineJoin().awtFlag;
float miterLimit = (float)getProperties().getPenMiterLimit();
- float dashes[] = ps.getLineDash().dashes;
+ float dashes[] = ps.getLineDashes();
boolean dashAlt = ps.isAlternateDash();
// This value is not an integer index into the dash pattern array.
// Instead, it is a floating-point value that specifies a linear distance.
public void drawString(byte[] text, int length, Point2D reference, Dimension2D scale, Rectangle2D clip, WmfExtTextOutOptions opts, List<Integer> dx, boolean isUnicode) {
final HwmfDrawProperties prop = getProperties();
+ final AffineTransform at = graphicsCtx.getTransform();
+ if (at.getScaleX() == 0. || at.getScaleY() == 0.) {
+ return;
+ }
+
+ try {
+ at.createInverse();
+ } catch (NoninvertibleTransformException e) {
+ return;
+ }
+
HwmfFont font = prop.getFont();
if (font == null || text == null || text.length == 0) {
return;
}
String textString = new String(text, charset).substring(0,length).trim();
+
if (textString.isEmpty()) {
return;
}
+
+ DrawFontManager fontHandler = DrawFactory.getInstance(graphicsCtx).getFontManager(graphicsCtx);
+ FontInfo fontInfo = fontHandler.getMappedFont(graphicsCtx, font);
+ if (fontInfo.getCharset() == FontCharset.SYMBOL) {
+ textString = DrawFontManagerDefault.mapSymbolChars(textString);
+ }
+
AttributedString as = new AttributedString(textString);
- addAttributes(as, font);
+ addAttributes(as, font, fontInfo.getTypeface());
// disabled for the time being, as the results aren't promising
/*
tx.transform(src, dst);
final Shape clipShape = graphicsCtx.getClip();
- final AffineTransform at = graphicsCtx.getTransform();
try {
if (clip != null) {
graphicsCtx.translate(-clip.getCenterX(), -clip.getCenterY());
}
}
- private void addAttributes(AttributedString as, HwmfFont font) {
- DrawFontManager fontHandler = DrawFactory.getInstance(graphicsCtx).getFontManager(graphicsCtx);
- FontInfo fontInfo = fontHandler.getMappedFont(graphicsCtx, font);
-
- as.addAttribute(TextAttribute.FAMILY, fontInfo.getTypeface());
+ private void addAttributes(AttributedString as, HwmfFont font, String typeface) {
+ as.addAttribute(TextAttribute.FAMILY, typeface);
as.addAttribute(TextAttribute.SIZE, getFontHeight(font));
if (font.isStrikeOut()) {
as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
graphicsCtx.setTransform(at);
}
}
+
+ /**
+ * @return the bounding box
+ */
+ public Rectangle2D getBbox() {
+ return (Rectangle2D)bbox.clone();
+ }
}
if (bitmap.isValid()) {
ctx.drawImage(getImage(), srcBounds, dstBounds);
} else if (!dstBounds.isEmpty()) {
- BufferedImage bi = new BufferedImage((int)dstBounds.getWidth(), (int)dstBounds.getHeight(), BufferedImage.TYPE_INT_ARGB);
- ctx.drawImage(bi, dstBounds, dstBounds);
+ BufferedImage bi = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
+ ctx.drawImage(bi, new Rectangle2D.Double(0,0,100,100), dstBounds);
}
}
private static final BitField SUBSECTION_JOIN = BitFieldFactory.getInstance(0x03000);
private static final BitField SUBSECTION_GEOMETRIC = BitFieldFactory.getInstance(0x10000);
- private int flag;
+ protected int flag;
public static HwmfPenStyle valueOf(int flag) {
HwmfPenStyle ps = new HwmfPenStyle();
public HwmfLineDash getLineDash() {
return HwmfLineDash.valueOf(SUBSECTION_DASH.getValue(flag));
}
-
+
+ /**
+ * Convienence method which should be used instead of accessing {@link HwmfLineDash#dashes}
+ * directly, so an subclass can provide user-style dashes
+ *
+ * @return the dash pattern
+ */
+ public float[] getLineDashes() {
+ return getLineDash().dashes;
+ }
/**
* The pen sets every other pixel (this style is applicable only for cosmetic pens).
package org.apache.poi.hwmf.record;
import static org.apache.poi.hwmf.record.HwmfDraw.boundsToString;
+import static org.apache.poi.hwmf.record.HwmfDraw.dimToString;
import static org.apache.poi.hwmf.record.HwmfDraw.normalizeBounds;
import static org.apache.poi.hwmf.record.HwmfDraw.pointToString;
import static org.apache.poi.hwmf.record.HwmfDraw.readBounds;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
+import org.apache.poi.hwmf.draw.HwmfDrawProperties;
import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.util.Dimension2DDouble;
import org.apache.poi.util.LittleEndianConsts;
@Override
public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setViewportOrg(origin.getX(), origin.getY());
- ctx.updateWindowMapMode();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ Rectangle2D old = prop.getViewport();
+ double oldX = (old == null ? 0 : old.getX());
+ double oldY = (old == null ? 0 : old.getY());
+ if (oldX != origin.getX() || oldY != origin.getY()) {
+ prop.setViewportOrg(origin.getX(), origin.getY());
+ ctx.updateWindowMapMode();
+ }
}
@Override
@Override
public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setViewportExt(extents.getWidth(), extents.getHeight());
- ctx.updateWindowMapMode();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ Rectangle2D old = prop.getViewport();
+ double oldW = (old == null ? 0 : old.getWidth());
+ double oldH = (old == null ? 0 : old.getHeight());
+ if (oldW != extents.getWidth() || oldH != extents.getHeight()) {
+ prop.setViewportExt(extents.getWidth(), extents.getHeight());
+ ctx.updateWindowMapMode();
+ }
}
@Override
public String toString() {
- return "{ width: "+extents.getWidth()+", height: "+extents.getHeight()+" }";
+ return dimToString(extents);
}
}
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D viewport = ctx.getProperties().getViewport();
- double x = (viewport == null) ? 0 : viewport.getX();
- double y = (viewport == null) ? 0 : viewport.getY();
- ctx.getProperties().setViewportOrg(x+offset.getX(), y+offset.getY());
+ final HwmfDrawProperties prop = ctx.getProperties();
+ Rectangle2D viewport = prop.getViewport();
+ if (offset.getX() != 0 || offset.getY() != 0) {
+ double x = (viewport == null) ? 0 : viewport.getX();
+ double y = (viewport == null) ? 0 : viewport.getY();
+ prop.setViewportOrg(x + offset.getX(), y + offset.getY());
+ ctx.updateWindowMapMode();
+ }
}
@Override
@Override
public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setWindowOrg(getX(), getY());
- ctx.updateWindowMapMode();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ final Rectangle2D old = prop.getWindow();
+ double oldX = (old == null ? 0 : old.getX());
+ double oldY = (old == null ? 0 : old.getY());
+ if (oldX != getX() || oldY != getY()) {
+ prop.setWindowOrg(getX(), getY());
+ ctx.updateWindowMapMode();
+ }
}
public double getY() {
@Override
public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setWindowExt(size.getWidth(), size.getHeight());
- ctx.updateWindowMapMode();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ Rectangle2D old = prop.getWindow();
+ double oldW = (old == null ? 0 : old.getWidth());
+ double oldH = (old == null ? 0 : old.getHeight());
+ if (oldW != size.getWidth() || oldH != size.getHeight()) {
+ prop.setWindowExt(size.getWidth(), size.getHeight());
+ ctx.updateWindowMapMode();
+ }
}
public Dimension2D getSize() {
@Override
public String toString() {
- return "{ width: "+size.getWidth()+", height: "+size.getHeight()+" }";
+ return dimToString(size);
}
}
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D window = ctx.getProperties().getWindow();
- ctx.getProperties().setWindowOrg(window.getX()+offset.getX(), window.getY()+offset.getY());
- ctx.updateWindowMapMode();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ Rectangle2D old = prop.getWindow();
+ if (offset.getX() != 0 || offset.getY() != 0) {
+ prop.setWindowOrg(old.getX() + offset.getX(), old.getY() + offset.getY());
+ ctx.updateWindowMapMode();
+ }
}
@Override
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D window = ctx.getProperties().getWindow();
- double width = window.getWidth() * scale.getWidth();
- double height = window.getHeight() * scale.getHeight();
- ctx.getProperties().setWindowExt(width, height);
- ctx.updateWindowMapMode();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ Rectangle2D old = prop.getWindow();
+ if (scale.getWidth() != 1.0 || scale.getHeight() != 1.0) {
+ double width = old.getWidth() * scale.getWidth();
+ double height = old.getHeight() * scale.getHeight();
+ ctx.getProperties().setWindowExt(width, height);
+ ctx.updateWindowMapMode();
+ }
}
@Override
@Override
public void draw(HwmfGraphics ctx) {
- Rectangle2D viewport = ctx.getProperties().getViewport();
- if (viewport == null) {
- viewport = ctx.getProperties().getWindow();
+ final HwmfDrawProperties prop = ctx.getProperties();
+ final Rectangle2D old = prop.getViewport() == null ? prop.getWindow() : prop.getViewport();
+
+ if (scale.getWidth() != 1.0 || scale.getHeight() != 1.0) {
+ double width = old.getWidth() * scale.getWidth();
+ double height = old.getHeight() * scale.getHeight();
+ prop.setViewportExt(width, height);
+ ctx.updateWindowMapMode();
}
- double width = viewport.getWidth() * scale.getWidth();
- double height = viewport.getHeight() * scale.getHeight();
- ctx.getProperties().setViewportExt(width, height);
}
@Override