123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- /* ====================================================================
- 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.hssf.usermodel;
-
- import org.apache.poi.ddf.*;
- import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
- import org.apache.poi.hssf.record.ObjRecord;
- import org.apache.poi.util.LittleEndian;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.util.Iterator;
-
- /**
- * An abstract shape.
- *
- * @author Glen Stampoultzis (glens at apache.org)
- */
- public abstract class HSSFShape {
- public static final int LINEWIDTH_ONE_PT = 12700;
- public static final int LINEWIDTH_DEFAULT = 9525;
- public static final int LINESTYLE__COLOR_DEFAULT = 0x08000040;
- public static final int FILL__FILLCOLOR_DEFAULT = 0x08000009;
- public static final boolean NO_FILL_DEFAULT = true;
-
- public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen
- public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style
- public static final int LINESTYLE_DOTSYS = 2; // PS_DOT system dash style
- public static final int LINESTYLE_DASHDOTSYS = 3; // PS_DASHDOT system dash style
- public static final int LINESTYLE_DASHDOTDOTSYS = 4; // PS_DASHDOTDOT system dash style
- public static final int LINESTYLE_DOTGEL = 5; // square dot style
- public static final int LINESTYLE_DASHGEL = 6; // dash style
- public static final int LINESTYLE_LONGDASHGEL = 7; // long dash style
- public static final int LINESTYLE_DASHDOTGEL = 8; // dash short dash
- public static final int LINESTYLE_LONGDASHDOTGEL = 9; // long dash short dash
- public static final int LINESTYLE_LONGDASHDOTDOTGEL = 10; // long dash short dash short dash
- public static final int LINESTYLE_NONE = -1;
-
- public static final int LINESTYLE_DEFAULT = LINESTYLE_NONE;
-
- // TODO - make all these fields private
- HSSFShape parent;
- HSSFAnchor anchor;
- HSSFPatriarch _patriarch;
-
- private final EscherContainerRecord _escherContainer;
- private final ObjRecord _objRecord;
- private final EscherOptRecord _optRecord;
-
- public final static int NO_FILLHITTEST_TRUE = 0x00110000;
- public final static int NO_FILLHITTEST_FALSE = 0x00010000;
-
- public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
- this._escherContainer = spContainer;
- this._objRecord = objRecord;
- this._optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID);
- this.anchor = HSSFAnchor.createAnchorFromEscher(spContainer);
- }
-
- /**
- * Create a new shape with the specified parent and anchor.
- */
- public HSSFShape(HSSFShape parent, HSSFAnchor anchor) {
- this.parent = parent;
- this.anchor = anchor;
- this._escherContainer = createSpContainer();
- _optRecord = _escherContainer.getChildById(EscherOptRecord.RECORD_ID);
- _objRecord = createObjRecord();
-
- }
-
- protected abstract EscherContainerRecord createSpContainer();
-
- protected abstract ObjRecord createObjRecord();
-
- protected abstract void afterRemove(HSSFPatriarch patriarch);
-
- protected void removeEscherProperty(EscherOptRecord opt, int num){
- for ( Iterator<EscherProperty> iterator = opt.getEscherProperties().iterator(); iterator.hasNext(); ) {
- EscherProperty prop = iterator.next();
- if (prop.getPropertyNumber() == num){
- iterator.remove();
- }
- }
- }
-
- void setShapeId(int shapeId){
- EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
- spRecord.setShapeId(shapeId);
- CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
- cod.setObjectId((short) (shapeId%1024));
- }
-
- int getShapeId(){
- return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
- }
-
- abstract void afterInsert(HSSFPatriarch patriarch);
-
- public EscherContainerRecord getEscherContainer() {
- return _escherContainer;
- }
-
- public ObjRecord getObjRecord() {
- return _objRecord;
- }
-
- public EscherOptRecord getOptRecord() {
- return _optRecord;
- }
-
- /**
- * Gets the parent shape.
- */
- public HSSFShape getParent() {
- return parent;
- }
-
- /**
- * @return the anchor that is used by this shape.
- */
- public HSSFAnchor getAnchor() {
- return anchor;
- }
-
- /**
- * Sets a particular anchor. A top-level shape must have an anchor of
- * HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor
- *
- * @param anchor the anchor to use.
- * @throws IllegalArgumentException when the wrong anchor is used for
- * this particular shape.
- * @see HSSFChildAnchor
- * @see HSSFClientAnchor
- */
- public void setAnchor(HSSFAnchor anchor) {
- int i = 0;
- int recordId = -1;
- if (parent == null) {
- if (anchor instanceof HSSFChildAnchor)
- throw new IllegalArgumentException("Must use client anchors for shapes directly attached to sheet.");
- EscherClientAnchorRecord anch = _escherContainer.getChildById(EscherClientAnchorRecord.RECORD_ID);
- if (null != anch) {
- for (i=0; i< _escherContainer.getChildRecords().size(); i++){
- if (_escherContainer.getChild(i).getRecordId() == EscherClientAnchorRecord.RECORD_ID){
- if (i != _escherContainer.getChildRecords().size() -1){
- recordId = _escherContainer.getChild(i+1).getRecordId();
- }
- }
- }
- _escherContainer.removeChildRecord(anch);
- }
- } else {
- if (anchor instanceof HSSFClientAnchor)
- throw new IllegalArgumentException("Must use child anchors for shapes attached to groups.");
- EscherChildAnchorRecord anch = _escherContainer.getChildById(EscherChildAnchorRecord.RECORD_ID);
- if (null != anch) {
- for (i=0; i< _escherContainer.getChildRecords().size(); i++){
- if (_escherContainer.getChild(i).getRecordId() == EscherChildAnchorRecord.RECORD_ID){
- if (i != _escherContainer.getChildRecords().size() -1){
- recordId = _escherContainer.getChild(i+1).getRecordId();
- }
- }
- }
- _escherContainer.removeChildRecord(anch);
- }
- }
- if (-1 == recordId){
- _escherContainer.addChildRecord(anchor.getEscherAnchor());
- } else {
- _escherContainer.addChildBefore(anchor.getEscherAnchor(), recordId);
- }
- this.anchor = anchor;
- }
-
- /**
- * The color applied to the lines of this shape.
- */
- public int getLineStyleColor() {
- EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR);
- return rgbProperty == null ? LINESTYLE__COLOR_DEFAULT : rgbProperty.getRgbColor();
- }
-
- /**
- * The color applied to the lines of this shape.
- */
- public void setLineStyleColor(int lineStyleColor) {
- setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
- }
-
- /**
- * The color applied to the lines of this shape.
- */
- public void setLineStyleColor(int red, int green, int blue) {
- int lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
- setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
- }
-
- /**
- * The color used to fill this shape.
- */
- public int getFillColor() {
- EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR);
- return rgbProperty == null ? FILL__FILLCOLOR_DEFAULT : rgbProperty.getRgbColor();
- }
-
- /**
- * The color used to fill this shape.
- */
- public void setFillColor(int fillColor) {
- setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
- }
-
- /**
- * The color used to fill this shape.
- */
- public void setFillColor(int red, int green, int blue) {
- int fillColor = ((blue) << 16) | ((green) << 8) | red;
- setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
- }
-
- /**
- * @return returns with width of the line in EMUs. 12700 = 1 pt.
- */
- public int getLineWidth() {
- EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH);
- return property == null ? LINEWIDTH_DEFAULT: property.getPropertyValue();
- }
-
- /**
- * Sets the width of the line. 12700 = 1 pt.
- *
- * @param lineWidth width in EMU's. 12700EMU's = 1 pt
- * @see HSSFShape#LINEWIDTH_ONE_PT
- */
- public void setLineWidth(int lineWidth) {
- setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth));
- }
-
- /**
- * @return One of the constants in LINESTYLE_*
- */
- public int getLineStyle() {
- EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING);
- if (null == property){
- return LINESTYLE_DEFAULT;
- }
- return property.getPropertyValue();
- }
-
- /**
- * Sets the line style.
- *
- * @param lineStyle One of the constants in LINESTYLE_*
- */
- public void setLineStyle(int lineStyle) {
- setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle));
- if (getLineStyle() != HSSFShape.LINESTYLE_SOLID) {
- setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEENDCAPSTYLE, 0));
- if (getLineStyle() == HSSFShape.LINESTYLE_NONE){
- setPropertyValue(new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080000));
- } else {
- setPropertyValue( new EscherBoolProperty( EscherProperties.LINESTYLE__NOLINEDRAWDASH, 0x00080008));
- }
- }
- }
-
- /**
- * @return <code>true</code> if this shape is not filled with a color.
- */
- public boolean isNoFill() {
- EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
- return property == null ? NO_FILL_DEFAULT : property.getPropertyValue() == NO_FILLHITTEST_TRUE;
- }
-
- /**
- * Sets whether this shape is filled or transparent.
- */
- public void setNoFill(boolean noFill) {
- setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? NO_FILLHITTEST_TRUE : NO_FILLHITTEST_FALSE));
- }
-
- protected void setPropertyValue(EscherProperty property){
- _optRecord.setEscherProperty(property);
- }
-
- public void setFlipVertical(boolean value){
- EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
- if (value){
- sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPVERT);
- } else {
- sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPVERT));
- }
- }
-
- public void setFlipHorizontal(boolean value){
- EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
- if (value){
- sp.setFlags(sp.getFlags() | EscherSpRecord.FLAG_FLIPHORIZ);
- } else {
- sp.setFlags(sp.getFlags() & (Integer.MAX_VALUE - EscherSpRecord.FLAG_FLIPHORIZ));
- }
- }
-
- public boolean isFlipVertical(){
- EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
- return (sp.getFlags() & EscherSpRecord.FLAG_FLIPVERT) != 0;
- }
-
- public boolean isFlipHorizontal(){
- EscherSpRecord sp = getEscherContainer().getChildById(EscherSpRecord.RECORD_ID);
- return (sp.getFlags() & EscherSpRecord.FLAG_FLIPHORIZ) != 0;
- }
-
- public int getRotationDegree(){
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- EscherSimpleProperty property = getOptRecord().lookup(EscherProperties.TRANSFORM__ROTATION);
- if (null == property){
- return 0;
- }
- try {
- LittleEndian.putInt(property.getPropertyValue(), bos);
- return LittleEndian.getShort(bos.toByteArray(), 2);
- } catch (IOException e) {
- e.printStackTrace();
- return 0;
- }
- }
-
- public void setRotationDegree(short value){
- setPropertyValue(new EscherSimpleProperty(EscherProperties.TRANSFORM__ROTATION , (value << 16)));
- }
-
- /**
- * Count of all children and their children's children.
- */
- public int countOfAllChildren() {
- return 1;
- }
-
- public abstract HSSFShape cloneShape();
- }
|