123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682 |
- /* ====================================================================
- 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.geom.Dimension2D;
- import java.awt.image.BufferedImage;
- 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.ColorUsage;
- import org.apache.poi.hwmf.record.HwmfFill.HwmfImageRecord;
- import org.apache.poi.util.Dimension2DDouble;
- import org.apache.poi.util.LittleEndianConsts;
- import org.apache.poi.util.LittleEndianInputStream;
-
- public class HwmfMisc {
-
- /**
- * The META_SAVEDC record saves the playback device context for later retrieval.
- */
- public static class WmfSaveDc implements HwmfRecord {
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.saveDc;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- return 0;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.saveProperties();
- }
-
- @Override
- public String toString() {
- return "{}";
- }
- }
-
- /**
- * The META_SETRELABS record is reserved and not supported.
- */
- public static class WmfSetRelabs implements HwmfRecord {
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setRelabs;
- }
-
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- return 0;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
-
- }
- }
-
- /**
- * The META_RESTOREDC record restores the playback device context from a previously saved device
- * context.
- */
- public static class WmfRestoreDc implements HwmfRecord {
-
- /**
- * nSavedDC (2 bytes): A 16-bit signed integer that defines the saved state to be restored. If this
- * 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.
- */
- protected int nSavedDC;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.restoreDc;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- nSavedDC = leis.readShort();
- return LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.restoreProperties(nSavedDC);
- }
-
- @Override
- public String toString() {
- return "{ nSavedDC: "+nSavedDC+" }";
- }
- }
-
- /**
- * The META_SETBKCOLOR record sets the background color in the playback device context to a
- * specified color, or to the nearest physical color if the device cannot represent the specified color.
- */
- public static class WmfSetBkColor implements HwmfRecord {
-
- protected final HwmfColorRef colorRef = new HwmfColorRef();
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setBkColor;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- return colorRef.init(leis);
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setBackgroundColor(colorRef);
- }
-
- @Override
- public String toString() {
- return "{ colorRef: "+colorRef+" }";
- }
- }
-
- /**
- * The META_SETBKMODE record defines the background raster operation mix mode in the playback
- * device context. The background mix mode is the mode for combining pens, text, hatched brushes,
- * and interiors of filled objects with background colors on the output surface.
- */
- public static class WmfSetBkMode implements HwmfRecord {
-
- /**
- * A 16-bit unsigned integer that defines background mix mode.
- */
- public enum HwmfBkMode {
- TRANSPARENT(0x0001), OPAQUE(0x0002);
-
- int flag;
- HwmfBkMode(int flag) {
- this.flag = flag;
- }
-
- public static HwmfBkMode valueOf(int flag) {
- for (HwmfBkMode bs : values()) {
- if (bs.flag == flag) return bs;
- }
- return null;
- }
- }
-
- protected HwmfBkMode bkMode;
-
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setBkMode;
- }
-
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- bkMode = HwmfBkMode.valueOf(leis.readUShort());
- return LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setBkMode(bkMode);
- }
-
- @Override
- public String toString() {
- return "{ bkMode: '"+bkMode+"' }";
- }
- }
-
- /**
- * The META_SETLAYOUT record defines the layout orientation in the playback device context.
- * The layout orientation determines the direction in which text and graphics are drawn
- */
- public static class WmfSetLayout implements HwmfRecord {
-
- /**
- * A 16-bit unsigned integer that defines the layout of text and graphics.
- * LAYOUT_LTR = 0x0000
- * LAYOUT_RTL = 0x0001
- * LAYOUT_BITMAPORIENTATIONPRESERVED = 0x0008
- */
- private int layout;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setLayout;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- layout = leis.readUShort();
- // A 16-bit field that MUST be ignored.
- /*int reserved =*/ leis.readShort();
- return 2*LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
-
- }
- }
-
- /**
- * The META_SETMAPMODE record defines the mapping mode in the playback device context.
- * The mapping mode defines the unit of measure used to transform page-space units into
- * device-space units, and also defines the orientation of the device's x and y axes.
- */
- public static class WmfSetMapMode implements HwmfRecord {
-
- protected HwmfMapMode mapMode;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setMapMode;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- mapMode = HwmfMapMode.valueOf(leis.readUShort());
- return LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.getProperties().setMapMode(mapMode);
- ctx.updateWindowMapMode();
- }
-
- @Override
- public String toString() {
- return "{ mapMode: '"+mapMode+"' }";
- }
- }
-
- /**
- * The META_SETMAPPERFLAGS record defines the algorithm that the font mapper uses when it maps
- * logical fonts to physical fonts.
- */
- public static class WmfSetMapperFlags implements HwmfRecord {
-
- /**
- * A 32-bit unsigned integer that defines whether the font mapper should attempt to
- * match a font's aspect ratio to the current device's aspect ratio. If bit 0 is
- * set, the font mapper SHOULD select only fonts that match the aspect ratio of the
- * output device, as it is currently defined in the playback device context.
- */
- private long mapperValues;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setMapperFlags;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- mapperValues = leis.readUInt();
- return LittleEndianConsts.INT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
-
- }
-
- @Override
- public String toString() {
- return "{ mapperValues: "+mapperValues+" }";
- }
- }
-
- /**
- * The META_SETROP2 record defines the foreground raster operation mix mode in the playback device
- * context. The foreground mix mode is the mode for combining pens and interiors of filled objects with
- * foreground colors on the output surface.
- */
- public static class WmfSetRop2 implements HwmfRecord {
-
- /** An unsigned integer that defines the foreground binary raster operation mixing mode */
- protected HwmfBinaryRasterOp drawMode;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setRop2;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- drawMode = HwmfBinaryRasterOp.valueOf(leis.readUShort());
- return LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
-
- }
-
- @Override
- public String toString() {
- return "{ drawMode: '"+drawMode+"' }";
- }
- }
-
- /**
- * The META_SETSTRETCHBLTMODE record defines the bitmap stretching mode in the playback device
- * context.
- */
- public static class WmfSetStretchBltMode implements HwmfRecord {
-
- public enum StretchBltMode {
- /**
- * Performs a Boolean AND operation by using the color values for the eliminated and existing pixels.
- * If the bitmap is a monochrome bitmap, this mode preserves black pixels at the expense of white pixels.
- *
- * EMF name: STRETCH_ANDSCANS
- */
- BLACKONWHITE(0x0001),
- /**
- * Performs a Boolean OR operation by using the color values for the eliminated and existing pixels.
- * If the bitmap is a monochrome bitmap, this mode preserves white pixels at the expense of black pixels.
- *
- * EMF name: STRETCH_ORSCANS
- */
- WHITEONBLACK(0x0002),
- /**
- * Deletes the pixels. This mode deletes all eliminated lines of pixels without trying
- * to preserve their information.
- *
- * EMF name: STRETCH_DELETESCANS
- */
- COLORONCOLOR(0x0003),
- /**
- * Maps pixels from the source rectangle into blocks of pixels in the destination rectangle.
- * The average color over the destination block of pixels approximates the color of the source
- * pixels.
- *
- * After setting the HALFTONE stretching mode, the brush origin MUST be set to avoid misalignment
- * artifacts - in EMF this is done via EmfSetBrushOrgEx
- *
- * EMF name: STRETCH_HALFTONE
- */
- HALFTONE(0x0004);
-
- public final int flag;
- StretchBltMode(int flag) {
- this.flag = flag;
- }
-
- public static StretchBltMode valueOf(int flag) {
- for (StretchBltMode bs : values()) {
- if (bs.flag == flag) return bs;
- }
- return null;
- }
- }
-
- protected StretchBltMode stretchBltMode;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.setStretchBltMode;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- stretchBltMode = StretchBltMode.valueOf(leis.readUShort());
- return LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
-
- }
-
- @Override
- public String toString() {
- return "{ stretchBltMode: '"+stretchBltMode+"' }";
- }
- }
-
- /**
- * The META_DIBCREATEPATTERNBRUSH record creates a Brush Object with a
- * pattern specified by a DeviceIndependentBitmap (DIB) Object
- */
- public static class WmfDibCreatePatternBrush implements HwmfRecord, HwmfImageRecord, HwmfObjectTableEntry {
-
- protected HwmfBrushStyle style;
-
- /**
- * A 16-bit unsigned integer that defines whether the Colors field of a DIB
- * Object contains explicit RGB values, or indexes into a palette.
- *
- * If the Style field specifies BS_PATTERN, a ColorUsage value of DIB_RGB_COLORS MUST be
- * used regardless of the contents of this field.
- *
- * If the Style field specified anything but BS_PATTERN, this field MUST be one of the ColorUsage values.
- */
- protected ColorUsage colorUsage;
-
- protected HwmfBitmapDib patternDib;
- private HwmfBitmap16 pattern16;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.dibCreatePatternBrush;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- style = HwmfBrushStyle.valueOf(leis.readUShort());
- colorUsage = ColorUsage.valueOf(leis.readUShort());
- int size = 2*LittleEndianConsts.SHORT_SIZE;
- switch (style) {
- case BS_SOLID:
- case BS_NULL:
- case BS_DIBPATTERN:
- case BS_DIBPATTERNPT:
- case BS_HATCHED:
- case BS_PATTERN:
- patternDib = new HwmfBitmapDib();
- size += patternDib.init(leis, (int)(recordSize-6-size));
- break;
- case BS_INDEXED:
- case BS_DIBPATTERN8X8:
- case BS_MONOPATTERN:
- case BS_PATTERN8X8:
- throw new RuntimeException("pattern not supported");
- }
- return size;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.addObjectTableEntry(this);
- }
-
- @Override
- public void applyObject(HwmfGraphics ctx) {
- if (patternDib != null && !patternDib.isValid()) {
- return;
- }
- HwmfDrawProperties prop = ctx.getProperties();
- prop.setBrushStyle(style);
- prop.setBrushBitmap(getImage());
- }
-
- @Override
- public BufferedImage getImage() {
- if (patternDib != null && patternDib.isValid()) {
- return patternDib.getImage();
- } else if (pattern16 != null) {
- return pattern16.getImage();
- } else {
- return null;
- }
- }
- }
-
- /**
- * The META_DELETEOBJECT record deletes an object, including Bitmap16, Brush,
- * DeviceIndependentBitmap, Font, Palette, Pen, and Region. After the object is deleted,
- * its index in the WMF Object Table is no longer valid but is available to be reused.
- */
- public static class WmfDeleteObject implements HwmfRecord {
- /**
- * A 16-bit unsigned integer used to index into the WMF Object Table to
- * get the object to be deleted.
- */
- protected int objectIndex;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.deleteObject;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- objectIndex = leis.readUShort();
- return LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- /* TODO:
- * The object specified by this record MUST be deleted from the EMF Object Table.
- * If the deleted object is currently selected in the playback device context,
- * the default object for that graphics property MUST be restored.
- */
-
- ctx.unsetObjectTableEntry(objectIndex);
- }
-
- @Override
- public String toString() {
- return "{ index: "+objectIndex+" }";
- }
- }
-
- public static class WmfCreatePatternBrush implements HwmfRecord, HwmfObjectTableEntry {
-
- private HwmfBitmap16 pattern;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.createPatternBrush;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- pattern = new HwmfBitmap16(true);
- return pattern.init(leis);
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.addObjectTableEntry(this);
- }
-
- @Override
- public void applyObject(HwmfGraphics ctx) {
- HwmfDrawProperties dp = ctx.getProperties();
- dp.setBrushBitmap(pattern.getImage());
- dp.setBrushStyle(HwmfBrushStyle.BS_PATTERN);
- }
- }
-
- public static class WmfCreatePenIndirect implements HwmfRecord, HwmfObjectTableEntry {
-
- protected HwmfPenStyle penStyle;
-
- protected final Dimension2D dimension = new Dimension2DDouble();
- /**
- * A 32-bit ColorRef Object that specifies the pen color value.
- */
- protected final HwmfColorRef colorRef = new HwmfColorRef();
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.createPenIndirect;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- penStyle = HwmfPenStyle.valueOf(leis.readUShort());
- // A 32-bit PointS Object that specifies a point for the object dimensions.
- // The x-coordinate is the pen width. The y-coordinate is ignored.
- int xWidth = leis.readShort();
- int yWidth = leis.readShort();
- dimension.setSize(xWidth, yWidth);
-
- int size = colorRef.init(leis);
- return size+3*LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.addObjectTableEntry(this);
- }
-
- @Override
- public void applyObject(HwmfGraphics ctx) {
- HwmfDrawProperties p = ctx.getProperties();
- p.setPenStyle(penStyle);
- p.setPenColor(colorRef);
- p.setPenWidth(dimension.getWidth());
- }
-
- @Override
- public String toString() {
- return
- "{ penStyle: "+penStyle+
- ", dimension: { width: "+dimension.getWidth()+", height: "+dimension.getHeight()+" }"+
- ", colorRef: "+colorRef+"}";
- }
- }
-
- /**
- * The META_CREATEBRUSHINDIRECT record creates a Brush Object
- * from a LogBrush Object.
- *
- * 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.
- *
- * <table>
- * <tr>
- * <th>BrushStyle</th>
- * <th>ColorRef</th>
- * <th>BrushHatch</th>
- * </tr>
- * <tr>
- * <td>BS_SOLID</td>
- * <td>SHOULD be a ColorRef Object, which determines the color of the brush.</td>
- * <td>Not used, and SHOULD be ignored.</td>
- * </tr>
- * <tr>
- * <td>BS_NULL</td>
- * <td>Not used, and SHOULD be ignored.</td>
- * <td>Not used, and SHOULD be ignored.</td>
- * </tr>
- * <tr>
- * <td>BS_PATTERN</td>
- * <td>Not used, and SHOULD be ignored.</td>
- * <td>Not used. A default object, such as a solidcolor black Brush Object, MAY be created.</td>
- * </tr>
- * <tr>
- * <td>BS_DIBPATTERN</td>
- * <td>Not used, and SHOULD be ignored.</td>
- * <td>Not used. A default object, such as a solidcolor black Brush Object, MAY be created</td>
- * </tr>
- * <tr>
- * <td>BS_DIBPATTERNPT</td>
- * <td>Not used, and SHOULD be ignored.</td>
- * <td>Not used. A default object, such as a solidcolor black Brush Object, MAY be created.</td>
- * </tr>
- * <tr>
- * <td>BS_HATCHED</td>
- * <td>SHOULD be a ColorRef Object, which determines the foreground color of the hatch pattern.</td>
- * <td>A value from the {@link HwmfHatchStyle} Enumeration that specifies the orientation of lines used to create the hatch.</td>
- * </tr>
- * </table>
- */
- public static class WmfCreateBrushIndirect implements HwmfRecord, HwmfObjectTableEntry {
- protected HwmfBrushStyle brushStyle;
-
- protected HwmfColorRef colorRef;
-
- protected HwmfHatchStyle brushHatch;
-
- @Override
- public HwmfRecordType getWmfRecordType() {
- return HwmfRecordType.createBrushIndirect;
- }
-
- @Override
- public int init(LittleEndianInputStream leis, long recordSize, int recordFunction) throws IOException {
- brushStyle = HwmfBrushStyle.valueOf(leis.readUShort());
- colorRef = new HwmfColorRef();
- int size = colorRef.init(leis);
- brushHatch = HwmfHatchStyle.valueOf(leis.readUShort());
- return size+2*LittleEndianConsts.SHORT_SIZE;
- }
-
- @Override
- public void draw(HwmfGraphics ctx) {
- ctx.addObjectTableEntry(this);
- }
-
- @Override
- public void applyObject(HwmfGraphics ctx) {
- HwmfDrawProperties p = ctx.getProperties();
- p.setBrushStyle(brushStyle);
- p.setBrushColor(colorRef);
- p.setBrushHatch(brushHatch);
- }
-
- @Override
- public String toString() {
- return
- "{ brushStyle: '"+brushStyle+"'"+
- ", colorRef: "+colorRef+
- ", brushHatch: '"+brushHatch+"' }";
- }
- }
- }
|