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) { |
131 while (1) { | 124 while (1) { |
dsinclair
2016/08/10 14:05:53
This loop only returns, never breaks. So, the whil
Wei Li
2016/08/10 17:46:44
Looks like a bug to me, mDWordMap should be examin
dsinclair
2016/08/10 18:47:39
In which case, should I leave the while() below in
Wei Li
2016/08/10 18:53:09
When getting charcode from CID, I think both pMap-
dsinclair
2016/08/10 19:33:30
Done.
| |
132 if (pMap->m_WordMapType == FXCMAP_CMap::Single) { | 125 if (pMap->m_WordMapType == FXCMAP_CMap::Single) { |
133 const uint16_t* pCur = pMap->m_pWordMap; | 126 const uint16_t* pCur = pMap->m_pWordMap; |
134 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2; | 127 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2; |
135 while (pCur < pEnd) { | 128 while (pCur < pEnd) { |
136 if (pCur[1] == cid) { | 129 if (pCur[1] == cid) |
137 return pCur[0]; | 130 return pCur[0]; |
138 } | 131 |
139 pCur += 2; | 132 pCur += 2; |
140 } | 133 } |
141 } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) { | 134 } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) { |
142 const uint16_t* pCur = pMap->m_pWordMap; | 135 const uint16_t* pCur = pMap->m_pWordMap; |
143 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3; | 136 const uint16_t* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3; |
144 while (pCur < pEnd) { | 137 while (pCur < pEnd) { |
145 if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) { | 138 if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) |
146 return pCur[0] + cid - pCur[2]; | 139 return pCur[0] + cid - pCur[2]; |
147 } | 140 |
148 pCur += 3; | 141 pCur += 3; |
149 } | 142 } |
150 } | 143 } |
151 if (pMap->m_UseOffset == 0) { | 144 if (pMap->m_UseOffset == 0) |
152 return 0; | 145 return 0; |
153 } | 146 |
154 pMap = pMap + pMap->m_UseOffset; | 147 pMap = pMap + pMap->m_UseOffset; |
155 } | 148 } |
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 } | 149 } |
OLD | NEW |