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.

HSLFTextRun.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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.hslf.usermodel;
  16. import static org.apache.poi.hslf.usermodel.HSLFTextParagraph.fetchOrAddTextProp;
  17. import java.awt.Color;
  18. import org.apache.poi.hslf.model.textproperties.*;
  19. import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
  20. import org.apache.poi.hslf.record.ColorSchemeAtom;
  21. import org.apache.poi.sl.usermodel.TextRun;
  22. import org.apache.poi.util.POILogFactory;
  23. import org.apache.poi.util.POILogger;
  24. /**
  25. * Represents a run of text, all with the same style
  26. *
  27. */
  28. public final class HSLFTextRun implements TextRun {
  29. protected POILogger logger = POILogFactory.getLogger(this.getClass());
  30. /** The TextRun we belong to */
  31. private HSLFTextParagraph parentParagraph;
  32. private String _runText = "";
  33. private String _fontFamily;
  34. /**
  35. * Our paragraph and character style.
  36. * Note - we may share these styles with other RichTextRuns
  37. */
  38. private TextPropCollection characterStyle = new TextPropCollection(1, TextPropType.character);
  39. /**
  40. * Create a new wrapper around a rich text string
  41. * @param parent The parent paragraph
  42. */
  43. public HSLFTextRun(HSLFTextParagraph parentParagraph) {
  44. this.parentParagraph = parentParagraph;
  45. }
  46. public TextPropCollection getCharacterStyle() {
  47. return characterStyle;
  48. }
  49. public void setCharacterStyle(TextPropCollection characterStyle) {
  50. assert(characterStyle != null);
  51. this.characterStyle = characterStyle;
  52. }
  53. /**
  54. * Supply the SlideShow we belong to
  55. */
  56. public void updateSheet() {
  57. if (_fontFamily != null) {
  58. setFontFamily(_fontFamily);
  59. _fontFamily = null;
  60. }
  61. }
  62. /**
  63. * Get the length of the text
  64. */
  65. public int getLength() {
  66. return _runText.length();
  67. }
  68. /**
  69. * Fetch the text, in raw storage form
  70. */
  71. public String getRawText() {
  72. return _runText;
  73. }
  74. /**
  75. * Change the text
  76. */
  77. public void setText(String text) {
  78. _runText = HSLFTextParagraph.toInternalString(text);
  79. }
  80. // --------------- Internal helpers on rich text properties -------
  81. /**
  82. * Fetch the value of the given flag in the CharFlagsTextProp.
  83. * Returns false if the CharFlagsTextProp isn't present, since the
  84. * text property won't be set if there's no CharFlagsTextProp.
  85. */
  86. private boolean isCharFlagsTextPropVal(int index) {
  87. return getFlag(index);
  88. }
  89. protected boolean getFlag(int index) {
  90. if (characterStyle == null) return false;
  91. BitMaskTextProp prop = (BitMaskTextProp)characterStyle.findByName(CharFlagsTextProp.NAME);
  92. if (prop == null){
  93. int txtype = parentParagraph.getRunType();
  94. HSLFSheet sheet = parentParagraph.getSheet();
  95. if (sheet != null) {
  96. HSLFMasterSheet master = sheet.getMasterSheet();
  97. if (master != null){
  98. prop = (BitMaskTextProp)master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), CharFlagsTextProp.NAME, true);
  99. }
  100. } else {
  101. logger.log(POILogger.WARN, "MasterSheet is not available");
  102. }
  103. }
  104. return prop == null ? false : prop.getSubValue(index);
  105. }
  106. /**
  107. * Set the value of the given flag in the CharFlagsTextProp, adding
  108. * it if required.
  109. */
  110. private void setCharFlagsTextPropVal(int index, boolean value) {
  111. if(getFlag(index) != value) setFlag(index, value);
  112. }
  113. /**
  114. * Fetch the value of the given Character related TextProp.
  115. * Returns -1 if that TextProp isn't present.
  116. * If the TextProp isn't present, the value from the appropriate
  117. * Master Sheet will apply.
  118. */
  119. private int getCharTextPropVal(String propName) {
  120. TextProp prop = null;
  121. if (characterStyle != null){
  122. prop = characterStyle.findByName(propName);
  123. }
  124. if (prop == null){
  125. HSLFSheet sheet = parentParagraph.getSheet();
  126. int txtype = parentParagraph.getRunType();
  127. HSLFMasterSheet master = sheet.getMasterSheet();
  128. if (master != null)
  129. prop = master.getStyleAttribute(txtype, parentParagraph.getIndentLevel(), propName, true);
  130. }
  131. return prop == null ? -1 : prop.getValue();
  132. }
  133. /**
  134. * Sets the value of the given Paragraph TextProp, add if required
  135. * @param propName The name of the Paragraph TextProp
  136. * @param val The value to set for the TextProp
  137. */
  138. public void setCharTextPropVal(String propName, int val) {
  139. TextProp tp = fetchOrAddTextProp(characterStyle, propName);
  140. tp.setValue(val);
  141. }
  142. // --------------- Friendly getters / setters on rich text properties -------
  143. /**
  144. * Is the text bold?
  145. */
  146. public boolean isBold() {
  147. return isCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX);
  148. }
  149. /**
  150. * Is the text bold?
  151. */
  152. public void setBold(boolean bold) {
  153. setCharFlagsTextPropVal(CharFlagsTextProp.BOLD_IDX, bold);
  154. }
  155. /**
  156. * Is the text italic?
  157. */
  158. public boolean isItalic() {
  159. return isCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX);
  160. }
  161. /**
  162. * Is the text italic?
  163. */
  164. public void setItalic(boolean italic) {
  165. setCharFlagsTextPropVal(CharFlagsTextProp.ITALIC_IDX, italic);
  166. }
  167. /**
  168. * Is the text underlined?
  169. */
  170. public boolean isUnderlined() {
  171. return isCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX);
  172. }
  173. /**
  174. * Is the text underlined?
  175. */
  176. public void setUnderlined(boolean underlined) {
  177. setCharFlagsTextPropVal(CharFlagsTextProp.UNDERLINE_IDX, underlined);
  178. }
  179. /**
  180. * Does the text have a shadow?
  181. */
  182. public boolean isShadowed() {
  183. return isCharFlagsTextPropVal(CharFlagsTextProp.SHADOW_IDX);
  184. }
  185. /**
  186. * Does the text have a shadow?
  187. */
  188. public void setShadowed(boolean flag) {
  189. setCharFlagsTextPropVal(CharFlagsTextProp.SHADOW_IDX, flag);
  190. }
  191. /**
  192. * Is this text embossed?
  193. */
  194. public boolean isEmbossed() {
  195. return isCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX);
  196. }
  197. /**
  198. * Is this text embossed?
  199. */
  200. public void setEmbossed(boolean flag) {
  201. setCharFlagsTextPropVal(CharFlagsTextProp.RELIEF_IDX, flag);
  202. }
  203. /**
  204. * Gets the strikethrough flag
  205. */
  206. public boolean isStrikethrough() {
  207. return isCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX);
  208. }
  209. /**
  210. * Sets the strikethrough flag
  211. */
  212. public void setStrikethrough(boolean flag) {
  213. setCharFlagsTextPropVal(CharFlagsTextProp.STRIKETHROUGH_IDX, flag);
  214. }
  215. /**
  216. * Gets the subscript/superscript option
  217. *
  218. * @return the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript
  219. */
  220. public int getSuperscript() {
  221. int val = getCharTextPropVal("superscript");
  222. return val == -1 ? 0 : val;
  223. }
  224. /**
  225. * Sets the subscript/superscript option
  226. *
  227. * @param val the percentage of the font size. If the value is positive, it is superscript, otherwise it is subscript
  228. */
  229. public void setSuperscript(int val) {
  230. setCharTextPropVal("superscript", val);
  231. }
  232. /**
  233. * Gets the font size
  234. */
  235. public double getFontSize() {
  236. return getCharTextPropVal("font.size");
  237. }
  238. /**
  239. * Sets the font size
  240. */
  241. public void setFontSize(int fontSize) {
  242. setCharTextPropVal("font.size", fontSize);
  243. }
  244. /**
  245. * Gets the font index
  246. */
  247. public int getFontIndex() {
  248. return getCharTextPropVal("font.index");
  249. }
  250. /**
  251. * Sets the font index
  252. */
  253. public void setFontIndex(int idx) {
  254. setCharTextPropVal("font.index", idx);
  255. }
  256. /**
  257. * Sets the font name to use
  258. */
  259. public void setFontFamily(String fontFamily) {
  260. HSLFSheet sheet = parentParagraph.getSheet();
  261. HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
  262. if (sheet == null || slideShow == null) {
  263. //we can't set font since slideshow is not assigned yet
  264. _fontFamily = fontFamily;
  265. return;
  266. }
  267. // Get the index for this font (adding if needed)
  268. int fontIdx = slideShow.getFontCollection().addFont(fontFamily);
  269. setCharTextPropVal("font.index", fontIdx);
  270. }
  271. /**
  272. * Gets the font name
  273. */
  274. @Override
  275. public String getFontFamily() {
  276. HSLFSheet sheet = parentParagraph.getSheet();
  277. HSLFSlideShow slideShow = (sheet == null) ? null : sheet.getSlideShow();
  278. if (sheet == null || slideShow == null) {
  279. return _fontFamily;
  280. }
  281. int fontIdx = getCharTextPropVal("font.index");
  282. if(fontIdx == -1) { return null; }
  283. return slideShow.getFontCollection().getFontWithId(fontIdx);
  284. }
  285. /**
  286. * @return font color as RGB value
  287. * @see java.awt.Color
  288. */
  289. public Color getFontColor() {
  290. int rgb = getCharTextPropVal("font.color");
  291. int cidx = rgb >> 24;
  292. if (rgb % 0x1000000 == 0){
  293. ColorSchemeAtom ca = parentParagraph.getSheet().getColorScheme();
  294. if(cidx >= 0 && cidx <= 7) rgb = ca.getColor(cidx);
  295. }
  296. Color tmp = new Color(rgb, true);
  297. return new Color(tmp.getBlue(), tmp.getGreen(), tmp.getRed());
  298. }
  299. /**
  300. * Sets color of the text, as a int bgr.
  301. * (PowerPoint stores as BlueGreenRed, not the more
  302. * usual RedGreenBlue)
  303. * @see java.awt.Color
  304. */
  305. public void setFontColor(int bgr) {
  306. setCharTextPropVal("font.color", bgr);
  307. }
  308. /**
  309. * Sets color of the text, as a java.awt.Color
  310. */
  311. public void setFontColor(Color color) {
  312. // In PowerPont RGB bytes are swapped, as BGR
  313. int rgb = new Color(color.getBlue(), color.getGreen(), color.getRed(), 254).getRGB();
  314. setFontColor(rgb);
  315. }
  316. protected void setFlag(int index, boolean value) {
  317. BitMaskTextProp prop = (BitMaskTextProp) fetchOrAddTextProp(characterStyle, CharFlagsTextProp.NAME);
  318. prop.setSubValue(value, index);
  319. }
  320. public HSLFTextParagraph getTextParagraph() {
  321. return parentParagraph;
  322. }
  323. public TextCap getTextCap() {
  324. return TextCap.NONE;
  325. }
  326. public boolean isSubscript() {
  327. return false;
  328. }
  329. public boolean isSuperscript() {
  330. return false;
  331. }
  332. public byte getPitchAndFamily() {
  333. return 0;
  334. }
  335. }