Source Code Cross Referenced for TextCompiler.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » Laszlo 4.0.10 » org.openlaszlo.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*****************************************************************************
002:         * TextCompiler.java
003:         * ****************************************************************************/package org.openlaszlo.compiler;
004:
005:        import org.openlaszlo.utils.ChainedException;
006:        import java.io.*;
007:        import java.util.*;
008:        import org.jdom.Attribute;
009:        import org.jdom.Comment;
010:        import org.jdom.CDATA;
011:        import org.jdom.Document;
012:        import org.jdom.Element;
013:        import org.jdom.EntityRef;
014:        import org.jdom.Text;
015:        import org.jdom.output.XMLOutputter;
016:        import java.util.Iterator;
017:        import org.apache.log4j.*;
018:        import org.openlaszlo.iv.flash.api.text.Font;
019:        import java.awt.geom.Rectangle2D;
020:
021:        /** Utility functions for measuring HTML content, and translating it into Flash strings.
022:         *
023:         * @author <a href="mailto:hminsky@laszlosystems.com">Henry Minsky</a>
024:         */
025:        abstract class TextCompiler {
026:
027:            private static Logger mLogger = Logger
028:                    .getLogger(TextCompiler.class);
029:            private static Logger mTextLogger = Logger.getLogger("lps.text");
030:
031:            public static double computeTextWidth(String text,
032:                    FontInfo fontInfo, SWFWriter generator)
033:                    throws CompilationError {
034:                LineMetrics lm = new LineMetrics();
035:                return computeTextWidth(text, fontInfo, generator, lm);
036:            }
037:
038:            /** Check if a specified font is known by the Font Manager
039:             *
040:             * @param generator
041:             * @param fontInfo the font spec you want to check
042:             *
043:             * This will throw an informative CompilationError if the font does not exist.
044:             */
045:            public static void checkFontExists(SWFWriter generator,
046:                    FontInfo fontInfo) {
047:                String fontName = fontInfo.getName();
048:                int size = fontInfo.getSize();
049:                int style = fontInfo.styleBits;
050:
051:                if (!generator.checkFontExists(fontInfo)) {
052:                    throw new CompilationError(
053:                    /* (non-Javadoc)
054:                     * @i18n.test
055:                     * @org-mes="Can't find font " + p[0] + " of style " + p[1]
056:                     */
057:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
058:                            TextCompiler.class.getName(), "051018-60",
059:                            new Object[] { fontName, fontInfo.getStyle() }));
060:                }
061:            }
062:
063:            /**
064:             * Compute text width for a given font 
065:             *
066:             * @param text text stringtext string
067:             * @param fontInfo font info for this text
068:             * @return text width in pixels
069:             */
070:            public static double computeTextWidth(String text,
071:                    FontInfo fontInfo, SWFWriter generator, LineMetrics lm)
072:                    throws CompilationError {
073:
074:                boolean trace = false; //mProperties.getProperty("trace.fonts", "false") == "true";
075:
076:                String fontName = fontInfo.getName();
077:                int size = fontInfo.getSize();
078:                int style = fontInfo.styleBits;
079:
080:                mTextLogger.debug(
081:                /* (non-Javadoc)
082:                 * @i18n.test
083:                 * @org-mes="computeTextWidth fontName " + p[0] + " (style: " + p[1] + ", size: " + p[2] + ") text: " + p[3]
084:                 */
085:                org.openlaszlo.i18n.LaszloMessages.getMessage(
086:                        TextCompiler.class.getName(), "051018-87",
087:                        new Object[] { fontName, fontInfo.getStyle(),
088:                                new Integer(fontInfo.getSize()), text }));
089:
090:                if (text.length() == 0) {
091:                    return 0;
092:                }
093:
094:                generator.checkFontExists(fontInfo);
095:
096:                FontFamily family = generator.getFontManager().getFontFamily(
097:                        fontName);
098:                if (family == null) {
099:                    throw new CompilationError("Can't find font " + fontName);
100:                }
101:
102:                Font font = family.getStyle(style);
103:                if (font == null) {
104:                    throw new CompilationError(
105:                    /* (non-Javadoc)
106:                     * @i18n.test
107:                     * @org-mes="Can't measure text because font " + p[0] + " " + p[1] + " is missing."
108:                     */
109:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
110:                            TextCompiler.class.getName(), "051018-109",
111:                            new Object[] { FontInfo.styleBitsToString(style),
112:                                    fontName }));
113:                }
114:
115:                Rectangle2D[] bounds = family.getBounds(style);
116:
117:                if (bounds == null) {
118:                    throw new CompilationError(
119:                    /* (non-Javadoc)
120:                     * @i18n.test
121:                     * @org-mes="Can't measure text because font " + p[0] + " " + p[1] + " is missing its bounds array."
122:                     */
123:                    org.openlaszlo.i18n.LaszloMessages.getMessage(
124:                            TextCompiler.class.getName(), "051018-122",
125:                            new Object[] { FontInfo.styleBitsToString(style),
126:                                    fontName }));
127:                }
128:
129:                double width = 0;
130:                int length = text.length();
131:                char c = text.charAt(0);
132:                int idx = font.getIndex(c);
133:                int nextIdx;
134:
135:                double last_charwidth = 0;
136:
137:                // Cope with \n \r and missing characters? XXX
138:                for (int i = 0; i < length; i++) {
139:                    if (idx == -1) {
140:                        mLogger.warn(
141:                        /* (non-Javadoc)
142:                         * @i18n.test
143:                         * @org-mes="Character \'" + p[0] + "\' (" + p[1] + ") not available in font " + p[2] + " (style " + p[3] + ")"
144:                         */
145:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
146:                                TextCompiler.class.getName(), "051018-143",
147:                                new Object[] { new Character(c),
148:                                        new Integer((int) c), fontName,
149:                                        fontInfo.getStyle() }));
150:                        continue;
151:                    } else {
152:                        double adv = font.getAdvanceValue(idx);
153:
154:                        if (i == length - 1) {
155:                            double m = 0;
156:                            try {
157:                                m = bounds[idx].getMaxX();
158:                            } catch (Exception e) {
159:                            }
160:                            if (m > adv) {
161:                                adv = m;
162:                            }
163:                        }
164:
165:                        if (i == 0) {
166:                            try {
167:                                double m = bounds[idx].getMinX();
168:                                if (m > 0) {
169:                                    adv += m;
170:                                }
171:                            } catch (Exception e) {
172:                            }
173:                        }
174:
175:                        last_charwidth = adv;
176:                        width += adv;
177:
178:                        mLogger.debug("adv " + adv);
179:                    }
180:
181:                    if (i != length - 1) {
182:                        c = text.charAt(i + 1);
183:                        nextIdx = font.getIndex(c);
184:                        if (nextIdx != -1) {
185:                            double cw = font.getKerning(idx, nextIdx);
186:                            width += cw;
187:                        }
188:                        idx = nextIdx;
189:                    }
190:                }
191:                // Width in pixels
192:                double w = (double) (width * fontInfo.getSize()) / 1024.0;
193:
194:                // If the last character was a space, remember it's width, as we may need
195:                // to trim the trailing space from the HTML formatted text
196:                if (c == ' ') {
197:                    lm.last_spacewidth = (double) (last_charwidth * fontInfo
198:                            .getSize()) / 1024.0;
199:                }
200:
201:                mTextLogger.debug(
202:                /* (non-Javadoc)
203:                 * @i18n.test
204:                 * @org-mes="computeTextWidth: " + p[0] + " (font: " + p[1] + ", size: " + p[2] + ", style: " + p[3] + ") has textwidth: " + p[4]
205:                 */
206:                org.openlaszlo.i18n.LaszloMessages.getMessage(
207:                        TextCompiler.class.getName(), "051018-201",
208:                        new Object[] { text, fontInfo.getName(),
209:                                new Integer(fontInfo.getSize()),
210:                                fontInfo.getStyle(), new Double(w) }));
211:
212:                // FIXME: [2003-09-26 bloch] handle empty string case? should it be w/out slop?
213:                // Match this in LzNewText.as
214:                //
215:                final int SLOP = 2;
216:
217:                return w + SLOP;
218:            }
219:
220:            /** Compute the text width of a string. If there are multiple
221:             * lines, return the maximum line width.
222:             *
223:             * <p>
224:             *
225:             * The only multi-line strings we will ever see here will be
226:             * non-normalized text such as inside &ltpre;&gt; verbatim
227:             * regions, because in normal running HTML text, the normalization
228:             * will have stripped out newlines.
229:             *
230:             * <p>
231:             *
232:             * The LineMetrics holds state from possibly a previous text run
233:             * on the same line, telling us whether we need to prepend an
234:             * extra whitespace.
235:             */
236:            static double getTextWidth(String str, FontInfo fontInfo,
237:                    SWFWriter generator, LineMetrics lm) {
238:
239:                double maxw = 0;
240:                int lastpos = 0;
241:                int nextpos = str.indexOf('\n');
242:                String substr;
243:
244:                if (nextpos < 0) {
245:                    return computeTextWidth(str, fontInfo, generator, lm);
246:                }
247:                while (nextpos >= 0) {
248:                    substr = str.substring(lastpos, nextpos);
249:                    maxw = Math.max(maxw, computeTextWidth(substr, fontInfo,
250:                            generator, lm));
251:                    lastpos = nextpos + 1;
252:                    nextpos = str.indexOf('\n', lastpos);
253:                    lm.nlines++;
254:                }
255:
256:                substr = str.substring(lastpos);
257:                maxw = Math.max(maxw, computeTextWidth(substr, fontInfo,
258:                        generator, lm));
259:                return maxw;
260:            }
261:
262:            /** Measure the content text allowing for "HTML" markup.
263:             *
264:             * This uses rules similar to how you would measure browser HTML text:
265:             *
266:             * <ul>
267:             * <li> All text is whitespace normalized, except that which occurs between &lt;pre&gt; tags
268:             * <li> Linebreaks occur only when &lt;br/&gt; or &lt;p/&gt; elements occur, or when a newline
269:             * is present inside of a &lt;pre&gt; region.
270:             * <li> When multiple text lines are present, the length of the longest line is returned.
271:             * </ul>
272:             */
273:
274:            static LineMetrics getElementWidth(Element e, FontInfo fontInfo,
275:                    SWFWriter generator) {
276:                LineMetrics lm = new LineMetrics();
277:                getElementWidth(e, fontInfo, generator, lm);
278:                lm.endOfLine();
279:                // cache the normalized HTML content
280:                ((ElementWithLocationInfo) e).setHTMLContent(lm.getText());
281:                return lm;
282:            }
283:
284:            /** Gets the text content, with HTML normalization rules applied */
285:            static String getHTMLContent(Element e) {
286:                // check if the normalized text is cached
287:                if ((e instanceof  ElementWithLocationInfo)
288:                        && ((ElementWithLocationInfo) e).getHTMLContent() != null) {
289:                    return ((ElementWithLocationInfo) e).getHTMLContent();
290:                }
291:
292:                LineMetrics lm = new LineMetrics();
293:                // Just use a dummy font info, we only care about the HTML
294:                // text, not string widths
295:                FontInfo fontInfo = new FontInfo("default", "8", "");
296:                getElementWidth(e, fontInfo, null, lm);
297:                lm.endOfLine();
298:                return lm.getText();
299:            }
300:
301:            /** Return text suitable for passing to Laszlo inputtext component.
302:             * This means currently no HTML tags are supported except PRE
303:             */
304:            static String getInputText(Element e) {
305:                String text = "";
306:                for (Iterator iter = e.getContent().iterator(); iter.hasNext();) {
307:                    Object node = iter.next();
308:                    if (node instanceof  Element) {
309:                        Element child = (Element) node;
310:                        String tagName = child.getName();
311:                        if (tagName.equals("p") || tagName.equals("br")) {
312:                            text += "\n";
313:                        } else if (tagName.equals("pre")) {
314:                            text += child.getText();
315:                        } else {
316:                            // ignore everything else
317:                        }
318:                    } else if ((node instanceof  Text)
319:                            || (node instanceof  CDATA)) {
320:                        if (node instanceof  Text) {
321:                            text += ((Text) node).getTextNormalize();
322:                        } else {
323:                            text += ((CDATA) node).getTextNormalize();
324:                        }
325:                    }
326:                }
327:                return text;
328:            }
329:
330:            /** 
331:                Processes the text content of the element.  The element
332:                content may contain XHTML markup elements, which we will
333:                interpret as we map over the content. Normally, whitespace
334:                will be normalized away. However, preformat &lt;pre&gt; tags
335:                will cause the enclosed text to be treated as verbatim,
336:                meaning means that whitespace and linebreaks will be
337:                preserved.
338:            
339:                Supported XHTML markup is currently:
340:                <ul>
341:                <li> P, BR cause linebreaks
342:                <li> PRE sets verbatim (literal whitespace) mode
343:                <li> font face control: B, I, FONT tags modify the font
344:                <li> A [href] indicates a hyperlink
345:                </ul>
346:
347:             */
348:            static void getElementWidth(Element e, FontInfo fontInfo,
349:                    SWFWriter generator, LineMetrics lm) {
350:                for (Iterator iter = e.getContent().iterator(); iter.hasNext();) {
351:                    Object node = iter.next();
352:                    if (node instanceof  Element) {
353:                        Element child = (Element) node;
354:                        String tagName = child.getName();
355:
356:                        if (tagName.equals("br")) {
357:                            lm.newline(); // explicit linebreak
358:                            getElementWidth(child, fontInfo, generator, lm);
359:                            if (!child.getText().equals("")) {
360:                                lm.newline();
361:                            }
362:                        } else if (tagName.equals("p")) {
363:                            lm.paragraphBreak();
364:                            getElementWidth(child, fontInfo, generator, lm);
365:                            lm.paragraphBreak();
366:                        } else if (tagName.equals("pre")) {
367:                            boolean prev = lm.verbatim;
368:                            lm.setVerbatim(true);
369:                            getElementWidth(child, fontInfo, generator, lm);
370:                            lm.setVerbatim(prev);
371:                        } else if (ViewSchema.isHTMLElement(child)) {
372:                            FontInfo newInfo = new FontInfo(fontInfo);
373:                            if (tagName.equals("b")) {
374:                                newInfo.styleBits |= FontInfo.BOLD;
375:                            } else if (tagName.equals("i")) {
376:                                newInfo.styleBits |= FontInfo.ITALIC;
377:                            } else if (tagName.equals("font")) {
378:                                ViewCompiler.setFontInfo(newInfo, child);
379:                            }
380:                            lm.addStartTag(tagName, newInfo, generator);
381:                            // print font-related attributes:
382:                            // face, size, color
383:                            // supported Flash HTML tags: http://www.macromedia.com/support/flash/ts/documents/htmltext.htm
384:                            for (Iterator attrs = child.getAttributes()
385:                                    .iterator(); attrs.hasNext();) {
386:                                Attribute attr = (Attribute) attrs.next();
387:                                String name = attr.getName();
388:                                String value = child.getAttributeValue(name);
389:                                // TBD: [hqm nov-15-2002] The value ought to be quoted in case it contains double quotes
390:                                // (but no values of currently supported HTML tags will contain double quotes)
391:                                lm.addFormat(" " + name + "=\"" + value + "\"");
392:                            }
393:                            lm.endStartTag();
394:                            getElementWidth(child, newInfo, generator, lm);
395:                            lm.addEndTag(tagName);
396:                        }
397:                    } else if ((node instanceof  Text)
398:                            || (node instanceof  CDATA)) {
399:                        String rawtext;
400:                        if (node instanceof  Text) {
401:                            rawtext = ((Text) node).getText();
402:                        } else {
403:                            rawtext = ((CDATA) node).getText();
404:                        }
405:                        if (lm.verbatim) {
406:                            lm.addSpan(rawtext, fontInfo, generator);
407:                        } else {
408:                            // Apply HTML normalization rules to the text content.
409:                            if (rawtext.length() > 0) {
410:                                // getTextNormalize turns an all-whitespace string into an empty string
411:                                String normalized_text;
412:                                if (node instanceof  Text) {
413:                                    normalized_text = ((Text) node)
414:                                            .getTextNormalize();
415:                                } else {
416:                                    normalized_text = ((CDATA) node)
417:                                            .getTextNormalize();
418:                                }
419:                                lm.addHTML(rawtext, normalized_text, fontInfo,
420:                                        generator);
421:                            }
422:                        }
423:                    } else if (node instanceof  EntityRef) {
424:                        // EntityRefs don't seem to occur in our JDOM, they were all resolved
425:                        // to strings by the parser already
426:                        throw new RuntimeException(
427:                        /* (non-Javadoc)
428:                         * @i18n.test
429:                         * @org-mes="encountered unexpected EntityRef node in getElementWidth()"
430:                         */
431:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
432:                                TextCompiler.class.getName(), "051018-418"));
433:                    }
434:                }
435:            }
436:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.