View | Details | Raw Unified | Return to bug 5335
Collapse All | Expand All

(-)java/org/apache/fop/fonts/CIDFont.java (-3 / +12 lines)
Lines 1-12 Link Here
1
/*
1
/*
2
 * Copyright 1999-2004 The Apache Software Foundation.
2
 * Copyright 1999-2004 The Apache Software Foundation.
3
 * 
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
6
 * You may obtain a copy of the License at
7
 * 
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 * 
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Lines 37-42 Link Here
37
    public Map usedGlyphsIndex = new java.util.HashMap();
37
    public Map usedGlyphsIndex = new java.util.HashMap();
38
    public int usedGlyphsCount = 0;
38
    public int usedGlyphsCount = 0;
39
39
40
    /**
41
     * usedCharsIndex contains new glyph, original char
42
     */
43
    public Map usedCharsIndex = new java.util.HashMap();
44
40
    //private PDFWArray warray = new PDFWArray();
45
    //private PDFWArray warray = new PDFWArray();
41
    public int width[] = null;
46
    public int width[] = null;
42
47
Lines 90-93 Link Here
90
        return true;
95
        return true;
91
    }
96
    }
92
97
98
    /**
99
     * Returns char[] array .
100
     */
101
    public abstract char[] getCharsUsed();
93
}
102
}
(-)java/org/apache/fop/fonts/MultiByteFont.java (-6 / +29 lines)
Lines 1-12 Link Here
1
/*
1
/*
2
 * Copyright 1999-2004 The Apache Software Foundation.
2
 * Copyright 1999-2004 The Apache Software Foundation.
3
 * 
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
6
 * You may obtain a copy of the License at
7
 * 
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 * 
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Lines 125-131 Link Here
125
     * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable()
125
     * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable()
126
     */
126
     */
127
    public boolean isEmbeddable() {
127
    public boolean isEmbeddable() {
128
        return !(getEmbedFileName() == null && embedResourceName == null); 
128
        return !(getEmbedFileName() == null && embedResourceName == null);
129
    }
129
    }
130
130
131
    /**
131
    /**
Lines 198-205 Link Here
198
        for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
198
        for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) {
199
            if (bfentries[i].getUnicodeStart() <= idx
199
            if (bfentries[i].getUnicodeStart() <= idx
200
                    && bfentries[i].getUnicodeEnd() >= idx) {
200
                    && bfentries[i].getUnicodeEnd() >= idx) {
201
                        
201
202
                retIdx = bfentries[i].getGlyphStartIndex() 
202
                retIdx = bfentries[i].getGlyphStartIndex()
203
                    + idx
203
                    + idx
204
                    - bfentries[i].getUnicodeStart();
204
                    - bfentries[i].getUnicodeStart();
205
            }
205
            }
Lines 222-227 Link Here
222
                               new Integer(usedGlyphsCount));
222
                               new Integer(usedGlyphsCount));
223
                usedGlyphsIndex.put(new Integer(usedGlyphsCount),
223
                usedGlyphsIndex.put(new Integer(usedGlyphsCount),
224
                                    new Integer(retIdx));
224
                                    new Integer(retIdx));
225
                usedCharsIndex.put(new Integer(usedGlyphsCount),
226
                                    new Integer((int) c));
225
                retIdx = usedGlyphsCount;
227
                retIdx = usedGlyphsCount;
226
                usedGlyphsCount++;
228
                usedGlyphsCount++;
227
            } else {
229
            } else {
Lines 299-303 Link Here
299
        return usedGlyphs;
301
        return usedGlyphs;
300
    }
302
    }
301
303
304
    /** The invalid Unicode character, suitable as a return value in methods
305
     * that need to return an invalid character. */
306
    public static final char INVALID_UNICODE_CHAR = 0xFFFF;
307
308
    public char[] getCharsUsed() {
309
        if (! isEmbeddable()) {
310
            return null;
311
        }
312
        char[] charArray = new char[usedGlyphsCount];
313
        for (int i = 0; i < usedGlyphsCount; i++) {
314
            Integer mapValue = (Integer)usedCharsIndex.get(new Integer(i));
315
            if(mapValue != null) {
316
                char arrayItem = (char) mapValue.intValue();
317
                charArray[i] = arrayItem;
318
            }
319
            else {
320
                charArray[i] = INVALID_UNICODE_CHAR;
321
            }
322
        }
323
        return charArray;
324
    }
