Source Code Cross Referenced for PDFont.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.util.Arrays;
033:        import java.util.Iterator;
034:        import de.intarsys.font.FontStyle;
035:        import de.intarsys.font.IFont;
036:        import de.intarsys.pdf.cos.COSArray;
037:        import de.intarsys.pdf.cos.COSBasedObject;
038:        import de.intarsys.pdf.cos.COSDictionary;
039:        import de.intarsys.pdf.cos.COSName;
040:        import de.intarsys.pdf.cos.COSNumber;
041:        import de.intarsys.pdf.cos.COSObject;
042:        import de.intarsys.pdf.encoding.Encoding;
043:        import de.intarsys.pdf.encoding.MacOSRomanEncoding;
044:        import de.intarsys.pdf.encoding.StandardEncoding;
045:        import de.intarsys.pdf.pd.PDObject;
046:
047:        /**
048:         * A PDF font object.
049:         */
050:        public abstract class PDFont extends PDObject implements  IFont {
051:            /**
052:             * The meta class implementation
053:             */
054:            public static class MetaClass extends PDObject.MetaClass {
055:                protected MetaClass(Class instanceClass) {
056:                    super (instanceClass);
057:                }
058:
059:                /*
060:                 * (non-Javadoc)
061:                 * 
062:                 * @see de.intarsys.pdf.cos.COSBasedObject.MetaClass#doDetermineClass(de.intarsys.pdf.cos.COSObject)
063:                 */
064:                protected COSBasedObject.MetaClass doDetermineClass(
065:                        COSObject object) {
066:                    COSDictionary dict;
067:
068:                    dict = object.asDictionary();
069:                    COSName type = dict.get(DK_Type).asName();
070:                    if (type == null) {
071:                        throw new IllegalArgumentException(
072:                                "Dictionary has no type");
073:                    }
074:                    if (!type.equals(CN_Type_Font)) {
075:                        throw new IllegalArgumentException("type <" + type
076:                                + "> is not a valid font type");
077:                    }
078:                    COSName subtype = dict.get(DK_Subtype).asName();
079:                    if (subtype == null) {
080:                        throw new IllegalArgumentException(
081:                                "font not identified by subtype");
082:                    }
083:                    if (subtype.equals(CN_Subtype_Type1)) {
084:                        return PDFontType1.META;
085:                    } else if (subtype.equals(CN_Subtype_TrueType)) {
086:                        if (dict.get(DK_FontDescriptor).isNull()) {
087:                            /*
088:                             * treat as if Type1 was specified, because that's probably
089:                             * what the creator meant; further processing would yield
090:                             * wrong results anyway as FontDescriptor is a required
091:                             * entry for TrueType fonts
092:                             */
093:                            return PDFontType1.META;
094:                        }
095:                        return PDFontTrueType.META;
096:                    } else if (subtype.equals(CN_Subtype_MMType1)) {
097:                        return PDFontMMType1.META;
098:                    } else if (subtype.equals(CN_Subtype_Type0)) {
099:                        return PDFontType0.META;
100:                    } else if (subtype.equals(CN_Subtype_Type3)) {
101:                        return PDFontType3.META;
102:                    } else if (subtype.equals(CN_Subtype_CIDFontType0)) {
103:                        return CIDFontType0.META;
104:                    } else if (subtype.equals(CN_Subtype_CIDFontType2)) {
105:                        return CIDFontType2.META;
106:                    }
107:                    throw new IllegalArgumentException("font subtype <"
108:                            + subtype + "> not supported");
109:                }
110:
111:                public Class getRootClass() {
112:                    return PDFont.class;
113:                }
114:            }
115:
116:            public static final COSName CN_Subtype_CIDFontType0 = COSName
117:                    .constant("CIDFontType0"); //$NON-NLS-1$
118:
119:            public static final COSName CN_Subtype_CIDFontType2 = COSName
120:                    .constant("CIDFontType2"); //$NON-NLS-1$
121:
122:            public static final COSName CN_Subtype_MMType1 = COSName
123:                    .constant("MMType1"); //$NON-NLS-1$
124:
125:            public static final COSName CN_Subtype_TrueType = COSName
126:                    .constant("TrueType"); //$NON-NLS-1$
127:
128:            public static final COSName CN_Subtype_Type0 = COSName
129:                    .constant("Type0"); //$NON-NLS-1$
130:
131:            public static final COSName CN_Subtype_Type1 = COSName
132:                    .constant("Type1"); //$NON-NLS-1$
133:
134:            public static final COSName CN_Subtype_Type3 = COSName
135:                    .constant("Type3"); //$NON-NLS-1$
136:
137:            public static final COSName CN_Type_Font = COSName.constant("Font"); //$NON-NLS-1$
138:
139:            public static final COSName DK_BaseFont = COSName
140:                    .constant("BaseFont"); //$NON-NLS-1$
141:
142:            public static final COSName DK_Encoding = COSName
143:                    .constant("Encoding"); //$NON-NLS-1$
144:
145:            public static final COSName DK_FirstChar = COSName
146:                    .constant("FirstChar"); //$NON-NLS-1$
147:
148:            public static final COSName DK_FontDescriptor = COSName
149:                    .constant("FontDescriptor"); //$NON-NLS-1$
150:
151:            public static final COSName DK_LastChar = COSName
152:                    .constant("LastChar"); //$NON-NLS-1$
153:
154:            public static final COSName DK_ToUnicode = COSName
155:                    .constant("ToUnicode"); //$NON-NLS-1$
156:
157:            public static final COSName DK_Widths = COSName.constant("Widths"); //$NON-NLS-1$
158:
159:            public static final COSName DK_Name = COSName.constant("Name"); //$NON-NLS-1$
160:
161:            /** The meta class instance */
162:            public static final MetaClass META = new MetaClass(MetaClass.class
163:                    .getDeclaringClass());
164:
165:            public static String getFontFamilyName(String name) {
166:                if (name == null) {
167:                    return null;
168:                }
169:                int posPlus = name.indexOf('+');
170:                if (posPlus > 0) {
171:                    name = name.substring(posPlus + 1);
172:                }
173:                int posMinus = name.lastIndexOf('-');
174:                if (posMinus > 0) {
175:                    name = name.substring(0, posMinus);
176:                }
177:                return name;
178:            }
179:
180:            /**
181:             * extracts the "name" portion from the given font name string
182:             * 
183:             * @param name
184:             *            a font name
185:             * 
186:             * @return font name's "name" portion
187:             */
188:            public static String getFontName(String name) {
189:                if (name == null) {
190:                    return null;
191:                }
192:                int posPlus = name.indexOf('+');
193:                if (posPlus > 0) {
194:                    name = name.substring(posPlus + 1);
195:                }
196:                return name;
197:            }
198:
199:            /**
200:             * extracts the "style" portion from the given font name
201:             * 
202:             * @param name
203:             *            a font name
204:             * 
205:             * @return font name's "style" portion
206:             */
207:            public static FontStyle getFontStyle(String name) {
208:                if (name == null) {
209:                    return FontStyle.REGULAR;
210:                }
211:                int posMinus = name.lastIndexOf('-');
212:                if (posMinus > 0) {
213:                    name = name.substring(posMinus + 1);
214:                }
215:                return FontStyle.getFontStyle(name);
216:            }
217:
218:            /**
219:             * Flags for every codepoint if the corresponding character is used in the
220:             * document.
221:             * 
222:             * <p>
223:             * If not, a serializer could decide to embedd a font partially.
224:             * </p>
225:             */
226:            private boolean[] charUsed = new boolean[256];
227:
228:            // the encoding used for this font
229:            private Encoding encoding;
230:
231:            // some detail information about the font
232:            private PDFontDescriptor fontDescriptor;
233:
234:            // an array for the width of each glyph used
235:            private int[] widths;
236:
237:            /**
238:             * Create the receiver class from an already defined {@link COSDictionary}.
239:             * NEVER use the constructor directly.
240:             * 
241:             * @param object
242:             *            the PDDocument containing the new object
243:             */
244:            protected PDFont(COSObject object) {
245:                super (object);
246:                Arrays.fill(charUsed, true);
247:            }
248:
249:            public void compress() {
250:                // nothing to do
251:            }
252:
253:            /**
254:             * The font descriptor for a builtin font.
255:             * 
256:             * @return The font descriptor for a builtin font
257:             * 
258:             * @throws IllegalStateException
259:             */
260:            protected PDFontDescriptor createBuiltinFontDescriptor() {
261:                // this may happen, there are strange documents around that depend on
262:                // certain TrueTypes to be present.
263:                // Note from EHK: I'm treating some strange TrueTypes as Type1 now, so
264:                // maybe doesn't happen anymore
265:                return null;
266:            }
267:
268:            /**
269:             * Fill the correct width values into an array of glyph widths for a builtin
270:             * font. This is a valid implementation for type1 builtin fonts only.
271:             * 
272:             * @param result
273:             *            The array to hold the glyph widths.
274:             * 
275:             * @return The array of widths for the defined range of chars in the font
276:             */
277:            protected int[] createBuiltInWidths(int[] result) {
278:                return result;
279:            }
280:
281:            /**
282:             * Fill an array of glyph widths from the definition prepared by the font
283:             * dictionary. The widths in the font are declared in the range from the
284:             * first supported code point to the last code point. The code point selects
285:             * a glyph out of the font depending on the encoding by the font, the
286:             * corresponding entry in the widt array defines its width.
287:             * 
288:             * @param result
289:             *            The array to hold the correct widths.
290:             * @param array
291:             *            The COSArray defining the widths.
292:             * 
293:             * @return The array of widths for the defined range of chars in the font
294:             */
295:            protected int[] createDeclaredWidths(int[] result, COSArray array) {
296:                int i = getFirstChar();
297:                for (Iterator it = array.iterator(); it.hasNext();) {
298:                    COSNumber width = ((COSObject) it.next()).asNumber();
299:                    if (width != null) {
300:                        result[i] = width.intValue();
301:                    }
302:                    i++;
303:                }
304:                return result;
305:            }
306:
307:            /**
308:             * get an encoding object that describes this fonts NATIVE encoding (if any)
309:             * 
310:             * @return an encoding
311:             */
312:            protected Encoding createDefaultEncoding() {
313:                return StandardEncoding.UNIQUE;
314:            }
315:
316:            /**
317:             * Create the encoding for the font. The encoding is specified either "by
318:             * default", as a known encoding name or a completely user defined
319:             * difference encoding.
320:             * 
321:             * @return The encoding object for the font.
322:             * 
323:             * @throws IllegalArgumentException
324:             *             When the encoding defined in the font is not supported.
325:             */
326:            protected Encoding createEncoding() {
327:                COSObject base = cosGetField(PDFont.DK_Encoding);
328:                if (base.isNull()) {
329:                    return createDefaultEncoding();
330:                }
331:                if (base instanceof  COSName) {
332:                    return Encoding.create((COSName) base);
333:                }
334:                if (base instanceof  COSDictionary) {
335:                    return DifferenceEncoding
336:                            .create((COSDictionary) base, this );
337:                }
338:
339:                // todo 1 cmap support stream CMaps for Type 0 fonts
340:                throw new IllegalArgumentException("encoding not supported");
341:            }
342:
343:            protected int createFirstChar() {
344:                return 0;
345:            }
346:
347:            /**
348:             * @return the lazily created font descriptor of this font
349:             */
350:            protected PDFontDescriptor createFontDescriptor() {
351:                COSObject base = cosGetField(DK_FontDescriptor);
352:                if (base.isNull()) {
353:                    return createBuiltinFontDescriptor();
354:                }
355:                return (PDFontDescriptorEmbedded) PDFontDescriptorEmbedded.META
356:                        .createFromCos(base);
357:            }
358:
359:            protected int createLastChar() {
360:                return 255;
361:            }
362:
363:            /**
364:             * construct a array of glyph widths for the current font the widths may be
365:             * defined in the /Widths entry of the pdf font or in the font metric (afm)
366:             * of a builtin font
367:             * 
368:             * @return the array of widths for the defined range of chars in the font
369:             */
370:            protected int[] createWidths() {
371:                int[] result = new int[256];
372:                int missing = getMissingWidth();
373:                for (int i = 0; i < 256; i++) {
374:                    result[i] = missing;
375:                }
376:
377:                COSArray base = cosGetField(DK_Widths).asArray();
378:                if (base == null) {
379:                    return createBuiltInWidths(result);
380:                }
381:                return createDeclaredWidths(result, base);
382:            }
383:
384:            protected void dump() {
385:                // do nothing
386:            }
387:
388:            /**
389:             * @return the base font for this font dictionary
390:             */
391:            public COSName getBaseFont() {
392:                return cosGetField(DK_BaseFont).asName();
393:            }
394:
395:            /**
396:             * The encoding of the glyphs in the font
397:             * 
398:             * @return The encoding of the glyphs in the font
399:             */
400:            public Encoding getEncoding() {
401:                if (encoding == null) {
402:                    encoding = createEncoding();
403:                }
404:                return encoding;
405:            }
406:
407:            /**
408:             * The first codepoint defined in the font.
409:             * 
410:             * @return The first codepoint defined in the font
411:             */
412:            public int getFirstChar() {
413:                COSNumber base = cosGetField(DK_FirstChar).asInteger();
414:                if (base == null) {
415:                    return createFirstChar();
416:                }
417:                return base.intValue();
418:            }
419:
420:            /**
421:             * @return the font descriptor object for this font
422:             */
423:            public PDFontDescriptor getFontDescriptor() {
424:                if (fontDescriptor == null) {
425:                    fontDescriptor = createFontDescriptor();
426:                }
427:                return fontDescriptor;
428:            }
429:
430:            /**
431:             * return the glyph width of a codepoint in the receiver font
432:             * 
433:             * @param codePoint
434:             *            the index of the glyph in the font
435:             * 
436:             * @return the width of the glyph
437:             */
438:            public int getGlyphWidth(int codePoint) {
439:                return getGlyphWidths()[codePoint];
440:            }
441:
442:            /**
443:             * 
444:             * @return the array of defined widths for the font
445:             */
446:            public int[] getGlyphWidths() {
447:                if (widths == null) {
448:                    widths = createWidths();
449:                }
450:                return widths;
451:            }
452:
453:            /**
454:             * @return the last codepoint defined in the font
455:             */
456:            public int getLastChar() {
457:                COSNumber base = cosGetField(DK_LastChar).asInteger();
458:                if (base == null) {
459:                    return createLastChar();
460:                }
461:                return base.intValue();
462:            }
463:
464:            /**
465:             * This is a special mapping that is used if we have a font on the physical
466:             * device using a Macintosh Roman encoding character map.
467:             * 
468:             * <p>
469:             * See PDF docs, "Encodings for True Type fonts".
470:             * </p>
471:             * 
472:             * @param codePoint
473:             * 
474:             * @return The unicode value for <code>codePoint</code>
475:             */
476:            public int getMacintoshRomanCode(int codePoint) {
477:                String glyphName = getEncoding().getGlyphName(codePoint);
478:                return MacOSRomanEncoding.UNIQUE.getByteCode(glyphName);
479:            }
480:
481:            /**
482:             * @return the width we should use for a missing/undefined glyph width
483:             */
484:            public int getMissingWidth() {
485:                if (getFontDescriptor() == null) {
486:                    return 0;
487:                }
488:                return getFontDescriptor().getMissingWidth();
489:            }
490:
491:            public abstract CID getNextCID(byte[] bytes, int offset);
492:
493:            public CMap getToUnicode() {
494:                return (CMap) CMap.META
495:                        .createFromCos(cosGetField(DK_ToUnicode));
496:            }
497:
498:            /*
499:             * (non-Javadoc)
500:             * 
501:             * @see de.intarsys.pdf.pd.PDObject#cosGetExpectedType()
502:             */
503:            protected COSName cosGetExpectedType() {
504:                return CN_Type_Font;
505:            }
506:
507:            public abstract float getUnderlinePosition();
508:
509:            public abstract int getUnderlineThickness();
510:
511:            public int getUnicode(int byteCode) {
512:                CMap toUnicode = getToUnicode();
513:                if (toUnicode == null) {
514:                    return getEncoding().getUnicode(byteCode);
515:                }
516:                CID cid = toUnicode.lookup(new byte[] { (byte) byteCode });
517:                return cid.getValue();
518:            }
519:
520:            public boolean isCharUsed(int c) {
521:                if ((c < 0) || (c > 255)) {
522:                    return false;
523:                }
524:                return charUsed[c];
525:            }
526:
527:            /**
528:             * Answer true if this font's program is embedded within the document.
529:             * 
530:             * @return Answer true if this font's program is embedded within the
531:             *         document.
532:             */
533:            public boolean isEmbedded() {
534:                // standard fonts can be embedded
535:                // if (isStandardFont()) {
536:                // return false;
537:                // }
538:                if (getFontDescriptor() == null) {
539:                    return false;
540:                }
541:                if (getFontDescriptor().getFontFile() != null) {
542:                    return true;
543:                }
544:                if (getFontDescriptor().getFontFile2() != null) {
545:                    return true;
546:                }
547:                if (getFontDescriptor().getFontFile3() != null) {
548:                    return true;
549:                }
550:                return false;
551:            }
552:
553:            /**
554:             * Answer true if this is one of the 14 standard fonts. TODO 2 implement
555:             * 
556:             * @return Answer true if this is one of the 14 standard fonts.
557:             */
558:            public boolean isStandardFont() {
559:                return false;
560:            }
561:
562:            /**
563:             * Answer true if this font is partially embedded in the document.
564:             * 
565:             * @return Answer true if this font is partially embedded in the document.
566:             */
567:            public boolean isSubset() {
568:                byte[] name = getBaseFont().byteValue();
569:                if (name.length > 7) {
570:                    return name[6] == '+';
571:                }
572:                return false;
573:            }
574:
575:            public void setBaseFont(String name) {
576:                setFieldName(DK_BaseFont, name);
577:            }
578:
579:            public void setCharUsed(int c) {
580:                if ((c < 0) || (c > 255)) {
581:                    return;
582:                }
583:                charUsed[c] = true;
584:            }
585:
586:            /**
587:             * set an encoding for the font
588:             * 
589:             * @param newFontEncoding
590:             *            the new encoding to use
591:             */
592:            public void setEncoding(Encoding newFontEncoding) {
593:                encoding = newFontEncoding;
594:                if (newFontEncoding != null) {
595:                    COSObject ref = encoding.getCosObject();
596:                    if (ref != null) {
597:                        cosSetField(DK_Encoding, ref);
598:                    }
599:                } else {
600:                    cosRemoveField(DK_Encoding);
601:                }
602:            }
603:
604:            public void setFontDescriptor(PDFontDescriptor descriptor) {
605:                fontDescriptor = descriptor;
606:                setFieldObject(DK_FontDescriptor, fontDescriptor);
607:            }
608:
609:            public String toString() {
610:                return cosGetSubtype().stringValue() + "-Font "
611:                        + getBaseFont().toString() + " (" + getEncoding() + ")";
612:            }
613:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.