All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mgz.afp.goca.GAD_GraphicsData Maven / Gradle / Ivy

Go to download

Alpheus AFP Parser is a library and parser for the IBM Advanced Function Presentation (AFP) document/print stream format. Alpheus covers all AFP specifications: MO:DCA, BCOCA, CMOCA, FOCA, GOCA, IOCA, and PTOCA. It is a complete implementation. Every Structured Field, Repeating Group, and Triplet is fully implemented as Java class. Alpheus AFP Parser was written from scratch and has no external dependencies. Copyright 2015,2016 Rudolf Fiala Alpheus AFP Parser is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

The newest version!
/*
Copyright 2015 Rudolf Fiala

This file is part of Alpheus AFP Parser.

Alpheus AFP Parser is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Alpheus AFP Parser is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Alpheus AFP Parser.  If not, see 
*/
package com.mgz.afp.goca;

import com.mgz.afp.base.StructuredField;
import com.mgz.afp.base.annotations.AFPField;
import com.mgz.afp.enums.IMutualExclusiveGroupedFlag;
import com.mgz.afp.enums.MutualExclusiveGroupedFlagHandler;
import com.mgz.afp.exceptions.AFPParserException;
import com.mgz.afp.exceptions.IAFPDecodeableWriteable;
import com.mgz.afp.goca.GAD_DrawingOrder.*;
import com.mgz.afp.parser.AFPParserConfiguration;
import com.mgz.util.Constants;
import com.mgz.util.UtilBinaryDecoding;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

