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


001:        /******************************************************************************
002:         * TTF2FFT.java
003:         * ****************************************************************************/package org.openlaszlo.media;
004:
005:        import java.io.InputStream;
006:        import java.io.FileInputStream;
007:        import java.io.IOException;
008:        import java.io.FileNotFoundException;
009:        import java.io.File;
010:        import java.awt.geom.Rectangle2D;
011:
012:        // JGenerator APIs
013:        import org.openlaszlo.iv.flash.api.*;
014:        import org.openlaszlo.iv.flash.api.shape.*;
015:        import org.openlaszlo.iv.flash.api.sound.*;
016:        import org.openlaszlo.iv.flash.api.text.Font;
017:        import org.openlaszlo.iv.flash.api.image.*;
018:        import org.openlaszlo.iv.flash.util.*;
019:
020:        import org.openlaszlo.server.LPS;
021:
022:        // Logger
023:        import org.apache.log4j.*;
024:
025:        // Apache Batik TrueType Font Parser
026:        import org.apache.batik.svggen.font.*;
027:        import org.apache.batik.svggen.font.table.*;
028:
029:        /**
030:         * TrueType Font to Flash Font converter
031:         *
032:         * @author <a href="mailto:bloch@laszlosystems.com">Eric Bloch</a>
033:         */
034:        public class TTF2FFT {
035:
036:            /** Character code used by lfc for newline processing 
037:             * See LzFont.as and LzFontManager.as.  0 doesn't work for some reason.
038:             */
039:            private final static int LFC_TMARK = 160;
040:
041:            /** Logger */
042:            private static Logger mLogger = Logger.getLogger(TTF2FFT.class);
043:
044:            /** Units per EmSquare for FFTs */
045:            private static final int FFT_UnitsPerEm = 1024;
046:
047:            /** 
048:             * @param input input TTF file
049:             * @return InputStream FFT
050:             */
051:            public static InputStream convert(File input)
052:                    throws TranscoderException, FileNotFoundException {
053:
054:                String path = input.getPath();
055:
056:                if (!input.exists()) {
057:                    throw new FileNotFoundException(path);
058:                }
059:
060:                // Batik should throw an exception when it can't read
061:                // the file (for access perms), but it doesn't.
062:                if (!input.canRead()) {
063:                    throw new FileNotFoundException(
064:                    /* (non-Javadoc)
065:                     * @i18n.test
066:                     * @org-mes="Can't read: " + p[0]
067:                     */
068:                    org.openlaszlo.i18n.LaszloMessages.getMessage(TTF2FFT.class
069:                            .getName(), "051018-75", new Object[] { path }));
070:                }
071:
072:                org.apache.batik.svggen.font.Font ttf;
073:                ttf = org.apache.batik.svggen.font.Font.create(input.getPath());
074:
075:                NameTable nameTable = ttf.getNameTable();
076:                String fontName = "";
077:                if (nameTable == null) {
078:                    fontName = input.getName();
079:                    int index = fontName.indexOf(".");
080:                    if (index > 0) {
081:                        fontName = fontName.substring(0, index);
082:                    }
083:                    mLogger
084:                            .warn(
085:                            /* (non-Javadoc)
086:                             * @i18n.test
087:                             * @org-mes="font missing ttf name table; made name, " + p[0] + ", based on filename "
088:                             */
089:                            org.openlaszlo.i18n.LaszloMessages.getMessage(
090:                                    TTF2FFT.class.getName(), "051018-96",
091:                                    new Object[] { fontName }));
092:                } else {
093:                    fontName = nameTable.getRecord((short) 1);
094:                }
095:                HeadTable headTable = ttf.getHeadTable();
096:                HmtxTable hmtxTable = ttf.getHmtxTable();
097:
098:                if (headTable == null) {
099:                    // Bitmap fonts aren't required to have the head table.
100:                    // We don't support them yet. XXX
101:                    throw new TranscoderException(
102:                    /* (non-Javadoc)
103:                     * @i18n.test
104:                     * @org-mes=p[0] + " missing ttf head table; this ttf font not supported"
105:                     */
106:                    org.openlaszlo.i18n.LaszloMessages.getMessage(TTF2FFT.class
107:                            .getName(), "051018-113", new Object[] { path }));
108:                }
109:
110:                if (hmtxTable == null) {
111:                    throw new TranscoderException(
112:                    /* (non-Javadoc)
113:                     * @i18n.test
114:                     * @org-mes=p[0] + " missing ttf hmtx (horiz. metrics) table; this ttf font not supported"
115:                     */
116:                    org.openlaszlo.i18n.LaszloMessages.getMessage(TTF2FFT.class
117:                            .getName(), "051018-124", new Object[] { path }));
118:                }
119:
120:                // FFT flags
121:                int flags = 0;
122:
123:                // Is font bold, italic, or bold-italic?
124:                int macStyle = headTable.getMacStyle();
125:                boolean isBold = (macStyle & 0x1) != 0;
126:                boolean isItalic = (macStyle & 0x2) != 0;
127:
128:                boolean isUnicode = false;
129:
130:                if (isBold)
131:                    flags |= org.openlaszlo.iv.flash.api.text.Font.BOLD;
132:                if (isItalic)
133:                    flags |= org.openlaszlo.iv.flash.api.text.Font.ITALIC;
134:
135:                // We have font metric info for the ttf
136:                flags |= org.openlaszlo.iv.flash.api.text.Font.HAS_LAYOUT;
137:
138:                final int maxCodes = 0xffff;
139:                int numCodes = 0;
140:
141:                int[] codeTable = new int[maxCodes];
142:                int[] indexTable = new int[maxCodes];
143:                int maxCode = 0;
144:
145:                // Add Code 0 (not sure why this is needed.  Probably some lfc reason
146:                codeTable[0] = 0;
147:                indexTable[0] = 0;
148:                numCodes = 1;
149:
150:                // 3 tries
151:                final int NUM_TRIES = 3;
152:                short[] cmapPlats = { Table.platformMicrosoft,
153:                        Table.platformMacintosh, Table.platformMicrosoft, };
154:
155:                short[] cmapEncodes = { Table.encodingUGL, Table.encodingRoman,
156:                        Table.encodingUndefined, };
157:
158:                boolean[] cmapIsUnicode = { true, false, false, };
159:
160:                int tries = 0;
161:
162:                CmapFormat cmapFmt = null;
163:                boolean hasTmark = false;
164:                int spaceIndex = 0;
165:
166:                for (int t = 0; t < NUM_TRIES; t++) {
167:
168:                    cmapFmt = ttf.getCmapTable().getCmapFormat(cmapPlats[t],
169:                            cmapEncodes[t]);
170:                    // Find char codes
171:                    if (cmapFmt != null) {
172:                        for (int ch = 0; ch < 0xffff; ch++) {
173:                            int index = cmapFmt.mapCharCode(ch);
174:
175:                            if (ch == 32) {
176:                                spaceIndex = index;
177:                            }
178:
179:                            if (index != 0) {
180:                                if (ch == LFC_TMARK) {
181:                                    hasTmark = true;
182:                                }
183:                                codeTable[numCodes] = ch;
184:                                indexTable[numCodes] = index;
185:                                numCodes++;
186:                                if (ch > maxCode) {
187:                                    maxCode = ch;
188:                                }
189:                            }
190:                        }
191:                    }
192:                    if (numCodes > 1) {
193:                        break;
194:                    }
195:                    isUnicode = cmapIsUnicode[t];
196:                }
197:
198:                if (cmapFmt == null) {
199:                    throw new TranscoderException(
200:                    /* (non-Javadoc)
201:                     * @i18n.test
202:                     * @org-mes="Can't find a cmap table in " + p[0]
203:                     */
204:                    org.openlaszlo.i18n.LaszloMessages.getMessage(TTF2FFT.class
205:                            .getName(), "051018-224", new Object[] { path }));
206:                }
207:
208:                if (!hasTmark) {
209:                    if (LFC_TMARK > maxCode) {
210:                        maxCode = LFC_TMARK;
211:                    }
212:
213:                    codeTable[numCodes] = LFC_TMARK;
214:                    indexTable[numCodes] = spaceIndex;
215:                    numCodes++;
216:                }
217:
218:                if (isUnicode)
219:                    flags |= org.openlaszlo.iv.flash.api.text.Font.UNICODE;
220:                else
221:                    flags |= org.openlaszlo.iv.flash.api.text.Font.ANSI;
222:
223:                boolean useWideCodes = (maxCode > 255);
224:                if (useWideCodes)
225:                    flags |= org.openlaszlo.iv.flash.api.text.Font.WIDE_CODES;
226:
227:                GlyfTable glyfTable = (GlyfTable) ttf
228:                        .getTable(org.apache.batik.svggen.font.table.Table.glyf);
229:
230:                //int              numGlyphs = ttf.getNumGlyphs();
231:                int numGlyphs = numCodes;
232:                Shape[] shapeTable = new Shape[numGlyphs];
233:                Rectangle2D[] boundsTable = new Rectangle2D[numGlyphs];
234:
235:                int unitsPerEm = headTable.getUnitsPerEm();
236:                double factor = (double) FFT_UnitsPerEm / (double) unitsPerEm;
237:
238:                // Get glyph shapes, and bounds.
239:                for (int i = 0; i < numGlyphs; i++) {
240:                    int index = indexTable[i];
241:                    int code = codeTable[i];
242:                    GlyfDescript glyf = glyfTable.getDescription(index);
243:                    TTFGlyph glyph = null;
244:
245:                    if (glyf != null) {
246:                        glyph = new TTFGlyph(glyf);
247:                        glyph.scale(factor);
248:                        mLogger.debug(
249:                        /* (non-Javadoc)
250:                         * @i18n.test
251:                         * @org-mes="index: " + p[0] + " charcode: " + p[1] + " char: " + p[2] + " numPoints: " + p[3]
252:                         */
253:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
254:                                TTF2FFT.class.getName(), "051018-274",
255:                                new Object[] { new Integer(index),
256:                                        new Integer(code),
257:                                        new Character((char) code),
258:                                        new Integer(glyph.getNumPoints()) }));
259:                    } else {
260:                        mLogger.debug(
261:                        /* (non-Javadoc)
262:                         * @i18n.test
263:                         * @org-mes="index: " + p[0] + " charcode: " + p[1] + " has no glyph."
264:                         */
265:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
266:                                TTF2FFT.class.getName(), "051018-283",
267:                                new Object[] { new Integer(index),
268:                                        new Integer(code) }));
269:                    }
270:
271:                    Shape shape = new Shape();
272:                    shape.newStyleBlock();
273:                    convertGlyphToShape(glyph, shape);
274:                    shapeTable[i] = shape;
275:
276:                    int x, w, y, h;
277:
278:                    if (glyf != null) {
279:                        x = (int) Math.round(glyf.getXMinimum() * factor);
280:                        y = (int) Math.round(glyf.getYMaximum() * -factor);
281:                        w = (int) Math.round((glyf.getXMaximum() - glyf
282:                                .getXMinimum())
283:                                * factor);
284:                        h = (int) Math.round((glyf.getYMaximum() - glyf
285:                                .getYMinimum())
286:                                * factor);
287:                    } else {
288:                        // Heuristic that hopefully works out ok for
289:                        // missing glyfs.  First try space.  Then try index0
290:                        glyf = glyfTable.getDescription(spaceIndex);
291:                        if (glyf == null) {
292:                            glyf = glyfTable.getDescription(0);
293:                        }
294:                        if (glyf != null) {
295:                            w = (int) Math.round((glyf.getXMaximum() - glyf
296:                                    .getXMinimum())
297:                                    * factor);
298:                        } else {
299:                            w = 0;
300:                        }
301:                        x = y = h = 0;
302:                    }
303:                    boundsTable[i] = new Rectangle2D.Double(x, y, w, h);
304:                    shape.setBounds(boundsTable[i]);
305:                }
306:
307:                // Create a 40K buffer for generating the FFT
308:                FlashOutput buf = new FlashOutput(40 * 1024);
309:
310:                // write header.
311:                final int TWIP = 20;
312:
313:                buf.writeByte('F');
314:                buf.writeByte('W');
315:                buf.writeByte('S');
316:                // write version
317:                buf.writeByte(5);
318:                // skip file size
319:                buf.skip(4);
320:                // write rect
321:                buf.write(new Rectangle2D.Double(0, 0, 5 * TWIP, 5 * TWIP));
322:                // write frame rate
323:                buf.writeWord(10 << 8);
324:
325:                // Frame count
326:                buf.writeWord(0);
327:
328:                // Remember position
329:                int tagPos = buf.getPos();
330:
331:                // Skip definefont2 tag header
332:                buf.skip(6);
333:
334:                // Write font id
335:                buf.writeWord(1);
336:
337:                // Skip flags
338:                int flagsPos = buf.getPos();
339:                buf.skip(2);
340:
341:                // Write font name
342:                buf.writeStringL(fontName);
343:
344:                // Write number of glyphs
345:                buf.writeWord(numGlyphs);
346:
347:                int[] offsetTable = new int[numGlyphs];
348:
349:                // Write out the converted shapes into a temporary buffer
350:                // And remember their offsets
351:                FlashOutput glyphBuf = new FlashOutput(20 * 1024);
352:                for (int i = 0; i < numGlyphs; i++) {
353:
354:                    offsetTable[i] = glyphBuf.getPos();
355:
356:                    mLogger.debug("Writing shape " + i);
357:                    // 1 bit of line and fill
358:                    glyphBuf.writeByte(0x11);
359:
360:                    ShapeRecords shapeRecords = shapeTable[i].getShapeRecords();
361:                    shapeRecords.write(glyphBuf, 1, 1);
362:                    // Write end of shape records
363:                    glyphBuf.writeBits(0, 6);
364:                    glyphBuf.flushBits();
365:                }
366:
367:                // UseWideOffset if glyph buf + offset table + codeTable offset
368:                // is bigger than 16bit int
369:                boolean useWideOffsets = glyphBuf.getSize() + (numGlyphs + 1)
370:                        * 2 > 0xffff;
371:
372:                // Write offsets and codeTable offset
373:                if (useWideOffsets) {
374:                    int offset = (numGlyphs + 1) * 4;
375:                    flags |= org.openlaszlo.iv.flash.api.text.Font.WIDE_OFFSETS;
376:                    for (int i = 0; i < numGlyphs; i++) {
377:                        buf.writeDWord(offsetTable[i] + offset);
378:                    }
379:                    buf.writeDWord(glyphBuf.getSize() + offset);
380:                } else {
381:                    int offset = (numGlyphs + 1) * 2;
382:                    for (int i = 0; i < numGlyphs; i++) {
383:                        buf.writeWord(offsetTable[i] + offset);
384:                    }
385:                    buf.writeWord(glyphBuf.getSize() + offset);
386:                }
387:
388:                // Write shapes
389:                buf.writeFOB(glyphBuf);
390:
391:                // Write out char code table. (glyph index to char code)
392:                for (int i = 0; i < numCodes; i++) {
393:                    if (useWideCodes) {
394:                        buf.writeWord(codeTable[i]);
395:                    } else {
396:                        buf.writeByte(codeTable[i]);
397:                    }
398:                }
399:
400:                // Write ascent, descent, (external) leading
401:                int ascent = (int) Math.round((ttf.getAscent() * factor));
402:                int descent = (int) Math.round((ttf.getDescent() * -factor));
403:                int leading = ascent + descent - FFT_UnitsPerEm;
404:                mLogger.debug(
405:                /* (non-Javadoc)
406:                 * @i18n.test
407:                 * @org-mes="Font metrics: " + p[0] + " " + p[1] + " " + p[2]
408:                 */
409:                org.openlaszlo.i18n.LaszloMessages.getMessage(TTF2FFT.class
410:                        .getName(), "051018-421", new Object[] {
411:                        new Integer(ascent), new Integer(descent),
412:                        new Integer(leading) }));
413:
414:                buf.writeWord(ascent);
415:                buf.writeWord(descent);
416:                buf.writeWord(leading);
417:
418:                // Write advance table 
419:                for (int i = 0; i < numCodes; i++) {
420:                    int index = indexTable[i];
421:                    buf.writeWord((int) Math.round(hmtxTable
422:                            .getAdvanceWidth(index)
423:                            * factor));
424:                }
425:
426:                // Write bounds table
427:                for (int i = 0; i < numCodes; i++) {
428:                    buf.write(boundsTable[i]);
429:                }
430:
431:                // Write kerning tables 
432:                int nKern = 0;
433:
434:                KernTable kernTable = (KernTable) ttf.getTable(Table.kern);
435:                // TODO: [2003-11-05 bloch] this should be passed in as an argument and taken
436:                // from the font definition in the LZX file
437:                boolean doKern = LPS.getProperty("lps.font.kerning", "false")
438:                        .equals("true");
439:
440:                if (kernTable != null) {
441:                    if (doKern) {
442:                        KernSubtable kst = kernTable.getSubtable(0);
443:                        nKern = kst.getKerningPairCount();
444:                        mLogger.debug(
445:                        /* (non-Javadoc)
446:                         * @i18n.test
447:                         * @org-mes=p[0] + " kern pairs"
448:                         */
449:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
450:                                TTF2FFT.class.getName(), "051018-456",
451:                                new Object[] { new Integer(nKern) }));
452:                        // We optimize out all 0s
453:                        int goodKern = nKern;
454:                        for (int i = 0; i < nKern; i++) {
455:                            if (kst.getKerningPair(i).getValue() == 0) {
456:                                goodKern--;
457:                            }
458:                        }
459:                        buf.writeWord(goodKern);
460:                        mLogger.debug(
461:                        /* (non-Javadoc)
462:                         * @i18n.test
463:                         * @org-mes=p[0] + " non-zero kern pairs"
464:                         */
465:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
466:                                TTF2FFT.class.getName(), "051018-472",
467:                                new Object[] { new Integer(goodKern) }));
468:                        for (int i = 0; i < nKern; i++) {
469:                            KerningPair pair = kst.getKerningPair(i);
470:                            if (pair.getValue() != 0) {
471:                                if (useWideCodes) {
472:                                    buf.writeWord(codeTable[pair.getLeft()]);
473:                                    buf.writeWord(codeTable[pair.getRight()]);
474:                                } else {
475:                                    buf.writeByte(codeTable[pair.getLeft()]);
476:                                    buf.writeByte(codeTable[pair.getRight()]);
477:                                }
478:                                buf.writeWord((int) Math.round(pair.getValue()
479:                                        * factor));
480:                            }
481:                        }
482:                    } else {
483:                        mLogger.warn(
484:                        /* (non-Javadoc)
485:                         * @i18n.test
486:                         * @org-mes="skipping non-empty kerning table in " + p[0]
487:                         */
488:                        org.openlaszlo.i18n.LaszloMessages.getMessage(
489:                                TTF2FFT.class.getName(), "051018-494",
490:                                new Object[] { path }));
491:                    }
492:                } else {
493:                    buf.writeWord(0);
494:                }
495:
496:                // Write the DEFINEFONT2 tag
497:                int x = buf.getPos() - tagPos - 6;
498:                buf.writeLongTagAt(Tag.DEFINEFONT2, x, tagPos);
499:                // Write the flags
500:                buf.writeWordAt(flags, flagsPos);
501:
502:                // Write the END tag
503:                Tag.END_TAG.write(buf);
504:
505:                // Write the file size back at the beginning.
506:                int filesize = buf.getSize();
507:                buf.writeDWordAt(filesize, 4);
508:
509:                return buf.getInputStream();
510:            }
511:
512:            /**
513:             * Convert TTF Glyph to Flash Shape
514:             * @param glyph
515:             * @param shape
516:             */
517:            private static void convertGlyphToShape(TTFGlyph glyph, Shape shape) {
518:
519:                if (glyph == null) {
520:                    return;
521:                }
522:                int firstIndex = 0;
523:                int count = 0;
524:
525:                // Add each contour to the shape.
526:                for (int i = 0; i < glyph.getNumPoints(); i++) {
527:                    count++;
528:                    if (glyph.getPoint(i).endOfContour) {
529:                        addContourToShape(shape, glyph, firstIndex, count);
530:                        firstIndex = i + 1;
531:                        count = 0;
532:                    }
533:                }
534:            }
535:
536:            /**
537:             * Add glyphs contour starting from index point and going 
538:             * count number of points to shape.
539:             * @param shape
540:             * @param glyph
541:             * @param startIndex
542:             * @param count
543:             */
544:            private static void addContourToShape(Shape shape, TTFGlyph glyph,
545:                    int startIndex, int count) {
546:
547:                // If this is a single point on it's own, we can't do anything with it
548:                if (glyph.getPoint(startIndex).endOfContour) {
549:                    return;
550:                }
551:
552:                int offset = 0;
553:
554:                while (offset < count) {
555:                    Point p0 = glyph.getPoint(startIndex + offset % count);
556:                    Point p1 = glyph
557:                            .getPoint(startIndex + (offset + 1) % count);
558:
559:                    if (offset == 0) {
560:                        shape.movePenTo(p0.x, p0.y);
561:                        if (startIndex == 0) {
562:                            StyleChangeRecord scr = new StyleChangeRecord();
563:                            scr.setFlags(StyleChangeRecord.FILLSTYLE1
564:                                    | StyleChangeRecord.LINESTYLE);
565:                            scr.setFillStyle1(1);
566:                            scr.setLineStyle(0);
567:                            shape.getShapeRecords().addStyleChangeRecord(scr);
568:                        }
569:                    }
570:
571:                    if (p0.onCurve) {
572:                        if (p1.onCurve) {
573:                            shape.drawLineTo(p1.x, p1.y);
574:                            offset++;
575:                        } else {
576:                            Point p2;
577:                            p2 = glyph.getPoint(startIndex + (offset + 2)
578:                                    % count);
579:
580:                            if (p2.onCurve) {
581:                                shape.drawCurveTo(p1.x, p1.y, p2.x, p2.y);
582:                            } else {
583:                                shape.drawCurveTo(p1.x, p1.y, midValue(p1.x,
584:                                        p2.x), midValue(p1.y, p2.y));
585:                            }
586:                            offset += 2;
587:                        }
588:                    } else {
589:                        if (!p1.onCurve) {
590:                            shape.drawCurveTo(p0.x, p0.y, midValue(p0.x, p1.x),
591:                                    midValue(p0.y, p1.y));
592:                        } else {
593:                            shape.drawCurveTo(p0.x, p0.y, p1.x, p1.y);
594:                        }
595:                        offset++;
596:                    }
597:                }
598:            }
599:
600:            /**
601:             * @return midpoint of (a,b)
602:             * @param a
603:             * @param b
604:             */
605:            private static int midValue(int a, int b) {
606:                return (a + b) / 2;
607:            }
608:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.