< prev index next >

src/java.desktop/share/classes/sun/font/CMap.java

Print this page




 549 /*
 550             System.err.println("segcount="+segCount);
 551             System.err.println("entrySelector="+entrySelector);
 552             System.err.println("rangeShift="+rangeShift);
 553             for (int j=0;j<segCount;j++) {
 554               System.err.println("j="+j+ " sc="+(int)(startCount[j]&0xffff)+
 555                                  " ec="+(int)(endCount[j]&0xffff)+
 556                                  " delta="+idDelta[j] +
 557                                  " ro="+(int)idRangeOffset[j]);
 558             }
 559 
 560             //System.err.println("numglyphs="+glyphIds.length);
 561             for (int i=0;i<numGlyphIds;i++) {
 562                   System.err.println("gid["+i+"]="+(int)glyphIds[i]);
 563             }
 564 */
 565         }
 566 
 567         char getGlyph(int charCode) {
 568 

 569             int index = 0;
 570             char glyphCode = 0;
 571 
 572             int controlGlyph = getControlCodeGlyph(charCode, true);
 573             if (controlGlyph >= 0) {
 574                 return (char)controlGlyph;
 575             }
 576 
 577             /* presence of translation array indicates that this
 578              * cmap is in some other (non-unicode encoding).
 579              * In order to look-up a char->glyph mapping we need to
 580              * translate the unicode code point to the encoding of
 581              * the cmap.
 582              * REMIND: VALID CHARCODES??
 583              */
 584             if (xlat != null) {
 585                 charCode = xlat[charCode];
 586             }
 587 
 588             /*


 620                 if (rangeOffset == 0) {
 621                     glyphCode = (char)(charCode + idDelta[index]);
 622                 } else {
 623                     /* Calculate an index into the glyphIds array */
 624 
 625 /*
 626                     System.err.println("rangeoffset="+rangeOffset+
 627                                        " charCode=" + charCode +
 628                                        " scnt["+index+"]="+(int)startCount[index] +
 629                                        " segCnt="+segCount);
 630 */
 631 
 632                     int glyphIDIndex = rangeOffset - segCount + index
 633                                          + (charCode - startCount[index]);
 634                     glyphCode = glyphIds[glyphIDIndex];
 635                     if (glyphCode != 0) {
 636                         glyphCode = (char)(glyphCode + idDelta[index]);
 637                     }
 638                 }
 639             }
 640             if (glyphCode != 0) {
 641             //System.err.println("cc="+Integer.toHexString((int)charCode) + " gc="+(int)glyphCode);
 642             }
 643             return glyphCode;
 644         }
 645     }
 646 
 647     // Format 0: Byte Encoding table
 648     static class CMapFormat0 extends CMap {
 649         byte [] cmap;
 650 
 651         CMapFormat0(ByteBuffer buffer, int offset) {
 652 
 653             /* skip 6 bytes of format, length, and version */
 654             int len = buffer.getChar(offset+2);
 655             cmap = new byte[len-6];
 656             buffer.position(offset+6);
 657             buffer.get(cmap);
 658         }
 659 
 660         char getGlyph(int charCode) {
 661             if (charCode < 256) {


 787             idRangeOffSetArray  = new char[numSubHeaders];
 788             for (int i=0; i<numSubHeaders; i++) {
 789                 firstCodeArray[i] = cBuffer.get();
 790                 entryCountArray[i] = cBuffer.get();
 791                 idDeltaArray[i] = (short)cBuffer.get();
 792                 idRangeOffSetArray[i] = cBuffer.get();
 793 //              System.out.println("sh["+i+"]:fc="+(int)firstCodeArray[i]+
 794 //                                 " ec="+(int)entryCountArray[i]+
 795 //                                 " delta="+(int)idDeltaArray[i]+
 796 //                                 " offset="+(int)idRangeOffSetArray[i]);
 797             }
 798 
 799             int glyphIndexArrSize = (tableLen-518-numSubHeaders*8)/2;
 800             glyphIndexArray = new char[glyphIndexArrSize];
 801             for (int i=0; i<glyphIndexArrSize;i++) {
 802                 glyphIndexArray[i] = cBuffer.get();
 803             }
 804         }
 805 
 806         char getGlyph(int charCode) {

 807             int controlGlyph = getControlCodeGlyph(charCode, true);
 808             if (controlGlyph >= 0) {
 809                 return (char)controlGlyph;
 810             }
 811 
 812             if (xlat != null) {
 813                 charCode = xlat[charCode];
 814             }
 815 
 816             char highByte = (char)(charCode >> 8);
 817             char lowByte = (char)(charCode & 0xff);
 818             int key = subHeaderKey[highByte]>>3; // index into subHeaders
 819             char mapMe;
 820 
 821             if (key != 0) {
 822                 mapMe = lowByte;
 823             } else {
 824                 mapMe = highByte;
 825                 if (mapMe == 0) {
 826                     mapMe = lowByte;


 842                  * the number of bytes from that location in the table where
 843                  * the subarray of glyphIndexes starting at "firstCode" begins.
 844                  * Each entry in the subHeader table is 8 bytes, and the
 845                  * idRangeOffSetArray field is at offset 6 in the entry.
 846                  * The glyphIndexArray immediately follows the subHeaders.
 847                  * So if there are "N" entries then the number of bytes to the
 848                  * start of glyphIndexArray is (N-key)*8-6.
 849                  * Subtract this from the idRangeOffSetArray value to get
 850                  * the number of bytes into glyphIndexArray and divide by 2 to
 851                  * get the (char) array index.
 852                  */
 853                 int glyphArrayOffset = ((idRangeOffSetArray.length-key)*8)-6;
 854                 int glyphSubArrayStart =
 855                         (idRangeOffSetArray[key] - glyphArrayOffset)/2;
 856                 char glyphCode = glyphIndexArray[glyphSubArrayStart+mapMe];
 857                 if (glyphCode != 0) {
 858                     glyphCode += idDeltaArray[key]; //idDelta
 859                     return glyphCode;
 860                 }
 861             }
 862             return 0;
 863         }
 864     }
 865 
 866     // Format 6: Trimmed table mapping
 867     static class CMapFormat6 extends CMap {
 868 
 869         char firstCode;
 870         char entryCount;
 871         char[] glyphIdArray;
 872 
 873         CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
 874 
 875              bbuffer.position(offset+6);
 876              CharBuffer buffer = bbuffer.asCharBuffer();
 877              firstCode = buffer.get();
 878              entryCount = buffer.get();
 879              glyphIdArray = new char[entryCount];
 880              for (int i=0; i< entryCount; i++) {
 881                  glyphIdArray[i] = buffer.get();
 882              }
 883          }
 884 
 885          char getGlyph(int charCode) {

 886             int controlGlyph = getControlCodeGlyph(charCode, true);
 887             if (controlGlyph >= 0) {
 888                 return (char)controlGlyph;
 889             }
 890 
 891              if (xlat != null) {
 892                  charCode = xlat[charCode];
 893              }
 894 
 895              charCode -= firstCode;
 896              if (charCode < 0 || charCode >= entryCount) {
 897                   return 0;
 898              } else {
 899                   return glyphIdArray[charCode];
 900              }
 901          }
 902     }
 903 
 904     // Format 8: mixed 16-bit and 32-bit coverage
 905     // Seems unlikely this code will ever get tested as we look for
 906     // MS platform Cmaps and MS states (in the Opentype spec on their website)
 907     // that MS doesn't support this format
 908     static class CMapFormat8 extends CMap {
 909          byte[] is32 = new byte[8192];
 910          int nGroups;
 911          int[] startCharCode;
 912          int[] endCharCode;
 913          int[] startGlyphID;
 914 
 915          CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
 916 
 917              bbuffer.position(12);


1015             if (value >= 1 << 4) {
1016                 value >>= 4;
1017                 highBit += 4;
1018             }
1019 
1020             if (value >= 1 << 2) {
1021                 value >>= 2;
1022                 highBit += 2;
1023             }
1024 
1025             if (value >= 1 << 1) {
1026                 value >>= 1;
1027                 highBit += 1;
1028             }
1029 
1030             power = 1 << highBit;
1031             extra = numGroups - power;
1032         }
1033 
1034         char getGlyph(int charCode) {

1035             int controlGlyph = getControlCodeGlyph(charCode, false);
1036             if (controlGlyph >= 0) {
1037                 return (char)controlGlyph;
1038             }
1039             int probe = power;
1040             int range = 0;
1041 
1042             if (startCharCode[extra] <= charCode) {
1043                 range = extra;
1044             }
1045 
1046             while (probe > 1) {
1047                 probe >>= 1;
1048 
1049                 if (startCharCode[range+probe] <= charCode) {
1050                     range += probe;
1051                 }
1052             }
1053 
1054             if (startCharCode[range] <= charCode &&
1055                   endCharCode[range] >= charCode) {
1056                 return (char)
1057                     (startGlyphID[range] + (charCode - startCharCode[range]));
1058             }
1059 
1060             return 0;
1061         }
1062 
1063     }
1064 
1065     /* Used to substitute for bad Cmaps. */
1066     static class NullCMapClass extends CMap {
1067 
1068         char getGlyph(int charCode) {
1069             return 0;
1070         }
1071     }
1072 
1073     public static final NullCMapClass theNullCmap = new NullCMapClass();
1074 
1075     final int getControlCodeGlyph(int charCode, boolean noSurrogates) {
1076         if (charCode < 0x0010) {
1077             switch (charCode) {
1078             case 0x0009:
1079             case 0x000a:
1080             case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
1081             }
1082         } else if (charCode >= 0x200c) {







1083             if ((charCode <= 0x200f) ||
1084                 (charCode >= 0x2028 && charCode <= 0x202e) ||
1085                 (charCode >= 0x206a && charCode <= 0x206f)) {
1086                 return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
1087             } else if (noSurrogates && charCode >= 0xFFFF) {
1088                 return 0;
1089             }
1090         }
1091         return -1;
1092     }
1093 
1094     static class UVS {
1095         int numSelectors;
1096         int[] selector;
1097 
1098         //for Non-Default UVS Table
1099         int[] numUVSMapping;
1100         int[][] unicodeValue;
1101         char[][] glyphID;
1102 
1103         UVS(ByteBuffer buffer, int offset) {
1104             numSelectors = buffer.getInt(offset+6);
1105             selector = new int[numSelectors];
1106             numUVSMapping = new int[numSelectors];
1107             unicodeValue = new int[numSelectors][];
1108             glyphID = new char[numSelectors][];
1109 
1110             for (int i = 0; i < numSelectors; i++) {
1111                 buffer.position(offset + 10 + i * 11);




 549 /*
 550             System.err.println("segcount="+segCount);
 551             System.err.println("entrySelector="+entrySelector);
 552             System.err.println("rangeShift="+rangeShift);
 553             for (int j=0;j<segCount;j++) {
 554               System.err.println("j="+j+ " sc="+(int)(startCount[j]&0xffff)+
 555                                  " ec="+(int)(endCount[j]&0xffff)+
 556                                  " delta="+idDelta[j] +
 557                                  " ro="+(int)idRangeOffset[j]);
 558             }
 559 
 560             //System.err.println("numglyphs="+glyphIds.length);
 561             for (int i=0;i<numGlyphIds;i++) {
 562                   System.err.println("gid["+i+"]="+(int)glyphIds[i]);
 563             }
 564 */
 565         }
 566 
 567         char getGlyph(int charCode) {
 568 
 569             final int origCharCode = charCode;
 570             int index = 0;
 571             char glyphCode = 0;
 572 
 573             int controlGlyph = getControlCodeGlyph(charCode, true);
 574             if (controlGlyph >= 0) {
 575                 return (char)controlGlyph;
 576             }
 577 
 578             /* presence of translation array indicates that this
 579              * cmap is in some other (non-unicode encoding).
 580              * In order to look-up a char->glyph mapping we need to
 581              * translate the unicode code point to the encoding of
 582              * the cmap.
 583              * REMIND: VALID CHARCODES??
 584              */
 585             if (xlat != null) {
 586                 charCode = xlat[charCode];
 587             }
 588 
 589             /*


 621                 if (rangeOffset == 0) {
 622                     glyphCode = (char)(charCode + idDelta[index]);
 623                 } else {
 624                     /* Calculate an index into the glyphIds array */
 625 
 626 /*
 627                     System.err.println("rangeoffset="+rangeOffset+
 628                                        " charCode=" + charCode +
 629                                        " scnt["+index+"]="+(int)startCount[index] +
 630                                        " segCnt="+segCount);
 631 */
 632 
 633                     int glyphIDIndex = rangeOffset - segCount + index
 634                                          + (charCode - startCount[index]);
 635                     glyphCode = glyphIds[glyphIDIndex];
 636                     if (glyphCode != 0) {
 637                         glyphCode = (char)(glyphCode + idDelta[index]);
 638                     }
 639                 }
 640             }
 641             if (glyphCode == 0) {
 642               glyphCode = getFormatCharGlyph(origCharCode);
 643             }
 644             return glyphCode;
 645         }
 646     }
 647 
 648     // Format 0: Byte Encoding table
 649     static class CMapFormat0 extends CMap {
 650         byte [] cmap;
 651 
 652         CMapFormat0(ByteBuffer buffer, int offset) {
 653 
 654             /* skip 6 bytes of format, length, and version */
 655             int len = buffer.getChar(offset+2);
 656             cmap = new byte[len-6];
 657             buffer.position(offset+6);
 658             buffer.get(cmap);
 659         }
 660 
 661         char getGlyph(int charCode) {
 662             if (charCode < 256) {


 788             idRangeOffSetArray  = new char[numSubHeaders];
 789             for (int i=0; i<numSubHeaders; i++) {
 790                 firstCodeArray[i] = cBuffer.get();
 791                 entryCountArray[i] = cBuffer.get();
 792                 idDeltaArray[i] = (short)cBuffer.get();
 793                 idRangeOffSetArray[i] = cBuffer.get();
 794 //              System.out.println("sh["+i+"]:fc="+(int)firstCodeArray[i]+
 795 //                                 " ec="+(int)entryCountArray[i]+
 796 //                                 " delta="+(int)idDeltaArray[i]+
 797 //                                 " offset="+(int)idRangeOffSetArray[i]);
 798             }
 799 
 800             int glyphIndexArrSize = (tableLen-518-numSubHeaders*8)/2;
 801             glyphIndexArray = new char[glyphIndexArrSize];
 802             for (int i=0; i<glyphIndexArrSize;i++) {
 803                 glyphIndexArray[i] = cBuffer.get();
 804             }
 805         }
 806 
 807         char getGlyph(int charCode) {
 808             final int origCharCode = charCode;
 809             int controlGlyph = getControlCodeGlyph(charCode, true);
 810             if (controlGlyph >= 0) {
 811                 return (char)controlGlyph;
 812             }
 813 
 814             if (xlat != null) {
 815                 charCode = xlat[charCode];
 816             }
 817 
 818             char highByte = (char)(charCode >> 8);
 819             char lowByte = (char)(charCode & 0xff);
 820             int key = subHeaderKey[highByte]>>3; // index into subHeaders
 821             char mapMe;
 822 
 823             if (key != 0) {
 824                 mapMe = lowByte;
 825             } else {
 826                 mapMe = highByte;
 827                 if (mapMe == 0) {
 828                     mapMe = lowByte;


 844                  * the number of bytes from that location in the table where
 845                  * the subarray of glyphIndexes starting at "firstCode" begins.
 846                  * Each entry in the subHeader table is 8 bytes, and the
 847                  * idRangeOffSetArray field is at offset 6 in the entry.
 848                  * The glyphIndexArray immediately follows the subHeaders.
 849                  * So if there are "N" entries then the number of bytes to the
 850                  * start of glyphIndexArray is (N-key)*8-6.
 851                  * Subtract this from the idRangeOffSetArray value to get
 852                  * the number of bytes into glyphIndexArray and divide by 2 to
 853                  * get the (char) array index.
 854                  */
 855                 int glyphArrayOffset = ((idRangeOffSetArray.length-key)*8)-6;
 856                 int glyphSubArrayStart =
 857                         (idRangeOffSetArray[key] - glyphArrayOffset)/2;
 858                 char glyphCode = glyphIndexArray[glyphSubArrayStart+mapMe];
 859                 if (glyphCode != 0) {
 860                     glyphCode += idDeltaArray[key]; //idDelta
 861                     return glyphCode;
 862                 }
 863             }
 864             return getFormatCharGlyph(origCharCode);
 865         }
 866     }
 867 
 868     // Format 6: Trimmed table mapping
 869     static class CMapFormat6 extends CMap {
 870 
 871         char firstCode;
 872         char entryCount;
 873         char[] glyphIdArray;
 874 
 875         CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
 876 
 877              bbuffer.position(offset+6);
 878              CharBuffer buffer = bbuffer.asCharBuffer();
 879              firstCode = buffer.get();
 880              entryCount = buffer.get();
 881              glyphIdArray = new char[entryCount];
 882              for (int i=0; i< entryCount; i++) {
 883                  glyphIdArray[i] = buffer.get();
 884              }
 885          }
 886 
 887          char getGlyph(int charCode) {
 888             final int origCharCode = charCode;
 889             int controlGlyph = getControlCodeGlyph(charCode, true);
 890             if (controlGlyph >= 0) {
 891                 return (char)controlGlyph;
 892             }
 893 
 894              if (xlat != null) {
 895                  charCode = xlat[charCode];
 896              }
 897 
 898              charCode -= firstCode;
 899              if (charCode < 0 || charCode >= entryCount) {
 900                   return getFormatCharGlyph(origCharCode);
 901              } else {
 902                   return glyphIdArray[charCode];
 903              }
 904          }
 905     }
 906 
 907     // Format 8: mixed 16-bit and 32-bit coverage
 908     // Seems unlikely this code will ever get tested as we look for
 909     // MS platform Cmaps and MS states (in the Opentype spec on their website)
 910     // that MS doesn't support this format
 911     static class CMapFormat8 extends CMap {
 912          byte[] is32 = new byte[8192];
 913          int nGroups;
 914          int[] startCharCode;
 915          int[] endCharCode;
 916          int[] startGlyphID;
 917 
 918          CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
 919 
 920              bbuffer.position(12);


1018             if (value >= 1 << 4) {
1019                 value >>= 4;
1020                 highBit += 4;
1021             }
1022 
1023             if (value >= 1 << 2) {
1024                 value >>= 2;
1025                 highBit += 2;
1026             }
1027 
1028             if (value >= 1 << 1) {
1029                 value >>= 1;
1030                 highBit += 1;
1031             }
1032 
1033             power = 1 << highBit;
1034             extra = numGroups - power;
1035         }
1036 
1037         char getGlyph(int charCode) {
1038             final int origCharCode = charCode;
1039             int controlGlyph = getControlCodeGlyph(charCode, false);
1040             if (controlGlyph >= 0) {
1041                 return (char)controlGlyph;
1042             }
1043             int probe = power;
1044             int range = 0;
1045 
1046             if (startCharCode[extra] <= charCode) {
1047                 range = extra;
1048             }
1049 
1050             while (probe > 1) {
1051                 probe >>= 1;
1052 
1053                 if (startCharCode[range+probe] <= charCode) {
1054                     range += probe;
1055                 }
1056             }
1057 
1058             if (startCharCode[range] <= charCode &&
1059                   endCharCode[range] >= charCode) {
1060                 return (char)
1061                     (startGlyphID[range] + (charCode - startCharCode[range]));
1062             }
1063 
1064             return getFormatCharGlyph(origCharCode);
1065         }
1066 
1067     }
1068 
1069     /* Used to substitute for bad Cmaps. */
1070     static class NullCMapClass extends CMap {
1071 
1072         char getGlyph(int charCode) {
1073             return 0;
1074         }
1075     }
1076 
1077     public static final NullCMapClass theNullCmap = new NullCMapClass();
1078 
1079     final int getControlCodeGlyph(int charCode, boolean noSurrogates) {
1080         if (charCode < 0x0010) {
1081             switch (charCode) {
1082             case 0x0009:
1083             case 0x000a:
1084             case 0x000d: return CharToGlyphMapper.INVISIBLE_GLYPH_ID;
1085             }
1086          } else if (noSurrogates && charCode >= 0xFFFF) {
1087             return 0;
1088         }
1089         return -1;
1090     }
1091 
1092     final char getFormatCharGlyph(int charCode) {
1093         if (charCode >= 0x200c) {
1094             if ((charCode <= 0x200f) ||
1095                 (charCode >= 0x2028 && charCode <= 0x202e) ||
1096                 (charCode >= 0x206a && charCode <= 0x206f)) {
1097                 return (char)CharToGlyphMapper.INVISIBLE_GLYPH_ID;


1098             }
1099         }
1100         return 0;
1101     }
1102 
1103     static class UVS {
1104         int numSelectors;
1105         int[] selector;
1106 
1107         //for Non-Default UVS Table
1108         int[] numUVSMapping;
1109         int[][] unicodeValue;
1110         char[][] glyphID;
1111 
1112         UVS(ByteBuffer buffer, int offset) {
1113             numSelectors = buffer.getInt(offset+6);
1114             selector = new int[numSelectors];
1115             numUVSMapping = new int[numSelectors];
1116             unicodeValue = new int[numSelectors][];
1117             glyphID = new char[numSelectors][];
1118 
1119             for (int i = 0; i < numSelectors; i++) {
1120                 buffer.position(offset + 10 + i * 11);


< prev index next >