aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/lowagie/text/pdf/codec/wmf
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/lowagie/text/pdf/codec/wmf')
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java112
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java94
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java760
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java211
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java71
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java91
-rw-r--r--src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java372
7 files changed, 1711 insertions, 0 deletions
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java
new file mode 100644
index 0000000..084761f
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/InputMeta.java
@@ -0,0 +1,112 @@
+/*
+ * $Id: InputMeta.java,v 1.3 2005/10/06 10:32:47 psoares33 Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+
+import java.io.*;
+import java.awt.Color;
+import com.lowagie.text.Image;
+
+public class InputMeta {
+
+ InputStream in;
+ int length;
+
+ public InputMeta(InputStream in) {
+ this.in = in;
+ }
+
+ public int readWord() throws IOException{
+ length += 2;
+ int k1 = in.read();
+ if (k1 < 0)
+ return 0;
+ return (k1 + (in.read() << 8)) & 0xffff;
+ }
+
+ public int readShort() throws IOException{
+ int k = readWord();
+ if (k > 0x7fff)
+ k -= 0x10000;
+ return k;
+ }
+
+ public int readInt() throws IOException{
+ length += 4;
+ int k1 = in.read();
+ if (k1 < 0)
+ return 0;
+ int k2 = in.read() << 8;
+ int k3 = in.read() << 16;
+ return k1 + k2 + k3 + (in.read() << 24);
+ }
+
+ public int readByte() throws IOException{
+ ++length;
+ return in.read() & 0xff;
+ }
+
+ public void skip(int len) throws IOException{
+ length += len;
+ Image.skip(in, len);
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public Color readColor() throws IOException{
+ int red = readByte();
+ int green = readByte();
+ int blue = readByte();
+ readByte();
+ return new Color(red, green, blue);
+ }
+}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java
new file mode 100644
index 0000000..430e177
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaBrush.java
@@ -0,0 +1,94 @@
+/*
+ * $Id: MetaBrush.java,v 1.2 2005/05/04 14:33:19 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+import java.io.IOException;
+import java.awt.Color;
+
+public class MetaBrush extends MetaObject {
+
+ public static final int BS_SOLID = 0;
+ public static final int BS_NULL = 1;
+ public static final int BS_HATCHED = 2;
+ public static final int BS_PATTERN = 3;
+ public static final int BS_DIBPATTERN = 5;
+ public static final int HS_HORIZONTAL = 0;
+ public static final int HS_VERTICAL = 1;
+ public static final int HS_FDIAGONAL = 2;
+ public static final int HS_BDIAGONAL = 3;
+ public static final int HS_CROSS = 4;
+ public static final int HS_DIAGCROSS = 5;
+
+ int style = BS_SOLID;
+ int hatch;
+ Color color = Color.white;
+
+ public MetaBrush() {
+ type = META_BRUSH;
+ }
+
+ public void init(InputMeta in) throws IOException {
+ style = in.readWord();
+ color = in.readColor();
+ hatch = in.readWord();
+ }
+
+ public int getStyle() {
+ return style;
+ }
+
+ public int getHatch() {
+ return hatch;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java
new file mode 100644
index 0000000..ca77294
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaDo.java
@@ -0,0 +1,760 @@
+/*
+ * $Id: MetaDo.java,v 1.3 2005/12/01 16:57:15 psoares33 Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+import java.io.*;
+import com.lowagie.text.pdf.*;
+import com.lowagie.text.pdf.codec.BmpImage;
+import com.lowagie.text.*;
+import java.awt.Point;
+import java.awt.Color;
+import java.util.ArrayList;
+
+public class MetaDo {
+
+ public static final int META_SETBKCOLOR = 0x0201;
+ public static final int META_SETBKMODE = 0x0102;
+ public static final int META_SETMAPMODE = 0x0103;
+ public static final int META_SETROP2 = 0x0104;
+ public static final int META_SETRELABS = 0x0105;
+ public static final int META_SETPOLYFILLMODE = 0x0106;
+ public static final int META_SETSTRETCHBLTMODE = 0x0107;
+ public static final int META_SETTEXTCHAREXTRA = 0x0108;
+ public static final int META_SETTEXTCOLOR = 0x0209;
+ public static final int META_SETTEXTJUSTIFICATION = 0x020A;
+ public static final int META_SETWINDOWORG = 0x020B;
+ public static final int META_SETWINDOWEXT = 0x020C;
+ public static final int META_SETVIEWPORTORG = 0x020D;
+ public static final int META_SETVIEWPORTEXT = 0x020E;
+ public static final int META_OFFSETWINDOWORG = 0x020F;
+ public static final int META_SCALEWINDOWEXT = 0x0410;
+ public static final int META_OFFSETVIEWPORTORG = 0x0211;
+ public static final int META_SCALEVIEWPORTEXT = 0x0412;
+ public static final int META_LINETO = 0x0213;
+ public static final int META_MOVETO = 0x0214;
+ public static final int META_EXCLUDECLIPRECT = 0x0415;
+ public static final int META_INTERSECTCLIPRECT = 0x0416;
+ public static final int META_ARC = 0x0817;
+ public static final int META_ELLIPSE = 0x0418;
+ public static final int META_FLOODFILL = 0x0419;
+ public static final int META_PIE = 0x081A;
+ public static final int META_RECTANGLE = 0x041B;
+ public static final int META_ROUNDRECT = 0x061C;
+ public static final int META_PATBLT = 0x061D;
+ public static final int META_SAVEDC = 0x001E;
+ public static final int META_SETPIXEL = 0x041F;
+ public static final int META_OFFSETCLIPRGN = 0x0220;
+ public static final int META_TEXTOUT = 0x0521;
+ public static final int META_BITBLT = 0x0922;
+ public static final int META_STRETCHBLT = 0x0B23;
+ public static final int META_POLYGON = 0x0324;
+ public static final int META_POLYLINE = 0x0325;
+ public static final int META_ESCAPE = 0x0626;
+ public static final int META_RESTOREDC = 0x0127;
+ public static final int META_FILLREGION = 0x0228;
+ public static final int META_FRAMEREGION = 0x0429;
+ public static final int META_INVERTREGION = 0x012A;
+ public static final int META_PAINTREGION = 0x012B;
+ public static final int META_SELECTCLIPREGION = 0x012C;
+ public static final int META_SELECTOBJECT = 0x012D;
+ public static final int META_SETTEXTALIGN = 0x012E;
+ public static final int META_CHORD = 0x0830;
+ public static final int META_SETMAPPERFLAGS = 0x0231;
+ public static final int META_EXTTEXTOUT = 0x0a32;
+ public static final int META_SETDIBTODEV = 0x0d33;
+ public static final int META_SELECTPALETTE = 0x0234;
+ public static final int META_REALIZEPALETTE = 0x0035;
+ public static final int META_ANIMATEPALETTE = 0x0436;
+ public static final int META_SETPALENTRIES = 0x0037;
+ public static final int META_POLYPOLYGON = 0x0538;
+ public static final int META_RESIZEPALETTE = 0x0139;
+ public static final int META_DIBBITBLT = 0x0940;
+ public static final int META_DIBSTRETCHBLT = 0x0b41;
+ public static final int META_DIBCREATEPATTERNBRUSH = 0x0142;
+ public static final int META_STRETCHDIB = 0x0f43;
+ public static final int META_EXTFLOODFILL = 0x0548;
+ public static final int META_DELETEOBJECT = 0x01f0;
+ public static final int META_CREATEPALETTE = 0x00f7;
+ public static final int META_CREATEPATTERNBRUSH = 0x01F9;
+ public static final int META_CREATEPENINDIRECT = 0x02FA;
+ public static final int META_CREATEFONTINDIRECT = 0x02FB;
+ public static final int META_CREATEBRUSHINDIRECT = 0x02FC;
+ public static final int META_CREATEREGION = 0x06FF;
+
+ public PdfContentByte cb;
+ public InputMeta in;
+ int left;
+ int top;
+ int right;
+ int bottom;
+ int inch;
+ MetaState state = new MetaState();
+
+ public MetaDo(InputStream in, PdfContentByte cb) {
+ this.cb = cb;
+ this.in = new InputMeta(in);
+ }
+
+ public void readAll() throws IOException, DocumentException{
+ if (in.readInt() != 0x9AC6CDD7) {
+ throw new DocumentException("Not a placeable windows metafile");
+ }
+ in.readWord();
+ left = in.readShort();
+ top = in.readShort();
+ right = in.readShort();
+ bottom = in.readShort();
+ inch = in.readWord();
+ state.setScalingX((float)(right - left) / (float)inch * 72f);
+ state.setScalingY((float)(bottom - top) / (float)inch * 72f);
+ state.setOffsetWx(left);
+ state.setOffsetWy(top);
+ state.setExtentWx(right - left);
+ state.setExtentWy(bottom - top);
+ in.readInt();
+ in.readWord();
+ in.skip(18);
+
+ int tsize;
+ int function;
+ cb.setLineCap(1);
+ cb.setLineJoin(1);
+ for (;;) {
+ int lenMarker = in.getLength();
+ tsize = in.readInt();
+ if (tsize < 3)
+ break;
+ function = in.readWord();
+ switch (function) {
+ case 0:
+ break;
+ case META_CREATEPALETTE:
+ case META_CREATEREGION:
+ case META_DIBCREATEPATTERNBRUSH:
+ state.addMetaObject(new MetaObject());
+ break;
+ case META_CREATEPENINDIRECT:
+ {
+ MetaPen pen = new MetaPen();
+ pen.init(in);
+ state.addMetaObject(pen);
+ break;
+ }
+ case META_CREATEBRUSHINDIRECT:
+ {
+ MetaBrush brush = new MetaBrush();
+ brush.init(in);
+ state.addMetaObject(brush);
+ break;
+ }
+ case META_CREATEFONTINDIRECT:
+ {
+ MetaFont font = new MetaFont();
+ font.init(in);
+ state.addMetaObject(font);
+ break;
+ }
+ case META_SELECTOBJECT:
+ {
+ int idx = in.readWord();
+ state.selectMetaObject(idx, cb);
+ break;
+ }
+ case META_DELETEOBJECT:
+ {
+ int idx = in.readWord();
+ state.deleteMetaObject(idx);
+ break;
+ }
+ case META_SAVEDC:
+ state.saveState(cb);
+ break;
+ case META_RESTOREDC:
+ {
+ int idx = in.readShort();
+ state.restoreState(idx, cb);
+ break;
+ }
+ case META_SETWINDOWORG:
+ state.setOffsetWy(in.readShort());
+ state.setOffsetWx(in.readShort());
+ break;
+ case META_SETWINDOWEXT:
+ state.setExtentWy(in.readShort());
+ state.setExtentWx(in.readShort());
+ break;
+ case META_MOVETO:
+ {
+ int y = in.readShort();
+ Point p = new Point(in.readShort(), y);
+ state.setCurrentPoint(p);
+ break;
+ }
+ case META_LINETO:
+ {
+ int y = in.readShort();
+ int x = in.readShort();
+ Point p = state.getCurrentPoint();
+ cb.moveTo(state.transformX(p.x), state.transformY(p.y));
+ cb.lineTo(state.transformX(x), state.transformY(y));
+ cb.stroke();
+ state.setCurrentPoint(new Point(x, y));
+ break;
+ }
+ case META_POLYLINE:
+ {
+ state.setLineJoinPolygon(cb);
+ int len = in.readWord();
+ int x = in.readShort();
+ int y = in.readShort();
+ cb.moveTo(state.transformX(x), state.transformY(y));
+ for (int k = 1; k < len; ++k) {
+ x = in.readShort();
+ y = in.readShort();
+ cb.lineTo(state.transformX(x), state.transformY(y));
+ }
+ cb.stroke();
+ break;
+ }
+ case META_POLYGON:
+ {
+ if (isNullStrokeFill(false))
+ break;
+ int len = in.readWord();
+ int sx = in.readShort();
+ int sy = in.readShort();
+ cb.moveTo(state.transformX(sx), state.transformY(sy));
+ for (int k = 1; k < len; ++k) {
+ int x = in.readShort();
+ int y = in.readShort();
+ cb.lineTo(state.transformX(x), state.transformY(y));
+ }
+ cb.lineTo(state.transformX(sx), state.transformY(sy));
+ strokeAndFill();
+ break;
+ }
+ case META_POLYPOLYGON:
+ {
+ if (isNullStrokeFill(false))
+ break;
+ int numPoly = in.readWord();
+ int lens[] = new int[numPoly];
+ for (int k = 0; k < lens.length; ++k)
+ lens[k] = in.readWord();
+ for (int j = 0; j < lens.length; ++j) {
+ int len = lens[j];
+ int sx = in.readShort();
+ int sy = in.readShort();
+ cb.moveTo(state.transformX(sx), state.transformY(sy));
+ for (int k = 1; k < len; ++k) {
+ int x = in.readShort();
+ int y = in.readShort();
+ cb.lineTo(state.transformX(x), state.transformY(y));
+ }
+ cb.lineTo(state.transformX(sx), state.transformY(sy));
+ }
+ strokeAndFill();
+ break;
+ }
+ case META_ELLIPSE:
+ {
+ if (isNullStrokeFill(state.getLineNeutral()))
+ break;
+ int b = in.readShort();
+ int r = in.readShort();
+ int t = in.readShort();
+ int l = in.readShort();
+ cb.arc(state.transformX(l), state.transformY(b), state.transformX(r), state.transformY(t), 0, 360);
+ strokeAndFill();
+ break;
+ }
+ case META_ARC:
+ {
+ if (isNullStrokeFill(state.getLineNeutral()))
+ break;
+ float yend = state.transformY(in.readShort());
+ float xend = state.transformX(in.readShort());
+ float ystart = state.transformY(in.readShort());
+ float xstart = state.transformX(in.readShort());
+ float b = state.transformY(in.readShort());
+ float r = state.transformX(in.readShort());
+ float t = state.transformY(in.readShort());
+ float l = state.transformX(in.readShort());
+ float cx = (r + l) / 2;
+ float cy = (t + b) / 2;
+ float arc1 = getArc(cx, cy, xstart, ystart);
+ float arc2 = getArc(cx, cy, xend, yend);
+ arc2 -= arc1;
+ if (arc2 <= 0)
+ arc2 += 360;
+ cb.arc(l, b, r, t, arc1, arc2);
+ cb.stroke();
+ break;
+ }
+ case META_PIE:
+ {
+ if (isNullStrokeFill(state.getLineNeutral()))
+ break;
+ float yend = state.transformY(in.readShort());
+ float xend = state.transformX(in.readShort());
+ float ystart = state.transformY(in.readShort());
+ float xstart = state.transformX(in.readShort());
+ float b = state.transformY(in.readShort());
+ float r = state.transformX(in.readShort());
+ float t = state.transformY(in.readShort());
+ float l = state.transformX(in.readShort());
+ float cx = (r + l) / 2;
+ float cy = (t + b) / 2;
+ float arc1 = getArc(cx, cy, xstart, ystart);
+ float arc2 = getArc(cx, cy, xend, yend);
+ arc2 -= arc1;
+ if (arc2 <= 0)
+ arc2 += 360;
+ ArrayList ar = PdfContentByte.bezierArc(l, b, r, t, arc1, arc2);
+ if (ar.size() == 0)
+ break;
+ float pt[] = (float [])ar.get(0);
+ cb.moveTo(cx, cy);
+ cb.lineTo(pt[0], pt[1]);
+ for (int k = 0; k < ar.size(); ++k) {
+ pt = (float [])ar.get(k);
+ cb.curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]);
+ }
+ cb.lineTo(cx, cy);
+ strokeAndFill();
+ break;
+ }
+ case META_CHORD:
+ {
+ if (isNullStrokeFill(state.getLineNeutral()))
+ break;
+ float yend = state.transformY(in.readShort());
+ float xend = state.transformX(in.readShort());
+ float ystart = state.transformY(in.readShort());
+ float xstart = state.transformX(in.readShort());
+ float b = state.transformY(in.readShort());
+ float r = state.transformX(in.readShort());
+ float t = state.transformY(in.readShort());
+ float l = state.transformX(in.readShort());
+ float cx = (r + l) / 2;
+ float cy = (t + b) / 2;
+ float arc1 = getArc(cx, cy, xstart, ystart);
+ float arc2 = getArc(cx, cy, xend, yend);
+ arc2 -= arc1;
+ if (arc2 <= 0)
+ arc2 += 360;
+ ArrayList ar = PdfContentByte.bezierArc(l, b, r, t, arc1, arc2);
+ if (ar.size() == 0)
+ break;
+ float pt[] = (float [])ar.get(0);
+ cx = pt[0];
+ cy = pt[1];
+ cb.moveTo(cx, cy);
+ for (int k = 0; k < ar.size(); ++k) {
+ pt = (float [])ar.get(k);
+ cb.curveTo(pt[2], pt[3], pt[4], pt[5], pt[6], pt[7]);
+ }
+ cb.lineTo(cx, cy);
+ strokeAndFill();
+ break;
+ }
+ case META_RECTANGLE:
+ {
+ if (isNullStrokeFill(true))
+ break;
+ float b = state.transformY(in.readShort());
+ float r = state.transformX(in.readShort());
+ float t = state.transformY(in.readShort());
+ float l = state.transformX(in.readShort());
+ cb.rectangle(l, b, r - l, t - b);
+ strokeAndFill();
+ break;
+ }
+ case META_ROUNDRECT:
+ {
+ if (isNullStrokeFill(true))
+ break;
+ float h = state.transformY(0) - state.transformY(in.readShort());
+ float w = state.transformX(in.readShort()) - state.transformX(0);
+ float b = state.transformY(in.readShort());
+ float r = state.transformX(in.readShort());
+ float t = state.transformY(in.readShort());
+ float l = state.transformX(in.readShort());
+ cb.roundRectangle(l, b, r - l, t - b, (h + w) / 4);
+ strokeAndFill();
+ break;
+ }
+ case META_INTERSECTCLIPRECT:
+ {
+ float b = state.transformY(in.readShort());
+ float r = state.transformX(in.readShort());
+ float t = state.transformY(in.readShort());
+ float l = state.transformX(in.readShort());
+ cb.rectangle(l, b, r - l, t - b);
+ cb.eoClip();
+ cb.newPath();
+ break;
+ }
+ case META_EXTTEXTOUT:
+ {
+ int y = in.readShort();
+ int x = in.readShort();
+ int count = in.readWord();
+ int flag = in.readWord();
+ int x1 = 0;
+ int y1 = 0;
+ int x2 = 0;
+ int y2 = 0;
+ if ((flag & (MetaFont.ETO_CLIPPED | MetaFont.ETO_OPAQUE)) != 0) {
+ x1 = in.readShort();
+ y1 = in.readShort();
+ x2 = in.readShort();
+ y2 = in.readShort();
+ }
+ byte text[] = new byte[count];
+ int k;
+ for (k = 0; k < count; ++k) {
+ byte c = (byte)in.readByte();
+ if (c == 0)
+ break;
+ text[k] = c;
+ }
+ String s;
+ try {
+ s = new String(text, 0, k, "Cp1252");
+ }
+ catch (UnsupportedEncodingException e) {
+ s = new String(text, 0, k);
+ }
+ outputText(x, y, flag, x1, y1, x2, y2, s);
+ break;
+ }
+ case META_TEXTOUT:
+ {
+ int count = in.readWord();
+ byte text[] = new byte[count];
+ int k;
+ for (k = 0; k < count; ++k) {
+ byte c = (byte)in.readByte();
+ if (c == 0)
+ break;
+ text[k] = c;
+ }
+ String s;
+ try {
+ s = new String(text, 0, k, "Cp1252");
+ }
+ catch (UnsupportedEncodingException e) {
+ s = new String(text, 0, k);
+ }
+ count = (count + 1) & 0xfffe;
+ in.skip(count - k);
+ int y = in.readShort();
+ int x = in.readShort();
+ outputText(x, y, 0, 0, 0, 0, 0, s);
+ break;
+ }
+ case META_SETBKCOLOR:
+ state.setCurrentBackgroundColor(in.readColor());
+ break;
+ case META_SETTEXTCOLOR:
+ state.setCurrentTextColor(in.readColor());
+ break;
+ case META_SETTEXTALIGN:
+ state.setTextAlign(in.readWord());
+ break;
+ case META_SETBKMODE:
+ state.setBackgroundMode(in.readWord());
+ break;
+ case META_SETPOLYFILLMODE:
+ state.setPolyFillMode(in.readWord());
+ break;
+ case META_SETPIXEL:
+ {
+ Color color = in.readColor();
+ int y = in.readShort();
+ int x = in.readShort();
+ cb.saveState();
+ cb.setColorFill(color);
+ cb.rectangle(state.transformX(x), state.transformY(y), .2f, .2f);
+ cb.fill();
+ cb.restoreState();
+ break;
+ }
+ case META_DIBSTRETCHBLT:
+ case META_STRETCHDIB: {
+ int rop = in.readInt();
+ if (function == META_STRETCHDIB) {
+ /*int usage = */ in.readWord();
+ }
+ int srcHeight = in.readShort();
+ int srcWidth = in.readShort();
+ int ySrc = in.readShort();
+ int xSrc = in.readShort();
+ float destHeight = state.transformY(in.readShort()) - state.transformY(0);
+ float destWidth = state.transformX(in.readShort()) - state.transformX(0);
+ float yDest = state.transformY(in.readShort());
+ float xDest = state.transformX(in.readShort());
+ byte b[] = new byte[(tsize * 2) - (in.getLength() - lenMarker)];
+ for (int k = 0; k < b.length; ++k)
+ b[k] = (byte)in.readByte();
+ try {
+ ByteArrayInputStream inb = new ByteArrayInputStream(b);
+ Image bmp = BmpImage.getImage(inb, true, b.length);
+ cb.saveState();
+ cb.rectangle(xDest, yDest, destWidth, destHeight);
+ cb.clip();
+ cb.newPath();
+ bmp.scaleAbsolute(destWidth * bmp.width() / srcWidth, -destHeight * bmp.height() / srcHeight);
+ bmp.setAbsolutePosition(xDest - destWidth * xSrc / srcWidth, yDest + destHeight * ySrc / srcHeight - bmp.scaledHeight());
+ cb.addImage(bmp);
+ cb.restoreState();
+ }
+ catch (Exception e) {
+ // empty on purpose
+ }
+ break;
+ }
+ }
+ in.skip((tsize * 2) - (in.getLength() - lenMarker));
+ }
+ state.cleanup(cb);
+ }
+
+ public void outputText(int x, int y, int flag, int x1, int y1, int x2, int y2, String text) throws IOException {
+ MetaFont font = state.getCurrentFont();
+ float refX = state.transformX(x);
+ float refY = state.transformY(y);
+ float angle = state.transformAngle(font.getAngle());
+ float sin = (float)Math.sin(angle);
+ float cos = (float)Math.cos(angle);
+ float fontSize = font.getFontSize(state);
+ BaseFont bf = font.getFont();
+ int align = state.getTextAlign();
+ float textWidth = bf.getWidthPoint(text, fontSize);
+ float tx = 0;
+ float ty = 0;
+ float descender = bf.getFontDescriptor(BaseFont.DESCENT, fontSize);
+ float ury = bf.getFontDescriptor(BaseFont.BBOXURY, fontSize);
+ cb.saveState();
+ cb.concatCTM(cos, sin, -sin, cos, refX, refY);
+ if ((align & MetaState.TA_CENTER) == MetaState.TA_CENTER)
+ tx = -textWidth / 2;
+ else if ((align & MetaState.TA_RIGHT) == MetaState.TA_RIGHT)
+ tx = -textWidth;
+ if ((align & MetaState.TA_BASELINE) == MetaState.TA_BASELINE)
+ ty = 0;
+ else if ((align & MetaState.TA_BOTTOM) == MetaState.TA_BOTTOM)
+ ty = -descender;
+ else
+ ty = -ury;
+ Color textColor;
+ if (state.getBackgroundMode() == MetaState.OPAQUE) {
+ textColor = state.getCurrentBackgroundColor();
+ cb.setColorFill(textColor);
+ cb.rectangle(tx, ty + descender, textWidth, ury - descender);
+ cb.fill();
+ }
+ textColor = state.getCurrentTextColor();
+ cb.setColorFill(textColor);
+ cb.beginText();
+ cb.setFontAndSize(bf, fontSize);
+ cb.setTextMatrix(tx, ty);
+ cb.showText(text);
+ cb.endText();
+ if (font.isUnderline()) {
+ cb.rectangle(tx, ty - fontSize / 4, textWidth, fontSize / 15);
+ cb.fill();
+ }
+ if (font.isStrikeout()) {
+ cb.rectangle(tx, ty + fontSize / 3, textWidth, fontSize / 15);
+ cb.fill();
+ }
+ cb.restoreState();
+ }
+
+ public boolean isNullStrokeFill(boolean isRectangle) {
+ MetaPen pen = state.getCurrentPen();
+ MetaBrush brush = state.getCurrentBrush();
+ boolean noPen = (pen.getStyle() == MetaPen.PS_NULL);
+ int style = brush.getStyle();
+ boolean isBrush = (style == MetaBrush.BS_SOLID || (style == MetaBrush.BS_HATCHED && state.getBackgroundMode() == MetaState.OPAQUE));
+ boolean result = noPen && !isBrush;
+ if (!noPen) {
+ if (isRectangle)
+ state.setLineJoinRectangle(cb);
+ else
+ state.setLineJoinPolygon(cb);
+ }
+ return result;
+ }
+
+ public void strokeAndFill(){
+ MetaPen pen = state.getCurrentPen();
+ MetaBrush brush = state.getCurrentBrush();
+ int penStyle = pen.getStyle();
+ int brushStyle = brush.getStyle();
+ if (penStyle == MetaPen.PS_NULL) {
+ cb.closePath();
+ if (state.getPolyFillMode() == MetaState.ALTERNATE) {
+ cb.eoFill();
+ }
+ else {
+ cb.fill();
+ }
+ }
+ else {
+ boolean isBrush = (brushStyle == MetaBrush.BS_SOLID || (brushStyle == MetaBrush.BS_HATCHED && state.getBackgroundMode() == MetaState.OPAQUE));
+ if (isBrush) {
+ if (state.getPolyFillMode() == MetaState.ALTERNATE)
+ cb.closePathEoFillStroke();
+ else
+ cb.closePathFillStroke();
+ }
+ else {
+ cb.closePathStroke();
+ }
+ }
+ }
+
+ static float getArc(float xCenter, float yCenter, float xDot, float yDot) {
+ double s = Math.atan2(yDot - yCenter, xDot - xCenter);
+ if (s < 0)
+ s += Math.PI * 2;
+ return (float)(s / Math.PI * 180);
+ }
+
+ public static byte[] wrapBMP(Image image) throws IOException {
+ if (image.getOriginalType() != Image.ORIGINAL_BMP)
+ throw new IOException("Only BMP can be wrapped in WMF.");
+ InputStream imgIn;
+ byte data[] = null;
+ if (image.getOriginalData() == null) {
+ imgIn = image.url().openStream();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int b = 0;
+ while ((b = imgIn.read()) != -1)
+ out.write(b);
+ imgIn.close();
+ data = out.toByteArray();
+ }
+ else
+ data = image.getOriginalData();
+ int sizeBmpWords = (data.length - 14 + 1) >>> 1;
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ // write metafile header
+ writeWord(os, 1);
+ writeWord(os, 9);
+ writeWord(os, 0x0300);
+ writeDWord(os, 9 + 4 + 5 + 5 + (13 + sizeBmpWords) + 3); // total metafile size
+ writeWord(os, 1);
+ writeDWord(os, 14 + sizeBmpWords); // max record size
+ writeWord(os, 0);
+ // write records
+ writeDWord(os, 4);
+ writeWord(os, META_SETMAPMODE);
+ writeWord(os, 8);
+
+ writeDWord(os, 5);
+ writeWord(os, META_SETWINDOWORG);
+ writeWord(os, 0);
+ writeWord(os, 0);
+
+ writeDWord(os, 5);
+ writeWord(os, META_SETWINDOWEXT);
+ writeWord(os, (int)image.height());
+ writeWord(os, (int)image.width());
+
+ writeDWord(os, 13 + sizeBmpWords);
+ writeWord(os, META_DIBSTRETCHBLT);
+ writeDWord(os, 0x00cc0020);
+ writeWord(os, (int)image.height());
+ writeWord(os, (int)image.width());
+ writeWord(os, 0);
+ writeWord(os, 0);
+ writeWord(os, (int)image.height());
+ writeWord(os, (int)image.width());
+ writeWord(os, 0);
+ writeWord(os, 0);
+ os.write(data, 14, data.length - 14);
+ if ((data.length & 1) == 1)
+ os.write(0);
+// writeDWord(os, 14 + sizeBmpWords);
+// writeWord(os, META_STRETCHDIB);
+// writeDWord(os, 0x00cc0020);
+// writeWord(os, 0);
+// writeWord(os, (int)image.height());
+// writeWord(os, (int)image.width());
+// writeWord(os, 0);
+// writeWord(os, 0);
+// writeWord(os, (int)image.height());
+// writeWord(os, (int)image.width());
+// writeWord(os, 0);
+// writeWord(os, 0);
+// os.write(data, 14, data.length - 14);
+// if ((data.length & 1) == 1)
+// os.write(0);
+
+ writeDWord(os, 3);
+ writeWord(os, 0);
+ os.close();
+ return os.toByteArray();
+ }
+
+ public static void writeWord(OutputStream os, int v) throws IOException {
+ os.write(v & 0xff);
+ os.write((v >>> 8) & 0xff);
+ }
+
+ public static void writeDWord(OutputStream os, int v) throws IOException {
+ writeWord(os, v & 0xffff);
+ writeWord(os, (v >>> 16) & 0xffff);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java
new file mode 100644
index 0000000..70da31d
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaFont.java
@@ -0,0 +1,211 @@
+/*
+ * $Id: MetaFont.java,v 1.3 2005/11/02 18:03:45 psoares33 Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import com.lowagie.text.pdf.*;
+import com.lowagie.text.Font;
+import com.lowagie.text.FontFactory;
+import com.lowagie.text.ExceptionConverter;
+
+public class MetaFont extends MetaObject {
+ static final String fontNames[] = {
+ "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
+ "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
+ "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
+ "Symbol", "ZapfDingbats"};
+
+ static final int MARKER_BOLD = 1;
+ static final int MARKER_ITALIC = 2;
+ static final int MARKER_COURIER = 0;
+ static final int MARKER_HELVETICA = 4;
+ static final int MARKER_TIMES = 8;
+ static final int MARKER_SYMBOL = 12;
+
+ static final int DEFAULT_PITCH = 0;
+ static final int FIXED_PITCH = 1;
+ static final int VARIABLE_PITCH = 2;
+ static final int FF_DONTCARE = 0;
+ static final int FF_ROMAN = 1;
+ static final int FF_SWISS = 2;
+ static final int FF_MODERN = 3;
+ static final int FF_SCRIPT = 4;
+ static final int FF_DECORATIVE = 5;
+ static final int BOLDTHRESHOLD = 600;
+ static final int nameSize = 32;
+ static final int ETO_OPAQUE = 2;
+ static final int ETO_CLIPPED = 4;
+
+ int height;
+ float angle;
+ int bold;
+ int italic;
+ boolean underline;
+ boolean strikeout;
+ int charset;
+ int pitchAndFamily;
+ String faceName = "arial";
+ BaseFont font = null;
+
+ public MetaFont() {
+ type = META_FONT;
+ }
+
+ public void init(InputMeta in) throws IOException {
+ height = Math.abs(in.readShort());
+ in.skip(2);
+ angle = (float)(in.readShort() / 1800.0 * Math.PI);
+ in.skip(2);
+ bold = (in.readShort() >= BOLDTHRESHOLD ? MARKER_BOLD : 0);
+ italic = (in.readByte() != 0 ? MARKER_ITALIC : 0);
+ underline = (in.readByte() != 0);
+ strikeout = (in.readByte() != 0);
+ charset = in.readByte();
+ in.skip(3);
+ pitchAndFamily = in.readByte();
+ byte name[] = new byte[nameSize];
+ int k;
+ for (k = 0; k < nameSize; ++k) {
+ int c = in.readByte();
+ if (c == 0) {
+ break;
+ }
+ name[k] = (byte)c;
+ }
+ try {
+ faceName = new String(name, 0, k, "Cp1252");
+ }
+ catch (UnsupportedEncodingException e) {
+ faceName = new String(name, 0, k);
+ }
+ faceName = faceName.toLowerCase();
+ }
+
+ public BaseFont getFont() {
+ if (font != null)
+ return font;
+ Font ff2 = FontFactory.getFont(faceName, BaseFont.CP1252, true, 10, ((italic != 0) ? Font.ITALIC : 0) | ((bold != 0) ? Font.BOLD : 0));
+ font = ff2.getBaseFont();
+ if (font != null)
+ return font;
+ String fontName;
+ if (faceName.indexOf("courier") != -1 || faceName.indexOf("terminal") != -1
+ || faceName.indexOf("fixedsys") != -1) {
+ fontName = fontNames[MARKER_COURIER + italic + bold];
+ }
+ else if (faceName.indexOf("ms sans serif") != -1 || faceName.indexOf("arial") != -1
+ || faceName.indexOf("system") != -1) {
+ fontName = fontNames[MARKER_HELVETICA + italic + bold];
+ }
+ else if (faceName.indexOf("arial black") != -1) {
+ fontName = fontNames[MARKER_HELVETICA + italic + MARKER_BOLD];
+ }
+ else if (faceName.indexOf("times") != -1 || faceName.indexOf("ms serif") != -1
+ || faceName.indexOf("roman") != -1) {
+ fontName = fontNames[MARKER_TIMES + italic + bold];
+ }
+ else if (faceName.indexOf("symbol") != -1) {
+ fontName = fontNames[MARKER_SYMBOL];
+ }
+ else {
+ int pitch = pitchAndFamily & 3;
+ int family = (pitchAndFamily >> 4) & 7;
+ switch (family) {
+ case FF_MODERN:
+ fontName = fontNames[MARKER_COURIER + italic + bold];
+ break;
+ case FF_ROMAN:
+ fontName = fontNames[MARKER_TIMES + italic + bold];
+ break;
+ case FF_SWISS:
+ case FF_SCRIPT:
+ case FF_DECORATIVE:
+ fontName = fontNames[MARKER_HELVETICA + italic + bold];
+ break;
+ default:
+ {
+ switch (pitch) {
+ case FIXED_PITCH:
+ fontName = fontNames[MARKER_COURIER + italic + bold];
+ break;
+ default:
+ fontName = fontNames[MARKER_HELVETICA + italic + bold];
+ break;
+ }
+ }
+ }
+ }
+ try {
+ font = BaseFont.createFont(fontName, "Cp1252", false);
+ }
+ catch (Exception e) {
+ throw new ExceptionConverter(e);
+ }
+
+ return font;
+ }
+
+ public float getAngle() {
+ return angle;
+ }
+
+ public boolean isUnderline() {
+ return underline;
+ }
+
+ public boolean isStrikeout() {
+ return strikeout;
+ }
+
+ public float getFontSize(MetaState state) {
+ return Math.abs(state.transformY(height) - state.transformY(0)) * 0.86f;
+ }
+}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java
new file mode 100644
index 0000000..d31fb02
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaObject.java
@@ -0,0 +1,71 @@
+/*
+ * $Id: MetaObject.java,v 1.2 2005/05/04 14:33:18 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+
+public class MetaObject {
+ public static final int META_NOT_SUPPORTED = 0;
+ public static final int META_PEN = 1;
+ public static final int META_BRUSH = 2;
+ public static final int META_FONT = 3;
+ public int type = META_NOT_SUPPORTED;
+
+ public MetaObject() {
+ }
+
+ public MetaObject(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java
new file mode 100644
index 0000000..29b85ca
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaPen.java
@@ -0,0 +1,91 @@
+/*
+ * $Id: MetaPen.java,v 1.2 2005/05/04 14:33:19 blowagie Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+import java.io.IOException;
+import java.awt.Color;
+
+public class MetaPen extends MetaObject {
+
+ public static final int PS_SOLID = 0;
+ public static final int PS_DASH = 1;
+ public static final int PS_DOT = 2;
+ public static final int PS_DASHDOT = 3;
+ public static final int PS_DASHDOTDOT = 4;
+ public static final int PS_NULL = 5;
+ public static final int PS_INSIDEFRAME = 6;
+
+ int style = PS_SOLID;
+ int penWidth = 1;
+ Color color = Color.black;
+
+ public MetaPen() {
+ type = META_PEN;
+ }
+
+ public void init(InputMeta in) throws IOException {
+ style = in.readWord();
+ penWidth = in.readShort();
+ in.readWord();
+ color = in.readColor();
+ }
+
+ public int getStyle() {
+ return style;
+ }
+
+ public int getPenWidth() {
+ return penWidth;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+}
diff --git a/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java
new file mode 100644
index 0000000..97f18f4
--- /dev/null
+++ b/src/main/java/com/lowagie/text/pdf/codec/wmf/MetaState.java
@@ -0,0 +1,372 @@
+/*
+ * $Id: MetaState.java,v 1.5 2005/12/01 16:57:15 psoares33 Exp $
+ * $Name: $
+ *
+ * Copyright 2001, 2002 Paulo Soares
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the License.
+ *
+ * The Original Code is 'iText, a free JAVA-PDF library'.
+ *
+ * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
+ * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
+ * All Rights Reserved.
+ * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
+ * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
+ *
+ * Contributor(s): all the names of the contributors are added in the source code
+ * where applicable.
+ *
+ * Alternatively, the contents of this file may be used under the terms of the
+ * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
+ * provisions of LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of the LGPL
+ * License and not to allow others to use your version of this file under
+ * the MPL, indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by the LGPL.
+ * If you do not delete the provisions above, a recipient may use your version
+ * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MPL as stated above or under the terms of the GNU
+ * Library General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
+ * details.
+ *
+ * If you didn't download this code from the following link, you should check if
+ * you aren't using an obsolete version:
+ * http://www.lowagie.com/iText/
+ */
+
+package com.lowagie.text.pdf.codec.wmf;
+
+import java.util.ArrayList;
+import java.util.Stack;
+import java.awt.Point;
+import java.awt.Color;
+import com.lowagie.text.pdf.*;
+
+public class MetaState {
+
+ public static final int TA_NOUPDATECP = 0;
+ public static final int TA_UPDATECP = 1;
+ public static final int TA_LEFT = 0;
+ public static final int TA_RIGHT = 2;
+ public static final int TA_CENTER = 6;
+ public static final int TA_TOP = 0;
+ public static final int TA_BOTTOM = 8;
+ public static final int TA_BASELINE = 24;
+
+ public static final int TRANSPARENT = 1;
+ public static final int OPAQUE = 2;
+
+ public static final int ALTERNATE = 1;
+ public static final int WINDING = 2;
+
+ public Stack savedStates;
+ public ArrayList MetaObjects;
+ public Point currentPoint;
+ public MetaPen currentPen;
+ public MetaBrush currentBrush;
+ public MetaFont currentFont;
+ public Color currentBackgroundColor = Color.white;
+ public Color currentTextColor = Color.black;
+ public int backgroundMode = OPAQUE;
+ public int polyFillMode = ALTERNATE;
+ public int lineJoin = 1;
+ public int textAlign;
+ public int offsetWx;
+ public int offsetWy;
+ public int extentWx;
+ public int extentWy;
+ public float scalingX;
+ public float scalingY;
+
+
+ /** Creates new MetaState */
+ public MetaState() {
+ savedStates = new Stack();
+ MetaObjects = new ArrayList();
+ currentPoint = new Point(0, 0);
+ currentPen = new MetaPen();
+ currentBrush = new MetaBrush();
+ currentFont = new MetaFont();
+ }
+
+ public MetaState(MetaState state) {
+ setMetaState(state);
+ }
+
+ public void setMetaState(MetaState state) {
+ savedStates = state.savedStates;
+ MetaObjects = state.MetaObjects;
+ currentPoint = state.currentPoint;
+ currentPen = state.currentPen;
+ currentBrush = state.currentBrush;
+ currentFont = state.currentFont;
+ currentBackgroundColor = state.currentBackgroundColor;
+ currentTextColor = state.currentTextColor;
+ backgroundMode = state.backgroundMode;
+ polyFillMode = state.polyFillMode;
+ textAlign = state.textAlign;
+ lineJoin = state.lineJoin;
+ offsetWx = state.offsetWx;
+ offsetWy = state.offsetWy;
+ extentWx = state.extentWx;
+ extentWy = state.extentWy;
+ scalingX = state.scalingX;
+ scalingY = state.scalingY;
+ }
+
+ public void addMetaObject(MetaObject object) {
+ for (int k = 0; k < MetaObjects.size(); ++k) {
+ if (MetaObjects.get(k) == null) {
+ MetaObjects.set(k, object);
+ return;
+ }
+ }
+ MetaObjects.add(object);
+ }
+
+ public void selectMetaObject(int index, PdfContentByte cb) {
+ MetaObject obj = (MetaObject)MetaObjects.get(index);
+ if (obj == null)
+ return;
+ int style;
+ switch (obj.getType()) {
+ case MetaObject.META_BRUSH:
+ currentBrush = (MetaBrush)obj;
+ style = currentBrush.getStyle();
+ if (style == MetaBrush.BS_SOLID) {
+ Color color = currentBrush.getColor();
+ cb.setColorFill(color);
+ }
+ else if (style == MetaBrush.BS_HATCHED) {
+ Color color = currentBackgroundColor;
+ cb.setColorFill(color);
+ }
+ break;
+ case MetaObject.META_PEN:
+ {
+ currentPen = (MetaPen)obj;
+ style = currentPen.getStyle();
+ if (style != MetaPen.PS_NULL) {
+ Color color = currentPen.getColor();
+ cb.setColorStroke(color);
+ cb.setLineWidth(Math.abs((float)currentPen.getPenWidth() * scalingX / extentWx));
+ switch (style) {
+ case MetaPen.PS_DASH:
+ cb.setLineDash(18, 6, 0);
+ break;
+ case MetaPen.PS_DASHDOT:
+ cb.setLiteral("[9 6 3 6]0 d\n");
+ break;
+ case MetaPen.PS_DASHDOTDOT:
+ cb.setLiteral("[9 3 3 3 3 3]0 d\n");
+ break;
+ case MetaPen.PS_DOT:
+ cb.setLineDash(3, 0);
+ break;
+ default:
+ cb.setLineDash(0);
+ break;
+ }
+ }
+ break;
+ }
+ case MetaObject.META_FONT:
+ {
+ currentFont = (MetaFont)obj;
+ break;
+ }
+ }
+ }
+
+ public void deleteMetaObject(int index) {
+ MetaObjects.set(index, null);
+ }
+
+ public void saveState(PdfContentByte cb) {
+ cb.saveState();
+ MetaState state = new MetaState(this);
+ savedStates.push(state);
+ }
+
+ public void restoreState(int index, PdfContentByte cb) {
+ int pops;
+ if (index < 0)
+ pops = Math.min(-index, savedStates.size());
+ else
+ pops = Math.max(savedStates.size() - index, 0);
+ if (pops == 0)
+ return;
+ MetaState state = null;
+ while (pops-- != 0) {
+ cb.restoreState();
+ state = (MetaState)savedStates.pop();
+ }
+ setMetaState(state);
+ }
+
+ public void cleanup(PdfContentByte cb) {
+ int k = savedStates.size();
+ while (k-- > 0)
+ cb.restoreState();
+ }
+
+ public float transformX(int x) {
+ return ((float)x - offsetWx) * scalingX / extentWx;
+ }
+
+ public float transformY(int y) {
+ return (1f - ((float)y - offsetWy) / extentWy) * scalingY;
+ }
+
+ public void setScalingX(float scalingX) {
+ this.scalingX = scalingX;
+ }
+
+ public void setScalingY(float scalingY) {
+ this.scalingY = scalingY;
+ }
+
+ public void setOffsetWx(int offsetWx) {
+ this.offsetWx = offsetWx;
+ }
+
+ public void setOffsetWy(int offsetWy) {
+ this.offsetWy = offsetWy;
+ }
+
+ public void setExtentWx(int extentWx) {
+ this.extentWx = extentWx;
+ }
+
+ public void setExtentWy(int extentWy) {
+ this.extentWy = extentWy;
+ }
+
+ public float transformAngle(float angle) {
+ float ta = scalingY < 0 ? -angle : angle;
+ return (float)(scalingX < 0 ? Math.PI - ta : ta);
+ }
+
+ public void setCurrentPoint(Point p) {
+ currentPoint = p;
+ }
+
+ public Point getCurrentPoint() {
+ return currentPoint;
+ }
+
+ public MetaBrush getCurrentBrush() {
+ return currentBrush;
+ }
+
+ public MetaPen getCurrentPen() {
+ return currentPen;
+ }
+
+ public MetaFont getCurrentFont() {
+ return currentFont;
+ }
+
+ /** Getter for property currentBackgroundColor.
+ * @return Value of property currentBackgroundColor.
+ */
+ public Color getCurrentBackgroundColor() {
+ return currentBackgroundColor;
+ }
+
+ /** Setter for property currentBackgroundColor.
+ * @param currentBackgroundColor New value of property currentBackgroundColor.
+ */
+ public void setCurrentBackgroundColor(Color currentBackgroundColor) {
+ this.currentBackgroundColor = currentBackgroundColor;
+ }
+
+ /** Getter for property currentTextColor.
+ * @return Value of property currentTextColor.
+ */
+ public Color getCurrentTextColor() {
+ return currentTextColor;
+ }
+
+ /** Setter for property currentTextColor.
+ * @param currentTextColor New value of property currentTextColor.
+ */
+ public void setCurrentTextColor(Color currentTextColor) {
+ this.currentTextColor = currentTextColor;
+ }
+
+ /** Getter for property backgroundMode.
+ * @return Value of property backgroundMode.
+ */
+ public int getBackgroundMode() {
+ return backgroundMode;
+ }
+
+ /** Setter for property backgroundMode.
+ * @param backgroundMode New value of property backgroundMode.
+ */
+ public void setBackgroundMode(int backgroundMode) {
+ this.backgroundMode = backgroundMode;
+ }
+
+ /** Getter for property textAlign.
+ * @return Value of property textAlign.
+ */
+ public int getTextAlign() {
+ return textAlign;
+ }
+
+ /** Setter for property textAlign.
+ * @param textAlign New value of property textAlign.
+ */
+ public void setTextAlign(int textAlign) {
+ this.textAlign = textAlign;
+ }
+
+ /** Getter for property polyFillMode.
+ * @return Value of property polyFillMode.
+ */
+ public int getPolyFillMode() {
+ return polyFillMode;
+ }
+
+ /** Setter for property polyFillMode.
+ * @param polyFillMode New value of property polyFillMode.
+ */
+ public void setPolyFillMode(int polyFillMode) {
+ this.polyFillMode = polyFillMode;
+ }
+
+ public void setLineJoinRectangle(PdfContentByte cb) {
+ if (lineJoin != 0) {
+ lineJoin = 0;
+ cb.setLineJoin(0);
+ }
+ }
+
+ public void setLineJoinPolygon(PdfContentByte cb) {
+ if (lineJoin == 0) {
+ lineJoin = 1;
+ cb.setLineJoin(1);
+ }
+ }
+
+ public boolean getLineNeutral() {
+ return (lineJoin == 0);
+ }
+
+}