Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

HSSFShape.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hssf.usermodel;
  16. import org.apache.poi.ddf.*;
  17. import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
  18. import org.apache.poi.hssf.record.ObjRecord;
  19. /**
  20. * An abstract shape.
  21. *
  22. * @author Glen Stampoultzis (glens at apache.org)
  23. */
  24. public abstract class HSSFShape {
  25. public static final int LINEWIDTH_ONE_PT = 12700;
  26. public static final int LINEWIDTH_DEFAULT = 9525;
  27. public static final int LINESTYLE__COLOR_DEFAULT = 0x08000040;
  28. public static final int FILL__FILLCOLOR_DEFAULT = 0x08000009;
  29. public static final boolean NO_FILL_DEFAULT = true;
  30. public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen
  31. public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style
  32. public static final int LINESTYLE_DOTSYS = 2; // PS_DOT system dash style
  33. public static final int LINESTYLE_DASHDOTSYS = 3; // PS_DASHDOT system dash style
  34. public static final int LINESTYLE_DASHDOTDOTSYS = 4; // PS_DASHDOTDOT system dash style
  35. public static final int LINESTYLE_DOTGEL = 5; // square dot style
  36. public static final int LINESTYLE_DASHGEL = 6; // dash style
  37. public static final int LINESTYLE_LONGDASHGEL = 7; // long dash style
  38. public static final int LINESTYLE_DASHDOTGEL = 8; // dash short dash
  39. public static final int LINESTYLE_LONGDASHDOTGEL = 9; // long dash short dash
  40. public static final int LINESTYLE_LONGDASHDOTDOTGEL = 10; // long dash short dash short dash
  41. public static final int LINESTYLE_NONE = -1;
  42. public static final int LINESTYLE_DEFAULT = LINESTYLE_NONE;
  43. // TODO - make all these fields private
  44. HSSFShape parent;
  45. HSSFAnchor anchor;
  46. HSSFPatriarch _patriarch;
  47. protected EscherContainerRecord _escherContainer;
  48. protected ObjRecord _objRecord;
  49. protected final EscherOptRecord _optRecord;
  50. public HSSFShape(EscherContainerRecord spContainer, ObjRecord objRecord) {
  51. this._escherContainer = spContainer;
  52. this._objRecord = objRecord;
  53. this._optRecord = spContainer.getChildById(EscherOptRecord.RECORD_ID);
  54. this.anchor = HSSFAnchor.createAnchorFromEscher(spContainer);
  55. }
  56. /**
  57. * Create a new shape with the specified parent and anchor.
  58. */
  59. public HSSFShape(HSSFShape parent, HSSFAnchor anchor) {
  60. this.parent = parent;
  61. this.anchor = anchor;
  62. this._escherContainer = new EscherContainerRecord();
  63. _optRecord = new EscherOptRecord();
  64. _optRecord.setRecordId( EscherOptRecord.RECORD_ID );
  65. _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, LINESTYLE_SOLID));
  66. _optRecord.addEscherProperty(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, LINEWIDTH_DEFAULT));
  67. _optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, FILL__FILLCOLOR_DEFAULT));
  68. _optRecord.addEscherProperty(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, LINESTYLE__COLOR_DEFAULT));
  69. _optRecord.addEscherProperty(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, 0x0));
  70. }
  71. protected abstract EscherContainerRecord createSpContainer();
  72. protected abstract ObjRecord createObjRecord();
  73. void setShapeId(int shapeId){
  74. EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
  75. spRecord.setShapeId(shapeId);
  76. CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
  77. cod.setObjectId((short) (shapeId-1024));
  78. }
  79. int getShapeId(){
  80. return ((EscherSpRecord)_escherContainer.getChildById(EscherSpRecord.RECORD_ID)).getShapeId();
  81. }
  82. void afterInsert(HSSFPatriarch patriarch){
  83. }
  84. public EscherContainerRecord getEscherContainer() {
  85. return _escherContainer;
  86. }
  87. public ObjRecord getObjRecord() {
  88. return _objRecord;
  89. }
  90. /**
  91. * Gets the parent shape.
  92. */
  93. public HSSFShape getParent() {
  94. return parent;
  95. }
  96. /**
  97. * @return the anchor that is used by this shape.
  98. */
  99. public HSSFAnchor getAnchor() {
  100. return anchor;
  101. }
  102. /**
  103. * Sets a particular anchor. A top-level shape must have an anchor of
  104. * HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor
  105. *
  106. * @param anchor the anchor to use.
  107. * @throws IllegalArgumentException when the wrong anchor is used for
  108. * this particular shape.
  109. * @see HSSFChildAnchor
  110. * @see HSSFClientAnchor
  111. */
  112. public void setAnchor(HSSFAnchor anchor) {
  113. int i = 0;
  114. int recordId = -1;
  115. if (parent == null) {
  116. if (anchor instanceof HSSFChildAnchor)
  117. throw new IllegalArgumentException("Must use client anchors for shapes directly attached to sheet.");
  118. EscherClientAnchorRecord anch = _escherContainer.getChildById(EscherClientAnchorRecord.RECORD_ID);
  119. if (null != anch) {
  120. for (i=0; i< _escherContainer.getChildRecords().size(); i++){
  121. if (_escherContainer.getChild(i).getRecordId() == EscherClientAnchorRecord.RECORD_ID){
  122. if (i != _escherContainer.getChildRecords().size() -1){
  123. recordId = _escherContainer.getChild(i+1).getRecordId();
  124. }
  125. }
  126. }
  127. _escherContainer.removeChildRecord(anch);
  128. }
  129. } else {
  130. if (anchor instanceof HSSFClientAnchor)
  131. throw new IllegalArgumentException("Must use child anchors for shapes attached to groups.");
  132. EscherChildAnchorRecord anch = _escherContainer.getChildById(EscherChildAnchorRecord.RECORD_ID);
  133. if (null != anch) {
  134. for (i=0; i< _escherContainer.getChildRecords().size(); i++){
  135. if (_escherContainer.getChild(i).getRecordId() == EscherChildAnchorRecord.RECORD_ID){
  136. if (i != _escherContainer.getChildRecords().size() -1){
  137. recordId = _escherContainer.getChild(i+1).getRecordId();
  138. }
  139. }
  140. }
  141. _escherContainer.removeChildRecord(anch);
  142. }
  143. }
  144. if (-1 == recordId){
  145. _escherContainer.addChildRecord(anchor.getEscherAnchor());
  146. } else {
  147. _escherContainer.addChildBefore(anchor.getEscherAnchor(), recordId);
  148. }
  149. this.anchor = anchor;
  150. }
  151. /**
  152. * The color applied to the lines of this shape.
  153. */
  154. public int getLineStyleColor() {
  155. EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.LINESTYLE__COLOR);
  156. return rgbProperty == null ? LINESTYLE__COLOR_DEFAULT : rgbProperty.getRgbColor();
  157. }
  158. /**
  159. * The color applied to the lines of this shape.
  160. */
  161. public void setLineStyleColor(int lineStyleColor) {
  162. setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
  163. }
  164. /**
  165. * The color applied to the lines of this shape.
  166. */
  167. public void setLineStyleColor(int red, int green, int blue) {
  168. int lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
  169. setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
  170. }
  171. /**
  172. * The color used to fill this shape.
  173. */
  174. public int getFillColor() {
  175. EscherRGBProperty rgbProperty = _optRecord.lookup(EscherProperties.FILL__FILLCOLOR);
  176. return rgbProperty == null ? FILL__FILLCOLOR_DEFAULT : rgbProperty.getRgbColor();
  177. }
  178. /**
  179. * The color used to fill this shape.
  180. */
  181. public void setFillColor(int fillColor) {
  182. setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
  183. }
  184. /**
  185. * The color used to fill this shape.
  186. */
  187. public void setFillColor(int red, int green, int blue) {
  188. int fillColor = ((blue) << 16) | ((green) << 8) | red;
  189. setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
  190. }
  191. /**
  192. * @return returns with width of the line in EMUs. 12700 = 1 pt.
  193. */
  194. public int getLineWidth() {
  195. EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEWIDTH);
  196. return property == null ? LINEWIDTH_DEFAULT: property.getPropertyValue();
  197. }
  198. /**
  199. * Sets the width of the line. 12700 = 1 pt.
  200. *
  201. * @param lineWidth width in EMU's. 12700EMU's = 1 pt
  202. * @see HSSFShape#LINEWIDTH_ONE_PT
  203. */
  204. public void setLineWidth(int lineWidth) {
  205. setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEWIDTH, lineWidth));
  206. }
  207. /**
  208. * @return One of the constants in LINESTYLE_*
  209. */
  210. public int getLineStyle() {
  211. EscherSimpleProperty property = _optRecord.lookup(EscherProperties.LINESTYLE__LINEDASHING);
  212. if (null == property){
  213. return LINESTYLE_DEFAULT;
  214. }
  215. return property.getPropertyValue();
  216. }
  217. /**
  218. * Sets the line style.
  219. *
  220. * @param lineStyle One of the constants in LINESTYLE_*
  221. */
  222. public void setLineStyle(int lineStyle) {
  223. setPropertyValue(new EscherSimpleProperty(EscherProperties.LINESTYLE__LINEDASHING, lineStyle));
  224. }
  225. /**
  226. * @return <code>true</code> if this shape is not filled with a color.
  227. */
  228. public boolean isNoFill() {
  229. EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
  230. return property == null ? NO_FILL_DEFAULT : property.isTrue();
  231. }
  232. /**
  233. * Sets whether this shape is filled or transparent.
  234. */
  235. public void setNoFill(boolean noFill) {
  236. setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? 1 : 0));
  237. }
  238. protected void setPropertyValue(EscherProperty property){
  239. if (null == _optRecord.lookup(property.getId())){
  240. _optRecord.addEscherProperty(property);
  241. } else {
  242. int i=0;
  243. for (EscherProperty prop: _optRecord.getEscherProperties()){
  244. if (prop.getId() == property.getId()){
  245. _optRecord.getEscherProperties().remove(i);
  246. break;
  247. }
  248. i++;
  249. }
  250. _optRecord.addEscherProperty(property);
  251. }
  252. }
  253. /**
  254. * Count of all children and their children's children.
  255. */
  256. public int countOfAllChildren() {
  257. return 1;
  258. }
  259. }