Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" | 7 #include "core/fpdfapi/fpdf_font/ttgsubtable.h" |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "core/fxge/include/fx_freetype.h" | 11 #include "core/fxge/include/fx_freetype.h" |
| 12 #include "core/fxge/include/fx_ge.h" | 12 #include "core/fxge/include/fx_ge.h" |
| 13 #include "third_party/base/stl_util.h" | 13 #include "third_party/base/stl_util.h" |
| 14 | 14 |
| 15 CFX_GlyphMap::CFX_GlyphMap() {} | 15 CFX_GlyphMap::CFX_GlyphMap() {} |
| 16 | |
| 16 CFX_GlyphMap::~CFX_GlyphMap() {} | 17 CFX_GlyphMap::~CFX_GlyphMap() {} |
| 18 | |
| 17 extern "C" { | 19 extern "C" { |
| 18 static int _CompareInt(const void* p1, const void* p2) { | 20 static int _CompareInt(const void* p1, const void* p2) { |
| 19 return (*(uint32_t*)p1) - (*(uint32_t*)p2); | 21 return (*(uint32_t*)p1) - (*(uint32_t*)p2); |
| 20 } | 22 } |
| 21 }; | 23 }; |
| 24 | |
| 22 struct _IntPair { | 25 struct _IntPair { |
| 23 int32_t key; | 26 int32_t key; |
| 24 int32_t value; | 27 int32_t value; |
| 25 }; | 28 }; |
| 29 | |
| 26 void CFX_GlyphMap::SetAt(int key, int value) { | 30 void CFX_GlyphMap::SetAt(int key, int value) { |
| 27 uint32_t count = m_Buffer.GetSize() / sizeof(_IntPair); | 31 uint32_t count = m_Buffer.GetSize() / sizeof(_IntPair); |
| 28 _IntPair* buf = (_IntPair*)m_Buffer.GetBuffer(); | 32 _IntPair* buf = (_IntPair*)m_Buffer.GetBuffer(); |
| 29 _IntPair pair = {key, value}; | 33 _IntPair pair = {key, value}; |
| 30 if (count == 0 || key > buf[count - 1].key) { | 34 if (count == 0 || key > buf[count - 1].key) { |
| 31 m_Buffer.AppendBlock(&pair, sizeof(_IntPair)); | 35 m_Buffer.AppendBlock(&pair, sizeof(_IntPair)); |
| 32 return; | 36 return; |
| 33 } | 37 } |
| 34 int low = 0, high = count - 1; | 38 int low = 0, high = count - 1; |
| 35 while (low <= high) { | 39 while (low <= high) { |
| 36 int mid = (low + high) / 2; | 40 int mid = (low + high) / 2; |
| 37 if (buf[mid].key < key) { | 41 if (buf[mid].key < key) { |
| 38 low = mid + 1; | 42 low = mid + 1; |
| 39 } else if (buf[mid].key > key) { | 43 } else if (buf[mid].key > key) { |
| 40 high = mid - 1; | 44 high = mid - 1; |
| 41 } else { | 45 } else { |
| 42 buf[mid].value = value; | 46 buf[mid].value = value; |
| 43 return; | 47 return; |
| 44 } | 48 } |
| 45 } | 49 } |
| 46 m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair)); | 50 m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair)); |
| 47 } | 51 } |
| 52 | |
| 48 FX_BOOL CFX_GlyphMap::Lookup(int key, int& value) { | 53 FX_BOOL CFX_GlyphMap::Lookup(int key, int& value) { |
| 49 void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), | 54 void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), |
| 50 m_Buffer.GetSize() / sizeof(_IntPair), | 55 m_Buffer.GetSize() / sizeof(_IntPair), |
| 51 sizeof(_IntPair), _CompareInt); | 56 sizeof(_IntPair), _CompareInt); |
| 52 if (!pResult) { | 57 if (!pResult) { |
| 53 return FALSE; | 58 return FALSE; |
| 54 } | 59 } |
| 55 value = ((uint32_t*)pResult)[1]; | 60 value = ((uint32_t*)pResult)[1]; |
| 56 return TRUE; | 61 return TRUE; |
| 57 } | 62 } |
| 63 | |
| 64 CFX_CTTGSUBTable::CFX_CTTGSUBTable(void) | |
| 65 : m_bFeautureMapLoad(FALSE), loaded(false) {} | |
| 66 | |
| 67 CFX_CTTGSUBTable::CFX_CTTGSUBTable(FT_Bytes gsub) | |
| 68 : m_bFeautureMapLoad(FALSE), loaded(false) { | |
| 69 LoadGSUBTable(gsub); | |
| 70 } | |
| 71 | |
| 72 CFX_CTTGSUBTable::~CFX_CTTGSUBTable() {} | |
| 73 bool CFX_CTTGSUBTable::IsOk(void) const { | |
|
dsinclair
2016/06/13 20:24:07
nit: blank line above.
Wei Li
2016/06/13 21:38:03
Done.
| |
| 74 return loaded; | |
| 75 } | |
| 76 | |
| 58 bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub) { | 77 bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub) { |
| 59 header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3]; | 78 header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3]; |
| 60 if (header.Version != 0x00010000) { | 79 if (header.Version != 0x00010000) { |
| 61 return false; | 80 return false; |
| 62 } | 81 } |
| 63 header.ScriptList = gsub[4] << 8 | gsub[5]; | 82 header.ScriptList = gsub[4] << 8 | gsub[5]; |
| 64 header.FeatureList = gsub[6] << 8 | gsub[7]; | 83 header.FeatureList = gsub[6] << 8 | gsub[7]; |
| 65 header.LookupList = gsub[8] << 8 | gsub[9]; | 84 header.LookupList = gsub[8] << 8 | gsub[9]; |
| 66 return Parse(&gsub[header.ScriptList], &gsub[header.FeatureList], | 85 return Parse(&gsub[header.ScriptList], &gsub[header.FeatureList], |
| 67 &gsub[header.LookupList]); | 86 &gsub[header.LookupList]); |
| 68 } | 87 } |
| 88 | |
| 69 bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, | 89 bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, |
| 70 uint32_t* vglyphnum) { | 90 uint32_t* vglyphnum) { |
| 71 uint32_t tag[] = { | 91 uint32_t tag[] = { |
| 72 (uint8_t)'v' << 24 | (uint8_t)'r' << 16 | (uint8_t)'t' << 8 | | 92 (uint8_t)'v' << 24 | (uint8_t)'r' << 16 | (uint8_t)'t' << 8 | |
| 73 (uint8_t)'2', | 93 (uint8_t)'2', |
| 74 (uint8_t)'v' << 24 | (uint8_t)'e' << 16 | (uint8_t)'r' << 8 | | 94 (uint8_t)'v' << 24 | (uint8_t)'e' << 16 | (uint8_t)'r' << 8 | |
| 75 (uint8_t)'t', | 95 (uint8_t)'t', |
| 76 }; | 96 }; |
| 77 if (!m_bFeautureMapLoad) { | 97 if (!m_bFeautureMapLoad) { |
| 78 for (int i = 0; i < ScriptList.ScriptCount; i++) { | 98 for (int i = 0; i < ScriptList.ScriptCount; i++) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 106 m_bFeautureMapLoad = TRUE; | 126 m_bFeautureMapLoad = TRUE; |
| 107 } | 127 } |
| 108 for (const auto& pair : m_featureMap) { | 128 for (const auto& pair : m_featureMap) { |
| 109 if (GetVerticalGlyphSub(glyphnum, vglyphnum, | 129 if (GetVerticalGlyphSub(glyphnum, vglyphnum, |
| 110 &FeatureList.FeatureRecord[pair.second].Feature)) { | 130 &FeatureList.FeatureRecord[pair.second].Feature)) { |
| 111 return true; | 131 return true; |
| 112 } | 132 } |
| 113 } | 133 } |
| 114 return false; | 134 return false; |
| 115 } | 135 } |
| 136 | |
| 116 bool CFX_CTTGSUBTable::GetVerticalGlyphSub(uint32_t glyphnum, | 137 bool CFX_CTTGSUBTable::GetVerticalGlyphSub(uint32_t glyphnum, |
| 117 uint32_t* vglyphnum, | 138 uint32_t* vglyphnum, |
| 118 struct TFeature* Feature) { | 139 struct TFeature* Feature) const { |
| 119 for (int i = 0; i < Feature->LookupCount; i++) { | 140 for (int i = 0; i < Feature->LookupCount; i++) { |
| 120 int index = Feature->LookupListIndex[i]; | 141 int index = Feature->LookupListIndex[i]; |
| 121 if (index < 0 || LookupList.LookupCount < index) { | 142 if (index < 0 || LookupList.LookupCount < index) { |
| 122 continue; | 143 continue; |
| 123 } | 144 } |
| 124 if (LookupList.Lookup[index].LookupType == 1) { | 145 if (LookupList.Lookup[index].LookupType == 1) { |
| 125 if (GetVerticalGlyphSub2(glyphnum, vglyphnum, | 146 if (GetVerticalGlyphSub2(glyphnum, vglyphnum, |
| 126 &LookupList.Lookup[index])) { | 147 &LookupList.Lookup[index])) { |
| 127 return true; | 148 return true; |
| 128 } | 149 } |
| 129 } | 150 } |
| 130 } | 151 } |
| 131 return false; | 152 return false; |
| 132 } | 153 } |
| 154 | |
| 133 bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, | 155 bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, |
| 134 uint32_t* vglyphnum, | 156 uint32_t* vglyphnum, |
| 135 struct TLookup* Lookup) { | 157 struct TLookup* Lookup) const { |
| 136 for (int i = 0; i < Lookup->SubTableCount; i++) { | 158 for (int i = 0; i < Lookup->SubTableCount; i++) { |
| 137 switch (Lookup->SubTable[i]->SubstFormat) { | 159 switch (Lookup->SubTable[i]->SubstFormat) { |
| 138 case 1: { | 160 case 1: { |
| 139 TSingleSubstFormat1* tbl1 = (TSingleSubstFormat1*)Lookup->SubTable[i]; | 161 TSingleSubstFormat1* tbl1 = (TSingleSubstFormat1*)Lookup->SubTable[i]; |
| 140 if (GetCoverageIndex(tbl1->Coverage, glyphnum) >= 0) { | 162 if (GetCoverageIndex(tbl1->Coverage, glyphnum) >= 0) { |
| 141 *vglyphnum = glyphnum + tbl1->DeltaGlyphID; | 163 *vglyphnum = glyphnum + tbl1->DeltaGlyphID; |
| 142 return true; | 164 return true; |
| 143 } | 165 } |
| 144 break; | 166 break; |
| 145 } | 167 } |
| 146 case 2: { | 168 case 2: { |
| 147 TSingleSubstFormat2* tbl2 = (TSingleSubstFormat2*)Lookup->SubTable[i]; | 169 TSingleSubstFormat2* tbl2 = (TSingleSubstFormat2*)Lookup->SubTable[i]; |
| 148 int index = -1; | 170 int index = -1; |
| 149 index = GetCoverageIndex(tbl2->Coverage, glyphnum); | 171 index = GetCoverageIndex(tbl2->Coverage, glyphnum); |
| 150 if (0 <= index && index < tbl2->GlyphCount) { | 172 if (0 <= index && index < tbl2->GlyphCount) { |
| 151 *vglyphnum = tbl2->Substitute[index]; | 173 *vglyphnum = tbl2->Substitute[index]; |
| 152 return true; | 174 return true; |
| 153 } | 175 } |
| 154 break; | 176 break; |
| 155 } | 177 } |
| 156 } | 178 } |
| 157 } | 179 } |
| 158 return false; | 180 return false; |
| 159 } | 181 } |
| 182 | |
| 160 int CFX_CTTGSUBTable::GetCoverageIndex(struct TCoverageFormatBase* Coverage, | 183 int CFX_CTTGSUBTable::GetCoverageIndex(struct TCoverageFormatBase* Coverage, |
| 161 uint32_t g) { | 184 uint32_t g) const { |
| 162 int i = 0; | 185 int i = 0; |
| 163 if (!Coverage) { | 186 if (!Coverage) { |
| 164 return -1; | 187 return -1; |
| 165 } | 188 } |
| 166 switch (Coverage->CoverageFormat) { | 189 switch (Coverage->CoverageFormat) { |
| 167 case 1: { | 190 case 1: { |
| 168 TCoverageFormat1* c1 = (TCoverageFormat1*)Coverage; | 191 TCoverageFormat1* c1 = (TCoverageFormat1*)Coverage; |
| 169 for (i = 0; i < c1->GlyphCount; i++) { | 192 for (i = 0; i < c1->GlyphCount; i++) { |
| 170 if ((uint32_t)c1->GlyphArray[i] == g) { | 193 if ((uint32_t)c1->GlyphArray[i] == g) { |
| 171 return i; | 194 return i; |
| 172 } | 195 } |
| 173 } | 196 } |
| 174 return -1; | 197 return -1; |
| 175 } | 198 } |
| 176 case 2: { | 199 case 2: { |
| 177 TCoverageFormat2* c2 = (TCoverageFormat2*)Coverage; | 200 TCoverageFormat2* c2 = (TCoverageFormat2*)Coverage; |
| 178 for (i = 0; i < c2->RangeCount; i++) { | 201 for (i = 0; i < c2->RangeCount; i++) { |
| 179 uint32_t s = c2->RangeRecord[i].Start; | 202 uint32_t s = c2->RangeRecord[i].Start; |
| 180 uint32_t e = c2->RangeRecord[i].End; | 203 uint32_t e = c2->RangeRecord[i].End; |
| 181 uint32_t si = c2->RangeRecord[i].StartCoverageIndex; | 204 uint32_t si = c2->RangeRecord[i].StartCoverageIndex; |
| 182 if (s <= g && g <= e) { | 205 if (s <= g && g <= e) { |
| 183 return si + g - s; | 206 return si + g - s; |
| 184 } | 207 } |
| 185 } | 208 } |
| 186 return -1; | 209 return -1; |
| 187 } | 210 } |
| 188 } | 211 } |
| 189 return -1; | 212 return -1; |
| 190 } | 213 } |
| 214 | |
| 215 uint8_t CFX_CTTGSUBTable::GetUInt8(FT_Bytes& p) const { | |
| 216 uint8_t ret = p[0]; | |
| 217 p += 1; | |
| 218 return ret; | |
| 219 } | |
| 220 | |
| 221 int16_t CFX_CTTGSUBTable::GetInt16(FT_Bytes& p) const { | |
| 222 uint16_t ret = p[0] << 8 | p[1]; | |
| 223 p += 2; | |
| 224 return *(int16_t*)&ret; | |
| 225 } | |
| 226 | |
| 227 uint16_t CFX_CTTGSUBTable::GetUInt16(FT_Bytes& p) const { | |
| 228 uint16_t ret = p[0] << 8 | p[1]; | |
| 229 p += 2; | |
| 230 return ret; | |
| 231 } | |
| 232 | |
| 233 int32_t CFX_CTTGSUBTable::GetInt32(FT_Bytes& p) const { | |
| 234 uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; | |
| 235 p += 4; | |
| 236 return *(int32_t*)&ret; | |
| 237 } | |
| 238 | |
| 239 uint32_t CFX_CTTGSUBTable::GetUInt32(FT_Bytes& p) const { | |
| 240 uint32_t ret = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; | |
| 241 p += 4; | |
| 242 return ret; | |
| 243 } | |
| 244 | |
| 191 bool CFX_CTTGSUBTable::Parse(FT_Bytes scriptlist, | 245 bool CFX_CTTGSUBTable::Parse(FT_Bytes scriptlist, |
| 192 FT_Bytes featurelist, | 246 FT_Bytes featurelist, |
| 193 FT_Bytes lookuplist) { | 247 FT_Bytes lookuplist) { |
| 194 ParseScriptList(scriptlist, &ScriptList); | 248 ParseScriptList(scriptlist, &ScriptList); |
| 195 ParseFeatureList(featurelist, &FeatureList); | 249 ParseFeatureList(featurelist, &FeatureList); |
| 196 ParseLookupList(lookuplist, &LookupList); | 250 ParseLookupList(lookuplist, &LookupList); |
| 197 return true; | 251 return true; |
| 198 } | 252 } |
| 253 | |
| 199 void CFX_CTTGSUBTable::ParseScriptList(FT_Bytes raw, struct TScriptList* rec) { | 254 void CFX_CTTGSUBTable::ParseScriptList(FT_Bytes raw, struct TScriptList* rec) { |
| 200 int i; | 255 int i; |
| 201 FT_Bytes sp = raw; | 256 FT_Bytes sp = raw; |
| 202 rec->ScriptCount = GetUInt16(sp); | 257 rec->ScriptCount = GetUInt16(sp); |
| 203 if (rec->ScriptCount <= 0) { | 258 if (rec->ScriptCount <= 0) { |
| 204 return; | 259 return; |
| 205 } | 260 } |
| 206 rec->ScriptRecord = new struct TScriptRecord[rec->ScriptCount]; | 261 rec->ScriptRecord = new struct TScriptRecord[rec->ScriptCount]; |
| 207 for (i = 0; i < rec->ScriptCount; i++) { | 262 for (i = 0; i < rec->ScriptCount; i++) { |
| 208 rec->ScriptRecord[i].ScriptTag = GetUInt32(sp); | 263 rec->ScriptRecord[i].ScriptTag = GetUInt32(sp); |
| 209 uint16_t offset = GetUInt16(sp); | 264 uint16_t offset = GetUInt16(sp); |
| 210 ParseScript(&raw[offset], &rec->ScriptRecord[i].Script); | 265 ParseScript(&raw[offset], &rec->ScriptRecord[i].Script); |
| 211 } | 266 } |
| 212 } | 267 } |
| 268 | |
| 213 void CFX_CTTGSUBTable::ParseScript(FT_Bytes raw, struct TScript* rec) { | 269 void CFX_CTTGSUBTable::ParseScript(FT_Bytes raw, struct TScript* rec) { |
| 214 int i; | 270 int i; |
| 215 FT_Bytes sp = raw; | 271 FT_Bytes sp = raw; |
| 216 rec->DefaultLangSys = GetUInt16(sp); | 272 rec->DefaultLangSys = GetUInt16(sp); |
| 217 rec->LangSysCount = GetUInt16(sp); | 273 rec->LangSysCount = GetUInt16(sp); |
| 218 if (rec->LangSysCount <= 0) { | 274 if (rec->LangSysCount <= 0) { |
| 219 return; | 275 return; |
| 220 } | 276 } |
| 221 rec->LangSysRecord = new struct TLangSysRecord[rec->LangSysCount]; | 277 rec->LangSysRecord = new struct TLangSysRecord[rec->LangSysCount]; |
| 222 for (i = 0; i < rec->LangSysCount; i++) { | 278 for (i = 0; i < rec->LangSysCount; i++) { |
| 223 rec->LangSysRecord[i].LangSysTag = GetUInt32(sp); | 279 rec->LangSysRecord[i].LangSysTag = GetUInt32(sp); |
| 224 uint16_t offset = GetUInt16(sp); | 280 uint16_t offset = GetUInt16(sp); |
| 225 ParseLangSys(&raw[offset], &rec->LangSysRecord[i].LangSys); | 281 ParseLangSys(&raw[offset], &rec->LangSysRecord[i].LangSys); |
| 226 } | 282 } |
| 227 } | 283 } |
| 284 | |
| 228 void CFX_CTTGSUBTable::ParseLangSys(FT_Bytes raw, struct TLangSys* rec) { | 285 void CFX_CTTGSUBTable::ParseLangSys(FT_Bytes raw, struct TLangSys* rec) { |
| 229 FT_Bytes sp = raw; | 286 FT_Bytes sp = raw; |
| 230 rec->LookupOrder = GetUInt16(sp); | 287 rec->LookupOrder = GetUInt16(sp); |
| 231 rec->ReqFeatureIndex = GetUInt16(sp); | 288 rec->ReqFeatureIndex = GetUInt16(sp); |
| 232 rec->FeatureCount = GetUInt16(sp); | 289 rec->FeatureCount = GetUInt16(sp); |
| 233 if (rec->FeatureCount <= 0) { | 290 if (rec->FeatureCount <= 0) { |
| 234 return; | 291 return; |
| 235 } | 292 } |
| 236 rec->FeatureIndex = new uint16_t[rec->FeatureCount]; | 293 rec->FeatureIndex = new uint16_t[rec->FeatureCount]; |
| 237 FXSYS_memset(rec->FeatureIndex, 0, sizeof(uint16_t) * rec->FeatureCount); | 294 FXSYS_memset(rec->FeatureIndex, 0, sizeof(uint16_t) * rec->FeatureCount); |
| 238 for (int i = 0; i < rec->FeatureCount; ++i) { | 295 for (int i = 0; i < rec->FeatureCount; ++i) { |
| 239 rec->FeatureIndex[i] = GetUInt16(sp); | 296 rec->FeatureIndex[i] = GetUInt16(sp); |
| 240 } | 297 } |
| 241 } | 298 } |
| 299 | |
| 242 void CFX_CTTGSUBTable::ParseFeatureList(FT_Bytes raw, TFeatureList* rec) { | 300 void CFX_CTTGSUBTable::ParseFeatureList(FT_Bytes raw, TFeatureList* rec) { |
| 243 int i; | 301 int i; |
| 244 FT_Bytes sp = raw; | 302 FT_Bytes sp = raw; |
| 245 rec->FeatureCount = GetUInt16(sp); | 303 rec->FeatureCount = GetUInt16(sp); |
| 246 if (rec->FeatureCount <= 0) { | 304 if (rec->FeatureCount <= 0) { |
| 247 return; | 305 return; |
| 248 } | 306 } |
| 249 rec->FeatureRecord = new struct TFeatureRecord[rec->FeatureCount]; | 307 rec->FeatureRecord = new struct TFeatureRecord[rec->FeatureCount]; |
| 250 for (i = 0; i < rec->FeatureCount; i++) { | 308 for (i = 0; i < rec->FeatureCount; i++) { |
| 251 rec->FeatureRecord[i].FeatureTag = GetUInt32(sp); | 309 rec->FeatureRecord[i].FeatureTag = GetUInt32(sp); |
| 252 uint16_t offset = GetUInt16(sp); | 310 uint16_t offset = GetUInt16(sp); |
| 253 ParseFeature(&raw[offset], &rec->FeatureRecord[i].Feature); | 311 ParseFeature(&raw[offset], &rec->FeatureRecord[i].Feature); |
| 254 } | 312 } |
| 255 } | 313 } |
| 314 | |
| 256 void CFX_CTTGSUBTable::ParseFeature(FT_Bytes raw, TFeature* rec) { | 315 void CFX_CTTGSUBTable::ParseFeature(FT_Bytes raw, TFeature* rec) { |
| 257 int i; | 316 int i; |
| 258 FT_Bytes sp = raw; | 317 FT_Bytes sp = raw; |
| 259 rec->FeatureParams = GetUInt16(sp); | 318 rec->FeatureParams = GetUInt16(sp); |
| 260 rec->LookupCount = GetUInt16(sp); | 319 rec->LookupCount = GetUInt16(sp); |
| 261 if (rec->LookupCount <= 0) { | 320 if (rec->LookupCount <= 0) { |
| 262 return; | 321 return; |
| 263 } | 322 } |
| 264 rec->LookupListIndex = new uint16_t[rec->LookupCount]; | 323 rec->LookupListIndex = new uint16_t[rec->LookupCount]; |
| 265 for (i = 0; i < rec->LookupCount; i++) { | 324 for (i = 0; i < rec->LookupCount; i++) { |
| 266 rec->LookupListIndex[i] = GetUInt16(sp); | 325 rec->LookupListIndex[i] = GetUInt16(sp); |
| 267 } | 326 } |
| 268 } | 327 } |
| 328 | |
| 269 void CFX_CTTGSUBTable::ParseLookupList(FT_Bytes raw, TLookupList* rec) { | 329 void CFX_CTTGSUBTable::ParseLookupList(FT_Bytes raw, TLookupList* rec) { |
| 270 int i; | 330 int i; |
| 271 FT_Bytes sp = raw; | 331 FT_Bytes sp = raw; |
| 272 rec->LookupCount = GetUInt16(sp); | 332 rec->LookupCount = GetUInt16(sp); |
| 273 if (rec->LookupCount <= 0) { | 333 if (rec->LookupCount <= 0) { |
| 274 return; | 334 return; |
| 275 } | 335 } |
| 276 rec->Lookup = new struct TLookup[rec->LookupCount]; | 336 rec->Lookup = new struct TLookup[rec->LookupCount]; |
| 277 for (i = 0; i < rec->LookupCount; i++) { | 337 for (i = 0; i < rec->LookupCount; i++) { |
| 278 uint16_t offset = GetUInt16(sp); | 338 uint16_t offset = GetUInt16(sp); |
| 279 ParseLookup(&raw[offset], &rec->Lookup[i]); | 339 ParseLookup(&raw[offset], &rec->Lookup[i]); |
| 280 } | 340 } |
| 281 } | 341 } |
| 342 | |
| 282 void CFX_CTTGSUBTable::ParseLookup(FT_Bytes raw, TLookup* rec) { | 343 void CFX_CTTGSUBTable::ParseLookup(FT_Bytes raw, TLookup* rec) { |
| 283 int i; | 344 int i; |
| 284 FT_Bytes sp = raw; | 345 FT_Bytes sp = raw; |
| 285 rec->LookupType = GetUInt16(sp); | 346 rec->LookupType = GetUInt16(sp); |
| 286 rec->LookupFlag = GetUInt16(sp); | 347 rec->LookupFlag = GetUInt16(sp); |
| 287 rec->SubTableCount = GetUInt16(sp); | 348 rec->SubTableCount = GetUInt16(sp); |
| 288 if (rec->SubTableCount <= 0) { | 349 if (rec->SubTableCount <= 0) { |
| 289 return; | 350 return; |
| 290 } | 351 } |
| 291 rec->SubTable = new struct TSubTableBase*[rec->SubTableCount]; | 352 rec->SubTable = new struct TSubTableBase*[rec->SubTableCount]; |
| 292 for (i = 0; i < rec->SubTableCount; i++) { | 353 for (i = 0; i < rec->SubTableCount; i++) { |
| 293 rec->SubTable[i] = nullptr; | 354 rec->SubTable[i] = nullptr; |
| 294 } | 355 } |
| 295 if (rec->LookupType != 1) { | 356 if (rec->LookupType != 1) { |
| 296 return; | 357 return; |
| 297 } | 358 } |
| 298 for (i = 0; i < rec->SubTableCount; i++) { | 359 for (i = 0; i < rec->SubTableCount; i++) { |
| 299 uint16_t offset = GetUInt16(sp); | 360 uint16_t offset = GetUInt16(sp); |
| 300 ParseSingleSubst(&raw[offset], &rec->SubTable[i]); | 361 ParseSingleSubst(&raw[offset], &rec->SubTable[i]); |
| 301 } | 362 } |
| 302 } | 363 } |
| 364 | |
| 303 void CFX_CTTGSUBTable::ParseCoverage(FT_Bytes raw, TCoverageFormatBase** rec) { | 365 void CFX_CTTGSUBTable::ParseCoverage(FT_Bytes raw, TCoverageFormatBase** rec) { |
| 304 FT_Bytes sp = raw; | 366 FT_Bytes sp = raw; |
| 305 uint16_t Format = GetUInt16(sp); | 367 uint16_t Format = GetUInt16(sp); |
| 306 switch (Format) { | 368 switch (Format) { |
| 307 case 1: | 369 case 1: |
| 308 *rec = new TCoverageFormat1(); | 370 *rec = new TCoverageFormat1(); |
| 309 ParseCoverageFormat1(raw, (TCoverageFormat1*)*rec); | 371 ParseCoverageFormat1(raw, (TCoverageFormat1*)*rec); |
| 310 break; | 372 break; |
| 311 case 2: | 373 case 2: |
| 312 *rec = new TCoverageFormat2(); | 374 *rec = new TCoverageFormat2(); |
| 313 ParseCoverageFormat2(raw, (TCoverageFormat2*)*rec); | 375 ParseCoverageFormat2(raw, (TCoverageFormat2*)*rec); |
| 314 break; | 376 break; |
| 315 } | 377 } |
| 316 } | 378 } |
| 379 | |
| 317 void CFX_CTTGSUBTable::ParseCoverageFormat1(FT_Bytes raw, | 380 void CFX_CTTGSUBTable::ParseCoverageFormat1(FT_Bytes raw, |
| 318 TCoverageFormat1* rec) { | 381 TCoverageFormat1* rec) { |
| 319 int i; | 382 int i; |
| 320 FT_Bytes sp = raw; | 383 FT_Bytes sp = raw; |
| 321 GetUInt16(sp); | 384 GetUInt16(sp); |
| 322 rec->GlyphCount = GetUInt16(sp); | 385 rec->GlyphCount = GetUInt16(sp); |
| 323 if (rec->GlyphCount <= 0) { | 386 if (rec->GlyphCount <= 0) { |
| 324 return; | 387 return; |
| 325 } | 388 } |
| 326 rec->GlyphArray = new uint16_t[rec->GlyphCount]; | 389 rec->GlyphArray = new uint16_t[rec->GlyphCount]; |
| 327 for (i = 0; i < rec->GlyphCount; i++) { | 390 for (i = 0; i < rec->GlyphCount; i++) { |
| 328 rec->GlyphArray[i] = GetUInt16(sp); | 391 rec->GlyphArray[i] = GetUInt16(sp); |
| 329 } | 392 } |
| 330 } | 393 } |
| 394 | |
| 331 void CFX_CTTGSUBTable::ParseCoverageFormat2(FT_Bytes raw, | 395 void CFX_CTTGSUBTable::ParseCoverageFormat2(FT_Bytes raw, |
| 332 TCoverageFormat2* rec) { | 396 TCoverageFormat2* rec) { |
| 333 int i; | 397 int i; |
| 334 FT_Bytes sp = raw; | 398 FT_Bytes sp = raw; |
| 335 GetUInt16(sp); | 399 GetUInt16(sp); |
| 336 rec->RangeCount = GetUInt16(sp); | 400 rec->RangeCount = GetUInt16(sp); |
| 337 if (rec->RangeCount <= 0) { | 401 if (rec->RangeCount <= 0) { |
| 338 return; | 402 return; |
| 339 } | 403 } |
| 340 rec->RangeRecord = new TRangeRecord[rec->RangeCount]; | 404 rec->RangeRecord = new TRangeRecord[rec->RangeCount]; |
| 341 for (i = 0; i < rec->RangeCount; i++) { | 405 for (i = 0; i < rec->RangeCount; i++) { |
| 342 rec->RangeRecord[i].Start = GetUInt16(sp); | 406 rec->RangeRecord[i].Start = GetUInt16(sp); |
| 343 rec->RangeRecord[i].End = GetUInt16(sp); | 407 rec->RangeRecord[i].End = GetUInt16(sp); |
| 344 rec->RangeRecord[i].StartCoverageIndex = GetUInt16(sp); | 408 rec->RangeRecord[i].StartCoverageIndex = GetUInt16(sp); |
| 345 } | 409 } |
| 346 } | 410 } |
| 411 | |
| 347 void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec) { | 412 void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec) { |
| 348 FT_Bytes sp = raw; | 413 FT_Bytes sp = raw; |
| 349 uint16_t Format = GetUInt16(sp); | 414 uint16_t Format = GetUInt16(sp); |
| 350 switch (Format) { | 415 switch (Format) { |
| 351 case 1: | 416 case 1: |
| 352 *rec = new TSingleSubstFormat1(); | 417 *rec = new TSingleSubstFormat1(); |
| 353 ParseSingleSubstFormat1(raw, (TSingleSubstFormat1*)*rec); | 418 ParseSingleSubstFormat1(raw, (TSingleSubstFormat1*)*rec); |
| 354 break; | 419 break; |
| 355 case 2: | 420 case 2: |
| 356 *rec = new TSingleSubstFormat2(); | 421 *rec = new TSingleSubstFormat2(); |
| 357 ParseSingleSubstFormat2(raw, (TSingleSubstFormat2*)*rec); | 422 ParseSingleSubstFormat2(raw, (TSingleSubstFormat2*)*rec); |
| 358 break; | 423 break; |
| 359 } | 424 } |
| 360 } | 425 } |
| 426 | |
| 361 void CFX_CTTGSUBTable::ParseSingleSubstFormat1(FT_Bytes raw, | 427 void CFX_CTTGSUBTable::ParseSingleSubstFormat1(FT_Bytes raw, |
| 362 TSingleSubstFormat1* rec) { | 428 TSingleSubstFormat1* rec) { |
| 363 FT_Bytes sp = raw; | 429 FT_Bytes sp = raw; |
| 364 GetUInt16(sp); | 430 GetUInt16(sp); |
| 365 uint16_t offset = GetUInt16(sp); | 431 uint16_t offset = GetUInt16(sp); |
| 366 ParseCoverage(&raw[offset], &rec->Coverage); | 432 ParseCoverage(&raw[offset], &rec->Coverage); |
| 367 rec->DeltaGlyphID = GetInt16(sp); | 433 rec->DeltaGlyphID = GetInt16(sp); |
| 368 } | 434 } |
| 435 | |
| 369 void CFX_CTTGSUBTable::ParseSingleSubstFormat2(FT_Bytes raw, | 436 void CFX_CTTGSUBTable::ParseSingleSubstFormat2(FT_Bytes raw, |
| 370 TSingleSubstFormat2* rec) { | 437 TSingleSubstFormat2* rec) { |
| 371 int i; | 438 int i; |
| 372 FT_Bytes sp = raw; | 439 FT_Bytes sp = raw; |
| 373 GetUInt16(sp); | 440 GetUInt16(sp); |
| 374 uint16_t offset = GetUInt16(sp); | 441 uint16_t offset = GetUInt16(sp); |
| 375 ParseCoverage(&raw[offset], &rec->Coverage); | 442 ParseCoverage(&raw[offset], &rec->Coverage); |
| 376 rec->GlyphCount = GetUInt16(sp); | 443 rec->GlyphCount = GetUInt16(sp); |
| 377 if (rec->GlyphCount <= 0) { | 444 if (rec->GlyphCount <= 0) { |
| 378 return; | 445 return; |
| 379 } | 446 } |
| 380 rec->Substitute = new uint16_t[rec->GlyphCount]; | 447 rec->Substitute = new uint16_t[rec->GlyphCount]; |
| 381 for (i = 0; i < rec->GlyphCount; i++) { | 448 for (i = 0; i < rec->GlyphCount; i++) { |
| 382 rec->Substitute[i] = GetUInt16(sp); | 449 rec->Substitute[i] = GetUInt16(sp); |
| 383 } | 450 } |
| 384 } | 451 } |
| 452 | |
| 453 CFX_CTTGSUBTable::TCoverageFormat1::TCoverageFormat1() | |
| 454 : GlyphCount(0), GlyphArray(nullptr) { | |
| 455 CoverageFormat = 1; | |
| 456 } | |
| 457 | |
| 458 CFX_CTTGSUBTable::TCoverageFormat1::~TCoverageFormat1() { | |
| 459 delete[] GlyphArray; | |
| 460 } | |
| 461 | |
| 462 CFX_CTTGSUBTable::TRangeRecord::TRangeRecord() | |
| 463 : Start(0), End(0), StartCoverageIndex(0) {} | |
| 464 | |
| 465 CFX_CTTGSUBTable::TCoverageFormat2::TCoverageFormat2() | |
| 466 : RangeCount(0), RangeRecord(nullptr) { | |
| 467 CoverageFormat = 2; | |
| 468 } | |
| 469 | |
| 470 CFX_CTTGSUBTable::TCoverageFormat2::~TCoverageFormat2() { | |
| 471 delete[] RangeRecord; | |
| 472 } | |
| 473 | |
| 474 CFX_CTTGSUBTable::TClassDefFormat1::TClassDefFormat1() | |
| 475 : StartGlyph(0), GlyphCount(0), ClassValueArray(nullptr) { | |
| 476 ClassFormat = 1; | |
| 477 } | |
| 478 | |
| 479 CFX_CTTGSUBTable::TClassDefFormat1::~TClassDefFormat1() { | |
| 480 delete[] ClassValueArray; | |
| 481 } | |
| 482 | |
| 483 CFX_CTTGSUBTable::TClassDefFormat2::TClassDefFormat2() | |
| 484 : ClassRangeCount(0), ClassRangeRecord(nullptr) { | |
| 485 ClassFormat = 2; | |
| 486 } | |
| 487 | |
| 488 CFX_CTTGSUBTable::TClassDefFormat2::~TClassDefFormat2() { | |
| 489 delete[] ClassRangeRecord; | |
| 490 } | |
| 491 | |
| 492 CFX_CTTGSUBTable::TSingleSubstFormat1::TSingleSubstFormat1() | |
| 493 : Coverage(nullptr), DeltaGlyphID(0) { | |
| 494 SubstFormat = 1; | |
| 495 } | |
| 496 | |
| 497 CFX_CTTGSUBTable::TSingleSubstFormat1::~TSingleSubstFormat1() { | |
| 498 delete Coverage; | |
| 499 } | |
| 500 | |
| 501 CFX_CTTGSUBTable::TSingleSubstFormat2::TSingleSubstFormat2() | |
| 502 : Coverage(nullptr), GlyphCount(0), Substitute(nullptr) { | |
| 503 SubstFormat = 2; | |
| 504 } | |
| 505 | |
| 506 CFX_CTTGSUBTable::TSingleSubstFormat2::~TSingleSubstFormat2() { | |
| 507 delete Coverage; | |
| 508 delete[] Substitute; | |
| 509 } | |
| 510 | |
| 511 CFX_CTTGSUBTable::TLookup::TLookup() | |
| 512 : LookupType(0), LookupFlag(0), SubTableCount(0), SubTable(nullptr) {} | |
| 513 | |
| 514 CFX_CTTGSUBTable::TLookup::~TLookup() { | |
| 515 if (SubTable) { | |
| 516 for (int i = 0; i < SubTableCount; ++i) | |
| 517 delete SubTable[i]; | |
| 518 delete[] SubTable; | |
| 519 } | |
| 520 } | |
| OLD | NEW |