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.

XSLFTableCell.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  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 java.awt.Color;
  21. import java.awt.geom.Rectangle2D;
  22. import org.apache.poi.sl.draw.DrawPaint;
  23. import org.apache.poi.sl.usermodel.ColorStyle;
  24. import org.apache.poi.sl.usermodel.PaintStyle;
  25. import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
  26. import org.apache.poi.sl.usermodel.StrokeStyle;
  27. import org.apache.poi.sl.usermodel.StrokeStyle.LineCap;
  28. import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
  29. import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
  30. import org.apache.poi.sl.usermodel.TableCell;
  31. import org.apache.poi.sl.usermodel.VerticalAlignment;
  32. import org.apache.poi.util.Units;
  33. import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
  34. import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle;
  35. import org.apache.xmlbeans.XmlObject;
  36. import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference;
  37. import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
  38. import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
  39. import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
  40. import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
  41. import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
  42. import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
  43. import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
  44. import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
  45. import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
  46. import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties;
  47. import org.openxmlformats.schemas.drawingml.x2006.main.CTTablePartStyle;
  48. import org.openxmlformats.schemas.drawingml.x2006.main.CTTableProperties;
  49. import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleCellStyle;
  50. import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleTextStyle;
  51. import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
  52. import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
  53. import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
  54. import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;
  55. import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
  56. import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
  57. import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
  58. import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
  59. import org.openxmlformats.schemas.drawingml.x2006.main.STOnOffStyleType;
  60. import org.openxmlformats.schemas.drawingml.x2006.main.STPenAlignment;
  61. import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
  62. import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
  63. import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
  64. /**
  65. * Represents a cell of a table in a .pptx presentation
  66. */
  67. public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,XSLFTextParagraph> {
  68. private CTTableCellProperties _tcPr = null;
  69. private final XSLFTable table;
  70. private int row = 0, col = 0;
  71. /**
  72. * Volatile/temporary anchor - e.g. for rendering
  73. */
  74. private Rectangle2D anchor = null;
  75. /*package*/ XSLFTableCell(CTTableCell cell, XSLFTable table){
  76. super(cell, table.getSheet());
  77. this.table = table;
  78. }
  79. @Override
  80. protected CTTextBody getTextBody(boolean create){
  81. CTTableCell cell = getCell();
  82. CTTextBody txBody = cell.getTxBody();
  83. if (txBody == null && create) {
  84. txBody = cell.addNewTxBody();
  85. XSLFAutoShape.initTextBody(txBody);
  86. }
  87. return txBody;
  88. }
  89. static CTTableCell prototype() {
  90. CTTableCell cell = CTTableCell.Factory.newInstance();
  91. CTTableCellProperties pr = cell.addNewTcPr();
  92. pr.addNewLnL().addNewNoFill();
  93. pr.addNewLnR().addNewNoFill();
  94. pr.addNewLnT().addNewNoFill();
  95. pr.addNewLnB().addNewNoFill();
  96. return cell;
  97. }
  98. protected CTTableCellProperties getCellProperties(boolean create) {
  99. if (_tcPr == null) {
  100. CTTableCell cell = getCell();
  101. _tcPr = cell.getTcPr();
  102. if (_tcPr == null && create) {
  103. _tcPr = cell.addNewTcPr();
  104. }
  105. }
  106. return _tcPr;
  107. }
  108. @Override
  109. public void setLeftInset(double margin){
  110. CTTableCellProperties pr = getCellProperties(true);
  111. pr.setMarL(Units.toEMU(margin));
  112. }
  113. @Override
  114. public void setRightInset(double margin){
  115. CTTableCellProperties pr = getCellProperties(true);
  116. pr.setMarR(Units.toEMU(margin));
  117. }
  118. @Override
  119. public void setTopInset(double margin){
  120. CTTableCellProperties pr = getCellProperties(true);
  121. pr.setMarT(Units.toEMU(margin));
  122. }
  123. @Override
  124. public void setBottomInset(double margin){
  125. CTTableCellProperties pr = getCellProperties(true);
  126. pr.setMarB(Units.toEMU(margin));
  127. }
  128. private CTLineProperties getCTLine(BorderEdge edge, boolean create) {
  129. if (edge == null) {
  130. throw new IllegalArgumentException("BorderEdge needs to be specified.");
  131. }
  132. CTTableCellProperties pr = getCellProperties(create);
  133. if (pr == null) return null;
  134. switch (edge) {
  135. case bottom:
  136. return (pr.isSetLnB()) ? pr.getLnB() : (create ? pr.addNewLnB() : null);
  137. case left:
  138. return (pr.isSetLnL()) ? pr.getLnL() : (create ? pr.addNewLnL() : null);
  139. case top:
  140. return (pr.isSetLnT()) ? pr.getLnT() : (create ? pr.addNewLnT() : null);
  141. case right:
  142. return (pr.isSetLnR()) ? pr.getLnR() : (create ? pr.addNewLnR() : null);
  143. default:
  144. return null;
  145. }
  146. }
  147. @Override
  148. public void removeBorder(BorderEdge edge) {
  149. CTTableCellProperties pr = getCellProperties(false);
  150. if (pr == null) return;
  151. switch (edge) {
  152. case bottom:
  153. if (pr.isSetLnB()) {
  154. pr.unsetLnB();
  155. }
  156. break;
  157. case left:
  158. if (pr.isSetLnL()) {
  159. pr.unsetLnL();
  160. }
  161. break;
  162. case top:
  163. if (pr.isSetLnT()) {
  164. pr.unsetLnT();
  165. }
  166. break;
  167. case right:
  168. if (pr.isSetLnR()) {
  169. pr.unsetLnB();
  170. }
  171. break;
  172. default:
  173. throw new IllegalArgumentException();
  174. }
  175. }
  176. @Override
  177. public StrokeStyle getBorderStyle(final BorderEdge edge) {
  178. final Double width = getBorderWidth(edge);
  179. return (width == null) ? null : new StrokeStyle() {
  180. public PaintStyle getPaint() {
  181. return DrawPaint.createSolidPaint(getBorderColor(edge));
  182. }
  183. public LineCap getLineCap() {
  184. return getBorderCap(edge);
  185. }
  186. public LineDash getLineDash() {
  187. return getBorderDash(edge);
  188. }
  189. public LineCompound getLineCompound() {
  190. return getBorderCompound(edge);
  191. }
  192. public double getLineWidth() {
  193. return width;
  194. }
  195. };
  196. }
  197. @Override
  198. public void setBorderStyle(BorderEdge edge, StrokeStyle style) {
  199. if (style == null) {
  200. throw new IllegalArgumentException("StrokeStyle needs to be specified.");
  201. }
  202. LineCap cap = style.getLineCap();
  203. if (cap != null) {
  204. setBorderCap(edge, cap);
  205. }
  206. LineCompound compound = style.getLineCompound();
  207. if (compound != null) {
  208. setBorderCompound(edge, compound);
  209. }
  210. LineDash dash = style.getLineDash();
  211. if (dash != null) {
  212. setBorderDash(edge, dash);
  213. }
  214. double width = style.getLineWidth();
  215. setBorderWidth(edge, width);
  216. }
  217. public Double getBorderWidth(BorderEdge edge) {
  218. CTLineProperties ln = getCTLine(edge, false);
  219. return (ln == null || !ln.isSetW()) ? null : Units.toPoints(ln.getW());
  220. }
  221. @Override
  222. public void setBorderWidth(BorderEdge edge, double width) {
  223. CTLineProperties ln = getCTLine(edge, true);
  224. ln.setW(Units.toEMU(width));
  225. }
  226. private CTLineProperties setBorderDefaults(BorderEdge edge) {
  227. CTLineProperties ln = getCTLine(edge, true);
  228. if (ln.isSetNoFill()) {
  229. ln.unsetNoFill();
  230. }
  231. if(!ln.isSetPrstDash()) {
  232. ln.addNewPrstDash().setVal(STPresetLineDashVal.SOLID);
  233. }
  234. if (!ln.isSetCmpd()) {
  235. ln.setCmpd(STCompoundLine.SNG);
  236. }
  237. if (!ln.isSetAlgn()) {
  238. ln.setAlgn(STPenAlignment.CTR);
  239. }
  240. if (!ln.isSetCap()) {
  241. ln.setCap(STLineCap.FLAT);
  242. }
  243. if (!ln.isSetRound()) {
  244. ln.addNewRound();
  245. }
  246. if (!ln.isSetHeadEnd()) {
  247. CTLineEndProperties hd = ln.addNewHeadEnd();
  248. hd.setType(STLineEndType.NONE);
  249. hd.setW(STLineEndWidth.MED);
  250. hd.setLen(STLineEndLength.MED);
  251. }
  252. if (!ln.isSetTailEnd()) {
  253. CTLineEndProperties tl = ln.addNewTailEnd();
  254. tl.setType(STLineEndType.NONE);
  255. tl.setW(STLineEndWidth.MED);
  256. tl.setLen(STLineEndLength.MED);
  257. }
  258. return ln;
  259. }
  260. @Override
  261. public void setBorderColor(BorderEdge edge, Color color) {
  262. if (color == null) {
  263. throw new IllegalArgumentException("Colors need to be specified.");
  264. }
  265. CTLineProperties ln = setBorderDefaults(edge);
  266. CTSolidColorFillProperties fill = ln.addNewSolidFill();
  267. XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
  268. c.setColor(color);
  269. }
  270. public Color getBorderColor(BorderEdge edge) {
  271. CTLineProperties ln = getCTLine(edge, false);
  272. if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill()) return null;
  273. CTSolidColorFillProperties fill = ln.getSolidFill();
  274. XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
  275. return c.getColor();
  276. }
  277. public LineCompound getBorderCompound(BorderEdge edge) {
  278. CTLineProperties ln = getCTLine(edge, false);
  279. if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCmpd()) {
  280. return null;
  281. }
  282. return LineCompound.fromOoxmlId(ln.getCmpd().intValue());
  283. }
  284. @Override
  285. public void setBorderCompound(BorderEdge edge, LineCompound compound) {
  286. if (compound == null) {
  287. throw new IllegalArgumentException("LineCompound need to be specified.");
  288. }
  289. CTLineProperties ln = setBorderDefaults(edge);
  290. ln.setCmpd(STCompoundLine.Enum.forInt(compound.ooxmlId));
  291. }
  292. public LineDash getBorderDash(BorderEdge edge) {
  293. CTLineProperties ln = getCTLine(edge, false);
  294. if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetPrstDash()) {
  295. return null;
  296. }
  297. return LineDash.fromOoxmlId(ln.getPrstDash().getVal().intValue());
  298. }
  299. @Override
  300. public void setBorderDash(BorderEdge edge, LineDash dash) {
  301. if (dash == null) {
  302. throw new IllegalArgumentException("LineDash need to be specified.");
  303. }
  304. CTLineProperties ln = setBorderDefaults(edge);
  305. ln.getPrstDash().setVal(STPresetLineDashVal.Enum.forInt(dash.ooxmlId));
  306. }
  307. public LineCap getBorderCap(BorderEdge edge) {
  308. CTLineProperties ln = getCTLine(edge, false);
  309. if (ln == null || ln.isSetNoFill() || !ln.isSetSolidFill() || !ln.isSetCap()) {
  310. return null;
  311. }
  312. return LineCap.fromOoxmlId(ln.getCap().intValue());
  313. }
  314. public void setBorderCap(BorderEdge edge, LineCap cap) {
  315. if (cap == null) {
  316. throw new IllegalArgumentException("LineCap need to be specified.");
  317. }
  318. CTLineProperties ln = setBorderDefaults(edge);
  319. ln.setCap(STLineCap.Enum.forInt(cap.ooxmlId));
  320. }
  321. /**
  322. * Specifies a solid color fill. The shape is filled entirely with the specified color.
  323. *
  324. * @param color the solid color fill.
  325. * The value of <code>null</code> unsets the solidFIll attribute from the underlying xml
  326. */
  327. @Override
  328. public void setFillColor(Color color) {
  329. CTTableCellProperties spPr = getCellProperties(true);
  330. if (color == null) {
  331. if(spPr.isSetSolidFill()) spPr.unsetSolidFill();
  332. } else {
  333. CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
  334. XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
  335. c.setColor(color);
  336. }
  337. }
  338. /**
  339. *
  340. * @return solid fill color of null if not set
  341. */
  342. @Override
  343. public Color getFillColor(){
  344. PaintStyle ps = getFillPaint();
  345. if (ps instanceof SolidPaint) {
  346. ColorStyle cs = ((SolidPaint)ps).getSolidColor();
  347. return DrawPaint.applyColorTransform(cs);
  348. }
  349. return null;
  350. }
  351. @SuppressWarnings("resource")
  352. @Override
  353. public PaintStyle getFillPaint() {
  354. XSLFSheet sheet = getSheet();
  355. XSLFTheme theme = sheet.getTheme();
  356. XmlObject props = getCellProperties(false);
  357. XSLFFillProperties fp = XSLFPropertiesDelegate.getFillDelegate(props);
  358. if (fp != null) {
  359. PaintStyle paint = selectPaint(fp, null, sheet.getPackagePart(), theme);
  360. if (paint != null) {
  361. return paint;
  362. }
  363. }
  364. CTTablePartStyle tps = getTablePartStyle(null);
  365. if (tps == null || !tps.isSetTcStyle()) {
  366. tps = getTablePartStyle(TablePartStyle.wholeTbl);
  367. if (tps == null || !tps.isSetTcStyle()) {
  368. return null;
  369. }
  370. }
  371. XMLSlideShow slideShow = sheet.getSlideShow();
  372. CTTableStyleCellStyle tcStyle = tps.getTcStyle();
  373. if (tcStyle.isSetFill()) {
  374. props = tcStyle.getFill();
  375. } else if (tcStyle.isSetFillRef()) {
  376. props = tcStyle.getFillRef();
  377. } else {
  378. return null;
  379. }
  380. fp = XSLFPropertiesDelegate.getFillDelegate(props);
  381. if (fp != null) {
  382. PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme);
  383. if (paint != null) {
  384. return paint;
  385. }
  386. }
  387. return null;
  388. }
  389. /**
  390. * Retrieves the part style depending on the location of this cell
  391. *
  392. * @param tablePartStyle the part to be returned, usually this is null
  393. * and only set when used as a helper method
  394. * @return the table part style
  395. */
  396. private CTTablePartStyle getTablePartStyle(TablePartStyle tablePartStyle) {
  397. CTTable ct = table.getCTTable();
  398. if (!ct.isSetTblPr()) {
  399. return null;
  400. }
  401. CTTableProperties pr = ct.getTblPr();
  402. boolean bandRow = (pr.isSetBandRow() && pr.getBandRow());
  403. boolean firstRow = (pr.isSetFirstRow() && pr.getFirstRow());
  404. boolean lastRow = (pr.isSetLastRow() && pr.getLastRow());
  405. boolean bandCol = (pr.isSetBandCol() && pr.getBandCol());
  406. boolean firstCol = (pr.isSetFirstCol() && pr.getFirstCol());
  407. boolean lastCol = (pr.isSetLastCol() && pr.getLastCol());
  408. TablePartStyle tps;
  409. if (tablePartStyle != null) {
  410. tps = tablePartStyle;
  411. } else if (row == 0 && firstRow) {
  412. tps = TablePartStyle.firstRow;
  413. } else if (row == table.getNumberOfRows()-1 && lastRow) {
  414. tps = TablePartStyle.lastRow;
  415. } else if (col == 0 && firstCol) {
  416. tps = TablePartStyle.firstCol;
  417. } else if (col == table.getNumberOfColumns()-1 && lastCol) {
  418. tps = TablePartStyle.lastCol;
  419. } else {
  420. tps = TablePartStyle.wholeTbl;
  421. int br = row + (firstRow ? 1 : 0);
  422. int bc = col + (firstCol ? 1 : 0);
  423. if (bandRow && (br & 1) == 0) {
  424. tps = TablePartStyle.band1H;
  425. } else if (bandCol && (bc & 1) == 0) {
  426. tps = TablePartStyle.band1V;
  427. }
  428. }
  429. XSLFTableStyle tabStyle = table.getTableStyle();
  430. if (tabStyle == null) {
  431. return null;
  432. }
  433. CTTablePartStyle part = tabStyle.getTablePartStyle(tps);
  434. return (part == null) ? tabStyle.getTablePartStyle(TablePartStyle.wholeTbl) : part;
  435. }
  436. void setGridSpan(int gridSpan_) {
  437. getCell().setGridSpan(gridSpan_);
  438. }
  439. @Override
  440. public int getGridSpan() {
  441. CTTableCell c = getCell();
  442. return (c.isSetGridSpan()) ? c.getGridSpan() : 1;
  443. }
  444. void setRowSpan(int rowSpan_) {
  445. getCell().setRowSpan(rowSpan_);
  446. }
  447. @Override
  448. public int getRowSpan() {
  449. CTTableCell c = getCell();
  450. return (c.isSetRowSpan()) ? c.getRowSpan() : 1;
  451. }
  452. void setHMerge(boolean merge_) {
  453. getCell().setHMerge(merge_);
  454. }
  455. void setVMerge(boolean merge_) {
  456. getCell().setVMerge(merge_);
  457. }
  458. @Override
  459. public void setVerticalAlignment(VerticalAlignment anchor){
  460. CTTableCellProperties cellProps = getCellProperties(true);
  461. if(anchor == null) {
  462. if(cellProps.isSetAnchor()) {
  463. cellProps.unsetAnchor();
  464. }
  465. } else {
  466. cellProps.setAnchor(STTextAnchoringType.Enum.forInt(anchor.ordinal() + 1));
  467. }
  468. }
  469. @Override
  470. public VerticalAlignment getVerticalAlignment(){
  471. CTTableCellProperties cellProps = getCellProperties(false);
  472. VerticalAlignment align = VerticalAlignment.TOP;
  473. if(cellProps != null && cellProps.isSetAnchor()) {
  474. int ival = cellProps.getAnchor().intValue();
  475. align = VerticalAlignment.values()[ival - 1];
  476. }
  477. return align;
  478. }
  479. /**
  480. * @since POI 3.15-beta2
  481. */
  482. @Override
  483. public void setTextDirection(TextDirection orientation) {
  484. CTTableCellProperties cellProps = getCellProperties(true);
  485. if(orientation == null) {
  486. if (cellProps.isSetVert()) {
  487. cellProps.unsetVert();
  488. }
  489. } else {
  490. STTextVerticalType.Enum vt;
  491. switch (orientation) {
  492. default:
  493. case HORIZONTAL:
  494. vt = STTextVerticalType.HORZ;
  495. break;
  496. case VERTICAL:
  497. vt = STTextVerticalType.VERT;
  498. break;
  499. case VERTICAL_270:
  500. vt = STTextVerticalType.VERT_270;
  501. break;
  502. case STACKED:
  503. vt = STTextVerticalType.WORD_ART_VERT;
  504. break;
  505. }
  506. cellProps.setVert(vt);
  507. }
  508. }
  509. /**
  510. * @since POI 3.15-beta2
  511. */
  512. @Override
  513. public TextDirection getTextDirection() {
  514. CTTableCellProperties cellProps = getCellProperties(false);
  515. STTextVerticalType.Enum orientation;
  516. if (cellProps != null && cellProps.isSetVert()) {
  517. orientation = cellProps.getVert();
  518. } else {
  519. orientation = STTextVerticalType.HORZ;
  520. }
  521. switch (orientation.intValue()) {
  522. default:
  523. case STTextVerticalType.INT_HORZ:
  524. return TextDirection.HORIZONTAL;
  525. case STTextVerticalType.INT_VERT:
  526. case STTextVerticalType.INT_EA_VERT:
  527. case STTextVerticalType.INT_MONGOLIAN_VERT:
  528. return TextDirection.VERTICAL;
  529. case STTextVerticalType.INT_VERT_270:
  530. return TextDirection.VERTICAL_270;
  531. case STTextVerticalType.INT_WORD_ART_VERT:
  532. case STTextVerticalType.INT_WORD_ART_VERT_RTL:
  533. return TextDirection.STACKED;
  534. }
  535. }
  536. private CTTableCell getCell() {
  537. return (CTTableCell)getXmlObject();
  538. }
  539. /* package */ void setRowColIndex(int row, int col) {
  540. this.row = row;
  541. this.col = col;
  542. }
  543. /**
  544. * Return a fake-xfrm which is used for calculating the text height
  545. */
  546. protected CTTransform2D getXfrm() {
  547. Rectangle2D anc = getAnchor();
  548. CTTransform2D xfrm = CTTransform2D.Factory.newInstance();
  549. CTPoint2D off = xfrm.addNewOff();
  550. off.setX(Units.toEMU(anc.getX()));
  551. off.setY(Units.toEMU(anc.getY()));
  552. CTPositiveSize2D size = xfrm.addNewExt();
  553. size.setCx(Units.toEMU(anc.getWidth()));
  554. size.setCy(Units.toEMU(anc.getHeight()));
  555. return xfrm;
  556. }
  557. /**
  558. * There's no real anchor for table cells - this method is used to temporarily store the location
  559. * of the cell for a later retrieval, e.g. for rendering
  560. *
  561. * @since POI 3.15-beta2
  562. */
  563. @Override
  564. public void setAnchor(Rectangle2D anchor) {
  565. if (this.anchor == null) {
  566. this.anchor = (Rectangle2D)anchor.clone();
  567. } else {
  568. this.anchor.setRect(anchor);
  569. }
  570. }
  571. /**
  572. * @since POI 3.15-beta2
  573. */
  574. @Override
  575. public Rectangle2D getAnchor() {
  576. if (anchor == null) {
  577. table.updateCellAnchor();
  578. }
  579. // anchor should be set, after updateCellAnchor is through
  580. assert(anchor != null);
  581. return anchor;
  582. }
  583. /**
  584. * @since POI 3.15-beta2
  585. */
  586. @Override
  587. public boolean isMerged() {
  588. CTTableCell c = getCell();
  589. return (c.isSetHMerge() && c.getHMerge()) || (c.isSetVMerge() && c.getVMerge());
  590. }
  591. /**
  592. * @since POI 3.15-beta2
  593. */
  594. @Override
  595. protected XSLFCellTextParagraph newTextParagraph(CTTextParagraph p) {
  596. return new XSLFCellTextParagraph(p, this);
  597. }
  598. @Override
  599. protected XmlObject getShapeProperties() {
  600. return getCellProperties(false);
  601. }
  602. /**
  603. * @since POI 3.15-beta2
  604. */
  605. private class XSLFCellTextParagraph extends XSLFTextParagraph {
  606. protected XSLFCellTextParagraph(CTTextParagraph p, XSLFTextShape shape) {
  607. super(p, shape);
  608. }
  609. @Override
  610. protected XSLFCellTextRun newTextRun(CTRegularTextRun r) {
  611. return new XSLFCellTextRun(r, this);
  612. }
  613. }
  614. /**
  615. * @since POI 3.15-beta2
  616. */
  617. private class XSLFCellTextRun extends XSLFTextRun {
  618. protected XSLFCellTextRun(CTRegularTextRun r, XSLFTextParagraph p) {
  619. super(r, p);
  620. }
  621. @Override
  622. public PaintStyle getFontColor(){
  623. CTTableStyleTextStyle txStyle = getTextStyle();
  624. if (txStyle == null) {
  625. return super.getFontColor();
  626. }
  627. CTSchemeColor phClr = null;
  628. CTFontReference fontRef = txStyle.getFontRef();
  629. if (fontRef != null) {
  630. phClr = fontRef.getSchemeClr();
  631. }
  632. XSLFTheme theme = getSheet().getTheme();
  633. final XSLFColor c = new XSLFColor(txStyle, theme, phClr);
  634. return DrawPaint.createSolidPaint(c.getColorStyle());
  635. }
  636. @Override
  637. public boolean isBold() {
  638. CTTableStyleTextStyle txStyle = getTextStyle();
  639. if (txStyle == null) {
  640. return super.isBold();
  641. } else {
  642. return txStyle.isSetB() && txStyle.getB().intValue() == STOnOffStyleType.INT_ON;
  643. }
  644. }
  645. @Override
  646. public boolean isItalic() {
  647. CTTableStyleTextStyle txStyle = getTextStyle();
  648. if (txStyle == null) {
  649. return super.isItalic();
  650. } else {
  651. return txStyle.isSetI() && txStyle.getI().intValue() == STOnOffStyleType.INT_ON;
  652. }
  653. }
  654. private CTTableStyleTextStyle getTextStyle() {
  655. CTTablePartStyle tps = getTablePartStyle(null);
  656. if (tps == null || !tps.isSetTcTxStyle()) {
  657. tps = getTablePartStyle(TablePartStyle.wholeTbl);
  658. }
  659. return (tps == null) ? null : tps.getTcTxStyle();
  660. }
  661. }
  662. }