src/java.desktop/share/classes/sun/font/CMap.java
author srl
Mon, 25 Jun 2018 11:40:46 -0700
changeset 50840 1db5917dfe1c
parent 50348 008f416a79cb
child 51923 16a0f33a5052
permissions -rw-r--r--
8187100: Support Unicode Variation Selectors Summary: Support Unicode Variation Selectors Reviewed-by: prr, srl Contributed-by: Toshio Nakamura <toshiona@jp.ibm.com>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 16879
diff changeset
     2
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3928
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.font;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.nio.ByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.nio.CharBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.nio.IntBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.util.Locale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.nio.charset.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * A tt font has a CMAP table which is in turn made up of sub-tables which
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * describe the char to glyph mapping in (possibly) multiple ways.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * CMAP subtables are described by 3 values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * 1. Platform ID (eg 3=Microsoft, which is the id we look for in JDK)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * 2. Encoding (eg 0=symbol, 1=unicode)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * 3. TrueType subtable format (how the char->glyph mapping for the encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * is stored in the subtable). See the TrueType spec. Format 4 is required
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * by MS in fonts for windows. Its uses segmented mapping to delta values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * Most typically we see are (3,1,4) :
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * CMAP Platform ID=3 is what we use.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * Encodings that are used in practice by JDK on Solaris are
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *  symbol (3,0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *  unicode (3,1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *  GBK (3,5) (note that solaris zh fonts report 3,4 but are really 3,5)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * The format for almost all subtables is 4. However the solaris (3,5)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * encodings are typically in format 2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
abstract class CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
//     static char WingDings_b2c[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
//         0xfffd, 0xfffd, 0x2702, 0x2701, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
//         0xfffd, 0x2706, 0x2709, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2707, 0x270d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
//         0xfffd, 0x270c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
//         0xfffd, 0x2708, 0xfffd, 0xfffd, 0x2744, 0xfffd, 0x271e, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
//         0x2720, 0x2721, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
//         0xfffd, 0x2751, 0x2752, 0xfffd, 0xfffd, 0x2756, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
//         0xfffd, 0xfffd, 0xfffd, 0x2740, 0x273f, 0x275d, 0x275e, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
//         0xfffd, 0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, 0x2786,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
//         0x2787, 0x2788, 0x2789, 0xfffd, 0x278a, 0x278b, 0x278c, 0x278d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
//         0x278e, 0x278f, 0x2790, 0x2791, 0x2792, 0x2793, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x274d, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2736, 0x2734, 0xfffd, 0x2735,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x272a, 0x2730, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x27a5, 0xfffd, 0x27a6, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
//         0x27a2, 0xfffd, 0xfffd, 0xfffd, 0x27b3, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
//         0x27a1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
//         0x27a9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
//         0xfffd, 0xfffd, 0xfffd, 0x2717, 0x2713, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
//    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
//     static char Symbols_b2c[] = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
//         0xfffd, 0xfffd, 0x2200, 0xfffd, 0x2203, 0xfffd, 0xfffd, 0x220d,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
//         0xfffd, 0xfffd, 0x2217, 0xfffd, 0xfffd, 0x2212, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
//         0x2245, 0x0391, 0x0392, 0x03a7, 0x0394, 0x0395, 0x03a6, 0x0393,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
//         0x0397, 0x0399, 0x03d1, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
//         0x03a0, 0x0398, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03c2, 0x03a9,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
//         0x039e, 0x03a8, 0x0396, 0xfffd, 0x2234, 0xfffd, 0x22a5, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
//         0xfffd, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
//         0x03b7, 0x03b9, 0x03d5, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
//         0x03c0, 0x03b8, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03d6, 0x03c9,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
//         0x03be, 0x03c8, 0x03b6, 0xfffd, 0xfffd, 0xfffd, 0x223c, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
//         0xfffd, 0x03d2, 0xfffd, 0x2264, 0x2215, 0x221e, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
//         0x2218, 0xfffd, 0xfffd, 0x2265, 0xfffd, 0x221d, 0xfffd, 0x2219,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
//         0xfffd, 0x2260, 0x2261, 0x2248, 0x22ef, 0x2223, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2297, 0x2295, 0x2205, 0x2229,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
//         0x222a, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
//         0xfffd, 0x2207, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x221a, 0x22c5,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
//         0xfffd, 0x2227, 0x2228, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
//         0x22c4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2211, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
//         0xfffd, 0xfffd, 0x222b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
//     };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    static final short ShiftJISEncoding = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    static final short GBKEncoding      = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    static final short Big5Encoding     = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    static final short WansungEncoding  = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    static final short JohabEncoding    = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    static final short MSUnicodeSurrogateEncoding = 10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    static final char noSuchChar = (char)0xfffd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    static final int SHORTMASK = 0x0000ffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    static final int INTMASK   = 0xffffffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    static final char[][] converterMaps = new char[7][];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * Unicode->other encoding translation array. A pre-computed look up
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * which can be shared across all fonts using that encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     * Using this saves running character coverters repeatedly.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    char[] xlat;
50840
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   143
    UVS uvs = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    static CMap initialize(TrueTypeFont font) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        CMap cmap = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        int offset, platformID, encodingID=-1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        int three0=0, three1=0, three2=0, three3=0, three4=0, three5=0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            three6=0, three10=0;
50840
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   153
        int zero5 = 0; // for Unicode Variation Sequences
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        boolean threeStar = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        ByteBuffer cmapBuffer = font.getTableBuffer(TrueTypeFont.cmapTag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        int cmapTableOffset = font.getTableSize(TrueTypeFont.cmapTag);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        short numberSubTables = cmapBuffer.getShort(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        /* locate the offsets of all 3,*  (ie Microsoft platform) encodings */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        for (int i=0; i<numberSubTables; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            cmapBuffer.position(i * 8 + 4);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            platformID = cmapBuffer.getShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            if (platformID == 3) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                threeStar = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                encodingID = cmapBuffer.getShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                offset     = cmapBuffer.getInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                switch (encodingID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                case 0:  three0  = offset; break; // MS Symbol encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                case 1:  three1  = offset; break; // MS Unicode cmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                case 2:  three2  = offset; break; // ShiftJIS cmap.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                case 3:  three3  = offset; break; // GBK cmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                case 4:  three4  = offset; break; // Big 5 cmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                case 5:  three5  = offset; break; // Wansung
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                case 6:  three6  = offset; break; // Johab
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                case 10: three10 = offset; break; // MS Unicode surrogates
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                }
50840
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   178
            } else if (platformID == 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   179
                encodingID = cmapBuffer.getShort();
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   180
                offset     = cmapBuffer.getInt();
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   181
                if (encodingID == 5) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   182
                    zero5 = offset;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   183
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        /* This defines the preference order for cmap subtables */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        if (threeStar) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            if (three10 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                cmap = createCMap(cmapBuffer, three10, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            else if  (three0 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                /* The special case treatment of these fonts leads to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                 * anomalies where a user can view "wingdings" and "wingdings2"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                 * and the latter shows all its code points in the unicode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                 * private use area at 0xF000->0XF0FF and the former shows
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                 * a scattered subset of its glyphs that are known mappings to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                 * unicode code points.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                 * The primary purpose of these mappings was to facilitate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                 * display of symbol chars etc in composite fonts, however
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                 * this is not needed as all these code points are covered
50348
008f416a79cb 8191522: Remove Bigelow&Holmes Lucida fonts from JDK sources
prr
parents: 47216
diff changeset
   202
                 * by some other platform symbol font.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                 * Commenting this out reduces the role of these two files
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                 * (assuming that they continue to be used in font.properties)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                 * to just one of contributing to the overall composite
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                 * font metrics, and also AWT can still access the fonts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                 * Clients which explicitly accessed these fonts as names
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                 * "Symbol" and "Wingdings" (ie as physical fonts) and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                 * expected to see a scattering of these characters will
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                 * see them now as missing. How much of a problem is this?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                 * Perhaps we could still support this mapping just for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                 * "Symbol.ttf" but I suspect some users would prefer it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                 * to be mapped in to the Latin range as that is how
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                 * the "symbol" font is used in native apps.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
//              String name = font.platName.toLowerCase(Locale.ENGLISH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
//              if (name.endsWith("symbol.ttf")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
//                  cmap = createSymbolCMap(cmapBuffer, three0, Symbols_b2c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
//              } else if (name.endsWith("wingding.ttf")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
//                  cmap = createSymbolCMap(cmapBuffer, three0, WingDings_b2c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
//              } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                    cmap = createCMap(cmapBuffer, three0, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
//              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            else if (three1 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                cmap = createCMap(cmapBuffer, three1, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            else if (three2 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                cmap = createCMap(cmapBuffer, three2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                                  getConverterMap(ShiftJISEncoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            else if (three3 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                cmap = createCMap(cmapBuffer, three3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                                  getConverterMap(GBKEncoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            else if (three4 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                /* GB2312 TrueType fonts on Solaris have wrong encoding ID for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                 * cmap table, these fonts have EncodingID 4 which is Big5
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                 * encoding according the TrueType spec, but actually the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                 * fonts are using gb2312 encoding, have to use this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                 * workaround to make Solaris zh_CN locale work.  -sherman
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                 */
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2
diff changeset
   243
                if (FontUtilities.isSolaris && font.platName != null &&
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                    (font.platName.startsWith(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                     "/usr/openwin/lib/locale/zh_CN.EUC/X11/fonts/TrueType") ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                     font.platName.startsWith(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                     "/usr/openwin/lib/locale/zh_CN/X11/fonts/TrueType") ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                     font.platName.startsWith(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                     "/usr/openwin/lib/locale/zh/X11/fonts/TrueType"))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                    cmap = createCMap(cmapBuffer, three4,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                                       getConverterMap(GBKEncoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                    cmap = createCMap(cmapBuffer, three4,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                                      getConverterMap(Big5Encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            else if (three5 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                cmap = createCMap(cmapBuffer, three5,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                                  getConverterMap(WansungEncoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            else if (three6 != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                cmap = createCMap(cmapBuffer, three6,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                                  getConverterMap(JohabEncoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            /* No 3,* subtable was found. Just use whatever is the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
             * table listed. Not very useful but maybe better than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
             * rejecting the font entirely?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            cmap = createCMap(cmapBuffer, cmapBuffer.getInt(8), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        }
50840
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   273
        // For Unicode Variation Sequences
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   274
        if (cmap != null && zero5 != 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   275
            cmap.createUVS(cmapBuffer, zero5);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   276
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        return cmap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    /* speed up the converting by setting the range for double
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * byte characters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    static char[] getConverter(short encodingID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        int dBegin = 0x8000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        int dEnd   = 0xffff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        String encoding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        switch (encodingID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        case ShiftJISEncoding:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            dBegin = 0x8140;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            dEnd   = 0xfcfc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            encoding = "SJIS";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        case GBKEncoding:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            dBegin = 0x8140;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            dEnd   = 0xfea0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            encoding = "GBK";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        case Big5Encoding:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            dBegin = 0xa140;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            dEnd   = 0xfefe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            encoding = "Big5";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        case WansungEncoding:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            dBegin = 0xa1a1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            dEnd   = 0xfede;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            encoding = "EUC_KR";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        case JohabEncoding:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            dBegin = 0x8141;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            dEnd   = 0xfdfe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            encoding = "Johab";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            char[] convertedChars = new char[65536];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            for (int i=0; i<65536; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                convertedChars[i] = noSuchChar;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            byte[] inputBytes = new byte[(dEnd-dBegin+1)*2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            char[] outputChars = new char[(dEnd-dBegin+1)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            int j = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            int firstByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            if (encodingID == ShiftJISEncoding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                for (int i = dBegin; i <= dEnd; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                    firstByte = (i >> 8 & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                    if (firstByte >= 0xa1 && firstByte <= 0xdf) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                        //sjis halfwidth katakana
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                        inputBytes[j++] = (byte)0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                        inputBytes[j++] = (byte)0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                        inputBytes[j++] = (byte)firstByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                        inputBytes[j++] = (byte)(i & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                for (int i = dBegin; i <= dEnd; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                    inputBytes[j++] = (byte)(i>>8 & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                    inputBytes[j++] = (byte)(i & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            Charset.forName(encoding).newDecoder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            .onMalformedInput(CodingErrorAction.REPLACE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
            .onUnmappableCharacter(CodingErrorAction.REPLACE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
            .replaceWith("\u0000")
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            .decode(ByteBuffer.wrap(inputBytes, 0, inputBytes.length),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                    CharBuffer.wrap(outputChars, 0, outputChars.length),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                    true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            // ensure single byte ascii
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            for (int i = 0x20; i <= 0x7e; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
                convertedChars[i] = (char)i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            //sjis halfwidth katakana
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            if (encodingID == ShiftJISEncoding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                for (int i = 0xa1; i <= 0xdf; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                    convertedChars[i] = (char)(i - 0xa1 + 0xff61);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            /* It would save heap space (approx 60Kbytes for each of these
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
             * converters) if stored only valid ranges (ie returned
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
             * outputChars directly. But this is tricky since want to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
             * include the ASCII range too.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
//          System.err.println("oc.len="+outputChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
//          System.err.println("cc.len="+convertedChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
//          System.err.println("dbegin="+dBegin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            System.arraycopy(outputChars, 0, convertedChars, dBegin,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                             outputChars.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            //return convertedChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            /* invert this map as now want it to map from Unicode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
             * to other encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            char [] invertedChars = new char[65536];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            for (int i=0;i<65536;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                if (convertedChars[i] != noSuchChar) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                    invertedChars[convertedChars[i]] = (char)i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            return invertedChars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
            e.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * The returned array maps to unicode from some other 2 byte encoding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     * eg for a 2byte index which represents a SJIS char, the indexed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * value is the corresponding unicode char.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
    static char[] getConverterMap(short encodingID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        if (converterMaps[encodingID] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
           converterMaps[encodingID] = getConverter(encodingID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        return converterMaps[encodingID];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    static CMap createCMap(ByteBuffer buffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        /* First do a sanity check that this cmap subtable is contained
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
         * within the cmap table.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        int subtableFormat = buffer.getChar(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        long subtableLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        if (subtableFormat < 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            subtableLength = buffer.getChar(offset+2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
            subtableLength = buffer.getInt(offset+4) & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        if (offset+subtableLength > buffer.capacity()) {
3928
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2
diff changeset
   422
            if (FontUtilities.isLogging()) {
be186a33df9b 6795908: Refactor FontManager
rkennke
parents: 2
diff changeset
   423
                FontUtilities.getLogger().warning("Cmap subtable overflows buffer.");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        switch (subtableFormat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        case 0:  return new CMapFormat0(buffer, offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        case 2:  return new CMapFormat2(buffer, offset, xlat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        case 4:  return new CMapFormat4(buffer, offset, xlat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        case 6:  return new CMapFormat6(buffer, offset, xlat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        case 8:  return new CMapFormat8(buffer, offset, xlat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        case 10: return new CMapFormat10(buffer, offset, xlat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        case 12: return new CMapFormat12(buffer, offset, xlat);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        default: throw new RuntimeException("Cmap format unimplemented: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                                            (int)buffer.getChar(offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
50840
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   439
    private void createUVS(ByteBuffer buffer, int offset) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   440
        int subtableFormat = buffer.getChar(offset);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   441
        if (subtableFormat == 14) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   442
            long subtableLength = buffer.getInt(offset + 2) & INTMASK;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   443
            if (offset + subtableLength > buffer.capacity()) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   444
                if (FontUtilities.isLogging()) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   445
                    FontUtilities.getLogger()
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   446
                            .warning("Cmap UVS subtable overflows buffer.");
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   447
                }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   448
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   449
            try {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   450
                this.uvs = new UVS(buffer, offset);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   451
            } catch (Throwable t) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   452
                t.printStackTrace();
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   453
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   454
        }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   455
        return;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   456
    }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
   457
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
    final char charVal(byte[] cmap, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        return (char)(((0xff & cmap[index]) << 8)+(0xff & cmap[index+1]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    final short shortVal(byte[] cmap, int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        return (short)(((0xff & cmap[index]) << 8)+(0xff & cmap[index+1]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    abstract char getGlyph(int charCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    /* Format 4 Header is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     * ushort format (off=0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     * ushort length (off=2)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
     * ushort language (off=4)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
     * ushort segCountX2 (off=6)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
     * ushort searchRange (off=8)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
     * ushort entrySelector (off=10)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
     * ushort rangeShift (off=12)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
     * ushort endCount[segCount] (off=14)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
     * ushort reservedPad
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
     * ushort startCount[segCount]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
     * short idDelta[segCount]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
     * idRangeOFfset[segCount]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * ushort glyphIdArray[]
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    static class CMapFormat4 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        int segCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        int entrySelector;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        int rangeShift;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        char[] endCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        char[] startCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        short[] idDelta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        char[] idRangeOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        char[] glyphIds;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        CMapFormat4(ByteBuffer bbuffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            this.xlat = xlat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
            bbuffer.position(offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            CharBuffer buffer = bbuffer.asCharBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            buffer.get(); // skip, we already know format=4
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
            int subtableLength = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            /* Try to recover from some bad fonts which specify a subtable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
             * length that would overflow the byte buffer holding the whole
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
             * cmap table. If this isn't a recoverable situation an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
             * may be thrown which is caught higher up the call stack.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
             * Whilst this may seem lenient, in practice, unless the "bad"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
             * subtable we are using is the last one in the cmap table we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
             * would have no way of knowing about this problem anyway.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            if (offset+subtableLength > bbuffer.capacity()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                subtableLength = bbuffer.capacity() - offset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            buffer.get(); // skip language
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            segCount = buffer.get()/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            int searchRange = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            entrySelector = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            rangeShift    = buffer.get()/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
            startCount = new char[segCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
            endCount = new char[segCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
            idDelta = new short[segCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            idRangeOffset = new char[segCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            for (int i=0; i<segCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                endCount[i] = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
            buffer.get(); // 2 bytes for reserved pad
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            for (int i=0; i<segCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                startCount[i] = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            for (int i=0; i<segCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                idDelta[i] = (short)buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            for (int i=0; i<segCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                char ctmp = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                idRangeOffset[i] = (char)((ctmp>>1)&0xffff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            /* Can calculate the number of glyph IDs by subtracting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
             * "pos" from the length of the cmap
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            int pos = (segCount*8+16)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
            buffer.position(pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            int numGlyphIds = (subtableLength/2 - pos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
            glyphIds = new char[numGlyphIds];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            for (int i=0;i<numGlyphIds;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                glyphIds[i] = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            System.err.println("segcount="+segCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            System.err.println("entrySelector="+entrySelector);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            System.err.println("rangeShift="+rangeShift);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            for (int j=0;j<segCount;j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
              System.err.println("j="+j+ " sc="+(int)(startCount[j]&0xffff)+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                                 " ec="+(int)(endCount[j]&0xffff)+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                                 " delta="+idDelta[j] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                                 " ro="+(int)idRangeOffset[j]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
            //System.err.println("numglyphs="+glyphIds.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
            for (int i=0;i<numGlyphIds;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                  System.err.println("gid["+i+"]="+(int)glyphIds[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
        char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
            int index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            char glyphCode = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            int controlGlyph = getControlCodeGlyph(charCode, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            if (controlGlyph >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                return (char)controlGlyph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            /* presence of translation array indicates that this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
             * cmap is in some other (non-unicode encoding).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
             * In order to look-up a char->glyph mapping we need to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
             * translate the unicode code point to the encoding of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
             * the cmap.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
             * REMIND: VALID CHARCODES??
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            if (xlat != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
                charCode = xlat[charCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
             * Citation from the TrueType (and OpenType) spec:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
             *   The segments are sorted in order of increasing endCode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
             *   values, and the segment values are specified in four parallel
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
             *   arrays. You search for the first endCode that is greater than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
             *   or equal to the character code you want to map. If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
             *   corresponding startCode is less than or equal to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
             *   character code, then you use the corresponding idDelta and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
             *   idRangeOffset to map the character code to a glyph index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
             *   (otherwise, the missingGlyph is returned).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
             * CMAP format4 defines several fields for optimized search of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
             * the segment list (entrySelector, searchRange, rangeShift).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
             * However, benefits are neglible and some fonts have incorrect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
             * data - so we use straightforward binary search (see bug 6247425)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            int left = 0, right = startCount.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            index = startCount.length >> 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            while (left < right) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                if (endCount[index] < charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                    left = index + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                    right = index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                index = (left + right) >> 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
            if (charCode >= startCount[index] && charCode <= endCount[index]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                int rangeOffset = idRangeOffset[index];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                if (rangeOffset == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                    glyphCode = (char)(charCode + idDelta[index]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                    /* Calculate an index into the glyphIds array */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                    System.err.println("rangeoffset="+rangeOffset+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                                       " charCode=" + charCode +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                                       " scnt["+index+"]="+(int)startCount[index] +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                                       " segCnt="+segCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                    int glyphIDIndex = rangeOffset - segCount + index
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                                         + (charCode - startCount[index]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                    glyphCode = glyphIds[glyphIDIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                    if (glyphCode != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                        glyphCode = (char)(glyphCode + idDelta[index]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            if (glyphCode != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            //System.err.println("cc="+Integer.toHexString((int)charCode) + " gc="+(int)glyphCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            return glyphCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    // Format 0: Byte Encoding table
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    static class CMapFormat0 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        byte [] cmap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        CMapFormat0(ByteBuffer buffer, int offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            /* skip 6 bytes of format, length, and version */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            int len = buffer.getChar(offset+2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            cmap = new byte[len-6];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            buffer.position(offset+6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            buffer.get(cmap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
            if (charCode < 256) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                if (charCode < 0x0010) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    switch (charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                    case 0x0009:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                    case 0x000a:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
                    case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                return (char)(0xff & cmap[charCode]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
//     static CMap createSymbolCMap(ByteBuffer buffer, int offset, char[] syms) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
//      CMap cmap = createCMap(buffer, offset, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
//      if (cmap == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
//          return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
//      } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
//          return new CMapFormatSymbol(cmap, syms);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
//      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
//     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
//     static class CMapFormatSymbol extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
//      CMap cmap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
//      static final int NUM_BUCKETS = 128;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
//      Bucket[] buckets = new Bucket[NUM_BUCKETS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
//      class Bucket {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
//          char unicode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
//          char glyph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
//          Bucket next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
//          Bucket(char u, char g) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
//              unicode = u;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
//              glyph = g;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
//          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
//      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
//      CMapFormatSymbol(CMap cmap, char[] syms) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
//          this.cmap = cmap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
//          for (int i=0;i<syms.length;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
//              char unicode = syms[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
//              if (unicode != noSuchChar) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
//                  char glyph = cmap.getGlyph(i + 0xf000);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
//                  int hash = unicode % NUM_BUCKETS;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
//                  Bucket bucket = new Bucket(unicode, glyph);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
//                  if (buckets[hash] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
//                      buckets[hash] = bucket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
//                  } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
//                      Bucket b = buckets[hash];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
//                      while (b.next != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
//                          b = b.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
//                      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
//                      b.next = bucket;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
//                  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
//              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
//          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
//      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
//      char getGlyph(int unicode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
//          if (unicode >= 0x1000) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
//              return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
//          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
//          else if (unicode >=0xf000 && unicode < 0xf100) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
//              return cmap.getGlyph(unicode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
//          } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
//              Bucket b = buckets[unicode % NUM_BUCKETS];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
//              while (b != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
//                  if (b.unicode == unicode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
//                      return b.glyph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
//                  } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
//                      b = b.next;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
//                  }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
//              }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
//              return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
//          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
//      }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
//     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
    // Format 2: High-byte mapping through table
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    static class CMapFormat2 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        char[] subHeaderKey = new char[256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
         /* Store subheaders in individual arrays
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
          * A SubHeader entry theortically looks like {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
          *   char firstCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
          *   char entryCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
          *   short idDelta;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
          *   char idRangeOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
          * }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
          */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        char[] firstCodeArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        char[] entryCountArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        short[] idDeltaArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        char[] idRangeOffSetArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        char[] glyphIndexArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        CMapFormat2(ByteBuffer buffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            this.xlat = xlat;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            int tableLen = buffer.getChar(offset+2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            buffer.position(offset+6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            CharBuffer cBuffer = buffer.asCharBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            char maxSubHeader = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            for (int i=0;i<256;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                subHeaderKey[i] = cBuffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                if (subHeaderKey[i] > maxSubHeader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                    maxSubHeader = subHeaderKey[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            /* The value of the subHeaderKey is 8 * the subHeader index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
             * so the number of subHeaders can be obtained by dividing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
             * this value bv 8 and adding 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            int numSubHeaders = (maxSubHeader >> 3) +1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            firstCodeArray = new char[numSubHeaders];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            entryCountArray = new char[numSubHeaders];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
            idDeltaArray  = new short[numSubHeaders];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
            idRangeOffSetArray  = new char[numSubHeaders];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
            for (int i=0; i<numSubHeaders; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                firstCodeArray[i] = cBuffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                entryCountArray[i] = cBuffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                idDeltaArray[i] = (short)cBuffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                idRangeOffSetArray[i] = cBuffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
//              System.out.println("sh["+i+"]:fc="+(int)firstCodeArray[i]+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
//                                 " ec="+(int)entryCountArray[i]+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
//                                 " delta="+(int)idDeltaArray[i]+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
//                                 " offset="+(int)idRangeOffSetArray[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
            int glyphIndexArrSize = (tableLen-518-numSubHeaders*8)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
            glyphIndexArray = new char[glyphIndexArrSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
            for (int i=0; i<glyphIndexArrSize;i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                glyphIndexArray[i] = cBuffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            int controlGlyph = getControlCodeGlyph(charCode, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
            if (controlGlyph >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                return (char)controlGlyph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            if (xlat != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                charCode = xlat[charCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
            char highByte = (char)(charCode >> 8);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            char lowByte = (char)(charCode & 0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            int key = subHeaderKey[highByte]>>3; // index into subHeaders
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            char mapMe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            if (key != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                mapMe = lowByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                mapMe = highByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                if (mapMe == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
                    mapMe = lowByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
//          System.err.println("charCode="+Integer.toHexString(charCode)+
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
//                             " key="+key+ " mapMe="+Integer.toHexString(mapMe));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            char firstCode = firstCodeArray[key];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            if (mapMe < firstCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                mapMe -= firstCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
            if (mapMe < entryCountArray[key]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                /* "address" arithmetic is needed to calculate the offset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                 * into glyphIndexArray. "idRangeOffSetArray[key]" specifies
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                 * the number of bytes from that location in the table where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
                 * the subarray of glyphIndexes starting at "firstCode" begins.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                 * Each entry in the subHeader table is 8 bytes, and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                 * idRangeOffSetArray field is at offset 6 in the entry.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                 * The glyphIndexArray immediately follows the subHeaders.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                 * So if there are "N" entries then the number of bytes to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                 * start of glyphIndexArray is (N-key)*8-6.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                 * Subtract this from the idRangeOffSetArray value to get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                 * the number of bytes into glyphIndexArray and divide by 2 to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                 * get the (char) array index.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                int glyphArrayOffset = ((idRangeOffSetArray.length-key)*8)-6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                int glyphSubArrayStart =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                        (idRangeOffSetArray[key] - glyphArrayOffset)/2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                char glyphCode = glyphIndexArray[glyphSubArrayStart+mapMe];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                if (glyphCode != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                    glyphCode += idDeltaArray[key]; //idDelta
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    return glyphCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    // Format 6: Trimmed table mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
    static class CMapFormat6 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
        char firstCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        char entryCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
        char[] glyphIdArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
             bbuffer.position(offset+6);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
             CharBuffer buffer = bbuffer.asCharBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
             firstCode = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
             entryCount = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
             glyphIdArray = new char[entryCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
             for (int i=0; i< entryCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                 glyphIdArray[i] = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
         char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
            int controlGlyph = getControlCodeGlyph(charCode, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
            if (controlGlyph >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                return (char)controlGlyph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
             if (xlat != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                 charCode = xlat[charCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
             charCode -= firstCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
             if (charCode < 0 || charCode >= entryCount) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                  return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
             } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
                  return glyphIdArray[charCode];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
    // Format 8: mixed 16-bit and 32-bit coverage
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    // Seems unlikely this code will ever get tested as we look for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    // MS platform Cmaps and MS states (in the Opentype spec on their website)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
    // that MS doesn't support this format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
    static class CMapFormat8 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
         byte[] is32 = new byte[8192];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
         int nGroups;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
         int[] startCharCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
         int[] endCharCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
         int[] startGlyphID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
         CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
             bbuffer.position(12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
             bbuffer.get(is32);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
             nGroups = bbuffer.getInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
             startCharCode = new int[nGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
             endCharCode   = new int[nGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
             startGlyphID  = new int[nGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
            if (xlat != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
                throw new RuntimeException("xlat array for cmap fmt=8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
    // Format 4-byte 10: Trimmed table mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
    // Seems unlikely this code will ever get tested as we look for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
    // MS platform Cmaps and MS states (in the Opentype spec on their website)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
    // that MS doesn't support this format
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
    static class CMapFormat10 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
         long firstCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
         int entryCount;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
         char[] glyphIdArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
         CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
             firstCode = bbuffer.getInt() & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
             entryCount = bbuffer.getInt() & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
             bbuffer.position(offset+20);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
             CharBuffer buffer = bbuffer.asCharBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
             glyphIdArray = new char[entryCount];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
             for (int i=0; i< entryCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
                 glyphIdArray[i] = buffer.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
         char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
             if (xlat != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
                 throw new RuntimeException("xlat array for cmap fmt=10");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
             int code = (int)(charCode - firstCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
             if (code < 0 || code >= entryCount) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
                 return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
             } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                 return glyphIdArray[code];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
             }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
         }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    // Format 12: Segmented coverage for UCS-4 (fonts supporting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
    // surrogate pairs)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
    static class CMapFormat12 extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        int numGroups;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
        int highBit =0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
        int power;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        int extra;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
        long[] startCharCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        long[] endCharCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
        int[] startGlyphID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
        CMapFormat12(ByteBuffer buffer, int offset, char[] xlat) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
            if (xlat != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                throw new RuntimeException("xlat array for cmap fmt=12");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
            numGroups = buffer.getInt(offset+12);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
            startCharCode = new long[numGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            endCharCode = new long[numGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
            startGlyphID = new int[numGroups];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
            buffer.position(offset+16);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
            buffer = buffer.slice();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
            IntBuffer ibuffer = buffer.asIntBuffer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            for (int i=0; i<numGroups; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
                startCharCode[i] = ibuffer.get() & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                endCharCode[i] = ibuffer.get() & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                startGlyphID[i] = ibuffer.get() & INTMASK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            /* Finds the high bit by binary searching through the bits */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
            int value = numGroups;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
            if (value >= 1 << 16) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
                value >>= 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
                highBit += 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
            if (value >= 1 << 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
                value >>= 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                highBit += 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
            if (value >= 1 << 4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                value >>= 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
                highBit += 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            if (value >= 1 << 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
                value >>= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
                highBit += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
            if (value >= 1 << 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                value >>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
                highBit += 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
            power = 1 << highBit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
            extra = numGroups - power;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
        char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
            int controlGlyph = getControlCodeGlyph(charCode, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            if (controlGlyph >= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
                return (char)controlGlyph;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            int probe = power;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
            int range = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            if (startCharCode[extra] <= charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                range = extra;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            while (probe > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                probe >>= 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
                if (startCharCode[range+probe] <= charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
                    range += probe;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
            if (startCharCode[range] <= charCode &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
                  endCharCode[range] >= charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
                return (char)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
                    (startGlyphID[range] + (charCode - startCharCode[range]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
    /* Used to substitute for bad Cmaps. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
    static class NullCMapClass extends CMap {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
        char getGlyph(int charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
    public static final NullCMapClass theNullCmap = new NullCMapClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    final int getControlCodeGlyph(int charCode, boolean noSurrogates) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
        if (charCode < 0x0010) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
            switch (charCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
            case 0x0009:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
            case 0x000a:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
            case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
        } else if (charCode >= 0x200c) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
            if ((charCode <= 0x200f) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                (charCode >= 0x2028 && charCode <= 0x202e) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                (charCode >= 0x206a && charCode <= 0x206f)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
            } else if (noSurrogates && charCode >= 0xFFFF) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
        return -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
    }
50840
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1093
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1094
    static class UVS {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1095
        int numSelectors;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1096
        int[] selector;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1097
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1098
        //for Non-Default UVS Table
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1099
        int[] numUVSMapping;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1100
        int[][] unicodeValue;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1101
        char[][] glyphID;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1102
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1103
        UVS(ByteBuffer buffer, int offset) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1104
            numSelectors = buffer.getInt(offset+6);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1105
            selector = new int[numSelectors];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1106
            numUVSMapping = new int[numSelectors];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1107
            unicodeValue = new int[numSelectors][];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1108
            glyphID = new char[numSelectors][];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1109
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1110
            for (int i = 0; i < numSelectors; i++) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1111
                buffer.position(offset + 10 + i * 11);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1112
                selector[i] = (buffer.get() & 0xff) << 16; //UINT24
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1113
                selector[i] += (buffer.get() & 0xff) << 8;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1114
                selector[i] += buffer.get() & 0xff;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1115
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1116
                //skip Default UVS Table
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1117
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1118
                //for Non-Default UVS Table
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1119
                int tableOffset = buffer.getInt(offset + 10 + i * 11 + 7);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1120
                if (tableOffset == 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1121
                    numUVSMapping[i] = 0;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1122
                } else if (tableOffset > 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1123
                    buffer.position(offset+tableOffset);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1124
                    numUVSMapping[i] = buffer.getInt() & INTMASK;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1125
                    unicodeValue[i] = new int[numUVSMapping[i]];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1126
                    glyphID[i] = new char[numUVSMapping[i]];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1127
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1128
                    for (int j = 0; j < numUVSMapping[i]; j++) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1129
                        int temp = (buffer.get() & 0xff) << 16; //UINT24
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1130
                        temp += (buffer.get() & 0xff) << 8;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1131
                        temp += buffer.get() & 0xff;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1132
                        unicodeValue[i][j] = temp;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1133
                        glyphID[i][j] = buffer.getChar();
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1134
                    }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1135
                }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1136
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1137
        }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1138
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1139
        static final int VS_NOGLYPH = 0;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1140
        private int getGlyph(int charCode, int variationSelector) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1141
            int targetSelector = -1;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1142
            for (int i = 0; i < numSelectors; i++) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1143
                if (selector[i] == variationSelector) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1144
                    targetSelector = i;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1145
                    break;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1146
                }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1147
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1148
            if (targetSelector == -1) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1149
                return VS_NOGLYPH;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1150
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1151
            if (numUVSMapping[targetSelector] > 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1152
                int index = java.util.Arrays.binarySearch(
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1153
                                unicodeValue[targetSelector], charCode);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1154
                if (index >= 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1155
                    return glyphID[targetSelector][index];
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1156
                }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1157
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1158
            return VS_NOGLYPH;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1159
        }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1160
    }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1161
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1162
    char getVariationGlyph(int charCode, int variationSelector) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1163
        char glyph = 0;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1164
        if (uvs == null) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1165
            glyph = getGlyph(charCode);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1166
        } else {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1167
            int result = uvs.getGlyph(charCode, variationSelector);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1168
            if (result > 0) {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1169
                glyph = (char)(result & 0xFFFF);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1170
            } else {
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1171
                glyph = getGlyph(charCode);
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1172
            }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1173
        }
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1174
        return glyph;
1db5917dfe1c 8187100: Support Unicode Variation Selectors
srl
parents: 50348
diff changeset
  1175
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
}