You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XSLFSimpleShape.java 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. /*
  2. * ====================================================================
  3. * Licensed to the Apache Software Foundation (ASF) under one or more
  4. * contributor license agreements. See the NOTICE file distributed with
  5. * this work for additional information regarding copyright ownership.
  6. * The ASF licenses this file to You under the Apache License, Version 2.0
  7. * (the "License"); you may not use this file except in compliance with
  8. * the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. * ====================================================================
  18. */
  19. package org.apache.poi.xslf.usermodel;
  20. import org.apache.poi.xslf.usermodel.LineCap;
  21. import org.apache.poi.xslf.usermodel.LineDash;
  22. import org.apache.poi.xslf.model.PropertyFetcher;
  23. import org.apache.poi.util.Beta;
  24. import org.apache.poi.util.Units;
  25. import org.apache.xmlbeans.XmlObject;
  26. import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
  27. import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
  28. import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
  29. import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
  30. import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
  31. import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
  32. import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
  33. import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
  34. import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
  35. import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
  36. import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
  37. import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
  38. import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
  39. import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
  40. import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
  41. import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
  42. import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
  43. import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;
  44. import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
  45. import org.openxmlformats.schemas.presentationml.x2006.main.STPlaceholderType;
  46. import java.awt.*;
  47. import java.awt.geom.Rectangle2D;
  48. /**
  49. * @author Yegor Kozlov
  50. */
  51. @Beta
  52. public abstract class XSLFSimpleShape extends XSLFShape {
  53. private final XmlObject _shape;
  54. private final XSLFSheet _sheet;
  55. private CTShapeProperties _spPr;
  56. private CTShapeStyle _spStyle;
  57. private CTNonVisualDrawingProps _nvPr;
  58. private CTPlaceholder _ph;
  59. /* package */XSLFSimpleShape(XmlObject shape, XSLFSheet sheet) {
  60. _shape = shape;
  61. _sheet = sheet;
  62. }
  63. public XmlObject getXmlObject() {
  64. return _shape;
  65. }
  66. public XSLFSheet getSheet() {
  67. return _sheet;
  68. }
  69. /**
  70. * TODO match STShapeType with
  71. * {@link org.apache.poi.sl.usermodel.ShapeTypes}
  72. */
  73. public int getShapeType() {
  74. CTPresetGeometry2D prst = getSpPr().getPrstGeom();
  75. STShapeType.Enum stEnum = prst == null ? null : prst.getPrst();
  76. return stEnum == null ? 0 : stEnum.intValue();
  77. }
  78. public String getShapeName() {
  79. return getNvPr().getName();
  80. }
  81. public int getShapeId() {
  82. return (int) getNvPr().getId();
  83. }
  84. protected CTNonVisualDrawingProps getNvPr() {
  85. if (_nvPr == null) {
  86. XmlObject[] rs = _shape
  87. .selectPath("declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr");
  88. if (rs.length != 0) {
  89. _nvPr = (CTNonVisualDrawingProps) rs[0];
  90. }
  91. }
  92. return _nvPr;
  93. }
  94. protected CTShapeProperties getSpPr() {
  95. if (_spPr == null) {
  96. for (XmlObject obj : _shape.selectPath("*")) {
  97. if (obj instanceof CTShapeProperties) {
  98. _spPr = (CTShapeProperties) obj;
  99. }
  100. }
  101. }
  102. if (_spPr == null) {
  103. throw new IllegalStateException("CTShapeProperties was not found.");
  104. }
  105. return _spPr;
  106. }
  107. protected CTShapeStyle getSpStyle() {
  108. if (_spStyle == null) {
  109. for (XmlObject obj : _shape.selectPath("*")) {
  110. if (obj instanceof CTShapeStyle) {
  111. _spStyle = (CTShapeStyle) obj;
  112. }
  113. }
  114. }
  115. return _spStyle;
  116. }
  117. protected CTPlaceholder getCTPlaceholder(){
  118. if(_ph == null){
  119. XmlObject[] obj = _shape.selectPath(
  120. "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:nvPr/p:ph");
  121. if(obj.length == 1){
  122. _ph = (CTPlaceholder)obj[0];
  123. }
  124. }
  125. return _ph;
  126. }
  127. private CTTransform2D getXfrm(){
  128. PropertyFetcher<CTTransform2D> fetcher = new PropertyFetcher<CTTransform2D>(){
  129. public boolean fetch(XSLFSimpleShape shape){
  130. CTShapeProperties pr = shape.getSpPr();
  131. if(pr.isSetXfrm()){
  132. setValue(pr.getXfrm());
  133. return true;
  134. }
  135. return false;
  136. }
  137. };
  138. fetchShapeProperty(fetcher);
  139. return fetcher.getValue();
  140. }
  141. public Rectangle2D getAnchor() {
  142. CTTransform2D xfrm = getXfrm();
  143. CTPoint2D off = xfrm.getOff();
  144. long x = off.getX();
  145. long y = off.getY();
  146. CTPositiveSize2D ext = xfrm.getExt();
  147. long cx = ext.getCx();
  148. long cy = ext.getCy();
  149. return new Rectangle2D.Double(
  150. Units.toPoints(x), Units.toPoints(y),
  151. Units.toPoints(cx), Units.toPoints(cy));
  152. }
  153. public void setAnchor(Rectangle2D anchor) {
  154. CTShapeProperties spPr = getSpPr();
  155. CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
  156. CTPoint2D off = xfrm.isSetOff() ? xfrm.getOff() : xfrm.addNewOff();
  157. long x = Units.toEMU(anchor.getX());
  158. long y = Units.toEMU(anchor.getY());
  159. off.setX(x);
  160. off.setY(y);
  161. CTPositiveSize2D ext = xfrm.isSetExt() ? xfrm.getExt() : xfrm
  162. .addNewExt();
  163. long cx = Units.toEMU(anchor.getWidth());
  164. long cy = Units.toEMU(anchor.getHeight());
  165. ext.setCx(cx);
  166. ext.setCy(cy);
  167. }
  168. /**
  169. * Rotate this shape.
  170. * <p>
  171. * Positive angles are clockwise (i.e., towards the positive y axis);
  172. * negative angles are counter-clockwise (i.e., towards the negative y
  173. * axis).
  174. * </p>
  175. *
  176. * @param theta the rotation angle in degrees.
  177. */
  178. public void setRotation(double theta) {
  179. CTShapeProperties spPr = getSpPr();
  180. CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
  181. xfrm.setRot((int) (theta * 60000));
  182. }
  183. /**
  184. * Rotation angle in degrees
  185. * <p>
  186. * Positive angles are clockwise (i.e., towards the positive y axis);
  187. * negative angles are counter-clockwise (i.e., towards the negative y
  188. * axis).
  189. * </p>
  190. *
  191. * @return rotation angle in degrees
  192. */
  193. public double getRotation() {
  194. CTTransform2D xfrm = getXfrm();
  195. return (double) xfrm.getRot() / 60000;
  196. }
  197. public void setFlipHorizontal(boolean flip) {
  198. CTShapeProperties spPr = getSpPr();
  199. CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
  200. xfrm.setFlipH(flip);
  201. }
  202. public void setFlipVertical(boolean flip) {
  203. CTShapeProperties spPr = getSpPr();
  204. CTTransform2D xfrm = spPr.isSetXfrm() ? spPr.getXfrm() : spPr.addNewXfrm();
  205. xfrm.setFlipV(flip);
  206. }
  207. /**
  208. * Whether the shape is horizontally flipped
  209. *
  210. * @return whether the shape is horizontally flipped
  211. */
  212. public boolean getFlipHorizontal() {
  213. return getXfrm().getFlipH();
  214. }
  215. public boolean getFlipVertical() {
  216. return getXfrm().getFlipV();
  217. }
  218. /**
  219. * Get line properties defined in the theme (if any)
  220. *
  221. * @return line propeties from the theme of null
  222. */
  223. CTLineProperties getDefaultLineProperties() {
  224. CTLineProperties ln = null;
  225. CTShapeStyle style = getSpStyle();
  226. if (style != null) {
  227. // 1-based index of a line style within the style matrix
  228. int idx = (int) style.getLnRef().getIdx();
  229. CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
  230. ln = styleMatrix.getLnStyleLst().getLnArray(idx - 1);
  231. }
  232. return ln;
  233. }
  234. public void setLineColor(Color color) {
  235. CTShapeProperties spPr = getSpPr();
  236. if (color == null) {
  237. if (spPr.isSetLn() && spPr.getLn().isSetSolidFill())
  238. spPr.getLn().unsetSolidFill();
  239. } else {
  240. CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
  241. .addNewLn();
  242. CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
  243. rgb.setVal(new byte[]{(byte) color.getRed(),
  244. (byte) color.getGreen(), (byte) color.getBlue()});
  245. CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln
  246. .getSolidFill() : ln.addNewSolidFill();
  247. fill.setSrgbClr(rgb);
  248. }
  249. }
  250. public Color getLineColor() {
  251. final XSLFTheme theme = _sheet.getTheme();
  252. PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
  253. public boolean fetch(XSLFSimpleShape shape){
  254. CTShapeProperties spPr = shape.getSpPr();
  255. CTLineProperties ln = spPr.getLn();
  256. if (ln != null) {
  257. if (ln.isSetNoFill()) {
  258. setValue(null);
  259. return true;
  260. }
  261. CTSolidColorFillProperties solidLine = ln.getSolidFill();
  262. if (solidLine != null) {
  263. setValue( theme.getSolidFillColor(ln.getSolidFill()) );
  264. return true;
  265. }
  266. }
  267. return false;
  268. }
  269. };
  270. fetchShapeProperty(fetcher);
  271. Color color = fetcher.getValue();
  272. if(color == null){
  273. // line color was not found, check if it is defined in the theme
  274. CTShapeStyle style = getSpStyle();
  275. if (style != null) {
  276. CTSchemeColor schemeColor = style.getLnRef().getSchemeClr();
  277. if (schemeColor != null) {
  278. color = theme.getSchemeColor(schemeColor);
  279. }
  280. }
  281. }
  282. return color;
  283. }
  284. public void setLineWidth(double width) {
  285. CTShapeProperties spPr = getSpPr();
  286. if (width == 0.) {
  287. if (spPr.isSetLn())
  288. spPr.getLn().unsetW();
  289. } else {
  290. CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
  291. .addNewLn();
  292. ln.setW(Units.toEMU(width));
  293. }
  294. }
  295. public double getLineWidth() {
  296. PropertyFetcher<Double> fetcher = new PropertyFetcher<Double>(){
  297. public boolean fetch(XSLFSimpleShape shape){
  298. CTShapeProperties spPr = shape.getSpPr();
  299. CTLineProperties ln = spPr.getLn();
  300. if (ln != null) {
  301. if (ln.isSetNoFill()) {
  302. setValue(0.);
  303. return true;
  304. }
  305. if (ln.isSetW()) {
  306. setValue( Units.toPoints(ln.getW()) );
  307. return true;
  308. }
  309. }
  310. return false;
  311. }
  312. };
  313. fetchShapeProperty(fetcher);
  314. double lineWidth = 0;
  315. if(fetcher.getValue() == null) {
  316. CTLineProperties defaultLn = getDefaultLineProperties();
  317. if (defaultLn != null) {
  318. if (defaultLn.isSetW()) lineWidth = Units.toPoints(defaultLn.getW());
  319. }
  320. } else {
  321. lineWidth = fetcher.getValue();
  322. }
  323. return lineWidth;
  324. }
  325. public void setLineDash(LineDash dash) {
  326. CTShapeProperties spPr = getSpPr();
  327. if (dash == null) {
  328. if (spPr.isSetLn())
  329. spPr.getLn().unsetPrstDash();
  330. } else {
  331. CTPresetLineDashProperties val = CTPresetLineDashProperties.Factory
  332. .newInstance();
  333. val.setVal(STPresetLineDashVal.Enum.forInt(dash.ordinal() + 1));
  334. CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
  335. .addNewLn();
  336. ln.setPrstDash(val);
  337. }
  338. }
  339. public LineDash getLineDash() {
  340. PropertyFetcher<LineDash> fetcher = new PropertyFetcher<LineDash>(){
  341. public boolean fetch(XSLFSimpleShape shape){
  342. CTShapeProperties spPr = shape.getSpPr();
  343. CTLineProperties ln = spPr.getLn();
  344. if (ln != null) {
  345. CTPresetLineDashProperties ctDash = ln.getPrstDash();
  346. if (ctDash != null) {
  347. setValue( LineDash.values()[ctDash.getVal().intValue() - 1] );
  348. return true;
  349. }
  350. }
  351. return false;
  352. }
  353. };
  354. fetchShapeProperty(fetcher);
  355. LineDash dash = fetcher.getValue();
  356. if(dash == null){
  357. CTLineProperties defaultLn = getDefaultLineProperties();
  358. if (defaultLn != null) {
  359. CTPresetLineDashProperties ctDash = defaultLn.getPrstDash();
  360. if (ctDash != null) {
  361. dash = LineDash.values()[ctDash.getVal().intValue() - 1];
  362. }
  363. }
  364. }
  365. return dash;
  366. }
  367. public void setLineCap(LineCap cap) {
  368. CTShapeProperties spPr = getSpPr();
  369. if (cap == null) {
  370. if (spPr.isSetLn())
  371. spPr.getLn().unsetCap();
  372. } else {
  373. CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
  374. .addNewLn();
  375. ln.setCap(STLineCap.Enum.forInt(cap.ordinal() + 1));
  376. }
  377. }
  378. public LineCap getLineCap() {
  379. PropertyFetcher<LineCap> fetcher = new PropertyFetcher<LineCap>(){
  380. public boolean fetch(XSLFSimpleShape shape){
  381. CTShapeProperties spPr = shape.getSpPr();
  382. CTLineProperties ln = spPr.getLn();
  383. if (ln != null) {
  384. STLineCap.Enum stCap = ln.getCap();
  385. if (stCap != null) {
  386. setValue( LineCap.values()[stCap.intValue() - 1] );
  387. return true;
  388. }
  389. }
  390. return false;
  391. }
  392. };
  393. fetchShapeProperty(fetcher);
  394. LineCap cap = fetcher.getValue();
  395. if(cap == null){
  396. CTLineProperties defaultLn = getDefaultLineProperties();
  397. if (defaultLn != null) {
  398. STLineCap.Enum stCap = defaultLn.getCap();
  399. if (stCap != null) {
  400. cap = LineCap.values()[stCap.intValue() - 1];
  401. }
  402. }
  403. }
  404. return cap;
  405. }
  406. /**
  407. * Specifies a solid color fill. The shape is filled entirely with the
  408. * specified color.
  409. *
  410. * @param color the solid color fill. The value of <code>null</code> unsets
  411. * the solidFIll attribute from the underlying xml
  412. */
  413. public void setFillColor(Color color) {
  414. CTShapeProperties spPr = getSpPr();
  415. if (color == null) {
  416. if (spPr.isSetSolidFill()) spPr.unsetSolidFill();
  417. if(!spPr.isSetNoFill()) spPr.addNewNoFill();
  418. } else {
  419. if(spPr.isSetNoFill()) spPr.unsetNoFill();
  420. CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr
  421. .getSolidFill() : spPr.addNewSolidFill();
  422. CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
  423. rgb.setVal(new byte[]{(byte) color.getRed(),
  424. (byte) color.getGreen(), (byte) color.getBlue()});
  425. fill.setSrgbClr(rgb);
  426. }
  427. }
  428. /**
  429. * @return solid fill color of null if not set
  430. */
  431. public Color getFillColor() {
  432. final XSLFTheme theme = _sheet.getTheme();
  433. PropertyFetcher<Color> fetcher = new PropertyFetcher<Color>(){
  434. public boolean fetch(XSLFSimpleShape shape){
  435. CTShapeProperties spPr = shape.getSpPr();
  436. if (spPr.isSetNoFill()) {
  437. setValue(null);
  438. return true;
  439. }
  440. if (spPr.isSetSolidFill()) {
  441. setValue( theme.getSolidFillColor(spPr.getSolidFill()) );
  442. return true;
  443. }
  444. return false;
  445. }
  446. };
  447. fetchShapeProperty(fetcher);
  448. Color color = fetcher.getValue();
  449. if(color == null){
  450. // fill color was not found, check if it is defined in the theme
  451. CTShapeStyle style = getSpStyle();
  452. if (style != null) {
  453. CTSchemeColor schemeColor = style.getFillRef().getSchemeClr();
  454. if (schemeColor != null) {
  455. color = theme.getSchemeColor(schemeColor);
  456. }
  457. }
  458. }
  459. return color;
  460. }
  461. public XSLFShadow getShadow(){
  462. PropertyFetcher<CTOuterShadowEffect> fetcher = new PropertyFetcher<CTOuterShadowEffect>(){
  463. public boolean fetch(XSLFSimpleShape shape){
  464. CTShapeProperties spPr = shape.getSpPr();
  465. if (spPr.isSetEffectLst()) {
  466. CTOuterShadowEffect obj = spPr.getEffectLst().getOuterShdw();
  467. setValue(obj);
  468. return true;
  469. }
  470. return false;
  471. }
  472. };
  473. fetchShapeProperty(fetcher);
  474. CTOuterShadowEffect obj = fetcher.getValue();
  475. if(obj == null){
  476. // fill color was not found, check if it is defined in the theme
  477. CTShapeStyle style = getSpStyle();
  478. if (style != null) {
  479. // 1-based index of a shadow style within the style matrix
  480. int idx = (int) style.getEffectRef().getIdx();
  481. CTStyleMatrix styleMatrix = _sheet.getTheme().getXmlObject().getThemeElements().getFmtScheme();
  482. CTEffectStyleItem ef = styleMatrix.getEffectStyleLst().getEffectStyleArray(idx - 1);
  483. obj = ef.getEffectLst().getOuterShdw();
  484. }
  485. }
  486. return obj == null ? null : new XSLFShadow(obj, this);
  487. }
  488. public void draw(Graphics2D graphics) {
  489. }
  490. protected void applyFill(Graphics2D graphics) {
  491. }
  492. protected float[] getDashPattern(LineDash lineDash, float lineWidth) {
  493. float[] dash = null;
  494. switch (lineDash) {
  495. case SYS_DOT:
  496. dash = new float[]{lineWidth, lineWidth};
  497. break;
  498. case SYS_DASH:
  499. dash = new float[]{2 * lineWidth, 2 * lineWidth};
  500. break;
  501. case DASH:
  502. dash = new float[]{3 * lineWidth, 4 * lineWidth};
  503. break;
  504. case DASH_DOT:
  505. dash = new float[]{4 * lineWidth, 3 * lineWidth, lineWidth,
  506. 3 * lineWidth};
  507. break;
  508. case LG_DASH:
  509. dash = new float[]{8 * lineWidth, 3 * lineWidth};
  510. break;
  511. case LG_DASH_DOT:
  512. dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth,
  513. 3 * lineWidth};
  514. break;
  515. case LG_DASH_DOT_DOT:
  516. dash = new float[]{8 * lineWidth, 3 * lineWidth, lineWidth,
  517. 3 * lineWidth, lineWidth, 3 * lineWidth};
  518. break;
  519. }
  520. return dash;
  521. }
  522. protected void applyStroke(Graphics2D graphics) {
  523. float lineWidth = (float) getLineWidth();
  524. LineDash lineDash = getLineDash();
  525. float[] dash = null;
  526. float dash_phase = 0;
  527. if (lineDash != null) {
  528. dash = getDashPattern(lineDash, lineWidth);
  529. }
  530. int cap = BasicStroke.CAP_BUTT;
  531. LineCap lineCap = getLineCap();
  532. if (lineCap != null) {
  533. switch (lineCap) {
  534. case ROUND:
  535. cap = BasicStroke.CAP_ROUND;
  536. break;
  537. case SQUARE:
  538. cap = BasicStroke.CAP_SQUARE;
  539. break;
  540. default:
  541. cap = BasicStroke.CAP_BUTT;
  542. break;
  543. }
  544. }
  545. int meter = BasicStroke.JOIN_ROUND;
  546. Stroke stroke = new BasicStroke(lineWidth, cap, meter, 0.0f, dash,
  547. dash_phase);
  548. graphics.setStroke(stroke);
  549. }
  550. /**
  551. * Walk up the inheritance tree and fetch properties.
  552. *
  553. * slide <-- slideLayout <-- slideMaster
  554. *
  555. *
  556. * @param visitor the object that collects the desired property
  557. * @return true if the property was fetched
  558. */
  559. boolean fetchShapeProperty(PropertyFetcher visitor){
  560. boolean ok = visitor.fetch(this);
  561. XSLFSimpleShape masterShape;
  562. if(!ok){
  563. // first try to fetch from the slide layout
  564. XSLFSlideLayout layout = getSheet().getSlideLayout();
  565. if(layout != null) {
  566. CTPlaceholder ph = getCTPlaceholder();
  567. if (ph != null) {
  568. masterShape = layout.getPlaceholder(ph);
  569. if (masterShape != null) {
  570. ok = visitor.fetch(masterShape);
  571. }
  572. }
  573. }
  574. }
  575. // try slide master
  576. if (!ok) {
  577. int textType;
  578. CTPlaceholder ph = getCTPlaceholder();
  579. if(ph == null || !ph.isSetType()) textType = STPlaceholderType.INT_BODY;
  580. else {
  581. switch(ph.getType().intValue()){
  582. case STPlaceholderType.INT_TITLE:
  583. case STPlaceholderType.INT_CTR_TITLE:
  584. textType = STPlaceholderType.INT_TITLE;
  585. break;
  586. case STPlaceholderType.INT_FTR:
  587. case STPlaceholderType.INT_SLD_NUM:
  588. case STPlaceholderType.INT_DT:
  589. textType = ph.getType().intValue();
  590. break;
  591. default:
  592. textType = STPlaceholderType.INT_BODY;
  593. break;
  594. }
  595. }
  596. XSLFSlideMaster master = getSheet().getSlideMaster();
  597. if(master != null) {
  598. masterShape = master.getPlaceholderByType(textType);
  599. if (masterShape != null) {
  600. ok = visitor.fetch(masterShape);
  601. }
  602. }
  603. }
  604. return ok;
  605. }
  606. }