Add type cast definitions for CPDF_Dictionary.
[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
12 void FPDFAPI_FindEmbeddedCMap(const char* name,
13                               int charset,
14                               int coding,
15                               const FXCMAP_CMap*& pMap) {
16   pMap = NULL;
17   CPDF_FontGlobals* pFontGlobals =
18       CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
19   const FXCMAP_CMap* pCMaps =
20       pFontGlobals->m_EmbeddedCharsets[charset].m_pMapList;
21   int nCMaps = pFontGlobals->m_EmbeddedCharsets[charset].m_Count;
22   for (int i = 0; i < nCMaps; i++) {
23     if (FXSYS_strcmp(name, pCMaps[i].m_Name)) {
24       continue;
25     }
26     pMap = &pCMaps[i];
27     break;
28   }
29 }
30 extern "C" {
31 static int compareWord(const void* p1, const void* p2) {
32   return (*(FX_WORD*)p1) - (*(FX_WORD*)p2);
33 }
34 };
35 extern "C" {
36 static int compareWordRange(const void* key, const void* element) {
37   if (*(FX_WORD*)key < *(FX_WORD*)element) {
38     return -1;
39   }
40   if (*(FX_WORD*)key > ((FX_WORD*)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   FX_DWORD key = *(FX_DWORD*)p1;
49   FX_WORD hiword = (FX_WORD)(key >> 16);
50   FX_WORD* element = (FX_WORD*)p2;
51   if (hiword < element[0]) {
52     return -1;
53   }
54   if (hiword > element[0]) {
55     return 1;
56   }
57   FX_WORD loword = (FX_WORD)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   FX_DWORD key = *(FX_DWORD*)p1;
70   FX_DWORD value = ((*(FX_WORD*)p2) << 16) | ((FX_WORD*)p2)[1];
71   if (key < value) {
72     return -1;
73   }
74   if (key > value) {
75     return 1;
76   }
77   return 0;
78 }
79 };
80 FX_WORD FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, FX_DWORD charcode) {
81   if (charcode >> 16) {
82     while (1) {
83       if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
84         FX_WORD* found =
85             (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap,
86                                     pMap->m_DWordCount, 8, compareDWordRange);
87         if (found) {
88           return found[3] + (FX_WORD)charcode - found[1];
89         }
90       } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
91         FX_WORD* found =
92             (FX_WORD*)FXSYS_bsearch(&charcode, pMap->m_pDWordMap,
93                                     pMap->m_DWordCount, 6, compareDWordSingle);
94         if (found) {
95           return found[2];
96         }
97       }
98       if (pMap->m_UseOffset == 0) {
99         return 0;
100       }
101       pMap = pMap + pMap->m_UseOffset;
102     }
103     return 0;
104   }
105   FX_WORD code = (FX_WORD)charcode;
106   while (1) {
107     if (pMap->m_pWordMap == NULL) {
108       return 0;
109     }
110     if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
111       FX_WORD* found = (FX_WORD*)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       FX_WORD* found = (FX_WORD*)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;
125     }
126     pMap = pMap + pMap->m_UseOffset;
127   }
128   return 0;
129 }
130 FX_DWORD FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, FX_WORD cid) {
131   while (1) {
132     if (pMap->m_WordMapType == FXCMAP_CMap::Single) {
133       const FX_WORD* pCur = pMap->m_pWordMap;
134       const FX_WORD* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 2;
135       while (pCur < pEnd) {
136         if (pCur[1] == cid) {
137           return pCur[0];
138         }
139         pCur += 2;
140       }
141     } else if (pMap->m_WordMapType == FXCMAP_CMap::Range) {
142       const FX_WORD* pCur = pMap->m_pWordMap;
143       const FX_WORD* pEnd = pMap->m_pWordMap + pMap->m_WordCount * 3;
144       while (pCur < pEnd) {
145         if (cid >= pCur[2] && cid <= pCur[2] + pCur[1] - pCur[0]) {
146           return pCur[0] + cid - pCur[2];
147         }
148         pCur += 3;
149       }
150     }
151     if (pMap->m_UseOffset == 0) {
152       return 0;
153     }
154     pMap = pMap + pMap->m_UseOffset;
155   }
156   while (1) {
157     if (pMap->m_DWordMapType == FXCMAP_CMap::Range) {
158       const FX_WORD* pCur = pMap->m_pDWordMap;
159       const FX_WORD* 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 (((FX_DWORD)pCur[0] << 16) | pCur[1]) + cid - pCur[3];
163         }
164         pCur += 4;
165       }
166     } else if (pMap->m_DWordMapType == FXCMAP_CMap::Single) {
167       const FX_WORD* pCur = pMap->m_pDWordMap;
168       const FX_WORD* pEnd = pMap->m_pDWordMap + pMap->m_DWordCount * 3;
169       while (pCur < pEnd) {
170         if (pCur[2] == cid) {
171           return ((FX_DWORD)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 }
183
184 void FPDFAPI_LoadCID2UnicodeMap(CIDSet charset,
185                                 const FX_WORD*& pMap,
186                                 FX_DWORD& count) {
187   CPDF_FontGlobals* pFontGlobals =
188       CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
189   pMap = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
190   count = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
191 }