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.hssf.model;
019:
020: import org.apache.poi.ddf.*;
021: import org.apache.poi.hssf.record.ObjRecord;
022: import org.apache.poi.hssf.record.EscherAggregate;
023: import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
024: import org.apache.poi.hssf.record.EndSubRecord;
025: import org.apache.poi.hssf.usermodel.HSSFShape;
026: import org.apache.poi.hssf.usermodel.HSSFPolygon;
027: import org.apache.poi.util.LittleEndian;
028:
029: public class PolygonShape extends AbstractShape {
030: public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30;
031:
032: private EscherContainerRecord spContainer;
033: private ObjRecord objRecord;
034:
035: /**
036: * Creates the low evel records for an polygon.
037: *
038: * @param hssfShape The highlevel shape.
039: * @param shapeId The shape id to use for this shape.
040: */
041: PolygonShape(HSSFPolygon hssfShape, int shapeId) {
042: spContainer = createSpContainer(hssfShape, shapeId);
043: objRecord = createObjRecord(hssfShape, shapeId);
044: }
045:
046: /**
047: * Generates the shape records for this shape.
048: *
049: */
050: private EscherContainerRecord createSpContainer(
051: HSSFPolygon hssfShape, int shapeId) {
052: HSSFShape shape = hssfShape;
053:
054: EscherContainerRecord spContainer = new EscherContainerRecord();
055: EscherSpRecord sp = new EscherSpRecord();
056: EscherOptRecord opt = new EscherOptRecord();
057: EscherClientDataRecord clientData = new EscherClientDataRecord();
058:
059: spContainer.setRecordId(EscherContainerRecord.SP_CONTAINER);
060: spContainer.setOptions((short) 0x000F);
061: sp.setRecordId(EscherSpRecord.RECORD_ID);
062: sp.setOptions((short) ((EscherAggregate.ST_DONUT << 4) | 0x2));
063: sp.setShapeId(shapeId);
064: if (hssfShape.getParent() == null)
065: sp.setFlags(EscherSpRecord.FLAG_HAVEANCHOR
066: | EscherSpRecord.FLAG_HASSHAPETYPE);
067: else
068: sp.setFlags(EscherSpRecord.FLAG_CHILD
069: | EscherSpRecord.FLAG_HAVEANCHOR
070: | EscherSpRecord.FLAG_HASSHAPETYPE);
071: opt.setRecordId(EscherOptRecord.RECORD_ID);
072: opt.addEscherProperty(new EscherSimpleProperty(
073: EscherProperties.TRANSFORM__ROTATION, false, false, 0));
074: opt.addEscherProperty(new EscherSimpleProperty(
075: EscherProperties.GEOMETRY__RIGHT, false, false,
076: hssfShape.getDrawAreaWidth()));
077: opt.addEscherProperty(new EscherSimpleProperty(
078: EscherProperties.GEOMETRY__BOTTOM, false, false,
079: hssfShape.getDrawAreaHeight()));
080: opt.addEscherProperty(new EscherShapePathProperty(
081: EscherProperties.GEOMETRY__SHAPEPATH,
082: EscherShapePathProperty.COMPLEX));
083: EscherArrayProperty verticesProp = new EscherArrayProperty(
084: EscherProperties.GEOMETRY__VERTICES, false, new byte[0]);
085: verticesProp
086: .setNumberOfElementsInArray(hssfShape.getXPoints().length + 1);
087: verticesProp
088: .setNumberOfElementsInMemory(hssfShape.getXPoints().length + 1);
089: verticesProp.setSizeOfElements(0xFFF0);
090: for (int i = 0; i < hssfShape.getXPoints().length; i++) {
091: byte[] data = new byte[4];
092: LittleEndian.putShort(data, 0, (short) hssfShape
093: .getXPoints()[i]);
094: LittleEndian.putShort(data, 2, (short) hssfShape
095: .getYPoints()[i]);
096: verticesProp.setElement(i, data);
097: }
098: int point = hssfShape.getXPoints().length;
099: byte[] data = new byte[4];
100: LittleEndian.putShort(data, 0,
101: (short) hssfShape.getXPoints()[0]);
102: LittleEndian.putShort(data, 2,
103: (short) hssfShape.getYPoints()[0]);
104: verticesProp.setElement(point, data);
105: opt.addEscherProperty(verticesProp);
106: EscherArrayProperty segmentsProp = new EscherArrayProperty(
107: EscherProperties.GEOMETRY__SEGMENTINFO, false, null);
108: segmentsProp.setSizeOfElements(0x0002);
109: segmentsProp
110: .setNumberOfElementsInArray(hssfShape.getXPoints().length * 2 + 4);
111: segmentsProp
112: .setNumberOfElementsInMemory(hssfShape.getXPoints().length * 2 + 4);
113: segmentsProp.setElement(0, new byte[] { (byte) 0x00,
114: (byte) 0x40 });
115: segmentsProp.setElement(1, new byte[] { (byte) 0x00,
116: (byte) 0xAC });
117: for (int i = 0; i < hssfShape.getXPoints().length; i++) {
118: segmentsProp.setElement(2 + i * 2, new byte[] {
119: (byte) 0x01, (byte) 0x00 });
120: segmentsProp.setElement(3 + i * 2, new byte[] {
121: (byte) 0x00, (byte) 0xAC });
122: }
123: segmentsProp.setElement(segmentsProp
124: .getNumberOfElementsInArray() - 2, new byte[] {
125: (byte) 0x01, (byte) 0x60 });
126: segmentsProp.setElement(segmentsProp
127: .getNumberOfElementsInArray() - 1, new byte[] {
128: (byte) 0x00, (byte) 0x80 });
129: opt.addEscherProperty(segmentsProp);
130: opt.addEscherProperty(new EscherSimpleProperty(
131: EscherProperties.GEOMETRY__FILLOK, false, false,
132: 0x00010001));
133: opt.addEscherProperty(new EscherSimpleProperty(
134: EscherProperties.LINESTYLE__LINESTARTARROWHEAD, false,
135: false, 0x0));
136: opt.addEscherProperty(new EscherSimpleProperty(
137: EscherProperties.LINESTYLE__LINEENDARROWHEAD, false,
138: false, 0x0));
139: opt.addEscherProperty(new EscherSimpleProperty(
140: EscherProperties.LINESTYLE__LINEENDCAPSTYLE, false,
141: false, 0x0));
142:
143: addStandardOptions(shape, opt);
144:
145: EscherRecord anchor = createAnchor(shape.getAnchor());
146: clientData.setRecordId(EscherClientDataRecord.RECORD_ID);
147: clientData.setOptions((short) 0x0000);
148:
149: spContainer.addChildRecord(sp);
150: spContainer.addChildRecord(opt);
151: spContainer.addChildRecord(anchor);
152: spContainer.addChildRecord(clientData);
153:
154: return spContainer;
155: }
156:
157: /**
158: * Creates the low level OBJ record for this shape.
159: */
160: private ObjRecord createObjRecord(HSSFShape hssfShape, int shapeId) {
161: HSSFShape shape = hssfShape;
162:
163: ObjRecord obj = new ObjRecord();
164: CommonObjectDataSubRecord c = new CommonObjectDataSubRecord();
165: c.setObjectType(OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING);
166: c.setObjectId((short) (shapeId));
167: c.setLocked(true);
168: c.setPrintable(true);
169: c.setAutofill(true);
170: c.setAutoline(true);
171: EndSubRecord e = new EndSubRecord();
172:
173: obj.addSubRecord(c);
174: obj.addSubRecord(e);
175:
176: return obj;
177: }
178:
179: public EscherContainerRecord getSpContainer() {
180: return spContainer;
181: }
182:
183: public ObjRecord getObjRecord() {
184: return objRecord;
185: }
186:
187: }
|