Source Code Cross Referenced for PDFontTrueType.java in  » PDF » jPod » de » intarsys » pdf » font » 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 » PDF » jPod » de.intarsys.pdf.font 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2007, intarsys consulting GmbH
003:         *
004:         * Redistribution and use in source and binary forms, with or without
005:         * modification, are permitted provided that the following conditions are met:
006:         *
007:         * - Redistributions of source code must retain the above copyright notice,
008:         *   this list of conditions and the following disclaimer.
009:         *
010:         * - Redistributions in binary form must reproduce the above copyright notice,
011:         *   this list of conditions and the following disclaimer in the documentation
012:         *   and/or other materials provided with the distribution.
013:         *
014:         * - Neither the name of intarsys nor the names of its contributors may be used
015:         *   to endorse or promote products derived from this software without specific
016:         *   prior written permission.
017:         *
018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028:         * POSSIBILITY OF SUCH DAMAGE.
029:         */
030:        package de.intarsys.pdf.font;
031:
032:        import java.io.ByteArrayOutputStream;
033:        import java.io.FileOutputStream;
034:        import java.io.IOException;
035:        import java.util.HashSet;
036:        import java.util.Map;
037:        import java.util.Set;
038:        import de.intarsys.font.FontStyle;
039:        import de.intarsys.font.truetype.TTFont;
040:        import de.intarsys.font.truetype.TTFontHeader;
041:        import de.intarsys.font.truetype.TTFontParser;
042:        import de.intarsys.font.truetype.TTFontSerializer;
043:        import de.intarsys.font.truetype.TTHorizontalHeader;
044:        import de.intarsys.font.truetype.TTMetrics;
045:        import de.intarsys.font.truetype.TTRegistry;
046:        import de.intarsys.font.truetype.TrueTypeException;
047:        import de.intarsys.pdf.cds.CDSRectangle;
048:        import de.intarsys.pdf.cos.COSArray;
049:        import de.intarsys.pdf.cos.COSBasedObject;
050:        import de.intarsys.pdf.cos.COSDictionary;
051:        import de.intarsys.pdf.cos.COSInteger;
052:        import de.intarsys.pdf.cos.COSName;
053:        import de.intarsys.pdf.cos.COSObject;
054:        import de.intarsys.pdf.cos.COSRuntimeException;
055:        import de.intarsys.pdf.cos.COSStream;
056:        import de.intarsys.pdf.encoding.Encoding;
057:        import de.intarsys.pdf.encoding.SymbolEncoding;
058:        import de.intarsys.pdf.encoding.WinAnsiEncoding;
059:        import de.intarsys.tools.locator.ByteArrayLocator;
060:        import de.intarsys.tools.locator.ILocator;
061:
062:        /**
063:         * basic implementation for true type support
064:         * 
065:         * <p>
066:         * todo 2 review initialization (sequence problems)
067:         * </p>
068:         */
069:        public class PDFontTrueType extends PDFont {
070:            /**
071:             * The meta class implementation
072:             */
073:            public static class MetaClass extends PDFont.MetaClass {
074:                protected MetaClass(Class instanceClass) {
075:                    super (instanceClass);
076:                }
077:
078:                protected COSBasedObject doCreateCOSBasedObject(COSObject object) {
079:                    return new PDFontTrueType(object);
080:                }
081:            }
082:
083:            /** The meta class instance */
084:            public static final MetaClass META = new MetaClass(MetaClass.class
085:                    .getDeclaringClass());
086:
087:            // the underlying TrueType font object
088:            private TTFont ttFont;
089:
090:            // serialized form of the font programm (compressed)
091:            private ByteArrayOutputStream serializedBOS = null;
092:
093:            /**
094:             * Create the receiver class from an already defined {@link COSDictionary}.
095:             * NEVER use the constructor directly.
096:             * 
097:             * @param object
098:             *            the PDDocument containing the new object
099:             */
100:            protected PDFontTrueType(COSObject object) {
101:                super (object);
102:            }
103:
104:            public static String getFontFamilyName(String name) {
105:                if (name == null) {
106:                    return null;
107:                }
108:                int posPlus = name.indexOf('+');
109:                if (posPlus > 0) {
110:                    name = name.substring(posPlus + 1);
111:                }
112:                int posMinus = name.indexOf('-');
113:                if (posMinus > 0) {
114:                    name = name.substring(0, posMinus);
115:                }
116:                int posComma = name.indexOf(',');
117:                if (posComma > 0) {
118:                    name = name.substring(0, posComma);
119:                }
120:                return name;
121:            }
122:
123:            public static FontStyle getFontStyle(String name) {
124:                if (name == null) {
125:                    return FontStyle.REGULAR;
126:                }
127:                int posMinus = name.indexOf('-');
128:                if (posMinus > 0) {
129:                    name = name.substring(posMinus + 1);
130:                }
131:                int posComma = name.indexOf(',');
132:                if (posComma > 0) {
133:                    name = name.substring(posComma + 1).trim();
134:                }
135:                return FontStyle.getFontStyle(name);
136:            }
137:
138:            /**
139:             * create a TrueType font object to be used in the pdf document
140:             * 
141:             * @param ttFont
142:             *            the baseFontName of the font to use
143:             * 
144:             * @return the new font created
145:             */
146:            public static PDFontTrueType createNew(TTFont ttFont) {
147:                PDFontTrueType font = null;
148:                font = (PDFontTrueType) PDFontTrueType.META.createNew();
149:                font.setTTFont(ttFont);
150:                font.initializeFromTTFont();
151:                return font;
152:            }
153:
154:            public String getFontFamilyName() {
155:                if (getTTFont() != null) {
156:                    // the embedded name must be parsed, too!
157:                    String embeddedName = getTTFont().getFontFamilyName();
158:                    return PDFontTrueType.getFontFamilyName(embeddedName);
159:                }
160:                return PDFontTrueType.getFontFamilyName(getBaseFont()
161:                        .stringValue());
162:            }
163:
164:            public String getFontName() {
165:                if (getTTFont() != null) {
166:                    // the embedded name must be parsed, too!
167:                    String embeddedName = getTTFont().getFontName();
168:                    if (embeddedName != null) {
169:                        return PDFont.getFontName(embeddedName);
170:                    }
171:                }
172:
173:                // todo 1 this may not happen since TrueType fonts require no basefont
174:                // key
175:                // instead its derived from a host postscript name
176:                return PDFont.getFontName(getBaseFont().stringValue());
177:            }
178:
179:            public FontStyle getFontStyle() {
180:                if (getTTFont() != null) {
181:                    // the embedded name must be parsed, too!
182:                    String embeddedName = getTTFont().getFontFamilyName();
183:                    return PDFontTrueType.getFontStyle(embeddedName);
184:                }
185:                return PDFontTrueType.getFontStyle(getBaseFont().stringValue());
186:            }
187:
188:            /*
189:             * (non-Javadoc)
190:             * 
191:             * @see de.intarsys.pdf.font.PDFont#getNextCID(byte[], int)
192:             */
193:            public CID getNextCID(byte[] bytes, int offset) {
194:                return new CIDSelectorCode((bytes[offset] & 0xff));
195:            }
196:
197:            /*
198:             * (non-Javadoc)
199:             * 
200:             * @see de.intarsys.pdf.pd.PDObject#cosGetExpectedSubtype()
201:             */
202:            protected COSName cosGetExpectedSubtype() {
203:                return CN_Subtype_TrueType;
204:            }
205:
206:            public float getUnderlinePosition() {
207:                if (getTTFont() != null) {
208:                    try {
209:                        return getTTFont().getPostScriptInformation()
210:                                .getUnderlinePosition();
211:                    } catch (TrueTypeException e) {
212:                        // ignore
213:                        return -100;
214:                    }
215:                }
216:
217:                return -100;
218:            }
219:
220:            public int getUnderlineThickness() {
221:                if (getTTFont() != null) {
222:                    try {
223:                        return getTTFont().getPostScriptInformation()
224:                                .getUnderlineThickness();
225:                    } catch (TrueTypeException e) {
226:                        // ignore
227:                        return 100;
228:                    }
229:                }
230:                return 100;
231:            }
232:
233:            /**
234:             * returns the glyph width from the TT font with units and cmap to glyph
235:             * indexing resolved
236:             */
237:            public int getTTGlyphWidth(int codePoint) {
238:                int result = 0;
239:                Map cmap = null;
240:                int unitsPerEm = 0;
241:
242:                try {
243:                    cmap = getTTFontCMap();
244:                    unitsPerEm = getTTFont().getFontHeader().getUnitsPerEm();
245:                } catch (TrueTypeException e) {
246:                    return result;
247:                }
248:                int unicode = getEncoding().getUnicode(codePoint);
249:                if (getFontDescriptor().getFlags().isSymbolic()) {
250:                    unicode = 0xF000 | codePoint;
251:                }
252:                Integer glyphIndex = (Integer) cmap.get(new Integer(unicode));
253:                if (glyphIndex != null) {
254:                    try {
255:                        // well rounded...
256:                        result = ((getTTFont().getGlyphWidth(
257:                                glyphIndex.intValue()) * 1000) + 500)
258:                                / unitsPerEm;
259:                    } catch (TrueTypeException e) {
260:                        cosGetObject().handleException(
261:                                new COSRuntimeException(e));
262:                    }
263:                }
264:                return result;
265:            }
266:
267:            public void compress() {
268:                super .compress();
269:
270:                int first = 255;
271:                int last = 0;
272:                Map cmap = null;
273:                int unitsPerEm = 0;
274:
275:                try {
276:                    cmap = getTTFontCMap();
277:                    unitsPerEm = getTTFont().getFontHeader().getUnitsPerEm();
278:                } catch (TrueTypeException e) {
279:                    cosGetObject()
280:                            .handleException(
281:                                    new COSRuntimeException(
282:                                            "error parsing TrueType", e)); //$NON-NLS-1$
283:                    return;
284:                }
285:
286:                for (int i = 0; i <= 255; i++) {
287:                    // for each codepoint
288:                    if (isCharUsed(i)) {
289:                        if (i < first) {
290:                            first = i;
291:                        }
292:
293:                        if (i > last) {
294:                            last = i;
295:                        }
296:                    }
297:                }
298:
299:                COSArray widths = COSArray.create(last - first + 1);
300:                Set glyphs = new HashSet();
301:
302:                for (int i = first; i <= last; i++) {
303:                    // for each codepoint
304:                    int width = 0;
305:
306:                    if (isCharUsed(i)) {
307:                        int unicode = getEncoding().getUnicode(i);
308:                        Integer glyphIndex = (Integer) cmap.get(new Integer(
309:                                unicode));
310:
311:                        if (glyphIndex != null) {
312:                            glyphs.add(glyphIndex);
313:
314:                            try {
315:                                width = (getTTFont().getGlyphWidth(
316:                                        glyphIndex.intValue()) * 1000)
317:                                        / unitsPerEm;
318:                            } catch (TrueTypeException e) {
319:                                cosGetObject().handleException(
320:                                        new COSRuntimeException(e));
321:                            }
322:                        }
323:                    }
324:
325:                    widths.add(COSInteger.create(width));
326:                }
327:
328:                cosSetField(DK_FirstChar, COSInteger.create(first));
329:                cosSetField(DK_LastChar, COSInteger.create(last));
330:                cosSetField(DK_Widths, widths);
331:
332:                try {
333:                    TTFont newFont = getTTFont().createSubset(glyphs);
334:                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
335:                    TTFontSerializer serializer = new TTFontSerializer(bos);
336:                    serializer.write(newFont);
337:                    setSerializedBOS(bos);
338:                } catch (IOException e) {
339:                    cosGetObject().handleException(new COSRuntimeException(e));
340:                } catch (TrueTypeException e) {
341:                    cosGetObject().handleException(new COSRuntimeException(e));
342:                }
343:            }
344:
345:            /*
346:             * (non-Javadoc)
347:             * 
348:             * @see de.intarsys.pdf.font.PDFont#dump()
349:             */
350:            protected void dump() {
351:                PDFontDescriptorEmbedded fd = (PDFontDescriptorEmbedded) getFontDescriptor();
352:                if (fd == null) {
353:                    return;
354:                }
355:                byte[] data = fd.getFontFile2();
356:                if (data == null) {
357:                    return;
358:                }
359:                try {
360:                    String filename = getBaseFont().stringValue();
361:                    filename = filename.replace('+', '_');
362:                    filename = filename.replace(',', '_');
363:                    FileOutputStream os = new FileOutputStream(
364:                            "fontdump_" + filename //$NON-NLS-1$
365:                                    + ".ttf"); //$NON-NLS-1$
366:                    os.write(data);
367:                    os.close();
368:                } catch (Exception e) {
369:                    // ignore and use fallback
370:                }
371:            }
372:
373:            public void embedFontProgramm() {
374:                if (getTTFont() == null) {
375:                    return;
376:                }
377:                compress();
378:                ((PDFontDescriptorEmbedded) getFontDescriptor())
379:                        .setFontFile2(getSerializedBOS().toByteArray());
380:            }
381:
382:            public void removeFontProgramm() {
383:                ((PDFontDescriptorEmbedded) getFontDescriptor())
384:                        .removeFontFile2();
385:            }
386:
387:            protected void setSerializedBOS(ByteArrayOutputStream serializedBOS) {
388:                this .serializedBOS = serializedBOS;
389:            }
390:
391:            protected ByteArrayOutputStream getSerializedBOS() {
392:                return serializedBOS;
393:            }
394:
395:            public void setTTFont(TTFont font) {
396:                ttFont = font;
397:            }
398:
399:            public TTFont getTTFont() {
400:                return ttFont;
401:            }
402:
403:            protected Map getTTFontCMap() throws TrueTypeException {
404:                // try different maps
405:                Map result = getTTFont().getCMapsAt(3, 3);
406:                if (result == null) {
407:                    result = getTTFont().getCMapsAt(3, 1);
408:                }
409:                if (result == null) {
410:                    result = getTTFont().getCMapsAt(3, 0);
411:                }
412:                if (result == null) {
413:                    result = getTTFont().getCMapsAt(1, 0);
414:                }
415:                if (result == null) {
416:                    result = getTTFont().getCMapsAt(0, 3);
417:                }
418:                if (result == null) {
419:                    result = getTTFont().getCMapsAt(0, 1);
420:                }
421:                if (result == null) {
422:                    result = getTTFont().getCMapsAt(0, 0);
423:                }
424:                if (result == null) {
425:                    throw new TrueTypeException("No CMap found"); //$NON-NLS-1$
426:                }
427:                return result;
428:            }
429:
430:            /**
431:             * Get an encoding object that describes this fonts NATIVE encoding (if
432:             * any).
433:             * 
434:             * <p>
435:             * With a true type font the /Encoding entry should select one of the fonts
436:             * available encodings. If no such encoding is defined "an implementation
437:             * dependent encoding is chosen" (PDF Reference 1.4, p332)
438:             * </p>
439:             * 
440:             * @return Get an encoding object that describes this fonts NATIVE encoding
441:             *         (if any).
442:             */
443:            protected Encoding createDefaultEncoding() {
444:                if ((getTTFont() != null) && getTTFont().isSymbolFont()) {
445:                    return SymbolEncoding.UNIQUE;
446:                }
447:                return WinAnsiEncoding.UNIQUE;
448:            }
449:
450:            /*
451:             * (non-Javadoc)
452:             * 
453:             * @see de.intarsys.pdf.pd.PDObject#initializeFromCos()
454:             */
455:            protected void initializeFromCos() {
456:                super .initializeFromCos();
457:                COSDictionary descriptor = cosGetField(DK_FontDescriptor)
458:                        .asDictionary();
459:                if (descriptor != null) {
460:                    COSStream fontFile = descriptor.get(
461:                            PDFontDescriptorEmbedded.DK_FontFile2).asStream();
462:                    if (fontFile != null) { // embedded TTFont
463:                        TTFontParser p = new TTFontParser();
464:                        try {
465:                            byte[] bytes = fontFile.getDecodedBytes();
466:                            ILocator locator = new ByteArrayLocator(bytes,
467:                                    getFontName(), "ttf");
468:                            TTFont ttFont = TTFont.createFromLocator(locator);
469:                            setTTFont(ttFont);
470:                        } catch (IOException e) {
471:                            // todo 2 handle corrupt tt font program
472:                            e.printStackTrace();
473:                        }
474:                    } else { // linked TTFont
475:                        // try to find the font from the registry
476:                        TTFont font = (TTFont) TTRegistry.get().getFont(
477:                                getBaseFont().stringValue());
478:
479:                        if (font != null) {
480:                            setTTFont(font);
481:                        } else {
482:                            // TODO 2 handle missing font program
483:                        }
484:                    }
485:                }
486:            }
487:
488:            public void initializeFromScratchFontDescriptor() {
489:                PDFontDescriptorEmbedded result = (PDFontDescriptorEmbedded) PDFontDescriptorEmbedded.META
490:                        .createNew();
491:                TTMetrics m;
492:
493:                try {
494:                    m = getTTFont().getMetrics();
495:
496:                    TTFontHeader fh = getTTFont().getFontHeader();
497:                    TTHorizontalHeader hh = getTTFont().getHorizontalHeader();
498:
499:                    //
500:                    result.setAscent((m.getSTypoAscender() * 1000)
501:                            / fh.getUnitsPerEm());
502:
503:                    result.setCapHeight(m.getSCapHeight());
504:                    result.setDescent((m.getSTypoDescender() * 1000)
505:                            / fh.getUnitsPerEm());
506:
507:                    CDSRectangle rect = new CDSRectangle((fh.getXMin() * 1000)
508:                            / fh.getUnitsPerEm(), (fh.getYMin() * 1000)
509:                            / fh.getUnitsPerEm(), (fh.getXMax() * 1000)
510:                            / fh.getUnitsPerEm(), (fh.getYMax() * 1000)
511:                            / fh.getUnitsPerEm());
512:                    result.setFontBB(rect);
513:
514:                    // todo 3 font name
515:                    result.setFontName(getBaseFont().stringValue());
516:
517:                    double italicAngle = (-Math.atan2(hh.getCaretSlopeRun(), hh
518:                            .getCaretSlopeRise()) * 180)
519:                            / Math.PI;
520:
521:                    result.setItalicAngle((float) italicAngle);
522:
523:                    // todo 3 constant value
524:                    // Comment on TT Fonts: "The value is not in TrueType fonts. You
525:                    // have to calculate it
526:                    // by analysis of, say, the cap I glyph. Don't worry too much about
527:                    // putting in a precise
528:                    // value: the value will only ever be used if the font is not
529:                    // present with the PDF file,
530:                    // when a vaguely similar font will be used instead."
531:                    result.setStemV(80);
532:
533:                    result.setFlags(0);
534:                    result.getFlags().setSymbolic(getTTFont().isSymbolFont());
535:                    result
536:                            .getFlags()
537:                            .setItalic(
538:                                    ((fh.getMacStyle() & TTFontHeader.MACSTYLE_ITALIC) != 0));
539:                    result
540:                            .getFlags()
541:                            .setForceBold(
542:                                    ((fh.getMacStyle() & TTFontHeader.MACSTYLE_BOLD) != 0));
543:                    if (m.getPanose() != null) {
544:                        result.getFlags().setFixedPitch(
545:                                m.getPanose().isProportionMonospaced());
546:                    }
547:
548:                    // result.setFontFile2(getTTFont().getData().getBytes());
549:                    setFontDescriptor(result);
550:                } catch (TrueTypeException e) {
551:                    cosGetObject()
552:                            .handleException(
553:                                    new COSRuntimeException(
554:                                            "error parsing TrueType", e));
555:                }
556:            }
557:
558:            protected void initializeFromTTFont() {
559:                super.initializeFromScratch();
560:                setBaseFont(getTTFont().getPsName());
561:                setEncoding(createDefaultEncoding());
562:                initializeFromScratchFontDescriptor();
563:                embedFontProgramm();
564:            }
565:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.