302
}
325
}
303
326
(-)java/org/apache/fop/fonts/SingleByteFont.java (-4 / +7 lines)
Lines 1-12 Link Here
1
/*
1
/*
2
 * Copyright 1999-2004 The Apache Software Foundation.
2
 * Copyright 1999-2004 The Apache Software Foundation.
3
 * 
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
6
 * You may obtain a copy of the License at
7
 * 
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 * 
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Lines 77-83 Link Here
77
            return '#';
77
            return '#';
78
        }
78
        }
79
    }
79
    }
80
    
80
81
    /**
81
    /**
82
     * @see org.apache.fop.fonts.Typeface#hasChar(char)
82
     * @see org.apache.fop.fonts.Typeface#hasChar(char)
83
     */
83
     */
Lines 99-103 Link Here
99
        this.width[index] = width;
99
        this.width[index] = width;
100
    }
100
    }
101
101
102
    public char[] getCharsUsed() {
103
        return null;
104
    }
102
}
105
}
103
106
(-)java/org/apache/fop/pdf/PDFCMap.java (-10 / +56 lines)
Lines 1-12 Link Here
1
/*
1
/*
2
 * Copyright 1999-2004 The Apache Software Foundation.
2
 * Copyright 1999-2004 The Apache Software Foundation.
3
 * 
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
6
 * You may obtain a copy of the License at
7
 * 
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 * 
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Lines 15-23 Link Here
15
 */
15
 */
16
16
17
/* $Id$ */
17
/* $Id$ */
18
 
18
19
package org.apache.fop.pdf;
19
package org.apache.fop.pdf;
20
20
21
// Java
22
import java.io.IOException;
23
import java.io.OutputStream;
24
21
/**
25
/**
22
 * Class representing the CMap encodings.
26
 * Class representing the CMap encodings.
23
 *
27
 *
Lines 423-475 Link Here
423
     * @param p the string buffer to add the pdf data to
427
     * @param p the string buffer to add the pdf data to
424
     */
428
     */
