1 31 package org.pdfbox.ttf; 32 33 import java.io.IOException ; 34 35 41 public class CMAPEncodingEntry 42 { 43 44 private int platformId; 45 private int platformEncodingId; 46 private long subTableOffset; 47 private int[] glyphIdToCharacterCode; 48 55 public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException 56 { 57 platformId = data.readUnsignedShort(); 58 platformEncodingId = data.readUnsignedShort(); 59 subTableOffset = data.readUnsignedInt(); 60 } 61 62 69 public void initSubtable( TrueTypeFont ttf, TTFDataStream data ) throws IOException 70 { 71 data.seek( ttf.getCMAP().getOffset() + subTableOffset ); 72 int subtableFormat = data.readUnsignedShort(); 73 int length = data.readUnsignedShort(); 74 int version = data.readUnsignedShort(); 75 int numGlyphs = ttf.getMaximumProfile().getNumGlyphs(); 76 if( subtableFormat == 0 ) 77 { 78 byte[] glyphMapping = data.read( 256 ); 79 glyphIdToCharacterCode = new int[256]; 80 for( int i=0;i<glyphMapping.length; i++ ) 81 { 82 glyphIdToCharacterCode[i]=(glyphMapping[i]+256)%256; 83 } 84 } 85 else if( subtableFormat == 2 ) 86 { 87 int[] subHeaderKeys = new int[256]; 88 for( int i=0; i<256; i++) 89 { 90 subHeaderKeys[i] = data.readUnsignedShort(); 91 } 92 int firstCode = data.readUnsignedShort(); 93 int entryCount = data.readUnsignedShort(); 94 short idDelta = data.readSignedShort(); 95 int idRangeOffset = data.readUnsignedShort(); 96 throw new IOException ( "Not yet implemented:" + subtableFormat ); 101 } 102 else if( subtableFormat == 4 ) 103 { 104 int segCountX2 = data.readUnsignedShort(); 105 int segCount = segCountX2/2; 106 int searchRange = data.readUnsignedShort(); 107 int entrySelector = data.readUnsignedShort(); 108 int rangeShift = data.readUnsignedShort(); 109 int[] endCount = data.readUnsignedShortArray( segCount ); 110 int reservedPad = data.readUnsignedShort(); 111 int[] startCount = data.readUnsignedShortArray( segCount ); 112 int[] idDelta = data.readUnsignedShortArray( segCount ); 113 int[] idRangeOffset = data.readUnsignedShortArray( segCount ); 114 115 glyphIdToCharacterCode = new int[numGlyphs]; 118 119 long currentPosition = data.getCurrentPosition(); 120 121 for( int i=0; i<segCount; i++ ) 122 { 123 int start = startCount[i]; 124 int end = endCount[i]; 125 int delta = idDelta[i]; 126 int rangeOffset = idRangeOffset[i]; 127 if( start != 65536 && end != 65536 ) 128 { 129 for( int j=start; j<=end; j++ ) 130 { 131 if( rangeOffset == 0 ) 132 { 133 glyphIdToCharacterCode[ ((j+delta)%65536) ]=j; 134 } 135 else 136 { 137 long glyphOffset = currentPosition + 138 ((rangeOffset/2) + (j-start) + (i-segCount))*2; data.seek( glyphOffset ); 142 int glyphIndex = data.readUnsignedShort(); 143 if( glyphIndex != 0 ) 144 { 145 glyphIndex += delta; 146 glyphIndex = glyphIndex % 65536; 147 if( glyphIdToCharacterCode[glyphIndex] == 0 ) 148 { 149 glyphIdToCharacterCode[glyphIndex] = j; 150 } 151 } 152 153 } 154 } 155 } 156 } 157 } 158 else if( subtableFormat == 6 ) 159 { 160 int firstCode = data.readUnsignedShort(); 161 int entryCount = data.readUnsignedShort(); 162 glyphIdToCharacterCode = new int[numGlyphs]; 163 int[] glyphIdArray = data.readUnsignedShortArray( entryCount ); 164 for( int i=0; i<entryCount; i++) 165 { 166 glyphIdToCharacterCode[glyphIdArray[i]] = firstCode+i; 167 } 168 } 169 else 170 { 171 throw new IOException ( "Unknown cmap format:" + subtableFormat ); 172 } 173 } 174 175 176 179 public int[] getGlyphIdToCharacterCode() 180 { 181 return glyphIdToCharacterCode; 182 } 183 186 public void setGlyphIdToCharacterCode(int[] glyphIdToCharacterCodeValue) 187 { 188 this.glyphIdToCharacterCode = glyphIdToCharacterCodeValue; 189 } 190 191 194 public int getPlatformEncodingId() 195 { 196 return platformEncodingId; 197 } 198 201 public void setPlatformEncodingId(int platformEncodingIdValue) 202 { 203 this.platformEncodingId = platformEncodingIdValue; 204 } 205 208 public int getPlatformId() 209 { 210 return platformId; 211 } 212 215 public void setPlatformId(int platformIdValue) 216 { 217 this.platformId = platformIdValue; 218 } 219 } 220 | Popular Tags |