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