Source Code Cross Referenced for TextLayout.java in  » Ajax » Laszlo-4.0.10 » org » openlaszlo » iv » flash » util » 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.iv.flash.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: TextLayout.java,v 1.5 2002/07/15 02:15:03 skavish Exp $
003:         *
004:         * ===========================================================================
005:         *
006:         * The JGenerator Software License, Version 1.0
007:         *
008:         * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009:         *
010:         * Redistribution and use in source and binary forms, with or without
011:         * modification, are permitted provided that the following conditions are met:
012:         *
013:         * 1. Redistributions of source code must retain the above copyright
014:         *    notice, this list of conditions and the following disclaimer.
015:         *
016:         * 2. Redistributions in binary form must reproduce the above copyright
017:         *    notice, this list of conditions and the following disclaimer in
018:         *    the documentation and/or other materials provided with the
019:         *    distribution.
020:         *
021:         * 3. The end-user documentation included with the redistribution, if
022:         *    any, must include the following acknowlegement:
023:         *    "This product includes software developed by Dmitry Skavish
024:         *     (skavish@usa.net, http://www.flashgap.com/)."
025:         *    Alternately, this acknowlegement may appear in the software itself,
026:         *    if and wherever such third-party acknowlegements normally appear.
027:         *
028:         * 4. The name "The JGenerator" must not be used to endorse or promote
029:         *    products derived from this software without prior written permission.
030:         *    For written permission, please contact skavish@usa.net.
031:         *
032:         * 5. Products derived from this software may not be called "The JGenerator"
033:         *    nor may "The JGenerator" appear in their names without prior written
034:         *    permission of Dmitry Skavish.
035:         *
036:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039:         * DISCLAIMED.  IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047:         * SUCH DAMAGE.
048:         *
049:         */
050:
051:        package org.openlaszlo.iv.flash.util;
052:
053:        import java.io.*;
054:        import java.awt.geom.*;
055:
056:        import org.openlaszlo.iv.flash.api.*;
057:        import org.openlaszlo.iv.flash.api.text.*;
058:
059:        /**
060:         * This class does simple text layout in a box.
061:         * <P>
062:         *
063:         * @author Dmitry Skavish
064:         * @see org.openlaszlo.iv.flash.api.text.Text
065:         * @see org.openlaszlo.iv.flash.api.text.Font
066:         * @see org.openlaszlo.iv.flash.api.text.FontDef
067:         * @see org.openlaszlo.iv.flash.api.text.TextRecord
068:         * @see org.openlaszlo.iv.flash.api.text.TextStyleChangeRecord
069:         */
070:        public final class TextLayout {
071:
072:            private static final int MAX_CHARS_IN_LINE = 250;
073:
074:            /**
075:             * One line of text.
076:             * <p>
077:             * Contains several style runs (text of different font and style)
078:             */
079:            public final class TextLine extends FlashItem {
080:
081:                /**
082:                 * Vector of TextRecords and TextStyleChangeRecords
083:                 * <P>
084:                 * TextStyleChangeRecords are at even positions,
085:                 * TextRecords are at odd positions.
086:                 */
087:                public IVVector records = new IVVector(4);
088:
089:                private TextItem lastItem;
090:                private TextRecord lastRecord;
091:
092:                public TextLine() {
093:                }
094:
095:                /**
096:                 * Creates new text record.
097:                 */
098:                public void newRecord() {
099:                    flushLastRecord();
100:                    lastItem = curItem;
101:                    lastRecord = new TextRecord(MAX_CHARS_IN_LINE);
102:                }
103:
104:                private void flushLastRecord() {
105:                    if (lastRecord != null && lastRecord.getSize() != 0) {
106:                        int size = records.size();
107:                        if (size % 2 == 0) { // make sure we add stylechange only after textrecord
108:                            records.addElement(getStyleChange(lastItem));
109:                        }
110:                        records.addElement(lastRecord);
111:                        lastRecord = null;
112:                    }
113:                }
114:
115:                /**
116:                 * Creates text style change record from specified text item
117:                 * and sets all the properties, like font, color and height as
118:                 * current properties.
119:                 *
120:                 * @param item   item for which to create style change record
121:                 * @return new style change record
122:                 */
123:                private TextStyleChangeRecord getStyleChange(TextItem item) {
124:                    // create text style change record
125:                    TextStyleChangeRecord ts = new TextStyleChangeRecord();
126:
127:                    if (item != null) {
128:                        ts.setFont(item.font);
129:                        ts.setHeight(item.height);
130:                        ts.setColor(item.color);
131:                    }
132:
133:                    return ts;
134:                }
135:
136:                /**
137:                 * Adds new character to last text record.
138:                 * <P>
139:                 * If last text record is overflowed then creates new text record
140:                 *
141:                 * @param ch     character to be added
142:                 * @param index  index of character in the font
143:                 * @param adv    advance value of the character
144:                 */
145:                public void add(char ch, int index, int adv) {
146:                    if (lastRecord.getSize() >= MAX_CHARS_IN_LINE) {
147:                        newRecord();
148:                    }
149:                    lastRecord.add(ch, index, adv);
150:                }
151:
152:                /**
153:                 * Trims this line from the end
154:                 * <P>
155:                 * Removes all spaces from the end
156:                 *
157:                 * @return width in twixels of all removed spaces
158:                 */
159:                public int trimEnd() {
160:                    flushLastRecord();
161:
162:                    int w = 0;
163:
164:                    for (int i = records.size(); --i > 0;) {
165:                        TextRecord tr = (TextRecord) records.elementAt(i);
166:                        w += tr.trimEnd();
167:                        if (tr.getSize() > 0)
168:                            break;
169:                        records.removeElementAt(i); // remove text record
170:                        records.removeElementAt(--i); // remove stylechange record
171:                    }
172:
173:                    return w;
174:                }
175:
176:                /**
177:                 * Trims this line from the start
178:                 * <P>
179:                 * Removes all spaces from the start
180:                 *
181:                 * @return width in twixels of all removed spaces
182:                 */
183:                public int trimStart() {
184:                    flushLastRecord();
185:
186:                    int w = 0;
187:
188:                    TextStyleChangeRecord lastts = null;
189:
190:                    for (; records.size() > 0;) {
191:                        TextStyleChangeRecord ts = (TextStyleChangeRecord) records
192:                                .elementAt(0);
193:                        if (lastts != null) {
194:                            lastts.mergeTo(ts);
195:                        }
196:                        lastts = ts;
197:                        TextRecord tr = (TextRecord) records.elementAt(1);
198:                        w += tr.trimStart();
199:                        if (tr.getSize() > 0)
200:                            break;
201:                        records.removeElementAt(1); // remove text record
202:                        records.removeElementAt(0); // remove stylechange record
203:                    }
204:
205:                    return w;
206:                }
207:
208:                /**
209:                 * Mark current position in current text record.
210:                 * <P>
211:                 * Used for rolling back if word does not fit in the text rectangle.
212:                 */
213:                public void markPosition() {
214:                    markedPosition = lastRecord.getSize();
215:                }
216:
217:                /**
218:                 * Rollbacks current position to the marked one.
219:                 */
220:                public void rollBack() {
221:                    lastRecord.setSize(markedPosition);
222:                }
223:
224:                /**
225:                 * Does end-of-line.
226:                 * <P>
227:                 * Flushes current text record
228:                 *
229:                 * @param x      x position of this line
230:                 * @param y      y position of this line
231:                 */
232:                public void endLine(int x, int y) {
233:                    flushLastRecord();
234:                    if (records.size() > 0) {
235:                        TextStyleChangeRecord ts = (TextStyleChangeRecord) records
236:                                .elementAt(0);
237:                        ts.setX(x);
238:                        ts.setY(y);
239:                    }
240:                }
241:
242:                /**
243:                 * Returns maximum advance value from all the records.
244:                 *
245:                 * @return maximum advance value from all the records
246:                 */
247:                public int getMaxAdvance() {
248:                    int max = Integer.MIN_VALUE;
249:                    // iterate over TextRecords only
250:                    for (int i = 1; i < records.size(); i += 2) {
251:                        TextRecord tr = (TextRecord) records.elementAt(i);
252:                        int adv = tr.getMaxAdvance();
253:                        if (adv > max)
254:                            max = adv;
255:                    }
256:                    if (max == Integer.MIN_VALUE)
257:                        return 0;
258:                    return max;
259:                }
260:
261:                /**
262:                 * Returns maximum character index from all the records.
263:                 *
264:                 * @return maximum character index from all the records
265:                 */
266:                public int getMaxIndex() {
267:                    int max = Integer.MIN_VALUE;
268:                    // iterate over TextRecords only
269:                    for (int i = 1; i < records.size(); i += 2) {
270:                        TextRecord tr = (TextRecord) records.elementAt(i);
271:                        int idx = tr.getMaxIndex();
272:                        if (idx > max)
273:                            max = idx;
274:                    }
275:                    if (max == Integer.MIN_VALUE)
276:                        return 0;
277:                    return max;
278:                }
279:
280:                /**
281:                 * Returns width of this line.
282:                 *
283:                 * @return width if this line in twixels
284:                 */
285:                public int getWidth() {
286:                    if (records.size() == 0)
287:                        return 0;
288:                    TextStyleChangeRecord ts = (TextStyleChangeRecord) records
289:                            .elementAt(0);
290:                    int width = ts.getX();
291:                    for (int i = 1; i < records.size(); i += 2) {
292:                        TextRecord tr = (TextRecord) records.elementAt(i);
293:                        width += tr.getWidth();
294:                    }
295:                    return width;
296:                }
297:
298:                /**
299:                 * Return number of characters in this line
300:                 *
301:                 * @return number of characters in this line
302:                 */
303:                public int getSize() {
304:                    int size = 0;
305:                    // iterate over TextRecords only
306:                    for (int i = 1; i < records.size(); i += 2) {
307:                        TextRecord tr = (TextRecord) records.elementAt(i);
308:                        size += tr.getSize();
309:                    }
310:                    if (lastRecord != null)
311:                        size += lastRecord.getSize();
312:                    return size;
313:                }
314:
315:                public void printContent(PrintStream out, String indent) {
316:                    out.println(indent + "TextLine: size=" + records.size()
317:                            + " x=" + x + " y=" + y);
318:                    records.printContent(out, indent + "   ");
319:                }
320:
321:                public void write(FlashOutput fob) {
322:                    records.write(fob);
323:                }
324:
325:                protected FlashItem copyInto(FlashItem item, ScriptCopier copier) {
326:                    ((TextLine) item).records = records.getCopy(copier);
327:                    // there is no need to copy lastItem and lastRecord (?)
328:                    return item;
329:                }
330:
331:                public FlashItem getCopy(ScriptCopier copier) {
332:                    return copyInto(new TextLine(), copier);
333:                }
334:            }
335:
336:            private int markedPosition = 0; // used only by TextLine
337:
338:            private TextItem curItem;
339:            private TextLine curLine;
340:            private boolean line_continued;
341:            private int line_width;
342:            private int line_window;
343:            private int x;
344:            private int y;
345:            private int max_ascent;
346:            private int max_descent;
347:            private int max_linesp;
348:
349:            private int rect_width;
350:            private Text myText;
351:            private Rectangle2D bounds;
352:            private IVVector lines = new IVVector();
353:
354:            private void reCalcHeights() {
355:                Font font = curItem.font;
356:                int height = curItem.height;
357:                max_ascent = (font.ascent * height) / 1024;
358:                max_linesp = curItem.linesp;
359:                max_descent = (font.descent * height) / 1024 + max_linesp;
360:            }
361:
362:            private void endLine() {
363:                if (curLine != null) {
364:                    y += max_ascent; // advance y to baseline
365:                    curLine.endLine(x, y);
366:                    y += max_descent; // advance y to next line
367:                    curLine = null;
368:                }
369:            }
370:
371:            /**
372:             *
373:             * @param cont   true if this new line is continued from previous, this affects
374:             *               alignment of this line
375:             */
376:            private void newLine(boolean cont) {
377:                endLine();
378:                reCalcHeights();
379:                curLine = new TextLine();
380:                line_continued = cont;
381:                lines.addElement(curLine);
382:                curLine.newRecord();
383:                line_width = 0;
384:                x = curItem.marginleft;
385:                line_window = rect_width
386:                        - (curItem.marginleft + curItem.marginright);
387:            }
388:
389:            private void newParagraph() {
390:                newLine(false);
391:                line_window -= curItem.indent;
392:                x += curItem.indent;
393:            }
394:
395:            /**
396:             * Creates new text layout.
397:             *
398:             * @param myText text to be layed out
399:             * @param bounds rectangle to be used for laying the text out in
400:             */
401:            public TextLayout(Text myText, Rectangle2D bounds) {
402:                this .myText = myText;
403:                this .bounds = bounds;
404:            }
405:
406:            /**
407:             * Retrieves vector of text records layed out by this
408:             * text layout for the specified font.
409:             *
410:             * @param font   font of the records to be retrieved
411:             * @return vector of {@link org.openlaszlo.iv.flash.api.text.TextRecord}s
412:             */
413:            public IVVector getTextRecords(Font font) {
414:                IVVector trs = new IVVector();
415:                Font lastFont = null;
416:                for (int i = 0; i < lines.size(); i++) {
417:                    TextLine line = (TextLine) lines.elementAt(i);
418:                    for (int k = 0; k < line.records.size(); k++) {
419:                        Object o = line.records.elementAt(k);
420:                        if (o instanceof  TextStyleChangeRecord) {
421:                            Font f = ((TextStyleChangeRecord) o).getFont();
422:                            if (f != null)
423:                                lastFont = f;
424:                        } else {
425:                            if (lastFont == font)
426:                                trs.addElement(o);
427:                        }
428:                    }
429:                }
430:                return trs;
431:            }
432:
433:            /**
434:             * Retrieves vector of all text records
435:             *
436:             * @return vector of {@link org.openlaszlo.iv.flash.api.text.TextRecord}s and {@link org.openlaszlo.iv.flash.api.text.TextStyleChangeRecord}s
437:             */
438:            public IVVector getAllTextRecords() {
439:                IVVector trs = new IVVector();
440:                for (int i = 0; i < lines.size(); i++) {
441:                    TextLine line = (TextLine) lines.elementAt(i);
442:                    for (int k = 0; k < line.records.size(); k++) {
443:                        trs.addElement(line.records.elementAt(k));
444:                    }
445:                }
446:                return trs;
447:            }
448:
449:            /**
450:             * Updates records' font.
451:             * <P>
452:             * Changes one specified font into another in all records.
453:             * In text records also updates indexes.
454:             *
455:             * @param old_font old font
456:             * @param new_font new font
457:             */
458:            public void changeFont(Font old_font, Font new_font) {
459:                for (int i = 0; i < lines.size(); i++) {
460:                    TextLine line = (TextLine) lines.elementAt(i);
461:                    IVVector records = line.records;
462:                    FontDef.changeRecordsFont(records, old_font, new_font);
463:                }
464:            }
465:
466:            /**
467:             * Aligns current line
468:             */
469:            private void alignLine() {
470:                switch (curItem.align) {
471:                case 0: // left
472:                    if (curLine != null /*&& line_continued*/) {
473:                        line_width -= curLine.trimStart();
474:                    }
475:                    break;
476:                case 1: // right
477:                    if (curLine != null) {
478:                        line_width -= curLine.trimEnd();
479:                    }
480:                    x += line_window - line_width;
481:                    break;
482:                case 2: // center
483:                    if (curLine != null) {
484:                        line_width -= curLine.trimEnd() + curLine.trimStart();
485:                    }
486:                    x += (line_window - line_width) / 2;
487:                    break;
488:                case 3: // justify
489:                    // ........
490:                    break;
491:                }
492:            }
493:
494:            /**
495:             * Removes whitespace at the end of the text
496:             * <P>
497:             * Text is specified by vector of TextItems
498:             *
499:             * @param items  vector of TextItems
500:             * @return
501:             */
502:            private void trimEnd(IVVector items) {
503:                for (int i = items.size(); --i >= 0;) {
504:                    TextItem item = (TextItem) items.elementAt(i);
505:                    String t = item.text;
506:                    int j = t.length();
507:                    for (; --j >= 0;) {
508:                        char ch = t.charAt(j);
509:                        if (!Character.isWhitespace(ch))
510:                            break;
511:                    }
512:                    if (j >= 0) {
513:                        item.text = t.substring(0, j + 1);
514:                        return;
515:                    } else {
516:                        items.removeElementAt(i);
517:                    }
518:                }
519:            }
520:
521:            /**
522:             * Does text layout.
523:             */
524:            public void layout() {
525:                IVVector items = myText.getTextItems();
526:                trimEnd(items);
527:                //        System.out.println( "layout of '"+((TextItem)items.elementAt(0)).text+"'" );
528:
529:                rect_width = (int) bounds.getWidth();
530:
531:                y = 0;
532:
533:                if (items.size() > 0) {
534:                    curItem = (TextItem) items.elementAt(0);
535:
536:                    newParagraph();
537:
538:                    int i = 0;
539:                    for (;;) {
540:                        Font font = curItem.font;
541:                        int height = curItem.height;
542:                        int ascent = (font.ascent * height) / 1024;
543:                        int descent = (font.descent * height) / 1024
544:                                + curItem.linesp;
545:                        if (ascent > max_ascent)
546:                            max_ascent = ascent;
547:                        if (descent > max_descent) {
548:                            max_descent = descent;
549:                            max_linesp = curItem.linesp;
550:                        }
551:
552:                        String text = curItem.text;
553:                        boolean isNowWord = false;
554:                        int word_width = 0;
555:                        int start_word = 0;
556:
557:                        int text_len = text.length();
558:                        for (int k = 0; k < text_len; k++) {
559:                            char ch = text.charAt(k);
560:                            boolean isWord = isWord(ch);
561:                            if (!isNowWord && isWord) { // start new word
562:                                curLine.markPosition();
563:                                word_width = 0;
564:                                start_word = k;
565:                                isNowWord = true;
566:                            } else {
567:                                isNowWord = isWord;
568:                            }
569:                            if (ch == '\r' || ch == '\n') {
570:                                alignLine();
571:                                if (k == text_len - 1)
572:                                    endLine();
573:                                else {
574:                                    char ch1 = text.charAt(k + 1);
575:                                    if (ch != ch1
576:                                            && (ch1 == '\r' || ch1 == '\n'))
577:                                        k++;
578:                                    if (k == text_len - 1)
579:                                        endLine();
580:                                    else
581:                                        newParagraph();
582:                                }
583:                            } else {
584:                                int idx = font.getIndex(ch);
585:                                int ch_adv = font.getAdvanceValue(idx);
586:                                if (k != text_len - 1)
587:                                    ch_adv += font.getKerning(ch, text
588:                                            .charAt(k + 1));
589:                                int adv = (ch_adv * height) / 1024;
590:                                adv += curItem.kerning;
591:                                line_width += adv;
592:                                word_width += adv;
593:                                if (line_width <= line_window) {
594:                                    curLine.add(ch, idx, adv);
595:                                } else {
596:                                    if (curLine.getSize() == 0) { // even one character does not fit
597:                                        // if even one character does not fit the window, then expand the window
598:                                        line_window = line_width;
599:                                        curLine.add(ch, idx, adv);
600:                                        alignLine();
601:                                        newLine(true);
602:                                        isNowWord = false;
603:                                    } else if (isNowWord) {
604:                                        if (word_width > line_window) {
605:                                            // split anyway, because the word does not fit the window at all
606:                                            line_width -= adv;
607:                                            k--;
608:                                            alignLine();
609:                                            newLine(true);
610:                                        } else {
611:                                            // rollback the word and send it to the next line
612:                                            line_width -= word_width;
613:                                            curLine.rollBack();
614:                                            k = start_word - 1;
615:                                            alignLine();
616:                                            newLine(true);
617:                                            isNowWord = false;
618:                                        }
619:                                    } else {
620:                                        line_width -= adv;
621:                                        k--;
622:                                        alignLine();
623:                                        newLine(true);
624:                                    }
625:                                }
626:                            }
627:                        }
628:
629:                        i++;
630:                        if (i >= items.size())
631:                            break;
632:                        curItem = (TextItem) items.elementAt(i);
633:                        if (curLine == null)
634:                            newParagraph();
635:                        else
636:                            curLine.newRecord();
637:                    }
638:                    alignLine();
639:                    endLine();
640:
641:                    y -= max_linesp;
642:                }
643:
644:                // optimize text
645:                optimize();
646:
647:                // calculate bounds
648:                int maxX = 0;
649:                for (int l = 0; l < lines.size(); l++) {
650:                    TextLine line = (TextLine) lines.elementAt(l);
651:                    int max = line.getWidth();
652:                    if (max > maxX)
653:                        maxX = max;
654:                }
655:
656:                // check what kind of behavior is expected: MMGen or JGen and
657:                //        create appropriate bounds
658:                int bs = myText.getBoundsStyle();
659:                boolean isMMStyle = bs == Text.PROPERTY_CONTROLLED ? PropertyManager.textMMStyle
660:                        : bs == Text.MM_STYLE;
661:                if (isMMStyle) {
662:                    // set bounds to be exactly equal to the text (MMGen style)
663:                    bounds
664:                            .setFrame(bounds.getMinX(), bounds.getMinY(), maxX,
665:                                    y);
666:                } else {
667:                    // set bounds to be equal whatever came from the template (JGen style)
668:                    double width = bounds.getWidth();
669:                    double height = bounds.getHeight();
670:                    if (maxX > width)
671:                        width = maxX;
672:                    if (y > height)
673:                        height = y;
674:                    bounds.setFrame(bounds.getMinX(), bounds.getMinY(), width,
675:                            height);
676:                }
677:
678:                myText.setBounds(bounds);
679:            }
680:
681:            protected int getNGlyphBits() {
682:                int maxIdx = 0;
683:                for (int l = 0; l < lines.size(); l++) {
684:                    TextLine line = (TextLine) lines.elementAt(l);
685:                    int max = line.getMaxIndex();
686:                    if (max > maxIdx)
687:                        maxIdx = max;
688:                }
689:
690:                return Util.getMinBitsU(maxIdx);
691:            }
692:
693:            protected int getNAdvanceBits() {
694:                int maxAdv = 0;
695:                for (int l = 0; l < lines.size(); l++) {
696:                    TextLine line = (TextLine) lines.elementAt(l);
697:                    int max = Math.abs(line.getMaxAdvance());
698:                    if (max > maxAdv)
699:                        maxAdv = max;
700:                }
701:
702:                return Util.getMinBitsS(maxAdv);
703:            }
704:
705:            /**
706:             * Removes unneccesary data from stylechangerecords
707:             */
708:            public void optimize() {
709:                Font lastFont = null;
710:                int lastHeight = -1;
711:                Color lastColor = null;
712:
713:                for (int k = 0; k < lines.size(); k++) {
714:                    TextLine line = (TextLine) lines.elementAt(k);
715:                    IVVector records = line.records;
716:                    for (int i = 0; i < records.size(); i += 2) {
717:                        TextStyleChangeRecord ts = (TextStyleChangeRecord) records
718:                                .elementAt(i);
719:                        if (lastFont != null && lastFont == ts.getFont()) {
720:                            if (lastHeight == ts.getHeight()) {
721:                                ts.setFont(null);
722:                            } else {
723:                                lastHeight = ts.getHeight();
724:                            }
725:                        } else {
726:                            lastFont = ts.getFont();
727:                            lastHeight = ts.getHeight();
728:                        }
729:                        if (lastColor != null
730:                                && lastColor.equals(ts.getColor())) {
731:                            ts.setColor(null);
732:                        } else {
733:                            lastColor = ts.getColor();
734:                        }
735:                    }
736:                }
737:            }
738:
739:            public void write(FlashOutput fob) {
740:                int nGlyphBits = getNGlyphBits();
741:                int nAdvanceBits = getNAdvanceBits();
742:                fob.writeByte(nGlyphBits);
743:                fob.writeByte(nAdvanceBits);
744:                //System.out.println("Layout write: nGlyphBits="+nGlyphBits+", nAdvanceBits="+nAdvanceBits);
745:                fob.setUserData(new int[] { nGlyphBits, nAdvanceBits });
746:
747:                for (int i = 0; i < lines.size(); i++) {
748:                    TextLine line = (TextLine) lines.elementAt(i);
749:                    line.write(fob);
750:                    //line.printContent(System.out, "Layout Write: ");
751:                }
752:                fob.writeByte(0);
753:            }
754:
755:            public TextLayout getCopy(ScriptCopier copier) {
756:                TextLayout tl = new TextLayout(myText, bounds);
757:                tl.lines = lines.getCopy(copier);
758:                return tl;
759:            }
760:
761:            private static boolean isWord(char ch) {
762:                //Text Flow by FX
763:                //Wrap words at whitespace and '-' only!
764:
765:                if (ch == '-')
766:                    return false;
767:
768:                return !Character.isWhitespace(ch);
769:            }
770:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.