425
    public void fillInPDF(StringBuffer p) {
429
    public void fillInPDF(StringBuffer p) {
430
        writePreStream(p);
431
        writeStreamComments(p);
432
        writeCIDInit(p);
433
        writeCIDSystemInfo(p);
434
        writeVersionTypeName(p);
435
        writeCodeSpaceRange(p);
436
        writeCIDRange(p);
437
        writeBFEntries(p);
438
        writeWrapUp(p);
439
        writeStreamAfterComments(p);
440
        writeUseCMap(p);
441
        add(p.toString());
442
    }
443
444
    protected void writePreStream(StringBuffer p) {
426
        // p.append("/Type /CMap\n");
445
        // p.append("/Type /CMap\n");
427
        // p.append(sysInfo.toPDFString());
446
        // p.append(sysInfo.toPDFString());
428
        // p.append("/CMapName /" + name);
447
        // p.append("/CMapName /" + name + EOL);
429
        // p.append("\n");
448
    }
449
450
    protected void writeStreamComments(StringBuffer p) {
430
        p.append("%!PS-Adobe-3.0 Resource-CMap\n");
451
        p.append("%!PS-Adobe-3.0 Resource-CMap\n");
431
        p.append("%%DocumentNeededResources: ProcSet (CIDInit)\n");
452
        p.append("%%DocumentNeededResources: ProcSet (CIDInit)\n");
432
        p.append("%%IncludeResource: ProcSet (CIDInit)\n");
453
        p.append("%%IncludeResource: ProcSet (CIDInit)\n");
433
        p.append("%%BeginResource: CMap (" + name + ")\n");
454
        p.append("%%BeginResource: CMap (" + name + ")\n");
434
        p.append("%%EndComments\n");
455
        p.append("%%EndComments\n");
456
    }
435
457
458
    protected void writeCIDInit(StringBuffer p) {
436
        p.append("/CIDInit /ProcSet findresource begin\n");
459
        p.append("/CIDInit /ProcSet findresource begin\n");
437
        p.append("12 dict begin\n");
460
        p.append("12 dict begin\n");
438
        p.append("begincmap\n");
461
        p.append("begincmap\n");
462
    }
439
463
464
    protected void writeCIDSystemInfo(StringBuffer p) {
440
        p.append("/CIDSystemInfo 3 dict dup begin\n");
465
        p.append("/CIDSystemInfo 3 dict dup begin\n");
441
        p.append("  /Registry (Adobe) def\n");
466
        p.append("  /Registry (Adobe) def\n");
442
        p.append("  /Ordering (Identity) def\n");
467
        p.append("  /Ordering (Identity) def\n");
443
        p.append("  /Supplement 0 def\n");
468
        p.append("  /Supplement 0 def\n");
444
        p.append("end def\n");
469
        p.append("end def\n");
470
    }
445
471
472
    protected void writeVersionTypeName(StringBuffer p) {
446
        p.append("/CMapVersion 1 def\n");
473
        p.append("/CMapVersion 1 def\n");
447
        p.append("/CMapType 1 def\n");
474
        p.append("/CMapType 1 def\n");
448
        p.append("/CMapName /" + name + " def\n");
475
        p.append("/CMapName /" + name + " def\n");
476
    }
449
477
478
    protected void writeCodeSpaceRange(StringBuffer p) {
450
        p.append("1 begincodespacerange\n");
479
        p.append("1 begincodespacerange\n");
451
        p.append("<0000> <FFFF>\n");
480
        p.append("<0000> <FFFF>\n");
452
        p.append("endcodespacerange\n");
481
        p.append("endcodespacerange\n");
482
    }
483
484
    protected void writeCIDRange(StringBuffer p) {
453
        p.append("1 begincidrange\n");
485
        p.append("1 begincidrange\n");
454
        p.append("<0000> <FFFF> 0\n");
486
        p.append("<0000> <FFFF> 0\n");
455
        p.append("endcidrange\n");
487
        p.append("endcidrange\n");
488
    }
456
489
490
    protected void writeBFEntries(StringBuffer p) {
457
        // p.append("1 beginbfrange\n");
491
        // p.append("1 beginbfrange\n");
458
        // p.append("<0020> <0100> <0000>\n");
492
        // p.append("<0020> <0100> <0000>\n");
459
        // p.append("endbfrange\n");
493
        // p.append("endbfrange\n");
494
    }
460
495
496
    protected void writeWrapUp(StringBuffer p) {
461
        p.append("endcmap\n");
497
        p.append("endcmap\n");
462
        p.append("CMapName currentdict /CMap defineresource pop\n");
498
        p.append("CMapName currentdict /CMap defineresource pop\n");
463
        p.append("end\n");
499
        p.append("end\n");
464
        p.append("end\n");
500
        p.append("end\n");
501
    }
502
503
    protected void writeStreamAfterComments(StringBuffer p) {
465
        p.append("%%EndResource\n");
504
        p.append("%%EndResource\n");
466
        p.append("%%EOF\n");
505
        p.append("%%EOF\n");
506
    }
507
508
    protected void writeUseCMap(StringBuffer p) {
467
        /*
509
        /*
468
         * p.append(" /Type /CMap\n/CMapName /" + name);
510
         * p.append(" /Type /CMap");
469
         * p.append("\n");
511
         * p.append("/CMapName /" + name + EOL);
470
         * p.append("\n/WMode "); p.append(wMode);
512
         * p.append("/WMode " + wMode + EOL);
471
         * if (base != null) {
513
         * if (base != null) {
472
         * p.append("\n/UseCMap ");
514
         *     p.append("/UseCMap ");
473
         * if (base instanceof String) {
515
         * if (base instanceof String) {
474
         * p.append("/"+base);
516
         * p.append("/"+base);
475
         * } else {// base instanceof PDFStream
517
         * } else {// base instanceof PDFStream
Lines 479-482 Link Here
479
         */
521
         */
480
    }
522
    }
481
523
524
    protected int output(OutputStream stream) throws IOException {
525
        fillInPDF(new StringBuffer());
526
        return super.output(stream);
527
    }
482
}
528
}
(-)java/org/apache/fop/pdf/PDFFactory.java (-4 / +12 lines)
Lines 1-12 Link Here
1
/*
1
/*
2
 * Copyright 1999-2005 The Apache Software Foundation.
2
 * Copyright 1999-2005 The Apache Software Foundation.
3
 * 
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
6
 * You may obtain a copy of the License at
7
 * 
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 * 
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Lines 43-48 Link Here
43
import org.apache.fop.fonts.truetype.TTFSubSetFile;
43
import org.apache.fop.fonts.truetype.TTFSubSetFile;
44
import org.apache.fop.fonts.type1.PFBData;
44
import org.apache.fop.fonts.type1.PFBData;
45
import org.apache.fop.fonts.type1.PFBParser;
45
import org.apache.fop.fonts.type1.PFBParser;
46
import org.apache.fop.pdf.PDFCMap;
47
import org.apache.fop.pdf.PDFToUnicodeCMap;
46
48
47
/**
49
/**
48
 * This class provides method to create and register PDF objects.
50
 * This class provides method to create and register PDF objects.
Lines 918-924 Link Here
918
     * @return the new PDF outline object
920
     * @return the new PDF outline object
919
     */
