Source Code Cross Referenced for CFFFont.java in  » PDF » pdf-itext » com » lowagie » text » pdf » 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 » pdf itext » com.lowagie.text.pdf 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *
0003:         * Copyright 2003 Sivan Toledo
0004:         *
0005:         * The contents of this file are subject to the Mozilla Public License Version 1.1
0006:         * (the "License"); you may not use this file except in compliance with the License.
0007:         * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0008:         *
0009:         * Software distributed under the License is distributed on an "AS IS" basis,
0010:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0011:         * for the specific language governing rights and limitations under the License.
0012:         *
0013:         * Contributor(s): all the names of the contributors are added in the source code
0014:         * where applicable.
0015:         *
0016:         * Alternatively, the contents of this file may be used under the terms of the
0017:         * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
0018:         * provisions of LGPL are applicable instead of those above.  If you wish to
0019:         * allow use of your version of this file only under the terms of the LGPL
0020:         * License and not to allow others to use your version of this file under
0021:         * the MPL, indicate your decision by deleting the provisions above and
0022:         * replace them with the notice and other provisions required by the LGPL.
0023:         * If you do not delete the provisions above, a recipient may use your version
0024:         * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
0025:         *
0026:         * This library is free software; you can redistribute it and/or modify it
0027:         * under the terms of the MPL as stated above or under the terms of the GNU
0028:         * Library General Public License as published by the Free Software Foundation;
0029:         * either version 2 of the License, or any later version.
0030:         *
0031:         * This library is distributed in the hope that it will be useful, but WITHOUT
0032:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0033:         * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
0034:         * details.
0035:         *
0036:         */
0037:
0038:        /*
0039:         * Comments by Sivan Toledo:
0040:         * I created this class in order to add to iText the ability to utilize
0041:         * OpenType fonts with CFF glyphs (these usually have an .otf extension).
0042:         * The CFF font within the CFF table of the OT font might be either a CID
0043:         * or a Type1 font. (CFF fonts may also contain multiple fonts; I do not
0044:         * know if this is allowed in an OT table). The PDF spec, however, only
0045:         * allow a CID font with an Identity-H or Identity-V encoding. Otherwise,
0046:         * you are limited to an 8-bit encoding.
0047:         * Adobe fonts come in both flavors. That is, the OTFs sometimes have
0048:         * a CID CFF inside (for Japanese fonts), and sometimes a Type1 CFF
0049:         * (virtually all the others, Latin/Greek/Cyrillic). So to easily use
0050:         * all the glyphs in the latter, without creating multiple 8-bit encoding,
0051:         * I wrote this class, whose main purpose is to convert a Type1 font inside
0052:         * a CFF container (which might include other fonts) into a CID CFF font
0053:         * that can be directly embeded in the PDF.
0054:         *
0055:         * Limitations of the current version:
0056:         * 1. It does not extract a single CID font from a CFF that contains that
0057:         *    particular CID along with other fonts. The Adobe Japanese OTF's that
0058:         *    I have only have one font in the CFF table, so these can be
0059:         *    embeded in the PDF as is.
0060:         * 2. It does not yet subset fonts.
0061:         * 3. It may or may not work on CFF fonts that are not within OTF's.
0062:         *    I didn't try that. In any case, that would probably only be
0063:         *    useful for subsetting CID fonts, not for CFF Type1 fonts (I don't
0064:         *    think there are any available.
0065:         * I plan to extend the class to support these three features at some
0066:         * future time.
0067:         */
0068:
0069:        package com.lowagie.text.pdf;
0070:
0071:        import java.util.Iterator;
0072:        import java.util.LinkedList;
0073:
0074:        import com.lowagie.text.ExceptionConverter;
0075:
0076:        public class CFFFont {
0077:
0078:            static final String operatorNames[] = { "version", "Notice",
0079:                    "FullName", "FamilyName", "Weight", "FontBBox",
0080:                    "BlueValues", "OtherBlues", "FamilyBlues",
0081:                    "FamilyOtherBlues", "StdHW", "StdVW", "UNKNOWN_12",
0082:                    "UniqueID", "XUID", "charset", "Encoding", "CharStrings",
0083:                    "Private", "Subrs", "defaultWidthX", "nominalWidthX",
0084:                    "UNKNOWN_22", "UNKNOWN_23", "UNKNOWN_24", "UNKNOWN_25",
0085:                    "UNKNOWN_26", "UNKNOWN_27", "UNKNOWN_28", "UNKNOWN_29",
0086:                    "UNKNOWN_30", "UNKNOWN_31", "Copyright", "isFixedPitch",
0087:                    "ItalicAngle", "UnderlinePosition", "UnderlineThickness",
0088:                    "PaintType", "CharstringType", "FontMatrix", "StrokeWidth",
0089:                    "BlueScale", "BlueShift", "BlueFuzz", "StemSnapH",
0090:                    "StemSnapV", "ForceBold", "UNKNOWN_12_15", "UNKNOWN_12_16",
0091:                    "LanguageGroup", "ExpansionFactor", "initialRandomSeed",
0092:                    "SyntheticBase", "PostScript", "BaseFontName",
0093:                    "BaseFontBlend", "UNKNOWN_12_24", "UNKNOWN_12_25",
0094:                    "UNKNOWN_12_26", "UNKNOWN_12_27", "UNKNOWN_12_28",
0095:                    "UNKNOWN_12_29", "ROS", "CIDFontVersion",
0096:                    "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase",
0097:                    "FDArray", "FDSelect", "FontName" };
0098:
0099:            static final String standardStrings[] = {
0100:                    // Automatically generated from Appendix A of the CFF specification; do
0101:                    // not edit. Size should be 391.
0102:                    ".notdef", "space", "exclam", "quotedbl", "numbersign",
0103:                    "dollar", "percent", "ampersand", "quoteright",
0104:                    "parenleft", "parenright", "asterisk", "plus", "comma",
0105:                    "hyphen", "period", "slash", "zero", "one", "two", "three",
0106:                    "four", "five", "six", "seven", "eight", "nine", "colon",
0107:                    "semicolon", "less", "equal", "greater", "question", "at",
0108:                    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
0109:                    "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
0110:                    "Y", "Z", "bracketleft", "backslash", "bracketright",
0111:                    "asciicircum", "underscore", "quoteleft", "a", "b", "c",
0112:                    "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
0113:                    "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
0114:                    "braceleft", "bar", "braceright", "asciitilde",
0115:                    "exclamdown", "cent", "sterling", "fraction", "yen",
0116:                    "florin", "section", "currency", "quotesingle",
0117:                    "quotedblleft", "guillemotleft", "guilsinglleft",
0118:                    "guilsinglright", "fi", "fl", "endash", "dagger",
0119:                    "daggerdbl", "periodcentered", "paragraph", "bullet",
0120:                    "quotesinglbase", "quotedblbase", "quotedblright",
0121:                    "guillemotright", "ellipsis", "perthousand",
0122:                    "questiondown", "grave", "acute", "circumflex", "tilde",
0123:                    "macron", "breve", "dotaccent", "dieresis", "ring",
0124:                    "cedilla", "hungarumlaut", "ogonek", "caron", "emdash",
0125:                    "AE", "ordfeminine", "Lslash", "Oslash", "OE",
0126:                    "ordmasculine", "ae", "dotlessi", "lslash", "oslash", "oe",
0127:                    "germandbls", "onesuperior", "logicalnot", "mu",
0128:                    "trademark", "Eth", "onehalf", "plusminus", "Thorn",
0129:                    "onequarter", "divide", "brokenbar", "degree", "thorn",
0130:                    "threequarters", "twosuperior", "registered", "minus",
0131:                    "eth", "multiply", "threesuperior", "copyright", "Aacute",
0132:                    "Acircumflex", "Adieresis", "Agrave", "Aring", "Atilde",
0133:                    "Ccedilla", "Eacute", "Ecircumflex", "Edieresis", "Egrave",
0134:                    "Iacute", "Icircumflex", "Idieresis", "Igrave", "Ntilde",
0135:                    "Oacute", "Ocircumflex", "Odieresis", "Ograve", "Otilde",
0136:                    "Scaron", "Uacute", "Ucircumflex", "Udieresis", "Ugrave",
0137:                    "Yacute", "Ydieresis", "Zcaron", "aacute", "acircumflex",
0138:                    "adieresis", "agrave", "aring", "atilde", "ccedilla",
0139:                    "eacute", "ecircumflex", "edieresis", "egrave", "iacute",
0140:                    "icircumflex", "idieresis", "igrave", "ntilde", "oacute",
0141:                    "ocircumflex", "odieresis", "ograve", "otilde", "scaron",
0142:                    "uacute", "ucircumflex", "udieresis", "ugrave", "yacute",
0143:                    "ydieresis", "zcaron", "exclamsmall", "Hungarumlautsmall",
0144:                    "dollaroldstyle", "dollarsuperior", "ampersandsmall",
0145:                    "Acutesmall", "parenleftsuperior", "parenrightsuperior",
0146:                    "twodotenleader", "onedotenleader", "zerooldstyle",
0147:                    "oneoldstyle", "twooldstyle", "threeoldstyle",
0148:                    "fouroldstyle", "fiveoldstyle", "sixoldstyle",
0149:                    "sevenoldstyle", "eightoldstyle", "nineoldstyle",
0150:                    "commasuperior", "threequartersemdash", "periodsuperior",
0151:                    "questionsmall", "asuperior", "bsuperior", "centsuperior",
0152:                    "dsuperior", "esuperior", "isuperior", "lsuperior",
0153:                    "msuperior", "nsuperior", "osuperior", "rsuperior",
0154:                    "ssuperior", "tsuperior", "ff", "ffi", "ffl",
0155:                    "parenleftinferior", "parenrightinferior",
0156:                    "Circumflexsmall", "hyphensuperior", "Gravesmall",
0157:                    "Asmall", "Bsmall", "Csmall", "Dsmall", "Esmall", "Fsmall",
0158:                    "Gsmall", "Hsmall", "Ismall", "Jsmall", "Ksmall", "Lsmall",
0159:                    "Msmall", "Nsmall", "Osmall", "Psmall", "Qsmall", "Rsmall",
0160:                    "Ssmall", "Tsmall", "Usmall", "Vsmall", "Wsmall", "Xsmall",
0161:                    "Ysmall", "Zsmall", "colonmonetary", "onefitted", "rupiah",
0162:                    "Tildesmall", "exclamdownsmall", "centoldstyle",
0163:                    "Lslashsmall", "Scaronsmall", "Zcaronsmall",
0164:                    "Dieresissmall", "Brevesmall", "Caronsmall",
0165:                    "Dotaccentsmall", "Macronsmall", "figuredash",
0166:                    "hypheninferior", "Ogoneksmall", "Ringsmall",
0167:                    "Cedillasmall", "questiondownsmall", "oneeighth",
0168:                    "threeeighths", "fiveeighths", "seveneighths", "onethird",
0169:                    "twothirds", "zerosuperior", "foursuperior",
0170:                    "fivesuperior", "sixsuperior", "sevensuperior",
0171:                    "eightsuperior", "ninesuperior", "zeroinferior",
0172:                    "oneinferior", "twoinferior", "threeinferior",
0173:                    "fourinferior", "fiveinferior", "sixinferior",
0174:                    "seveninferior", "eightinferior", "nineinferior",
0175:                    "centinferior", "dollarinferior", "periodinferior",
0176:                    "commainferior", "Agravesmall", "Aacutesmall",
0177:                    "Acircumflexsmall", "Atildesmall", "Adieresissmall",
0178:                    "Aringsmall", "AEsmall", "Ccedillasmall", "Egravesmall",
0179:                    "Eacutesmall", "Ecircumflexsmall", "Edieresissmall",
0180:                    "Igravesmall", "Iacutesmall", "Icircumflexsmall",
0181:                    "Idieresissmall", "Ethsmall", "Ntildesmall", "Ogravesmall",
0182:                    "Oacutesmall", "Ocircumflexsmall", "Otildesmall",
0183:                    "Odieresissmall", "OEsmall", "Oslashsmall", "Ugravesmall",
0184:                    "Uacutesmall", "Ucircumflexsmall", "Udieresissmall",
0185:                    "Yacutesmall", "Thornsmall", "Ydieresissmall", "001.000",
0186:                    "001.001", "001.002", "001.003", "Black", "Bold", "Book",
0187:                    "Light", "Medium", "Regular", "Roman", "Semibold" };
0188:
0189:            //private String[] strings;
0190:            public String getString(char sid) {
0191:                if (sid < standardStrings.length)
0192:                    return standardStrings[sid];
0193:                if (sid >= standardStrings.length + (stringOffsets.length - 1))
0194:                    return null;
0195:                int j = sid - standardStrings.length;
0196:                //java.lang.System.err.println("going for "+j);
0197:                int p = getPosition();
0198:                seek(stringOffsets[j]);
0199:                StringBuffer s = new StringBuffer();
0200:                for (int k = stringOffsets[j]; k < stringOffsets[j + 1]; k++) {
0201:                    s.append(getCard8());
0202:                }
0203:                seek(p);
0204:                return s.toString();
0205:            }
0206:
0207:            char getCard8() {
0208:                try {
0209:                    byte i = buf.readByte();
0210:                    return (char) (i & 0xff);
0211:                } catch (Exception e) {
0212:                    throw new ExceptionConverter(e);
0213:                }
0214:            }
0215:
0216:            char getCard16() {
0217:                try {
0218:                    return buf.readChar();
0219:                } catch (Exception e) {
0220:                    throw new ExceptionConverter(e);
0221:                }
0222:            }
0223:
0224:            int getOffset(int offSize) {
0225:                int offset = 0;
0226:                for (int i = 0; i < offSize; i++) {
0227:                    offset *= 256;
0228:                    offset += getCard8();
0229:                }
0230:                return offset;
0231:            }
0232:
0233:            void seek(int offset) {
0234:                try {
0235:                    buf.seek(offset);
0236:                } catch (Exception e) {
0237:                    throw new ExceptionConverter(e);
0238:                }
0239:            }
0240:
0241:            short getShort() {
0242:                try {
0243:                    return buf.readShort();
0244:                } catch (Exception e) {
0245:                    throw new ExceptionConverter(e);
0246:                }
0247:            }
0248:
0249:            int getInt() {
0250:                try {
0251:                    return buf.readInt();
0252:                } catch (Exception e) {
0253:                    throw new ExceptionConverter(e);
0254:                }
0255:            }
0256:
0257:            int getPosition() {
0258:                try {
0259:                    return buf.getFilePointer();
0260:                } catch (Exception e) {
0261:                    throw new ExceptionConverter(e);
0262:                }
0263:            }
0264:
0265:            int nextIndexOffset;
0266:
0267:            // read the offsets in the next index
0268:            // data structure, convert to global
0269:            // offsets, and return them.
0270:            // Sets the nextIndexOffset.
0271:            int[] getIndex(int nextIndexOffset) {
0272:                int count, indexOffSize;
0273:
0274:                seek(nextIndexOffset);
0275:                count = getCard16();
0276:                int[] offsets = new int[count + 1];
0277:
0278:                if (count == 0) {
0279:                    offsets[0] = -1;
0280:                    nextIndexOffset += 2;
0281:                    return offsets;
0282:                }
0283:
0284:                indexOffSize = getCard8();
0285:
0286:                for (int j = 0; j <= count; j++) {
0287:                    //nextIndexOffset = ofset to relative segment
0288:                    offsets[j] = nextIndexOffset
0289:                    //2-> count in the index header. 1->offset size in index header
0290:                            + 2 + 1
0291:                            //offset array size * offset size 
0292:                            + (count + 1) * indexOffSize
0293:                            //???zero <-> one base
0294:                            - 1
0295:                            // read object offset relative to object array base 
0296:                            + getOffset(indexOffSize);
0297:                }
0298:                //nextIndexOffset = offsets[count];
0299:                return offsets;
0300:            }
0301:
0302:            protected String key;
0303:            protected Object[] args = new Object[48];
0304:            protected int arg_count = 0;
0305:
0306:            protected void getDictItem() {
0307:                for (int i = 0; i < arg_count; i++)
0308:                    args[i] = null;
0309:                arg_count = 0;
0310:                key = null;
0311:                boolean gotKey = false;
0312:
0313:                while (!gotKey) {
0314:                    char b0 = getCard8();
0315:                    if (b0 == 29) {
0316:                        int item = getInt();
0317:                        args[arg_count] = new Integer(item);
0318:                        arg_count++;
0319:                        //System.err.println(item+" ");
0320:                        continue;
0321:                    }
0322:                    if (b0 == 28) {
0323:                        short item = getShort();
0324:                        args[arg_count] = new Integer(item);
0325:                        arg_count++;
0326:                        //System.err.println(item+" ");
0327:                        continue;
0328:                    }
0329:                    if (b0 >= 32 && b0 <= 246) {
0330:                        byte item = (byte) (b0 - 139);
0331:                        args[arg_count] = new Integer(item);
0332:                        arg_count++;
0333:                        //System.err.println(item+" ");
0334:                        continue;
0335:                    }
0336:                    if (b0 >= 247 && b0 <= 250) {
0337:                        char b1 = getCard8();
0338:                        short item = (short) ((b0 - 247) * 256 + b1 + 108);
0339:                        args[arg_count] = new Integer(item);
0340:                        arg_count++;
0341:                        //System.err.println(item+" ");
0342:                        continue;
0343:                    }
0344:                    if (b0 >= 251 && b0 <= 254) {
0345:                        char b1 = getCard8();
0346:                        short item = (short) (-(b0 - 251) * 256 - b1 - 108);
0347:                        args[arg_count] = new Integer(item);
0348:                        arg_count++;
0349:                        //System.err.println(item+" ");
0350:                        continue;
0351:                    }
0352:                    if (b0 == 30) {
0353:                        String item = "";
0354:                        boolean done = false;
0355:                        char buffer = 0;
0356:                        byte avail = 0;
0357:                        int nibble = 0;
0358:                        while (!done) {
0359:                            // get a nibble
0360:                            if (avail == 0) {
0361:                                buffer = getCard8();
0362:                                avail = 2;
0363:                            }
0364:                            if (avail == 1) {
0365:                                nibble = (buffer / 16);
0366:                                avail--;
0367:                            }
0368:                            if (avail == 2) {
0369:                                nibble = (buffer % 16);
0370:                                avail--;
0371:                            }
0372:                            switch (nibble) {
0373:                            case 0xa:
0374:                                item += ".";
0375:                                break;
0376:                            case 0xb:
0377:                                item += "E";
0378:                                break;
0379:                            case 0xc:
0380:                                item += "E-";
0381:                                break;
0382:                            case 0xe:
0383:                                item += "-";
0384:                                break;
0385:                            case 0xf:
0386:                                done = true;
0387:                                break;
0388:                            default:
0389:                                if (nibble >= 0 && nibble <= 9)
0390:                                    item += String.valueOf(nibble);
0391:                                else {
0392:                                    item += "<NIBBLE ERROR: " + nibble + '>';
0393:                                    done = true;
0394:                                }
0395:                                break;
0396:                            }
0397:                        }
0398:                        args[arg_count] = item;
0399:                        arg_count++;
0400:                        //System.err.println(" real=["+item+"]");
0401:                        continue;
0402:                    }
0403:                    if (b0 <= 21) {
0404:                        gotKey = true;
0405:                        if (b0 != 12)
0406:                            key = operatorNames[b0];
0407:                        else
0408:                            key = operatorNames[32 + getCard8()];
0409:                        //for (int i=0; i<arg_count; i++)
0410:                        //  System.err.print(args[i].toString()+" ");
0411:                        //System.err.println(key+" ;");
0412:                        continue;
0413:                    }
0414:                }
0415:            }
0416:
0417:            /** List items for the linked list that builds the new CID font.
0418:             */
0419:
0420:            protected static abstract class Item {
0421:                protected int myOffset = -1;
0422:
0423:                /** remember the current offset and increment by item's size in bytes. */
0424:                public void increment(int[] currentOffset) {
0425:                    myOffset = currentOffset[0];
0426:                }
0427:
0428:                /** Emit the byte stream for this item. */
0429:                public void emit(byte[] buffer) {
0430:                }
0431:
0432:                /** Fix up cross references to this item (applies only to markers). */
0433:                public void xref() {
0434:                }
0435:            }
0436:
0437:            protected static abstract class OffsetItem extends Item {
0438:                public int value;
0439:
0440:                /** set the value of an offset item that was initially unknown.
0441:                 * It will be fixed up latex by a call to xref on some marker.
0442:                 */
0443:                public void set(int offset) {
0444:                    this .value = offset;
0445:                }
0446:            }
0447:
0448:            /** A range item.
0449:             */
0450:
0451:            protected static final class RangeItem extends Item {
0452:                public int offset, length;
0453:                private RandomAccessFileOrArray buf;
0454:
0455:                public RangeItem(RandomAccessFileOrArray buf, int offset,
0456:                        int length) {
0457:                    this .offset = offset;
0458:                    this .length = length;
0459:                    this .buf = buf;
0460:                }
0461:
0462:                public void increment(int[] currentOffset) {
0463:                    super .increment(currentOffset);
0464:                    currentOffset[0] += length;
0465:                }
0466:
0467:                public void emit(byte[] buffer) {
0468:                    //System.err.println("range emit offset "+offset+" size="+length);
0469:                    try {
0470:                        buf.seek(offset);
0471:                        for (int i = myOffset; i < myOffset + length; i++)
0472:                            buffer[i] = buf.readByte();
0473:                    } catch (Exception e) {
0474:                        throw new ExceptionConverter(e);
0475:                    }
0476:                    //System.err.println("finished range emit");
0477:                }
0478:            }
0479:
0480:            /** An index-offset item for the list.
0481:             * The size denotes the required size in the CFF. A positive
0482:             * value means that we need a specific size in bytes (for offset arrays)
0483:             * and a negative value means that this is a dict item that uses a
0484:             * variable-size representation.
0485:             */
0486:            static protected final class IndexOffsetItem extends OffsetItem {
0487:                public final int size;
0488:
0489:                public IndexOffsetItem(int size, int value) {
0490:                    this .size = size;
0491:                    this .value = value;
0492:                }
0493:
0494:                public IndexOffsetItem(int size) {
0495:                    this .size = size;
0496:                }
0497:
0498:                public void increment(int[] currentOffset) {
0499:                    super .increment(currentOffset);
0500:                    currentOffset[0] += size;
0501:                }
0502:
0503:                public void emit(byte[] buffer) {
0504:                    int i = 0;
0505:                    switch (size) {
0506:                    case 4:
0507:                        buffer[myOffset + i] = (byte) ((value >>> 24) & 0xff);
0508:                        i++;
0509:                    case 3:
0510:                        buffer[myOffset + i] = (byte) ((value >>> 16) & 0xff);
0511:                        i++;
0512:                    case 2:
0513:                        buffer[myOffset + i] = (byte) ((value >>> 8) & 0xff);
0514:                        i++;
0515:                    case 1:
0516:                        buffer[myOffset + i] = (byte) ((value >>> 0) & 0xff);
0517:                        i++;
0518:                    }
0519:                    /*
0520:                    int mask = 0xff;
0521:                    for (int i=size-1; i>=0; i--) {
0522:                        buffer[myOffset+i] = (byte) (value & mask);
0523:                        mask <<= 8;
0524:                    }
0525:                     */
0526:                }
0527:            }
0528:
0529:            static protected final class IndexBaseItem extends Item {
0530:                public IndexBaseItem() {
0531:                }
0532:            }
0533:
0534:            static protected final class IndexMarkerItem extends Item {
0535:                private OffsetItem offItem;
0536:                private IndexBaseItem indexBase;
0537:
0538:                public IndexMarkerItem(OffsetItem offItem,
0539:                        IndexBaseItem indexBase) {
0540:                    this .offItem = offItem;
0541:                    this .indexBase = indexBase;
0542:                }
0543:
0544:                public void xref() {
0545:                    //System.err.println("index marker item, base="+indexBase.myOffset+" my="+this.myOffset);
0546:                    offItem.set(this .myOffset - indexBase.myOffset + 1);
0547:                }
0548:            }
0549:
0550:            /**
0551:             * TODO To change the template for this generated type comment go to
0552:             * Window - Preferences - Java - Code Generation - Code and Comments
0553:             */
0554:            static protected final class SubrMarkerItem extends Item {
0555:                private OffsetItem offItem;
0556:                private IndexBaseItem indexBase;
0557:
0558:                public SubrMarkerItem(OffsetItem offItem,
0559:                        IndexBaseItem indexBase) {
0560:                    this .offItem = offItem;
0561:                    this .indexBase = indexBase;
0562:                }
0563:
0564:                public void xref() {
0565:                    //System.err.println("index marker item, base="+indexBase.myOffset+" my="+this.myOffset);
0566:                    offItem.set(this .myOffset - indexBase.myOffset);
0567:                }
0568:            }
0569:
0570:            /** an unknown offset in a dictionary for the list.
0571:             * We will fix up the offset later; for now, assume it's large.
0572:             */
0573:            static protected final class DictOffsetItem extends OffsetItem {
0574:                public final int size;
0575:
0576:                public DictOffsetItem() {
0577:                    this .size = 5;
0578:                }
0579:
0580:                public void increment(int[] currentOffset) {
0581:                    super .increment(currentOffset);
0582:                    currentOffset[0] += size;
0583:                }
0584:
0585:                // this is incomplete!
0586:                public void emit(byte[] buffer) {
0587:                    if (size == 5) {
0588:                        buffer[myOffset] = 29;
0589:                        buffer[myOffset + 1] = (byte) ((value >>> 24) & 0xff);
0590:                        buffer[myOffset + 2] = (byte) ((value >>> 16) & 0xff);
0591:                        buffer[myOffset + 3] = (byte) ((value >>> 8) & 0xff);
0592:                        buffer[myOffset + 4] = (byte) ((value >>> 0) & 0xff);
0593:                    }
0594:                }
0595:            }
0596:
0597:            /** Card24 item.
0598:             */
0599:
0600:            static protected final class UInt24Item extends Item {
0601:                public int value;
0602:
0603:                public UInt24Item(int value) {
0604:                    this .value = value;
0605:                }
0606:
0607:                public void increment(int[] currentOffset) {
0608:                    super .increment(currentOffset);
0609:                    currentOffset[0] += 3;
0610:                }
0611:
0612:                // this is incomplete!
0613:                public void emit(byte[] buffer) {
0614:                    buffer[myOffset + 0] = (byte) ((value >>> 16) & 0xff);
0615:                    buffer[myOffset + 1] = (byte) ((value >>> 8) & 0xff);
0616:                    buffer[myOffset + 2] = (byte) ((value >>> 0) & 0xff);
0617:                }
0618:            }
0619:
0620:            /** Card32 item.
0621:             */
0622:
0623:            static protected final class UInt32Item extends Item {
0624:                public int value;
0625:
0626:                public UInt32Item(int value) {
0627:                    this .value = value;
0628:                }
0629:
0630:                public void increment(int[] currentOffset) {
0631:                    super .increment(currentOffset);
0632:                    currentOffset[0] += 4;
0633:                }
0634:
0635:                // this is incomplete!
0636:                public void emit(byte[] buffer) {
0637:                    buffer[myOffset + 0] = (byte) ((value >>> 24) & 0xff);
0638:                    buffer[myOffset + 1] = (byte) ((value >>> 16) & 0xff);
0639:                    buffer[myOffset + 2] = (byte) ((value >>> 8) & 0xff);
0640:                    buffer[myOffset + 3] = (byte) ((value >>> 0) & 0xff);
0641:                }
0642:            }
0643:
0644:            /** A SID or Card16 item.
0645:             */
0646:
0647:            static protected final class UInt16Item extends Item {
0648:                public char value;
0649:
0650:                public UInt16Item(char value) {
0651:                    this .value = value;
0652:                }
0653:
0654:                public void increment(int[] currentOffset) {
0655:                    super .increment(currentOffset);
0656:                    currentOffset[0] += 2;
0657:                }
0658:
0659:                // this is incomplete!
0660:                public void emit(byte[] buffer) {
0661:                    buffer[myOffset + 0] = (byte) ((value >>> 8) & 0xff);
0662:                    buffer[myOffset + 1] = (byte) ((value >>> 0) & 0xff);
0663:                }
0664:            }
0665:
0666:            /** A Card8 item.
0667:             */
0668:
0669:            static protected final class UInt8Item extends Item {
0670:                public char value;
0671:
0672:                public UInt8Item(char value) {
0673:                    this .value = value;
0674:                }
0675:
0676:                public void increment(int[] currentOffset) {
0677:                    super .increment(currentOffset);
0678:                    currentOffset[0] += 1;
0679:                }
0680:
0681:                // this is incomplete!
0682:                public void emit(byte[] buffer) {
0683:                    buffer[myOffset + 0] = (byte) ((value >>> 0) & 0xff);
0684:                }
0685:            }
0686:
0687:            static protected final class StringItem extends Item {
0688:                public String s;
0689:
0690:                public StringItem(String s) {
0691:                    this .s = s;
0692:                }
0693:
0694:                public void increment(int[] currentOffset) {
0695:                    super .increment(currentOffset);
0696:                    currentOffset[0] += s.length();
0697:                }
0698:
0699:                public void emit(byte[] buffer) {
0700:                    for (int i = 0; i < s.length(); i++)
0701:                        buffer[myOffset + i] = (byte) (s.charAt(i) & 0xff);
0702:                }
0703:            }
0704:
0705:            /** A dictionary number on the list.
0706:             * This implementation is inefficient: it doesn't use the variable-length
0707:             * representation.
0708:             */
0709:
0710:            static protected final class DictNumberItem extends Item {
0711:                public final int value;
0712:                public int size = 5;
0713:
0714:                public DictNumberItem(int value) {
0715:                    this .value = value;
0716:                }
0717:
0718:                public void increment(int[] currentOffset) {
0719:                    super .increment(currentOffset);
0720:                    currentOffset[0] += size;
0721:                }
0722:
0723:                // this is imcomplete!
0724:                public void emit(byte[] buffer) {
0725:                    if (size == 5) {
0726:                        buffer[myOffset] = 29;
0727:                        buffer[myOffset + 1] = (byte) ((value >>> 24) & 0xff);
0728:                        buffer[myOffset + 2] = (byte) ((value >>> 16) & 0xff);
0729:                        buffer[myOffset + 3] = (byte) ((value >>> 8) & 0xff);
0730:                        buffer[myOffset + 4] = (byte) ((value >>> 0) & 0xff);
0731:                    }
0732:                }
0733:            }
0734:
0735:            /** An offset-marker item for the list.
0736:             * It is used to mark an offset and to set the offset list item.
0737:             */
0738:
0739:            static protected final class MarkerItem extends Item {
0740:                OffsetItem p;
0741:
0742:                public MarkerItem(OffsetItem pointerToMarker) {
0743:                    p = pointerToMarker;
0744:                }
0745:
0746:                public void xref() {
0747:                    p.set(this .myOffset);
0748:                }
0749:            }
0750:
0751:            /** a utility that creates a range item for an entire index
0752:             *
0753:             * @param indexOffset where the index is
0754:             * @return a range item representing the entire index
0755:             */
0756:
0757:            protected RangeItem getEntireIndexRange(int indexOffset) {
0758:                seek(indexOffset);
0759:                int count = getCard16();
0760:                if (count == 0) {
0761:                    return new RangeItem(buf, indexOffset, 2);
0762:                } else {
0763:                    int indexOffSize = getCard8();
0764:                    seek(indexOffset + 2 + 1 + count * indexOffSize);
0765:                    int size = getOffset(indexOffSize) - 1;
0766:                    return new RangeItem(buf, indexOffset, 2 + 1 + (count + 1)
0767:                            * indexOffSize + size);
0768:                }
0769:            }
0770:
0771:            /** get a single CID font. The PDF architecture (1.4)
0772:             * supports 16-bit strings only with CID CFF fonts, not
0773:             * in Type-1 CFF fonts, so we convert the font to CID if
0774:             * it is in the Type-1 format.
0775:             * Two other tasks that we need to do are to select
0776:             * only a single font from the CFF package (this again is
0777:             * a PDF restriction) and to subset the CharStrings glyph
0778:             * description.
0779:             */
0780:
0781:            public byte[] getCID(String fontName)
0782:            //throws java.io.FileNotFoundException
0783:            {
0784:                int j;
0785:                for (j = 0; j < fonts.length; j++)
0786:                    if (fontName.equals(fonts[j].name))
0787:                        break;
0788:                if (j == fonts.length)
0789:                    return null;
0790:
0791:                LinkedList l = new LinkedList();
0792:
0793:                // copy the header
0794:
0795:                seek(0);
0796:
0797:                int major = getCard8();
0798:                int minor = getCard8();
0799:                int hdrSize = getCard8();
0800:                int offSize = getCard8();
0801:                nextIndexOffset = hdrSize;
0802:
0803:                l.addLast(new RangeItem(buf, 0, hdrSize));
0804:
0805:                int nglyphs = -1, nstrings = -1;
0806:                if (!fonts[j].isCID) {
0807:                    // count the glyphs
0808:                    seek(fonts[j].charstringsOffset);
0809:                    nglyphs = getCard16();
0810:                    seek(stringIndexOffset);
0811:                    nstrings = getCard16() + standardStrings.length;
0812:                    //System.err.println("number of glyphs = "+nglyphs);
0813:                }
0814:
0815:                // create a name index
0816:
0817:                l.addLast(new UInt16Item((char) 1)); // count
0818:                l.addLast(new UInt8Item((char) 1)); // offSize
0819:                l.addLast(new UInt8Item((char) 1)); // first offset
0820:                l.addLast(new UInt8Item((char) (1 + fonts[j].name.length())));
0821:                l.addLast(new StringItem(fonts[j].name));
0822:
0823:                // create the topdict Index
0824:
0825:                l.addLast(new UInt16Item((char) 1)); // count
0826:                l.addLast(new UInt8Item((char) 2)); // offSize
0827:                l.addLast(new UInt16Item((char) 1)); // first offset
0828:                OffsetItem topdictIndex1Ref = new IndexOffsetItem(2);
0829:                l.addLast(topdictIndex1Ref);
0830:                IndexBaseItem topdictBase = new IndexBaseItem();
0831:                l.addLast(topdictBase);
0832:
0833:                /*
0834:                int maxTopdictLen = (topdictOffsets[j+1]-topdictOffsets[j])
0835:                                    + 9*2 // at most 9 new keys
0836:                                    + 8*5 // 8 new integer arguments
0837:                                    + 3*2;// 3 new SID arguments
0838:                 */
0839:
0840:                //int    topdictNext = 0;
0841:                //byte[] topdict = new byte[maxTopdictLen];
0842:                OffsetItem charsetRef = new DictOffsetItem();
0843:                OffsetItem charstringsRef = new DictOffsetItem();
0844:                OffsetItem fdarrayRef = new DictOffsetItem();
0845:                OffsetItem fdselectRef = new DictOffsetItem();
0846:
0847:                if (!fonts[j].isCID) {
0848:                    // create a ROS key
0849:                    l.addLast(new DictNumberItem(nstrings));
0850:                    l.addLast(new DictNumberItem(nstrings + 1));
0851:                    l.addLast(new DictNumberItem(0));
0852:                    l.addLast(new UInt8Item((char) 12));
0853:                    l.addLast(new UInt8Item((char) 30));
0854:                    // create a CIDCount key
0855:                    l.addLast(new DictNumberItem(nglyphs));
0856:                    l.addLast(new UInt8Item((char) 12));
0857:                    l.addLast(new UInt8Item((char) 34));
0858:                    // What about UIDBase (12,35)? Don't know what is it.
0859:                    // I don't think we need FontName; the font I looked at didn't have it.
0860:                }
0861:
0862:                // create an FDArray key
0863:                l.addLast(fdarrayRef);
0864:                l.addLast(new UInt8Item((char) 12));
0865:                l.addLast(new UInt8Item((char) 36));
0866:                // create an FDSelect key
0867:                l.addLast(fdselectRef);
0868:                l.addLast(new UInt8Item((char) 12));
0869:                l.addLast(new UInt8Item((char) 37));
0870:                // create an charset key
0871:                l.addLast(charsetRef);
0872:                l.addLast(new UInt8Item((char) 15));
0873:                // create a CharStrings key
0874:                l.addLast(charstringsRef);
0875:                l.addLast(new UInt8Item((char) 17));
0876:
0877:                seek(topdictOffsets[j]);
0878:                while (getPosition() < topdictOffsets[j + 1]) {
0879:                    int p1 = getPosition();
0880:                    getDictItem();
0881:                    int p2 = getPosition();
0882:                    if (key == "Encoding" || key == "Private"
0883:                            || key == "FDSelect" || key == "FDArray"
0884:                            || key == "charset" || key == "CharStrings") {
0885:                        // just drop them
0886:                    } else {
0887:                        l.add(new RangeItem(buf, p1, p2 - p1));
0888:                    }
0889:                }
0890:
0891:                l.addLast(new IndexMarkerItem(topdictIndex1Ref, topdictBase));
0892:
0893:                // Copy the string index and append new strings.
0894:                // We need 3 more strings: Registry, Ordering, and a FontName for one FD.
0895:                // The total length is at most "Adobe"+"Identity"+63 = 76
0896:
0897:                if (fonts[j].isCID) {
0898:                    l.addLast(getEntireIndexRange(stringIndexOffset));
0899:                } else {
0900:                    String fdFontName = fonts[j].name + "-OneRange";
0901:                    if (fdFontName.length() > 127)
0902:                        fdFontName = fdFontName.substring(0, 127);
0903:                    String extraStrings = "Adobe" + "Identity" + fdFontName;
0904:
0905:                    int origStringsLen = stringOffsets[stringOffsets.length - 1]
0906:                            - stringOffsets[0];
0907:                    int stringsBaseOffset = stringOffsets[0] - 1;
0908:
0909:                    byte stringsIndexOffSize;
0910:                    if (origStringsLen + extraStrings.length() <= 0xff)
0911:                        stringsIndexOffSize = 1;
0912:                    else if (origStringsLen + extraStrings.length() <= 0xffff)
0913:                        stringsIndexOffSize = 2;
0914:                    else if (origStringsLen + extraStrings.length() <= 0xffffff)
0915:                        stringsIndexOffSize = 3;
0916:                    else
0917:                        stringsIndexOffSize = 4;
0918:
0919:                    l.addLast(new UInt16Item(
0920:                            (char) ((stringOffsets.length - 1) + 3))); // count
0921:                    l.addLast(new UInt8Item((char) stringsIndexOffSize)); // offSize
0922:                    for (int i = 0; i < stringOffsets.length; i++)
0923:                        l.addLast(new IndexOffsetItem(stringsIndexOffSize,
0924:                                stringOffsets[i] - stringsBaseOffset));
0925:                    int currentStringsOffset = stringOffsets[stringOffsets.length - 1]
0926:                            - stringsBaseOffset;
0927:                    //l.addLast(new IndexOffsetItem(stringsIndexOffSize,currentStringsOffset));
0928:                    currentStringsOffset += ("Adobe").length();
0929:                    l.addLast(new IndexOffsetItem(stringsIndexOffSize,
0930:                            currentStringsOffset));
0931:                    currentStringsOffset += ("Identity").length();
0932:                    l.addLast(new IndexOffsetItem(stringsIndexOffSize,
0933:                            currentStringsOffset));
0934:                    currentStringsOffset += fdFontName.length();
0935:                    l.addLast(new IndexOffsetItem(stringsIndexOffSize,
0936:                            currentStringsOffset));
0937:
0938:                    l.addLast(new RangeItem(buf, stringOffsets[0],
0939:                            origStringsLen));
0940:                    l.addLast(new StringItem(extraStrings));
0941:                }
0942:
0943:                // copy the global subroutine index
0944:
0945:                l.addLast(getEntireIndexRange(gsubrIndexOffset));
0946:
0947:                // deal with fdarray, fdselect, and the font descriptors
0948:
0949:                if (fonts[j].isCID) {
0950:                    // copy the FDArray, FDSelect, charset
0951:                } else {
0952:                    // create FDSelect
0953:                    l.addLast(new MarkerItem(fdselectRef));
0954:                    l.addLast(new UInt8Item((char) 3)); // format identifier
0955:                    l.addLast(new UInt16Item((char) 1)); // nRanges
0956:
0957:                    l.addLast(new UInt16Item((char) 0)); // Range[0].firstGlyph
0958:                    l.addLast(new UInt8Item((char) 0)); // Range[0].fd
0959:
0960:                    l.addLast(new UInt16Item((char) nglyphs)); // sentinel
0961:
0962:                    // recreate a new charset
0963:                    // This format is suitable only for fonts without subsetting
0964:
0965:                    l.addLast(new MarkerItem(charsetRef));
0966:                    l.addLast(new UInt8Item((char) 2)); // format identifier
0967:
0968:                    l.addLast(new UInt16Item((char) 1)); // first glyph in range (ignore .notdef)
0969:                    l.addLast(new UInt16Item((char) (nglyphs - 1))); // nLeft
0970:                    // now all are covered, the data structure is complete.
0971:
0972:                    // create a font dict index (fdarray)
0973:
0974:                    l.addLast(new MarkerItem(fdarrayRef));
0975:                    l.addLast(new UInt16Item((char) 1));
0976:                    l.addLast(new UInt8Item((char) 1)); // offSize
0977:                    l.addLast(new UInt8Item((char) 1)); // first offset
0978:
0979:                    OffsetItem privateIndex1Ref = new IndexOffsetItem(1);
0980:                    l.addLast(privateIndex1Ref);
0981:                    IndexBaseItem privateBase = new IndexBaseItem();
0982:                    l.addLast(privateBase);
0983:
0984:                    // looking at the PS that acrobat generates from a PDF with
0985:                    // a CFF opentype font embeded with an identity-H encoding,
0986:                    // it seems that it does not need a FontName.
0987:                    //l.addLast(new DictNumberItem((standardStrings.length+(stringOffsets.length-1)+2)));
0988:                    //l.addLast(new UInt8Item((char)12));
0989:                    //l.addLast(new UInt8Item((char)38)); // FontName
0990:
0991:                    l.addLast(new DictNumberItem(fonts[j].privateLength));
0992:                    OffsetItem privateRef = new DictOffsetItem();
0993:                    l.addLast(privateRef);
0994:                    l.addLast(new UInt8Item((char) 18)); // Private
0995:
0996:                    l
0997:                            .addLast(new IndexMarkerItem(privateIndex1Ref,
0998:                                    privateBase));
0999:
1000:                    // copy the private index & local subroutines
1001:
1002:                    l.addLast(new MarkerItem(privateRef));
1003:                    // copy the private dict and the local subroutines.
1004:                    // the length of the private dict seems to NOT include
1005:                    // the local subroutines.
1006:                    l.addLast(new RangeItem(buf, fonts[j].privateOffset,
1007:                            fonts[j].privateLength));
1008:                    if (fonts[j].privateSubrs >= 0) {
1009:                        //System.err.println("has subrs="+fonts[j].privateSubrs+" ,len="+fonts[j].privateLength);
1010:                        l.addLast(getEntireIndexRange(fonts[j].privateSubrs));
1011:                    }
1012:                }
1013:
1014:                // copy the charstring index
1015:
1016:                l.addLast(new MarkerItem(charstringsRef));
1017:                l.addLast(getEntireIndexRange(fonts[j].charstringsOffset));
1018:
1019:                // now create the new CFF font
1020:
1021:                int[] currentOffset = new int[1];
1022:                currentOffset[0] = 0;
1023:
1024:                Iterator listIter = l.iterator();
1025:                while (listIter.hasNext()) {
1026:                    Item item = (Item) listIter.next();
1027:                    item.increment(currentOffset);
1028:                }
1029:
1030:                listIter = l.iterator();
1031:                while (listIter.hasNext()) {
1032:                    Item item = (Item) listIter.next();
1033:                    item.xref();
1034:                }
1035:
1036:                int size = currentOffset[0];
1037:                byte[] b = new byte[size];
1038:
1039:                listIter = l.iterator();
1040:                while (listIter.hasNext()) {
1041:                    Item item = (Item) listIter.next();
1042:                    item.emit(b);
1043:                }
1044:
1045:                return b;
1046:            }
1047:
1048:            public boolean isCID(String fontName) {
1049:                int j;
1050:                for (j = 0; j < fonts.length; j++)
1051:                    if (fontName.equals(fonts[j].name))
1052:                        return fonts[j].isCID;
1053:                return false;
1054:            }
1055:
1056:            public boolean exists(String fontName) {
1057:                int j;
1058:                for (j = 0; j < fonts.length; j++)
1059:                    if (fontName.equals(fonts[j].name))
1060:                        return true;
1061:                return false;
1062:            }
1063:
1064:            public String[] getNames() {
1065:                String[] names = new String[fonts.length];
1066:                for (int i = 0; i < fonts.length; i++)
1067:                    names[i] = fonts[i].name;
1068:                return names;
1069:            }
1070:
1071:            /**
1072:             * A random Access File or an array
1073:             */
1074:            protected RandomAccessFileOrArray buf;
1075:            private int offSize;
1076:
1077:            protected int nameIndexOffset;
1078:            protected int topdictIndexOffset;
1079:            protected int stringIndexOffset;
1080:            protected int gsubrIndexOffset;
1081:            protected int[] nameOffsets;
1082:            protected int[] topdictOffsets;
1083:            protected int[] stringOffsets;
1084:            protected int[] gsubrOffsets;
1085:
1086:            /**
1087:             * TODO Changed from private to protected by Ygal&Oren
1088:             */
1089:            protected final class Font {
1090:                public String name;
1091:                public String fullName;
1092:                public boolean isCID = false;
1093:                public int privateOffset = -1; // only if not CID
1094:                public int privateLength = -1; // only if not CID
1095:                public int privateSubrs = -1;
1096:                public int charstringsOffset = -1;
1097:                public int encodingOffset = -1;
1098:                public int charsetOffset = -1;
1099:                public int fdarrayOffset = -1; // only if CID
1100:                public int fdselectOffset = -1; // only if CID
1101:                public int[] fdprivateOffsets;
1102:                public int[] fdprivateLengths;
1103:                public int[] fdprivateSubrs;
1104:
1105:                // Added by Oren & Ygal
1106:                public int nglyphs;
1107:                public int nstrings;
1108:                public int CharsetLength;
1109:                public int[] charstringsOffsets;
1110:                public int[] charset;
1111:                public int[] FDSelect;
1112:                public int FDSelectLength;
1113:                public int FDSelectFormat;
1114:                public int CharstringType = 2;
1115:                public int FDArrayCount;
1116:                public int FDArrayOffsize;
1117:                public int[] FDArrayOffsets;
1118:                public int[] PrivateSubrsOffset;
1119:                public int[][] PrivateSubrsOffsetsArray;
1120:                public int[] SubrsOffsets;
1121:            }
1122:
1123:            // Changed from private to protected by Ygal&Oren
1124:            protected Font[] fonts;
1125:
1126:            public CFFFont(RandomAccessFileOrArray inputbuffer) {
1127:
1128:                //System.err.println("CFF: nStdString = "+standardStrings.length);
1129:                buf = inputbuffer;
1130:                seek(0);
1131:
1132:                int major, minor;
1133:                major = getCard8();
1134:                minor = getCard8();
1135:
1136:                //System.err.println("CFF Major-Minor = "+major+"-"+minor);
1137:
1138:                int hdrSize = getCard8();
1139:
1140:                offSize = getCard8();
1141:
1142:                //System.err.println("offSize = "+offSize);
1143:
1144:                //int count, indexOffSize, indexOffset, nextOffset;
1145:
1146:                nameIndexOffset = hdrSize;
1147:                nameOffsets = getIndex(nameIndexOffset);
1148:                topdictIndexOffset = nameOffsets[nameOffsets.length - 1];
1149:                topdictOffsets = getIndex(topdictIndexOffset);
1150:                stringIndexOffset = topdictOffsets[topdictOffsets.length - 1];
1151:                stringOffsets = getIndex(stringIndexOffset);
1152:                gsubrIndexOffset = stringOffsets[stringOffsets.length - 1];
1153:                gsubrOffsets = getIndex(gsubrIndexOffset);
1154:
1155:                fonts = new Font[nameOffsets.length - 1];
1156:
1157:                // now get the name index
1158:
1159:                /*
1160:                names             = new String[nfonts];
1161:                privateOffset     = new int[nfonts];
1162:                charsetOffset     = new int[nfonts];
1163:                encodingOffset    = new int[nfonts];
1164:                charstringsOffset = new int[nfonts];
1165:                fdarrayOffset     = new int[nfonts];
1166:                fdselectOffset    = new int[nfonts];
1167:                 */
1168:
1169:                for (int j = 0; j < nameOffsets.length - 1; j++) {
1170:                    fonts[j] = new Font();
1171:                    seek(nameOffsets[j]);
1172:                    fonts[j].name = "";
1173:                    for (int k = nameOffsets[j]; k < nameOffsets[j + 1]; k++) {
1174:                        fonts[j].name += (char) getCard8();
1175:                    }
1176:                    //System.err.println("name["+j+"]=<"+fonts[j].name+">");
1177:                }
1178:
1179:                // string index
1180:
1181:                //strings = new String[stringOffsets.length-1];
1182:                /*
1183:                System.err.println("std strings = "+standardStrings.length);
1184:                System.err.println("fnt strings = "+(stringOffsets.length-1));
1185:                for (char j=0; j<standardStrings.length+(stringOffsets.length-1); j++) {
1186:                    //seek(stringOffsets[j]);
1187:                    //strings[j] = "";
1188:                    //for (int k=stringOffsets[j]; k<stringOffsets[j+1]; k++) {
1189:                    //	strings[j] += (char)getCard8();
1190:                    //}
1191:                    System.err.println("j="+(int)j+" <? "+(standardStrings.length+(stringOffsets.length-1)));
1192:                    System.err.println("strings["+(int)j+"]=<"+getString(j)+">");
1193:                }
1194:                 */
1195:
1196:                // top dict
1197:                for (int j = 0; j < topdictOffsets.length - 1; j++) {
1198:                    seek(topdictOffsets[j]);
1199:                    while (getPosition() < topdictOffsets[j + 1]) {
1200:                        getDictItem();
1201:                        if (key == "FullName") {
1202:                            //System.err.println("getting fullname sid = "+((Integer)args[0]).intValue());
1203:                            fonts[j].fullName = getString((char) ((Integer) args[0])
1204:                                    .intValue());
1205:                            //System.err.println("got it");
1206:                        } else if (key == "ROS")
1207:                            fonts[j].isCID = true;
1208:                        else if (key == "Private") {
1209:                            fonts[j].privateLength = ((Integer) args[0])
1210:                                    .intValue();
1211:                            fonts[j].privateOffset = ((Integer) args[1])
1212:                                    .intValue();
1213:                        } else if (key == "charset") {
1214:                            fonts[j].charsetOffset = ((Integer) args[0])
1215:                                    .intValue();
1216:
1217:                        } else if (key == "Encoding") {
1218:                            fonts[j].encodingOffset = ((Integer) args[0])
1219:                                    .intValue();
1220:                            ReadEncoding(fonts[j].encodingOffset);
1221:                        } else if (key == "CharStrings") {
1222:                            fonts[j].charstringsOffset = ((Integer) args[0])
1223:                                    .intValue();
1224:                            //System.err.println("charstrings "+fonts[j].charstringsOffset);
1225:                            // Added by Oren & Ygal
1226:                            int p = getPosition();
1227:                            fonts[j].charstringsOffsets = getIndex(fonts[j].charstringsOffset);
1228:                            seek(p);
1229:                        } else if (key == "FDArray")
1230:                            fonts[j].fdarrayOffset = ((Integer) args[0])
1231:                                    .intValue();
1232:                        else if (key == "FDSelect")
1233:                            fonts[j].fdselectOffset = ((Integer) args[0])
1234:                                    .intValue();
1235:                        else if (key == "CharstringType")
1236:                            fonts[j].CharstringType = ((Integer) args[0])
1237:                                    .intValue();
1238:                    }
1239:
1240:                    // private dict
1241:                    if (fonts[j].privateOffset >= 0) {
1242:                        //System.err.println("PRIVATE::");
1243:                        seek(fonts[j].privateOffset);
1244:                        while (getPosition() < fonts[j].privateOffset
1245:                                + fonts[j].privateLength) {
1246:                            getDictItem();
1247:                            if (key == "Subrs")
1248:                                //Add the private offset to the lsubrs since the offset is 
1249:                                // relative to the begining of the PrivateDict
1250:                                fonts[j].privateSubrs = ((Integer) args[0])
1251:                                        .intValue()
1252:                                        + fonts[j].privateOffset;
1253:                        }
1254:                    }
1255:
1256:                    // fdarray index
1257:                    if (fonts[j].fdarrayOffset >= 0) {
1258:                        int[] fdarrayOffsets = getIndex(fonts[j].fdarrayOffset);
1259:
1260:                        fonts[j].fdprivateOffsets = new int[fdarrayOffsets.length - 1];
1261:                        fonts[j].fdprivateLengths = new int[fdarrayOffsets.length - 1];
1262:
1263:                        //System.err.println("FD Font::");
1264:
1265:                        for (int k = 0; k < fdarrayOffsets.length - 1; k++) {
1266:                            seek(fdarrayOffsets[k]);
1267:                            while (getPosition() < fdarrayOffsets[k + 1])
1268:                                getDictItem();
1269:                            if (key == "Private") {
1270:                                fonts[j].fdprivateLengths[k] = ((Integer) args[0])
1271:                                        .intValue();
1272:                                fonts[j].fdprivateOffsets[k] = ((Integer) args[1])
1273:                                        .intValue();
1274:                            }
1275:
1276:                        }
1277:                    }
1278:                }
1279:                //System.err.println("CFF: done");
1280:            }
1281:
1282:            // ADDED BY Oren & Ygal
1283:
1284:            void ReadEncoding(int nextIndexOffset) {
1285:                int format;
1286:                seek(nextIndexOffset);
1287:                format = getCard8();
1288:            }
1289:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.