WMF fixes
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1722046 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ae1020ac35
commit
a89d5210c3
@ -0,0 +1,189 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.hwmf.draw;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.record.HwmfBrushStyle;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfColorRef;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfFill.WmfSetPolyfillMode.HwmfPolyfillMode;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfHatchStyle;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfMapMode;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfPenStyle;
|
||||||
|
|
||||||
|
public class HwmfDrawProperties {
|
||||||
|
private Rectangle2D window = new Rectangle2D.Double(0, 0, 1, 1);
|
||||||
|
private Rectangle2D viewport = new Rectangle2D.Double(0, 0, 1, 1);
|
||||||
|
private Point2D location = new Point2D.Double(0,0);
|
||||||
|
private HwmfMapMode mapMode = HwmfMapMode.MM_ANISOTROPIC;
|
||||||
|
private HwmfColorRef backgroundColor = new HwmfColorRef(Color.BLACK);
|
||||||
|
private HwmfBrushStyle brushStyle = HwmfBrushStyle.BS_SOLID;
|
||||||
|
private HwmfColorRef brushColor = new HwmfColorRef(Color.BLACK);
|
||||||
|
private HwmfHatchStyle brushHatch = HwmfHatchStyle.HS_HORIZONTAL;
|
||||||
|
private BufferedImage brushBitmap = null;
|
||||||
|
private double penWidth = 1;
|
||||||
|
private HwmfPenStyle penStyle = HwmfPenStyle.valueOf(0);
|
||||||
|
private HwmfColorRef penColor = new HwmfColorRef(Color.BLACK);
|
||||||
|
private double penMiterLimit = 10;
|
||||||
|
private HwmfBkMode bkMode = HwmfBkMode.OPAQUE;
|
||||||
|
private HwmfPolyfillMode polyfillMode = HwmfPolyfillMode.WINDING;
|
||||||
|
|
||||||
|
public void setViewportExt(double width, double height) {
|
||||||
|
double x = viewport.getX();
|
||||||
|
double y = viewport.getY();
|
||||||
|
double w = (width != 0) ? width : viewport.getWidth();
|
||||||
|
double h = (height != 0) ? height : viewport.getHeight();
|
||||||
|
viewport.setRect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setViewportOrg(double x, double y) {
|
||||||
|
double w = viewport.getWidth();
|
||||||
|
double h = viewport.getHeight();
|
||||||
|
viewport.setRect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle2D getViewport() {
|
||||||
|
return (Rectangle2D)viewport.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindowExt(double width, double height) {
|
||||||
|
double x = window.getX();
|
||||||
|
double y = window.getY();
|
||||||
|
double w = (width != 0) ? width : window.getWidth();
|
||||||
|
double h = (height != 0) ? height : window.getHeight();
|
||||||
|
window.setRect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWindowOrg(double x, double y) {
|
||||||
|
double w = window.getWidth();
|
||||||
|
double h = window.getHeight();
|
||||||
|
window.setRect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle2D getWindow() {
|
||||||
|
return (Rectangle2D)window.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocation(double x, double y) {
|
||||||
|
location.setLocation(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point2D getLocation() {
|
||||||
|
return (Point2D)location.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMapMode(HwmfMapMode mapMode) {
|
||||||
|
this.mapMode = mapMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfMapMode getMapMode() {
|
||||||
|
return mapMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfBrushStyle getBrushStyle() {
|
||||||
|
return brushStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrushStyle(HwmfBrushStyle brushStyle) {
|
||||||
|
this.brushStyle = brushStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfHatchStyle getBrushHatch() {
|
||||||
|
return brushHatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrushHatch(HwmfHatchStyle brushHatch) {
|
||||||
|
this.brushHatch = brushHatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfColorRef getBrushColor() {
|
||||||
|
return brushColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrushColor(HwmfColorRef brushColor) {
|
||||||
|
this.brushColor = brushColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfBkMode getBkMode() {
|
||||||
|
return bkMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBkMode(HwmfBkMode bkMode) {
|
||||||
|
this.bkMode = bkMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfPenStyle getPenStyle() {
|
||||||
|
return penStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenStyle(HwmfPenStyle penStyle) {
|
||||||
|
this.penStyle = penStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfColorRef getPenColor() {
|
||||||
|
return penColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenColor(HwmfColorRef penColor) {
|
||||||
|
this.penColor = penColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPenWidth() {
|
||||||
|
return penWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenWidth(double penWidth) {
|
||||||
|
this.penWidth = penWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getPenMiterLimit() {
|
||||||
|
return penMiterLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPenMiterLimit(double penMiterLimit) {
|
||||||
|
this.penMiterLimit = penMiterLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfColorRef getBackgroundColor() {
|
||||||
|
return backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBackgroundColor(HwmfColorRef backgroundColor) {
|
||||||
|
this.backgroundColor = backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfPolyfillMode getPolyfillMode() {
|
||||||
|
return polyfillMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPolyfillMode(HwmfPolyfillMode polyfillMode) {
|
||||||
|
this.polyfillMode = polyfillMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getBrushBitmap() {
|
||||||
|
return brushBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBrushBitmap(BufferedImage brushBitmap) {
|
||||||
|
this.brushBitmap = brushBitmap;
|
||||||
|
}
|
||||||
|
}
|
185
src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
Normal file
185
src/scratchpad/src/org/apache/poi/hwmf/draw/HwmfGraphics.java
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.hwmf.draw;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Paint;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Shape;
|
||||||
|
import java.awt.TexturePaint;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.GeneralPath;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Deque;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.record.HwmfBrushStyle;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfHatchStyle;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfPenStyle;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfPenStyle.HwmfLineDash;
|
||||||
|
import org.apache.poi.util.Units;
|
||||||
|
|
||||||
|
public class HwmfGraphics {
|
||||||
|
private final Graphics2D graphicsCtx;
|
||||||
|
private final Deque<HwmfDrawProperties> propStack = new ArrayDeque<HwmfDrawProperties>();
|
||||||
|
HwmfDrawProperties prop;
|
||||||
|
|
||||||
|
public HwmfGraphics(Graphics2D graphicsCtx) {
|
||||||
|
this.graphicsCtx = graphicsCtx;
|
||||||
|
prop = new HwmfDrawProperties();
|
||||||
|
propStack.push(prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfDrawProperties getProperties() {
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Shape shape) {
|
||||||
|
HwmfLineDash lineDash = prop.getPenStyle().getLineDash();
|
||||||
|
if (lineDash == HwmfLineDash.NULL) {
|
||||||
|
// line is not drawn
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape tshape = fitShapeToView(shape);
|
||||||
|
BasicStroke stroke = getStroke();
|
||||||
|
|
||||||
|
// 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)) {
|
||||||
|
graphicsCtx.setStroke(new BasicStroke(stroke.getLineWidth()));
|
||||||
|
graphicsCtx.setColor(prop.getBackgroundColor().getColor());
|
||||||
|
graphicsCtx.draw(tshape);
|
||||||
|
}
|
||||||
|
|
||||||
|
// then draw the (dashed) line
|
||||||
|
graphicsCtx.setStroke(stroke);
|
||||||
|
graphicsCtx.setColor(prop.getPenColor().getColor());
|
||||||
|
graphicsCtx.draw(tshape);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(Shape shape) {
|
||||||
|
if (prop.getBrushStyle() != HwmfBrushStyle.BS_NULL) {
|
||||||
|
GeneralPath gp = new GeneralPath(shape);
|
||||||
|
gp.setWindingRule(prop.getPolyfillMode().awtFlag);
|
||||||
|
Shape tshape = fitShapeToView(gp);
|
||||||
|
graphicsCtx.setPaint(getFill());
|
||||||
|
graphicsCtx.fill(tshape);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Shape fitShapeToView(Shape shape) {
|
||||||
|
int scaleUnits = prop.getMapMode().scale;
|
||||||
|
Rectangle2D view = prop.getViewport(), win = prop.getWindow();
|
||||||
|
double scaleX, scaleY;
|
||||||
|
switch (scaleUnits) {
|
||||||
|
case -1:
|
||||||
|
scaleX = view.getWidth() / win.getWidth();
|
||||||
|
scaleY = view.getHeight() / win.getHeight();
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
scaleX = scaleY = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
scaleX = scaleY = scaleUnits / (double)Units.POINT_DPI;
|
||||||
|
}
|
||||||
|
|
||||||
|
AffineTransform at = new AffineTransform();
|
||||||
|
at.translate(view.getX(), view.getY());
|
||||||
|
at.scale(scaleX, scaleY);
|
||||||
|
at.translate(-win.getX(), -win.getY());
|
||||||
|
at.translate(-view.getX(), -view.getY());
|
||||||
|
|
||||||
|
return at.createTransformedShape(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BasicStroke getStroke() {
|
||||||
|
Rectangle2D view = prop.getViewport(), win = prop.getWindow();
|
||||||
|
float width = (float)(prop.getPenWidth() * view.getWidth() / win.getWidth());
|
||||||
|
HwmfPenStyle ps = prop.getPenStyle();
|
||||||
|
int cap = ps.getLineCap().awtFlag;
|
||||||
|
int join = ps.getLineJoin().awtFlag;
|
||||||
|
float miterLimit = (float)prop.getPenMiterLimit();
|
||||||
|
float dashes[] = ps.getLineDash().dashes;
|
||||||
|
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.
|
||||||
|
float dashStart = (dashAlt && dashes.length > 1) ? dashes[0] : 0;
|
||||||
|
|
||||||
|
return new BasicStroke(width, cap, join, miterLimit, dashes, dashStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Paint getFill() {
|
||||||
|
switch (prop.getBrushStyle()) {
|
||||||
|
default:
|
||||||
|
case BS_INDEXED:
|
||||||
|
case BS_PATTERN8X8:
|
||||||
|
case BS_DIBPATTERN8X8:
|
||||||
|
case BS_MONOPATTERN:
|
||||||
|
case BS_NULL: return null;
|
||||||
|
case BS_PATTERN:
|
||||||
|
case BS_DIBPATTERN:
|
||||||
|
case BS_DIBPATTERNPT: return getPatternPaint();
|
||||||
|
case BS_SOLID: return getSolidFill();
|
||||||
|
case BS_HATCHED: return getHatchedFill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Paint getSolidFill() {
|
||||||
|
return prop.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)
|
||||||
|
? new Color(0, true)
|
||||||
|
: prop.getBackgroundColor().getColor();
|
||||||
|
g.setColor(c);
|
||||||
|
g.fillRect(0, 0, dim, dim);
|
||||||
|
g.setColor(prop.getBrushColor().getColor());
|
||||||
|
HwmfHatchStyle h = prop.getBrushHatch();
|
||||||
|
if (h == HwmfHatchStyle.HS_HORIZONTAL || h == HwmfHatchStyle.HS_CROSS) {
|
||||||
|
g.drawLine(0, mid, dim, mid);
|
||||||
|
}
|
||||||
|
if (h == HwmfHatchStyle.HS_VERTICAL || h == HwmfHatchStyle.HS_CROSS) {
|
||||||
|
g.drawLine(mid, 0, mid, dim);
|
||||||
|
}
|
||||||
|
if (h == HwmfHatchStyle.HS_FDIAGONAL || h == HwmfHatchStyle.HS_DIAGCROSS) {
|
||||||
|
g.drawLine(0, 0, dim, dim);
|
||||||
|
}
|
||||||
|
if (h == HwmfHatchStyle.HS_BDIAGONAL || h == HwmfHatchStyle.HS_DIAGCROSS) {
|
||||||
|
g.drawLine(0, dim, dim, 0);
|
||||||
|
}
|
||||||
|
g.dispose();
|
||||||
|
return new TexturePaint(bi, new Rectangle(0,0,dim,dim));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Paint getPatternPaint() {
|
||||||
|
BufferedImage bi = prop.getBrushBitmap();
|
||||||
|
return (bi == null) ? null
|
||||||
|
: new TexturePaint(bi, new Rectangle(0,0,bi.getWidth(),bi.getHeight()));
|
||||||
|
}
|
||||||
|
}
|
@ -18,12 +18,9 @@
|
|||||||
package org.apache.poi.hwmf.record;
|
package org.apache.poi.hwmf.record;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.imageio.stream.ImageInputStream;
|
|
||||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
|
||||||
|
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
@ -75,31 +72,45 @@ public class HwmfBitmap16 {
|
|||||||
assert(skipSize == 18);
|
assert(skipSize == 18);
|
||||||
size += 18+LittleEndianConsts.INT_SIZE;
|
size += 18+LittleEndianConsts.INT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
|
||||||
|
|
||||||
int size2 = 0;
|
|
||||||
byte buf[] = new byte[widthBytes];
|
|
||||||
for (int h=0; h<height; h++) {
|
|
||||||
leis.read(buf);
|
|
||||||
size2 += widthBytes;
|
|
||||||
|
|
||||||
ImageInputStream iis = new MemoryCacheImageInputStream(new ByteArrayInputStream(buf));
|
|
||||||
|
|
||||||
for (int w=0; w<width; w++) {
|
|
||||||
long bitsAtPixel = iis.readBits(bitsPixel);
|
|
||||||
// TODO: is bitsPixel a multiple of 3 (r,g,b)
|
|
||||||
// which colortable should be used for the various bit sizes???
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int bytes = (((width * bitsPixel + 15) >> 4) << 1) * height;
|
int bytes = (((width * bitsPixel + 15) >> 4) << 1) * height;
|
||||||
assert (bytes == size2);
|
byte buf[] = new byte[bytes];
|
||||||
|
leis.read(buf);
|
||||||
size += size2;
|
|
||||||
|
FileOutputStream fos = new FileOutputStream("bla16.bmp");
|
||||||
|
fos.write(buf);
|
||||||
|
fos.close();
|
||||||
|
|
||||||
|
|
||||||
|
// BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
//
|
||||||
|
// int size2 = 0;
|
||||||
|
// byte buf[] = new byte[widthBytes];
|
||||||
|
// for (int h=0; h<height; h++) {
|
||||||
|
// leis.read(buf);
|
||||||
|
// size2 += widthBytes;
|
||||||
|
//
|
||||||
|
// ImageInputStream iis = new MemoryCacheImageInputStream(new ByteArrayInputStream(buf));
|
||||||
|
//
|
||||||
|
// for (int w=0; w<width; w++) {
|
||||||
|
// long bitsAtPixel = iis.readBits(bitsPixel);
|
||||||
|
// // TODO: is bitsPixel a multiple of 3 (r,g,b)
|
||||||
|
// // which colortable should be used for the various bit sizes???
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// assert (bytes == size2);
|
||||||
|
//
|
||||||
|
// size += size2;
|
||||||
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
|
return bi;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,16 @@ package org.apache.poi.hwmf.record;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.image.IndexColorModel;
|
import java.io.BufferedInputStream;
|
||||||
import java.awt.image.WritableRaster;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.apache.poi.hssf.record.RecordFormatException;
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
@ -59,25 +63,25 @@ public class HwmfBitmapDib {
|
|||||||
* Each pixel in the bitmap is represented by a 16-bit value.
|
* Each pixel in the bitmap is represented by a 16-bit value.
|
||||||
* <br/>
|
* <br/>
|
||||||
* If the Compression field of the BitmapInfoHeader Object is BI_RGB, the Colors field of DIB
|
* If the Compression field of the BitmapInfoHeader Object is BI_RGB, the Colors field of DIB
|
||||||
* is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of
|
* is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of
|
||||||
* red, green, and blue are represented with 5 bits for each color component. The value for blue
|
* red, green, and blue are represented with 5 bits for each color component. The value for blue
|
||||||
* is in the least significant 5 bits, followed by 5 bits each for green and red. The most significant
|
* is in the least significant 5 bits, followed by 5 bits each for green and red. The most significant
|
||||||
* bit is not used. The color table is used for optimizing colors on palette-based devices, and
|
* bit is not used. The color table is used for optimizing colors on palette-based devices, and
|
||||||
* contains the number of entries specified by the ColorUsed field of the BitmapInfoHeader
|
* contains the number of entries specified by the ColorUsed field of the BitmapInfoHeader
|
||||||
* Object.
|
* Object.
|
||||||
* <br/>
|
* <br/>
|
||||||
* If the Compression field of the BitmapInfoHeader Object is BI_BITFIELDS, the Colors field
|
* If the Compression field of the BitmapInfoHeader Object is BI_BITFIELDS, the Colors field
|
||||||
* contains three DWORD color masks that specify the red, green, and blue components,
|
* contains three DWORD color masks that specify the red, green, and blue components,
|
||||||
* respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.
|
* respectively, of each pixel. Each WORD in the bitmap array represents a single pixel.
|
||||||
* <br/>
|
* <br/>
|
||||||
* When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask MUST be
|
* When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask MUST be
|
||||||
* contiguous and SHOULD NOT overlap the bits of another mask.
|
* contiguous and SHOULD NOT overlap the bits of another mask.
|
||||||
*/
|
*/
|
||||||
BI_BITCOUNT_4(0x0010),
|
BI_BITCOUNT_4(0x0010),
|
||||||
/**
|
/**
|
||||||
* The bitmap has a maximum of 2^24 colors, and the Colors field of DIB is
|
* The bitmap has a maximum of 2^24 colors, and the Colors field of DIB is
|
||||||
* NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green,
|
* NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green,
|
||||||
* and red, respectively, for a pixel. The Colors color table is used for optimizing colors used on
|
* and red, respectively, for a pixel. The Colors color table is used for optimizing colors used on
|
||||||
* palette-based devices, and MUST contain the number of entries specified by the ColorUsed
|
* palette-based devices, and MUST contain the number of entries specified by the ColorUsed
|
||||||
* field of the BitmapInfoHeader Object.
|
* field of the BitmapInfoHeader Object.
|
||||||
*/
|
*/
|
||||||
@ -85,23 +89,23 @@ public class HwmfBitmapDib {
|
|||||||
/**
|
/**
|
||||||
* The bitmap has a maximum of 2^24 colors.
|
* The bitmap has a maximum of 2^24 colors.
|
||||||
* <br/>
|
* <br/>
|
||||||
* If the Compression field of the BitmapInfoHeader Object is set to BI_RGB, the Colors field
|
* If the Compression field of the BitmapInfoHeader Object is set to BI_RGB, the Colors field
|
||||||
* of DIB is set to NULL. Each DWORD in the bitmap array represents the relative intensities of
|
* of DIB is set to NULL. Each DWORD in the bitmap array represents the relative intensities of
|
||||||
* blue, green, and red, respectively, for a pixel. The high byte in each DWORD is not used. The
|
* blue, green, and red, respectively, for a pixel. The high byte in each DWORD is not used. The
|
||||||
* Colors color table is used for optimizing colors used on palette-based devices, and MUST
|
* Colors color table is used for optimizing colors used on palette-based devices, and MUST
|
||||||
* contain the number of entries specified by the ColorUsed field of the BitmapInfoHeader
|
* contain the number of entries specified by the ColorUsed field of the BitmapInfoHeader
|
||||||
* Object.
|
* Object.
|
||||||
* <br/>
|
* <br/>
|
||||||
* If the Compression field of the BitmapInfoHeader Object is set to BI_BITFIELDS, the Colors
|
* If the Compression field of the BitmapInfoHeader Object is set to BI_BITFIELDS, the Colors
|
||||||
* field contains three DWORD color masks that specify the red, green, and blue components,
|
* field contains three DWORD color masks that specify the red, green, and blue components,
|
||||||
* respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.
|
* respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.
|
||||||
* <br/>
|
* <br/>
|
||||||
* When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask must be
|
* When the Compression field is set to BI_BITFIELDS, bits set in each DWORD mask must be
|
||||||
* contiguous and should not overlap the bits of another mask. All the bits in the pixel do not
|
* contiguous and should not overlap the bits of another mask. All the bits in the pixel do not
|
||||||
* need to be used.
|
* need to be used.
|
||||||
*/
|
*/
|
||||||
BI_BITCOUNT_6(0x0020);
|
BI_BITCOUNT_6(0x0020);
|
||||||
|
|
||||||
int flag;
|
int flag;
|
||||||
BitCount(int flag) {
|
BitCount(int flag) {
|
||||||
this.flag = flag;
|
this.flag = flag;
|
||||||
@ -139,18 +143,18 @@ public class HwmfBitmapDib {
|
|||||||
*/
|
*/
|
||||||
BI_BITFIELDS(0x0003),
|
BI_BITFIELDS(0x0003),
|
||||||
/**
|
/**
|
||||||
* The image is a JPEG image, as specified in [JFIF]. This value SHOULD only be used in
|
* The image is a JPEG image, as specified in [JFIF]. This value SHOULD only be used in
|
||||||
* certain bitmap operations, such as JPEG pass-through. The application MUST query for the
|
* certain bitmap operations, such as JPEG pass-through. The application MUST query for the
|
||||||
* pass-through support, since not all devices support JPEG pass-through. Using non-RGB
|
* pass-through support, since not all devices support JPEG pass-through. Using non-RGB
|
||||||
* bitmaps MAY limit the portability of the metafile to other devices. For instance, display device
|
* bitmaps MAY limit the portability of the metafile to other devices. For instance, display device
|
||||||
* contexts generally do not support this pass-through.
|
* contexts generally do not support this pass-through.
|
||||||
*/
|
*/
|
||||||
BI_JPEG(0x0004),
|
BI_JPEG(0x0004),
|
||||||
/**
|
/**
|
||||||
* The image is a PNG image, as specified in [RFC2083]. This value SHOULD only be
|
* The image is a PNG image, as specified in [RFC2083]. This value SHOULD only be
|
||||||
* used certain bitmap operations, such as JPEG/PNG pass-through. The application MUST query
|
* used certain bitmap operations, such as JPEG/PNG pass-through. The application MUST query
|
||||||
* for the pass-through support, because not all devices support JPEG/PNG pass-through. Using
|
* for the pass-through support, because not all devices support JPEG/PNG pass-through. Using
|
||||||
* non-RGB bitmaps MAY limit the portability of the metafile to other devices. For instance,
|
* non-RGB bitmaps MAY limit the portability of the metafile to other devices. For instance,
|
||||||
* display device contexts generally do not support this pass-through.
|
* display device contexts generally do not support this pass-through.
|
||||||
*/
|
*/
|
||||||
BI_PNG(0x0005),
|
BI_PNG(0x0005),
|
||||||
@ -170,7 +174,7 @@ public class HwmfBitmapDib {
|
|||||||
* color indexes.
|
* color indexes.
|
||||||
*/
|
*/
|
||||||
BI_CMYKRLE4(0x000D);
|
BI_CMYKRLE4(0x000D);
|
||||||
|
|
||||||
int flag;
|
int flag;
|
||||||
Compression(int flag) {
|
Compression(int flag) {
|
||||||
this.flag = flag;
|
this.flag = flag;
|
||||||
@ -180,93 +184,113 @@ public class HwmfBitmapDib {
|
|||||||
if (c.flag == flag) return c;
|
if (c.flag == flag) return c;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int headerSize;
|
|
||||||
int headerWidth;
|
|
||||||
int headerHeight;
|
|
||||||
int headerPlanes;
|
|
||||||
BitCount headerBitCount;
|
|
||||||
Compression headerCompression;
|
|
||||||
long headerImageSize = -1;
|
|
||||||
int headerXPelsPerMeter = -1;
|
|
||||||
int headerYPelsPerMeter = -1;
|
|
||||||
long headerColorUsed = -1;
|
|
||||||
long headerColorImportant = -1;
|
|
||||||
|
|
||||||
Color colorTable[];
|
|
||||||
int colorMaskRed=0,colorMaskGreen=0,colorMaskBlue=0;
|
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis) throws IOException {
|
|
||||||
int size = 0;
|
|
||||||
size += readHeader(leis);
|
|
||||||
size += readColors(leis);
|
|
||||||
int size2;
|
|
||||||
switch (headerBitCount) {
|
|
||||||
default:
|
|
||||||
case BI_BITCOUNT_0:
|
|
||||||
throw new RuntimeException("JPG and PNG formats aren't supported yet.");
|
|
||||||
case BI_BITCOUNT_1:
|
|
||||||
case BI_BITCOUNT_2:
|
|
||||||
case BI_BITCOUNT_3:
|
|
||||||
size2 = readBitmapIndexed(leis);
|
|
||||||
break;
|
|
||||||
case BI_BITCOUNT_4:
|
|
||||||
case BI_BITCOUNT_5:
|
|
||||||
case BI_BITCOUNT_6:
|
|
||||||
size2 = readBitmapDirect(leis);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int BMP_HEADER_SIZE = 14;
|
||||||
|
|
||||||
|
private int headerSize;
|
||||||
|
private int headerWidth;
|
||||||
|
private int headerHeight;
|
||||||
|
private int headerPlanes;
|
||||||
|
private BitCount headerBitCount;
|
||||||
|
private Compression headerCompression;
|
||||||
|
private long headerImageSize = -1;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private int headerXPelsPerMeter = -1;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private int headerYPelsPerMeter = -1;
|
||||||
|
private long headerColorUsed = -1;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private long headerColorImportant = -1;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private Color colorTable[];
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private int colorMaskRed=0,colorMaskGreen=0,colorMaskBlue=0;
|
||||||
|
|
||||||
|
// size of header and color table, for start of image data calculation
|
||||||
|
private int introSize;
|
||||||
|
private byte imageData[];
|
||||||
|
|
||||||
|
public int init(LittleEndianInputStream leis, int recordSize) throws IOException {
|
||||||
|
leis.mark(10000);
|
||||||
|
|
||||||
assert( headerSize != 0x0C || ((((headerWidth * headerPlanes * headerBitCount.flag + 31) & ~31) / 8) * Math.abs(headerHeight)) == size2);
|
// need to read the header to calculate start of bitmap data correct
|
||||||
assert ( headerSize == 0x0C || headerImageSize == size2 );
|
introSize = readHeader(leis);
|
||||||
|
assert(introSize == headerSize);
|
||||||
|
introSize += readColors(leis);
|
||||||
|
assert(introSize < 10000);
|
||||||
|
|
||||||
|
int fileSize = (headerImageSize != 0) ? (int)(introSize+headerImageSize) : recordSize;
|
||||||
|
|
||||||
size += size2;
|
imageData = new byte[fileSize];
|
||||||
|
leis.reset();
|
||||||
|
leis.read(imageData, 0, fileSize);
|
||||||
|
|
||||||
return size;
|
assert( headerSize != 0x0C || ((((headerWidth * headerPlanes * headerBitCount.flag + 31) & ~31) / 8) * Math.abs(headerHeight)) == headerImageSize);
|
||||||
|
|
||||||
|
return fileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int readHeader(LittleEndianInputStream leis) throws IOException {
|
protected int readHeader(LittleEndianInputStream leis) throws IOException {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DIBHeaderInfo (variable): Either a BitmapCoreHeader Object or a
|
* DIBHeaderInfo (variable): Either a BitmapCoreHeader Object or a
|
||||||
* BitmapInfoHeader Object that specifies information about the image.
|
* BitmapInfoHeader Object that specifies information about the image.
|
||||||
*
|
*
|
||||||
* The first 32 bits of this field is the HeaderSize value.
|
* The first 32 bits of this field is the HeaderSize value.
|
||||||
* If it is 0x0000000C, then this is a BitmapCoreHeader; otherwise, this is a BitmapInfoHeader.
|
* If it is 0x0000000C, then this is a BitmapCoreHeader; otherwise, this is a BitmapInfoHeader.
|
||||||
*/
|
*/
|
||||||
headerSize = leis.readInt();
|
headerSize = leis.readInt();
|
||||||
size += LittleEndianConsts.INT_SIZE;
|
size += LittleEndianConsts.INT_SIZE;
|
||||||
|
|
||||||
// BitmapCoreHeader
|
|
||||||
// A 16-bit unsigned integer that defines the width of the DIB, in pixels.
|
|
||||||
headerWidth = leis.readUShort();
|
|
||||||
// A 16-bit unsigned integer that defines the height of the DIB, in pixels.
|
|
||||||
headerHeight = leis.readUShort();
|
|
||||||
// A 16-bit unsigned integer that defines the number of planes for the target
|
|
||||||
// device. This value MUST be 0x0001.
|
|
||||||
headerPlanes = leis.readUShort();
|
|
||||||
// A 16-bit unsigned integer that defines the format of each pixel, and the
|
|
||||||
// maximum number of colors in the DIB.
|
|
||||||
headerBitCount = BitCount.valueOf(leis.readUShort());
|
|
||||||
size += 4*LittleEndianConsts.SHORT_SIZE;
|
|
||||||
|
|
||||||
if (headerSize > 0x0C) {
|
if (headerSize == 0x0C) {
|
||||||
|
// BitmapCoreHeader
|
||||||
|
// A 16-bit unsigned integer that defines the width of the DIB, in pixels.
|
||||||
|
headerWidth = leis.readUShort();
|
||||||
|
// A 16-bit unsigned integer that defines the height of the DIB, in pixels.
|
||||||
|
headerHeight = leis.readUShort();
|
||||||
|
// A 16-bit unsigned integer that defines the number of planes for the target
|
||||||
|
// device. This value MUST be 0x0001.
|
||||||
|
headerPlanes = leis.readUShort();
|
||||||
|
// A 16-bit unsigned integer that defines the format of each pixel, and the
|
||||||
|
// maximum number of colors in the DIB.
|
||||||
|
headerBitCount = BitCount.valueOf(leis.readUShort());
|
||||||
|
size += 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
|
} else {
|
||||||
// BitmapInfoHeader
|
// BitmapInfoHeader
|
||||||
// A 32-bit unsigned integer that defines the compression mode of the
|
// A 32-bit signed integer that defines the width of the DIB, in pixels.
|
||||||
// DIB.
|
// This value MUST be positive.
|
||||||
|
// This field SHOULD specify the width of the decompressed image file,
|
||||||
|
// if the Compression value specifies JPEG or PNG format.
|
||||||
|
headerWidth = leis.readInt();
|
||||||
|
// A 32-bit signed integer that defines the height of the DIB, in pixels.
|
||||||
|
// This value MUST NOT be zero.
|
||||||
|
// - If this value is positive, the DIB is a bottom-up bitmap,
|
||||||
|
// and its origin is the lower-left corner.
|
||||||
|
// This field SHOULD specify the height of the decompressed image file,
|
||||||
|
// if the Compression value specifies JPEG or PNG format.
|
||||||
|
// - If this value is negative, the DIB is a top-down bitmap,
|
||||||
|
// and its origin is the upper-left corner. Top-down bitmaps do not support compression.
|
||||||
|
headerHeight = leis.readInt();
|
||||||
|
// A 16-bit unsigned integer that defines the number of planes for the target
|
||||||
|
// device. This value MUST be 0x0001.
|
||||||
|
headerPlanes = leis.readUShort();
|
||||||
|
// A 16-bit unsigned integer that defines the format of each pixel, and the
|
||||||
|
// maximum number of colors in the DIB.
|
||||||
|
headerBitCount = BitCount.valueOf(leis.readUShort());
|
||||||
|
// A 32-bit unsigned integer that defines the compression mode of the DIB.
|
||||||
// This value MUST NOT specify a compressed format if the DIB is a top-down bitmap,
|
// This value MUST NOT specify a compressed format if the DIB is a top-down bitmap,
|
||||||
// as indicated by the Height value.
|
// as indicated by the Height value.
|
||||||
headerCompression = Compression.valueOf((int)leis.readUInt());
|
headerCompression = Compression.valueOf((int)leis.readUInt());
|
||||||
// A 32-bit unsigned integer that defines the size, in bytes, of the image.
|
// A 32-bit unsigned integer that defines the size, in bytes, of the image.
|
||||||
// If the Compression value is BI_RGB, this value SHOULD be zero and MUST be ignored.
|
// If the Compression value is BI_RGB, this value SHOULD be zero and MUST be ignored.
|
||||||
// If the Compression value is BI_JPEG or BI_PNG, this value MUST specify the size of the JPEG
|
// If the Compression value is BI_JPEG or BI_PNG, this value MUST specify the size of the JPEG
|
||||||
// or PNG image buffer, respectively.
|
// or PNG image buffer, respectively.
|
||||||
headerImageSize = leis.readUInt();
|
headerImageSize = leis.readUInt();
|
||||||
// A 32-bit signed integer that defines the horizontal resolution,
|
// A 32-bit signed integer that defines the horizontal resolution,
|
||||||
// in pixels-per-meter, of the target device for the DIB.
|
// in pixels-per-meter, of the target device for the DIB.
|
||||||
headerXPelsPerMeter = leis.readInt();
|
headerXPelsPerMeter = leis.readInt();
|
||||||
// A 32-bit signed integer that defines the vertical resolution,
|
// A 32-bit signed integer that defines the vertical resolution,
|
||||||
@ -278,8 +302,9 @@ public class HwmfBitmapDib {
|
|||||||
// A 32-bit unsigned integer that defines the number of color indexes that are
|
// A 32-bit unsigned integer that defines the number of color indexes that are
|
||||||
// required for displaying the DIB. If this value is zero, all color indexes are required.
|
// required for displaying the DIB. If this value is zero, all color indexes are required.
|
||||||
headerColorImportant = leis.readUInt();
|
headerColorImportant = leis.readUInt();
|
||||||
size += 6*LittleEndianConsts.INT_SIZE;
|
size += 8*LittleEndianConsts.INT_SIZE+2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
assert(size == headerSize);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +322,7 @@ public class HwmfBitmapDib {
|
|||||||
return readRGBQuad(leis, 16);
|
return readRGBQuad(leis, 16);
|
||||||
case BI_BITCOUNT_3:
|
case BI_BITCOUNT_3:
|
||||||
// 256 colors
|
// 256 colors
|
||||||
return readRGBQuad(leis, 256);
|
return readRGBQuad(leis, (int)headerColorUsed);
|
||||||
case BI_BITCOUNT_5:
|
case BI_BITCOUNT_5:
|
||||||
colorMaskRed=0xFF;
|
colorMaskRed=0xFF;
|
||||||
colorMaskGreen=0xFF;
|
colorMaskGreen=0xFF;
|
||||||
@ -316,7 +341,7 @@ public class HwmfBitmapDib {
|
|||||||
colorMaskRed = leis.readInt();
|
colorMaskRed = leis.readInt();
|
||||||
return 3*LittleEndianConsts.INT_SIZE;
|
return 3*LittleEndianConsts.INT_SIZE;
|
||||||
}
|
}
|
||||||
case BI_BITCOUNT_6:
|
case BI_BITCOUNT_6:
|
||||||
if (headerCompression == Compression.BI_RGB) {
|
if (headerCompression == Compression.BI_RGB) {
|
||||||
colorMaskBlue = colorMaskGreen = colorMaskRed = 0xFF;
|
colorMaskBlue = colorMaskGreen = colorMaskRed = 0xFF;
|
||||||
return 0;
|
return 0;
|
||||||
@ -329,7 +354,7 @@ public class HwmfBitmapDib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int readRGBQuad(LittleEndianInputStream leis, int count) throws IOException {
|
protected int readRGBQuad(LittleEndianInputStream leis, int count) throws IOException {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
List<Color> colorList = new ArrayList<Color>();
|
List<Color> colorList = new ArrayList<Color>();
|
||||||
@ -346,96 +371,32 @@ public class HwmfBitmapDib {
|
|||||||
colorTable = colorList.toArray(new Color[colorList.size()]);
|
colorTable = colorList.toArray(new Color[colorList.size()]);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int readBitmapIndexed(LittleEndianInputStream leis) throws IOException {
|
public BufferedImage getImage() {
|
||||||
assert(colorTable != null);
|
if (imageData == null) {
|
||||||
byte r[] = new byte[colorTable.length];
|
throw new RecordFormatException("bitmap not initialized ... need to call init() before");
|
||||||
byte g[] = new byte[colorTable.length];
|
|
||||||
byte b[] = new byte[colorTable.length];
|
|
||||||
for (int i=0; i<colorTable.length; i++) {
|
|
||||||
r[i] = (byte)colorTable[i].getRed();
|
|
||||||
g[i] = (byte)colorTable[i].getGreen();
|
|
||||||
b[i] = (byte)colorTable[i].getBlue();
|
|
||||||
}
|
}
|
||||||
int bits = 32-Integer.numberOfLeadingZeros(colorTable.length);
|
|
||||||
IndexColorModel cm = new IndexColorModel(bits,colorTable.length,r,g,b);
|
// create the image data and leave the parsing to the ImageIO api
|
||||||
|
byte buf[] = new byte[BMP_HEADER_SIZE+imageData.length];
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/BMP_file_format # Bitmap file header
|
||||||
|
buf[0] = (byte)'B';
|
||||||
|
buf[1] = (byte)'M';
|
||||||
|
// the full size of the bmp
|
||||||
|
LittleEndian.putInt(buf, 2, (int)(BMP_HEADER_SIZE + introSize + headerImageSize));
|
||||||
|
// the next 4 bytes are unused
|
||||||
|
LittleEndian.putInt(buf, 6, 0);
|
||||||
|
// start of image = BMP header length + dib header length + color tables length
|
||||||
|
LittleEndian.putInt(buf, 10, BMP_HEADER_SIZE + introSize);
|
||||||
|
|
||||||
BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_BYTE_INDEXED, cm);
|
System.arraycopy(imageData, 0, buf, BMP_HEADER_SIZE, imageData.length);
|
||||||
WritableRaster wr = bi.getRaster();
|
|
||||||
|
|
||||||
int pixelCount = headerWidth*headerHeight;
|
try {
|
||||||
int size = 0;
|
return ImageIO.read(new ByteArrayInputStream(buf));
|
||||||
for (int pixel=0; pixel<pixelCount; size++) {
|
} catch (IOException e) {
|
||||||
int v = leis.readUByte();
|
// ... shouldn't happen
|
||||||
switch (headerBitCount) {
|
throw new RecordFormatException("invalid bitmap data", e);
|
||||||
default:
|
|
||||||
throw new RuntimeException("invalid bitcount for indexed image");
|
|
||||||
case BI_BITCOUNT_1:
|
|
||||||
for (int j=0; j<8 && pixel<pixelCount; j++,pixel++) {
|
|
||||||
wr.setSample(pixel/headerWidth,pixel%headerWidth,0,(v>>(7-j))&1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BI_BITCOUNT_2:
|
|
||||||
wr.setSample(pixel/headerWidth, pixel%headerWidth, 0, (v>>4)&15);
|
|
||||||
pixel++;
|
|
||||||
if (pixel<pixelCount) {
|
|
||||||
wr.setSample(pixel/headerWidth, pixel%headerWidth, 0, v&15);
|
|
||||||
pixel++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BI_BITCOUNT_3:
|
|
||||||
wr.setSample(pixel/headerWidth, pixel%headerWidth, 0, v);
|
|
||||||
pixel++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int readBitmapDirect(LittleEndianInputStream leis) throws IOException {
|
|
||||||
assert(colorTable == null);
|
|
||||||
|
|
||||||
BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_INT_RGB);
|
|
||||||
WritableRaster wr = bi.getRaster();
|
|
||||||
|
|
||||||
int bitShiftRed=0,bitShiftGreen=0,bitShiftBlue=0;
|
|
||||||
if (headerCompression == Compression.BI_BITFIELDS) {
|
|
||||||
bitShiftGreen = 32-Integer.numberOfLeadingZeros(this.colorMaskBlue);
|
|
||||||
bitShiftRed = 32-Integer.numberOfLeadingZeros(this.colorMaskGreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
int pixelCount = headerWidth*headerHeight;
|
|
||||||
int size = 0;
|
|
||||||
int rgb[] = new int[3];
|
|
||||||
for (int pixel=0; pixel<pixelCount; pixel++) {
|
|
||||||
int v;
|
|
||||||
switch (headerBitCount) {
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("invalid bitcount for indexed image");
|
|
||||||
case BI_BITCOUNT_4:
|
|
||||||
v = leis.readUShort();
|
|
||||||
rgb[0] = (v & colorMaskRed) >> bitShiftRed;
|
|
||||||
rgb[1] = (v & colorMaskGreen) >> bitShiftGreen;
|
|
||||||
rgb[2] = (v & colorMaskBlue) >> bitShiftBlue;
|
|
||||||
size += LittleEndianConsts.SHORT_SIZE;
|
|
||||||
break;
|
|
||||||
case BI_BITCOUNT_5:
|
|
||||||
rgb[2] = leis.readUByte();
|
|
||||||
rgb[1] = leis.readUByte();
|
|
||||||
rgb[0] = leis.readUByte();
|
|
||||||
size += 3*LittleEndianConsts.BYTE_SIZE;
|
|
||||||
break;
|
|
||||||
case BI_BITCOUNT_6:
|
|
||||||
v = leis.readInt();
|
|
||||||
rgb[0] = (v & colorMaskRed) >> bitShiftRed;
|
|
||||||
rgb[1] = (v & colorMaskGreen) >> bitShiftGreen;
|
|
||||||
rgb[2] = (v & colorMaskBlue) >> bitShiftBlue;
|
|
||||||
size += LittleEndianConsts.INT_SIZE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wr.setPixel(pixel/headerWidth,pixel%headerWidth,rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,21 @@ import java.io.IOException;
|
|||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 32-bit ColorRef Object that defines the color value.
|
||||||
|
* Red (1 byte): An 8-bit unsigned integer that defines the relative intensity of red.
|
||||||
|
* Green (1 byte): An 8-bit unsigned integer that defines the relative intensity of green.
|
||||||
|
* Blue (1 byte): An 8-bit unsigned integer that defines the relative intensity of blue.
|
||||||
|
* Reserved (1 byte): An 8-bit unsigned integer that MUST be 0x00.
|
||||||
|
*/
|
||||||
public class HwmfColorRef {
|
public class HwmfColorRef {
|
||||||
/**
|
private Color colorRef = Color.BLACK;
|
||||||
* A 32-bit ColorRef Object that defines the color value.
|
|
||||||
* Red (1 byte): An 8-bit unsigned integer that defines the relative intensity of red.
|
public HwmfColorRef() {}
|
||||||
* Green (1 byte): An 8-bit unsigned integer that defines the relative intensity of green.
|
|
||||||
* Blue (1 byte): An 8-bit unsigned integer that defines the relative intensity of blue.
|
public HwmfColorRef(Color colorRef) {
|
||||||
* Reserved (1 byte): An 8-bit unsigned integer that MUST be 0x00.
|
this.colorRef = colorRef;
|
||||||
*/
|
}
|
||||||
Color colorRef;
|
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis) throws IOException {
|
public int init(LittleEndianInputStream leis) throws IOException {
|
||||||
int red = leis.readUByte();
|
int red = leis.readUByte();
|
||||||
@ -44,4 +50,7 @@ public class HwmfColorRef {
|
|||||||
return 4*LittleEndianConsts.BYTE_SIZE;
|
return 4*LittleEndianConsts.BYTE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return colorRef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,13 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwmf.record;
|
package org.apache.poi.hwmf.record;
|
||||||
|
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import java.awt.geom.GeneralPath;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
@ -28,102 +33,140 @@ public class HwmfDraw {
|
|||||||
* point.
|
* point.
|
||||||
*/
|
*/
|
||||||
public static class WmfMoveTo implements HwmfRecord {
|
public static class WmfMoveTo implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units.
|
* A 16-bit signed integer that defines the y-coordinate, in logical units.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units.
|
* A 16-bit signed integer that defines the x-coordinate, in logical units.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.moveTo;
|
return HwmfRecordType.moveTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
y = leis.readShort();
|
||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setLocation(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_LINETO record draws a line from the drawing position that is defined in the playback
|
* The META_LINETO record draws a line from the drawing position that is defined in the playback
|
||||||
* device context up to, but not including, the specified point.
|
* device context up to, but not including, the specified point.
|
||||||
*/
|
*/
|
||||||
public static class WmfLineTo implements HwmfRecord {
|
public static class WmfLineTo implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the vertical component of the drawing
|
* A 16-bit signed integer that defines the vertical component of the drawing
|
||||||
* destination position, in logical units.
|
* destination position, in logical units.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal component of the drawing
|
* A 16-bit signed integer that defines the horizontal component of the drawing
|
||||||
* destination position, in logical units.
|
* destination position, in logical units.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.lineTo;
|
return HwmfRecordType.lineTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
y = leis.readShort();
|
||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
Point2D start = ctx.getProperties().getLocation();
|
||||||
|
Line2D line = new Line2D.Double(start.getX(), start.getY(), x, y);
|
||||||
|
ctx.draw(line);
|
||||||
|
ctx.getProperties().setLocation(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_POLYGON record paints a polygon consisting of two or more vertices connected by
|
* The META_POLYGON record paints a polygon consisting of two or more vertices connected by
|
||||||
* straight lines. The polygon is outlined by using the pen and filled by using the brush and polygon fill
|
* straight lines. The polygon is outlined by using the pen and filled by using the brush and polygon fill
|
||||||
* mode that are defined in the playback device context.
|
* mode that are defined in the playback device context.
|
||||||
*/
|
*/
|
||||||
public static class WmfPolygon implements HwmfRecord {
|
public static class WmfPolygon implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the number of points in the array.
|
* A 16-bit signed integer that defines the number of points in the array.
|
||||||
*/
|
*/
|
||||||
int numberofPoints;
|
private int numberofPoints;
|
||||||
|
|
||||||
short xPoints[], yPoints[];
|
short xPoints[], yPoints[];
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.polygon;
|
return HwmfRecordType.polygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
numberofPoints = leis.readShort();
|
numberofPoints = leis.readShort();
|
||||||
xPoints = new short[numberofPoints];
|
xPoints = new short[numberofPoints];
|
||||||
yPoints = new short[numberofPoints];
|
yPoints = new short[numberofPoints];
|
||||||
|
|
||||||
for (int i=0; i<numberofPoints; i++) {
|
for (int i=0; i<numberofPoints; i++) {
|
||||||
// A 16-bit signed integer that defines the horizontal (x) coordinate of the point.
|
// A 16-bit signed integer that defines the horizontal (x) coordinate of the point.
|
||||||
xPoints[i] = leis.readShort();
|
xPoints[i] = leis.readShort();
|
||||||
// A 16-bit signed integer that defines the vertical (y) coordinate of the point.
|
// A 16-bit signed integer that defines the vertical (y) coordinate of the point.
|
||||||
yPoints[i] = leis.readShort();
|
yPoints[i] = leis.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return LittleEndianConsts.SHORT_SIZE+numberofPoints*LittleEndianConsts.INT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE+numberofPoints*LittleEndianConsts.INT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.fill(getShape());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Polygon getShape() {
|
||||||
|
Polygon polygon = new Polygon();
|
||||||
|
for(int i = 0; i < numberofPoints; i++) {
|
||||||
|
polygon.addPoint(xPoints[i], yPoints[i]);
|
||||||
|
}
|
||||||
|
return polygon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_POLYLINE record draws a series of line segments by connecting the points in the
|
* The META_POLYLINE record draws a series of line segments by connecting the points in the
|
||||||
* specified array.
|
* specified array.
|
||||||
*/
|
*/
|
||||||
public static class WmfPolyline extends WmfPolygon {
|
public static class WmfPolyline extends WmfPolygon {
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.polyline;
|
return HwmfRecordType.polyline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.draw(getShape());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_ELLIPSE record draws an ellipse. The center of the ellipse is the center of the specified
|
* The META_ELLIPSE record draws an ellipse. The center of the ellipse is the center of the specified
|
||||||
* bounding rectangle. The ellipse is outlined by using the pen and is filled by using the brush; these
|
* bounding rectangle. The ellipse is outlined by using the pen and is filled by using the brush; these
|
||||||
@ -134,27 +177,29 @@ public class HwmfDraw {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int bottomRect;
|
private int bottomRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int rightRect;
|
private int rightRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the bounding rectangle.
|
* upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int topRect;
|
private int topRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the upper-left corner of the bounding rectangle.
|
* the upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int leftRect;
|
private int leftRect;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.ellipse;
|
return HwmfRecordType.ellipse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
bottomRect = leis.readShort();
|
bottomRect = leis.readShort();
|
||||||
rightRect = leis.readShort();
|
rightRect = leis.readShort();
|
||||||
@ -162,6 +207,11 @@ public class HwmfDraw {
|
|||||||
leftRect = leis.readShort();
|
leftRect = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -173,27 +223,29 @@ public class HwmfDraw {
|
|||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
||||||
* the region to be framed.
|
* the region to be framed.
|
||||||
*/
|
*/
|
||||||
int region;
|
private int region;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get the
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get the
|
||||||
* Brush to use for filling the region.
|
* Brush to use for filling the region.
|
||||||
*/
|
*/
|
||||||
int brush;
|
private int brush;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the
|
* A 16-bit signed integer that defines the height, in logical units, of the
|
||||||
* region frame.
|
* region frame.
|
||||||
*/
|
*/
|
||||||
int height;
|
private int height;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the
|
* A 16-bit signed integer that defines the width, in logical units, of the
|
||||||
* region frame.
|
* region frame.
|
||||||
*/
|
*/
|
||||||
int width;
|
private int width;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.frameRegion;
|
return HwmfRecordType.frameRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
region = leis.readUShort();
|
region = leis.readUShort();
|
||||||
brush = leis.readUShort();
|
brush = leis.readUShort();
|
||||||
@ -201,6 +253,11 @@ public class HwmfDraw {
|
|||||||
width = leis.readShort();
|
width = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -209,33 +266,35 @@ public class HwmfDraw {
|
|||||||
* device context. The polygons drawn by this function can overlap.
|
* device context. The polygons drawn by this function can overlap.
|
||||||
*/
|
*/
|
||||||
public static class WmfPolyPolygon implements HwmfRecord {
|
public static class WmfPolyPolygon implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the number of polygons in the object.
|
* A 16-bit unsigned integer that defines the number of polygons in the object.
|
||||||
*/
|
*/
|
||||||
int numberOfPolygons;
|
private int numberOfPolygons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A NumberOfPolygons array of 16-bit unsigned integers that define the number of
|
* A NumberOfPolygons array of 16-bit unsigned integers that define the number of
|
||||||
* points for each polygon in the object.
|
* points for each polygon in the object.
|
||||||
*/
|
*/
|
||||||
int pointsPerPolygon[];
|
private int pointsPerPolygon[];
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of 16-bit unsigned integers that define the coordinates of the polygons.
|
|
||||||
*/
|
|
||||||
int xPoints[][];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of 16-bit unsigned integers that define the coordinates of the polygons.
|
* An array of 16-bit unsigned integers that define the coordinates of the polygons.
|
||||||
*/
|
*/
|
||||||
int yPoints[][];
|
private int xPoints[][];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An array of 16-bit unsigned integers that define the coordinates of the polygons.
|
||||||
|
*/
|
||||||
|
private int yPoints[][];
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.polyPolygon;
|
return HwmfRecordType.polyPolygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
// see http://secunia.com/gfx/pdf/SA31675_BA.pdf ;)
|
// see http://secunia.com/gfx/pdf/SA31675_BA.pdf ;)
|
||||||
numberOfPolygons = leis.readUShort();
|
numberOfPolygons = leis.readUShort();
|
||||||
@ -244,26 +303,31 @@ public class HwmfDraw {
|
|||||||
yPoints = new int[numberOfPolygons][];
|
yPoints = new int[numberOfPolygons][];
|
||||||
|
|
||||||
int size = LittleEndianConsts.SHORT_SIZE;
|
int size = LittleEndianConsts.SHORT_SIZE;
|
||||||
|
|
||||||
for (int i=0; i<numberOfPolygons; i++) {
|
for (int i=0; i<numberOfPolygons; i++) {
|
||||||
pointsPerPolygon[i] = leis.readUShort();
|
pointsPerPolygon[i] = leis.readUShort();
|
||||||
size += LittleEndianConsts.SHORT_SIZE;
|
size += LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<numberOfPolygons; i++) {
|
for (int i=0; i<numberOfPolygons; i++) {
|
||||||
|
|
||||||
xPoints[i] = new int[pointsPerPolygon[i]];
|
xPoints[i] = new int[pointsPerPolygon[i]];
|
||||||
yPoints[i] = new int[pointsPerPolygon[i]];
|
yPoints[i] = new int[pointsPerPolygon[i]];
|
||||||
|
|
||||||
for (int j=0; j<pointsPerPolygon[i]; j++) {
|
for (int j=0; j<pointsPerPolygon[i]; j++) {
|
||||||
xPoints[i][j] = leis.readUShort();
|
xPoints[i][j] = leis.readUShort();
|
||||||
yPoints[i][j] = leis.readUShort();
|
yPoints[i][j] = leis.readUShort();
|
||||||
size += 2*LittleEndianConsts.SHORT_SIZE;
|
size += 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -275,27 +339,29 @@ public class HwmfDraw {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the lower-right corner of the rectangle.
|
* the lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int bottomRect;
|
private int bottomRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the lower-right corner of the rectangle.
|
* the lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int rightRect;
|
private int rightRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int topRect;
|
private int topRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the upper-left corner of the rectangle.
|
* the upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int leftRect;
|
private int leftRect;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.frameRegion;
|
return HwmfRecordType.frameRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
bottomRect = leis.readShort();
|
bottomRect = leis.readShort();
|
||||||
rightRect = leis.readShort();
|
rightRect = leis.readShort();
|
||||||
@ -303,6 +369,11 @@ public class HwmfDraw {
|
|||||||
leftRect = leis.readShort();
|
leftRect = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,25 +384,27 @@ public class HwmfDraw {
|
|||||||
/**
|
/**
|
||||||
* A ColorRef Object that defines the color value.
|
* A ColorRef Object that defines the color value.
|
||||||
*/
|
*/
|
||||||
HwmfColorRef colorRef;
|
HwmfColorRef colorRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
|
||||||
* to be set.
|
* to be set.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
|
||||||
* to be set.
|
* to be set.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setPixel;
|
return HwmfRecordType.setPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
int size = colorRef.init(leis);
|
int size = colorRef.init(leis);
|
||||||
@ -339,6 +412,11 @@ public class HwmfDraw {
|
|||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE+size;
|
return 2*LittleEndianConsts.SHORT_SIZE+size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -350,43 +428,45 @@ public class HwmfDraw {
|
|||||||
* A 16-bit signed integer that defines the height, in logical coordinates, of the
|
* A 16-bit signed integer that defines the height, in logical coordinates, of the
|
||||||
* ellipse used to draw the rounded corners.
|
* ellipse used to draw the rounded corners.
|
||||||
*/
|
*/
|
||||||
int height;
|
private int height;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical coordinates, of the
|
* A 16-bit signed integer that defines the width, in logical coordinates, of the
|
||||||
* ellipse used to draw the rounded corners.
|
* ellipse used to draw the rounded corners.
|
||||||
*/
|
*/
|
||||||
int width;
|
private int width;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the lower-right corner of the rectangle.
|
* the lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int bottomRect;
|
private int bottomRect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the lower-right corner of the rectangle.
|
* the lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int rightRect;
|
private int rightRect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int topRect;
|
private int topRect;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the upper-left corner of the rectangle.
|
* the upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int leftRect;
|
private int leftRect;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.roundRect;
|
return HwmfRecordType.roundRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
height = leis.readShort();
|
height = leis.readShort();
|
||||||
width = leis.readShort();
|
width = leis.readShort();
|
||||||
@ -396,8 +476,13 @@ public class HwmfDraw {
|
|||||||
leftRect = leis.readShort();
|
leftRect = leis.readShort();
|
||||||
return 6*LittleEndianConsts.SHORT_SIZE;
|
return 6*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -410,47 +495,49 @@ public class HwmfDraw {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical
|
* A 16-bit signed integer that defines the y-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the second radial.
|
* coordinates, of the endpoint of the second radial.
|
||||||
*/
|
*/
|
||||||
int yRadial2;
|
private int yRadial2;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical
|
* A 16-bit signed integer that defines the x-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the second radial.
|
* coordinates, of the endpoint of the second radial.
|
||||||
*/
|
*/
|
||||||
int xRadial2;
|
private int xRadial2;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical
|
* A 16-bit signed integer that defines the y-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the first radial.
|
* coordinates, of the endpoint of the first radial.
|
||||||
*/
|
*/
|
||||||
int yRadial1;
|
private int yRadial1;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical
|
* A 16-bit signed integer that defines the x-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the first radial.
|
* coordinates, of the endpoint of the first radial.
|
||||||
*/
|
*/
|
||||||
int xRadial1;
|
private int xRadial1;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int bottomRect;
|
private int bottomRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int rightRect;
|
private int rightRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the bounding rectangle.
|
* upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int topRect;
|
private int topRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the upper-left corner of the bounding rectangle.
|
* the upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int leftRect;
|
private int leftRect;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.pie;
|
return HwmfRecordType.pie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yRadial2 = leis.readShort();
|
yRadial2 = leis.readShort();
|
||||||
xRadial2 = leis.readShort();
|
xRadial2 = leis.readShort();
|
||||||
@ -462,6 +549,12 @@ public class HwmfDraw {
|
|||||||
leftRect = leis.readShort();
|
leftRect = leis.readShort();
|
||||||
return 8*LittleEndianConsts.SHORT_SIZE;
|
return 8*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -472,47 +565,49 @@ public class HwmfDraw {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the ending point of the radial line defining the ending point of the arc.
|
* the ending point of the radial line defining the ending point of the arc.
|
||||||
*/
|
*/
|
||||||
int yEndArc;
|
private int yEndArc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the ending point of the radial line defining the ending point of the arc.
|
* the ending point of the radial line defining the ending point of the arc.
|
||||||
*/
|
*/
|
||||||
int xEndArc;
|
private int xEndArc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the ending point of the radial line defining the starting point of the arc.
|
* the ending point of the radial line defining the starting point of the arc.
|
||||||
*/
|
*/
|
||||||
int yStartArc;
|
private int yStartArc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the ending point of the radial line defining the starting point of the arc.
|
* the ending point of the radial line defining the starting point of the arc.
|
||||||
*/
|
*/
|
||||||
int xStartArc;
|
private int xStartArc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int bottomRect;
|
private int bottomRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int rightRect;
|
private int rightRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the bounding rectangle.
|
* upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int topRect;
|
private int topRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the upper-left corner of the bounding rectangle.
|
* the upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int leftRect;
|
private int leftRect;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.arc;
|
return HwmfRecordType.arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yEndArc = leis.readShort();
|
yEndArc = leis.readShort();
|
||||||
xEndArc = leis.readShort();
|
xEndArc = leis.readShort();
|
||||||
@ -524,6 +619,11 @@ public class HwmfDraw {
|
|||||||
leftRect = leis.readShort();
|
leftRect = leis.readShort();
|
||||||
return 8*LittleEndianConsts.SHORT_SIZE;
|
return 8*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -533,51 +633,53 @@ public class HwmfDraw {
|
|||||||
*/
|
*/
|
||||||
public static class WmfChord implements HwmfRecord {
|
public static class WmfChord implements HwmfRecord {
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical
|
* A 16-bit signed integer that defines the y-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the second radial.
|
* coordinates, of the endpoint of the second radial.
|
||||||
*/
|
*/
|
||||||
int yRadial2;
|
private int yRadial2;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical
|
* A 16-bit signed integer that defines the x-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the second radial.
|
* coordinates, of the endpoint of the second radial.
|
||||||
*/
|
*/
|
||||||
int xRadial2;
|
private int xRadial2;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical
|
* A 16-bit signed integer that defines the y-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the first radial.
|
* coordinates, of the endpoint of the first radial.
|
||||||
*/
|
*/
|
||||||
int yRadial1;
|
private int yRadial1;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical
|
* A 16-bit signed integer that defines the x-coordinate, in logical
|
||||||
* coordinates, of the endpoint of the first radial.
|
* coordinates, of the endpoint of the first radial.
|
||||||
*/
|
*/
|
||||||
int xRadial1;
|
private int xRadial1;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int bottomRect;
|
private int bottomRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the lower-right corner of the bounding rectangle.
|
* the lower-right corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int rightRect;
|
private int rightRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the bounding rectangle.
|
* upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int topRect;
|
private int topRect;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of
|
||||||
* the upper-left corner of the bounding rectangle.
|
* the upper-left corner of the bounding rectangle.
|
||||||
*/
|
*/
|
||||||
int leftRect;
|
private int leftRect;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.chord;
|
return HwmfRecordType.chord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yRadial2 = leis.readShort();
|
yRadial2 = leis.readShort();
|
||||||
xRadial2 = leis.readShort();
|
xRadial2 = leis.readShort();
|
||||||
@ -589,31 +691,43 @@ public class HwmfDraw {
|
|||||||
leftRect = leis.readShort();
|
leftRect = leis.readShort();
|
||||||
return 8*LittleEndianConsts.SHORT_SIZE;
|
return 8*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_SELECTOBJECT record specifies a graphics object for the playback device context. The
|
* The META_SELECTOBJECT record specifies a graphics object for the playback device context. The
|
||||||
* new object replaces the previous object of the same type, unless if the previous object is a palette
|
* new object replaces the previous object of the same type, unless if the previous object is a palette
|
||||||
* object. If the previous object is a palette object, then the META_SELECTPALETTE record must be
|
* object. If the previous object is a palette object, then the META_SELECTPALETTE record must be
|
||||||
* used instead of the META_SELECTOBJECT record, as the META_SELECTOBJECT record does not
|
* used instead of the META_SELECTOBJECT record, as the META_SELECTOBJECT record does not
|
||||||
* support replacing the palette object type.
|
* support replacing the palette object type.
|
||||||
*/
|
*/
|
||||||
public static class WmfSelectObject implements HwmfRecord {
|
public static class WmfSelectObject implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to
|
* A 16-bit unsigned integer used to index into the WMF Object Table to
|
||||||
* get the object to be selected.
|
* get the object to be selected.
|
||||||
*/
|
*/
|
||||||
int objectIndex;
|
private int objectIndex;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.selectObject;
|
return HwmfRecordType.selectObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
objectIndex = leis.readUShort();
|
objectIndex = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package org.apache.poi.hwmf.record;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
|
import org.apache.poi.util.HexDump;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
@ -28,21 +30,23 @@ public class HwmfEscape implements HwmfRecord {
|
|||||||
* A 16-bit unsigned integer that defines the escape function. The
|
* A 16-bit unsigned integer that defines the escape function. The
|
||||||
* value MUST be from the MetafileEscapes enumeration.
|
* value MUST be from the MetafileEscapes enumeration.
|
||||||
*/
|
*/
|
||||||
int escapeFunction;
|
private int escapeFunction;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that specifies the size, in bytes, of the
|
* A 16-bit unsigned integer that specifies the size, in bytes, of the
|
||||||
* EscapeData field.
|
* EscapeData field.
|
||||||
*/
|
*/
|
||||||
int byteCount;
|
private int byteCount;
|
||||||
/**
|
/**
|
||||||
* An array of bytes of size ByteCount.
|
* An array of bytes of size ByteCount.
|
||||||
*/
|
*/
|
||||||
byte escapeData[];
|
private byte escapeData[];
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.escape;
|
return HwmfRecordType.escape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
escapeFunction = leis.readUShort();
|
escapeFunction = leis.readUShort();
|
||||||
byteCount = leis.readUShort();
|
byteCount = leis.readUShort();
|
||||||
@ -50,4 +54,16 @@ public class HwmfEscape implements HwmfRecord {
|
|||||||
leis.read(escapeData);
|
leis.read(escapeData);
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE+byteCount;
|
return 2*LittleEndianConsts.SHORT_SIZE+byteCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("escape - function: "+escapeFunction+"\n");
|
||||||
|
sb.append(HexDump.dump(escapeData, 0, 0));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,26 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwmf.record;
|
package org.apache.poi.hwmf.record;
|
||||||
|
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
public class HwmfFill {
|
public class HwmfFill {
|
||||||
|
/**
|
||||||
|
* A record which contains an image (to be extracted)
|
||||||
|
*/
|
||||||
|
public interface HwmfImageRecord {
|
||||||
|
BufferedImage getImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_FILLREGION record fills a region using a specified brush.
|
* The META_FILLREGION record fills a region using a specified brush.
|
||||||
*/
|
*/
|
||||||
@ -32,23 +46,30 @@ public class HwmfFill {
|
|||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
||||||
* the region to be filled.
|
* the region to be filled.
|
||||||
*/
|
*/
|
||||||
int region;
|
private int region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get the
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get the
|
||||||
* brush to use for filling the region.
|
* brush to use for filling the region.
|
||||||
*/
|
*/
|
||||||
int brush;
|
private int brush;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.fillRegion;
|
return HwmfRecordType.fillRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
region = leis.readUShort();
|
region = leis.readUShort();
|
||||||
brush = leis.readUShort();
|
brush = leis.readUShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,6 +92,11 @@ public class HwmfFill {
|
|||||||
region = leis.readUShort();
|
region = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,23 +109,25 @@ public class HwmfFill {
|
|||||||
/**
|
/**
|
||||||
* A 32-bit ColorRef Object that defines the color value.
|
* A 32-bit ColorRef Object that defines the color value.
|
||||||
*/
|
*/
|
||||||
HwmfColorRef colorRef;
|
private HwmfColorRef colorRef;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* point where filling is to start.
|
* point where filling is to start.
|
||||||
*/
|
*/
|
||||||
int yStart;
|
private int yStart;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* point where filling is to start.
|
* point where filling is to start.
|
||||||
*/
|
*/
|
||||||
int xStart;
|
private int xStart;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.floodFill;
|
return HwmfRecordType.floodFill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
int size = colorRef.init(leis);
|
int size = colorRef.init(leis);
|
||||||
@ -107,6 +135,11 @@ public class HwmfFill {
|
|||||||
xStart = leis.readShort();
|
xStart = leis.readShort();
|
||||||
return size+2*LittleEndianConsts.SHORT_SIZE;
|
return size+2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,21 +147,57 @@ public class HwmfFill {
|
|||||||
* graphics operations that fill polygons.
|
* graphics operations that fill polygons.
|
||||||
*/
|
*/
|
||||||
public static class WmfSetPolyfillMode implements HwmfRecord {
|
public static class WmfSetPolyfillMode implements HwmfRecord {
|
||||||
|
/**
|
||||||
|
* A 16-bit unsigned integer that defines polygon fill mode.
|
||||||
|
* This MUST be one of the values: ALTERNATE = 0x0001, WINDING = 0x0002
|
||||||
|
*/
|
||||||
|
public enum HwmfPolyfillMode {
|
||||||
|
/**
|
||||||
|
* Selects alternate mode (fills the area between odd-numbered and
|
||||||
|
* even-numbered polygon sides on each scan line).
|
||||||
|
*/
|
||||||
|
ALTERNATE(0x0001, Path2D.WIND_EVEN_ODD),
|
||||||
|
/**
|
||||||
|
* Selects winding mode (fills any region with a nonzero winding value).
|
||||||
|
*/
|
||||||
|
WINDING(0x0002, Path2D.WIND_NON_ZERO);
|
||||||
|
|
||||||
|
public int wmfFlag;
|
||||||
|
public int awtFlag;
|
||||||
|
HwmfPolyfillMode(int wmfFlag, int awtFlag) {
|
||||||
|
this.wmfFlag = wmfFlag;
|
||||||
|
this.awtFlag = awtFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HwmfPolyfillMode valueOf(int wmfFlag) {
|
||||||
|
for (HwmfPolyfillMode pm : values()) {
|
||||||
|
if (pm.wmfFlag == wmfFlag) return pm;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines polygon fill mode.
|
* A 16-bit unsigned integer that defines polygon fill mode.
|
||||||
* This MUST be one of the values: ALTERNATE = 0x0001, WINDING = 0x0002
|
* This MUST be one of the values: ALTERNATE = 0x0001, WINDING = 0x0002
|
||||||
*/
|
*/
|
||||||
int polyFillMode;
|
private HwmfPolyfillMode polyfillMode;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setPolyFillMode;
|
return HwmfRecordType.setPolyFillMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
polyFillMode = leis.readUShort();
|
polyfillMode = HwmfPolyfillMode.valueOf(leis.readUShort());
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setPolyfillMode(polyfillMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -151,29 +220,31 @@ public class HwmfFill {
|
|||||||
* Filling continues outward in all directions as long as the color is encountered.
|
* Filling continues outward in all directions as long as the color is encountered.
|
||||||
* This style is useful for filling areas with multicolored boundaries.
|
* This style is useful for filling areas with multicolored boundaries.
|
||||||
*/
|
*/
|
||||||
int mode;
|
private int mode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 32-bit ColorRef Object that defines the color value.
|
* A 32-bit ColorRef Object that defines the color value.
|
||||||
*/
|
*/
|
||||||
HwmfColorRef colorRef;
|
private HwmfColorRef colorRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the point
|
||||||
* to be set.
|
* to be set.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the point
|
||||||
* to be set.
|
* to be set.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.extFloodFill;
|
return HwmfRecordType.extFloodFill;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
mode = leis.readUShort();
|
mode = leis.readUShort();
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
@ -182,6 +253,11 @@ public class HwmfFill {
|
|||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
return size+3*LittleEndianConsts.SHORT_SIZE;
|
return size+3*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,16 +269,23 @@ public class HwmfFill {
|
|||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
||||||
* the region to be inverted.
|
* the region to be inverted.
|
||||||
*/
|
*/
|
||||||
int region;
|
private int region;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.invertRegion;
|
return HwmfRecordType.invertRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
region = leis.readUShort();
|
region = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -217,39 +300,41 @@ public class HwmfFill {
|
|||||||
* A 32-bit unsigned integer that defines the raster operation code.
|
* A 32-bit unsigned integer that defines the raster operation code.
|
||||||
* This code MUST be one of the values in the Ternary Raster Operation enumeration table.
|
* This code MUST be one of the values in the Ternary Raster Operation enumeration table.
|
||||||
*/
|
*/
|
||||||
HwmfTernaryRasterOp rasterOperation;
|
private HwmfTernaryRasterOp rasterOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the rectangle.
|
* A 16-bit signed integer that defines the height, in logical units, of the rectangle.
|
||||||
*/
|
*/
|
||||||
int height;
|
private int height;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the rectangle.
|
* A 16-bit signed integer that defines the width, in logical units, of the rectangle.
|
||||||
*/
|
*/
|
||||||
int width;
|
private int width;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle to be filled.
|
* upper-left corner of the rectangle to be filled.
|
||||||
*/
|
*/
|
||||||
int yLeft;
|
private int yLeft;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle to be filled.
|
* upper-left corner of the rectangle to be filled.
|
||||||
*/
|
*/
|
||||||
int xLeft;
|
private int xLeft;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.patBlt;
|
return HwmfRecordType.patBlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
int rasterOpIndex = leis.readUShort();
|
|
||||||
int rasterOpCode = leis.readUShort();
|
int rasterOpCode = leis.readUShort();
|
||||||
|
int rasterOpIndex = leis.readUShort();
|
||||||
|
|
||||||
rasterOperation = HwmfTernaryRasterOp.fromOpIndex(rasterOpIndex);
|
rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
|
||||||
assert(rasterOpCode == rasterOperation.opCode);
|
assert(rasterOpCode == rasterOperation.opCode);
|
||||||
|
|
||||||
height = leis.readShort();
|
height = leis.readShort();
|
||||||
@ -259,6 +344,11 @@ public class HwmfFill {
|
|||||||
|
|
||||||
return 6*LittleEndianConsts.SHORT_SIZE;
|
return 6*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -269,44 +359,44 @@ public class HwmfFill {
|
|||||||
* in the playback device context, and the destination pixels are to be combined to form the new
|
* in the playback device context, and the destination pixels are to be combined to form the new
|
||||||
* image. This code MUST be one of the values in the Ternary Raster Operation Enumeration
|
* image. This code MUST be one of the values in the Ternary Raster Operation Enumeration
|
||||||
*/
|
*/
|
||||||
HwmfTernaryRasterOp rasterOperation;
|
private HwmfTernaryRasterOp rasterOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the source rectangle.
|
* A 16-bit signed integer that defines the height, in logical units, of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int srcHeight;
|
private int srcHeight;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the source rectangle.
|
* A 16-bit signed integer that defines the width, in logical units, of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int srcWidth;
|
private int srcWidth;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left corner
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left corner
|
||||||
* of the source rectangle.
|
* of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int ySrc;
|
private int ySrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left corner
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left corner
|
||||||
* of the source rectangle.
|
* of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int xSrc;
|
private int xSrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the destination rectangle.
|
* A 16-bit signed integer that defines the height, in logical units, of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int destHeight;
|
private int destHeight;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the destination rectangle.
|
* A 16-bit signed integer that defines the width, in logical units, of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int destWidth;
|
private int destWidth;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
|
||||||
* corner of the destination rectangle.
|
* corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int yDest;
|
private int yDest;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left
|
||||||
* corner of the destination rectangle.
|
* corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int xDest;
|
private int xDest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable-sized Bitmap16 Object that defines source image content.
|
* A variable-sized Bitmap16 Object that defines source image content.
|
||||||
@ -314,19 +404,21 @@ public class HwmfFill {
|
|||||||
*/
|
*/
|
||||||
HwmfBitmap16 target;
|
HwmfBitmap16 target;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.stretchBlt;
|
return HwmfRecordType.stretchBlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int rasterOpIndex = leis.readUShort();
|
|
||||||
int rasterOpCode = leis.readUShort();
|
int rasterOpCode = leis.readUShort();
|
||||||
|
int rasterOpIndex = leis.readUShort();
|
||||||
|
|
||||||
rasterOperation = HwmfTernaryRasterOp.fromOpIndex(rasterOpIndex);
|
rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
|
||||||
assert(rasterOpCode == rasterOperation.opCode);
|
assert(rasterOpCode == rasterOperation.opCode);
|
||||||
|
|
||||||
srcHeight = leis.readShort();
|
srcHeight = leis.readShort();
|
||||||
@ -351,6 +443,11 @@ public class HwmfFill {
|
|||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -360,13 +457,13 @@ public class HwmfFill {
|
|||||||
* The source of the color data is a DIB, and the destination of the transfer is
|
* The source of the color data is a DIB, and the destination of the transfer is
|
||||||
* the current output region in the playback device context.
|
* the current output region in the playback device context.
|
||||||
*/
|
*/
|
||||||
public static class WmfStretchDib implements HwmfRecord {
|
public static class WmfStretchDib implements HwmfRecord, HwmfImageRecord {
|
||||||
/**
|
/**
|
||||||
* A 32-bit unsigned integer that defines how the source pixels, the current brush in
|
* A 32-bit unsigned integer that defines how the source pixels, the current brush in
|
||||||
* the playback device context, and the destination pixels are to be combined to
|
* the playback device context, and the destination pixels are to be combined to
|
||||||
* form the new image.
|
* form the new image.
|
||||||
*/
|
*/
|
||||||
HwmfTernaryRasterOp rasterOperation;
|
private HwmfTernaryRasterOp rasterOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines whether the Colors field of the
|
* A 16-bit unsigned integer that defines whether the Colors field of the
|
||||||
@ -376,63 +473,65 @@ public class HwmfFill {
|
|||||||
* DIB_PAL_COLORS = 0x0001,
|
* DIB_PAL_COLORS = 0x0001,
|
||||||
* DIB_PAL_INDICES = 0x0002
|
* DIB_PAL_INDICES = 0x0002
|
||||||
*/
|
*/
|
||||||
int colorUsage;
|
private int colorUsage;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the
|
* A 16-bit signed integer that defines the height, in logical units, of the
|
||||||
* source rectangle.
|
* source rectangle.
|
||||||
*/
|
*/
|
||||||
int srcHeight;
|
private int srcHeight;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the
|
* A 16-bit signed integer that defines the width, in logical units, of the
|
||||||
* source rectangle.
|
* source rectangle.
|
||||||
*/
|
*/
|
||||||
int srcWidth;
|
private int srcWidth;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* source rectangle.
|
* source rectangle.
|
||||||
*/
|
*/
|
||||||
int ySrc;
|
private int ySrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* source rectangle.
|
* source rectangle.
|
||||||
*/
|
*/
|
||||||
int xSrc;
|
private int xSrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the
|
* A 16-bit signed integer that defines the height, in logical units, of the
|
||||||
* destination rectangle.
|
* destination rectangle.
|
||||||
*/
|
*/
|
||||||
int destHeight;
|
private int destHeight;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the
|
* A 16-bit signed integer that defines the width, in logical units, of the
|
||||||
* destination rectangle.
|
* destination rectangle.
|
||||||
*/
|
*/
|
||||||
int destWidth;
|
private int destWidth;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the destination rectangle.
|
* upper-left corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int yDst;
|
private int yDst;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the destination rectangle.
|
* upper-left corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int xDst;
|
private int xDst;
|
||||||
/**
|
/**
|
||||||
* A variable-sized DeviceIndependentBitmap Object (section 2.2.2.9) that is the
|
* A variable-sized DeviceIndependentBitmap Object (section 2.2.2.9) that is the
|
||||||
* source of the color data.
|
* source of the color data.
|
||||||
*/
|
*/
|
||||||
HwmfBitmapDib dib;
|
private HwmfBitmapDib dib;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.stretchDib;
|
return HwmfRecordType.stretchDib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
int rasterOpIndex = leis.readUShort();
|
|
||||||
int rasterOpCode = leis.readUShort();
|
int rasterOpCode = leis.readUShort();
|
||||||
|
int rasterOpIndex = leis.readUShort();
|
||||||
|
|
||||||
rasterOperation = HwmfTernaryRasterOp.fromOpIndex(rasterOpIndex);
|
rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
|
||||||
assert(rasterOpCode == rasterOperation.opCode);
|
assert(rasterOpCode == rasterOperation.opCode);
|
||||||
|
|
||||||
colorUsage = leis.readUShort();
|
colorUsage = leis.readUShort();
|
||||||
@ -447,9 +546,20 @@ public class HwmfFill {
|
|||||||
|
|
||||||
int size = 11*LittleEndianConsts.SHORT_SIZE;
|
int size = 11*LittleEndianConsts.SHORT_SIZE;
|
||||||
dib = new HwmfBitmapDib();
|
dib = new HwmfBitmapDib();
|
||||||
size += dib.init(leis);
|
size += dib.init(leis, (int)(recordSize-6-size));
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
return dib.getImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WmfBitBlt implements HwmfRecord {
|
public static class WmfBitBlt implements HwmfRecord {
|
||||||
@ -458,57 +568,59 @@ public class HwmfFill {
|
|||||||
* A 32-bit unsigned integer that defines how the source pixels, the current brush in the playback
|
* A 32-bit unsigned integer that defines how the source pixels, the current brush in the playback
|
||||||
* device context, and the destination pixels are to be combined to form the new image.
|
* device context, and the destination pixels are to be combined to form the new image.
|
||||||
*/
|
*/
|
||||||
HwmfTernaryRasterOp rasterOperation;
|
private HwmfTernaryRasterOp rasterOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left corner
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left corner
|
||||||
of the source rectangle.
|
of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int ySrc;
|
private int ySrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left corner
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left corner
|
||||||
of the source rectangle.
|
of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int xSrc;
|
private int xSrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the source and
|
* A 16-bit signed integer that defines the height, in logical units, of the source and
|
||||||
destination rectangles.
|
destination rectangles.
|
||||||
*/
|
*/
|
||||||
int height;
|
private int height;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the source and destination
|
* A 16-bit signed integer that defines the width, in logical units, of the source and destination
|
||||||
rectangles.
|
rectangles.
|
||||||
*/
|
*/
|
||||||
int width;
|
private int width;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
|
||||||
corner of the destination rectangle.
|
corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int yDest;
|
private int yDest;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left
|
||||||
corner of the destination rectangle.
|
corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int xDest;
|
private int xDest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable-sized Bitmap16 Object that defines source image content.
|
* A variable-sized Bitmap16 Object that defines source image content.
|
||||||
* This object MUST be specified, even if the raster operation does not require a source.
|
* This object MUST be specified, even if the raster operation does not require a source.
|
||||||
*/
|
*/
|
||||||
HwmfBitmap16 target;
|
private HwmfBitmap16 target;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.bitBlt;
|
return HwmfRecordType.bitBlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int rasterOpIndex = leis.readUShort();
|
|
||||||
int rasterOpCode = leis.readUShort();
|
int rasterOpCode = leis.readUShort();
|
||||||
|
int rasterOpIndex = leis.readUShort();
|
||||||
|
|
||||||
rasterOperation = HwmfTernaryRasterOp.fromOpIndex(rasterOpIndex);
|
rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
|
||||||
assert(rasterOpCode == rasterOperation.opCode);
|
assert(rasterOpCode == rasterOperation.opCode);
|
||||||
|
|
||||||
ySrc = leis.readShort();
|
ySrc = leis.readShort();
|
||||||
@ -535,6 +647,11 @@ public class HwmfFill {
|
|||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -543,7 +660,7 @@ public class HwmfFill {
|
|||||||
* using deviceindependent color data.
|
* using deviceindependent color data.
|
||||||
* The source of the color data is a DIB
|
* The source of the color data is a DIB
|
||||||
*/
|
*/
|
||||||
public static class WmfSetDibToDev implements HwmfRecord {
|
public static class WmfSetDibToDev implements HwmfRecord, HwmfImageRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines whether the Colors field of the
|
* A 16-bit unsigned integer that defines whether the Colors field of the
|
||||||
@ -553,55 +670,57 @@ public class HwmfFill {
|
|||||||
* DIB_PAL_COLORS = 0x0001,
|
* DIB_PAL_COLORS = 0x0001,
|
||||||
* DIB_PAL_INDICES = 0x0002
|
* DIB_PAL_INDICES = 0x0002
|
||||||
*/
|
*/
|
||||||
int colorUsage;
|
private int colorUsage;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the number of scan lines in the source.
|
* A 16-bit unsigned integer that defines the number of scan lines in the source.
|
||||||
*/
|
*/
|
||||||
int scanCount;
|
private int scanCount;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the starting scan line in the source.
|
* A 16-bit unsigned integer that defines the starting scan line in the source.
|
||||||
*/
|
*/
|
||||||
int startScan;
|
private int startScan;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit unsigned integer that defines the y-coordinate, in logical units, of the
|
||||||
* source rectangle.
|
* source rectangle.
|
||||||
*/
|
*/
|
||||||
int yDib;
|
private int yDib;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit unsigned integer that defines the x-coordinate, in logical units, of the
|
||||||
* source rectangle.
|
* source rectangle.
|
||||||
*/
|
*/
|
||||||
int xDib;
|
private int xDib;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the height, in logical units, of the
|
* A 16-bit unsigned integer that defines the height, in logical units, of the
|
||||||
* source and destination rectangles.
|
* source and destination rectangles.
|
||||||
*/
|
*/
|
||||||
int height;
|
private int height;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the width, in logical units, of the
|
* A 16-bit unsigned integer that defines the width, in logical units, of the
|
||||||
* source and destination rectangles.
|
* source and destination rectangles.
|
||||||
*/
|
*/
|
||||||
int width;
|
private int width;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit unsigned integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the destination rectangle.
|
* upper-left corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int yDest;
|
private int yDest;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit unsigned integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the destination rectangle.
|
* upper-left corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int xDest;
|
private int xDest;
|
||||||
/**
|
/**
|
||||||
* A variable-sized DeviceIndependentBitmap Object that is the source of the color data.
|
* A variable-sized DeviceIndependentBitmap Object that is the source of the color data.
|
||||||
*/
|
*/
|
||||||
HwmfBitmapDib dib;
|
private HwmfBitmapDib dib;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setDibToDev;
|
return HwmfRecordType.setDibToDev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
colorUsage = leis.readUShort();
|
colorUsage = leis.readUShort();
|
||||||
scanCount = leis.readUShort();
|
scanCount = leis.readUShort();
|
||||||
@ -615,14 +734,24 @@ public class HwmfFill {
|
|||||||
|
|
||||||
int size = 9*LittleEndianConsts.SHORT_SIZE;
|
int size = 9*LittleEndianConsts.SHORT_SIZE;
|
||||||
dib = new HwmfBitmapDib();
|
dib = new HwmfBitmapDib();
|
||||||
size += dib.init(leis);
|
size += dib.init(leis, (int)(recordSize-6-size));
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
return dib.getImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class WmfDibBitBlt implements HwmfRecord {
|
public static class WmfDibBitBlt implements HwmfRecord, HwmfImageRecord {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 32-bit unsigned integer that defines how the source pixels, the current brush
|
* A 32-bit unsigned integer that defines how the source pixels, the current brush
|
||||||
@ -633,51 +762,53 @@ public class HwmfFill {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the source rectangle.
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int ySrc;
|
private int ySrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the source rectangle.
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int xSrc;
|
private int xSrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the source and
|
* A 16-bit signed integer that defines the height, in logical units, of the source and
|
||||||
* destination rectangles.
|
* destination rectangles.
|
||||||
*/
|
*/
|
||||||
int height;
|
private int height;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the source and destination
|
* A 16-bit signed integer that defines the width, in logical units, of the source and destination
|
||||||
* rectangles.
|
* rectangles.
|
||||||
*/
|
*/
|
||||||
int width;
|
private int width;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the upper-left
|
||||||
* corner of the destination rectangle.
|
* corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int yDest;
|
private int yDest;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the upper-left
|
||||||
* corner of the destination rectangle.
|
* corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int xDest;
|
private int xDest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable-sized DeviceIndependentBitmap Object that defines image content.
|
* A variable-sized DeviceIndependentBitmap Object that defines image content.
|
||||||
* This object MUST be specified, even if the raster operation does not require a source.
|
* This object MUST be specified, even if the raster operation does not require a source.
|
||||||
*/
|
*/
|
||||||
HwmfBitmapDib target;
|
private HwmfBitmapDib target;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.dibBitBlt;
|
return HwmfRecordType.dibBitBlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int rasterOpIndex = leis.readUShort();
|
|
||||||
int rasterOpCode = leis.readUShort();
|
int rasterOpCode = leis.readUShort();
|
||||||
|
int rasterOpIndex = leis.readUShort();
|
||||||
|
|
||||||
rasterOperation = HwmfTernaryRasterOp.fromOpIndex(rasterOpIndex);
|
rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
|
||||||
assert(rasterOpCode == rasterOperation.opCode);
|
assert(rasterOpCode == rasterOperation.opCode);
|
||||||
|
|
||||||
ySrc = leis.readShort();
|
ySrc = leis.readShort();
|
||||||
@ -696,76 +827,88 @@ public class HwmfFill {
|
|||||||
size += 4*LittleEndianConsts.SHORT_SIZE;
|
size += 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
if (hasBitmap) {
|
if (hasBitmap) {
|
||||||
target = new HwmfBitmapDib();
|
target = new HwmfBitmapDib();
|
||||||
size += target.init(leis);
|
size += target.init(leis, (int)(recordSize-6-size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
return target.getImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WmfDibStretchBlt implements HwmfRecord {
|
public static class WmfDibStretchBlt implements HwmfRecord, HwmfImageRecord {
|
||||||
/**
|
/**
|
||||||
* A 32-bit unsigned integer that defines how the source pixels, the current brush
|
* A 32-bit unsigned integer that defines how the source pixels, the current brush
|
||||||
* in the playback device context, and the destination pixels are to be combined to form the
|
* in the playback device context, and the destination pixels are to be combined to form the
|
||||||
* new image. This code MUST be one of the values in the Ternary Raster Operation Enumeration.
|
* new image. This code MUST be one of the values in the Ternary Raster Operation Enumeration.
|
||||||
*/
|
*/
|
||||||
HwmfTernaryRasterOp rasterOperation;
|
private HwmfTernaryRasterOp rasterOperation;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the source rectangle.
|
* A 16-bit signed integer that defines the height, in logical units, of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int srcHeight;
|
private int srcHeight;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the source rectangle.
|
* A 16-bit signed integer that defines the width, in logical units, of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int srcWidth;
|
private int srcWidth;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the source rectangle.
|
* upper-left corner of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int ySrc;
|
private int ySrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the source rectangle.
|
* upper-left corner of the source rectangle.
|
||||||
*/
|
*/
|
||||||
int xSrc;
|
private int xSrc;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the height, in logical units, of the
|
* A 16-bit signed integer that defines the height, in logical units, of the
|
||||||
* destination rectangle.
|
* destination rectangle.
|
||||||
*/
|
*/
|
||||||
int destHeight;
|
private int destHeight;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the width, in logical units, of the
|
* A 16-bit signed integer that defines the width, in logical units, of the
|
||||||
* destination rectangle.
|
* destination rectangle.
|
||||||
*/
|
*/
|
||||||
int destWidth;
|
private int destWidth;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units,
|
* A 16-bit signed integer that defines the y-coordinate, in logical units,
|
||||||
* of the upper-left corner of the destination rectangle.
|
* of the upper-left corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int yDest;
|
private int yDest;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units,
|
* A 16-bit signed integer that defines the x-coordinate, in logical units,
|
||||||
* of the upper-left corner of the destination rectangle.
|
* of the upper-left corner of the destination rectangle.
|
||||||
*/
|
*/
|
||||||
int xDest;
|
private int xDest;
|
||||||
/**
|
/**
|
||||||
* A variable-sized DeviceIndependentBitmap Object that defines image content.
|
* A variable-sized DeviceIndependentBitmap Object that defines image content.
|
||||||
* This object MUST be specified, even if the raster operation does not require a source.
|
* This object MUST be specified, even if the raster operation does not require a source.
|
||||||
*/
|
*/
|
||||||
HwmfBitmapDib target;
|
HwmfBitmapDib target;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.dibStretchBlt;
|
return HwmfRecordType.dibStretchBlt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
boolean hasBitmap = (recordSize > ((recordFunction >> 8) + 3));
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int rasterOpIndex = leis.readUShort();
|
|
||||||
int rasterOpCode = leis.readUShort();
|
int rasterOpCode = leis.readUShort();
|
||||||
|
int rasterOpIndex = leis.readUShort();
|
||||||
|
|
||||||
rasterOperation = HwmfTernaryRasterOp.fromOpIndex(rasterOpIndex);
|
rasterOperation = HwmfTernaryRasterOp.valueOf(rasterOpIndex);
|
||||||
assert(rasterOpCode == rasterOperation.opCode);
|
assert(rasterOpCode == rasterOperation.opCode);
|
||||||
|
|
||||||
srcHeight = leis.readShort();
|
srcHeight = leis.readShort();
|
||||||
@ -785,10 +928,20 @@ public class HwmfFill {
|
|||||||
size += 4*LittleEndianConsts.SHORT_SIZE;
|
size += 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
if (hasBitmap) {
|
if (hasBitmap) {
|
||||||
target = new HwmfBitmapDib();
|
target = new HwmfBitmapDib();
|
||||||
size += target.init(leis);
|
size += target.init(leis, (int)(recordSize-6-size));
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
return target.getImage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ package org.apache.poi.hwmf.record;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -440,7 +441,7 @@ public class HwmfFont {
|
|||||||
*
|
*
|
||||||
* @see WmfClipPrecision
|
* @see WmfClipPrecision
|
||||||
*/
|
*/
|
||||||
int clipPrecision;
|
WmfClipPrecision clipPrecision;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An 8-bit unsigned integer that defines the output quality.
|
* An 8-bit unsigned integer that defines the output quality.
|
||||||
@ -477,22 +478,23 @@ public class HwmfFont {
|
|||||||
strikeOut = leis.readByte() != 0;
|
strikeOut = leis.readByte() != 0;
|
||||||
charSet = WmfCharset.valueOf(leis.readUByte());
|
charSet = WmfCharset.valueOf(leis.readUByte());
|
||||||
outPrecision = WmfOutPrecision.valueOf(leis.readUByte());
|
outPrecision = WmfOutPrecision.valueOf(leis.readUByte());
|
||||||
|
clipPrecision = WmfClipPrecision.valueOf(leis.readUByte());
|
||||||
quality = WmfFontQuality.valueOf(leis.readUByte());
|
quality = WmfFontQuality.valueOf(leis.readUByte());
|
||||||
int pitchAndFamily = leis.readUByte();
|
int pitchAndFamily = leis.readUByte();
|
||||||
family = WmfFontFamilyClass.valueOf(pitchAndFamily & 0xF);
|
family = WmfFontFamilyClass.valueOf(pitchAndFamily & 0xF);
|
||||||
pitch = WmfFontPitch.valueOf((pitchAndFamily >>> 6) & 3);
|
pitch = WmfFontPitch.valueOf((pitchAndFamily >>> 6) & 3);
|
||||||
|
|
||||||
byte buf[] = new byte[32], readBytes;
|
byte buf[] = new byte[32], b, readBytes = 0;
|
||||||
for (readBytes = 0; readBytes < 32; readBytes++) {
|
do {
|
||||||
if ((buf[readBytes] = leis.readByte()) == 0) {
|
if (readBytes == 32) {
|
||||||
break;
|
throw new IOException("Font facename can't be determined.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (readBytes == 1 || readBytes == 32) {
|
buf[readBytes++] = b = leis.readByte();
|
||||||
throw new IOException("Font facename can't be determined.");
|
} while (b != 0 && b != -1 && readBytes <= 32);
|
||||||
}
|
|
||||||
facename = new String(buf, 0, readBytes-1, Charset.forName("ISO-8859-1"));
|
facename = new String(buf, 0, readBytes-1, Charset.forName("ISO-8859-1"));
|
||||||
|
|
||||||
return 17+readBytes;
|
return 5*LittleEndianConsts.SHORT_SIZE+8*LittleEndianConsts.BYTE_SIZE+readBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,17 +21,17 @@ package org.apache.poi.hwmf.record;
|
|||||||
* The HatchStyle Enumeration specifies the hatch pattern.
|
* The HatchStyle Enumeration specifies the hatch pattern.
|
||||||
*/
|
*/
|
||||||
public enum HwmfHatchStyle {
|
public enum HwmfHatchStyle {
|
||||||
/** A horizontal hatch */
|
/** ----- - A horizontal hatch */
|
||||||
HS_HORIZONTAL(0x0000),
|
HS_HORIZONTAL(0x0000),
|
||||||
/** A vertical hatch */
|
/** ||||| - A vertical hatch */
|
||||||
HS_VERTICAL(0x0001),
|
HS_VERTICAL(0x0001),
|
||||||
/** A 45-degree downward, left-to-right hatch. */
|
/** \\\\\ - A 45-degree downward, left-to-right hatch. */
|
||||||
HS_FDIAGONAL(0x0002),
|
HS_FDIAGONAL(0x0002),
|
||||||
/** A 45-degree upward, left-to-right hatch. */
|
/** ///// - A 45-degree upward, left-to-right hatch. */
|
||||||
HS_BDIAGONAL(0x0003),
|
HS_BDIAGONAL(0x0003),
|
||||||
/** A horizontal and vertical cross-hatch. */
|
/** +++++ - A horizontal and vertical cross-hatch. */
|
||||||
HS_CROSS(0x0004),
|
HS_CROSS(0x0004),
|
||||||
/** A 45-degree crosshatch. */
|
/** xxxxx - A 45-degree crosshatch. */
|
||||||
HS_DIAGCROSS(0x0005);
|
HS_DIAGCROSS(0x0005);
|
||||||
|
|
||||||
int flag;
|
int flag;
|
||||||
|
114
src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java
Normal file
114
src/scratchpad/src/org/apache/poi/hwmf/record/HwmfMapMode.java
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.hwmf.record;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 16-bit unsigned integer that defines the mapping mode.
|
||||||
|
*
|
||||||
|
* The MapMode defines how logical units are mapped to physical units;
|
||||||
|
* that is, assuming that the origins in both the logical and physical coordinate systems
|
||||||
|
* are at the same point on the drawing surface, what is the physical coordinate (x',y')
|
||||||
|
* that corresponds to logical coordinate (x,y).
|
||||||
|
*
|
||||||
|
* For example, suppose the mapping mode is MM_TEXT. Given the following definition of that
|
||||||
|
* mapping mode, and an origin (0,0) at the top left corner of the drawing surface, logical
|
||||||
|
* coordinate (4,5) would map to physical coordinate (4,5) in pixels.
|
||||||
|
*
|
||||||
|
* Now suppose the mapping mode is MM_LOENGLISH, with the same origin as the previous
|
||||||
|
* example. Given the following definition of that mapping mode, logical coordinate (4,-5)
|
||||||
|
* would map to physical coordinate (0.04,0.05) in inches.
|
||||||
|
*/
|
||||||
|
public enum HwmfMapMode {
|
||||||
|
/**
|
||||||
|
* Each logical unit is mapped to one device pixel.
|
||||||
|
* Positive x is to the right; positive y is down.
|
||||||
|
*/
|
||||||
|
MM_TEXT(0x0001, 0),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each logical unit is mapped to 0.1 millimeter.
|
||||||
|
* Positive x is to the right; positive y is up.
|
||||||
|
*/
|
||||||
|
MM_LOMETRIC(0x0002, 254),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each logical unit is mapped to 0.01 millimeter.
|
||||||
|
* Positive x is to the right; positive y is up.
|
||||||
|
*/
|
||||||
|
MM_HIMETRIC(0x0003, 2540),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each logical unit is mapped to 0.01 inch.
|
||||||
|
* Positive x is to the right; positive y is up.
|
||||||
|
*/
|
||||||
|
MM_LOENGLISH(0x0004, 100),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each logical unit is mapped to 0.001 inch.
|
||||||
|
* Positive x is to the right; positive y is up.
|
||||||
|
*/
|
||||||
|
MM_HIENGLISH(0x0005, 1000),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each logical unit is mapped to one twentieth (1/20) of a point.
|
||||||
|
* In printing, a point is 1/72 of an inch; therefore, 1/20 of a point is 1/1440 of an inch.
|
||||||
|
* This unit is also known as a "twip".
|
||||||
|
* Positive x is to the right; positive y is up.
|
||||||
|
*/
|
||||||
|
MM_TWIPS(0x0006, 1440),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logical units are mapped to arbitrary device units with equally scaled axes;
|
||||||
|
* that is, one unit along the x-axis is equal to one unit along the y-axis.
|
||||||
|
* The META_SETWINDOWEXT and META_SETVIEWPORTEXT records specify the units and the
|
||||||
|
* orientation of the axes.
|
||||||
|
* The processing application SHOULD make adjustments as necessary to ensure the x and y
|
||||||
|
* units remain the same size. For example, when the window extent is set, the viewport
|
||||||
|
* SHOULD be adjusted to keep the units isotropic.
|
||||||
|
*/
|
||||||
|
MM_ISOTROPIC(0x0007, -1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logical units are mapped to arbitrary units with arbitrarily scaled axes.
|
||||||
|
*/
|
||||||
|
MM_ANISOTROPIC(0x0008, -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* native flag
|
||||||
|
*/
|
||||||
|
public final int flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* transformation units - usually scale relative to current dpi.
|
||||||
|
* when scale == 0, then don't scale
|
||||||
|
* when scale == -1, then scale relative to window dimension.
|
||||||
|
*/
|
||||||
|
public final int scale;
|
||||||
|
|
||||||
|
HwmfMapMode(int flag, int scale) {
|
||||||
|
this.flag = flag;
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HwmfMapMode valueOf(int flag) {
|
||||||
|
for (HwmfMapMode mm : values()) {
|
||||||
|
if (mm.flag == flag) return mm;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -17,8 +17,12 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwmf.record;
|
package org.apache.poi.hwmf.record;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfDrawProperties;
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
@ -28,22 +32,38 @@ public class HwmfMisc {
|
|||||||
* The META_SAVEDC record saves the playback device context for later retrieval.
|
* The META_SAVEDC record saves the playback device context for later retrieval.
|
||||||
*/
|
*/
|
||||||
public static class WmfSaveDc implements HwmfRecord {
|
public static class WmfSaveDc implements HwmfRecord {
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.saveDc; }
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.saveDc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_SETRELABS record is reserved and not supported.
|
* The META_SETRELABS record is reserved and not supported.
|
||||||
*/
|
*/
|
||||||
public static class WmfSetRelabs implements HwmfRecord {
|
public static class WmfSetRelabs implements HwmfRecord {
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.setRelabs; }
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.setRelabs;
|
||||||
|
}
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,16 +77,23 @@ public class HwmfMisc {
|
|||||||
* member is positive, nSavedDC represents a specific instance of the state to be restored. If
|
* member is positive, nSavedDC represents a specific instance of the state to be restored. If
|
||||||
* this member is negative, nSavedDC represents an instance relative to the current state.
|
* this member is negative, nSavedDC represents an instance relative to the current state.
|
||||||
*/
|
*/
|
||||||
int nSavedDC;
|
private int nSavedDC;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.restoreDc;
|
return HwmfRecordType.restoreDc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
nSavedDC = leis.readShort();
|
nSavedDC = leis.readShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,16 +102,23 @@ public class HwmfMisc {
|
|||||||
*/
|
*/
|
||||||
public static class WmfSetBkColor implements HwmfRecord {
|
public static class WmfSetBkColor implements HwmfRecord {
|
||||||
|
|
||||||
HwmfColorRef colorRef;
|
private HwmfColorRef colorRef;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setBkColor;
|
return HwmfRecordType.setBkColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
return colorRef.init(leis);
|
return colorRef.init(leis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setBackgroundColor(colorRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,18 +130,38 @@ public class HwmfMisc {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines background mix mode.
|
* A 16-bit unsigned integer that defines background mix mode.
|
||||||
* This MUST be either TRANSPARENT = 0x0001 or OPAQUE = 0x0002
|
|
||||||
*/
|
*/
|
||||||
int bkMode;
|
public enum HwmfBkMode {
|
||||||
|
TRANSPARENT(0x0001), OPAQUE(0x0002);
|
||||||
|
|
||||||
|
int flag;
|
||||||
|
HwmfBkMode(int flag) {
|
||||||
|
this.flag = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HwmfBkMode valueOf(int flag) {
|
||||||
|
for (HwmfBkMode bs : values()) {
|
||||||
|
if (bs.flag == flag) return bs;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HwmfBkMode bkMode;
|
||||||
|
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setBkMode;
|
return HwmfRecordType.setBkMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
bkMode = leis.readUShort();
|
bkMode = HwmfBkMode.valueOf(leis.readUShort());
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setBkMode(bkMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -122,19 +176,26 @@ public class HwmfMisc {
|
|||||||
* LAYOUT_RTL = 0x0001
|
* LAYOUT_RTL = 0x0001
|
||||||
* LAYOUT_BITMAPORIENTATIONPRESERVED = 0x0008
|
* LAYOUT_BITMAPORIENTATIONPRESERVED = 0x0008
|
||||||
*/
|
*/
|
||||||
int layout;
|
private int layout;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setLayout;
|
return HwmfRecordType.setLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
layout = leis.readUShort();
|
layout = leis.readUShort();
|
||||||
// A 16-bit field that MUST be ignored.
|
// A 16-bit field that MUST be ignored.
|
||||||
int reserved = leis.readShort();
|
int reserved = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,72 +205,23 @@ public class HwmfMisc {
|
|||||||
*/
|
*/
|
||||||
public static class WmfSetMapMode implements HwmfRecord {
|
public static class WmfSetMapMode implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
private HwmfMapMode mapMode;
|
||||||
* A 16-bit unsigned integer that defines the mapping mode.
|
|
||||||
*
|
|
||||||
* The MapMode defines how logical units are mapped to physical units;
|
|
||||||
* that is, assuming that the origins in both the logical and physical coordinate systems
|
|
||||||
* are at the same point on the drawing surface, what is the physical coordinate (x',y')
|
|
||||||
* that corresponds to logical coordinate (x,y).
|
|
||||||
*
|
|
||||||
* For example, suppose the mapping mode is MM_TEXT. Given the following definition of that
|
|
||||||
* mapping mode, and an origin (0,0) at the top left corner of the drawing surface, logical
|
|
||||||
* coordinate (4,5) would map to physical coordinate (4,5) in pixels.
|
|
||||||
*
|
|
||||||
* Now suppose the mapping mode is MM_LOENGLISH, with the same origin as the previous
|
|
||||||
* example. Given the following definition of that mapping mode, logical coordinate (4,-5)
|
|
||||||
* would map to physical coordinate (0.04,0.05) in inches.
|
|
||||||
*
|
|
||||||
* This MUST be one of the following:
|
|
||||||
*
|
|
||||||
* MM_TEXT (= 0x0001):
|
|
||||||
* Each logical unit is mapped to one device pixel.
|
|
||||||
* Positive x is to the right; positive y is down.
|
|
||||||
*
|
|
||||||
* MM_LOMETRIC (= 0x0002):
|
|
||||||
* Each logical unit is mapped to 0.1 millimeter.
|
|
||||||
* Positive x is to the right; positive y is up.
|
|
||||||
*
|
|
||||||
* MM_HIMETRIC (= 0x0003):
|
|
||||||
* Each logical unit is mapped to 0.01 millimeter.
|
|
||||||
* Positive x is to the right; positive y is up.
|
|
||||||
*
|
|
||||||
* MM_LOENGLISH (= 0x0004):
|
|
||||||
* Each logical unit is mapped to 0.01 inch.
|
|
||||||
* Positive x is to the right; positive y is up.
|
|
||||||
*
|
|
||||||
* MM_HIENGLISH (= 0x0005):
|
|
||||||
* Each logical unit is mapped to 0.001 inch.
|
|
||||||
* Positive x is to the right; positive y is up.
|
|
||||||
*
|
|
||||||
* MM_TWIPS (= 0x0006):
|
|
||||||
* Each logical unit is mapped to one twentieth (1/20) of a point.
|
|
||||||
* In printing, a point is 1/72 of an inch; therefore, 1/20 of a point is 1/1440 of an inch.
|
|
||||||
* This unit is also known as a "twip".
|
|
||||||
* Positive x is to the right; positive y is up.
|
|
||||||
*
|
|
||||||
* MM_ISOTROPIC (= 0x0007):
|
|
||||||
* Logical units are mapped to arbitrary device units with equally scaled axes;
|
|
||||||
* that is, one unit along the x-axis is equal to one unit along the y-axis.
|
|
||||||
* The META_SETWINDOWEXT and META_SETVIEWPORTEXT records specify the units and the
|
|
||||||
* orientation of the axes.
|
|
||||||
* The processing application SHOULD make adjustments as necessary to ensure the x and y
|
|
||||||
* units remain the same size. For example, when the window extent is set, the viewport
|
|
||||||
* SHOULD be adjusted to keep the units isotropic.
|
|
||||||
*
|
|
||||||
* MM_ANISOTROPIC (= 0x0008):
|
|
||||||
* Logical units are mapped to arbitrary units with arbitrarily scaled axes.
|
|
||||||
*/
|
|
||||||
int mapMode;
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setMapMode;
|
return HwmfRecordType.setMapMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
mapMode = leis.readUShort();
|
mapMode = HwmfMapMode.valueOf(leis.readUShort());
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setMapMode(mapMode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,16 +235,23 @@ public class HwmfMisc {
|
|||||||
* match a font's aspect ratio to the current device's aspect ratio. If bit 0 is
|
* match a font's aspect ratio to the current device's aspect ratio. If bit 0 is
|
||||||
* set, the mapper selects only matching fonts.
|
* set, the mapper selects only matching fonts.
|
||||||
*/
|
*/
|
||||||
long mapperValues;
|
private long mapperValues;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setMapperFlags;
|
return HwmfRecordType.setMapperFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
mapperValues = leis.readUInt();
|
mapperValues = leis.readUInt();
|
||||||
return LittleEndianConsts.INT_SIZE;
|
return LittleEndianConsts.INT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,16 +281,23 @@ public class HwmfMisc {
|
|||||||
* R2_MERGEPEN = 0x000F,
|
* R2_MERGEPEN = 0x000F,
|
||||||
* R2_WHITE = 0x0010
|
* R2_WHITE = 0x0010
|
||||||
*/
|
*/
|
||||||
int drawMode;
|
private int drawMode;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setRop2;
|
return HwmfRecordType.setRop2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
drawMode = leis.readUShort();
|
drawMode = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,25 +314,32 @@ public class HwmfMisc {
|
|||||||
* COLORONCOLOR = 0x0003,
|
* COLORONCOLOR = 0x0003,
|
||||||
* HALFTONE = 0x0004
|
* HALFTONE = 0x0004
|
||||||
*/
|
*/
|
||||||
int setStretchBltMode;
|
private int setStretchBltMode;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setStretchBltMode;
|
return HwmfRecordType.setStretchBltMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
setStretchBltMode = leis.readUShort();
|
setStretchBltMode = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
|
* The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
|
||||||
* pattern specified by a DeviceIndependentBitmap (DIB) Object
|
* pattern specified by a DeviceIndependentBitmap (DIB) Object
|
||||||
*/
|
*/
|
||||||
public static class WmfDibCreatePatternBrush implements HwmfRecord {
|
public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord {
|
||||||
|
|
||||||
HwmfBrushStyle style;
|
private HwmfBrushStyle style;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines whether the Colors field of a DIB
|
* A 16-bit unsigned integer that defines whether the Colors field of a DIB
|
||||||
@ -320,15 +353,17 @@ public class HwmfMisc {
|
|||||||
* DIB_PAL_COLORS = 0x0001,
|
* DIB_PAL_COLORS = 0x0001,
|
||||||
* DIB_PAL_INDICES = 0x0002
|
* DIB_PAL_INDICES = 0x0002
|
||||||
*/
|
*/
|
||||||
int colorUsage;
|
private int colorUsage;
|
||||||
|
|
||||||
HwmfBitmapDib patternDib;
|
private HwmfBitmapDib patternDib;
|
||||||
HwmfBitmap16 pattern16;
|
private HwmfBitmap16 pattern16;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.dibCreatePatternBrush;
|
return HwmfRecordType.dibCreatePatternBrush;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
style = HwmfBrushStyle.valueOf(leis.readUShort());
|
style = HwmfBrushStyle.valueOf(leis.readUShort());
|
||||||
colorUsage = leis.readUShort();
|
colorUsage = leis.readUShort();
|
||||||
@ -339,12 +374,9 @@ public class HwmfMisc {
|
|||||||
case BS_DIBPATTERN:
|
case BS_DIBPATTERN:
|
||||||
case BS_DIBPATTERNPT:
|
case BS_DIBPATTERNPT:
|
||||||
case BS_HATCHED:
|
case BS_HATCHED:
|
||||||
patternDib = new HwmfBitmapDib();
|
|
||||||
size += patternDib.init(leis);
|
|
||||||
break;
|
|
||||||
case BS_PATTERN:
|
case BS_PATTERN:
|
||||||
pattern16 = new HwmfBitmap16();
|
patternDib = new HwmfBitmapDib();
|
||||||
size += pattern16.init(leis);
|
size += patternDib.init(leis, (int)(recordSize-6-size));
|
||||||
break;
|
break;
|
||||||
case BS_INDEXED:
|
case BS_INDEXED:
|
||||||
case BS_DIBPATTERN8X8:
|
case BS_DIBPATTERN8X8:
|
||||||
@ -354,6 +386,24 @@ public class HwmfMisc {
|
|||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
HwmfDrawProperties prop = ctx.getProperties();
|
||||||
|
prop.setBrushStyle(style);
|
||||||
|
prop.setBrushBitmap(getImage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
if (patternDib != null) {
|
||||||
|
return patternDib.getImage();
|
||||||
|
} else if (pattern16 != null) {
|
||||||
|
return pattern16.getImage();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -364,84 +414,94 @@ public class HwmfMisc {
|
|||||||
public static class WmfDeleteObject implements HwmfRecord {
|
public static class WmfDeleteObject implements HwmfRecord {
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to
|
* A 16-bit unsigned integer used to index into the WMF Object Table to
|
||||||
get the object to be deleted.
|
* get the object to be deleted.
|
||||||
*/
|
*/
|
||||||
int objectIndex;
|
private int objectIndex;
|
||||||
|
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.deleteObject; }
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.deleteObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
objectIndex = leis.readUShort();
|
objectIndex = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WmfCreatePatternBrush implements HwmfRecord {
|
public static class WmfCreatePatternBrush implements HwmfRecord {
|
||||||
|
|
||||||
HwmfBitmap16 pattern;
|
private HwmfBitmap16 pattern;
|
||||||
|
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.createPatternBrush; }
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.createPatternBrush;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
pattern = new HwmfBitmap16(true);
|
pattern = new HwmfBitmap16(true);
|
||||||
return pattern.init(leis);
|
return pattern.init(leis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WmfCreatePenIndirect implements HwmfRecord {
|
public static class WmfCreatePenIndirect implements HwmfRecord {
|
||||||
|
|
||||||
/**
|
private HwmfPenStyle penStyle;
|
||||||
* A 16-bit unsigned integer that specifies the pen style.
|
|
||||||
* The value MUST be defined from the PenStyle Enumeration table.
|
|
||||||
*
|
|
||||||
* PS_COSMETIC = 0x0000,
|
|
||||||
* PS_ENDCAP_ROUND = 0x0000,
|
|
||||||
* PS_JOIN_ROUND = 0x0000,
|
|
||||||
* PS_SOLID = 0x0000,
|
|
||||||
* PS_DASH = 0x0001,
|
|
||||||
* PS_DOT = 0x0002,
|
|
||||||
* PS_DASHDOT = 0x0003,
|
|
||||||
* PS_DASHDOTDOT = 0x0004,
|
|
||||||
* PS_NULL = 0x0005,
|
|
||||||
* PS_INSIDEFRAME = 0x0006,
|
|
||||||
* PS_USERSTYLE = 0x0007,
|
|
||||||
* PS_ALTERNATE = 0x0008,
|
|
||||||
* PS_ENDCAP_SQUARE = 0x0100,
|
|
||||||
* PS_ENDCAP_FLAT = 0x0200,
|
|
||||||
* PS_JOIN_BEVEL = 0x1000,
|
|
||||||
* PS_JOIN_MITER = 0x2000
|
|
||||||
*/
|
|
||||||
int penStyle;
|
|
||||||
/**
|
/**
|
||||||
* A 32-bit PointS Object that specifies a point for the object dimensions.
|
* A 32-bit PointS Object that specifies a point for the object dimensions.
|
||||||
* The xcoordinate is the pen width. The y-coordinate is ignored.
|
* The xcoordinate is the pen width. The y-coordinate is ignored.
|
||||||
*/
|
*/
|
||||||
int xWidth, yWidth;
|
private int xWidth;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private int yWidth;
|
||||||
/**
|
/**
|
||||||
* A 32-bit ColorRef Object that specifies the pen color value.
|
* A 32-bit ColorRef Object that specifies the pen color value.
|
||||||
*/
|
*/
|
||||||
HwmfColorRef colorRef;
|
private HwmfColorRef colorRef;
|
||||||
|
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.createPenIndirect; }
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.createPenIndirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
penStyle = leis.readUShort();
|
penStyle = HwmfPenStyle.valueOf(leis.readUShort());
|
||||||
xWidth = leis.readShort();
|
xWidth = leis.readShort();
|
||||||
yWidth = leis.readShort();
|
yWidth = leis.readShort();
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
int size = 3*LittleEndianConsts.SHORT_SIZE;
|
int size = colorRef.init(leis);
|
||||||
size += colorRef.init(leis);
|
return size+3*LittleEndianConsts.SHORT_SIZE;
|
||||||
return size;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
HwmfDrawProperties p = ctx.getProperties();
|
||||||
|
p.setPenStyle(penStyle);
|
||||||
|
p.setPenColor(colorRef);
|
||||||
|
p.setPenWidth(xWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_CREATEBRUSHINDIRECT record creates a Brush Object
|
* The META_CREATEBRUSHINDIRECT record creates a Brush Object
|
||||||
* from a LogBrush Object.
|
* from a LogBrush Object.
|
||||||
*
|
*
|
||||||
* The following table shows the relationship between values in the BrushStyle,
|
* The following table shows the relationship between values in the BrushStyle,
|
||||||
* ColorRef and BrushHatch fields in a LogBrush Object. Only supported brush styles are listed.
|
* ColorRef and BrushHatch fields in a LogBrush Object. Only supported brush styles are listed.
|
||||||
*
|
*
|
||||||
* <table>
|
* <table>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <th>BrushStyle</th>
|
* <th>BrushStyle</th>
|
||||||
@ -481,26 +541,37 @@ public class HwmfMisc {
|
|||||||
* </table>
|
* </table>
|
||||||
*/
|
*/
|
||||||
public static class WmfCreateBrushIndirect implements HwmfRecord {
|
public static class WmfCreateBrushIndirect implements HwmfRecord {
|
||||||
HwmfBrushStyle brushStyle;
|
private HwmfBrushStyle brushStyle;
|
||||||
|
|
||||||
HwmfColorRef colorRef;
|
private HwmfColorRef colorRef;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit field that specifies the brush hatch type.
|
* A 16-bit field that specifies the brush hatch type.
|
||||||
* Its interpretation depends on the value of BrushStyle.
|
* Its interpretation depends on the value of BrushStyle.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
HwmfHatchStyle brushHatch;
|
private HwmfHatchStyle brushHatch;
|
||||||
|
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.createBrushIndirect; }
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.createBrushIndirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
brushStyle = HwmfBrushStyle.valueOf(leis.readUShort());
|
brushStyle = HwmfBrushStyle.valueOf(leis.readUShort());
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
int size = colorRef.init(leis);
|
int size = colorRef.init(leis);
|
||||||
brushHatch = HwmfHatchStyle.valueOf(leis.readUShort());
|
brushHatch = HwmfHatchStyle.valueOf(leis.readUShort());
|
||||||
size += 4;
|
return size+2*LittleEndianConsts.SHORT_SIZE;
|
||||||
return size;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
HwmfDrawProperties p = ctx.getProperties();
|
||||||
|
p.setBrushStyle(brushStyle);
|
||||||
|
p.setBrushColor(colorRef);
|
||||||
|
p.setBrushHatch(brushHatch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ package org.apache.poi.hwmf.record;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ public class HwmfPalette {
|
|||||||
// Blue (1 byte): An 8-bit unsigned integer that defines the blue intensity value for the palette entry.
|
// Blue (1 byte): An 8-bit unsigned integer that defines the blue intensity value for the palette entry.
|
||||||
// Green (1 byte): An 8-bit unsigned integer that defines the green intensity value for the palette entry.
|
// Green (1 byte): An 8-bit unsigned integer that defines the green intensity value for the palette entry.
|
||||||
// Red (1 byte): An 8-bit unsigned integer that defines the red intensity value for the palette entry.
|
// Red (1 byte): An 8-bit unsigned integer that defines the red intensity value for the palette entry.
|
||||||
int values, blue, green, red;
|
private int values, blue, green, red;
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis) throws IOException {
|
public int init(LittleEndianInputStream leis) throws IOException {
|
||||||
values = leis.readUByte();
|
values = leis.readUByte();
|
||||||
@ -48,16 +49,17 @@ public class HwmfPalette {
|
|||||||
* used with the META_SETPALENTRIES and META_ANIMATEPALETTE record types.
|
* used with the META_SETPALENTRIES and META_ANIMATEPALETTE record types.
|
||||||
* When used with META_CREATEPALETTE, it MUST be 0x0300
|
* When used with META_CREATEPALETTE, it MUST be 0x0300
|
||||||
*/
|
*/
|
||||||
int start;
|
private int start;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NumberOfEntries (2 bytes): A 16-bit unsigned integer that defines the number of objects in
|
* NumberOfEntries (2 bytes): A 16-bit unsigned integer that defines the number of objects in
|
||||||
* aPaletteEntries.
|
* aPaletteEntries.
|
||||||
*/
|
*/
|
||||||
int numberOfEntries;
|
private int numberOfEntries;
|
||||||
|
|
||||||
PaletteEntry entries[];
|
PaletteEntry entries[];
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
start = leis.readUShort();
|
start = leis.readUShort();
|
||||||
numberOfEntries = leis.readUShort();
|
numberOfEntries = leis.readUShort();
|
||||||
@ -69,15 +71,26 @@ public class HwmfPalette {
|
|||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_CREATEPALETTE record creates a Palette Object
|
* The META_CREATEPALETTE record creates a Palette Object
|
||||||
*/
|
*/
|
||||||
public static class WmfCreatePalette extends WmfPaletteParent {
|
public static class WmfCreatePalette extends WmfPaletteParent {
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.createPalette;
|
return HwmfRecordType.createPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,9 +98,15 @@ public class HwmfPalette {
|
|||||||
* palette that is defined in the playback device context.
|
* palette that is defined in the playback device context.
|
||||||
*/
|
*/
|
||||||
public static class WmfSetPaletteEntries extends WmfPaletteParent {
|
public static class WmfSetPaletteEntries extends WmfPaletteParent {
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setPalEntries;
|
return HwmfRecordType.setPalEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,14 +120,21 @@ public class HwmfPalette {
|
|||||||
*/
|
*/
|
||||||
int numberOfEntries;
|
int numberOfEntries;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.resizePalette;
|
return HwmfRecordType.resizePalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
numberOfEntries = leis.readUShort();
|
numberOfEntries = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -119,16 +145,23 @@ public class HwmfPalette {
|
|||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
||||||
* the Palette Object to be selected.
|
* the Palette Object to be selected.
|
||||||
*/
|
*/
|
||||||
int palette;
|
private int palette;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.selectPalette;
|
return HwmfRecordType.selectPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
palette = leis.readUShort();
|
palette = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,11 +169,20 @@ public class HwmfPalette {
|
|||||||
* is defined in the playback device context to the system palette.
|
* is defined in the playback device context to the system palette.
|
||||||
*/
|
*/
|
||||||
public static class WmfRealizePalette implements HwmfRecord {
|
public static class WmfRealizePalette implements HwmfRecord {
|
||||||
public HwmfRecordType getRecordType() { return HwmfRecordType.realizePalette; }
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.realizePalette;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,8 +198,14 @@ public class HwmfPalette {
|
|||||||
* this record SHOULD have no effect.
|
* this record SHOULD have no effect.
|
||||||
*/
|
*/
|
||||||
public static class WmfAnimatePalette extends WmfPaletteParent {
|
public static class WmfAnimatePalette extends WmfPaletteParent {
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.animatePalette;
|
return HwmfRecordType.animatePalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
171
src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java
Normal file
171
src/scratchpad/src/org/apache/poi/hwmf/record/HwmfPenStyle.java
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/* ====================================================================
|
||||||
|
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.hwmf.record;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
|
||||||
|
import org.apache.poi.util.BitField;
|
||||||
|
import org.apache.poi.util.BitFieldFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 16-bit PenStyle Enumeration is used to specify different types of pens
|
||||||
|
* that can be used in graphics operations.
|
||||||
|
*
|
||||||
|
* Various styles can be combined by using a logical OR statement, one from
|
||||||
|
* each subsection of Style, EndCap, Join, and Type (Cosmetic).
|
||||||
|
*
|
||||||
|
* The defaults in case the other values of the subsection aren't set are
|
||||||
|
* solid, round end caps, round joins and cosmetic type.
|
||||||
|
*/
|
||||||
|
public class HwmfPenStyle {
|
||||||
|
public enum HwmfLineCap {
|
||||||
|
/** Rounded ends */
|
||||||
|
ROUND(0, BasicStroke.CAP_ROUND),
|
||||||
|
/** Square protrudes by half line width */
|
||||||
|
SQUARE(1, BasicStroke.CAP_SQUARE),
|
||||||
|
/** Line ends at end point*/
|
||||||
|
FLAT(2, BasicStroke.CAP_BUTT);
|
||||||
|
|
||||||
|
public int wmfFlag;
|
||||||
|
public int awtFlag;
|
||||||
|
HwmfLineCap(int wmfFlag, int awtFlag) {
|
||||||
|
this.wmfFlag = wmfFlag;
|
||||||
|
this.awtFlag = awtFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HwmfLineCap valueOf(int wmfFlag) {
|
||||||
|
for (HwmfLineCap hs : values()) {
|
||||||
|
if (hs.wmfFlag == wmfFlag) return hs;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum HwmfLineJoin {
|
||||||
|
/**Line joins are round. */
|
||||||
|
ROUND(0, BasicStroke.JOIN_ROUND),
|
||||||
|
/** Line joins are beveled. */
|
||||||
|
BEVEL(1, BasicStroke.JOIN_BEVEL),
|
||||||
|
/**
|
||||||
|
* Line joins are mitered when they are within the current limit set by the
|
||||||
|
* SETMITERLIMIT META_ESCAPE record. A join is beveled when it would exceed the limit
|
||||||
|
*/
|
||||||
|
MITER(2, BasicStroke.JOIN_MITER);
|
||||||
|
|
||||||
|
public int wmfFlag;
|
||||||
|
public int awtFlag;
|
||||||
|
HwmfLineJoin(int wmfFlag, int awtFlag) {
|
||||||
|
this.wmfFlag = wmfFlag;
|
||||||
|
this.awtFlag = awtFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HwmfLineJoin valueOf(int wmfFlag) {
|
||||||
|
for (HwmfLineJoin hs : values()) {
|
||||||
|
if (hs.wmfFlag == wmfFlag) return hs;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum HwmfLineDash {
|
||||||
|
/**
|
||||||
|
* The pen is solid.
|
||||||
|
*/
|
||||||
|
SOLID(0x0000, 10),
|
||||||
|
/**
|
||||||
|
* The pen is dashed. (-----)
|
||||||
|
*/
|
||||||
|
DASH(0x0001, 10, 8),
|
||||||
|
/**
|
||||||
|
* The pen is dotted. (.....)
|
||||||
|
*/
|
||||||
|
DOT(0x0002, 2, 4),
|
||||||
|
/**
|
||||||
|
* The pen has alternating dashes and dots. (_._._._)
|
||||||
|
*/
|
||||||
|
DASHDOT(0x0003, 10, 8, 2, 8),
|
||||||
|
/**
|
||||||
|
* The pen has dashes and double dots. (_.._.._)
|
||||||
|
*/
|
||||||
|
DASHDOTDOT(0x0004, 10, 4, 2, 4, 2, 4),
|
||||||
|
/**
|
||||||
|
* The pen is invisible.
|
||||||
|
*/
|
||||||
|
NULL(0x0005),
|
||||||
|
/**
|
||||||
|
* The pen is solid. When this pen is used in any drawing record that takes a
|
||||||
|
* bounding rectangle, the dimensions of the figure are shrunk so that it fits
|
||||||
|
* entirely in the bounding rectangle, taking into account the width of the pen.
|
||||||
|
*/
|
||||||
|
INSIDEFRAME(0x0006, 10),
|
||||||
|
/**
|
||||||
|
* The pen uses a styling array supplied by the user.
|
||||||
|
* (this is currently not supported and drawn as solid ... no idea where the user
|
||||||
|
* styling is supposed to come from ...)
|
||||||
|
*/
|
||||||
|
USERSTYLE(0x0007, 10);
|
||||||
|
|
||||||
|
|
||||||
|
public int wmfFlag;
|
||||||
|
public float[] dashes;
|
||||||
|
HwmfLineDash(int wmfFlag, float... dashes) {
|
||||||
|
this.wmfFlag = wmfFlag;
|
||||||
|
this.dashes = dashes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HwmfLineDash valueOf(int wmfFlag) {
|
||||||
|
for (HwmfLineDash hs : values()) {
|
||||||
|
if (hs.wmfFlag == wmfFlag) return hs;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final BitField SUBSECTION_DASH = BitFieldFactory.getInstance(0x0007);
|
||||||
|
private static final BitField SUBSECTION_ALTERNATE = BitFieldFactory.getInstance(0x0008);
|
||||||
|
private static final BitField SUBSECTION_ENDCAP = BitFieldFactory.getInstance(0x0300);
|
||||||
|
private static final BitField SUBSECTION_JOIN = BitFieldFactory.getInstance(0x3000);
|
||||||
|
|
||||||
|
private int flag;
|
||||||
|
|
||||||
|
public static HwmfPenStyle valueOf(int flag) {
|
||||||
|
HwmfPenStyle ps = new HwmfPenStyle();
|
||||||
|
ps.flag = flag;
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfLineCap getLineCap() {
|
||||||
|
return HwmfLineCap.valueOf(SUBSECTION_ENDCAP.getValue(flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfLineJoin getLineJoin() {
|
||||||
|
return HwmfLineJoin.valueOf(SUBSECTION_JOIN.getValue(flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
public HwmfLineDash getLineDash() {
|
||||||
|
return HwmfLineDash.valueOf(SUBSECTION_DASH.getValue(flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The pen sets every other pixel (this style is applicable only for cosmetic pens).
|
||||||
|
*/
|
||||||
|
public boolean isAlternateDash() {
|
||||||
|
return SUBSECTION_ALTERNATE.isSet(flag);
|
||||||
|
}
|
||||||
|
}
|
@ -19,6 +19,7 @@ package org.apache.poi.hwmf.record;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
public interface HwmfRecord {
|
public interface HwmfRecord {
|
||||||
@ -32,4 +33,11 @@ public interface HwmfRecord {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException;
|
int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the record settings to the graphics context
|
||||||
|
*
|
||||||
|
* @param ctx the graphics context to modify
|
||||||
|
*/
|
||||||
|
void draw(HwmfGraphics ctx);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ public enum HwmfTernaryRasterOp {
|
|||||||
this.opCmd=opCmd;
|
this.opCmd=opCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HwmfTernaryRasterOp fromOpIndex(int opIndex) {
|
public static HwmfTernaryRasterOp valueOf(int opIndex) {
|
||||||
for (HwmfTernaryRasterOp bb : HwmfTernaryRasterOp.values()) {
|
for (HwmfTernaryRasterOp bb : HwmfTernaryRasterOp.values()) {
|
||||||
if (bb.opIndex == opIndex) {
|
if (bb.opIndex == opIndex) {
|
||||||
return bb;
|
return bb;
|
||||||
|
@ -19,9 +19,12 @@ package org.apache.poi.hwmf.record;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
|
import org.apache.poi.hwmf.record.HwmfMisc.WmfSetMapMode;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
import org.apache.poi.util.LocaleUtil;
|
||||||
|
import org.apache.poi.util.RecordFormatException;
|
||||||
|
|
||||||
public class HwmfText {
|
public class HwmfText {
|
||||||
|
|
||||||
@ -38,16 +41,23 @@ public class HwmfText {
|
|||||||
* this value is transformed and rounded to the nearest pixel. For details about setting the
|
* this value is transformed and rounded to the nearest pixel. For details about setting the
|
||||||
* mapping mode, see META_SETMAPMODE
|
* mapping mode, see META_SETMAPMODE
|
||||||
*/
|
*/
|
||||||
int charExtra;
|
private int charExtra;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setTextCharExtra;
|
return HwmfRecordType.setTextCharExtra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
charExtra = leis.readUShort();
|
charExtra = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,16 +65,23 @@ public class HwmfText {
|
|||||||
*/
|
*/
|
||||||
public static class WmfSetTextColor implements HwmfRecord {
|
public static class WmfSetTextColor implements HwmfRecord {
|
||||||
|
|
||||||
HwmfColorRef colorRef;
|
private HwmfColorRef colorRef;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setTextColor;
|
return HwmfRecordType.setTextColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
colorRef = new HwmfColorRef();
|
colorRef = new HwmfColorRef();
|
||||||
return colorRef.init(leis);
|
return colorRef.init(leis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,7 +93,7 @@ public class HwmfText {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that specifies the number of space characters in the line.
|
* A 16-bit unsigned integer that specifies the number of space characters in the line.
|
||||||
*/
|
*/
|
||||||
int breakCount;
|
private int breakCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that specifies the total extra space, in logical
|
* A 16-bit unsigned integer that specifies the total extra space, in logical
|
||||||
@ -84,17 +101,24 @@ public class HwmfText {
|
|||||||
* identified by the BreakExtra member is transformed and rounded to the nearest pixel. For
|
* identified by the BreakExtra member is transformed and rounded to the nearest pixel. For
|
||||||
* details about setting the mapping mode, see {@link WmfSetMapMode}.
|
* details about setting the mapping mode, see {@link WmfSetMapMode}.
|
||||||
*/
|
*/
|
||||||
int breakExtra;
|
private int breakExtra;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setBkColor;
|
return HwmfRecordType.setBkColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
breakCount = leis.readUShort();
|
breakCount = leis.readUShort();
|
||||||
breakExtra = leis.readUShort();
|
breakExtra = leis.readUShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,7 +129,7 @@ public class HwmfText {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the length of the string, in bytes, pointed to by String.
|
* A 16-bit signed integer that defines the length of the string, in bytes, pointed to by String.
|
||||||
*/
|
*/
|
||||||
int stringLength;
|
private int stringLength;
|
||||||
/**
|
/**
|
||||||
* The size of this field MUST be a multiple of two. If StringLength is an odd
|
* The size of this field MUST be a multiple of two. If StringLength is an odd
|
||||||
* number, then this field MUST be of a size greater than or equal to StringLength + 1.
|
* number, then this field MUST be of a size greater than or equal to StringLength + 1.
|
||||||
@ -114,31 +138,38 @@ public class HwmfText {
|
|||||||
* length of the string.
|
* length of the string.
|
||||||
* The string is written at the location specified by the XStart and YStart fields.
|
* The string is written at the location specified by the XStart and YStart fields.
|
||||||
*/
|
*/
|
||||||
String text;
|
private String text;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the vertical (y-axis) coordinate, in logical
|
* A 16-bit signed integer that defines the vertical (y-axis) coordinate, in logical
|
||||||
* units, of the point where drawing is to start.
|
* units, of the point where drawing is to start.
|
||||||
*/
|
*/
|
||||||
int yStart;
|
private int yStart;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal (x-axis) coordinate, in
|
* A 16-bit signed integer that defines the horizontal (x-axis) coordinate, in
|
||||||
* logical units, of the point where drawing is to start.
|
* logical units, of the point where drawing is to start.
|
||||||
*/
|
*/
|
||||||
int xStart;
|
private int xStart;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.textOut;
|
return HwmfRecordType.textOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
stringLength = leis.readShort();
|
stringLength = leis.readShort();
|
||||||
byte buf[] = new byte[stringLength+(stringLength%2)];
|
byte buf[] = new byte[stringLength+(stringLength&1)];
|
||||||
leis.readFully(buf);
|
leis.readFully(buf);
|
||||||
text = new String(buf, "UTF16-LE").trim();
|
text = new String(buf, 0, stringLength, LocaleUtil.CHARSET_1252).trim();
|
||||||
yStart = leis.readShort();
|
yStart = leis.readShort();
|
||||||
xStart = leis.readShort();
|
xStart = leis.readShort();
|
||||||
return 3*LittleEndianConsts.SHORT_SIZE+buf.length;
|
return 3*LittleEndianConsts.SHORT_SIZE+buf.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,16 +183,16 @@ public class HwmfText {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, where the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, where the
|
||||||
text string is to be located.
|
text string is to be located.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, where the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, where the
|
||||||
text string is to be located.
|
text string is to be located.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the length of the string.
|
* A 16-bit signed integer that defines the length of the string.
|
||||||
*/
|
*/
|
||||||
int stringLength;
|
private int stringLength;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the use of the application-defined
|
* A 16-bit unsigned integer that defines the use of the application-defined
|
||||||
* rectangle. This member can be a combination of one or more values in the
|
* rectangle. This member can be a combination of one or more values in the
|
||||||
@ -196,7 +227,7 @@ public class HwmfText {
|
|||||||
* Indicates that both horizontal and vertical character displacement values
|
* Indicates that both horizontal and vertical character displacement values
|
||||||
* SHOULD be provided.
|
* SHOULD be provided.
|
||||||
*/
|
*/
|
||||||
int fwOpts;
|
private int fwOpts;
|
||||||
/**
|
/**
|
||||||
* An optional 8-byte Rect Object (section 2.2.2.18) that defines the
|
* An optional 8-byte Rect Object (section 2.2.2.18) that defines the
|
||||||
* dimensions, in logical coordinates, of a rectangle that is used for clipping, opaquing, or both.
|
* dimensions, in logical coordinates, of a rectangle that is used for clipping, opaquing, or both.
|
||||||
@ -205,43 +236,58 @@ public class HwmfText {
|
|||||||
* Each value is a 16-bit signed integer that defines the coordinate, in logical coordinates, of
|
* Each value is a 16-bit signed integer that defines the coordinate, in logical coordinates, of
|
||||||
* the upper-left corner of the rectangle
|
* the upper-left corner of the rectangle
|
||||||
*/
|
*/
|
||||||
int left,top,right,bottom;
|
private int left,top,right,bottom;
|
||||||
/**
|
/**
|
||||||
* A variable-length string that specifies the text to be drawn. The string does
|
* A variable-length string that specifies the text to be drawn. The string does
|
||||||
* not need to be null-terminated, because StringLength specifies the length of the string. If
|
* not need to be null-terminated, because StringLength specifies the length of the string. If
|
||||||
* the length is odd, an extra byte is placed after it so that the following member (optional Dx) is
|
* the length is odd, an extra byte is placed after it so that the following member (optional Dx) is
|
||||||
* aligned on a 16-bit boundary.
|
* aligned on a 16-bit boundary.
|
||||||
*/
|
*/
|
||||||
String text;
|
private String text;
|
||||||
/**
|
/**
|
||||||
* An optional array of 16-bit signed integers that indicate the distance between
|
* An optional array of 16-bit signed integers that indicate the distance between
|
||||||
* origins of adjacent character cells. For example, Dx[i] logical units separate the origins of
|
* origins of adjacent character cells. For example, Dx[i] logical units separate the origins of
|
||||||
* character cell i and character cell i + 1. If this field is present, there MUST be the same
|
* character cell i and character cell i + 1. If this field is present, there MUST be the same
|
||||||
* number of values as there are characters in the string.
|
* number of values as there are characters in the string.
|
||||||
*/
|
*/
|
||||||
int dx[];
|
private int dx[];
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.extTextOut;
|
return HwmfRecordType.extTextOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
y = leis.readShort();
|
||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
stringLength = leis.readShort();
|
stringLength = leis.readShort();
|
||||||
fwOpts = leis.readUShort();
|
fwOpts = leis.readUShort();
|
||||||
left = leis.readShort();
|
|
||||||
top = leis.readShort();
|
|
||||||
right = leis.readShort();
|
|
||||||
bottom = leis.readShort();
|
|
||||||
|
|
||||||
byte buf[] = new byte[stringLength+(stringLength%2)];
|
int size = 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
|
|
||||||
|
if (fwOpts != 0) {
|
||||||
|
// the bounding rectangle is optional and only read when fwOpts are given
|
||||||
|
left = leis.readShort();
|
||||||
|
top = leis.readShort();
|
||||||
|
right = leis.readShort();
|
||||||
|
bottom = leis.readShort();
|
||||||
|
size += 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte buf[] = new byte[stringLength+(stringLength&1)];
|
||||||
leis.readFully(buf);
|
leis.readFully(buf);
|
||||||
text = new String(buf, "UTF16-LE");
|
text = new String(buf, 0, stringLength, LocaleUtil.CHARSET_1252);
|
||||||
|
size += buf.length;
|
||||||
|
|
||||||
int size = 8*LittleEndianConsts.SHORT_SIZE+buf.length;
|
// -6 bytes of record function and length header
|
||||||
if (size < recordSize) {
|
int remainingRecordSize = (int)(recordSize-6);
|
||||||
dx = new int[text.length()];
|
if (size < remainingRecordSize) {
|
||||||
|
if (size + stringLength*LittleEndianConsts.SHORT_SIZE < remainingRecordSize) {
|
||||||
|
throw new RecordFormatException("can't read Dx array - given recordSize doesn't contain enough values for string length "+stringLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
dx = new int[stringLength];
|
||||||
for (int i=0; i<dx.length; i++) {
|
for (int i=0; i<dx.length; i++) {
|
||||||
dx[i] = leis.readShort();
|
dx[i] = leis.readShort();
|
||||||
}
|
}
|
||||||
@ -250,6 +296,11 @@ public class HwmfText {
|
|||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -320,28 +371,42 @@ public class HwmfText {
|
|||||||
* VTA_BASELINE (0x0018):
|
* VTA_BASELINE (0x0018):
|
||||||
* The reference point MUST be on the baseline of the text.
|
* The reference point MUST be on the baseline of the text.
|
||||||
*/
|
*/
|
||||||
int textAlignmentMode;
|
private int textAlignmentMode;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setTextAlign;
|
return HwmfRecordType.setTextAlign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
textAlignmentMode = leis.readUShort();
|
textAlignmentMode = leis.readUShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WmfCreateFontIndirect implements HwmfRecord {
|
public static class WmfCreateFontIndirect implements HwmfRecord {
|
||||||
HwmfFont font;
|
private HwmfFont font;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.createFontIndirect;
|
return HwmfRecordType.createFontIndirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
font = new HwmfFont();
|
font = new HwmfFont();
|
||||||
return font.init(leis);
|
return font.init(leis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,43 +17,17 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwmf.record;
|
package org.apache.poi.hwmf.record;
|
||||||
|
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.poi.hwmf.draw.HwmfGraphics;
|
||||||
import org.apache.poi.util.LittleEndianConsts;
|
import org.apache.poi.util.LittleEndianConsts;
|
||||||
import org.apache.poi.util.LittleEndianInputStream;
|
import org.apache.poi.util.LittleEndianInputStream;
|
||||||
|
|
||||||
public class HwmfWindowing {
|
public class HwmfWindowing {
|
||||||
|
|
||||||
/**
|
|
||||||
* The META_OFFSETCLIPRGN record moves the clipping region in the playback device context by the
|
|
||||||
* specified offsets.
|
|
||||||
*/
|
|
||||||
public static class WmfOffsetClipRgn implements HwmfRecord {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A 16-bit signed integer that defines the number of logical units to move up or down.
|
|
||||||
*/
|
|
||||||
int yOffset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A 16-bit signed integer that defines the number of logical units to move left or right.
|
|
||||||
*/
|
|
||||||
int xOffset;
|
|
||||||
|
|
||||||
public HwmfRecordType getRecordType() {
|
|
||||||
return HwmfRecordType.offsetClipRgn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
|
||||||
yOffset = leis.readShort();
|
|
||||||
xOffset = leis.readShort();
|
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_SETVIEWPORTORG record defines the viewport origin in the playback device context.
|
* The META_SETVIEWPORTORG record defines the viewport origin in the playback device context.
|
||||||
*/
|
*/
|
||||||
@ -62,22 +36,29 @@ public class HwmfWindowing {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the vertical offset, in device units.
|
* A 16-bit signed integer that defines the vertical offset, in device units.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal offset, in device units.
|
* A 16-bit signed integer that defines the horizontal offset, in device units.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setViewportOrg;
|
return HwmfRecordType.setViewportOrg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
y = leis.readShort();
|
||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setViewportOrg(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,23 +71,30 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit signed integer that defines the vertical extent
|
* A 16-bit signed integer that defines the vertical extent
|
||||||
* of the viewport in device units.
|
* of the viewport in device units.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int height;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal extent
|
* A 16-bit signed integer that defines the horizontal extent
|
||||||
* of the viewport in device units.
|
* of the viewport in device units.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int width;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setViewportExt;
|
return HwmfRecordType.setViewportExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
height = leis.readShort();
|
||||||
x = leis.readShort();
|
width = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setViewportExt(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,22 +106,30 @@ public class HwmfWindowing {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the vertical offset, in device units.
|
* A 16-bit signed integer that defines the vertical offset, in device units.
|
||||||
*/
|
*/
|
||||||
int yOffset;
|
private int yOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal offset, in device units.
|
* A 16-bit signed integer that defines the horizontal offset, in device units.
|
||||||
*/
|
*/
|
||||||
int xOffset;
|
private int xOffset;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.offsetViewportOrg;
|
return HwmfRecordType.offsetViewportOrg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yOffset = leis.readShort();
|
yOffset = leis.readShort();
|
||||||
xOffset = leis.readShort();
|
xOffset = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
Rectangle2D viewport = ctx.getProperties().getViewport();
|
||||||
|
ctx.getProperties().setViewportOrg(viewport.getX()+xOffset, viewport.getY()+yOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,22 +140,29 @@ public class HwmfWindowing {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units.
|
* A 16-bit signed integer that defines the y-coordinate, in logical units.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int y;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units.
|
* A 16-bit signed integer that defines the x-coordinate, in logical units.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int x;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setWindowOrg;
|
return HwmfRecordType.setWindowOrg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
y = leis.readShort();
|
||||||
x = leis.readShort();
|
x = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setWindowOrg(x, y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,23 +175,30 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit signed integer that defines the vertical extent of
|
* A 16-bit signed integer that defines the vertical extent of
|
||||||
* the window in logical units.
|
* the window in logical units.
|
||||||
*/
|
*/
|
||||||
int y;
|
private int height;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal extent of
|
* A 16-bit signed integer that defines the horizontal extent of
|
||||||
* the window in logical units.
|
* the window in logical units.
|
||||||
*/
|
*/
|
||||||
int x;
|
private int width;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.setWindowExt;
|
return HwmfRecordType.setWindowExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
y = leis.readShort();
|
height = leis.readShort();
|
||||||
x = leis.readShort();
|
width = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
ctx.getProperties().setWindowExt(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -200,22 +210,30 @@ public class HwmfWindowing {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the vertical offset, in device units.
|
* A 16-bit signed integer that defines the vertical offset, in device units.
|
||||||
*/
|
*/
|
||||||
int yOffset;
|
private int yOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the horizontal offset, in device units.
|
* A 16-bit signed integer that defines the horizontal offset, in device units.
|
||||||
*/
|
*/
|
||||||
int xOffset;
|
private int xOffset;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.offsetWindowOrg;
|
return HwmfRecordType.offsetWindowOrg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yOffset = leis.readShort();
|
yOffset = leis.readShort();
|
||||||
xOffset = leis.readShort();
|
xOffset = leis.readShort();
|
||||||
return 2*LittleEndianConsts.SHORT_SIZE;
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
Rectangle2D window = ctx.getProperties().getWindow();
|
||||||
|
ctx.getProperties().setWindowOrg(window.getX()+xOffset, window.getY()+yOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,30 +246,32 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit signed integer that defines the amount by which to divide the
|
* A 16-bit signed integer that defines the amount by which to divide the
|
||||||
* result of multiplying the current y-extent by the value of the yNum member.
|
* result of multiplying the current y-extent by the value of the yNum member.
|
||||||
*/
|
*/
|
||||||
int yDenom;
|
private int yDenom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the amount by which to multiply the
|
* A 16-bit signed integer that defines the amount by which to multiply the
|
||||||
* current y-extent.
|
* current y-extent.
|
||||||
*/
|
*/
|
||||||
int yNum;
|
private int yNum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the amount by which to divide the
|
* A 16-bit signed integer that defines the amount by which to divide the
|
||||||
* result of multiplying the current x-extent by the value of the xNum member.
|
* result of multiplying the current x-extent by the value of the xNum member.
|
||||||
*/
|
*/
|
||||||
int xDenom;
|
private int xDenom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the amount by which to multiply the
|
* A 16-bit signed integer that defines the amount by which to multiply the
|
||||||
* current x-extent.
|
* current x-extent.
|
||||||
*/
|
*/
|
||||||
int xNum;
|
private int xNum;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.scaleWindowExt;
|
return HwmfRecordType.scaleWindowExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yDenom = leis.readShort();
|
yDenom = leis.readShort();
|
||||||
yNum = leis.readShort();
|
yNum = leis.readShort();
|
||||||
@ -259,6 +279,14 @@ public class HwmfWindowing {
|
|||||||
xNum = leis.readShort();
|
xNum = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
Rectangle2D window = ctx.getProperties().getWindow();
|
||||||
|
double width = window.getWidth() * xNum / xDenom;
|
||||||
|
double height = window.getHeight() * yNum / yDenom;
|
||||||
|
ctx.getProperties().setWindowExt(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -273,30 +301,32 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit signed integer that defines the amount by which to divide the
|
* A 16-bit signed integer that defines the amount by which to divide the
|
||||||
* result of multiplying the current y-extent by the value of the yNum member.
|
* result of multiplying the current y-extent by the value of the yNum member.
|
||||||
*/
|
*/
|
||||||
int yDenom;
|
private int yDenom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the amount by which to multiply the
|
* A 16-bit signed integer that defines the amount by which to multiply the
|
||||||
* current y-extent.
|
* current y-extent.
|
||||||
*/
|
*/
|
||||||
int yNum;
|
private int yNum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the amount by which to divide the
|
* A 16-bit signed integer that defines the amount by which to divide the
|
||||||
* result of multiplying the current x-extent by the value of the xNum member.
|
* result of multiplying the current x-extent by the value of the xNum member.
|
||||||
*/
|
*/
|
||||||
int xDenom;
|
private int xDenom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the amount by which to multiply the
|
* A 16-bit signed integer that defines the amount by which to multiply the
|
||||||
* current x-extent.
|
* current x-extent.
|
||||||
*/
|
*/
|
||||||
int xNum;
|
private int xNum;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.scaleViewportExt;
|
return HwmfRecordType.scaleViewportExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
yDenom = leis.readShort();
|
yDenom = leis.readShort();
|
||||||
yNum = leis.readShort();
|
yNum = leis.readShort();
|
||||||
@ -304,6 +334,48 @@ public class HwmfWindowing {
|
|||||||
xNum = leis.readShort();
|
xNum = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
Rectangle2D viewport = ctx.getProperties().getViewport();
|
||||||
|
double width = viewport.getWidth() * xNum / xDenom;
|
||||||
|
double height = viewport.getHeight() * yNum / yDenom;
|
||||||
|
ctx.getProperties().setViewportExt(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The META_OFFSETCLIPRGN record moves the clipping region in the playback device context by the
|
||||||
|
* specified offsets.
|
||||||
|
*/
|
||||||
|
public static class WmfOffsetClipRgn implements HwmfRecord {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 16-bit signed integer that defines the number of logical units to move up or down.
|
||||||
|
*/
|
||||||
|
private int yOffset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 16-bit signed integer that defines the number of logical units to move left or right.
|
||||||
|
*/
|
||||||
|
private int xOffset;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HwmfRecordType getRecordType() {
|
||||||
|
return HwmfRecordType.offsetClipRgn;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
|
yOffset = leis.readShort();
|
||||||
|
xOffset = leis.readShort();
|
||||||
|
return 2*LittleEndianConsts.SHORT_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,30 +388,32 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* lower-right corner of the rectangle.
|
* lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int bottom;
|
private int bottom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* lower-right corner of the rectangle.
|
* lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int right;
|
private int right;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int top;
|
private int top;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int left;
|
private int left;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.excludeClipRect;
|
return HwmfRecordType.excludeClipRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
bottom = leis.readShort();
|
bottom = leis.readShort();
|
||||||
right = leis.readShort();
|
right = leis.readShort();
|
||||||
@ -347,6 +421,11 @@ public class HwmfWindowing {
|
|||||||
left = leis.readShort();
|
left = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -360,30 +439,32 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* lower-right corner of the rectangle.
|
* lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int bottom;
|
private int bottom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* lower-right corner of the rectangle.
|
* lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int right;
|
private int right;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int top;
|
private int top;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int left;
|
private int left;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.intersectClipRect;
|
return HwmfRecordType.intersectClipRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
bottom = leis.readShort();
|
bottom = leis.readShort();
|
||||||
right = leis.readShort();
|
right = leis.readShort();
|
||||||
@ -391,11 +472,15 @@ public class HwmfWindowing {
|
|||||||
left = leis.readShort();
|
left = leis.readShort();
|
||||||
return 4*LittleEndianConsts.SHORT_SIZE;
|
return 4*LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The META_INTERSECTCLIPRECT record sets the clipping region in the playback device context to the
|
* The META_SELECTCLIPREGION record specifies a Region Object to be the current clipping region.
|
||||||
* intersection of the existing clipping region and the specified rectangle.
|
|
||||||
*/
|
*/
|
||||||
public static class WmfSelectClipRegion implements HwmfRecord {
|
public static class WmfSelectClipRegion implements HwmfRecord {
|
||||||
|
|
||||||
@ -403,16 +488,23 @@ public class HwmfWindowing {
|
|||||||
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
* A 16-bit unsigned integer used to index into the WMF Object Table to get
|
||||||
* the region to be clipped.
|
* the region to be clipped.
|
||||||
*/
|
*/
|
||||||
int region;
|
private int region;
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.selectClipRegion;
|
return HwmfRecordType.selectClipRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
region = leis.readShort();
|
region = leis.readShort();
|
||||||
return LittleEndianConsts.SHORT_SIZE;
|
return LittleEndianConsts.SHORT_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class WmfScanObject {
|
public static class WmfScanObject {
|
||||||
@ -421,30 +513,30 @@ public class HwmfWindowing {
|
|||||||
* coordinates in the ScanLines array. This value MUST be a multiple of 2, since left and right
|
* coordinates in the ScanLines array. This value MUST be a multiple of 2, since left and right
|
||||||
* endpoints are required to specify each scanline.
|
* endpoints are required to specify each scanline.
|
||||||
*/
|
*/
|
||||||
int count;
|
private int count;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the top scanline.
|
* A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the top scanline.
|
||||||
*/
|
*/
|
||||||
int top;
|
private int top;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the bottom scanline.
|
* A 16-bit unsigned integer that defines the vertical (y-axis) coordinate, in logical units, of the bottom scanline.
|
||||||
*/
|
*/
|
||||||
int bottom;
|
private int bottom;
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
|
* A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
|
||||||
* in logical units, of the left endpoint of the scanline.
|
* in logical units, of the left endpoint of the scanline.
|
||||||
*/
|
*/
|
||||||
int left_scanline[];
|
private int left_scanline[];
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
|
* A 16-bit unsigned integer that defines the horizontal (x-axis) coordinate,
|
||||||
* in logical units, of the right endpoint of the scanline.
|
* in logical units, of the right endpoint of the scanline.
|
||||||
*/
|
*/
|
||||||
int right_scanline[];
|
private int right_scanline[];
|
||||||
/**
|
/**
|
||||||
* A 16-bit unsigned integer that MUST be the same as the value of the Count
|
* A 16-bit unsigned integer that MUST be the same as the value of the Count
|
||||||
* field; it is present to allow upward travel in the structure.
|
* field; it is present to allow upward travel in the structure.
|
||||||
*/
|
*/
|
||||||
int count2;
|
private int count2;
|
||||||
|
|
||||||
public int init(LittleEndianInputStream leis) {
|
public int init(LittleEndianInputStream leis) {
|
||||||
count = leis.readUShort();
|
count = leis.readUShort();
|
||||||
@ -465,62 +557,64 @@ public class HwmfWindowing {
|
|||||||
/**
|
/**
|
||||||
* A 16-bit signed integer. A value that MUST be ignored.
|
* A 16-bit signed integer. A value that MUST be ignored.
|
||||||
*/
|
*/
|
||||||
int nextInChain;
|
private int nextInChain;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that specifies the region identifier. It MUST be 0x0006.
|
* A 16-bit signed integer that specifies the region identifier. It MUST be 0x0006.
|
||||||
*/
|
*/
|
||||||
int objectType;
|
private int objectType;
|
||||||
/**
|
/**
|
||||||
* A 32-bit unsigned integer. A value that MUST be ignored.
|
* A 32-bit unsigned integer. A value that MUST be ignored.
|
||||||
*/
|
*/
|
||||||
int objectCount;
|
private int objectCount;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the size of the region in bytes plus the size of aScans in bytes.
|
* A 16-bit signed integer that defines the size of the region in bytes plus the size of aScans in bytes.
|
||||||
*/
|
*/
|
||||||
int regionSize;
|
private int regionSize;
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the number of scanlines composing the region.
|
* A 16-bit signed integer that defines the number of scanlines composing the region.
|
||||||
*/
|
*/
|
||||||
int scanCount;
|
private int scanCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the maximum number of points in any one scan in this region.
|
* A 16-bit signed integer that defines the maximum number of points in any one scan in this region.
|
||||||
*/
|
*/
|
||||||
int maxScan;
|
private int maxScan;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* lower-right corner of the rectangle.
|
* lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int bottom;
|
private int bottom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* lower-right corner of the rectangle.
|
* lower-right corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int right;
|
private int right;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the y-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int top;
|
private int top;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
* A 16-bit signed integer that defines the x-coordinate, in logical units, of the
|
||||||
* upper-left corner of the rectangle.
|
* upper-left corner of the rectangle.
|
||||||
*/
|
*/
|
||||||
int left;
|
private int left;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of Scan objects that define the scanlines in the region.
|
* An array of Scan objects that define the scanlines in the region.
|
||||||
*/
|
*/
|
||||||
WmfScanObject scanObjects[];
|
private WmfScanObject scanObjects[];
|
||||||
|
|
||||||
|
@Override
|
||||||
public HwmfRecordType getRecordType() {
|
public HwmfRecordType getRecordType() {
|
||||||
return HwmfRecordType.createRegion;
|
return HwmfRecordType.createRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
|
||||||
nextInChain = leis.readShort();
|
nextInChain = leis.readShort();
|
||||||
objectType = leis.readShort();
|
objectType = leis.readShort();
|
||||||
@ -545,5 +639,10 @@ public class HwmfWindowing {
|
|||||||
|
|
||||||
return 20 + size;
|
return 20 + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(HwmfGraphics ctx) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package org.apache.poi.hwmf.usermodel;
|
package org.apache.poi.hwmf.usermodel;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -37,7 +39,8 @@ public class HwmfPicture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public HwmfPicture(InputStream inputStream) throws IOException {
|
public HwmfPicture(InputStream inputStream) throws IOException {
|
||||||
LittleEndianInputStream leis = new LittleEndianInputStream(inputStream);
|
BufferedInputStream bis = new BufferedInputStream(inputStream, 10000);
|
||||||
|
LittleEndianInputStream leis = new LittleEndianInputStream(bis);
|
||||||
HwmfPlaceableHeader placeableHeader = HwmfPlaceableHeader.readHeader(leis);
|
HwmfPlaceableHeader placeableHeader = HwmfPlaceableHeader.readHeader(leis);
|
||||||
HwmfHeader header = new HwmfHeader(leis);
|
HwmfHeader header = new HwmfHeader(leis);
|
||||||
|
|
||||||
@ -65,8 +68,15 @@ public class HwmfPicture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
consumedSize += wr.init(leis, recordSize, recordFunction);
|
consumedSize += wr.init(leis, recordSize, recordFunction);
|
||||||
if (consumedSize < recordSize) {
|
int remainingSize = (int)(recordSize - consumedSize);
|
||||||
leis.skip(recordSize - consumedSize);
|
assert(remainingSize >= 0);
|
||||||
|
if (remainingSize > 0) {
|
||||||
|
byte remaining[] = new byte[remainingSize];
|
||||||
|
leis.read(remaining);
|
||||||
|
FileOutputStream fos = new FileOutputStream("remaining.dat");
|
||||||
|
fos.write(remaining);
|
||||||
|
fos.close();
|
||||||
|
// leis.skip(remainingSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,27 @@ package org.apache.poi.hwmf;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.apache.poi.POIDataSamples;
|
import org.apache.poi.POIDataSamples;
|
||||||
|
import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
|
||||||
import org.apache.poi.hwmf.record.HwmfRecord;
|
import org.apache.poi.hwmf.record.HwmfRecord;
|
||||||
import org.apache.poi.hwmf.usermodel.HwmfPicture;
|
import org.apache.poi.hwmf.usermodel.HwmfPicture;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData;
|
||||||
|
import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
||||||
|
import org.apache.poi.sl.usermodel.SlideShow;
|
||||||
|
import org.apache.poi.sl.usermodel.SlideShowFactory;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TestHwmfParsing {
|
public class TestHwmfParsing {
|
||||||
@ -39,4 +52,58 @@ public class TestHwmfParsing {
|
|||||||
List<HwmfRecord> records = wmf.getRecords();
|
List<HwmfRecord> records = wmf.getRecords();
|
||||||
assertEquals(581, records.size());
|
assertEquals(581, records.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void extract() throws IOException {
|
||||||
|
File dir = new File("test-data/slideshow");
|
||||||
|
File files[] = dir.listFiles(new FileFilter() {
|
||||||
|
public boolean accept(File pathname) {
|
||||||
|
return pathname.getName().matches("(?i).*\\.pptx?$");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
boolean outputFiles = false;
|
||||||
|
|
||||||
|
File outdir = new File("build/ppt");
|
||||||
|
if (outputFiles) {
|
||||||
|
outdir.mkdirs();
|
||||||
|
}
|
||||||
|
int wmfIdx = 1;
|
||||||
|
for (File f : files) {
|
||||||
|
try {
|
||||||
|
SlideShow<?,?> ss = SlideShowFactory.create(f);
|
||||||
|
for (PictureData pd : ss.getPictureData()) {
|
||||||
|
if (pd.getType() != PictureType.WMF) continue;
|
||||||
|
byte wmfData[] = pd.getData();
|
||||||
|
if (outputFiles) {
|
||||||
|
String filename = String.format(Locale.ROOT, "pic%04d.wmf", wmfIdx);
|
||||||
|
FileOutputStream fos = new FileOutputStream(new File(outdir, filename));
|
||||||
|
fos.write(wmfData);
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
HwmfPicture wmf = new HwmfPicture(new ByteArrayInputStream(wmfData));
|
||||||
|
|
||||||
|
int bmpIndex = 1;
|
||||||
|
for (HwmfRecord r : wmf.getRecords()) {
|
||||||
|
if (r instanceof HwmfImageRecord) {
|
||||||
|
BufferedImage bi = ((HwmfImageRecord)r).getImage();
|
||||||
|
if (outputFiles) {
|
||||||
|
String filename = String.format(Locale.ROOT, "pic%04d-%04d.png", wmfIdx, bmpIndex);
|
||||||
|
ImageIO.write(bi, "PNG", new File(outdir, filename));
|
||||||
|
}
|
||||||
|
bmpIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wmfIdx++;
|
||||||
|
}
|
||||||
|
ss.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(f+" ignored.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user