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.

FOText.java 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /* $Id$
  2. * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
  3. * For details on use and redistribution please refer to the
  4. * LICENSE file included with these sources."
  5. */
  6. package org.apache.fop.fo;
  7. // FOP
  8. import org.apache.fop.layout.Area;
  9. import org.apache.fop.messaging.MessageHandler;
  10. import org.apache.fop.layout.BlockArea;
  11. import org.apache.fop.layout.FontState;
  12. import org.apache.fop.layout.*;
  13. import org.apache.fop.datatypes.*;
  14. import org.apache.fop.fo.properties.*;
  15. import org.apache.fop.apps.FOPException;
  16. import org.apache.fop.system.BufferManager;
  17. /**
  18. * a text node in the formatting object tree
  19. */
  20. public class FOText extends FONode {
  21. // protected char[] ca;
  22. protected int start;
  23. protected int length;
  24. FontState fs;
  25. float red;
  26. float green;
  27. float blue;
  28. int wrapOption;
  29. int whiteSpaceCollapse;
  30. int verticalAlign;
  31. // Textdecoration
  32. protected boolean underlined = false;
  33. protected boolean overlined = false;
  34. protected boolean lineThrough = false;
  35. TextState ts;
  36. public FOText(char[] chars, int s, int e, FObj parent) {
  37. super(parent);
  38. this.start = 0;
  39. char ca[] = new char[e - s];
  40. for (int i = s; i < e; i++)
  41. ca[i - s] = chars[i];
  42. this.length = e - s;
  43. this.bufferManager = parent.bufferManager;
  44. if (this.bufferManager != null) {
  45. bufferManager.writeBuffer((Object) this, ca);
  46. }
  47. else {
  48. System.out.println("abnormal exit");
  49. System.exit(0);
  50. }
  51. }
  52. public void setUnderlined(boolean ul) {
  53. this.underlined = ul;
  54. }
  55. public void setOverlined(boolean ol) {
  56. this.overlined = ol;
  57. }
  58. public void setLineThrough(boolean lt) {
  59. this.lineThrough = lt;
  60. }
  61. public boolean willCreateArea()
  62. {
  63. char ca[] = this.bufferManager.readBuffer((Object) this);
  64. this.whiteSpaceCollapse = this.parent.properties.get(
  65. "white-space-collapse").getEnum();
  66. if(this.whiteSpaceCollapse == WhiteSpaceCollapse.FALSE && length > 0) {
  67. return true;
  68. }
  69. for (int i = start; i < start + length; i++) {
  70. char ch = ca[i];
  71. if (!((ch == ' ') || (ch == '\n') || (ch == '\r') ||
  72. (ch == '\t'))) { // whitespace
  73. return true;
  74. }
  75. }
  76. return false;
  77. }
  78. public Status layout(Area area) throws FOPException {
  79. char ca[] = this.bufferManager.readBuffer((Object) this);
  80. if (!(area instanceof BlockArea)) {
  81. MessageHandler.errorln("WARNING: text outside block area" +
  82. new String(ca, start, length));
  83. return new Status(Status.OK);
  84. }
  85. if (this.marker == START) {
  86. String fontFamily =
  87. this.parent.properties.get("font-family").getString();
  88. String fontStyle =
  89. this.parent.properties.get("font-style").getString();
  90. String fontWeight =
  91. this.parent.properties.get("font-weight").getString();
  92. int fontSize = this.parent.properties.get(
  93. "font-size").getLength().mvalue();
  94. // font-variant support
  95. // added by Eric SCHAEFFER
  96. int fontVariant = this.parent.properties.get("font-variant").getEnum();
  97. this.fs = new FontState(area.getFontInfo(), fontFamily,
  98. fontStyle, fontWeight, fontSize, fontVariant);
  99. ColorType c =
  100. this.parent.properties.get("color").getColorType();
  101. this.red = c.red();
  102. this.green = c.green();
  103. this.blue = c.blue();
  104. this.verticalAlign = this.parent.properties.get("vertical-align").getEnum();
  105. this.wrapOption =
  106. this.parent.properties.get("wrap-option").getEnum();
  107. this.whiteSpaceCollapse = this.parent.properties.get(
  108. "white-space-collapse").getEnum();
  109. this.ts = new TextState();
  110. ts.setUnderlined(underlined);
  111. ts.setOverlined(overlined);
  112. ts.setLineThrough(lineThrough);
  113. this.marker = this.start;
  114. }
  115. int orig_start = this.marker;
  116. this.marker = addText((BlockArea)area, fs, red, green, blue,
  117. wrapOption, this.getLinkSet(), whiteSpaceCollapse, ca,
  118. this.marker, length, ts, verticalAlign);
  119. if (this.marker == -1) {
  120. // commented out by Hani Elabed, 11/28/2000
  121. // if this object has been laid out
  122. // successfully, leave it alone....
  123. // Now, to prevent the array index out of
  124. // bound of LineArea.addText(), I have added
  125. // the following test at the beginning of that method.
  126. // if( start == -1 ) return -1;
  127. // see LineArea.addText()
  128. //this.marker = 0;
  129. return new Status(Status.OK);
  130. } else if (this.marker != orig_start) {
  131. return new Status(Status.AREA_FULL_SOME);
  132. } else {
  133. return new Status(Status.AREA_FULL_NONE);
  134. }
  135. }
  136. // font-variant support : addText is a wrapper for addRealText
  137. // added by Eric SCHAEFFER
  138. public static int addText(BlockArea ba, FontState fontState, float red, float green,
  139. float blue, int wrapOption, LinkSet ls,
  140. int whiteSpaceCollapse, char data[], int start, int end,
  141. TextState textState, int vAlign) {
  142. if (fontState.getFontVariant() == FontVariant.SMALL_CAPS) {
  143. FontState smallCapsFontState;
  144. try {
  145. int smallCapsFontHeight = (int) (((double) fontState.getFontSize()) * 0.8d);
  146. smallCapsFontState = new FontState(
  147. fontState.getFontInfo(),
  148. fontState.getFontFamily(),
  149. fontState.getFontStyle(),
  150. fontState.getFontWeight(),
  151. smallCapsFontHeight,
  152. FontVariant.NORMAL);
  153. } catch (FOPException ex) {
  154. smallCapsFontState = fontState;
  155. MessageHandler.errorln("Error creating small-caps FontState: " + ex.getMessage());
  156. }
  157. // parse text for upper/lower case and call addRealText
  158. char c;
  159. boolean isLowerCase;
  160. int caseStart;
  161. FontState fontStateToUse;
  162. for (int i = start; i < end; ) {
  163. caseStart = i;
  164. c = data[i];
  165. isLowerCase = (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c));
  166. while (isLowerCase == (java.lang.Character.isLetter(c) && java.lang.Character.isLowerCase(c))) {
  167. if (isLowerCase) {
  168. data[i] = java.lang.Character.toUpperCase(c);
  169. }
  170. i++;
  171. if (i == end)
  172. break;
  173. c = data[i];
  174. }
  175. if (isLowerCase) {
  176. fontStateToUse = smallCapsFontState;
  177. } else {
  178. fontStateToUse = fontState;
  179. }
  180. int index = addRealText(ba, fontStateToUse, red, green, blue, wrapOption, ls,
  181. whiteSpaceCollapse, data, caseStart, i, textState, vAlign);
  182. if (index != -1) {
  183. return index;
  184. }
  185. }
  186. return -1;
  187. }
  188. // font-variant normal
  189. return addRealText(ba, fontState, red, green, blue, wrapOption, ls,
  190. whiteSpaceCollapse, data, start, end, textState, vAlign);
  191. }
  192. protected static int addRealText(BlockArea ba, FontState fontState, float red, float green,
  193. float blue, int wrapOption, LinkSet ls,
  194. int whiteSpaceCollapse, char data[], int start, int end,
  195. TextState textState, int vAlign) {
  196. int ts, te;
  197. char[] ca;
  198. ts = start;
  199. te = end;
  200. ca = data;
  201. LineArea la = ba.getCurrentLineArea();
  202. if (la == null) {
  203. return start;
  204. }
  205. la.changeFont(fontState);
  206. la.changeColor(red, green, blue);
  207. la.changeWrapOption(wrapOption);
  208. la.changeWhiteSpaceCollapse(whiteSpaceCollapse);
  209. la.changeVerticalAlign(vAlign);
  210. // la.changeHyphenation(language, country, hyphenate,
  211. // hyphenationChar, hyphenationPushCharacterCount,
  212. // hyphenationRemainCharacterCount);
  213. ba.setupLinkSet(ls);
  214. ts = la.addText(ca, ts, te, ls, textState);
  215. // this.hasLines = true;
  216. while (ts != -1) {
  217. la = ba.createNextLineArea();
  218. if (la == null) {
  219. return ts;
  220. }
  221. la.changeFont(fontState);
  222. la.changeColor(red, green, blue);
  223. la.changeWrapOption(wrapOption);
  224. la.changeWhiteSpaceCollapse(
  225. whiteSpaceCollapse);
  226. // la.changeHyphenation(language, country, hyphenate,
  227. // hyphenationChar, hyphenationPushCharacterCount,
  228. // hyphenationRemainCharacterCount);
  229. ba.setupLinkSet(ls);
  230. ts = la.addText(ca, ts, te, ls, textState);
  231. }
  232. return -1;
  233. }
  234. }