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_cmaps/cmap_int.h" | 7 #include "core/fpdfapi/fpdf_cmaps/cmap_int.h" |
8 | 8 |
9 #include "core/fpdfapi/fpdf_font/font_int.h" | 9 #include "core/fpdfapi/fpdf_font/font_int.h" |
10 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" | 10 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" |
11 #include "core/fpdfapi/include/cpdf_modulemgr.h" | 11 #include "core/fpdfapi/include/cpdf_modulemgr.h" |
12 | 12 |
| 13 extern "C" { |
| 14 |
| 15 static int compareWord(const void* p1, const void* p2) { |
| 16 return (*(uint16_t*)p1) - (*(uint16_t*)p2); |
| 17 } |
| 18 |
| 19 static int compareWordRange(const void* key, const void* element) { |
| 20 if (*(uint16_t*)key < *(uint16_t*)element) |
| 21 return -1; |
| 22 if (*(uint16_t*)key > ((uint16_t*)element)[1]) |
| 23 return 1; |
| 24 return 0; |
| 25 } |
| 26 |
| 27 static int compareDWordRange(const void* p1, const void* p2) { |
| 28 uint32_t key = *(uint32_t*)p1; |
| 29 uint16_t hiword = (uint16_t)(key >> 16); |
| 30 uint16_t* element = (uint16_t*)p2; |
| 31 if (hiword < element[0]) |
| 32 return -1; |
| 33 if (hiword > element[0]) |
| 34 return 1; |
| 35 |
| 36 uint16_t loword = (uint16_t)key; |
| 37 if (loword < element[1]) |
| 38 return -1; |
| 39 if (loword > element[2]) |
| 40 return 1; |
| 41 return 0; |
| 42 } |
| 43 |
| 44 static int compareDWordSingle(const void* p1, const void* p2) { |
| 45 uint32_t key = *(uint32_t*)p1; |
| 46 uint32_t value = ((*(uint16_t*)p2) << 16) | ((uint16_t*)p2)[1]; |
| 47 if (key < value) |
| 48 return -1; |
| 49 if (key > value) |
| 50 return 1; |
| 51 return 0; |
| 52 } |
| 53 |
| 54 }; // extern "C" |
| 55 |
13 void FPDFAPI_FindEmbeddedCMap(const char* name, | 56 void FPDFAPI_FindEmbeddedCMap(const char* name, |
14 int charset, | 57 int charset, |
15 int coding, | 58 int coding, |
16 const FXCMAP_CMap*& pMap) { | 59 const FXCMAP_CMap*& pMap) { |
17 pMap = nullptr; | 60 pMap = nullptr; |
18 CPDF_FontGlobals* pFontGlobals = | 61 CPDF_FontGlobals* pFontGlobals = |
19 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); | 62 CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals(); |
20 const FXCMAP_CMap* pCMaps = | 63 const FXCMAP_CMap* pCMaps = |
21 pFontGlobals->m_EmbeddedCharsets[charset].m_pMapList; | 64 pFontGlobals->m_EmbeddedCharsets[charset].m_pMapList; |
22 for (uint32_t i = 0; i < pFontGlobals->m_EmbeddedCharsets[charset].m_Count; | 65 for (uint32_t i = 0; i < pFontGlobals->m_EmbeddedCharsets[charset].m_Count; |
23 i++) { | 66 i++) { |
24 if (FXSYS_strcmp(name, pCMaps[i].m_Name)) | 67 if (FXSYS_strcmp(name, pCMaps[i].m_Name)) |
25 continue; | 68 continue; |
26 pMap = &pCMaps[i]; | 69 pMap = &pCMaps[i]; |
27 break; | 70 break; |
28 } | 71 } |
29 } | 72 } |
30 extern "C" { | 73 |
31 static int compareWord(const void* p1, const void* p2) { | |
32 return (*(uint16_t*)p1) - (*(uint16_t*)p2); | |
33 } | |
34 }; | |
35 extern "C" { | |
36 static int compareWordRange(const void* key, const void* element) { | |
37 if (*(uint16_t*)key < *(uint16_t*)element) { | |
38 return -1; | |
39 } | |
40 if (*(uint16_t*)key > ((uint16_t*)element)[1]) { | |
41 return 1; | |
42 } | |
43 return 0; | |
44 } | |
45 }; | |
46 extern "C" { | |
47 static int compareDWordRange(const void* p1, const void* p2) { | |
48 uint32_t key = *(uint32_t*)p1; | |
49 uint16_t hiword = (uint16_t)(key >> 16); | |
50 uint16_t* element = (uint16_t*)p2; | |
51 if (hiword < element[0]) { | |
52 return -1; | |
53 } | |
54 if (hiword > element[0]) { | |
55 return 1; | |
56 } | |
57 uint16_t loword = (uint16_t)key; | |
58 if (loword < element[1]) { | |
59 return -1; | |
60 } | |
61 if (loword > element[2]) { | |
62 return 1; | |
63 } | |
64 return 0; | |
65 } | |
66 }; | |
67 extern "C" { | |
68 static int compareDWordSingle(const void* p1, const void* p2) { | |
69 uint32_t key = *(uint32_t*)p1; | |
70 uint32_t value = ((*(uint16_t*)p2) << 16) | ((uint16_t*)p2)[1]; | |
71 if (key < value) { | |
72 return -1; | |
73 } | |
74 if (key > value) { | |
75 return 1; | |
76 } | |
77 return 0; | |
78 } | |
79 }; | |
80 uint16_t FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, uint32_t charcode) { | 74 uint16_t FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, uint32_t charcode) { |
81 if (charcode >> 16) { | 75 if (charcode >> 16) { |
82 while (1) { | 76 while (1) { |
83 if (pMap->m_DWordMapType == FXCMAP_CMap::Range) { | 77 if (pMap->m_DWordMapType == FXCMAP_CMap::Range) { |
84 uint16_t* found = | 78 uint16_t* found = static_cast<uint16_t*>( |
85 (uint16_t*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, | 79 FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 8, |
86 pMap->m_DWordCount, 8, compareDWordRange); | 80 compareDWordRange)); |
87 if (found) { | 81 if (found) |
88 return found[3] + (uint16_t)charcode - found[1]; | 82 return found[3] + (uint16_t)charcode - found[1]; |
89 } | 83 |
90 } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) { | 84 } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) { |
91 uint16_t* found = | 85 uint16_t* found = static_cast<uint16_t*>( |
92 (uint16_t*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap, | 86 FXSYS_bsearch(&charcode, pMap->m_pDWordMap, pMap->m_DWordCount, 6, |
93 pMap->m_DWordCount, 6, compareDWordSingle); | 87 compareDWordSingle)); |
94 if (found) { | 88 if (found) |
95 return found[2]; | 89 return found[2]; |
96 } | |
97 } | 90 } |
98 if (pMap->m_UseOffset == 0) { | 91 if (pMap->m_UseOffset == 0) |
99 return 0; | 92 return 0; |
100 } | 93 |
101 pMap = pMap + pMap->m_UseOffset; | 94 pMap = pMap + pMap->m_UseOffset; |
102 } | 95 } |
103 return 0; | 96 return 0; |
104 } | 97 } |
| 98 |
105 uint16_t code = (uint16_t)charcode; | 99 uint16_t code = (uint16_t)charcode; |
106 while (1) { | 100 while (1) { |
107 if (!pMap->m_pWordMap) { | 101 if (!pMap->m_pWordMap) |
108 return 0; | 102 return 0; |
| 103 if (pMap->m_WordMapType == FXCMAP_CMap::Single) { |
| 104 uint16_t* found = static_cast<uint16_t*>(FXSYS_bsearch( |
| 105 &code, pMap->m_pWordMap, pMap->m_WordCount, 4, compareWord)); |
| 106 if (found) |
| 107 return found[1]; |
| 108 |
| 109 } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) { |
| 110 uint16_t* found = static_cast<uint16_t*>(FXSYS_bsearch( |
| 111 &code, pMap->m_pWordMap, pMap->m_WordCount, 6, compareWordRange)); |
| 112 if (found) |
| 113 return found[2] + code - found[0]; |
109 } | 114 } |
110 if (pMap->m_WordMapType == FXCMAP_CMap::Single) { | 115 if (pMap->m_UseOffset == 0) |
111 uint16_t* found = (uint16_t*)FXSYS_bsearch( | |
112 &code, pMap->m_pWordMap, pMap->m_WordCount, 4, compareWord); | |
113 if (found) { | |
114 return found[1]; | |
115 } | |
116 } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) { | |
117 uint16_t* found = (uint16_t*)FXSYS_bsearch( | |
118 &code, pMap->m_pWordMap, pMap->m_WordCount, 6, compareWordRange); | |
119 if (found) { | |
120 return found[2] + code - found[0]; | |
121 } | |
122 } | |
123 if (pMap->m_UseOffset == 0) { | |
124 return 0; | 116 return 0; |
125 } | 117 |
126 pMap = pMap + pMap->m_UseOffset; | 118 pMap = pMap + pMap->m_UseOffset; |
127 } | 119 } |
128 return 0; | 120 return 0; |
129 } | 121 } |
| 122 |
130 uint32_t FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, uint16_t cid) { | 123 uint32_t FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, uint16_t cid) { |
| 124 // TODO(dsinclair): This should be checking both pMap->m_WordMap and |
| 125 // pMap->m_DWordMap. There was a second while() but it was never reached as |
| 126 // the first always returns. Investigate and determine how this should |
| 127 // really be working. (https://codereview.chromium.org/2235743003 removed the |
| 128 // second while loop.) |
131 while (1) { | 129 while (1) { |
132 if (pMap->m_WordMapType == FXCMAP_CMap::Single) { | 130 if (pMap->m_WordMapType == FXCMAP_CMap::Single) { |
133 const uint16_t* pCur = pMap->m_pWordMap; | 131 const uint16_t* pCur = pMap->m_pWordMap; |
134 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2; | 132 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2; |
135 while (pCur < pEnd) { | 133 while (pCur < pEnd) { |
136 if (pCur[1] == cid) { | 134 if (pCur[1] == cid) |
137 return pCur[0]; | 135 return pCur[0]; |
138 } | 136 |
139 pCur += 2; | 137 pCur += 2; |
140 } | 138 } |
141 } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) { | 139 } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) { |
142 const uint16_t* pCur = pMap->m_pWordMap; | 140 const uint16_t* pCur = pMap->m_pWordMap; |
143 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3; | 141 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3; |
144 while (pCur < pEnd) { | 142 while (pCur < pEnd) { |
145 if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) { | 143 if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) |
146 return pCur[0] + cid - pCur[2]; | 144 return pCur[0] + cid - pCur[2]; |
147 } | 145 |
148 pCur += 3; | 146 pCur += 3; |
149 } | 147 } |
150 } | 148 } |
151 if (pMap->m_UseOffset == 0) { | 149 if (pMap->m_UseOffset == 0) |
152 return 0; | 150 return 0; |
153 } | 151 |
154 pMap = pMap + pMap->m_UseOffset; | 152 pMap = pMap + pMap->m_UseOffset; |
155 } | 153 } |
156 while (1) { | |
157 if (pMap->m_DWordMapType == FXCMAP_CMap::Range) { | |
158 const uint16_t* pCur = pMap->m_pDWordMap; | |
159 const uint16_t* pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 4; | |
160 while (pCur < pEnd) { | |
161 if (cid >= pCur[3] && cid <= pCur[3] + pCur[2] - pCur[1]) { | |
162 return (((uint32_t)pCur[0] << 16) | pCur[1]) + cid - pCur[3]; | |
163 } | |
164 pCur += 4; | |
165 } | |
166 } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) { | |
167 const uint16_t* pCur = pMap->m_pDWordMap; | |
168 const uint16_t* pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 3; | |
169 while (pCur < pEnd) { | |
170 if (pCur[2] == cid) { | |
171 return ((uint32_t)pCur[0] << 16) | pCur[1]; | |
172 } | |
173 pCur += 3; | |
174 } | |
175 } | |
176 if (pMap->m_UseOffset == 0) { | |
177 return 0; | |
178 } | |
179 pMap = pMap + pMap->m_UseOffset; | |
180 } | |
181 return 0; | |
182 } | 154 } |
OLD | NEW |