/**
 * GOCA, 164.

*

* The graphics segments for a graphics object are contained within one or more GAD structured * fields. Receipt of the first segment starts the drawing process. No restrictions exist on how * much or how little graphics data is specified in a single GAD, except for the length limit of the * structured field. A GAD, for example, can carry partial segments, full segments, multiple * segments, or any combination of these. The only requirement is that the data itself is ordered in * the sequence that is expected for immediate processing and that the last GAD completes the last * segment. Because this environment does not support the calling of segments, all segments should * be chained segments. Any unchained segments in the data are ignored. The GAD structured field is * optional in a MO:DCA graphics object and may be repeated multiple times. */ public class GAD_GraphicsData extends StructuredField { private static final List buildDrawingOrders(byte[] sfData, int offset, int length, AFPParserConfiguration config) throws AFPParserException { int actualLength = length != -1 ? length : sfData.length - offset; List drawingOrders = new ArrayList(); int pos = 0; while (pos < actualLength) { int dotLength = 0; GAD_DrawingOrder drawingOrder = null; int drawingOrderCode = UtilBinaryDecoding.parseInt(sfData, offset + pos, 1); switch (drawingOrderCode) { case 0x00: { drawingOrder = new GNOP1_NopOperation(); dotLength = 1; } break; case 0x01: { drawingOrder = new GCOMT_Comment(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x04: { drawingOrder = new GDGCH_SegmentCharacteristics(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x08: { drawingOrder = new GSPS_SetPatternSet(); dotLength = 2; } break; case 0x0a: { drawingOrder = new GSCOL_SetColor(); dotLength = 2; } break; case 0x0c: { drawingOrder = new GSMX_SetMix(); dotLength = 2; } break; case 0x0d: { drawingOrder = new GSBMX_SetBackgroundMix(); dotLength = 2; } break; case 0x11: { drawingOrder = new GSFLW_SetFractionLineWidth(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x18: { drawingOrder = new GSLT_SetLineType(); dotLength = 2; } break; case 0x19: { drawingOrder = new GSLW_SetLineWidth(); dotLength = 2; } break; case 0x1a: { drawingOrder = new GSLE_SetLineEnd(); dotLength = 2; } break; case 0x1b: { drawingOrder = new GSLJ_SetLineJoin(); dotLength = 2; } break; case 0x21: { drawingOrder = new GSCP_SetCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x22: { drawingOrder = new GSAP_SetArcParameters(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x26: { drawingOrder = new GSECOL_SetExtendedColor(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x28: { drawingOrder = new GSPT_SetPatternSymbol(); dotLength = 2; } break; case 0x29: { drawingOrder = new GSMT_SetMarkerSymbol(); dotLength = 2; } break; case 0x33: { drawingOrder = new GSCC_SetCharacterCell(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x34: { drawingOrder = new GSCA_SetCharacterAngle(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x35: { drawingOrder = new GSCH_SetCharacterShear(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x37: { drawingOrder = new GSMC_SetMarkerCell(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x38: { drawingOrder = new GSCS_SetCharacterSet(); dotLength = 2; } break; case 0x39: { drawingOrder = new GSCR_SetCharacterPrecision(); dotLength = 2; } break; case 0x3a: { drawingOrder = new GSCD_SetCharacterDirection(); dotLength = 2; } break; case 0x3b: { drawingOrder = new GSMP_SetMarkerPrecision(); dotLength = 2; } break; case 0x3c: { drawingOrder = new GSMS_SetMarkerSet(); dotLength = 2; } break; case 0x3e: { drawingOrder = new GEPROL_EndProlog(); dotLength = 2; } break; case 0x60: { drawingOrder = new GEAR_EndArea(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x68: { drawingOrder = new GBAR_BeginArea(); dotLength = 2; } break; case 0x80: { drawingOrder = new GCBOX_BoxAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x81: { drawingOrder = new GCLINE_LineAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x82: { drawingOrder = new GCMRK_MarkerAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x83: { drawingOrder = new GCCHST_CharacterStringAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x85: { drawingOrder = new GCFLT_FilletAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x87: { drawingOrder = new GCFARC_FullArcAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x91: { drawingOrder = new GCBIMG_BeginImageAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x92: { drawingOrder = new GIMD_ImageData(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0x93: { drawingOrder = new GEIMD_EndImage(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xa1: { drawingOrder = new GCRLINE_RelativeLineAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xa3: { drawingOrder = new GCPARC_PartialArcAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xa5: { drawingOrder = new GCCBEZ_CubicBezierCurveAtCurrentPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xb2: { drawingOrder = new GSPCOL_SetProcessColor(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xc0: { drawingOrder = new GBOX_BoxAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xc1: { drawingOrder = new GLINE_LineAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xc2: { drawingOrder = new GMRK_MarkerAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xc3: { drawingOrder = new GCHST_CharacterStringAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xc5: { drawingOrder = new GFLT_FilletAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xc7: { drawingOrder = new GFARC_FullArcAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xd1: { drawingOrder = new GBIMG_BeginImageAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xe1: { drawingOrder = new GRLINE_RelativeLineAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xe3: { drawingOrder = new GPARC_PartialArcAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xe5: { drawingOrder = new GCBEZ_CubicBezierCurveAtGivenPosition(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 1, 1) + 2; } break; case 0xfe: { drawingOrder = new GEXO_ExtendedOrder(); dotLength = UtilBinaryDecoding.parseInt(sfData, offset + pos + 2, 2) + 4; } break; default: { drawingOrder = null; } break; } if (drawingOrder == null) { throw new AFPParserException("The drawing order code 0x" + Integer.toHexString(drawingOrderCode) + "is unknown."); } drawingOrder.decodeAFP(sfData, offset + pos, dotLength, config); drawingOrders.add(drawingOrder); pos += dotLength; } return drawingOrders; } @Override public void decodeAFP(byte[] sfData, int offset, int length, AFPParserConfiguration config) throws AFPParserException { } @Override public void writeAFP(OutputStream os, AFPParserConfiguration config) throws IOException { } public static class BeginSegment implements IAFPDecodeableWriteable { public static short COMMANDCODE_BeginSegment = 0x70; @AFPField short commandCode = COMMANDCODE_BeginSegment; @AFPField short lengtOfFollowingParameters = 0x0C; @AFPField String nameOfSegment; @AFPField byte flagAnyValue; @AFPField EnumSet segmentPropertiesFlags = EnumSet.noneOf(SegmentPropertiesFlag.class); @AFPField int segmentDataLength; @AFPField String nameOfPredecessorSuccessorSegment; @AFPField List drawingOrders; @Override public void decodeAFP(byte[] sfData, int offset, int length, AFPParserConfiguration config) throws AFPParserException { commandCode = UtilBinaryDecoding.parseShort(sfData, offset, 1); lengtOfFollowingParameters = UtilBinaryDecoding.parseShort(sfData, offset + 1, 1); nameOfSegment = new String(sfData, offset + 2, 4, Constants.cpIBM500); flagAnyValue = sfData[offset + 6]; segmentPropertiesFlags = SegmentPropertiesFlag.valueOF(sfData[offset + 7]); segmentDataLength = UtilBinaryDecoding.parseInt(sfData, offset + 8, 2); nameOfPredecessorSuccessorSegment = new String(sfData, offset + 10, 4, Constants.cpIBM500); if (segmentDataLength > 0) { drawingOrders = buildDrawingOrders(sfData, offset + 13, segmentDataLength, config); } else { drawingOrders = null; } } @Override public void writeAFP(OutputStream os, AFPParserConfiguration config) throws IOException { byte[] drawingOrdersData = null; os.write(commandCode); os.write(lengtOfFollowingParameters); os.write(nameOfSegment.getBytes(Constants.cpIBM500)); os.write(flagAnyValue); if (segmentPropertiesFlags != null) { os.write(SegmentPropertiesFlag.toByte(segmentPropertiesFlags)); } else { os.write(0x00); } if (drawingOrders != null && drawingOrders.size() > 0) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); for (GAD_DrawingOrder order : drawingOrders) { if (order == null) { continue; } order.writeAFP(baos, config); } drawingOrdersData = baos.toByteArray(); segmentDataLength = drawingOrdersData.length; } else { segmentDataLength = 0; } os.write(UtilBinaryDecoding.intToByteArray(segmentDataLength, 2)); os.write(nameOfPredecessorSuccessorSegment.getBytes(Constants.cpIBM500)); if (drawingOrdersData != null) { os.write(drawingOrdersData); } } /** * Sets the given {@link SegmentPropertiesFlag} and un-sets corresponding mutual exclusive * flags. * * @param flag {@link SegmentPropertiesFlag} to set. */ public void setSegmentPropertiesFlag(SegmentPropertiesFlag flag) { if (segmentPropertiesFlags == null) { segmentPropertiesFlags = EnumSet.noneOf(SegmentPropertiesFlag.class); } SegmentPropertiesFlag.setFlag(segmentPropertiesFlags, flag); } public short getCommandCode() { return commandCode; } public void setCommandCode(short commandCode) { this.commandCode = commandCode; } public short getLengtOfFollowingParameters() { return lengtOfFollowingParameters; } public void setLengtOfFollowingParameters(short lengtOfFollowingParameters) { this.lengtOfFollowingParameters = lengtOfFollowingParameters; } public String getNameOfSegment() { return nameOfSegment; } public void setNameOfSegment(String nameOfSegment) { this.nameOfSegment = nameOfSegment; } public byte getFlagAnyValue() { return flagAnyValue; } public void setFlagAnyValue(byte flagAnyValue) { this.flagAnyValue = flagAnyValue; } public EnumSet getSegmentPropertiesFlags() { return segmentPropertiesFlags; } public void setSegmentPropertiesFlags( EnumSet segmentPropertiesFlags) { this.segmentPropertiesFlags = segmentPropertiesFlags; } public int getSegmentDataLength() { return segmentDataLength; } public void setSegmentDataLength(int segmentDataLength) { this.segmentDataLength = segmentDataLength; } public String getNameOfPredecessorSuccessorSegment() { return nameOfPredecessorSuccessorSegment; } public void setNameOfPredecessorSuccessorSegment( String nameOfPredecessorSuccessorSegment) { this.nameOfPredecessorSuccessorSegment = nameOfPredecessorSuccessorSegment; } public List getDrawingOrders() { return drawingOrders; } public void setDrawingOrders(List drawingOrders) { this.drawingOrders = drawingOrders; } public enum SegmentPropertiesFlag implements IMutualExclusiveGroupedFlag { Chained(0), Unchained(0), NoProlog(1), Prolog(1), NewSegment(2), Reserved_01(2), Reserved_10(2), AppendToExisting(2); int group; SegmentPropertiesFlag(int group) { this.group = group; } public static EnumSet valueOF(byte flagsByte) { EnumSet result = EnumSet.noneOf(SegmentPropertiesFlag.class); if ((flagsByte & 0x80) == 0) { result.add(Chained); } else { result.add(Unchained); } if ((flagsByte & 0x10) == 0) { result.add(NoProlog); } else { result.add(Prolog); } int crap = (flagsByte >> 1) & 0x03; if (crap == 0x00) { result.add(NewSegment); } else if (crap == 0x01) { result.add(Reserved_01); } else if (crap == 0x02) { result.add(Reserved_10); } else if (crap == 0x03) { result.add(AppendToExisting); } return result; } public static int toByte(EnumSet flags) { int result = 0; if (flags.contains(Unchained)) { result |= 0x80; } if (flags.contains(Prolog)) { result |= 0x10; } if (flags.contains(Reserved_01)) { result += 2; } else if (flags.contains(Reserved_10)) { result += 4; } else if (flags.contains(AppendToExisting)) { result += 6; } return result; } public static void setFlag(EnumSet set, SegmentPropertiesFlag flag) { new MutualExclusiveGroupedFlagHandler().setFlag(set, flag); } @Override public int getGroup() { return group; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy