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