921
     */
920
    public PDFOutline makeOutline(PDFOutline parent, String label,
922
    public PDFOutline makeOutline(PDFOutline parent, String label,
921
                                  String destination, float yoffset, 
923
                                  String destination, float yoffset,
922
                                  boolean showSubItems) {
924
                                  boolean showSubItems) {
923
925
924
        String goToRef = getGoToReference(destination, yoffset);
926
        String goToRef = getGoToReference(destination, yoffset);
Lines 1021-1026 Link Here
1021
                                   (PDFCIDFontDescriptor)pdfdesc);
1023
                                   (PDFCIDFontDescriptor)pdfdesc);
1022
                getDocument().registerObject(cidFont);
1024
                getDocument().registerObject(cidFont);
1023
1025
1026
                PDFCMap cmap = new PDFToUnicodeCMap(cidMetrics, "fop-ucs-H",
1027
                    new PDFCIDSystemInfo("Adobe",
1028
                        "Identity",
1029
                        0));
1030
                getDocument().registerObject(cmap);
1031
                ((PDFFontType0)font).setCMAP(cmap);
1024
                ((PDFFontType0)font).setDescendantFonts(cidFont);
1032
                ((PDFFontType0)font).setDescendantFonts(cidFont);
1025
            } else {
1033
            } else {
1026
                int firstChar = 0;
1034
                int firstChar = 0;
(-)java/org/apache/fop/pdf/PDFToUnicodeCMap.java (+322 lines)
Line 0 Link Here
1
/*
2
 * $Id: PDFToUnicodeCMap.java,v 1.3.2.1 2005/12/01 12:00:00 ono Exp $
3
 * ============================================================================
4
 *                    The Apache Software License, Version 1.1
5
 * ============================================================================
6
 *
7
 * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without modifica-
10
 * tion, are permitted provided that the following conditions are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright notice,
13
 *    this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright notice,
16
 *    this list of conditions and the following disclaimer in the documentation
17
 *    and/or other materials provided with the distribution.
18
 *
19
 * 3. The end-user documentation included with the redistribution, if any, must
20
 *    include the following acknowledgment: "This product includes software
21
 *    developed by the Apache Software Foundation (http://www.apache.org/)."
22
 *    Alternately, this acknowledgment may appear in the software itself, if
23
 *    and wherever such third-party acknowledgments normally appear.
24
 *
25
 * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26
 *    endorse or promote products derived from this software without prior
27
 *    written permission. For written permission, please contact
28
 *    apache@apache.org.
29
 *
30
 * 5. Products derived from this software may not be called "Apache", nor may
31
 *    "Apache" appear in their name, without prior written permission of the
32
 *    Apache Software Foundation.
33
 *
34
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37
 * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39
 * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44
 * ============================================================================
45
 *
46
 * This software consists of voluntary contributions made by many individuals
47
 * on behalf of the Apache Software Foundation and was originally created by
48
 * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49
 * Software Foundation, please see <http://www.apache.org/>.
50
 */
51
package org.apache.fop.pdf;
52
53
/**
54
 * Class representing ToUnicode CMaps.
55
 * Here are some documentation resources:
56
 * <ul>
57
 * <li>PDF Reference, Second Edition, Section 5.6.4, for general information
58
 * about CMaps in PDF Files.</li>
59
 * <li>PDF Reference, Second Edition, Section 5.9, for specific information
60
 * about ToUnicodeCMaps in PDF Files.</li>
61
 * <li>
62
 * <a href="http://partners.adobe.com/asn/developer/pdfs/tn/5411.ToUnicode.pdf">
63
 * Adobe Technical Note #5411, "ToUnicode Mapping File Tutorial"</a>.
64
 * </ul>
65
 */
66
import org.apache.fop.fonts.CIDFont;
67
68
public class PDFToUnicodeCMap extends PDFCMap {
69
70
    /**
71
     * handle to read font
72
     */
73
    protected CIDFont cidFont;
74
75
    /**
76
     * Constructor.
77
     *
78
     * @param name One of the registered names found in Table 5.14 in PDF
79
     * Reference, Second Edition.
80
     * @param sysInfo The attributes of the character collection of the CIDFont.
81
     */
82
    public PDFToUnicodeCMap(CIDFont cidMetrics, String name, PDFCIDSystemInfo sysInfo) {
83
        super(name, sysInfo);
84
        cidFont = cidMetrics;
85
    }
86
87
    public void fillInPDF(StringBuffer p) {
88
        writeCIDInit(p);
89
        writeCIDSystemInfo(p);
90
        writeVersionTypeName(p);
91
        writeCodeSpaceRange(p);
92
        writeBFEntries(p);
93
        writeWrapUp(p);
94
        add(p.toString());
95
    }
96
97
    protected void writeCIDSystemInfo(StringBuffer p) {
98
        p.append("/CIDSystemInfo\n");
99
        p.append("<< /Registry (Adobe)\n");
100
        p.append("/Ordering (UCS)\n");
101
        p.append("/Supplement 0\n");
102
        p.append(">> def\n");
103
    }
104
105
    protected void writeVersionTypeName(StringBuffer p) {
106
        p.append("/CMapName /Adobe-Identity-UCS def\n");
107
        p.append("/CMapType 2 def\n");
108
    }
109
110
    /**
111
     * Writes the character mappings for this font.
112
     */
113
    protected void writeBFEntries(StringBuffer p) {
114
        if(cidFont == null) return;
115
116
        char[] charArray = cidFont.getCharsUsed();
117
118
        if(charArray != null) {
119
            writeBFCharEntries(p, charArray);
120
            writeBFRangeEntries(p, charArray);
121
        }
122
    }
123
124
    protected void writeBFCharEntries(StringBuffer p, char[] charArray) {
125
        int completedEntries = 0;
126
        int totalEntries = 0;
127
        for (int i = 0; i < charArray.length; i++) {
128
            if (! partOfRange(charArray, i)) {
129
                totalEntries ++;
130
            }
131
        }
132
        if (totalEntries < 1) {
133
            return;
134
        }
135
        int remainingEntries = totalEntries;
136
        /* Limited to 100 entries in each section */
137
        int entriesThisSection = Math.min(remainingEntries, 100);
138
        int remainingEntriesThisSection = entriesThisSection;
139
        p.append(entriesThisSection + " beginbfchar\n");
140
        for (int i = 0; i < charArray.length; i++) {
141
            if (partOfRange(charArray, i)) {
142
                continue;
143
            }
144
            p.append("<" + padHexString(Integer.toHexString(i), 4)
145
                    + "> ");
146
            p.append("<" + padHexString(Integer.toHexString(charArray[i]), 4)
147
                    + ">\n");
148
            /* Compute the statistics. */
149
            completedEntries ++;
150
            remainingEntries = totalEntries - completedEntries;
151
            remainingEntriesThisSection --;
152
            if (remainingEntriesThisSection < 1) {
153
                if (remainingEntries > 0) {
154
                    p.append("endbfchar\n");
155
                    entriesThisSection = Math.min(remainingEntries, 100);
156
                    remainingEntriesThisSection = entriesThisSection;
157
                    p.append(entriesThisSection + " beginbfchar\n");
158
                }
159
            }
160
        }
161
        p.append("endbfchar\n");
162
    }
163
164
    protected void writeBFRangeEntries(StringBuffer p, char[] charArray) {
165
        int completedEntries = 0;
166
        int totalEntries = 0;
167
        for (int i = 0; i < charArray.length; i++) {
168
            if (startOfRange(charArray, i)) {
169
                totalEntries ++;
170
            }
171
        }
172
        if (totalEntries < 1) {
173
            return;
174
        }
175
        int remainingEntries = totalEntries;
176
        int entriesThisSection = Math.min(remainingEntries, 100);
177
        int remainingEntriesThisSection = entriesThisSection;
178
        p.append(entriesThisSection + " beginbfrange\n");
179
        for (int i = 0; i < charArray.length; i++) {
180
            if (! startOfRange(charArray, i)) {
181
                continue;
182
            }
183
            p.append("<"
184
                    + padHexString(Integer.toHexString(i), 4)
185
                    + "> ");
186
            p.append("<"
187
                    + padHexString(Integer.toHexString
188
                            (endOfRange(charArray, i)), 4)
189
                    + "> ");
190
            p.append("<"
191
                    + padHexString(Integer.toHexString(charArray[i]), 4)
192
                    + ">\n");
193
            /* Compute the statistics. */
194
            completedEntries ++;
195
            remainingEntries = totalEntries - completedEntries;
196
            if (remainingEntriesThisSection < 1) {
197
                if (remainingEntries > 0) {
198
                    p.append("endbfrange\n");
199
                    entriesThisSection = Math.min(remainingEntries, 100);
200
                    remainingEntriesThisSection = entriesThisSection;
201
                    p.append(entriesThisSection + " beginbfrange\n");
202
                }
203
            }
204
        }
205
        p.append("endbfrange\n");
206
    }
207
208
    /**
209
     * Find the end of the current range.
210
     * @param charArray The array which is being tested.
211
     * @param startOfRange The index to the array element that is the start of
212
     * the range.
213
     * @return The index to the element that is the end of the range.
214
     */
215
    private int endOfRange(char[] charArray, int startOfRange) {
216
        int endOfRange = -1;
217
        for (int i = startOfRange; i < charArray.length - 1 && endOfRange < 0;
218
                i++) {
219
            if (! sameRangeEntryAsNext(charArray, i)) {
220
                endOfRange = i;
221
            }
222
        }
223
        return endOfRange;
224
    }
225
226
    /**
227
     * Determine whether this array element should be part of a bfchar entry or
228
     * a bfrange entry.
229
     * @param charArray The array to be tested.
230
     * @param arrayIndex The index to the array element to be tested.
231
     * @return True if this array element should be included in a range.
232
     */
233
    private boolean partOfRange(char[] charArray, int arrayIndex) {
234
        if (charArray.length < 2) {
235
            return false;
236
        }
237
        if (arrayIndex == 0) {
238
            return sameRangeEntryAsNext(charArray, 0);
239
        }
240
        if (arrayIndex == charArray.length - 1) {
241
            return sameRangeEntryAsNext(charArray, arrayIndex - 1);
242
        }
243
        if (sameRangeEntryAsNext(charArray, arrayIndex - 1)) {
244
            return true;
245
        }
246
        if (sameRangeEntryAsNext(charArray, arrayIndex)) {
247
            return true;
248
        }
249
        return false;
250
    }
251
252
    /**
253
     * Determine whether two bytes can be written in the same bfrange entry.
254
     * @param charArray The array to be tested.
255
     * @param firstItem The first of the two items in the array to be tested.
256
     * The second item is firstItem + 1.
257
     * @return True if both 1) the next item in the array is sequential with
258
     * this one, and 2) the first byte of the character in the first position
259
     * is equal to the first byte of the character in the second position.
260
     */
261
    private boolean sameRangeEntryAsNext(char[] charArray, int firstItem) {
262
        if (charArray[firstItem] + 1 != charArray[firstItem + 1]) {
263
            return false;
264
        }
265
        if (firstItem / 256 != (firstItem + 1) / 256) {
266
            return false;
267
        }
268
        return true;
269
    }
270
271
    /**
272
     * Determine whether this array element should be the start of a bfrange
273
     * entry.
274
     * @param charArray The array to be tested.
275
     * @param arrayIndex The index to the array element to be tested.
276
     * @return True if this array element is the beginning of a range.
277
     */
278
    private boolean startOfRange(char[] charArray, int arrayIndex) {
279
        // Can't be the start of a range if not part of a range.
280
        if (! partOfRange(charArray, arrayIndex)) {
281
            return false;
282
        }
283
        // If first element in the array, must be start of a range
284
        if (arrayIndex == 0) {
285
            return true;
286
        }
287
        // If last element in the array, cannot be start of a range
288
        if (arrayIndex == charArray.length - 1) {
289
            return false;
290
        }
291
        /*
292
         * If part of same range as the previous element is, cannot be start
293
         * of range.
294
         */
295
        if (sameRangeEntryAsNext(charArray, arrayIndex - 1)) {
296
            return false;
297
        }
298
        // Otherwise, this is start of a range.
299
        return true;
300
    }
301
302
    /**
303
     * Prepends the input string with a sufficient number of "0" characters to
304
     * get the returned string to be numChars length.
305
     * @param input The input string.
306
     * @param numChars The minimum characters in the output string.
307
     * @return The padded string.
308
     */
309
    public static String padHexString(String input, int numChars) {
310
        int length = input.length();
311
        if (length >= numChars) {
312
            return input;
313
        }
314
        StringBuffer returnString = new StringBuffer();
315
        for (int i = 1; i <= numChars - length; i++) {
316
            returnString.append("0");
317
        }
318
        returnString.append(input);
319
        return returnString.toString();
320
    }
321
322
}

Return to bug 5335