1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_module.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_page.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "font_int.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_cmaps/cmap_int.h"
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h"
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_freetype.h"
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_LPVOID FXFC_LoadPackage(FX_LPCSTR name);
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_BOOL FXFC_LoadFile(FX_LPVOID pPackage, FX_LPCSTR name, FX_LPBYTE& pBuffer, FX_DWORD& size);
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern void FXFC_ClosePackage(FX_LPVOID pPackage);
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern short TT2PDF(int m, FXFT_Face face);
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_BOOL FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id);
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_LPCSTR GetAdobeCharName(int iBaseEncoding, const CFX_ByteString* pCharNames, int charcode);
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMapManager::CPDF_CMapManager()
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bPrompted = FALSE;
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPackage = NULL;
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_CID2UnicodeMaps, 0, sizeof m_CID2UnicodeMaps);
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMapManager::~CPDF_CMapManager()
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DropAll(FALSE);
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPackage) {
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXFC_ClosePackage(m_pPackage);
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_LPVOID CPDF_CMapManager::GetPackage(FX_BOOL bPrompt)
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FOXIT_CHROME_BUILD
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPackage == NULL) {
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString filename = CPDF_ModuleMgr::Get()->GetModuleFilePath(ADDIN_NAME_CJK, "FPDFCJK.BIN");
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pPackage = FXFC_LoadPackage(filename);
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bPrompt && m_pPackage == NULL && !m_bPrompted) {
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_bPrompted = TRUE;
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!CPDF_ModuleMgr::Get()->DownloadModule(ADDIN_NAME_CJK)) {
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return NULL;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pPackage = FXFC_LoadPackage(filename);
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pPackage;
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMap* CPDF_CMapManager::GetPredefinedCMap(const CFX_ByteString& name, FX_BOOL bPromptCJK)
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CMap* pCMap;
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_CMaps.Lookup(name, (FX_LPVOID&)pCMap)) {
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return pCMap;
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCMap = LoadPredefinedCMap(name, bPromptCJK);
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (name.IsEmpty()) {
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return pCMap;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_CMaps.SetAt(name, pCMap);
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pCMap;
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMap* CPDF_CMapManager::LoadPredefinedCMap(const CFX_ByteString& name, FX_BOOL bPromptCJK)
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CMap* pCMap = FX_NEW CPDF_CMap;
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCSTR pname = name;
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (*pname == '/') {
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pname ++;
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCMap->LoadPredefined(this, pname, bPromptCJK);
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pCMap;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_LPCSTR g_CharsetNames[] = {NULL, "GB1", "CNS1", "Japan1", "Korea1", "UCS", NULL};
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst int g_CharsetCPs[] = {0, 936, 950, 932, 949, 1200, 0};
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint _CharsetFromOrdering(const CFX_ByteString& Ordering)
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int charset = 1;
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (g_CharsetNames[charset] && Ordering != CFX_ByteStringC(g_CharsetNames[charset])) {
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charset ++;
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (g_CharsetNames[charset] == NULL) {
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CIDSET_UNKNOWN;
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return charset;
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CMapManager::ReloadAll()
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DropAll(TRUE);
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CMapManager::DropAll(FX_BOOL bReload)
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos = m_CMaps.GetStartPosition();
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (pos) {
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString name;
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_CMap* pCMap;
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CMaps.GetNextAssoc(pos, name, (FX_LPVOID&)pCMap);
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pCMap == NULL) {
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bReload) {
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pCMap->LoadPredefined(this, name, FALSE);
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pCMap;
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < sizeof m_CID2UnicodeMaps / sizeof(CPDF_CID2UnicodeMap*); i ++) {
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_CID2UnicodeMap* pMap = m_CID2UnicodeMaps[i];
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pMap == NULL) {
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bReload) {
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pMap->Load(this, i, FALSE);
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pMap;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CID2UnicodeMap* CPDF_CMapManager::GetCID2UnicodeMap(int charset, FX_BOOL bPromptCJK)
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_CID2UnicodeMaps[charset] == NULL) {
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CID2UnicodeMaps[charset] = LoadCID2UnicodeMap(charset, bPromptCJK);
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_CID2UnicodeMaps[charset];
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CID2UnicodeMap* CPDF_CMapManager::LoadCID2UnicodeMap(int charset, FX_BOOL bPromptCJK)
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CID2UnicodeMap* pMap = FX_NEW CPDF_CID2UnicodeMap();
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pMap->Initialize()) {
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pMap;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pMap->Load(this, charset, bPromptCJK);
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pMap;
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMapParser::CPDF_CMapParser()
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCMap = NULL;
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Status = 0;
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_CodeSeq = 0;
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL	CPDF_CMapParser::Initialize(CPDF_CMap* pCMap)
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCMap = pCMap;
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Status = 0;
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_CodeSeq = 0;
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_AddMaps.EstimateSize(0, 10240);
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_DWORD CMap_GetCode(FX_BSTR word)
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int num = 0;
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (word.GetAt(0) == '<') {
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 1; i < word.GetLength(); i ++) {
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BYTE digit = word.GetAt(i);
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (digit >= '0' && digit <= '9') {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                digit = digit - '0';
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (digit >= 'a' && digit <= 'f') {
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                digit = digit - 'a' + 10;
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (digit >= 'A' && digit <= 'F') {
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                digit = digit - 'A' + 10;
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return num;
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            num = num * 16 + digit;
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < word.GetLength(); i ++) {
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (word.GetAt(i) < '0' || word.GetAt(i) > '9') {
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return num;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            num = num * 10 + word.GetAt(i) - '0';
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return num;
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_BOOL _CMap_GetCodeRange(_CMap_CodeRange& range, FX_BSTR first, FX_BSTR second)
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (first.GetLength() == 0 || first.GetAt(0) != '<') {
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int num = 0;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 1; i < first.GetLength(); i ++)
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (first.GetAt(i) == '>') {
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    range.m_CharSize = (i - 1) / 2;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (range.m_CharSize > 4) {
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < range.m_CharSize; i ++) {
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE digit1 = first.GetAt(i * 2 + 1);
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE digit2 = first.GetAt(i * 2 + 2);
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE byte = (digit1 >= '0' && digit1 <= '9') ? (digit1 - '0') : ((digit1 & 0xdf) - 'A' + 10);
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        byte = byte * 16 + ((digit2 >= '0' && digit2 <= '9') ? (digit2 - '0') : ((digit2 & 0xdf) - 'A' + 10));
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        range.m_Lower[i] = byte;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD size = second.GetLength();
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < range.m_CharSize; i ++) {
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE digit1 = ((FX_DWORD)i * 2 + 1 < size) ? second.GetAt((FX_STRSIZE)i * 2 + 1) : 0;
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE digit2 = ((FX_DWORD)i * 2 + 2 < size) ? second.GetAt((FX_STRSIZE)i * 2 + 2) : 0;
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BYTE byte = (digit1 >= '0' && digit1 <= '9') ? (digit1 - '0') : ((digit1 & 0xdf) - 'A' + 10);
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        byte = byte * 16 + ((digit2 >= '0' && digit2 <= '9') ? (digit2 - '0') : ((digit2 & 0xdf) - 'A' + 10));
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        range.m_Upper[i] = byte;
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic CFX_ByteString CMap_GetString(FX_BSTR word)
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return word.Mid(1, word.GetLength() - 2);
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CMapParser::ParseWord(FX_BSTR word)
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (word.IsEmpty()) {
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (word == FX_BSTRC("begincidchar")) {
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 1;
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CodeSeq = 0;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("begincidrange")) {
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 2;
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CodeSeq = 0;
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("endcidrange") || word == FX_BSTRC("endcidchar")) {
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 0;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("/WMode")) {
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 6;
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("/Registry")) {
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 3;
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("/Ordering")) {
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 4;
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("/Supplement")) {
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 5;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("begincodespacerange")) {
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 7;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CodeSeq = 0;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (word == FX_BSTRC("usecmap")) {
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Status == 1 || m_Status == 2) {
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CodePoints[m_CodeSeq] = CMap_GetCode(word);
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CodeSeq ++;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD StartCode, EndCode;
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_WORD StartCID;
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Status == 1) {
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_CodeSeq < 2) {
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            EndCode = StartCode = m_CodePoints[0];
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            StartCID = (FX_WORD)m_CodePoints[1];
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_CodeSeq < 3) {
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            StartCode = m_CodePoints[0];
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            EndCode = m_CodePoints[1];
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            StartCID = (FX_WORD)m_CodePoints[2];
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (EndCode < 0x10000) {
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (FX_DWORD code = StartCode; code <= EndCode; code ++) {
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pCMap->m_pMapping[code] = (FX_WORD)(StartCID + code - StartCode);
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD buf[2];
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            buf[0] = StartCode;
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            buf[1] = ((EndCode - StartCode) << 16) + StartCID;
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_AddMaps.AppendBlock(buf, sizeof buf);
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CodeSeq = 0;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Status == 3) {
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CMap_GetString(word);
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 0;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Status == 4) {
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCMap->m_Charset = _CharsetFromOrdering(CMap_GetString(word));
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 0;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Status == 5) {
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CMap_GetCode(word);
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 0;
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Status == 6) {
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCMap->m_bVertical = CMap_GetCode(word);
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = 0;
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_Status == 7) {
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (word == FX_BSTRC("endcodespacerange")) {
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int nSegs = m_CodeRanges.GetSize();
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (nSegs > 1) {
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pCMap->m_CodingScheme = CPDF_CMap::MixedFourBytes;
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pCMap->m_nCodeRanges = nSegs;
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pCMap->m_pLeadingBytes = FX_Alloc(FX_BYTE, nSegs * sizeof(_CMap_CodeRange));
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXSYS_memcpy32(m_pCMap->m_pLeadingBytes, m_CodeRanges.GetData(), nSegs * sizeof(_CMap_CodeRange));
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (nSegs == 1) {
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pCMap->m_CodingScheme = (m_CodeRanges[0].m_CharSize == 2) ? CPDF_CMap::TwoBytes : CPDF_CMap::OneByte;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Status = 0;
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (word.GetLength() == 0 || word.GetAt(0) != '<') {
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_CodeSeq % 2) {
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CMap_CodeRange range;
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (_CMap_GetCodeRange(range, m_LastWord, word)) {
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_CodeRanges.Add(range);
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_CodeSeq ++;
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LastWord = word;
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMap::CPDF_CMap()
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Charset = CIDSET_UNKNOWN;
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Coding = CIDCODING_UNKNOWN;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_CodingScheme = TwoBytes;
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bVertical = 0;
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLoaded = FALSE;
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pMapping = NULL;
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pLeadingBytes = NULL;
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAddMapping = NULL;
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pEmbedMap = NULL;
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pUseMap = NULL;
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCodeRanges = 0;
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CMap::~CPDF_CMap()
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pMapping) {
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pMapping);
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAddMapping) {
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pAddMapping);
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pLeadingBytes) {
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pLeadingBytes);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pUseMap) {
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pUseMap;
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CMap::Release()
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PredefinedCMap.IsEmpty()) {
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete this;
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst CPDF_PredefinedCMap g_PredefinedCMaps[] = {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "GB-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} },
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "GBpc-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfc} },
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "GBK-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} },
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "GBKp-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} },
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "GBK2K-EUC", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} },
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "GBK2K", CIDSET_GB1, CIDCODING_GB, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} },
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniGB-UCS2", CIDSET_GB1, CIDCODING_UCS2, CPDF_CMap::TwoBytes },
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniGB-UTF16", CIDSET_GB1, CIDCODING_UTF16, CPDF_CMap::TwoBytes },
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "B5pc", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfc} },
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "HKscs-B5", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0x88, 0xfe} },
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "ETen-B5", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} },
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "ETenms-B5", CIDSET_CNS1, CIDCODING_BIG5, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} },
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniCNS-UCS2", CIDSET_CNS1, CIDCODING_UCS2, CPDF_CMap::TwoBytes },
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniCNS-UTF16", CIDSET_CNS1, CIDCODING_UTF16, CPDF_CMap::TwoBytes },
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "83pv-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} },
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "90ms-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} },
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "90msp-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} },
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "90pv-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} },
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Add-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} },
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "EUC", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x8e, 0x8e, 0xa1, 0xfe} },
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "H", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e} },
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "V", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::TwoBytes, 1, {0x21, 0x7e} },
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "Ext-RKSJ", CIDSET_JAPAN1, CIDCODING_JIS, CPDF_CMap::MixedTwoBytes, 2, {0x81, 0x9f, 0xe0, 0xfc} },
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniJIS-UCS2", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes },
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniJIS-UCS2-HW", CIDSET_JAPAN1, CIDCODING_UCS2, CPDF_CMap::TwoBytes },
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniJIS-UTF16", CIDSET_JAPAN1, CIDCODING_UTF16, CPDF_CMap::TwoBytes },
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "KSC-EUC", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfe} },
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "KSCms-UHC", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} },
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "KSCms-UHC-HW", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0x81, 0xfe} },
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "KSCpc-EUC", CIDSET_KOREA1, CIDCODING_KOREA, CPDF_CMap::MixedTwoBytes, 1, {0xa1, 0xfd} },
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniKS-UCS2", CIDSET_KOREA1, CIDCODING_UCS2, CPDF_CMap::TwoBytes },
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { "UniKS-UTF16", CIDSET_KOREA1, CIDCODING_UTF16, CPDF_CMap::TwoBytes },
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { NULL, 0, 0 }
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern void FPDFAPI_FindEmbeddedCMap(const char* name, int charset, int coding, const FXCMAP_CMap*& pMap);
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_WORD FPDFAPI_CIDFromCharCode(const FXCMAP_CMap* pMap, FX_DWORD charcode);
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CMap::LoadPredefined(CPDF_CMapManager* pMgr, FX_LPCSTR pName, FX_BOOL bPromptCJK)
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PredefinedCMap = pName;
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_PredefinedCMap == FX_BSTRC("Identity-H") || m_PredefinedCMap == FX_BSTRC("Identity-V")) {
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Coding = CIDCODING_CID;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bVertical = pName[9] == 'V';
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bLoaded = TRUE;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString cmapid = m_PredefinedCMap;
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bVertical = cmapid.Right(1) == FX_BSTRC("V");
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cmapid.GetLength() > 2) {
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        cmapid = cmapid.Left(cmapid.GetLength() - 2);
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = 0;
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (1) {
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (g_PredefinedCMaps[index].m_pName == NULL) {
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (cmapid == CFX_ByteStringC(g_PredefinedCMaps[index].m_pName)) {
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        index ++;
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CPDF_PredefinedCMap& map = g_PredefinedCMaps[index];
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Charset = map.m_Charset;
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Coding = map.m_Coding;
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_CodingScheme = map.m_CodingScheme;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_CodingScheme == MixedTwoBytes) {
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pLeadingBytes = FX_Alloc(FX_BYTE, 256);
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memset32(m_pLeadingBytes, 0, 256);
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD i = 0; i < map.m_LeadingSegCount; i ++) {
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (int b = map.m_LeadingSegs[i * 2]; b <= map.m_LeadingSegs[i * 2 + 1]; b ++) {
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pLeadingBytes[b] = 1;
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FPDFAPI_FindEmbeddedCMap(pName, m_Charset, m_Coding, m_pEmbedMap);
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pEmbedMap) {
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bLoaded = TRUE;
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPVOID pPackage = pMgr->GetPackage(bPromptCJK);
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE pBuffer;
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD size;
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPackage == NULL || !FXFC_LoadFile(pPackage, m_PredefinedCMap, pBuffer, size)) {
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pMapping = FX_Alloc(FX_WORD, 65536);
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_pMapping, 0, 65536 * sizeof(FX_WORD));
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD dwRecodeEndPos = 0;
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBuffer[5] == 0) {
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD dwStartIndex = *(FX_DWORD*)(pBuffer + 8);
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD dwRecordCount = *(FX_DWORD*)(pBuffer + 16);
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD dwDataOffset = *(FX_DWORD*)(pBuffer + 20);
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dwRecordCount * 2 + dwStartIndex * 2 < 65536) {
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memcpy32(m_pMapping + dwStartIndex * 2, pBuffer + dwDataOffset, dwRecordCount * 2);
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dwRecodeEndPos = dwDataOffset + dwRecordCount * 2;
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (pBuffer[5] == 2) {
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD nSegments = *(FX_DWORD*)(pBuffer + 16);
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD dwDataOffset = *(FX_DWORD*)(pBuffer + 20);
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dwRecodeEndPos = dwDataOffset + 6 * nSegments;
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD i = 0; i < nSegments; i ++) {
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPBYTE pRecord = pBuffer + dwDataOffset + i * 6;
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_WORD IndexStart = *(FX_WORD*)pRecord;
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_WORD IndexCount = *(FX_WORD*)(pRecord + 2);
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_WORD CodeStart = *(FX_WORD*)(pRecord + 4);
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (IndexStart + IndexCount < 65536)
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (FX_DWORD j = 0; j < IndexCount; j ++) {
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pMapping[IndexStart + j ] = (FX_WORD)(CodeStart + j);
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dwRecodeEndPos < size) {
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD dwMapLen = *(FX_DWORD*)(pBuffer + dwRecodeEndPos);
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dwMapLen) {
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pUseMap = FX_NEW CPDF_CMap;
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_ByteString bsName(pBuffer + dwRecodeEndPos + 4 , dwMapLen);
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pUseMap) {
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pUseMap->LoadPredefined(pMgr, bsName, bPromptCJK);
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(pBuffer);
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLoaded = TRUE;
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern "C" {
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static int compare_dword(const void* data1, const void* data2)
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (*(FX_DWORD*)data1) - (*(FX_DWORD*)data2);
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CMap::LoadEmbedded(FX_LPCBYTE pData, FX_DWORD size)
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pMapping = FX_Alloc(FX_WORD, 65536);
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_pMapping, 0, 65536 * sizeof(FX_WORD));
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CMapParser parser;
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    parser.Initialize(this);
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_SimpleParser syntax(pData, size);
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (1) {
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteStringC word = syntax.GetWord();
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (word.IsEmpty()) {
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        parser.ParseWord(word);
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_CodingScheme == MixedFourBytes && parser.m_AddMaps.GetSize()) {
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAddMapping = FX_Alloc(FX_BYTE, parser.m_AddMaps.GetSize() + 4);
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *(FX_DWORD*)m_pAddMapping = parser.m_AddMaps.GetSize() / 8;
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(m_pAddMapping + 4, parser.m_AddMaps.GetBuffer(), parser.m_AddMaps.GetSize());
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_qsort(m_pAddMapping + 4, parser.m_AddMaps.GetSize() / 8, 8, compare_dword);
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern "C" {
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static int compareCID(const void* key, const void* element)
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((*(FX_DWORD*)key) < (*(FX_DWORD*)element)) {
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((*(FX_DWORD*)key) > (*(FX_DWORD*)element) + ((FX_DWORD*)element)[1] / 65536) {
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 1;
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_WORD CPDF_CMap::CIDFromCharCode(FX_DWORD charcode) const
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Coding == CIDCODING_CID) {
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (FX_WORD)charcode;
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pEmbedMap) {
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FPDFAPI_CIDFromCharCode(m_pEmbedMap, charcode);
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pMapping == NULL) {
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (FX_WORD)charcode;
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (charcode >> 16) {
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pAddMapping) {
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            void* found = FXSYS_bsearch(&charcode, m_pAddMapping + 4, *(FX_DWORD*)m_pAddMapping, 8, compareCID);
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (found == NULL) {
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (m_pUseMap) {
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return m_pUseMap->CIDFromCharCode(charcode);
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 0;
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (FX_WORD)(((FX_DWORD*)found)[1] % 65536 + charcode - * (FX_DWORD*)found);
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pUseMap) {
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return m_pUseMap->CIDFromCharCode(charcode);
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD CID = m_pMapping[charcode];
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!CID && m_pUseMap) {
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pUseMap->CIDFromCharCode(charcode);
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (FX_WORD)CID;
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int _CheckCodeRange(FX_LPBYTE codes, int size, _CMap_CodeRange* pRanges, int nRanges)
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iSeg = nRanges - 1;
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (iSeg >= 0) {
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pRanges[iSeg].m_CharSize < size) {
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iSeg --;
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int iChar = 0;
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (iChar < size) {
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (codes[iChar] < pRanges[iSeg].m_Lower[iChar] ||
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    codes[iChar] > pRanges[iSeg].m_Upper[iChar]) {
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iChar ++;
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iChar == pRanges[iSeg].m_CharSize) {
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 2;
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iChar) {
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (size == pRanges[iSeg].m_CharSize) {
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 2;
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 1;
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iSeg --;
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CPDF_CMap::GetNextChar(FX_LPCSTR pString, int& offset) const
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (m_CodingScheme) {
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case OneByte:
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return ((FX_LPBYTE)pString)[offset++];
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TwoBytes:
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            offset += 2;
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return ((FX_LPBYTE)pString)[offset - 2] * 256 + ((FX_LPBYTE)pString)[offset - 1];
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedTwoBytes: {
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE byte1 = ((FX_LPBYTE)pString)[offset++];
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!m_pLeadingBytes[byte1]) {
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return byte1;
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE byte2 = ((FX_LPBYTE)pString)[offset++];
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return byte1 * 256 + byte2;
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedFourBytes: {
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_BYTE codes[4];
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int char_size = 1;
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                codes[0] = ((FX_LPBYTE)pString)[offset++];
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CMap_CodeRange* pRanges = (_CMap_CodeRange*)m_pLeadingBytes;
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                while (1) {
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int ret = _CheckCodeRange(codes, char_size, pRanges, m_nCodeRanges);
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (ret == 0) {
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return 0;
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (ret == 2) {
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        FX_DWORD charcode = 0;
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        for (int i = 0; i < char_size; i ++) {
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            charcode = (charcode << 8) + codes[i];
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return charcode;
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (char_size == 4) {
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return 0;
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    codes[char_size ++] = ((FX_LPBYTE)pString)[offset++];
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CMap::GetCharSize(FX_DWORD charcode) const
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (m_CodingScheme) {
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case OneByte:
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 1;
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TwoBytes:
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 2;
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedTwoBytes:
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedFourBytes:
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (charcode < 0x100) {
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 1;
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (charcode < 0x10000) {
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 2;
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (charcode < 0x1000000) {
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 3;
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 4;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 1;
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CMap::CountChar(FX_LPCSTR pString, int size) const
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (m_CodingScheme) {
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case OneByte:
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return size;
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TwoBytes:
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (size + 1) / 2;
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedTwoBytes: {
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int count = 0;
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int i = 0; i < size; i ++) {
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    count ++;
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (m_pLeadingBytes[((FX_LPBYTE)pString)[i]]) {
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        i ++;
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return count;
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedFourBytes: {
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int count = 0, offset = 0;
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                while (offset < size) {
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    GetNextChar(pString, offset);
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    count ++;
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return count;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return size;
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint _GetCharSize(FX_DWORD charcode, _CMap_CodeRange* pRanges, int iRangesSize)
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!iRangesSize) {
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 1;
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE codes[4];
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    codes[0] = codes[1] = 0x00;
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    codes[2] = (FX_BYTE)(charcode >> 8 & 0xFF);
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    codes[3] = (FX_BYTE)charcode;
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int offset = 0, size = 4;
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < 4; ++i) {
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int iSeg = iRangesSize - 1;
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (iSeg >= 0) {
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pRanges[iSeg].m_CharSize < size) {
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iSeg --;
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int iChar = 0;
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (iChar < size) {
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (codes[offset + iChar] < pRanges[iSeg].m_Lower[iChar] ||
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        codes[offset + iChar] > pRanges[iSeg].m_Upper[iChar]) {
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iChar ++;
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (iChar == pRanges[iSeg].m_CharSize) {
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return size;
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iSeg --;
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        size --;
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        offset ++;
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 1;
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CMap::AppendChar(FX_LPSTR str, FX_DWORD charcode) const
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (m_CodingScheme) {
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case OneByte:
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            str[0] = (FX_BYTE)charcode;
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 1;
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TwoBytes:
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            str[0] = (FX_BYTE)(charcode / 256);
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            str[1] = (FX_BYTE)(charcode % 256);
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 2;
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedTwoBytes:
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MixedFourBytes:
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (charcode < 0x100) {
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _CMap_CodeRange* pRanges = (_CMap_CodeRange*)m_pLeadingBytes;
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int iSize = _GetCharSize(charcode, pRanges, m_nCodeRanges);
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (iSize == 0) {
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    iSize = 1;
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (iSize > 1) {
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXSYS_memset32(str, 0, sizeof(FX_BYTE) * iSize);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[iSize - 1] = (FX_BYTE)charcode;
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return iSize;
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (charcode < 0x10000) {
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[0] = (FX_BYTE)(charcode >> 8);
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[1] = (FX_BYTE)charcode;
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 2;
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (charcode < 0x1000000) {
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[0] = (FX_BYTE)(charcode >> 16);
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[1] = (FX_BYTE)(charcode >> 8);
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[2] = (FX_BYTE)charcode;
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 3;
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[0] = (FX_BYTE)(charcode >> 24);
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[1] = (FX_BYTE)(charcode >> 16);
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[2] = (FX_BYTE)(charcode >> 8);
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                str[3] = (FX_BYTE)charcode;
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 4;
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CID2UnicodeMap::CPDF_CID2UnicodeMap()
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_EmbeddedCount = 0;
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pExternalMap = NULL;
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CID2UnicodeMap::~CPDF_CID2UnicodeMap()
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pExternalMap) {
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pExternalMap;
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CID2UnicodeMap::Initialize()
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pExternalMap = FX_NEW CPDF_FXMP;
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CID2UnicodeMap::IsLoaded()
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_EmbeddedCount != 0;
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_EmbeddedCount != 0 || (m_pExternalMap != NULL && m_pExternalMap->IsLoaded());
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_WCHAR CPDF_CID2UnicodeMap::UnicodeFromCID(FX_WORD CID)
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Charset == CIDSET_UNICODE) {
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CID;
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (CID < m_EmbeddedCount) {
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pEmbeddedMap[CID];
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCBYTE record = m_pExternalMap->GetRecord(CID);
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (record == NULL) {
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return *(FX_WORD*)record;
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid FPDFAPI_LoadCID2UnicodeMap(int charset, const FX_WORD*& pMap, FX_DWORD& count);
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CID2UnicodeMap::Load(CPDF_CMapManager* pMgr, int charset, FX_BOOL bPromptCJK)
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Charset = charset;
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FPDFAPI_LoadCID2UnicodeMap(charset, m_pEmbeddedMap, m_EmbeddedCount);
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_EmbeddedCount) {
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPVOID pPackage = pMgr->GetPackage(bPromptCJK);
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPackage == NULL) {
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pExternalMap->LoadFile(pPackage, FX_BSTRC("CIDInfo_") + g_CharsetNames[charset]);
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ttgsubtable.h"
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CIDFont::CPDF_CIDFont()
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCMap = NULL;
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAllocatedCMap = NULL;
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCID2UnicodeMap = NULL;
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAnsiWidths = NULL;
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCIDToGIDMap = NULL;
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bCIDIsGID = FALSE;
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bAdobeCourierStd = FALSE;
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pTTGSUBTable = NULL;
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset8(m_CharBBox, 0xff, 256 * sizeof(FX_SMALL_RECT));
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_CIDFont::~CPDF_CIDFont()
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAnsiWidths) {
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(m_pAnsiWidths);
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAllocatedCMap) {
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pAllocatedCMap;
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCIDToGIDMap) {
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCIDToGIDMap;
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pTTGSUBTable) {
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pTTGSUBTable;
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_WORD CPDF_CIDFont::CIDFromCharCode(FX_DWORD charcode) const
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCMap == NULL) {
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (FX_WORD)charcode;
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCMap->CIDFromCharCode(charcode);
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CIDFont::IsVertWriting() const
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCMap ? m_pCMap->IsVertWriting() : FALSE;
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern FX_DWORD FPDFAPI_CharCodeFromCID(const FXCMAP_CMap* pMap, FX_WORD cid);
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_DWORD _EmbeddedCharcodeFromUnicode(const FXCMAP_CMap* pEmbedMap, int charset, FX_WCHAR unicode)
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (charset <= 0 || charset > 4) {
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCodes == NULL) {
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count;
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < nCodes; i++) {
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pCodes[i] == unicode) {
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD CharCode = FPDFAPI_CharCodeFromCID(pEmbedMap, i);
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (CharCode == 0) {
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return CharCode;
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_WCHAR _EmbeddedUnicodeFromCharcode(const FXCMAP_CMap* pEmbedMap, int charset, FX_DWORD charcode)
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (charset <= 0 || charset > 4) {
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_WORD cid = FPDFAPI_CIDFromCharCode(pEmbedMap, charcode);
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cid == 0) {
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_FontGlobals* pFontGlobals = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals();
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const FX_WORD* pCodes = pFontGlobals->m_EmbeddedToUnicodes[charset].m_pMap;
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCodes == NULL) {
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (cid < pFontGlobals->m_EmbeddedToUnicodes[charset].m_Count) {
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return pCodes[cid];
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_WCHAR CPDF_CIDFont::_UnicodeFromCharCode(FX_DWORD charcode) const
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (m_pCMap->m_Coding) {
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_UCS2:
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_UTF16:
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (FX_WCHAR)charcode;
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_CID:
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) {
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 0;
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)charcode);
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pCMap->IsLoaded() || m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) {
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_WCHAR unicode;
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int charsize = 1;
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (charcode > 255) {
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            charcode = (charcode % 256) * 256 + (charcode / 256);
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            charsize = 2;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int ret = FXSYS_MultiByteToWideChar(g_CharsetCPs[m_pCMap->m_Coding], 0, (FX_LPCSTR)&charcode, charsize, &unicode, 1);
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (ret != 1) {
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 0;
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return unicode;
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pCMap->m_pEmbedMap) {
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return _EmbeddedUnicodeFromCharcode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, charcode);
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 0;
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCID2UnicodeMap->UnicodeFromCID(CIDFromCharCode(charcode));
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CPDF_CIDFont::_CharCodeFromUnicode(FX_WCHAR unicode) const
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (m_pCMap->m_Coding) {
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_UNKNOWN:
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 0;
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_UCS2:
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_UTF16:
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return unicode;
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_CID: {
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) {
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return 0;
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_DWORD CID = 0;
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                while (CID < 65536) {
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_WCHAR this_unicode = m_pCID2UnicodeMap->UnicodeFromCID((FX_WORD)CID);
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (this_unicode == unicode) {
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return CID;
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    CID ++;
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE buffer[32];
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret = FXSYS_WideCharToMultiByte(g_CharsetCPs[m_pCMap->m_Coding], 0, &unicode, 1, (char*)buffer, 4, NULL, NULL);
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret == 1) {
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return buffer[0];
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (ret == 2) {
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return buffer[0] * 256 + buffer[1];
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (unicode < 0x80) {
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (FX_DWORD)unicode;
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pCMap->m_pEmbedMap) {
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return _EmbeddedCharcodeFromUnicode(m_pCMap->m_pEmbedMap, m_pCMap->m_Charset, unicode);
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return 0;
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void FT_UseCIDCharmap(FXFT_Face face, int coding)
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int encoding;
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (coding) {
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_GB:
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            encoding = FXFT_ENCODING_GB2312;
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_BIG5:
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            encoding = FXFT_ENCODING_BIG5;
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_JIS:
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            encoding = FXFT_ENCODING_SJIS;
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CIDCODING_KOREA:
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            encoding = FXFT_ENCODING_JOHAB;
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        default:
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            encoding = FXFT_ENCODING_UNICODE;
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int err = FXFT_Select_Charmap(face, encoding);
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (err) {
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        err = FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE);
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (err && FXFT_Get_Face_Charmaps(face)) {
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXFT_Set_Charmap(face, *FXFT_Get_Face_Charmaps(face));
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CIDFont::_Load()
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFontDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("TrueType")) {
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return LoadGB2312();
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pFonts = m_pFontDict->GetArray(FX_BSTRC("DescendantFonts"));
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFonts == NULL) {
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFonts->GetCount() != 1) {
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pCIDFontDict = pFonts->GetDict(0);
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCIDFontDict == NULL) {
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BaseFont = pCIDFontDict->GetString(FX_BSTRC("BaseFont"));
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((m_BaseFont.Compare("CourierStd") == 0 || m_BaseFont.Compare("CourierStd-Bold") == 0
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            || m_BaseFont.Compare("CourierStd-BoldOblique") == 0 || m_BaseFont.Compare("CourierStd-Oblique") == 0)
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            && !IsEmbedded()) {
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bAdobeCourierStd = TRUE;
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDesc = pCIDFontDict->GetDict(FX_BSTRC("FontDescriptor"));
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFontDesc) {
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        LoadFontDescriptor(pFontDesc);
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pEncoding = m_pFontDict->GetElementValue(FX_BSTRC("Encoding"));
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pEncoding == NULL) {
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString subtype = pCIDFontDict->GetString(FX_BSTRC("Subtype"));
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bType1 = FALSE;
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (subtype == FX_BSTRC("CIDFontType0")) {
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_bType1 = TRUE;
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pEncoding->GetType() == PDFOBJ_NAME) {
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString cmap = pEncoding->GetString();
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetPredefinedCMap(cmap,
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  m_pFontFile && m_bType1);
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (pEncoding->GetType() == PDFOBJ_STREAM) {
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAllocatedCMap = m_pCMap = FX_NEW CPDF_CMap;
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Stream* pStream = (CPDF_Stream*)pEncoding;
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_StreamAcc acc;
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        acc.LoadAllData(pStream, FALSE);
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCMap->LoadEmbedded(acc.GetData(), acc.GetSize());
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCMap == NULL) {
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Charset = m_pCMap->m_Charset;
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Charset == CIDSET_UNKNOWN) {
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pCIDInfo = pCIDFontDict->GetDict(FX_BSTRC("CIDSystemInfo"));
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pCIDInfo) {
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Charset = _CharsetFromOrdering(pCIDInfo->GetString(FX_BSTRC("Ordering")));
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Charset != CIDSET_UNKNOWN)
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(m_Charset,
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            m_pFontFile == NULL && (m_pCMap->m_Coding == CIDCODING_CID || pCIDFontDict->KeyExist(FX_BSTRC("W"))));
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Font.GetFace()) {
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_bType1) {
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXFT_Select_Charmap(m_Font.GetFace(), FXFT_ENCODING_UNICODE);
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FT_UseCIDCharmap(m_Font.GetFace(), m_pCMap->m_Coding);
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DefaultWidth = pCIDFontDict->GetInteger(FX_BSTRC("DW"), 1000);
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pWidthArray = pCIDFontDict->GetArray(FX_BSTRC("W"));
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pWidthArray) {
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        LoadMetricsArray(pWidthArray, m_WidthList, 1);
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!IsEmbedded()) {
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        LoadSubstFont();
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (1) {
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pFontFile || (GetSubstFont()->m_SubstFlags & FXFONT_SUBST_EXACT)) {
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Object* pmap = pCIDFontDict->GetElementValue(FX_BSTRC("CIDToGIDMap"));
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pmap) {
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pmap->GetType() == PDFOBJ_STREAM) {
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pCIDToGIDMap = FX_NEW CPDF_StreamAcc;
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pCIDToGIDMap->LoadAllData((CPDF_Stream*)pmap, FALSE);
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if (pmap->GetString() == FX_BSTRC("Identity")) {
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (m_pFontFile) {
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        m_bCIDIsGID = TRUE;
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_bCIDIsGID = TRUE;
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CheckFontMetrics();
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (IsVertWriting()) {
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray = pCIDFontDict->GetArray(FX_BSTRC("W2"));
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pWidthArray) {
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            LoadMetricsArray(pWidthArray, m_VertMetrics, 3);
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pDefaultArray = pCIDFontDict->GetArray(FX_BSTRC("DW2"));
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pDefaultArray) {
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_DefaultVY = pDefaultArray->GetInteger(0);
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_DefaultW1 = pDefaultArray->GetInteger(1);
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_DefaultVY = 880;
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_DefaultW1 = -1000;
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_FLOAT _CIDTransformToFloat(FX_BYTE ch)
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ch < 128) {
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return ch * 1.0f / 127;
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (-255 + ch) * 1.0f / 127;
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CIDFont::GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level)
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (charcode < 256 && m_CharBBox[charcode].Right != -1) {
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.bottom = m_CharBBox[charcode].Bottom;
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.left = m_CharBBox[charcode].Left;
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.right = m_CharBBox[charcode].Right;
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.top = m_CharBBox[charcode].Top;
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bVert = FALSE;
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int glyph_index = GlyphFromCharCode(charcode, &bVert);
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Font.m_Face == NULL) {
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect = FX_RECT(0, 0, 0, 0);
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect.left = rect.bottom = rect.right = rect.top = 0;
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXFT_Face face = m_Font.m_Face;
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (FXFT_Is_Face_Tricky(face)) {
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!err) {
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXFT_BBox cbox;
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXFT_Glyph glyph;
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                err = FXFT_Get_Glyph(((FXFT_Face)face)->glyph, &glyph);
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!err) {
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int pixel_size_x = ((FXFT_Face)face)->size->metrics.x_ppem;
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int	pixel_size_y = ((FXFT_Face)face)->size->metrics.y_ppem;
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pixel_size_x == 0 || pixel_size_y == 0) {
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.left = cbox.xMin;
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.right = cbox.xMax;
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.top = cbox.yMax;
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.bottom = cbox.yMin;
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.left = cbox.xMin * 1000 / pixel_size_x;
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.right = cbox.xMax * 1000 / pixel_size_x;
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.top = cbox.yMax * 1000 / pixel_size_y;
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.bottom = cbox.yMin * 1000 / pixel_size_y;
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (rect.top > FXFT_Get_Face_Ascender(face)) {
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.top = FXFT_Get_Face_Ascender(face);
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (rect.bottom < FXFT_Get_Face_Descender(face)) {
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        rect.bottom = FXFT_Get_Face_Descender(face);
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FXFT_Done_Glyph(glyph);
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int err = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_SCALE);
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (err == 0) {
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.left = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face), face);
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.right = TT2PDF(FXFT_Get_Glyph_HoriBearingX(face) + FXFT_Get_Glyph_Width(face), face);
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.top = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face), face);
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.top += rect.top / 64;
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rect.bottom = TT2PDF(FXFT_Get_Glyph_HoriBearingY(face) - FXFT_Get_Glyph_Height(face), face);
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFontFile == NULL && m_Charset == CIDSET_JAPAN1) {
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_WORD CID = CIDFromCharCode(charcode);
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPCBYTE pTransform = GetCIDTransform(CID);
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pTransform && !bVert) {
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_AffineMatrix matrix(_CIDTransformToFloat(pTransform[0]), _CIDTransformToFloat(pTransform[1]),
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    _CIDTransformToFloat(pTransform[2]), _CIDTransformToFloat(pTransform[3]),
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    _CIDTransformToFloat(pTransform[4]) * 1000 , _CIDTransformToFloat(pTransform[5]) * 1000);
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_FloatRect rect_f(rect);
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect_f.Transform(&matrix);
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect = rect_f.GetOutterRect();
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (charcode < 256) {
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CharBBox[charcode].Bottom = (short)rect.bottom;
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CharBBox[charcode].Left = (short)rect.left;
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CharBBox[charcode].Right = (short)rect.right;
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_CharBBox[charcode].Top = (short)rect.top;
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CIDFont::GetCharWidthF(FX_DWORD charcode, int level)
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pAnsiWidths && charcode < 0x80) {
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pAnsiWidths[charcode];
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_WORD cid = CIDFromCharCode(charcode);
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_WidthList.GetSize();
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD* list = m_WidthList.GetData();
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < size; i += 3) {
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (cid >= list[i] && cid <= list[i + 1]) {
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (int)list[i + 2];
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_DefaultWidth;
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovshort CPDF_CIDFont::GetVertWidth(FX_WORD CID) const
1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (vertsize == 0) {
1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_DefaultW1;
1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const FX_DWORD* pTable = m_VertMetrics.GetData();
1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_DWORD i = 0; i < vertsize; i ++)
1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (short)(int)pTable[i * 5 + 2];
1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_DefaultW1;
1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CIDFont::GetVertOrigin(FX_WORD CID, short& vx, short &vy) const
1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD vertsize = m_VertMetrics.GetSize() / 5;
1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (vertsize) {
1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const FX_DWORD* pTable = m_VertMetrics.GetData();
1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD i = 0; i < vertsize; i ++)
1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pTable[i * 5] <= CID && pTable[i * 5 + 1] >= CID) {
1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                vx = (short)(int)pTable[i * 5 + 3];
1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                vy = (short)(int)pTable[i * 5 + 4];
1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD dwWidth = m_DefaultWidth;
1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_WidthList.GetSize();
1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const FX_DWORD* list = m_WidthList.GetData();
1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < size; i += 3) {
1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (CID >= list[i] && CID <= list[i + 1]) {
1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            dwWidth = (FX_WORD)list[i + 2];
1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    vx = (short)dwWidth / 2;
1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    vy = (short)m_DefaultVY;
1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint	CPDF_CIDFont::GetGlyphIndex(FX_DWORD unicode, FX_BOOL *pVertGlyph)
1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pVertGlyph) {
1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pVertGlyph = FALSE;
1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = FXFT_Get_Char_Index(m_Font.m_Face, unicode );
1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (unicode == 0x2502) {
1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return index;
1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (index && IsVertWriting()) {
1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pTTGSUBTable) {
1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            TT_uint32_t vindex = 0;
1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (vindex) {
1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                index = vindex;
1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pVertGlyph) {
1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *pVertGlyph = TRUE;
1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return index;
1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (NULL == m_Font.m_pGsubData) {
1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            unsigned long length = 0;
1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int error = FXFT_Load_Sfnt_Table( m_Font.m_Face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, NULL, &length);
1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!error) {
1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_Font.m_pGsubData = (unsigned char*)FX_Alloc(FX_BYTE, length);
1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int error = FXFT_Load_Sfnt_Table( m_Font.m_Face, FT_MAKE_TAG('G', 'S', 'U', 'B'), 0, m_Font.m_pGsubData, NULL);
1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!error && m_Font.m_pGsubData) {
1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pTTGSUBTable = FX_NEW CFX_CTTGSUBTable;
1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pTTGSUBTable->LoadGSUBTable((FT_Bytes)m_Font.m_pGsubData);
1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            TT_uint32_t vindex = 0;
1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pTTGSUBTable->GetVerticalGlyph(index, &vindex);
1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (vindex) {
1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                index = vindex;
1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pVertGlyph) {
1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    *pVertGlyph = TRUE;
1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return index;
1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pVertGlyph) {
1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pVertGlyph = FALSE;
1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return index;
1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CIDFont::GlyphFromCharCode(FX_DWORD charcode, FX_BOOL *pVertGlyph)
1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pVertGlyph) {
1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *pVertGlyph = FALSE;
1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFontFile == NULL && m_pCIDToGIDMap == NULL) {
1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_WORD cid = CIDFromCharCode(charcode);
1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_WCHAR unicode = 0;
1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_bCIDIsGID) {
1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return cid;
1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_Flags & PDFFONT_SYMBOLIC) {
1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return cid;
1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_WideString uni_str = UnicodeFromCharCode(charcode);
1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (uni_str.IsEmpty()) {
1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return cid;
1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            unicode = uni_str.GetAt(0);
1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (cid && m_pCID2UnicodeMap && m_pCID2UnicodeMap->IsLoaded()) {
1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = m_pCID2UnicodeMap->UnicodeFromCID(cid);
1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (unicode == 0) {
1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = _UnicodeFromCharCode(charcode);
1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (unicode == 0 && !(m_Flags & PDFFONT_SYMBOLIC)) {
1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = UnicodeFromCharCode(charcode).GetAt(0);
1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (unicode == 0) {
1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!m_bAdobeCourierStd) {
1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return charcode == 0 ? -1 : (int)charcode;
1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            charcode += 31;
1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = 0, iBaseEncoding;
1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bMSUnicode = FT_UseTTCharmap(m_Font.m_Face, 3, 1);
1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_BOOL bMacRoman = FALSE;
1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!bMSUnicode) {
1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                bMacRoman = FT_UseTTCharmap(m_Font.m_Face, 1, 0);
1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iBaseEncoding = PDFFONT_ENCODING_STANDARD;
1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bMSUnicode) {
1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iBaseEncoding = PDFFONT_ENCODING_WINANSI;
1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (bMacRoman) {
1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iBaseEncoding = PDFFONT_ENCODING_MACROMAN;
1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_LPCSTR name = GetAdobeCharName(iBaseEncoding, NULL, charcode);
1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (name == NULL) {
1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return charcode == 0 ? -1 : (int)charcode;
1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_WORD unicode = PDF_UnicodeFromAdobeName(name);
1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (unicode) {
1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bMSUnicode) {
1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    index = FXFT_Get_Char_Index(m_Font.m_Face, unicode);
1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else if (bMacRoman) {
1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    FX_DWORD maccode = FT_CharCodeFromUnicode(FXFT_ENCODING_APPLE_ROMAN, unicode);
1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    index = !maccode ? FXFT_Get_Name_Index(m_Font.m_Face, (char *)name) : FXFT_Get_Char_Index(m_Font.m_Face, maccode);
1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return FXFT_Get_Char_Index(m_Font.m_Face, unicode);
1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return charcode == 0 ? -1 : (int)charcode;
1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (index == 0 || index == 0xffff) {
1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return charcode == 0 ? -1 : (int)charcode;
1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return index;
1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Charset == CIDSET_JAPAN1) {
1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (unicode == '\\') {
1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = '/';
1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_) && _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else if (unicode == 0xa5) {
1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = 0x5c;
1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Font.m_Face == NULL) {
1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return unicode;
1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int err = FXFT_Select_Charmap(m_Font.m_Face, FXFT_ENCODING_UNICODE);
1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (err != 0) {
1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int i;
1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.m_Face); i ++) {
1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FX_DWORD ret = FT_CharCodeFromUnicode(FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]), (FX_WCHAR)charcode);
1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (ret == 0) {
1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    continue;
1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXFT_Set_Charmap(m_Font.m_Face, FXFT_Get_Face_Charmaps(m_Font.m_Face)[i]);
1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = (FX_WCHAR)ret;
1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (i == FXFT_Get_Face_CharmapCount(m_Font.m_Face) && i) {
1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                FXFT_Set_Charmap(m_Font.m_Face, FXFT_Get_Face_Charmaps(m_Font.m_Face)[0]);
1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                unicode = (FX_WCHAR)charcode;
1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (FXFT_Get_Face_Charmap(m_Font.m_Face)) {
1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int index = GetGlyphIndex(unicode, pVertGlyph);
1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (index == 0) {
1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return -1;
1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return index;
1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return unicode ;
1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Font.m_Face == NULL) {
1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_WORD cid = CIDFromCharCode(charcode);
1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bType1) {
1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (NULL == m_pCIDToGIDMap) {
1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return cid;
1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pCIDToGIDMap == NULL) {
1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pFontFile && m_pCMap->m_pMapping == NULL) {
1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return cid;
1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_pCMap->m_Coding == CIDCODING_UNKNOWN || FXFT_Get_Face_Charmap(m_Font.m_Face) == NULL) {
1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return cid;
1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmap(m_Font.m_Face)) == FXFT_ENCODING_UNICODE) {
1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CFX_WideString unicode_str = UnicodeFromCharCode(charcode);
1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (unicode_str.IsEmpty()) {
1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return -1;
1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                charcode = unicode_str.GetAt(0);
1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return GetGlyphIndex(charcode, pVertGlyph);
1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD byte_pos = cid * 2;
1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (byte_pos + 2 > m_pCIDToGIDMap->GetSize()) {
1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCBYTE pdata = m_pCIDToGIDMap->GetData() + byte_pos;
1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pdata[0] * 256 + pdata[1];
1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CPDF_CIDFont::GetNextChar(FX_LPCSTR pString, int& offset) const
1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCMap->GetNextChar(pString, offset);
1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CIDFont::GetCharSize(FX_DWORD charcode) const
1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCMap->GetCharSize(charcode);
1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CIDFont::CountChar(FX_LPCSTR pString, int size) const
1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCMap->CountChar(pString, size);
1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_CIDFont::AppendChar(FX_LPSTR str, FX_DWORD charcode) const
1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pCMap->AppendChar(str, charcode);
1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CIDFont::IsUnicodeCompatible() const
1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pCMap->IsLoaded() || m_pCID2UnicodeMap == NULL || !m_pCID2UnicodeMap->IsLoaded()) {
1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pCMap->m_Coding != CIDCODING_UNKNOWN;
1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CIDFont::IsFontStyleFromCharCode(FX_DWORD charcode) const
1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CIDFont::LoadSubstFont()
1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Font.LoadSubst(m_BaseFont, !m_bType1, m_Flags, m_StemV * 5, m_ItalicAngle, g_CharsetCPs[m_Charset], IsVertWriting());
1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_CIDFont::LoadMetricsArray(CPDF_Array* pArray, CFX_DWordArray& result, int nElements)
1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int width_status = 0;
1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iCurElement = 0;
1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int first_code = 0, last_code;
1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD count = pArray->GetCount();
1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_DWORD i = 0; i < count; i ++) {
1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pObj = pArray->GetElementValue(i);
1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pObj == NULL) {
1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pObj->GetType() == PDFOBJ_ARRAY) {
1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (width_status != 1) {
1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return;
1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Array* pArray = (CPDF_Array*)pObj;
1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FX_DWORD count = pArray->GetCount();
1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (FX_DWORD j = 0; j < count; j += nElements) {
1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                result.Add(first_code);
1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                result.Add(first_code);
1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int k = 0; k < nElements; k ++) {
1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    result.Add(pArray->GetInteger(j + k));
1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                first_code ++;
1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            width_status = 0;
1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (width_status == 0) {
1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                first_code = pObj->GetInteger();
1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                width_status = 1;
1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else if (width_status == 1) {
1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                last_code = pObj->GetInteger();
1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                width_status = 2;
1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iCurElement = 0;
1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!iCurElement) {
1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    result.Add(first_code);
1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    result.Add(last_code);
1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                result.Add(pObj->GetInteger());
1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                iCurElement ++;
1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (iCurElement == nElements) {
1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    width_status = 0;
1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_CIDFont::LoadGB2312()
1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_BaseFont = m_pFontDict->GetString(FX_BSTRC("BaseFont"));
1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDesc = m_pFontDict->GetDict(FX_BSTRC("FontDescriptor"));
1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFontDesc) {
1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        LoadFontDescriptor(pFontDesc);
1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Charset = CIDSET_GB1;
1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bType1 = FALSE;
1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetPredefinedCMap(
1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                  FX_BSTRC("GBK-EUC-H"), FALSE);
1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCID2UnicodeMap = CPDF_ModuleMgr::Get()->GetPageModule()->GetFontGlobals()->m_CMapManager.GetCID2UnicodeMap(m_Charset, FALSE);
1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!IsEmbedded()) {
1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        LoadSubstFont();
1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CheckFontMetrics();
1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DefaultWidth = 1000;
1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pAnsiWidths = FX_Alloc(FX_WORD, 128);
1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(m_pAnsiWidths, 0, 128 * sizeof(FX_WORD));
1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 32; i < 127; i ++) {
1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pAnsiWidths[i] = 500;
1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst struct _CIDTransform {
1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_WORD		CID;
1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE		a, b, c, d, e, f;
1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovJapan1_VertCIDs[] = {
1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {97, 129, 0, 0, 127, 55, 0},
1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7887, 127, 0, 0, 127, 76, 89},
1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7888, 127, 0, 0, 127, 79, 94},
1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7889, 0, 129, 127, 0, 17, 127},
1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7890, 0, 129, 127, 0, 17, 127},
1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7891, 0, 129, 127, 0, 17, 127},
1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7892, 0, 129, 127, 0, 17, 127},
1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7893, 0, 129, 127, 0, 17, 127},
1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7894, 0, 129, 127, 0, 17, 127},
1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7895, 0, 129, 127, 0, 17, 127},
1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7896, 0, 129, 127, 0, 17, 127},
1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7897, 0, 129, 127, 0, 17, 127},
1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7898, 0, 129, 127, 0, 17, 127},
1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7899, 0, 129, 127, 0, 17, 104},
1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7900, 0, 129, 127, 0, 17, 127},
1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7901, 0, 129, 127, 0, 17, 104},
1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7902, 0, 129, 127, 0, 17, 127},
1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7903, 0, 129, 127, 0, 17, 127},
1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7904, 0, 129, 127, 0, 17, 127},
1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7905, 0, 129, 127, 0, 17, 114},
1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7906, 0, 129, 127, 0, 17, 127},
1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7907, 0, 129, 127, 0, 17, 127},
1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7908, 0, 129, 127, 0, 17, 127},
1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7909, 0, 129, 127, 0, 17, 127},
1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7910, 0, 129, 127, 0, 17, 127},
1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7911, 0, 129, 127, 0, 17, 127},
1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7912, 0, 129, 127, 0, 17, 127},
1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7913, 0, 129, 127, 0, 17, 127},
1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7914, 0, 129, 127, 0, 17, 127},
1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7915, 0, 129, 127, 0, 17, 114},
1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7916, 0, 129, 127, 0, 17, 127},
1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7917, 0, 129, 127, 0, 17, 127},
1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7918, 127, 0, 0, 127, 18, 25},
1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7919, 127, 0, 0, 127, 18, 25},
1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7920, 127, 0, 0, 127, 18, 25},
1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7921, 127, 0, 0, 127, 18, 25},
1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7922, 127, 0, 0, 127, 18, 25},
1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7923, 127, 0, 0, 127, 18, 25},
1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7924, 127, 0, 0, 127, 18, 25},
1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7925, 127, 0, 0, 127, 18, 25},
1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7926, 127, 0, 0, 127, 18, 25},
1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7927, 127, 0, 0, 127, 18, 25},
1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7928, 127, 0, 0, 127, 18, 25},
1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7929, 127, 0, 0, 127, 18, 25},
1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7930, 127, 0, 0, 127, 18, 25},
1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7931, 127, 0, 0, 127, 18, 25},
1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7932, 127, 0, 0, 127, 18, 25},
1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7933, 127, 0, 0, 127, 18, 25},
1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7934, 127, 0, 0, 127, 18, 25},
1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7935, 127, 0, 0, 127, 18, 25},
1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7936, 127, 0, 0, 127, 18, 25},
1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7937, 127, 0, 0, 127, 18, 25},
1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7938, 127, 0, 0, 127, 18, 25},
1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {7939, 127, 0, 0, 127, 18, 25},
1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8720, 0, 129, 127, 0, 19, 102},
1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8721, 0, 129, 127, 0, 13, 127},
1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8722, 0, 129, 127, 0, 19, 108},
1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8723, 0, 129, 127, 0, 19, 102},
1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8724, 0, 129, 127, 0, 19, 102},
1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8725, 0, 129, 127, 0, 19, 102},
1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8726, 0, 129, 127, 0, 19, 102},
1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8727, 0, 129, 127, 0, 19, 102},
1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8728, 0, 129, 127, 0, 19, 114},
1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8729, 0, 129, 127, 0, 19, 114},
1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8730, 0, 129, 127, 0, 38, 108},
1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8731, 0, 129, 127, 0, 13, 108},
1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8732, 0, 129, 127, 0, 19, 108},
1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8733, 0, 129, 127, 0, 19, 108},
1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8734, 0, 129, 127, 0, 19, 108},
1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8735, 0, 129, 127, 0, 19, 108},
1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8736, 0, 129, 127, 0, 19, 102},
1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8737, 0, 129, 127, 0, 19, 102},
1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8738, 0, 129, 127, 0, 19, 102},
1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8739, 0, 129, 127, 0, 19, 102},
1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8740, 0, 129, 127, 0, 19, 102},
1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8741, 0, 129, 127, 0, 19, 102},
1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8742, 0, 129, 127, 0, 19, 102},
1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8743, 0, 129, 127, 0, 19, 102},
1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8744, 0, 129, 127, 0, 19, 102},
1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8745, 0, 129, 127, 0, 19, 102},
1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8746, 0, 129, 127, 0, 19, 114},
1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8747, 0, 129, 127, 0, 19, 114},
1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8748, 0, 129, 127, 0, 19, 102},
1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8749, 0, 129, 127, 0, 19, 102},
1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8750, 0, 129, 127, 0, 19, 102},
1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8751, 0, 129, 127, 0, 19, 102},
1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8752, 0, 129, 127, 0, 19, 102},
1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8753, 0, 129, 127, 0, 19, 102},
1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8754, 0, 129, 127, 0, 19, 102},
1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8755, 0, 129, 127, 0, 19, 102},
1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8756, 0, 129, 127, 0, 19, 102},
1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8757, 0, 129, 127, 0, 19, 102},
1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8758, 0, 129, 127, 0, 19, 102},
1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8759, 0, 129, 127, 0, 19, 102},
1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8760, 0, 129, 127, 0, 19, 102},
1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8761, 0, 129, 127, 0, 19, 102},
1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8762, 0, 129, 127, 0, 19, 102},
1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8763, 0, 129, 127, 0, 19, 102},
1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8764, 0, 129, 127, 0, 19, 102},
1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8765, 0, 129, 127, 0, 19, 102},
1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8766, 0, 129, 127, 0, 19, 102},
1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8767, 0, 129, 127, 0, 19, 102},
1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8768, 0, 129, 127, 0, 19, 102},
1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8769, 0, 129, 127, 0, 19, 102},
1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8770, 0, 129, 127, 0, 19, 102},
1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8771, 0, 129, 127, 0, 19, 102},
1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8772, 0, 129, 127, 0, 19, 102},
1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8773, 0, 129, 127, 0, 19, 102},
1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8774, 0, 129, 127, 0, 19, 102},
1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8775, 0, 129, 127, 0, 19, 102},
1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8776, 0, 129, 127, 0, 19, 102},
1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8777, 0, 129, 127, 0, 19, 102},
1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8778, 0, 129, 127, 0, 19, 102},
1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8779, 0, 129, 127, 0, 19, 114},
1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8780, 0, 129, 127, 0, 19, 108},
1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8781, 0, 129, 127, 0, 19, 114},
1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8782, 0, 129, 127, 0, 13, 114},
1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8783, 0, 129, 127, 0, 19, 108},
1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8784, 0, 129, 127, 0, 13, 114},
1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8785, 0, 129, 127, 0, 19, 108},
1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8786, 0, 129, 127, 0, 19, 108},
1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8787, 0, 129, 127, 0, 19, 108},
1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8788, 0, 129, 127, 0, 19, 108},
1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8789, 0, 129, 127, 0, 19, 108},
1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8790, 0, 129, 127, 0, 19, 108},
1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8791, 0, 129, 127, 0, 19, 108},
1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8792, 0, 129, 127, 0, 19, 108},
1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8793, 0, 129, 127, 0, 19, 108},
1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8794, 0, 129, 127, 0, 19, 108},
1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8795, 0, 129, 127, 0, 19, 108},
1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8796, 0, 129, 127, 0, 19, 108},
1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8797, 0, 129, 127, 0, 19, 108},
1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8798, 0, 129, 127, 0, 19, 108},
1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8799, 0, 129, 127, 0, 19, 108},
1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8800, 0, 129, 127, 0, 19, 108},
1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8801, 0, 129, 127, 0, 19, 108},
1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8802, 0, 129, 127, 0, 19, 108},
1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8803, 0, 129, 127, 0, 19, 108},
1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8804, 0, 129, 127, 0, 19, 108},
1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8805, 0, 129, 127, 0, 19, 108},
1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8806, 0, 129, 127, 0, 19, 108},
1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8807, 0, 129, 127, 0, 19, 108},
1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8808, 0, 129, 127, 0, 19, 108},
1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8809, 0, 129, 127, 0, 19, 108},
1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8810, 0, 129, 127, 0, 19, 108},
1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8811, 0, 129, 127, 0, 19, 114},
1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8812, 0, 129, 127, 0, 19, 102},
1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8813, 0, 129, 127, 0, 19, 114},
1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8814, 0, 129, 127, 0, 76, 102},
1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8815, 0, 129, 127, 0, 13, 121},
1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8816, 0, 129, 127, 0, 19, 114},
1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8817, 0, 129, 127, 0, 19, 127},
1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8818, 0, 129, 127, 0, 19, 114},
1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {8819, 0, 129, 127, 0, 218, 108},
1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_LPCBYTE CPDF_CIDFont::GetCIDTransform(FX_WORD CID) const
1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Charset != CIDSET_JAPAN1 || m_pFontFile != NULL) {
1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int begin = 0;
1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int end = sizeof Japan1_VertCIDs / sizeof(struct _CIDTransform) - 1;
1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (begin <= end) {
1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int middle = (begin + end) / 2;
1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_WORD middlecode = Japan1_VertCIDs[middle].CID;
1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (middlecode > CID) {
1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            end = middle - 1;
1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (middlecode < CID) {
1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            begin = middle + 1;
1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return &Japan1_VertCIDs[middle].a;
1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1717