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

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:


/* ====================================================================
   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


   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   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.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

import org.apache.poi.common.usermodel.GenericRecord;
import org.apache.poi.hemf.draw.HemfGraphics;
import org.apache.poi.hemf.record.emfplus.HemfPlusBrush.EmfPlusBrush;
import org.apache.poi.hemf.record.emfplus.HemfPlusFont.EmfPlusFont;
import org.apache.poi.hemf.record.emfplus.HemfPlusHeader.EmfPlusGraphicsVersion;
import org.apache.poi.hemf.record.emfplus.HemfPlusImage.EmfPlusImage;
import org.apache.poi.hemf.record.emfplus.HemfPlusImage.EmfPlusImageAttributes;
import org.apache.poi.hemf.record.emfplus.HemfPlusMisc.EmfPlusObjectId;
import org.apache.poi.hemf.record.emfplus.HemfPlusPath.EmfPlusPath;
import org.apache.poi.hemf.record.emfplus.HemfPlusPen.EmfPlusPen;
import org.apache.poi.hemf.record.emfplus.HemfPlusRegion.EmfPlusRegion;
import org.apache.poi.hwmf.draw.HwmfGraphics;
import org.apache.poi.hwmf.record.HwmfObjectTableEntry;
import org.apache.poi.util.BitField;
import org.apache.poi.util.BitFieldFactory;
import org.apache.poi.util.GenericRecordUtil;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndianConsts;
import org.apache.poi.util.LittleEndianInputStream;

public class HemfPlusObject {
    private static final int MAX_OBJECT_SIZE = 50_000_000;

     * The ObjectType enumeration defines types of graphics objects that can be created and used in graphics operations.
    public enum EmfPlusObjectType {
         * The object is not a valid object.
        INVALID(0x00000000, EmfPlusUnknownData::new),
         * Brush objects fill graphics regions.
        BRUSH(0x00000001, EmfPlusBrush::new),
         * Pen objects draw graphics lines.
        PEN(0x00000002, EmfPlusPen::new),
         * Path objects specify sequences of lines, curves, and shapes.
        PATH(0x00000003, EmfPlusPath::new),
         * Region objects specify areas of the output surface.
        REGION(0x00000004, EmfPlusRegion::new),
         * Image objects encapsulate bitmaps and metafiles.
        IMAGE(0x00000005, EmfPlusImage::new),
         * Font objects specify font properties, including typeface style, em size, and font family.
        FONT(0x00000006, EmfPlusFont::new),
         * String format objects specify text layout, including alignment, orientation, tab stops, clipping,
         * and digit substitution for languages that do not use Western European digits.
        STRING_FORMAT(0x00000007, EmfPlusUnknownData::new),
         * Image attribute objects specify operations on pixels during image rendering, including color
         * adjustment, grayscale adjustment, gamma correction, and color mapping.
        IMAGE_ATTRIBUTES(0x00000008, EmfPlusImageAttributes::new),
         * Custom line cap objects specify shapes to draw at the ends of a graphics line, including
         * squares, circles, and diamonds.
        CUSTOM_LINE_CAP(0x00000009, EmfPlusUnknownData::new);

        public final int id;
        public final Supplier<? extends EmfPlusObjectData> constructor;

        EmfPlusObjectType(int id, Supplier<? extends EmfPlusObjectData> constructor) {
            this.id = id;
            this.constructor = constructor;

        public static EmfPlusObjectType valueOf(int id) {
            for (EmfPlusObjectType wrt : values()) {
                if (wrt.id == id) return wrt;
            return null;

     * The EmfPlusObject record specifies an object for use in graphics operations. The object definition
     * can span multiple records), which is indicated by the value of the Flags field.
    public static class EmfPlusObject implements HemfPlusRecord, EmfPlusObjectId, HwmfObjectTableEntry {
         * Indicates that the object definition continues on in the next EmfPlusObject
         * record. This flag is never set in the final record that defines the object.
        private static final BitField CONTINUABLE = BitFieldFactory.getInstance(0x8000);

         * Specifies the metafileType of object to be created by this record, from the
         * ObjectType enumeration
        private static final BitField OBJECT_TYPE = BitFieldFactory.getInstance(0x7F00);

        private static final int[] FLAGS_MASKS = { 0x7F00, 0x8000 };

        private static final String[] FLAGS_NAMES = { "OBJECT_TYPE", "CONTINUABLE" };

        private int flags;
        // for debugging
        private int objectId;
        private EmfPlusObjectData objectData;
        private List<EmfPlusObjectData> continuedObjectData;
        private int totalObjectSize;

        public HemfPlusRecordType getEmfPlusRecordType() {
            return HemfPlusRecordType.object;

        public int getFlags() {
            return flags;

        public EmfPlusObjectType getObjectType() {
            return EmfPlusObjectType.valueOf(OBJECT_TYPE.getValue(flags));

        public <T extends EmfPlusObjectData> T getObjectData() {
            return (T)objectData;

        public int getTotalObjectSize() {
            return totalObjectSize;

        public long init(LittleEndianInputStream leis, long dataSize, long recordId, int flags) throws IOException {
            this.flags = flags;

            objectId = getObjectId();
            EmfPlusObjectType objectType = getObjectType();
            assert (objectType != null);

            long size = 0;

            totalObjectSize = 0;
            int dataSize2 = (int) dataSize;

            if (CONTINUABLE.isSet(flags)) {
                // If the record is continuable, when the continue bit is set, this field will be present.
                // Continuing objects have multiple EMF+ records starting with EmfPlusContinuedObjectRecord.
                // Each EmfPlusContinuedObjectRecord will contain a TotalObjectSize. Once TotalObjectSize number
                // of bytes has been read, the next EMF+ record will not be treated as part of the continuing object.
                totalObjectSize = leis.readInt();
                size += LittleEndianConsts.INT_SIZE;
                dataSize2 -= LittleEndianConsts.INT_SIZE;

            objectData = objectType.constructor.get();
            size += objectData.init(leis, dataSize2, objectType, flags);

            return Math.toIntExact(size);

        public void draw(HemfGraphics ctx) {
            if (objectData.isContinuedRecord()) {
                EmfPlusObject other;
                HwmfObjectTableEntry entry = ctx.getPlusObjectTableEntry(getObjectId());
                if (entry instanceof EmfPlusObject &&
                    objectData.getClass().isInstance((other = (EmfPlusObject)entry).getObjectData())
                ) {
                } else {
                    throw new RuntimeException("can't find previous record for continued record");
            } else {
                ctx.addPlusObjectTableEntry(this, getObjectId());

        public void applyObject(HwmfGraphics ctx) {
            objectData.applyObject((HemfGraphics)ctx, continuedObjectData);

        void linkContinuedObject(EmfPlusObjectData continueObject) {
            if (continuedObjectData == null) {
                continuedObjectData = new ArrayList<>();

        List<EmfPlusObjectData> getContinuedObject() {
            return continuedObjectData;

        public Map<String, Supplier<?>> getGenericProperties() {
            return GenericRecordUtil.getGenericProperties(
                "flags", getBitsAsString(this::getFlags, FLAGS_MASKS, FLAGS_NAMES),
                "objectId", this::getObjectId,
                "objectData", () -> objectData.isContinuedRecord() ? null : getObjectData(),
                "continuedObject", objectData::isContinuedRecord,
                "totalObjectSize", this::getTotalObjectSize


    public interface EmfPlusObjectData extends GenericRecord {
        long init(LittleEndianInputStream leis, long dataSize, EmfPlusObjectType objectType, int flags) throws IOException;

        void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData);

        EmfPlusGraphicsVersion getGraphicsVersion();

        default boolean isContinuedRecord() {
            EmfPlusGraphicsVersion gv = getGraphicsVersion();
            return (gv.getGraphicsVersion() == null || gv.getMetafileSignature() != 0xDBC01);

    public static class EmfPlusUnknownData implements EmfPlusObjectData {
        private EmfPlusObjectType objectType;
        private final EmfPlusGraphicsVersion graphicsVersion = new EmfPlusGraphicsVersion();
        private byte[] objectDataBytes;

        public long init(LittleEndianInputStream leis, long dataSize, EmfPlusObjectType objectType, int flags) throws IOException {
            this.objectType = objectType;

            long size = graphicsVersion.init(leis);

            objectDataBytes = IOUtils.toByteArray(leis, (int)(dataSize - size), MAX_OBJECT_SIZE);

            return dataSize;

        public void applyObject(HemfGraphics ctx, List<? extends EmfPlusObjectData> continuedObjectData) {


        public EmfPlusGraphicsVersion getGraphicsVersion() {
            return graphicsVersion;

        public EmfPlusObjectType getGenericRecordType() {
            return objectType;

        public Map<String, Supplier<?>> getGenericProperties() {
            return GenericRecordUtil.getGenericProperties(
                "graphicsVersion", this::getGraphicsVersion,
                "objectDataBytes", () -> objectDataBytes


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


What Is poi-examples-5.2.3.jar?

What Is poi-excelant-5.2.3.jar?

Downloading and Installing Apache POI Java Library

⇑⇑ FAQ for Apache POI (Poor Obfuscation Implementation)

2017-03-22, 5928👍, 0💬