Categories:
Audio (13)
Biotech (29)
Bytecode (36)
Database (77)
Framework (7)
Game (7)
General (507)
Graphics (53)
I/O (35)
IDE (2)
JAR Tools (101)
JavaBeans (21)
JDBC (121)
JDK (426)
JSP (20)
Logging (108)
Mail (58)
Messaging (8)
Network (84)
PDF (97)
Report (7)
Scripting (84)
Security (32)
Server (121)
Servlet (26)
SOAP (24)
Testing (54)
Web (15)
XML (309)
Collections:
Other Resources:
What Is poi-scratchpad-5.2.3.jar?
What Is poi-scratchpad-5.2.3.jar?
✍: FYIcenter.com
poi-scratchpad-5.2.3.jar is one of the JAR files for Apache POI 5.2.3, which provides an API for Microsoft document files of Word, Excel, PowerPoint, and Visio.
poi-scratchpad-5.2.3.jar provides support for older versions of Microsoft document files like Word 97, Excel 97, PowerPoint 97, etc.
poi-scratchpad-5.2.3.jar is distributed as part of the poi-bin-5.2.3-20220909.zip download file.
JAR File Size and Download Location:
JAR name: poi-scratchpad-5.2.3.jar Target JDK version: 9 Dependency: poi.jar File name: poi-scratchpad.jar, poi-scratchpad-5.2.3.jar File size: 1897121 bytes Release date: 09-09-2022 Download: Apache POI Website
Here are Java Source Code files for poi-scratchpad-5.2.3.jar:
⏎ org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
/* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ package org.apache.poi.hemf.record.emfplus; import static org.apache.poi.util.GenericRecordUtil.getBitsAsString; import java.awt.Color; import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.PrimitiveIterator.OfInt; import java.util.function.BiFunction; import java.util.function.Supplier; import org.apache.commons.math3.linear.LUDecomposition; import org.apache.commons.math3.linear.MatrixUtils; import org.apache.commons.math3.linear.RealMatrix; import org.apache.poi.hemf.draw.HemfDrawProperties; import org.apache.poi.hemf.draw.HemfGraphics; import org.apache.poi.hemf.record.emf.HemfFill; import org.apache.poi.hemf.record.emfplus.HemfPlusMisc.EmfPlusObjectId; import org.apache.poi.hwmf.record.HwmfBrushStyle; import org.apache.poi.hwmf.record.HwmfColorRef; import org.apache.poi.hwmf.record.HwmfMisc.WmfSetBkMode.HwmfBkMode; import org.apache.poi.hwmf.record.HwmfPenStyle; import org.apache.poi.hwmf.record.HwmfTernaryRasterOp; import org.apache.poi.hwmf.record.HwmfText; import org.apache.poi.sl.draw.ImageRenderer; import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.GenericRecordJsonWriter; import org.apache.poi.util.GenericRecordUtil; import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndianConsts; import org.apache.poi.util.LittleEndianInputStream; import org.apache.poi.util.StringUtil; @SuppressWarnings("WeakerAccess") public final class HemfPlusDraw { private static final int MAX_OBJECT_SIZE = 1_000_000; private HemfPlusDraw() {} public enum EmfPlusUnitType { /** Specifies a unit of logical distance within the world space. */ World(0x00), /** Specifies a unit of distance based on the characteristics of the physical display. */ Display(0x01), /** Specifies a unit of 1 pixel. */ Pixel(0x02), /** Specifies a unit of 1 printer's point, or 1/72 inch. */ Point(0x03), /** Specifies a unit of 1 inch. */ Inch(0x04), /** Specifies a unit of 1/300 inch. */ Document(0x05), /** Specifies a unit of 1 millimeter. */ Millimeter(0x06) ; public final int id; EmfPlusUnitType(int id) { this.id = id; } public static EmfPlusUnitType valueOf(int id) { for (EmfPlusUnitType wrt : values()) { if (wrt.id == id) return wrt; } return null; } } public interface EmfPlusCompressed { /** * This bit indicates whether the data in the RectData field is compressed. * If set, RectData contains an EmfPlusRect object. * If clear, RectData contains an EmfPlusRectF object object. */ BitField COMPRESSED = BitFieldFactory.getInstance(0x4000); int getFlags(); /** * The index in the EMF+ Object Table to associate with the object * created by this record. The value MUST be zero to 63, inclusive. */ default boolean isCompressed() { return COMPRESSED.isSet(getFlags()); } default BiFunction<LittleEndianInputStream, Rectangle2D, Integer> getReadRect() { return isCompressed() ? HemfPlusDraw::readRectS : HemfPlusDraw::readRectF; } } public interface EmfPlusRelativePosition { /** * This bit indicates whether the PointData field specifies relative or absolute locations. * If set, each element in PointData specifies a location in the coordinate space that is relative to the * location specified by the previous element in the array. In the case of the first element in PointData, * a previous location at coordinates (0,0) is assumed. * If clear, PointData specifies absolute locations according to the {@link EmfPlusCompressed#isCompressed()} flag. * * Note If this flag is set, the {@link EmfPlusCompressed#isCompressed()} flag (above) is undefined and MUST be ignored. */ BitField POSITION = BitFieldFactory.getInstance(0x0800); int getFlags(); default boolean isRelativePosition() { return POSITION.isSet(getFlags()); } } public interface EmfPlusSolidColor { /** * If set, brushId specifies a color as an EmfPlusARGB object. * If clear, brushId contains the index of an EmfPlusBrush object in the EMF+ Object Table. */ BitField SOLID_COLOR = BitFieldFactory.getInstance(0x8000); int getFlags(); int getBrushIdValue(); default boolean isSolidColor() { return SOLID_COLOR.isSet(getFlags()); } default int getBrushId() { return (isSolidColor()) ? -1 : getBrushIdValue(); } default Color getSolidColor() { return (isSolidColor()) ? readARGB(getBrushIdValue()) : null; } default void applyColor(HemfGraphics ctx) { HemfDrawProperties prop = ctx.getProperties(); if (isSolidColor()) { prop.setBrushStyle(HwmfBrushStyle.BS_SOLID); prop.setBrushColor(new HwmfColorRef(getSolidColor())); } else { ctx.applyPlusObjectTableEntry(getBrushId()); } } } /** * The EmfPlusDrawPath record specifies drawing a graphics path */ public static class EmfPlusDrawPath implements HemfPlusRecord, EmfPlusObjectId { private int flags; private int penId; @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.drawPath; } @Override public int getFlags() { return flags; } public int getPenId() { return penId; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that specifies an index in the EMF+ Object Table for an EmfPlusPen object // to use for drawing the EmfPlusPath. The value MUST be zero to 63, inclusive. penId = leis.readInt(); assert (0 <= penId && penId <= 63); assert (dataSize == LittleEndianConsts.INT_SIZE); return LittleEndianConsts.INT_SIZE; } @Override public void draw(HemfGraphics ctx) { ctx.applyPlusObjectTableEntry(penId); ctx.applyPlusObjectTableEntry(getObjectId()); HemfDrawProperties prop = ctx.getProperties(); final Path2D path = prop.getPath(); if (path != null) { ctx.draw(path); } } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public HemfPlusRecordType getGenericRecordType() { return getEmfPlusRecordType(); } @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "flags", this::getFlags, "penId", this::getPenId ); } } /** * The EmfPlusFillRects record specifies filling the interiors of a series of rectangles. */ public static class EmfPlusFillRects implements HemfPlusRecord, EmfPlusCompressed, EmfPlusSolidColor { private int flags; private int brushId; private final ArrayList<Rectangle2D> rectData = new ArrayList<>(); @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.fillRects; } @Override public int getFlags() { return flags; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that defines the brush, the content of which is // determined by the S bit in the Flags field. brushId = leis.readInt(); // A 32-bit unsigned integer that specifies the number of rectangles in the RectData field. int count = leis.readInt(); BiFunction<LittleEndianInputStream, Rectangle2D, Integer> readRect = getReadRect(); rectData.ensureCapacity(count); int size = 2 * LittleEndianConsts.INT_SIZE; for (int i = 0; i<count; i++) { Rectangle2D rect = new Rectangle2D.Double(); size += readRect.apply(leis, rect); rectData.add(rect); } return size; } @Override public void draw(HemfGraphics ctx) { HemfDrawProperties prop = ctx.getProperties(); applyColor(ctx); Area area = new Area(); rectData.stream().map(Area::new).forEach(area::add); HwmfPenStyle ps = prop.getPenStyle(); try { prop.setPenStyle(null); ctx.fill(area); } finally { prop.setPenStyle(ps); } } @Override public int getBrushIdValue() { return brushId; } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public HemfPlusRecordType getGenericRecordType() { return getEmfPlusRecordType(); } public List<Rectangle2D> getRectData() { return rectData; } @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "flags", this::getFlags, "brushId", this::getBrushId, "brushColor", this::getSolidColor, "rectData", this::getRectData ); } } /** The EmfPlusDrawImagePoints record specifies drawing a scaled image inside a parallelogram. */ @SuppressWarnings("unused") public static class EmfPlusDrawImagePoints implements HemfPlusRecord, EmfPlusObjectId, EmfPlusCompressed, EmfPlusRelativePosition { /** * This bit indicates that the rendering of the image includes applying an effect. * If set, an object of the Effect class MUST have been specified in an earlier EmfPlusSerializableObject record. */ private static final BitField EFFECT = BitFieldFactory.getInstance(0x2000); private int flags; private int imageAttributesID; private EmfPlusUnitType srcUnit; private final Rectangle2D srcRect = new Rectangle2D.Double(); private final Point2D upperLeft = new Point2D.Double(); private final Point2D lowerRight = new Point2D.Double(); private final Point2D lowerLeft = new Point2D.Double(); private final AffineTransform trans = new AffineTransform(); @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.drawImagePoints; } @Override public int getFlags() { return flags; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that contains the index of the // optional EmfPlusImageAttributes object in the EMF+ Object Table. imageAttributesID = leis.readInt(); // A 32-bit signed integer that defines the units of the SrcRect field. // It MUST be the UnitPixel value of the UnitType enumeration srcUnit = EmfPlusUnitType.valueOf(leis.readInt()); assert(srcUnit == EmfPlusUnitType.Pixel); int size = 2 * LittleEndianConsts.INT_SIZE; // An EmfPlusRectF object that defines a portion of the image to be rendered. size += readRectF(leis, srcRect); // A 32-bit unsigned integer that specifies the number of points in the PointData array. // Exactly 3 points MUST be specified. int count = leis.readInt(); assert(count == 3); size += LittleEndianConsts.INT_SIZE; BiFunction<LittleEndianInputStream, Point2D, Integer> readPoint; if (isRelativePosition()) { // If the POSITION flag is set in the Flags, the points specify relative locations. readPoint = HemfPlusDraw::readPointR; } else if (isCompressed()) { // If the POSITION bit is clear and the COMPRESSED bit is set in the Flags field, the points // specify absolute locations with integer values. readPoint = HemfPlusDraw::readPointS; } else { // If the POSITION bit is clear and the COMPRESSED bit is clear in the Flags field, the points // specify absolute locations with floating-point values. readPoint = HemfPlusDraw::readPointF; } // TODO: handle relative coordinates // An array of Count points that specify three points of a parallelogram. // The three points represent the upper-left, upper-right, and lower-left corners of the parallelogram. // The fourth point of the parallelogram is extrapolated from the first three. // The portion of the image specified by the SrcRect field SHOULD have scaling and shearing transforms // applied if necessary to fit inside the parallelogram. // size += readPoint.apply(leis, upperLeft); // size += readPoint.apply(leis, upperRight); // size += readPoint.apply(leis, lowerLeft); size += readPoint.apply(leis, lowerLeft); size += readPoint.apply(leis, lowerRight); size += readPoint.apply(leis, upperLeft); // https://math.stackexchange.com/questions/2772737/how-to-transform-arbitrary-rectangle-into-specific-parallelogram RealMatrix para2normal = MatrixUtils.createRealMatrix(new double[][] { { lowerLeft.getX(), lowerRight.getX(), upperLeft.getX() }, { lowerLeft.getY(), lowerRight.getY(), upperLeft.getY() }, { 1, 1, 1 } }); RealMatrix rect2normal = MatrixUtils.createRealMatrix(new double[][]{ { srcRect.getMinX(), srcRect.getMaxX(), srcRect.getMinX() }, { srcRect.getMinY(), srcRect.getMinY(), srcRect.getMaxY() }, { 1, 1, 1 } }); RealMatrix normal2rect = new LUDecomposition(rect2normal).getSolver().getInverse(); double[][] m = para2normal.multiply(normal2rect).getData(); trans.setTransform(round10(m[0][0]), round10(m[1][0]), round10(m[0][1]), round10(m[1][1]), round10(m[0][2]), round10(m[1][2])); return size; } @Override public void draw(HemfGraphics ctx) { HemfDrawProperties prop = ctx.getProperties(); ctx.applyPlusObjectTableEntry(imageAttributesID); ctx.applyPlusObjectTableEntry(getObjectId()); final ImageRenderer ir = prop.getEmfPlusImage(); if (ir == null) { return; } AffineTransform txSaved = ctx.getTransform(); AffineTransform tx = (AffineTransform)txSaved.clone(); HwmfTernaryRasterOp oldOp = prop.getRasterOp3(); HwmfBkMode oldBk = prop.getBkMode(); try { tx.concatenate(trans); ctx.setTransform(tx); prop.setRasterOp3(HwmfTernaryRasterOp.SRCCOPY); prop.setBkMode(HwmfBkMode.TRANSPARENT); // transformation from srcRect to destRect was already applied, // therefore use srcRect as third parameter ctx.drawImage(ir, srcRect, srcRect); } finally { prop.setBkMode(oldBk); prop.setRasterOp3(oldOp); ctx.setTransform(txSaved); } } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public Map<String, Supplier<?>> getGenericProperties() { final Map<String,Supplier<?>> m = new LinkedHashMap<>(); m.put("flags", this::getFlags); m.put("imageAttributesID", () -> imageAttributesID); m.put("srcUnit", () -> srcUnit); m.put("srcRect", () -> srcRect); m.put("upperLeft", () -> upperLeft); m.put("lowerLeft", () -> lowerLeft); m.put("lowerRight", () -> lowerRight); m.put("transform", () -> trans); return Collections.unmodifiableMap(m); } } /** The EmfPlusDrawImage record specifies drawing a scaled image. */ public static class EmfPlusDrawImage implements HemfPlusRecord, EmfPlusObjectId, EmfPlusCompressed { private int flags; private int imageAttributesID; private EmfPlusUnitType srcUnit; private final Rectangle2D srcRect = new Rectangle2D.Double(); private final Rectangle2D rectData = new Rectangle2D.Double(); @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.drawImage; } @Override public int getFlags() { return flags; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that contains the index of the // optional EmfPlusImageAttributes object in the EMF+ Object Table. imageAttributesID = leis.readInt(); // A 32-bit signed integer that defines the units of the SrcRect field. // It MUST be the UnitPixel value of the UnitType enumeration srcUnit = EmfPlusUnitType.valueOf(leis.readInt()); assert(srcUnit == EmfPlusUnitType.Pixel); int size = 2 * LittleEndianConsts.INT_SIZE; // An EmfPlusRectF object that specifies a portion of the image to be rendered. The portion of the image // specified by this rectangle is scaled to fit the destination rectangle specified by the RectData field. size += readRectF(leis, srcRect); // Either an EmfPlusRect or EmfPlusRectF object that defines the bounding box of the image. The portion of // the image specified by the SrcRect field is scaled to fit this rectangle. size += getReadRect().apply(leis, rectData); return size; } @Override public void draw(HemfGraphics ctx) { ctx.applyPlusObjectTableEntry(imageAttributesID); ctx.applyPlusObjectTableEntry(getObjectId()); HemfDrawProperties prop = ctx.getProperties(); prop.setRasterOp3(HwmfTernaryRasterOp.SRCCOPY); prop.setBkMode(HwmfBkMode.TRANSPARENT); ctx.drawImage(prop.getEmfPlusImage(), srcRect, rectData); } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "flags", this::getFlags, "imageAttributesID", () -> imageAttributesID, "srcUnit", () -> srcUnit, "srcRect", () -> srcRect, "rectData", () -> rectData ); } } /** The EmfPlusFillRegion record specifies filling the interior of a graphics region. */ public static class EmfPlusFillRegion implements HemfPlusRecord, EmfPlusSolidColor, EmfPlusObjectId { private int flags; private int brushId; @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.fillRegion; } @Override public int getFlags() { return flags; } @Override public int getBrushIdValue() { return brushId; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that defines the brush, the content of which is determined by // the SOLID_COLOR bit in the Flags field. // If SOLID_COLOR is set, BrushId specifies a color as an EmfPlusARGB object. // If clear, BrushId contains the index of an EmfPlusBrush object in the EMF+ Object Table. brushId = leis.readInt(); return LittleEndianConsts.INT_SIZE; } @Override public void draw(HemfGraphics ctx) { applyColor(ctx); ctx.applyPlusObjectTableEntry(getObjectId()); HemfDrawProperties prop = ctx.getProperties(); ctx.fill(prop.getPath()); } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "flags", this::getFlags, "brushId", () -> brushId ); } } /** The EmfPlusFillPath record specifies filling the interior of a graphics path. */ public static class EmfPlusFillPath extends EmfPlusFillRegion { @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.fillPath; } } /** The EmfPlusDrawDriverString record specifies text output with character positions. */ @SuppressWarnings("unused") public static class EmfPlusDrawDriverString implements HemfPlusRecord, EmfPlusObjectId, EmfPlusSolidColor { /** * If set, the positions of character glyphs SHOULD be specified in a character map lookup table. * If clear, the glyph positions SHOULD be obtained from an array of coordinates. */ private static final BitField CMAP_LOOKUP = BitFieldFactory.getInstance(0x0001); /** * If set, the string SHOULD be rendered vertically. * If clear, the string SHOULD be rendered horizontally. */ private static final BitField VERTICAL = BitFieldFactory.getInstance(0x0002); /** * If set, character glyph positions SHOULD be calculated relative to the position of the first glyph. * If clear, the glyph positions SHOULD be obtained from an array of coordinates. */ private static final BitField REALIZED_ADVANCE = BitFieldFactory.getInstance(0x0004); /** * If set, less memory SHOULD be used to cache anti-aliased glyphs, which produces lower quality text rendering. * If clear, more memory SHOULD be used, which produces higher quality text rendering. */ private static final BitField LIMIT_SUBPIXEL = BitFieldFactory.getInstance(0x0008); private static final int[] OPTIONS_MASK = { 0x0001, 0x0002, 0x0004, 0x0008 }; private static final String[] OPTIONS_NAMES = { "CMAP_LOOKUP", "VERTICAL", "REALIZED_ADVANCE", "LIMIT_SUBPIXEL" }; private int flags; private int brushId; private int optionsFlags; private String glyphs; private final List<Point2D> glyphPos = new ArrayList<>(); private final AffineTransform transformMatrix = new AffineTransform(); @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.drawDriverString; } @Override public int getFlags() { return flags; } @Override public int getBrushIdValue() { return brushId; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that specifies either the foreground color of the text or a graphics brush, // depending on the value of the SOLID_COLOR flag in the Flags. brushId = leis.readInt(); // A 32-bit unsigned integer that specifies the spacing, orientation, and quality of rendering for the // string. This value MUST be composed of DriverStringOptions flags optionsFlags = leis.readInt(); // A 32-bit unsigned integer that specifies whether a transform matrix is present in the // TransformMatrix field. int matrixPresent = leis.readInt(); // A 32-bit unsigned integer that specifies number of glyphs in the string. int glyphCount = leis.readInt(); int size = 4 * LittleEndianConsts.INT_SIZE; // TOOD: implement Non-Cmap-Lookup correctly // If the CMAP_LOOKUP flag in the optionsFlags field is set, each value in this array specifies a // Unicode character. Otherwise, each value specifies an index to a character glyph in the EmfPlusFont // object specified by the ObjectId value in Flags field. byte[] glyphBuf = IOUtils.toByteArray(leis, glyphCount*2, MAX_OBJECT_SIZE); glyphs = StringUtil.getFromUnicodeLE(glyphBuf); size += glyphBuf.length; // An array of EmfPlusPointF objects that specify the output position of each character glyph. // There MUST be GlyphCount elements, which have a one-to-one correspondence with the elements // in the Glyphs array. // // Glyph positions are calculated from the position of the first glyph if the REALIZED_ADVANCE flag in // Options flags is set. In this case, GlyphPos specifies the position of the first glyph only. int glyphPosCnt = REALIZED_ADVANCE.isSet(optionsFlags) ? 1 : glyphCount; for (int i=0; i<glyphCount; i++) { Point2D p = new Point2D.Double(); size += readPointF(leis, p); glyphPos.add(p); } if (matrixPresent != 0) { size += HemfFill.readXForm(leis, transformMatrix); } return size; } @Override public void draw(HemfGraphics ctx) { HemfDrawProperties prop = ctx.getProperties(); prop.setTextAlignLatin(HwmfText.HwmfTextAlignment.LEFT); prop.setTextVAlignLatin(HwmfText.HwmfTextVerticalAlignment.BASELINE); ctx.applyPlusObjectTableEntry(getObjectId()); if (isSolidColor()) { prop.setTextColor(new HwmfColorRef(getSolidColor())); } else { ctx.applyPlusObjectTableEntry(getBrushId()); } if (REALIZED_ADVANCE.isSet(optionsFlags)) { byte[] buf = glyphs.getBytes(StandardCharsets.UTF_16LE); ctx.drawString(buf, buf.length, glyphPos.get(0), null, null, null, null, true); } else { final OfInt glyphIter = glyphs.codePoints().iterator(); glyphPos.forEach(p -> { byte[] buf = new String(new int[]{glyphIter.next()}, 0, 1).getBytes(StandardCharsets.UTF_16LE); ctx.drawString(buf, buf.length, p, null, null, null, null, true); }); } } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "flags", this::getFlags, "brushId", this::getBrushId, "optionsFlags", getBitsAsString(() -> optionsFlags, OPTIONS_MASK, OPTIONS_NAMES), "glyphs", () -> glyphs, "glyphPos", () -> glyphPos, "transform", () -> transformMatrix ); } } /** The EmfPlusDrawRects record specifies drawing a series of rectangles. */ public static class EmfPlusDrawRects implements HemfPlusRecord, EmfPlusObjectId, EmfPlusCompressed { private int flags; private final List<Rectangle2D> rectData = new ArrayList<>(); @Override public HemfPlusRecordType getEmfPlusRecordType() { return HemfPlusRecordType.drawRects; } @Override public int getFlags() { return flags; } @Override public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException { this.flags = flags; // A 32-bit unsigned integer that specifies the number of rectangles in the RectData member. int count = leis.readInt(); int size = LittleEndianConsts.INT_SIZE; BiFunction<LittleEndianInputStream, Rectangle2D, Integer> readRect = getReadRect(); for (int i=0; i<count; i++) { Rectangle2D rect = new Rectangle2D.Double(); size += readRect.apply(leis, rect); } return size; } @Override public String toString() { return GenericRecordJsonWriter.marshal(this); } @Override public Map<String, Supplier<?>> getGenericProperties() { return GenericRecordUtil.getGenericProperties( "flags", this::getFlags, "rectData", () -> rectData ); } } @SuppressWarnings("squid:S2111") static double round10(double d) { return BigDecimal.valueOf(d).setScale(10, RoundingMode.HALF_UP).doubleValue(); } static int readRectS(LittleEndianInputStream leis, Rectangle2D bounds) { // A 16-bit signed integer that defines the ... coordinate final int x = leis.readShort(); final int y = leis.readShort(); final int width = leis.readShort(); final int height = leis.readShort(); bounds.setRect(x, y, width, height); return 4 * LittleEndianConsts.SHORT_SIZE; } static int readRectF(LittleEndianInputStream leis, Rectangle2D bounds) { // A 32-bit floating-point that defines the ... coordinate final double x = leis.readFloat(); final double y = leis.readFloat(); final double width = leis.readFloat(); final double height = leis.readFloat(); bounds.setRect(x, y, width, height); return 4 * LittleEndianConsts.INT_SIZE; } /** * The EmfPlusPoint object specifies an ordered pair of integer (X,Y) values that define an absolute * location in a coordinate space. */ static int readPointS(LittleEndianInputStream leis, Point2D point) { double x = leis.readShort(); double y = leis.readShort(); point.setLocation(x,y); return 2*LittleEndianConsts.SHORT_SIZE; } /** * The EmfPlusPointF object specifies an ordered pair of floating-point (X,Y) values that define an * absolute location in a coordinate space. */ static int readPointF(LittleEndianInputStream leis, Point2D point) { double x = leis.readFloat(); double y = leis.readFloat(); point.setLocation(x,y); return 2*LittleEndianConsts.INT_SIZE; } /** * The EmfPlusPointR object specifies an ordered pair of integer (X,Y) values that define a relative * location in a coordinate space. */ static int readPointR(LittleEndianInputStream leis, Point2D point) { int[] p = { 0 }; int size = readEmfPlusInteger(leis, p); double x = p[0]; size += readEmfPlusInteger(leis, p); double y = p[0]; point.setLocation(x,y); return size; } private static int readEmfPlusInteger(LittleEndianInputStream leis, int[] value) { value[0] = leis.readByte(); // check for EmfPlusInteger7 value if ((value[0] & 0x80) == 0) { return LittleEndianConsts.BYTE_SIZE; } // ok we've read a EmfPlusInteger15 value[0] = ((value[0] << 8) | (leis.readByte() & 0xFF)) & 0x7FFF; return LittleEndianConsts.SHORT_SIZE; } static Color readARGB(int argb) { return new Color((argb >>> 16) & 0xFF, (argb >>> 8) & 0xFF, argb & 0xFF, (argb >>> 24) & 0xFF); } }
⏎ org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
Or download all of them as a single archive file:
File name: poi-scratchpad-5.2.3-src.zip File size: 1238744 bytes Release date: 2022-09-09 Download
⇒ What Is poi-examples-5.2.3.jar?
⇐ What Is poi-excelant-5.2.3.jar?
2017-03-22, 34173👍, 0💬
Popular Posts:
What Is js.jar in Rhino JavaScript 1.7R5? js.jar in Rhino JavaScript 1.7R5 is the JAR file for Rhino...
MP3SPI is a Java Service Provider Interface that adds MP3 (MPEG 1/2/2.5 Layer 1/2/3) audio format su...
What is the sax\Writer.java provided in the Apache Xerces package? I have Apache Xerces 2.11.0 insta...
What Is fop.jar? I got it from the fop-2.7-bin.zip. fop.jar in fop-2.7-bin.zip is the JAR file for F...
JDK 11 java.xml.jmod is the JMOD file for JDK 11 XML (eXtensible Markup Language) module. JDK 11 XML...