001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.ddf;
019:
020: import org.apache.poi.util.HexDump;
021: import org.apache.poi.util.LittleEndian;
022:
023: /**
024: * Together the the EscherOptRecord this record defines some of the basic
025: * properties of a shape.
026: *
027: * @author Glen Stampoultzis (glens at apache.org)
028: */
029: public class EscherSpRecord extends EscherRecord {
030: public static final short RECORD_ID = (short) 0xF00A;
031: public static final String RECORD_DESCRIPTION = "MsofbtSp";
032:
033: public static final int FLAG_GROUP = 0x0001;
034: public static final int FLAG_CHILD = 0x0002;
035: public static final int FLAG_PATRIARCH = 0x0004;
036: public static final int FLAG_DELETED = 0x0008;
037: public static final int FLAG_OLESHAPE = 0x0010;
038: public static final int FLAG_HAVEMASTER = 0x0020;
039: public static final int FLAG_FLIPHORIZ = 0x0040;
040: public static final int FLAG_FLIPVERT = 0x0080;
041: public static final int FLAG_CONNECTOR = 0x0100;
042: public static final int FLAG_HAVEANCHOR = 0x0200;
043: public static final int FLAG_BACKGROUND = 0x0400;
044: public static final int FLAG_HASSHAPETYPE = 0x0800;
045:
046: private int field_1_shapeId;
047: private int field_2_flags;
048:
049: /**
050: * This method deserializes the record from a byte array.
051: *
052: * @param data The byte array containing the escher record information
053: * @param offset The starting offset into <code>data</code>.
054: * @param recordFactory May be null since this is not a container record.
055: * @return The number of bytes read from the byte array.
056: */
057: public int fillFields(byte[] data, int offset,
058: EscherRecordFactory recordFactory) {
059: int bytesRemaining = readHeader(data, offset);
060: int pos = offset + 8;
061: int size = 0;
062: field_1_shapeId = LittleEndian.getInt(data, pos + size);
063: size += 4;
064: field_2_flags = LittleEndian.getInt(data, pos + size);
065: size += 4;
066: // bytesRemaining -= size;
067: // remainingData = new byte[bytesRemaining];
068: // System.arraycopy( data, pos + size, remainingData, 0, bytesRemaining );
069: return getRecordSize();
070: }
071:
072: /**
073: * This method serializes this escher record into a byte array.
074: *
075: * @param offset The offset into <code>data</code> to start writing the record data to.
076: * @param data The byte array to serialize to.
077: * @param listener A listener to retrieve start and end callbacks. Use a <code>NullEscherSerailizationListener</code> to ignore these events.
078: * @return The number of bytes written.
079: *
080: * @see NullEscherSerializationListener
081: */
082: public int serialize(int offset, byte[] data,
083: EscherSerializationListener listener) {
084: listener.beforeRecordSerialize(offset, getRecordId(), this );
085: LittleEndian.putShort(data, offset, getOptions());
086: LittleEndian.putShort(data, offset + 2, getRecordId());
087: int remainingBytes = 8;
088: LittleEndian.putInt(data, offset + 4, remainingBytes);
089: LittleEndian.putInt(data, offset + 8, field_1_shapeId);
090: LittleEndian.putInt(data, offset + 12, field_2_flags);
091: // System.arraycopy( remainingData, 0, data, offset + 26, remainingData.length );
092: // int pos = offset + 8 + 18 + remainingData.length;
093: listener.afterRecordSerialize(offset + getRecordSize(),
094: getRecordId(), getRecordSize(), this );
095: return 8 + 8;
096: }
097:
098: /**
099: * Returns the number of bytes that are required to serialize this record.
100: *
101: * @return Number of bytes
102: */
103: public int getRecordSize() {
104: return 8 + 8;
105: }
106:
107: /**
108: * @return the 16 bit identifier for this record.
109: */
110: public short getRecordId() {
111: return RECORD_ID;
112: }
113:
114: /**
115: * The short name for this record
116: */
117: public String getRecordName() {
118: return "Sp";
119: }
120:
121: /**
122: * @return the string representing this shape.
123: */
124: public String toString() {
125: String nl = System.getProperty("line.separator");
126:
127: return getClass().getName() + ":" + nl + " RecordId: 0x"
128: + HexDump.toHex(RECORD_ID) + nl + " Options: 0x"
129: + HexDump.toHex(getOptions()) + nl + " ShapeId: "
130: + field_1_shapeId + nl + " Flags: "
131: + decodeFlags(field_2_flags) + " (0x"
132: + HexDump.toHex(field_2_flags) + ")" + nl;
133:
134: }
135:
136: /**
137: * Converts the shape flags into a more descriptive name.
138: */
139: private String decodeFlags(int flags) {
140: StringBuffer result = new StringBuffer();
141: result.append((flags & FLAG_GROUP) != 0 ? "|GROUP" : "");
142: result.append((flags & FLAG_CHILD) != 0 ? "|CHILD" : "");
143: result
144: .append((flags & FLAG_PATRIARCH) != 0 ? "|PATRIARCH"
145: : "");
146: result.append((flags & FLAG_DELETED) != 0 ? "|DELETED" : "");
147: result.append((flags & FLAG_OLESHAPE) != 0 ? "|OLESHAPE" : "");
148: result.append((flags & FLAG_HAVEMASTER) != 0 ? "|HAVEMASTER"
149: : "");
150: result
151: .append((flags & FLAG_FLIPHORIZ) != 0 ? "|FLIPHORIZ"
152: : "");
153: result.append((flags & FLAG_FLIPVERT) != 0 ? "|FLIPVERT" : "");
154: result
155: .append((flags & FLAG_CONNECTOR) != 0 ? "|CONNECTOR"
156: : "");
157: result.append((flags & FLAG_HAVEANCHOR) != 0 ? "|HAVEANCHOR"
158: : "");
159: result.append((flags & FLAG_BACKGROUND) != 0 ? "|BACKGROUND"
160: : "");
161: result
162: .append((flags & FLAG_HASSHAPETYPE) != 0 ? "|HASSHAPETYPE"
163: : "");
164:
165: //need to check, else blows up on some records - bug 34435
166: if (result.length() > 0) {
167: result.deleteCharAt(0);
168: }
169: return result.toString();
170: }
171:
172: /**
173: * @return A number that identifies this shape
174: */
175: public int getShapeId() {
176: return field_1_shapeId;
177: }
178:
179: /**
180: * Sets a number that identifies this shape.
181: */
182: public void setShapeId(int field_1_shapeId) {
183: this .field_1_shapeId = field_1_shapeId;
184: }
185:
186: /**
187: * The flags that apply to this shape.
188: *
189: * @see #FLAG_GROUP
190: * @see #FLAG_CHILD
191: * @see #FLAG_PATRIARCH
192: * @see #FLAG_DELETED
193: * @see #FLAG_OLESHAPE
194: * @see #FLAG_HAVEMASTER
195: * @see #FLAG_FLIPHORIZ
196: * @see #FLAG_FLIPVERT
197: * @see #FLAG_CONNECTOR
198: * @see #FLAG_HAVEANCHOR
199: * @see #FLAG_BACKGROUND
200: * @see #FLAG_HASSHAPETYPE
201: */
202: public int getFlags() {
203: return field_2_flags;
204: }
205:
206: /**
207: * The flags that apply to this shape.
208: *
209: * @see #FLAG_GROUP
210: * @see #FLAG_CHILD
211: * @see #FLAG_PATRIARCH
212: * @see #FLAG_DELETED
213: * @see #FLAG_OLESHAPE
214: * @see #FLAG_HAVEMASTER
215: * @see #FLAG_FLIPHORIZ
216: * @see #FLAG_FLIPVERT
217: * @see #FLAG_CONNECTOR
218: * @see #FLAG_HAVEANCHOR
219: * @see #FLAG_BACKGROUND
220: * @see #FLAG_HASSHAPETYPE
221: */
222: public void setFlags(int field_2_flags) {
223: this.field_2_flags = field_2_flags;
224: }
225: }
|