| 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/include/fxge/fx_freetype.h" | 11 #include "core/include/fxge/fx_freetype.h" |
| 12 #include "core/include/fxge/fx_ge.h" | 12 #include "core/include/fxge/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 CFX_GlyphMap::~CFX_GlyphMap() {} | 16 CFX_GlyphMap::~CFX_GlyphMap() {} |
| 17 extern "C" { | 17 extern "C" { |
| 18 static int _CompareInt(const void* p1, const void* p2) { | 18 static int _CompareInt(const void* p1, const void* p2) { |
| 19 return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2); | 19 return (*(uint32_t*)p1) - (*(uint32_t*)p2); |
| 20 } | 20 } |
| 21 }; | 21 }; |
| 22 struct _IntPair { | 22 struct _IntPair { |
| 23 int32_t key; | 23 int32_t key; |
| 24 int32_t value; | 24 int32_t value; |
| 25 }; | 25 }; |
| 26 void CFX_GlyphMap::SetAt(int key, int value) { | 26 void CFX_GlyphMap::SetAt(int key, int value) { |
| 27 FX_DWORD count = m_Buffer.GetSize() / sizeof(_IntPair); | 27 uint32_t count = m_Buffer.GetSize() / sizeof(_IntPair); |
| 28 _IntPair* buf = (_IntPair*)m_Buffer.GetBuffer(); | 28 _IntPair* buf = (_IntPair*)m_Buffer.GetBuffer(); |
| 29 _IntPair pair = {key, value}; | 29 _IntPair pair = {key, value}; |
| 30 if (count == 0 || key > buf[count - 1].key) { | 30 if (count == 0 || key > buf[count - 1].key) { |
| 31 m_Buffer.AppendBlock(&pair, sizeof(_IntPair)); | 31 m_Buffer.AppendBlock(&pair, sizeof(_IntPair)); |
| 32 return; | 32 return; |
| 33 } | 33 } |
| 34 int low = 0, high = count - 1; | 34 int low = 0, high = count - 1; |
| 35 while (low <= high) { | 35 while (low <= high) { |
| 36 int mid = (low + high) / 2; | 36 int mid = (low + high) / 2; |
| 37 if (buf[mid].key < key) { | 37 if (buf[mid].key < key) { |
| 38 low = mid + 1; | 38 low = mid + 1; |
| 39 } else if (buf[mid].key > key) { | 39 } else if (buf[mid].key > key) { |
| 40 high = mid - 1; | 40 high = mid - 1; |
| 41 } else { | 41 } else { |
| 42 buf[mid].value = value; | 42 buf[mid].value = value; |
| 43 return; | 43 return; |
| 44 } | 44 } |
| 45 } | 45 } |
| 46 m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair)); | 46 m_Buffer.InsertBlock(low * sizeof(_IntPair), &pair, sizeof(_IntPair)); |
| 47 } | 47 } |
| 48 FX_BOOL CFX_GlyphMap::Lookup(int key, int& value) { | 48 FX_BOOL CFX_GlyphMap::Lookup(int key, int& value) { |
| 49 void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), | 49 void* pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), |
| 50 m_Buffer.GetSize() / sizeof(_IntPair), | 50 m_Buffer.GetSize() / sizeof(_IntPair), |
| 51 sizeof(_IntPair), _CompareInt); | 51 sizeof(_IntPair), _CompareInt); |
| 52 if (!pResult) { | 52 if (!pResult) { |
| 53 return FALSE; | 53 return FALSE; |
| 54 } | 54 } |
| 55 value = ((FX_DWORD*)pResult)[1]; | 55 value = ((uint32_t*)pResult)[1]; |
| 56 return TRUE; | 56 return TRUE; |
| 57 } | 57 } |
| 58 bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub) { | 58 bool CFX_CTTGSUBTable::LoadGSUBTable(FT_Bytes gsub) { |
| 59 header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3]; | 59 header.Version = gsub[0] << 24 | gsub[1] << 16 | gsub[2] << 8 | gsub[3]; |
| 60 if (header.Version != 0x00010000) { | 60 if (header.Version != 0x00010000) { |
| 61 return false; | 61 return false; |
| 62 } | 62 } |
| 63 header.ScriptList = gsub[4] << 8 | gsub[5]; | 63 header.ScriptList = gsub[4] << 8 | gsub[5]; |
| 64 header.FeatureList = gsub[6] << 8 | gsub[7]; | 64 header.FeatureList = gsub[6] << 8 | gsub[7]; |
| 65 header.LookupList = gsub[8] << 8 | gsub[9]; | 65 header.LookupList = gsub[8] << 8 | gsub[9]; |
| 66 return Parse(&gsub[header.ScriptList], &gsub[header.FeatureList], | 66 return Parse(&gsub[header.ScriptList], &gsub[header.FeatureList], |
| 67 &gsub[header.LookupList]); | 67 &gsub[header.LookupList]); |
| 68 } | 68 } |
| 69 bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, | 69 bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, |
| 70 uint32_t* vglyphnum) { | 70 uint32_t* vglyphnum) { |
| 71 uint32_t tag[] = { | 71 uint32_t tag[] = { |
| 72 (uint8_t)'v' << 24 | (uint8_t)'r' << 16 | (uint8_t)'t' << 8 | | 72 (uint8_t)'v' << 24 | (uint8_t)'r' << 16 | (uint8_t)'t' << 8 | |
| 73 (uint8_t)'2', | 73 (uint8_t)'2', |
| 74 (uint8_t)'v' << 24 | (uint8_t)'e' << 16 | (uint8_t)'r' << 8 | | 74 (uint8_t)'v' << 24 | (uint8_t)'e' << 16 | (uint8_t)'r' << 8 | |
| 75 (uint8_t)'t', | 75 (uint8_t)'t', |
| 76 }; | 76 }; |
| 77 if (!m_bFeautureMapLoad) { | 77 if (!m_bFeautureMapLoad) { |
| 78 for (int i = 0; i < ScriptList.ScriptCount; i++) { | 78 for (int i = 0; i < ScriptList.ScriptCount; i++) { |
| 79 for (int j = 0; j < (ScriptList.ScriptRecord + i)->Script.LangSysCount; | 79 for (int j = 0; j < (ScriptList.ScriptRecord + i)->Script.LangSysCount; |
| 80 ++j) { | 80 ++j) { |
| 81 for (int k = 0; | 81 for (int k = 0; |
| 82 k < ((ScriptList.ScriptRecord + i)->Script.LangSysRecord + j) | 82 k < ((ScriptList.ScriptRecord + i)->Script.LangSysRecord + j) |
| 83 ->LangSys.FeatureCount; | 83 ->LangSys.FeatureCount; |
| 84 ++k) { | 84 ++k) { |
| 85 FX_DWORD index = | 85 uint32_t index = |
| 86 *(((ScriptList.ScriptRecord + i)->Script.LangSysRecord + j) | 86 *(((ScriptList.ScriptRecord + i)->Script.LangSysRecord + j) |
| 87 ->LangSys.FeatureIndex + | 87 ->LangSys.FeatureIndex + |
| 88 k); | 88 k); |
| 89 if (FeatureList.FeatureRecord[index].FeatureTag == tag[0] || | 89 if (FeatureList.FeatureRecord[index].FeatureTag == tag[0] || |
| 90 FeatureList.FeatureRecord[index].FeatureTag == tag[1]) { | 90 FeatureList.FeatureRecord[index].FeatureTag == tag[1]) { |
| 91 if (!pdfium::ContainsKey(m_featureMap, index)) { | 91 if (!pdfium::ContainsKey(m_featureMap, index)) { |
| 92 m_featureMap[index] = index; | 92 m_featureMap[index] = index; |
| 93 } | 93 } |
| 94 } | 94 } |
| 95 } | 95 } |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 ParseCoverage(&raw[offset], &rec->Coverage); | 375 ParseCoverage(&raw[offset], &rec->Coverage); |
| 376 rec->GlyphCount = GetUInt16(sp); | 376 rec->GlyphCount = GetUInt16(sp); |
| 377 if (rec->GlyphCount <= 0) { | 377 if (rec->GlyphCount <= 0) { |
| 378 return; | 378 return; |
| 379 } | 379 } |
| 380 rec->Substitute = new uint16_t[rec->GlyphCount]; | 380 rec->Substitute = new uint16_t[rec->GlyphCount]; |
| 381 for (i = 0; i < rec->GlyphCount; i++) { | 381 for (i = 0; i < rec->GlyphCount; i++) { |
| 382 rec->Substitute[i] = GetUInt16(sp); | 382 rec->Substitute[i] = GetUInt16(sp); |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 FX_BOOL CFX_GSUBTable::GetVerticalGlyph(FX_DWORD glyphnum, | 385 FX_BOOL CFX_GSUBTable::GetVerticalGlyph(uint32_t glyphnum, |
| 386 FX_DWORD* vglyphnum) { | 386 uint32_t* vglyphnum) { |
| 387 return m_GsubImp.GetVerticalGlyph(glyphnum, vglyphnum); | 387 return m_GsubImp.GetVerticalGlyph(glyphnum, vglyphnum); |
| 388 } | 388 } |
| 389 // static | 389 // static |
| 390 IFX_GSUBTable* IFX_GSUBTable::Create(CFX_Font* pFont) { | 390 IFX_GSUBTable* IFX_GSUBTable::Create(CFX_Font* pFont) { |
| 391 if (!pFont) { | 391 if (!pFont) { |
| 392 return NULL; | 392 return NULL; |
| 393 } | 393 } |
| 394 if (!pFont->GetSubData()) { | 394 if (!pFont->GetSubData()) { |
| 395 unsigned long length = 0; | 395 unsigned long length = 0; |
| 396 int error = FXFT_Load_Sfnt_Table( | 396 int error = FXFT_Load_Sfnt_Table( |
| 397 pFont->GetFace(), FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, NULL, &length); | 397 pFont->GetFace(), FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, NULL, &length); |
| 398 if (!error) { | 398 if (!error) { |
| 399 pFont->SetSubData(FX_Alloc(uint8_t, length)); | 399 pFont->SetSubData(FX_Alloc(uint8_t, length)); |
| 400 } | 400 } |
| 401 if (!pFont->GetSubData()) { | 401 if (!pFont->GetSubData()) { |
| 402 return NULL; | 402 return NULL; |
| 403 } | 403 } |
| 404 } | 404 } |
| 405 int error = | 405 int error = |
| 406 FXFT_Load_Sfnt_Table(pFont->GetFace(), FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, | 406 FXFT_Load_Sfnt_Table(pFont->GetFace(), FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, |
| 407 pFont->GetSubData(), NULL); | 407 pFont->GetSubData(), NULL); |
| 408 if (!error && pFont->GetSubData()) { | 408 if (!error && pFont->GetSubData()) { |
| 409 std::unique_ptr<CFX_GSUBTable> pGsubTable(new CFX_GSUBTable); | 409 std::unique_ptr<CFX_GSUBTable> pGsubTable(new CFX_GSUBTable); |
| 410 if (pGsubTable->m_GsubImp.LoadGSUBTable((FT_Bytes)pFont->GetSubData())) { | 410 if (pGsubTable->m_GsubImp.LoadGSUBTable((FT_Bytes)pFont->GetSubData())) { |
| 411 return pGsubTable.release(); | 411 return pGsubTable.release(); |
| 412 } | 412 } |
| 413 } | 413 } |
| 414 return NULL; | 414 return NULL; |
| 415 } | 415 } |
| OLD | NEW |