1 4 5 9 10 package org.openlaszlo.compiler; 11 import org.openlaszlo.utils.ChainedException; 12 import java.io.*; 13 import java.util.*; 14 import org.jdom.Attribute; 15 import org.jdom.Comment; 16 import org.jdom.CDATA; 17 import org.jdom.Document; 18 import org.jdom.Element; 19 import org.jdom.EntityRef; 20 import org.jdom.Text; 21 import org.jdom.output.XMLOutputter; 22 import java.util.Iterator ; 23 import org.apache.log4j.*; 24 import org.openlaszlo.iv.flash.api.text.Font; 25 import java.awt.geom.Rectangle2D ; 26 27 31 abstract class TextCompiler { 32 33 private static Logger mLogger = Logger.getLogger(TextCompiler.class); 34 private static Logger mTextLogger = Logger.getLogger("lps.text"); 35 36 public static double computeTextWidth(String text, FontInfo fontInfo, SWFWriter generator) 37 throws CompilationError { 38 LineMetrics lm = new LineMetrics(); 39 return computeTextWidth(text, fontInfo, generator, lm); 40 } 41 42 49 public static void checkFontExists (SWFWriter generator, FontInfo fontInfo) { 50 String fontName = fontInfo.getName(); 51 int size = fontInfo.getSize(); 52 int style = fontInfo.styleBits; 53 54 if (!generator.checkFontExists(fontInfo)) { 55 throw new CompilationError( 56 "Can't find font " 57 + fontName 58 + " of style " 59 + fontInfo.getStyle()); 60 } 61 } 62 63 70 public static double computeTextWidth(String text, FontInfo fontInfo, SWFWriter generator, LineMetrics lm) 71 throws CompilationError { 72 73 boolean trace = false; 75 String fontName = fontInfo.getName(); 76 int size = fontInfo.getSize(); 77 int style = fontInfo.styleBits; 78 79 mTextLogger.debug("computeTextWidth fontName " + fontName + 80 " (style: " + fontInfo.getStyle() + 81 ", size: " + fontInfo.getSize() + 82 ") text: " + text); 83 84 if (text.length() == 0) { 85 return 0; 86 } 87 88 generator.checkFontExists(fontInfo); 89 90 FontFamily family = generator.getFontManager().getFontFamily(fontName); 91 if (family == null) { 92 throw new CompilationError("Can't find font " + fontName); 93 } 94 95 Font font = family.getStyle(style); 96 if (font == null) { 97 throw new CompilationError( 98 "Can't measure text because font " 99 + FontInfo.styleBitsToString(style) + " " 100 + fontName 101 + " is missing."); 102 } 103 104 Rectangle2D [] bounds = family.getBounds(style); 105 106 if (bounds == null) { 107 throw new CompilationError( 108 "Can't measure text because font " 109 + FontInfo.styleBitsToString(style) + " " 110 + fontName 111 + " is missing its bounds array."); 112 } 113 114 double width = 0; 115 int length = text.length(); 116 char c = text.charAt(0); 117 int idx = font.getIndex(c); 118 int nextIdx; 119 120 double last_charwidth = 0; 121 122 for(int i = 0; i < length; i++) { 124 if (idx == -1) { 125 mLogger.warn("Character \'" + c + 126 "\' (" + (int)c + ") not available in font " + fontName + 127 " (style " + 128 fontInfo.getStyle() + ")"); 129 continue; 130 } else { 131 double adv = font.getAdvanceValue(idx); 132 133 if (i == length - 1) { 134 double m = 0; 135 try { 136 m = bounds[idx].getMaxX(); 137 } catch (Exception e) { 138 } 139 if (m > adv) { 140 adv = m; 141 } 142 } 143 144 if (i == 0) { 145 try { 146 double m = bounds[idx].getMinX(); 147 if (m > 0) { 148 adv += m; 149 } 150 } catch (Exception e) { 151 } 152 } 153 154 last_charwidth = adv; 155 width += adv; 156 157 mLogger.debug("adv " + adv); 158 } 159 160 if (i != length - 1) { 161 c = text.charAt(i+1); 162 nextIdx = font.getIndex(c); 163 if (nextIdx != -1) { 164 double cw = font.getKerning(idx, nextIdx); 165 width += cw; 166 } 167 idx = nextIdx; 168 } 169 } 170 double w = (double)(width * fontInfo.getSize()) / 1024.0; 172 173 if (c == ' ') { 176 lm.last_spacewidth = (double)(last_charwidth * fontInfo.getSize()) / 1024.0; 177 } 178 179 mTextLogger.debug("computeTextWidth: " + text + 180 " (font: " + fontInfo.getName() + 181 ", size: " + fontInfo.getSize() + 182 ", style: " + fontInfo.getStyle() + 183 ") has textwidth: " + w); 184 185 final int SLOP = 2; 189 190 return w + SLOP; 191 } 192 193 209 static double getTextWidth(String str, FontInfo fontInfo, SWFWriter generator, 210 LineMetrics lm) { 211 212 double maxw = 0; 213 int lastpos = 0; 214 int nextpos = str.indexOf('\n'); 215 String substr; 216 217 if (nextpos < 0) { 218 return computeTextWidth(str, fontInfo, generator, lm); 219 } 220 while (nextpos >= 0) { 221 substr = str.substring(lastpos, nextpos); 222 maxw = Math.max(maxw, computeTextWidth(substr, fontInfo, generator, lm)); 223 lastpos = nextpos+1; 224 nextpos = str.indexOf('\n', lastpos); 225 lm.nlines++; 226 } 227 228 substr = str.substring(lastpos); 229 maxw = Math.max(maxw, computeTextWidth(substr, fontInfo, generator, lm)); 230 return maxw; 231 } 232 233 244 245 static LineMetrics getElementWidth(Element e, FontInfo fontInfo, SWFWriter generator) { 246 LineMetrics lm = new LineMetrics(); 247 getElementWidth(e, fontInfo, generator, lm); 248 lm.endOfLine(); 249 ((ElementWithLocationInfo) e).setHTMLContent(lm.getText()); 251 return lm; 252 } 253 254 255 static String getHTMLContent(Element e) { 256 if ((e instanceof ElementWithLocationInfo) && 258 ((ElementWithLocationInfo) e).getHTMLContent() != null) { 259 return ((ElementWithLocationInfo) e).getHTMLContent(); 260 } 261 262 LineMetrics lm = new LineMetrics(); 263 FontInfo fontInfo = new FontInfo("default", "8", ""); 266 getElementWidth(e, fontInfo, null, lm); 267 lm.endOfLine(); 268 return lm.getText(); 269 } 270 271 274 static String getInputText (Element e) { 275 String text = ""; 276 for (Iterator iter = e.getContent().iterator(); 277 iter.hasNext();) { 278 Object node = iter.next(); 279 if (node instanceof Element) { 280 Element child = (Element) node; 281 String tagName = child.getName(); 282 if (tagName.equals("p") || tagName.equals("br")) { 283 text += "\n"; 284 } else if (tagName.equals("pre")) { 285 text += child.getText(); 286 } else { 287 } 289 } else if ((node instanceof Text) || (node instanceof CDATA)) { 290 if (node instanceof Text) { 291 text += ((Text) node).getTextNormalize(); 292 } else { 293 text += ((CDATA) node).getTextNormalize(); 294 } 295 } 296 } 297 return text; 298 } 299 300 301 319 static void getElementWidth(Element e, FontInfo fontInfo, SWFWriter generator, 320 LineMetrics lm) { 321 for (Iterator iter = e.getContent().iterator(); 322 iter.hasNext();) { 323 Object node = iter.next(); 324 if (node instanceof Element) { 325 Element child = (Element) node; 326 String tagName = child.getName(); 327 328 if (tagName.equals("br")) { 329 lm.newline(); getElementWidth(child, fontInfo, generator, lm); 331 if (!child.getText().equals("")) { 332 lm.newline(); 333 } 334 } else if (tagName.equals("p")) { 335 lm.paragraphBreak(); 336 getElementWidth(child, fontInfo, generator, lm); 337 lm.paragraphBreak(); 338 } else if (tagName.equals("pre")) { 339 boolean prev = lm.verbatim; 340 lm.setVerbatim(true); 341 getElementWidth(child, fontInfo, generator, lm); 342 lm.setVerbatim(prev); 343 } else if (ViewSchema.isHTMLElement(child)) { 344 FontInfo newInfo = new FontInfo(fontInfo); 345 if (tagName.equals("b")) { 346 newInfo.styleBits |= FontInfo.BOLD; 347 } else if (tagName.equals("i")) { 348 newInfo.styleBits |= FontInfo.ITALIC; 349 } else if (tagName.equals("font")) { 350 ViewCompiler.setFontInfo(newInfo, child); 351 } 352 lm.addStartTag(tagName, newInfo, generator); 353 for (Iterator attrs = child.getAttributes().iterator(); attrs.hasNext(); ) { 357 Attribute attr = (Attribute) attrs.next(); 358 String name = attr.getName(); 359 String value = child.getAttributeValue(name); 360 lm.addFormat(" "+name+"=\""+value+"\""); 363 } 364 lm.endStartTag(); 365 getElementWidth(child, newInfo, generator, lm); 366 lm.addEndTag(tagName); 367 } 368 } else if ((node instanceof Text) || (node instanceof CDATA)) { 369 String rawtext; 370 if (node instanceof Text) { 371 rawtext = ((Text) node).getText(); 372 } else { 373 rawtext = ((CDATA) node).getText(); 374 } 375 if (lm.verbatim) { 376 lm.addSpan(rawtext, fontInfo, generator); 377 } else { 378 if (rawtext.length() > 0) { 380 String normalized_text; 382 if (node instanceof Text) { 383 normalized_text = ((Text) node).getTextNormalize(); 384 } else { 385 normalized_text = ((CDATA) node).getTextNormalize(); 386 } 387 lm.addHTML (rawtext, normalized_text, fontInfo, generator); 388 } 389 } 390 } else if (node instanceof EntityRef) { 391 throw new RuntimeException ("encountered unexpected EntityRef node in getElementWidth()"); 394 } 395 } 396 } 397 } 398 | Popular Tags |