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


001:        /*
002:         * $Id: FontDef.java,v 1.3 2002/02/24 02:10:19 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.api.text;
052:
053:        import org.openlaszlo.iv.flash.parser.Parser;
054:        import org.openlaszlo.iv.flash.util.*;
055:        import org.openlaszlo.iv.flash.cache.*;
056:
057:        import org.openlaszlo.iv.flash.api.*;
058:        import java.io.*;
059:        import java.awt.geom.Rectangle2D;
060:
061:        /**
062:         * Instance of Font in particular flash file.
063:         * <p>
064:         * There may be several instances of one font in one file.
065:         *
066:         * @author Dmitry Skavish
067:         */
068:        public final class FontDef extends FlashDef {
069:
070:            private boolean isWriteLayout = false; // if true - write font outlines as well
071:            private boolean isWriteAllChars = false; // if true - write full set of characters, otherwise only used ones
072:            private Font font; // font
073:            private IVVector textBlocks = new IVVector(); // vector of TextBlock's using this font
074:
075:            /**
076:             * Creates empty font definition
077:             */
078:            public FontDef() {
079:            }
080:
081:            /**
082:             * Creates font definition of specified font and ID
083:             *
084:             * @param font   specified font
085:             * @param id     ID of font definition to be created
086:             */
087:            public FontDef(Font font, int id) {
088:                this .font = font;
089:                setID(id);
090:            }
091:
092:            public int getTag() {
093:                return Tag.DEFINEFONT2;
094:            }
095:
096:            /**
097:             * Returns font name
098:             *
099:             * @return font name
100:             */
101:            public String getFontName() {
102:                return font.fontName;
103:            }
104:
105:            /**
106:             * Returns font
107:             *
108:             * @return font
109:             */
110:            public Font getFont() {
111:                return font;
112:            }
113:
114:            public void setFont(Font font) {
115:                this .font = font;
116:            }
117:
118:            /**
119:             * Adds specified text block to this fontdef
120:             *
121:             * @param tblock specified text block
122:             */
123:            public void addTextBlock(TextBlock tblock) {
124:                if (tblock == null)
125:                    return;
126:                textBlocks.addElement(tblock);
127:            }
128:
129:            /**
130:             * Adds vector of text blocks to this fontdef
131:             *
132:             * @param tblocks vector of text blocks
133:             */
134:            public void addTextBlocks(IVVector tblocks) {
135:                if (tblocks == null)
136:                    return;
137:                for (int i = 0; i < tblocks.size(); i++) {
138:                    addTextBlock((TextBlock) tblocks.elementAt(i));
139:                }
140:            }
141:
142:            /**
143:             * Returns all text blocks added to this fontdef
144:             *
145:             * @return all text blocks added to this fontdef
146:             */
147:            public IVVector getTextBlocks() {
148:                return textBlocks;
149:            }
150:
151:            /**
152:             * Specifies whether to write layout information when generating this font or not
153:             *
154:             * @param v      true - write layout
155:             */
156:            public void setWriteLayout(boolean v) {
157:                isWriteLayout = v;
158:            }
159:
160:            /**
161:             * Returns true if layout information is going to generated
162:             *
163:             * @return true if layout information is going to generated
164:             */
165:            public boolean isWriteLayout() {
166:                return isWriteLayout;
167:            }
168:
169:            /**
170:             * Specifies whether to write all font's character or only used (in text blocks) ones.
171:             *
172:             * @param v      true - write all characters
173:             */
174:            public void setWriteAllChars(boolean v) {
175:                isWriteAllChars = v;
176:            }
177:
178:            /**
179:             * Returns true if all font's character are going to be generated
180:             *
181:             * @return true if all font's character are going to be generated
182:             */
183:            public boolean isWriteAllChars() {
184:                return isWriteAllChars;
185:            }
186:
187:            /**
188:             * Parses External font tag
189:             */
190:            public static FontDef parseExternalFontTag(Parser p) {
191:                int id = p.getUWord();
192:                String fontFileName = p.getString();
193:                Font font = load(fontFileName, p.getFile());
194:                if (font != null)
195:                    return new FontDef(font, id);
196:                return null;
197:            }
198:
199:            /**
200:             * Loads external font to the specified file
201:             */
202:            public static Font load(String fontFileName, FlashFile file) {
203:                FlashFile fontFile;
204:                try {
205:                    fontFile = file.addExternalFile(fontFileName, true);
206:                } catch (IVException e) {
207:                    Log.log(e);
208:                    // load default symbol file and pick first font from it
209:                    fontFile = file.getDefaultSymbolFile();
210:                }
211:                if (fontFile != null) {
212:                    IVVector v = fontFile.getLocalFonts();
213:                    if (v.size() == 0) {
214:                        Log.logRB(Resource.INVLEXTERNALFONT,
215:                                new Object[] { fontFileName });
216:                        return null;
217:                    }
218:                    return (Font) v.elementAt(0);
219:                }
220:                return null;
221:            }
222:
223:            /**
224:             * Loads font from file (FFT)
225:             *
226:             * @param fontFileName font file name
227:             * @return loaded font
228:             */
229:            public static Font load(String fontFileName) {
230:                FlashFile fontFile;
231:
232:                // Find the font
233:                fontFileName = Util.translatePath(fontFileName);
234:                File f = new File(fontFileName);
235:                if (!f.exists()) {
236:                    fontFileName = Util.concatFileNames(
237:                            PropertyManager.fontPath, fontFileName);
238:                    f = new File(Util.getInstallDir(), fontFileName);
239:                    if (!f.exists()) {
240:                        Log.logRB(Resource.FILENOTFOUND,
241:                                new Object[] { fontFileName });
242:                        return null;
243:                    }
244:                }
245:                fontFileName = f.getAbsolutePath();
246:
247:                // Load the font
248:                try {
249:                    fontFile = FlashFile.parse(fontFileName);
250:                    IVVector v = fontFile.getLocalFonts();
251:                    if (v.size() == 0) {
252:                        Log.logRB(Resource.INVLEXTERNALFONT,
253:                                new Object[] { fontFileName });
254:                        return null;
255:                    }
256:                    return (Font) v.elementAt(0);
257:                } catch (FileNotFoundException e) {
258:                    Log.logRB(Resource.FILENOTFOUND,
259:                            new Object[] { fontFileName });
260:                    return null;
261:                } catch (IVException e) {
262:                    Log.log(e);
263:                    return null;
264:                }
265:            }
266:
267:            /**
268:             * Parses DefineFont tag.
269:             * <P>
270:             * We expect that after DefineFont tag, DefineFontInfo tag will follow
271:             * which will define codetable for this font.<br>
272:             * This is not always true of course, but in majority of cases it is.
273:             *
274:             * @param p      parser
275:             * @return font def
276:             */
277:            public static FontDef parse(Parser p) {
278:                // get id
279:                int id = p.getUWord();
280:                Font font = new Font();
281:                font.flags = Font.ANSI;
282:                font.fileBuffer = p.getBuf();
283:
284:                // get offset table and shape table
285:                int tableOffset = p.getPos();
286:                int offset = p.getUWord();
287:                int nGlyph = offset / 2;
288:
289:                int[] glyphOffsets = new int[nGlyph + 1]; // +1 because we need last offset
290:                glyphOffsets[0] = tableOffset + offset;
291:                for (int i = 1; i < nGlyph; i++)
292:                    glyphOffsets[i] = tableOffset + p.getUWord();
293:
294:                p.skipLastTag(); // skip all shapes
295:                glyphOffsets[nGlyph] = p.getPos();
296:
297:                font.glyphOffsets = glyphOffsets;
298:
299:                // there is no need to cache font, fontinfo will take care of it
300:                return new FontDef(font, id);
301:            }
302:
303:            /**
304:             * Parse  DefineFontInfo tag
305:             */
306:            public static void parseFontInfoTag(Parser p, boolean MX) {
307:                // get id
308:                int fontId = p.getUWord();
309:                FontDef fontDef = (FontDef) p.getDef(fontId);
310:                String fontName = p.getString(p.getUByte());
311:                int flags = (MX) ? p.getUWord() : p.getUByte();
312:                String ext = ((flags & 0x04) != 0 ? "%i" : "")
313:                        + ((flags & 0x02) != 0 ? "%b" : "");
314:                String fontKey = fontName + ext;
315:
316:                // do not put this font into cache
317:                // later on we will try to merge it into some probably existing in cache font
318:
319:                Font font = fontDef.font;
320:                font.fontName = fontName;
321:                font.fontKey = fontKey;
322:                font.flags = ((flags & 0x04) != 0 ? Font.ITALIC : 0)
323:                        | ((flags & 0x02) != 0 ? Font.BOLD : 0)
324:                        | ((flags & 0x20) != 0 ? Font.UNICODE : 0)
325:                        | ((flags & 0x10) != 0 ? Font.SHIFT_JIS : 0)
326:                        | ((flags & 0x08) != 0 ? Font.ANSI : 0)
327:                        | ((flags & 0x01) != 0 ? Font.WIDE_CODES : 0);
328:                //Log.logRB( Resource.STR, "parseInfo: font="+fontName+", font2="+font2+", flags="+Util.w2h(font.flags) );
329:                // get code table
330:                int nGlyph = font.getNumGlyph();
331:                int[] codeTable = new int[nGlyph];
332:                if ((font.flags & Font.WIDE_CODES) != 0) {
333:                    for (int i = 0; i < nGlyph; i++)
334:                        codeTable[i] = p.getUWord();
335:                } else {
336:                    for (int i = 0; i < nGlyph; i++)
337:                        codeTable[i] = p.getUByte();
338:                }
339:                font.codeTable = codeTable;
340:
341:                // find 'blank'
342:                for (int i = 0; i < nGlyph; i++) {
343:                    if (codeTable[i] == ' ') {
344:                        font.blankPos = i;
345:                        break;
346:                    }
347:                }
348:            }
349:
350:            /**
351:             * Parse  DefineFontInfo tag
352:             */
353:            public static void parseFontInfoTag(Parser p) {
354:                parseFontInfoTag(p, false);
355:            }
356:
357:            /**
358:             * Parse  DefineFontInfo2 tag
359:             */
360:            public static void parseFontInfoTag2(Parser p) {
361:                parseFontInfoTag(p, true);
362:            }
363:
364:            /**
365:             * Parse  DefineFont2 tag
366:             */
367:            public static FontDef parse2(Parser p) {
368:                // get id
369:                int id = p.getUWord();
370:                // get flags
371:                int flags = p.getUWord();
372:                // get name of the font
373:                String fontName = p.getString(p.getUByte());
374:
375:                // check if this font is in cache
376:                String ext = ((flags & Font.ITALIC) != 0 ? "%i" : "")
377:                        + ((flags & Font.BOLD) != 0 ? "%b" : "");
378:                String fontKey = fontName + ext;
379:                /* NOTE LASZLO: [2003-09-22 bloch] disable font cache (see bug 2109) */
380:                /*
381:                Font font2 = FontCache.getFont( fontKey );
382:                 */
383:                Font font2 = null;
384:
385:                // get offset table and shape table
386:                int nGlyph = p.getUWord();
387:
388:                // if these fonts have the same number of glyphs and the same flags then
389:                // we guess that this is the same font and don't parse it further
390:                // (we may be wrong, but it's very unlikely)
391:                if (font2 != null) {
392:                    if (nGlyph == font2.getNumGlyph() && flags == font2.flags) {
393:                        return new FontDef(font2, id);
394:                    }
395:                }
396:
397:                Font font = new Font();
398:                font.flags = flags;
399:                font.fontName = fontName;
400:                font.fontKey = fontKey;
401:                font.fileBuffer = p.getBuf();
402:                int tableOffset = p.getPos();
403:                int[] glyphOffsets = new int[nGlyph + 1]; // +1 because we need last offset
404:                int codeOff;
405:                if ((flags & Font.WIDE_OFFSETS) != 0) {
406:                    for (int i = 0; i < nGlyph; i++)
407:                        glyphOffsets[i] = tableOffset + p.getUDWord();
408:                    codeOff = p.getUDWord();
409:                } else {
410:                    for (int i = 0; i < nGlyph; i++)
411:                        glyphOffsets[i] = tableOffset + p.getUWord();
412:                    codeOff = p.getUWord();
413:                }
414:                font.glyphOffsets = glyphOffsets;
415:
416:                // do not parse shapes, delay until we really need them
417:                p.setPos(tableOffset + codeOff); // skip shapes
418:                glyphOffsets[nGlyph] = p.getPos();
419:
420:                // get code table
421:                int[] codeTable = new int[nGlyph];
422:                if ((flags & Font.WIDE_CODES) != 0) {
423:                    for (int i = 0; i < nGlyph; i++)
424:                        codeTable[i] = p.getUWord();
425:                } else {
426:                    for (int i = 0; i < nGlyph; i++)
427:                        codeTable[i] = p.getUByte();
428:                }
429:                font.codeTable = codeTable;
430:
431:                // find 'blank'
432:                for (int i = 0; i < nGlyph; i++) {
433:                    if (codeTable[i] == ' ') {
434:                        font.blankPos = i;
435:                        break;
436:                    }
437:                }
438:
439:                if ((flags & Font.HAS_LAYOUT) != 0) {
440:                    font.ascent = p.getWord();
441:                    font.descent = p.getWord();
442:                    font.leading = p.getWord();
443:
444:                    // get advance table
445:                    int[] advanceTable = new int[nGlyph];
446:                    for (int i = 0; i < nGlyph; i++)
447:                        advanceTable[i] = p.getWord();
448:                    font.advanceTable = advanceTable;
449:
450:                    // skip bounds table, delay until we need them
451:                    font.boundsBuffer = p.getBuf();
452:                    font.boundsOffset = p.getPos();
453:                    for (int i = 0; i < nGlyph; i++)
454:                        p.skipRect();
455:                    font.boundsLength = p.getPos() - font.boundsOffset;
456:
457:                    // get kerning table
458:                    int nKern = p.getUWord();
459:                    font.kernLeftCodes = new int[nKern];
460:                    font.kernRightCodes = new int[nKern];
461:                    font.kernAdjustment = new int[nKern];
462:                    if ((flags & Font.WIDE_CODES) != 0) {
463:                        for (int i = 0; i < nKern; i++) {
464:                            font.kernLeftCodes[i] = p.getUWord();
465:                            font.kernRightCodes[i] = p.getUWord();
466:                            font.kernAdjustment[i] = p.getWord();
467:                        }
468:                    } else {
469:                        for (int i = 0; i < nKern; i++) {
470:                            font.kernLeftCodes[i] = p.getUByte();
471:                            font.kernRightCodes[i] = p.getUByte();
472:                            font.kernAdjustment[i] = p.getWord();
473:                        }
474:                    }
475:                }
476:
477:                // cache only if there is no already such font in cache, font has a layout and number of
478:                // glyphs >= 200
479:                /* NOTE LASZLO: [2003-09-22 bloch] disable font cache (see bug 2109) */
480:                /*
481:                if( font2 == null && (flags&Font.HAS_LAYOUT) != 0 && nGlyph >= 200 ) {
482:                    FontCache.addFont( fontKey, font );
483:                }
484:                 */
485:
486:                return new FontDef(font, id);
487:            }
488:
489:            /**
490:             * Builds and generates this font into buffer
491:             *
492:             * @param fob    flash buffer
493:             */
494:            public void write(FlashOutput fob) {
495:
496:                if (fob.defined(font)) {
497:                    return;
498:                }
499:
500:                int pos = fob.getPos();
501:                fob.skip(6);
502:
503:                fob.writeFontID(font);
504:                if (isWriteLayout) {
505:                    fob.writeWord(font.flags);
506:                } else {
507:                    fob.writeWord(font.flags & ~Font.HAS_LAYOUT);
508:                }
509:                fob.writeStringL(getFontName());
510:
511:                // create index table
512:                int[] indexTable = new int[font.codeTable.length];
513:
514:                // create codetable from registered text blocks
515:                int[] codeTable;
516:                int nGlyph;
517:                if (isWriteAllChars) {
518:                    codeTable = font.codeTable;
519:                    nGlyph = codeTable.length;
520:                    for (int i = 0; i < indexTable.length; i++)
521:                        indexTable[i] = i;
522:                } else {
523:                    codeTable = new int[font.codeTable.length];
524:                    nGlyph = 0;
525:                }
526:
527:                for (int i = 0; i < textBlocks.size(); i++) {
528:                    TextBlock tblock = (TextBlock) textBlocks.elementAt(i);
529:                    tblock.layout();
530:                    IVVector trs = tblock.getTextRecords(font);
531:                    if (trs == null || trs.size() == 0)
532:                        continue;
533:                    for (int t = 0; t < trs.size(); t++) {
534:                        TextRecord tr = (TextRecord) trs.elementAt(t);
535:                        L1: for (int c = 0; c < tr.getSize(); c++) {
536:                            char ch = tr.getChar(c);
537:                            if (ch == '\r' || ch == '\n') { // how come we see this chars here ?
538:                                tr.setIndex(c, 0); // ???
539:                                continue;
540:                            }
541:                            // find this char in our codetable
542:                            for (int j = 0; j < nGlyph; j++) {
543:                                if (codeTable[j] == ch) {
544:                                    tr.setIndex(c, j);
545:                                    continue L1;
546:                                }
547:                            }
548:                            // char has not been not found, add it
549:                            if (!isWriteAllChars) { // should always be true here!
550:                                int idx = font.getIndex(ch); // get original index
551:                                if (idx == -1) {
552:                                    idx = font.getIndex(' ');
553:                                }
554:                                indexTable[nGlyph] = idx;
555:                                tr.setIndex(c, nGlyph);
556:                                codeTable[nGlyph] = ch;
557:                                ++nGlyph;
558:                            }
559:                        }
560:                    }
561:                }
562:
563:                fob.writeWord(nGlyph);
564:                int offsetTable = fob.getPos();
565:                int inc = (font.flags & Font.WIDE_OFFSETS) != 0 ? 4 : 2;
566:                fob.skip(nGlyph * inc);
567:                int codeOffset = fob.getPos();
568:                fob.skip(inc);
569:                for (int i = 0, curOff = offsetTable; i < nGlyph; i++, curOff += inc) {
570:                    int offset = fob.getPos() - offsetTable;
571:                    int idx = indexTable[i];
572:                    int start = font.glyphOffsets[idx];
573:                    int end = font.glyphOffsets[idx + 1];
574:                    fob.writeArray(font.fileBuffer, start, end - start);
575:                    if (inc == 2)
576:                        fob.writeWordAt(offset, curOff);
577:                    else
578:                        fob.writeDWordAt(offset, curOff);
579:                }
580:                if (inc == 2)
581:                    fob.writeWordAt(fob.getPos() - offsetTable, codeOffset);
582:                else
583:                    fob.writeDWordAt(fob.getPos() - offsetTable, codeOffset);
584:
585:                for (int i = 0; i < nGlyph; i++) {
586:                    if ((font.flags & Font.WIDE_CODES) != 0) {
587:                        fob.writeWord(codeTable[i]);
588:                    } else {
589:                        fob.writeByte(codeTable[i]);
590:                    }
591:                }
592:
593:                // write layout
594:                if (isWriteLayout && ((font.flags & Font.HAS_LAYOUT) != 0)) {
595:                    fob.writeWord(font.ascent);
596:                    fob.writeWord(font.descent);
597:                    fob.writeWord(font.leading);
598:
599:                    // write advance table
600:                    for (int i = 0; i < nGlyph; i++)
601:                        fob.writeWord(font.advanceTable[indexTable[i]]);
602:
603:                    // copy bounds table
604:                    if (isWriteAllChars) {
605:                        // just for the sake of perfomance, because font.getGlyphBounds() causes parsing of all bounds
606:                        fob.writeArray(font.boundsBuffer, font.boundsOffset,
607:                                font.boundsLength);
608:                    } else {
609:                        Rectangle2D[] bounds = font.getGlyphBounds();
610:                        for (int i = 0; i < nGlyph; i++) {
611:                            fob.write(bounds[indexTable[i]]);
612:                        }
613:                    }
614:
615:                    // write kerning tables
616:                    // probably we need to restrict writing only to codes from codetable
617:                    int nKern = font.kernLeftCodes.length;
618:                    fob.writeWord(nKern);
619:                    if ((font.flags & Font.WIDE_CODES) != 0) {
620:                        for (int i = 0; i < nKern; i++) {
621:                            fob.writeWord(font.kernLeftCodes[i]);
622:                            fob.writeWord(font.kernRightCodes[i]);
623:                            fob.writeWord(font.kernAdjustment[i]);
624:                        }
625:                    } else {
626:                        for (int i = 0; i < nKern; i++) {
627:                            fob.writeByte(font.kernLeftCodes[i]);
628:                            fob.writeByte(font.kernRightCodes[i]);
629:                            fob.writeWord(font.kernAdjustment[i]);
630:                        }
631:                    }
632:                }
633:
634:                fob
635:                        .writeLongTagAt(Tag.DEFINEFONT2,
636:                                fob.getPos() - pos - 6, pos);
637:            }
638:
639:            /**
640:             * Merge two fonts
641:             *
642:             * @param f1     font to merge
643:             * @param f2     font to merge
644:             * @return new merged font
645:             */
646:            public static Font mergeFonts(Font f1, Font f2) {
647:                //System.out.println( "Merging fonts: "+f2.getFontName() );
648:                int flags = f2.flags | f1.flags;
649:                //System.out.println( "f2_flags: "+Util.w2h(f2.flags)+", f1_flags: "+Util.w2h(f2.flags) );
650:
651:                boolean f1_hasLayout = (f1.flags & Font.HAS_LAYOUT) != 0;
652:                boolean f2_hasLayout = (f2.flags & Font.HAS_LAYOUT) != 0;
653:                if (f1_hasLayout && !f2_hasLayout) {
654:                    Font f = f1;
655:                    f1 = f2;
656:                    f2 = f;
657:                    boolean fb = f1_hasLayout;
658:                    f1_hasLayout = f2_hasLayout;
659:                    f2_hasLayout = fb;
660:                }
661:
662:                // merge code tables
663:                int[] codeTable1 = f1.codeTable;
664:                int[] codeTable2 = f2.codeTable;
665:                int n = 0;
666:                int[] codeTable_tmp = new int[codeTable1.length];
667:                int[] indexes = new int[codeTable1.length];
668:                for (int i = 0; i < codeTable1.length; i++) {
669:                    int code = codeTable1[i];
670:                    int j = 0;
671:                    for (; j < codeTable2.length; j++) {
672:                        if (codeTable2[j] == code)
673:                            break;
674:                    }
675:                    if (j == codeTable2.length) {
676:                        codeTable_tmp[n] = code;
677:                        indexes[n] = i;
678:                        n++;
679:                    }
680:                }
681:
682:                if (n == 0) { // no new characters in f1
683:                    f2.copyTo(f1); // no need!!!
684:                    return f2;
685:                }
686:                //System.out.println( "continue merge" );
687:
688:                int nGlyph = codeTable2.length + n;
689:                int[] codeTable = new int[nGlyph];
690:                System
691:                        .arraycopy(codeTable2, 0, codeTable, 0,
692:                                codeTable2.length);
693:                System.arraycopy(codeTable_tmp, 0, codeTable,
694:                        codeTable2.length, n);
695:
696:                // merge glyphs
697:                int f1_start = f1.glyphOffsets[0];
698:                int f1_end = f1.glyphOffsets[codeTable1.length];
699:                int f2_start = f2.glyphOffsets[0];
700:                int f2_end = f2.glyphOffsets[codeTable2.length];
701:                int totalSize = f1_end - f1_start + f2_end - f2_start;
702:                byte[] fileBuffer = new byte[totalSize];
703:                int[] glyphOffsets = new int[nGlyph + 1];
704:                int offset = f2_end - f2_start;
705:                // copy glyphoffset and shapes from f2
706:                System
707:                        .arraycopy(f2.fileBuffer, f2_start, fileBuffer, 0,
708:                                offset);
709:                int gln = 0;
710:                for (; gln < codeTable2.length; gln++) {
711:                    int off = f2.glyphOffsets[gln] - f2_start;
712:                    glyphOffsets[gln] = off;
713:                }
714:                // copy glyphoffsets and shapes from f1
715:                for (int i = 0; i < n; i++, gln++) {
716:                    int idx = indexes[i];
717:                    int start = f1.glyphOffsets[idx];
718:                    int end = f1.glyphOffsets[idx + 1];
719:                    int size = end - start;
720:                    System.arraycopy(f1.fileBuffer, start, fileBuffer, offset,
721:                            size);
722:                    glyphOffsets[gln] = offset;
723:                    offset += size;
724:                }
725:                glyphOffsets[gln] = offset;
726:
727:                int[] advanceTable = null;
728:                int[] kernLeftCodes = f2.kernLeftCodes;
729:                int[] kernRightCodes = f2.kernRightCodes;
730:                int[] kernAdjustment = f2.kernAdjustment;
731:                // 2 cases:
732:                //  - no fonts have layouts
733:                //  - at least f2 has layout
734:                if (f1_hasLayout || f2_hasLayout) {
735:                    if (f1_hasLayout) {
736:                        // merge two layouts
737:                        // extend advancetable and boundstable
738:                        advanceTable = new int[nGlyph];
739:                        int off = codeTable2.length;
740:                        System.arraycopy(f2.advanceTable, 0, advanceTable, 0,
741:                                off);
742:                        for (int i = 0; i < n; i++, off++) {
743:                            int idx = indexes[i];
744:                            int adv = f1.advanceTable[idx];
745:                            advanceTable[off] = adv;
746:                        }
747:                    } else {
748:                        // use f2 layout
749:                        // extend advancetable and boundstable
750:                        advanceTable = new int[nGlyph];
751:                        System.arraycopy(f2.advanceTable, 0, advanceTable, 0,
752:                                codeTable2.length);
753:                        for (int i = codeTable2.length; i < nGlyph; i++) {
754:                            advanceTable[i] = 500;
755:                        }
756:                    }
757:                }
758:
759:                synchronized (f2) {
760:                    // store new data to f2 font
761:                    for (int i = 0; i < nGlyph; i++) {
762:                        if (codeTable[i] == ' ') {
763:                            f2.blankPos = i;
764:                            break;
765:                        }
766:                    }
767:                    f2.kernAdjustment = kernAdjustment;
768:                    f2.kernLeftCodes = kernLeftCodes;
769:                    f2.kernRightCodes = kernRightCodes;
770:                    f2.advanceTable = advanceTable;
771:                    f2.flags = flags;
772:                    f2.codeTable = codeTable;
773:                    f2.glyphOffsets = glyphOffsets;
774:                    f2.fileBuffer = fileBuffer;
775:
776:                    // need to copy bounds buffer too !!!
777:                    // .....
778:                    // ....
779:
780:                    f2.copyTo(f1); // no need !!!
781:                }
782:
783:                return f2;
784:            }
785:
786:            public void printContent(PrintStream out, String indent) {
787:                font.printContent(out, indent, getID());
788:            }
789:
790:            public boolean isConstant() {
791:                return true;
792:            }
793:
794:            protected FlashItem copyInto(FlashItem item, ScriptCopier copier) {
795:                super .copyInto(item, copier);
796:                ((FontDef) item).font = font;
797:                ((FontDef) item).isWriteAllChars = isWriteAllChars;
798:                ((FontDef) item).isWriteLayout = isWriteLayout;
799:                // nothing else
800:                return item;
801:            }
802:
803:            public FlashItem getCopy(ScriptCopier copier) {
804:                return copyInto(new FontDef(), copier);
805:            }
806:
807:            /**
808:             * Change font in all specified records to new one
809:             *
810:             * @param records  vector containing TextRecord and TextStyleChangeRecord
811:             * @param new_font new font
812:             */
813:            public static void changeRecordsFont(IVVector records,
814:                    Font old_font, Font new_font) {
815:                //System.out.println( "changeRecordsFont:" );
816:                Font last_font = null;
817:                for (int i = 0; i < records.size(); i++) {
818:                    Object o = records.elementAt(i);
819:                    if (o instanceof  TextRecord) {
820:                        if (last_font == old_font) {
821:                            ((TextRecord) o).updateIndexes(new_font);
822:                        }
823:                    } else {
824:                        TextStyleChangeRecord trs = (TextStyleChangeRecord) o;
825:                        Font font = trs.getFont();
826:                        if (font != null) {
827:                            last_font = font;
828:                            if (last_font == old_font) {
829:                                trs.setFont(new_font);
830:                            }
831:                        }
832:                    }
833:                }
834:            }
835:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.