fpdf_cmaps.cpp revision ee451cb395940862dad63c85adfe8f2fd55e864c
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"
11void 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}
25extern "C" {
26    static int compareWord(const void* p1, const void* p2)
27    {
28        return (*(FX_WORD*)p1) - (*(FX_WORD*)p2);
29    }
30};
31extern "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};
43extern "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};
65extern "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};
79FX_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}
124FX_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}
178void 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}
184