Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: core/fpdfapi/fpdf_font/ttgsubtable.cpp

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

Powered by Google App Engine
This is Rietveld 408576698