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_page.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_module.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_page/pageint.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <limits.h>
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Document::CPDF_Document() : CPDF_IndirectObjects(NULL)
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict = NULL;
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pInfoDict = NULL;
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLinearized = FALSE;
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwFirstPageNo = 0;
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwFirstPageObjNum = 0;
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::CreateNewDoc()
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pRootDict == NULL && m_pInfoDict == NULL);
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict = FX_NEW CPDF_Dictionary;
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict->SetAtName("Type", "Catalog");
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int objnum = AddIndirectObject(m_pRootDict);
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = FX_NEW CPDF_Dictionary;
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPages->SetAtName("Type", "Pages");
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPages->SetAtNumber("Count", 0);
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pPages->SetAt("Kids", FX_NEW CPDF_Array);
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    objnum = AddIndirectObject(pPages);
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRootDict->SetAtReference("Pages", this, objnum);
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pInfoDict = FX_NEW CPDF_Dictionary;
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(m_pInfoDict);
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP874Unicodes[128] = {
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000,
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1250Unicodes[128] = {
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9,
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1251Unicodes[128] = {
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1253Unicodes[128] = {
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000,
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1254Unicodes[128] = {
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF,
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1255Unicodes[128] = {
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7,
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000,
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1256Unicodes[128] = {
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2,
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_WCHAR g_FX_CP1257Unicodes[128] = {
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9,
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef struct {
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE		m_Charset;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const FX_WCHAR*	m_pUnicodes;
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} FX_CharsetUnicodes;
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst FX_CharsetUnicodes g_FX_CharsetUnicodes[] = {
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_THAI_CHARSET, g_FX_CP874Unicodes },
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_EASTEUROPE_CHARSET, g_FX_CP1250Unicodes },
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_RUSSIAN_CHARSET, g_FX_CP1251Unicodes },
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_GREEK_CHARSET, g_FX_CP1253Unicodes },
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_TURKISH_CHARSET, g_FX_CP1254Unicodes },
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_HEBREW_CHARSET, g_FX_CP1255Unicodes },
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_ARABIC_CHARSET, g_FX_CP1256Unicodes },
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { FXFONT_BALTIC_CHARSET, g_FX_CP1257Unicodes },
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_)
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _InsertWidthArray(HDC hDC, int start, int end, CPDF_Array* pWidthArray)
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = end - start + 1;
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int* widths = FX_Alloc(int, size);
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GetCharWidth(hDC, start, end, widths);
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 1; i < size; i ++)
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (widths[i] != *widths) {
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (i == size) {
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int first = pWidthArray->GetInteger(pWidthArray->GetCount() - 1);
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->AddInteger(first + size - 1);
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->AddInteger(*widths);
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidthArray1 = FX_NEW CPDF_Array;
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->Add(pWidthArray1);
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < size; i ++) {
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray1->AddInteger(widths[i]);
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(widths);
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont, FX_BOOL bVert, FX_BOOL bTranslateName)
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LOGFONTA lfa;
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memcpy32(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa);
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName);
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (face.GetLength() >= LF_FACESIZE) {
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_strcpy(lfa.lfFaceName, (FX_LPCSTR)face);
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return AddWindowsFont(&lfa, bVert, bTranslateName);
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern CFX_ByteString _FPDF_GetNameFromTT(FX_LPCBYTE name_table, FX_DWORD name);
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_ByteString _FPDF_GetPSNameFromTT(HDC hDC)
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString result;
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DWORD size = ::GetFontData(hDC, 'eman', 0, NULL, 0);
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (size != GDI_ERROR) {
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        LPBYTE buffer = FX_Alloc(BYTE, size);
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ::GetFontData(hDC, 'eman', 0, buffer, size);
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        result = _FPDF_GetNameFromTT(buffer, 6);
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Free(buffer);
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return result;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, FX_BOOL bVert, FX_BOOL bTranslateName)
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pLogFont->lfHeight = -1000;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pLogFont->lfWidth = 0;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    HGDIOBJ hFont = CreateFontIndirectA(pLogFont);
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    HDC hDC = CreateCompatibleDC(NULL);
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    hFont = SelectObject(hDC, hFont);
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int tm_size = GetOutlineTextMetrics(hDC, 0, NULL);
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (tm_size == 0) {
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hFont = SelectObject(hDC, hFont);
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        DeleteObject(hFont);
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        DeleteDC(hDC);
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LPBYTE tm_buf = FX_Alloc(BYTE, tm_size);
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    OUTLINETEXTMETRIC* ptm = (OUTLINETEXTMETRIC*)tm_buf;
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GetOutlineTextMetrics(hDC, tm_size, ptm);
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int flags = 0, italicangle, ascend, descend, capheight, bbox[4];
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pLogFont->lfItalic) {
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_ITALIC;
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH) {
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_FIXEDPITCH;
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN) {
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_SERIF;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT) {
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_SCRIPT;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET || pLogFont->lfCharSet == GB2312_CHARSET ||
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   pLogFont->lfCharSet == HANGEUL_CHARSET || pLogFont->lfCharSet == SHIFTJIS_CHARSET;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString basefont;
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bTranslateName && bCJK) {
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        basefont = _FPDF_GetPSNameFromTT(hDC);
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (basefont.IsEmpty()) {
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        basefont = pLogFont->lfFaceName;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    italicangle = ptm->otmItalicAngle / 10;
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ascend = ptm->otmrcFontBox.top;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    descend = ptm->otmrcFontBox.bottom;
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    capheight = ptm->otmsCapEmHeight;
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[0] = ptm->otmrcFontBox.left;
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[1] = ptm->otmrcFontBox.bottom;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[2] = ptm->otmrcFontBox.right;
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[3] = ptm->otmrcFontBox.top;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(tm_buf);
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    basefont.Replace(" ", "");
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pBaseDict = FX_NEW CPDF_Dictionary;
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBaseDict->SetAtName("Type", "Font");
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDict = pBaseDict;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bCJK) {
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pLogFont->lfCharSet == ANSI_CHARSET || pLogFont->lfCharSet == DEFAULT_CHARSET ||
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pLogFont->lfCharSet == SYMBOL_CHARSET) {
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pLogFont->lfCharSet == SYMBOL_CHARSET) {
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                flags |= PDFFONT_SYMBOLIC;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                flags |= PDFFONT_NONSYMBOLIC;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            flags |= PDFFONT_NONSYMBOLIC;
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int i;
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes); i ++)
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (g_FX_CharsetUnicodes[i].m_Charset == pLogFont->lfCharSet) {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) {
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Dictionary* pEncoding = FX_NEW CPDF_Dictionary;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pEncoding->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding");
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Array* pArray = FX_NEW CPDF_Array;
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pArray->AddInteger(128);
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int j = 0; j < 128; j ++) {
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (name.IsEmpty()) {
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pArray->AddName(FX_BSTRC(".notdef"));
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pArray->AddName(name);
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pEncoding->SetAt(FX_BSTRC("Differences"), pArray);
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AddIndirectObject(pEncoding);
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncoding);
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pLogFont->lfWeight > FW_MEDIUM && pLogFont->lfItalic) {
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",BoldItalic";
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (pLogFont->lfWeight > FW_MEDIUM) {
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",Bold";
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (pLogFont->lfItalic) {
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",Italic";
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Subtype", "TrueType");
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("BaseFont", basefont);
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtNumber("FirstChar", 32);
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtNumber("LastChar", 255);
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int char_widths[224];
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        GetCharWidth(hDC, 32, 255, char_widths);
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidths = FX_NEW CPDF_Array;
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < 224; i ++) {
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidths->AddInteger(char_widths[i]);
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAt("Widths", pWidths);
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_NONSYMBOLIC;
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict = FX_NEW CPDF_Dictionary;
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString cmap;
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString ordering;
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int supplement;
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidthArray = FX_NEW CPDF_Array;
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (pLogFont->lfCharSet) {
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case CHINESEBIG5_CHARSET:
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "CNS1";
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                supplement = 4;
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(1);
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray);
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case GB2312_CHARSET:
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "GB1", supplement = 2;
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(7716);
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0x20, 0x20, pWidthArray);
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(814);
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0x21, 0x7e, pWidthArray);
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case HANGEUL_CHARSET:
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "Korea1";
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                supplement = 2;
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(1);
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0x20, 0x7e, pWidthArray);
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case SHIFTJIS_CHARSET:
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "Japan1";
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                supplement = 5;
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(231);
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0x20, 0x7d, pWidthArray);
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(326);
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0xa0, 0xa0, pWidthArray);
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(327);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0xa1, 0xdf, pWidthArray);
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(631);
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray(hDC, 0x7e, 0x7e, pWidthArray);
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Subtype", "Type0");
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("BaseFont", basefont);
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Encoding", cmap);
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAt("W", pWidthArray);
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("Type", "Font");
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("Subtype", "CIDFontType2");
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("BaseFont", basefont);
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pCIDSysInfo = FX_NEW CPDF_Dictionary;
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtString("Registry", "Adobe");
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtString("Ordering", ordering);
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtInteger("Supplement", supplement);
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pArray = FX_NEW CPDF_Array;
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAt("DescendantFonts", pArray);
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AddIndirectObject(pFontDict);
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pArray->AddReference(this, pFontDict);
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(pBaseDict);
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDesc = FX_NEW CPDF_Dictionary;
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtName("Type", "FontDescriptor");
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtName("FontName", basefont);
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Flags", flags);
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pBBox = FX_NEW CPDF_Array;
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < 4; i ++) {
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBBox->AddInteger(bbox[i]);
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAt("FontBBox", pBBox);
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("ItalicAngle", italicangle);
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Ascent", ascend);
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Descent", descend);
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("CapHeight", capheight);
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("StemV", pLogFont->lfWeight / 5);
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(pFontDesc);
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    hFont = SelectObject(hDC, hFont);
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DeleteObject(hFont);
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DeleteDC(hDC);
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return LoadFont(pBaseDict);
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if (_FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_)
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_UINT32 FX_GetLangHashCode( FX_LPCSTR pStr)
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_assert( pStr != NULL);
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 iLength = FXSYS_strlen(pStr);
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCSTR pStrEnd = pStr + iLength;
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_UINT32 uHashCode = 0;
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while ( pStr < pStrEnd) {
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        uHashCode = 31 * uHashCode + tolower(*pStr++);
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return uHashCode;
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct FX_LANG2CS {
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD    uLang;
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int         uCharset;
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}*FX_LPLANG2CS;
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic const FX_LANG2CS gs_FXLang2CharsetTable[] = {
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3109, 0},
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3121, 178},
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3129, 162},
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3139, 204},
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3141, 204},
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3166, 0},
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3184, 238},
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3197, 0},
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3201, 0},
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3239, 161},
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3241, 0},
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3246, 0},
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3247, 186},
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3248, 0},
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3259, 178},
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3267, 0},
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3273, 0},
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3276, 0},
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3301, 0},
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3310, 1},
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3325, 177},
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3329, 1},
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3338, 238},
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3341, 238},
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3345, 1},
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3355, 0},
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3370, 0},
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3371, 0},
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3383, 128},
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3424, 204},
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3427, 1},
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3428, 129},
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3436, 178},
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3464, 186},
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3466, 186},
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3486, 204},
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3487, 0},
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3493, 1},
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3494, 0},
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3508, 0},
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3518, 0},
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3520, 0},
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3569, 1},
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3580, 238},
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3588, 0},
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3645, 238},
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3651, 204},
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3672, 238},
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3673, 238},
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3678, 238},
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3679, 238},
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3683, 0},
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3684, 0},
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3693, 1},
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3697, 1},
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3700, 222},
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3710, 162},
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3734, 204},
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3741, 178},
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3749, 162},
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3763, 163},
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3886, 134},
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {105943, 0},
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {106375, 1},
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3923451837, 134},
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {3923451838, 136},
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_WORD FX_GetCsFromLangCode(FX_UINT32 uCode)
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 iStart = 0;
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 iEnd = sizeof(gs_FXLang2CharsetTable) / sizeof(FX_LANG2CS) - 1;
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (iStart <= iEnd) {
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_INT32 iMid = (iStart + iEnd) / 2;
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const FX_LANG2CS &charset = gs_FXLang2CharsetTable[iMid];
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (uCode == charset.uLang) {
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return charset.uCharset;
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (uCode < charset.uLang) {
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iEnd = iMid - 1;
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            iStart = iMid + 1;
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    };
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_WORD FX_GetCharsetFromLang(FX_LPCSTR pLang, FX_INT32 iLength)
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_assert(pLang);
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iLength < 0) {
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iLength = FXSYS_strlen(pLang);
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_UINT32 uHash = FX_GetLangHashCode(pLang);
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FX_GetCsFromLangCode(uHash);
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _CFString2CFXByteString(CFStringRef src, CFX_ByteString &dest)
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SInt32 len =  CFStringGetLength(src);
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFRange range = CFRangeMake(0, len);
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFIndex used = 0;
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    UInt8* pBuffer = (UInt8*)malloc(sizeof(UInt8) * (len + 1));
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(pBuffer, 0, sizeof(UInt8) * (len + 1));
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFStringGetBytes(src, range, kCFStringEncodingASCII, 0, false, pBuffer, len, &used);
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    dest = (FX_LPSTR)pBuffer;
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    free(pBuffer);
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL IsHasCharSet(CFArrayRef languages, const CFX_DWordArray &charSets)
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int iCount = charSets.GetSize();
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < CFArrayGetCount(languages); ++i) {
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(languages, i);
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD CharSet = FX_GetCharsetFromLang(CFStringGetCStringPtr(language, kCFStringEncodingMacRoman), -1);
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int j = 0; j < iCount; ++j) {
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (CharSet == charSets[j]) {
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return TRUE;
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid FX_GetCharWidth(CTFontRef font, UniChar start, UniChar end, int* width)
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CGFloat size = CTFontGetSize(font);
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (; start <= end; ++start) {
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CGGlyph pGlyph = 0;
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFIndex count = 1;
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CTFontGetGlyphsForCharacters(font, &start, &pGlyph, count);
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CGSize advances;
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &pGlyph, &advances, 1);
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *width = (int)(advances.width / size * 1000) ;
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        width++;
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _InsertWidthArray(CTFontRef font, int start, int end, CPDF_Array* pWidthArray)
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = end - start + 1;
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int* widths = FX_Alloc(int, size);
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_GetCharWidth(font, start, end, widths);
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 1; i < size; i ++)
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (widths[i] != *widths) {
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (i == size) {
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int first = pWidthArray->GetInteger(pWidthArray->GetCount() - 1);
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->AddInteger(first + size - 1);
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->AddInteger(*widths);
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidthArray1 = FX_NEW CPDF_Array;
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->Add(pWidthArray1);
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < size; i ++) {
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray1->AddInteger(widths[i]);
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(widths);
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Font* CPDF_Document::AddMacFont(CTFontRef pFont, FX_BOOL bVert, FX_BOOL bTranslateName)
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CTFontRef font = (CTFontRef)pFont;
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CTFontDescriptorRef descriptor = CTFontCopyFontDescriptor(font);
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (descriptor == NULL) {
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString basefont;
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bCJK = FALSE;
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int flags = 0, italicangle = 0, ascend = 0, descend = 0, capheight = 0, bbox[4];
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_memset32(bbox, 0, sizeof(int) * 4);
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFArrayRef languages = (CFArrayRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontLanguagesAttribute);
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (languages == NULL) {
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFRelease(descriptor);
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DWordArray charSets;
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    charSets.Add(FXFONT_CHINESEBIG5_CHARSET);
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    charSets.Add(FXFONT_GB2312_CHARSET);
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    charSets.Add(FXFONT_HANGEUL_CHARSET);
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    charSets.Add(FXFONT_SHIFTJIS_CHARSET);
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (IsHasCharSet(languages, charSets)) {
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bCJK = TRUE;
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFRelease(descriptor);
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFDictionaryRef traits = (CFDictionaryRef)CTFontCopyTraits(font);
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (traits == NULL) {
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFRelease(languages);
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFNumberRef sybolicTrait = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait);
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CTFontSymbolicTraits trait = 0;
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFNumberGetValue(sybolicTrait, kCFNumberSInt32Type, &trait);
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (trait & kCTFontItalicTrait) {
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_ITALIC;
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (trait & kCTFontMonoSpaceTrait) {
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_FIXEDPITCH;
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (trait & kCTFontModernSerifsClass) {
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_SERIF;
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (trait & kCTFontScriptsClass) {
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_SCRIPT;
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFNumberRef weightTrait = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontWeightTrait);
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Float32 weight = 0;
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFNumberGetValue(weightTrait, kCFNumberFloat32Type, &weight);
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    italicangle = CTFontGetSlantAngle(font);
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ascend      = CTFontGetAscent(font);
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    descend     = CTFontGetDescent(font);
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    capheight   = CTFontGetCapHeight(font);
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CGRect box  = CTFontGetBoundingBox(font);
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[0]     = box.origin.x;
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[1]     = box.origin.y;
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[2]     = box.origin.x + box.size.width;
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox[3]     = box.origin.y + box.size.height;
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bTranslateName && bCJK) {
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFStringRef postName = CTFontCopyPostScriptName(font);
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CFString2CFXByteString(postName, basefont);
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFRelease(postName);
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (basefont.IsEmpty()) {
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFStringRef fullName = CTFontCopyFullName(font);
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CFString2CFXByteString(fullName, basefont);
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFRelease(fullName);
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    basefont.Replace(" ", "");
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDict = NULL;
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pBaseDict = FX_NEW CPDF_Dictionary;
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDict = pBaseDict;
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bCJK) {
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.RemoveAll();
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_ANSI_CHARSET);
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_DEFAULT_CHARSET);
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_SYMBOL_CHARSET);
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (IsHasCharSet(languages, charSets)) {
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            charSets.RemoveAll();
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            charSets.Add(FXFONT_SYMBOL_CHARSET);
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (IsHasCharSet(languages, charSets)) {
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                flags |= PDFFONT_SYMBOLIC;
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                flags |= PDFFONT_NONSYMBOLIC;
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            flags |= PDFFONT_NONSYMBOLIC;
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int i;
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes); i ++) {
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                charSets.RemoveAll();
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                charSets.Add(g_FX_CharsetUnicodes[i].m_Charset);
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (IsHasCharSet(languages, charSets)) {
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) {
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Dictionary* pEncoding = FX_NEW CPDF_Dictionary;
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pEncoding->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding");
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Array* pArray = FX_NEW CPDF_Array;
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pArray->AddInteger(128);
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int j = 0; j < 128; j ++) {
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (name.IsEmpty()) {
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pArray->AddName(FX_BSTRC(".notdef"));
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pArray->AddName(name);
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pEncoding->SetAt(FX_BSTRC("Differences"), pArray);
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AddIndirectObject(pEncoding);
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncoding);
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (weight > 0.0 && trait & kCTFontItalicTrait) {
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",BoldItalic";
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (weight > 0.0) {
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",Bold";
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (trait & kCTFontItalicTrait) {
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",Italic";
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Subtype", "TrueType");
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("BaseFont", basefont);
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtNumber("FirstChar", 32);
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtNumber("LastChar", 255);
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int char_widths[224];
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_GetCharWidth(font, 32, 255, char_widths);
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidths = FX_NEW CPDF_Array;
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = 0; i < 224; i ++) {
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidths->AddInteger(char_widths[i]);
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAt("Widths", pWidths);
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }  else {
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_NONSYMBOLIC;
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pArray = NULL;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict = FX_NEW CPDF_Dictionary;
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString cmap;
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString ordering;
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int supplement;
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bFound = FALSE;
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidthArray = FX_NEW CPDF_Array;
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.RemoveAll();
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_CHINESEBIG5_CHARSET);
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (IsHasCharSet(languages, charSets)) {
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ordering = "CNS1";
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            supplement = 4;
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(1);
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0x20, 0x7e, pWidthArray);
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bFound = TRUE;
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.RemoveAll();
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_GB2312_CHARSET);
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!bFound && IsHasCharSet(languages, charSets)) {
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ordering = "GB1", supplement = 2;
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(7716);
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0x20, 0x20, pWidthArray);
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(814);
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0x21, 0x7e, pWidthArray);
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bFound = TRUE;
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.RemoveAll();
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_HANGEUL_CHARSET);
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!bFound && IsHasCharSet(languages, charSets)) {
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ordering = "Korea1";
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            supplement = 2;
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(1);
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0x20, 0x7e, pWidthArray);
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bFound = TRUE;
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.RemoveAll();
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        charSets.Add(FXFONT_SHIFTJIS_CHARSET);
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!bFound && IsHasCharSet(languages, charSets)) {
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ordering = "Japan1";
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            supplement = 5;
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(231);
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0x20, 0x7d, pWidthArray);
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(326);
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0xa0, 0xa0, pWidthArray);
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(327);
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0xa1, 0xdf, pWidthArray);
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray->AddInteger(631);
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            _InsertWidthArray(font, 0x7e, 0x7e, pWidthArray);
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Subtype", "Type0");
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("BaseFont", basefont);
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Encoding", cmap);
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAt("W", pWidthArray);
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("Type", "Font");
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("Subtype", "CIDFontType2");
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("BaseFont", basefont);
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pCIDSysInfo = FX_NEW CPDF_Dictionary;
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtString("Registry", "Adobe");
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtString("Ordering", ordering);
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtInteger("Supplement", supplement);
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pArray = FX_NEW CPDF_Array;
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAt("DescendantFonts", pArray);
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AddIndirectObject(pFontDict);
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pArray->AddReference(this, pFontDict);
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(pBaseDict);
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDesc = FX_NEW CPDF_Dictionary;
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtName("Type", "FontDescriptor");
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtName("FontName", basefont);
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Flags", flags);
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pBBox = FX_NEW CPDF_Array;
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < 4; i ++) {
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBBox->AddInteger(bbox[i]);
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAt("FontBBox", pBBox);
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("ItalicAngle", italicangle);
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Ascent", ascend);
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Descent", descend);
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("CapHeight", capheight);
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CGFloat fStemV = 0;
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int16_t min_width = SHRT_MAX;
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const UniChar stem_chars[] = {'i', 'I', '!', '1'};
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CGGlyph glyphs[count];
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CGRect boundingRects[count];
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (CTFontGetGlyphsForCharacters(font, stem_chars, glyphs, count)) {
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CTFontGetBoundingRectsForGlyphs(font, kCTFontHorizontalOrientation,
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        glyphs, boundingRects, count);
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (size_t i = 0; i < count; i++) {
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int16_t width = boundingRects[i].size.width;
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (width > 0 && width < min_width) {
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                min_width = width;
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                fStemV = min_width;
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("StemV", fStemV);
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(pFontDesc);
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFRelease(traits);
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFRelease(languages);
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return LoadFont(pBaseDict);
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _InsertWidthArray1(CFX_Font* pFont, IFX_FontEncoding* pEncoding, FX_WCHAR start, FX_WCHAR end, CPDF_Array* pWidthArray)
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = end - start + 1;
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int* widths = FX_Alloc(int, size);
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < size; i ++) {
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int glyph_index = pEncoding->GlyphFromCharCode(start + i);
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        widths[i] = pFont->GetGlyphWidth(glyph_index);
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 1; i < size; i ++)
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (widths[i] != *widths) {
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (i == size) {
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int first = pWidthArray->GetInteger(pWidthArray->GetCount() - 1);
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->AddInteger(first + size - 1);
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->AddInteger(*widths);
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidthArray1 = FX_NEW CPDF_Array;
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pWidthArray->Add(pWidthArray1);
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < size; i ++) {
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidthArray1->AddInteger(widths[i]);
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(widths);
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert)
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFont == NULL) {
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bCJK = charset == FXFONT_CHINESEBIG5_CHARSET || charset == FXFONT_GB2312_CHARSET ||
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                   charset == FXFONT_HANGEUL_CHARSET || charset == FXFONT_SHIFTJIS_CHARSET;
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString basefont = pFont->GetFamilyName();
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    basefont.Replace(" ", "");
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int flags = 0;
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFont->IsBold()) {
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_FORCEBOLD;
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFont->IsItalic()) {
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_ITALIC;
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFont->IsFixedWidth()) {
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_FIXEDPITCH;
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pBaseDict = FX_NEW CPDF_Dictionary;
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBaseDict->SetAtName("Type", "Font");
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    IFX_FontEncoding* pEncoding = FXGE_CreateUnicodeEncoding(pFont);
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDict = pBaseDict;
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bCJK) {
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidths = FX_NEW CPDF_Array;
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int charcode;
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (charcode = 32; charcode < 128; charcode ++) {
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int glyph_index = pEncoding->GlyphFromCharCode(charcode);
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int char_width = pFont->GetGlyphWidth(glyph_index);
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pWidths->AddInteger(char_width);
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET ||
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                charset == FXFONT_SYMBOL_CHARSET) {
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (charset == FXFONT_SYMBOL_CHARSET) {
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                flags |= PDFFONT_SYMBOLIC;
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                flags |= PDFFONT_NONSYMBOLIC;
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pBaseDict->SetAtName(FX_BSTRC("Encoding"), "WinAnsiEncoding");
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (charcode = 128; charcode <= 255; charcode ++) {
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int glyph_index = pEncoding->GlyphFromCharCode(charcode);
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int char_width = pFont->GetGlyphWidth(glyph_index);
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidths->AddInteger(char_width);
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            flags |= PDFFONT_NONSYMBOLIC;
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int i;
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (i = 0; i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes); i ++)
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (g_FX_CharsetUnicodes[i].m_Charset == charset) {
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (i < sizeof g_FX_CharsetUnicodes / sizeof(FX_CharsetUnicodes)) {
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Dictionary* pEncodingDict = FX_NEW CPDF_Dictionary;
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pEncodingDict->SetAtName(FX_BSTRC("BaseEncoding"), "WinAnsiEncoding");
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_Array* pArray = FX_NEW CPDF_Array;
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pArray->AddInteger(128);
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                const FX_WCHAR* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes;
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int j = 0; j < 128; j ++) {
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]);
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (name.IsEmpty()) {
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pArray->AddName(FX_BSTRC(".notdef"));
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pArray->AddName(name);
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]);
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    int char_width = pFont->GetGlyphWidth(glyph_index);
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pWidths->AddInteger(char_width);
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pEncodingDict->SetAt(FX_BSTRC("Differences"), pArray);
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                AddIndirectObject(pEncodingDict);
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pBaseDict->SetAtReference(FX_BSTRC("Encoding"), this, pEncodingDict);
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pFont->IsBold() && pFont->IsItalic()) {
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",BoldItalic";
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (pFont->IsBold()) {
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",Bold";
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (pFont->IsItalic()) {
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            basefont += ",Italic";
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Subtype", "TrueType");
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("BaseFont", basefont);
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtNumber("FirstChar", 32);
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtNumber("LastChar", 255);
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAt("Widths", pWidths);
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        flags |= PDFFONT_NONSYMBOLIC;
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict = FX_NEW CPDF_Dictionary;
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString cmap;
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString ordering;
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int supplement;
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pWidthArray = FX_NEW CPDF_Array;
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (charset) {
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case FXFONT_CHINESEBIG5_CHARSET:
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H";
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "CNS1";
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                supplement = 4;
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(1);
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7e, pWidthArray);
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case FXFONT_GB2312_CHARSET:
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "GBK-EUC-V" : "GBK-EUC-H";
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "GB1", supplement = 2;
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(7716);
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0x20, 0x20, pWidthArray);
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(814);
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0x21, 0x7e, pWidthArray);
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case FXFONT_HANGEUL_CHARSET:
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "KSCms-UHC-V" : "KSCms-UHC-H";
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "Korea1";
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                supplement = 2;
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(1);
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7e, pWidthArray);
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case FXFONT_SHIFTJIS_CHARSET:
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                cmap = bVert ? "90ms-RKSJ-V" : "90ms-RKSJ-H";
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ordering = "Japan1";
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                supplement = 5;
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(231);
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0x20, 0x7d, pWidthArray);
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(326);
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0xa0, 0xa0, pWidthArray);
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(327);
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0xa1, 0xdf, pWidthArray);
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pWidthArray->AddInteger(631);
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                _InsertWidthArray1(pFont, pEncoding, 0x7e, 0x7e, pWidthArray);
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Subtype", "Type0");
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("BaseFont", basefont);
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAtName("Encoding", cmap);
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAt("W", pWidthArray);
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("Type", "Font");
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("Subtype", "CIDFontType2");
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAtName("BaseFont", basefont);
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pCIDSysInfo = FX_NEW CPDF_Dictionary;
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtString("Registry", "Adobe");
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtString("Ordering", ordering);
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCIDSysInfo->SetAtInteger("Supplement", supplement);
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pFontDict->SetAt("CIDSystemInfo", pCIDSysInfo);
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pArray = FX_NEW CPDF_Array;
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBaseDict->SetAt("DescendantFonts", pArray);
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        AddIndirectObject(pFontDict);
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pArray->AddReference(this, pFontDict);
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(pBaseDict);
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFontDesc = FX_NEW CPDF_Dictionary;
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtName("Type", "FontDescriptor");
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtName("FontName", basefont);
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Flags", flags);
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("ItalicAngle", pFont->m_pSubstFont ? pFont->m_pSubstFont->m_ItalicAngle : 0);
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Ascent", pFont->GetAscent());
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("Descent", pFont->GetDescent());
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT bbox;
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFont->GetBBox(bbox);
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pBBox = FX_NEW CPDF_Array;
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBBox->AddInteger(bbox.left);
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBBox->AddInteger(bbox.bottom);
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBBox->AddInteger(bbox.right);
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBBox->AddInteger(bbox.top);
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAt("FontBBox", pBBox);
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 nStemV = 0;
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFont->m_pSubstFont) {
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nStemV = pFont->m_pSubstFont->m_Weight / 5;
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'};
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const size_t count = sizeof(stem_chars) / sizeof(stem_chars[0]);
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD glyph = pEncoding->GlyphFromCharCode(stem_chars[0]);
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nStemV = pFont->GetGlyphWidth(glyph);
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (size_t i = 1; i < count; i++) {
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            glyph = pEncoding->GlyphFromCharCode(stem_chars[i]);
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int width = pFont->GetGlyphWidth(glyph);
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (width > 0 && width < nStemV) {
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                nStemV = width;
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pEncoding) {
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pEncoding;
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDesc->SetAtInteger("StemV", nStemV);
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AddIndirectObject(pFontDesc);
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pFontDict->SetAtReference("FontDescriptor", this, pFontDesc);
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return LoadFont(pBaseDict);
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic CPDF_Stream* GetFormStream(CPDF_Document* pDoc, CPDF_Object* pResObj)
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pResObj->GetType() != PDFOBJ_REFERENCE) {
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Reference* pRef = (CPDF_Reference*)pResObj;
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bForm;
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pDoc->IsFormStream(pRef->GetRefObjNum(), bForm) && !bForm) {
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pResObj = pRef->GetDirect();
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pResObj->GetType() != PDFOBJ_STREAM) {
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Stream* pXObject = (CPDF_Stream*)pResObj;
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pXObject->GetDict()->GetString(FX_BSTRC("Subtype")) != FX_BSTRC("Form")) {
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pXObject;
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int InsertDeletePDFPage(CPDF_Document* pDoc, CPDF_Dictionary* pPages,
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               int nPagesToGo, CPDF_Dictionary* pPage, FX_BOOL bInsert, CFX_PtrArray& stackList)
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Array* pKidList = pPages->GetArray("Kids");
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pKidList) {
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nKids = pKidList->GetCount();
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < nKids; i ++) {
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pKid = pKidList->GetDict(i);
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKid->GetString("Type") == FX_BSTRC("Page")) {
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (nPagesToGo == 0) {
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (bInsert) {
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pKidList->InsertAt(i, CPDF_Reference::Create(pDoc, pPage->GetObjNum()));
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pPage->SetAtReference("Parent", pDoc, pPages->GetObjNum());
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pKidList->RemoveAt(i);
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pPages->SetAtInteger("Count", pPages->GetInteger("Count") + (bInsert ? 1 : -1));
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 1;
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nPagesToGo --;
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int nPages = pKid->GetInteger("Count");
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (nPagesToGo < nPages) {
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int stackCount = stackList.GetSize();
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (int j = 0; j < stackCount; ++j) {
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pKid == stackList[j]) {
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return -1;
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                stackList.Add(pKid);
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (InsertDeletePDFPage(pDoc, pKid, nPagesToGo, pPage, bInsert, stackList) < 0) {
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return -1;
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                stackList.RemoveAt(stackCount);
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pPages->SetAtInteger("Count", pPages->GetInteger("Count") + (bInsert ? 1 : -1));
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return 1;
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nPagesToGo -= nPages;
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic int InsertNewPage(CPDF_Document* pDoc, int iPage, CPDF_Dictionary* pPageDict, CFX_DWordArray &pageList)
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pRoot = pDoc->GetRoot();
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pRoot) {
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages"));
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pPages) {
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nPages = pDoc->GetPageCount();
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iPage < 0 || iPage > nPages) {
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return -1;
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iPage == nPages) {
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Array* pPagesList = pPages->GetArray(FX_BSTRC("Kids"));
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pPagesList) {
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pPagesList = FX_NEW CPDF_Array;
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pPages->SetAt(FX_BSTRC("Kids"), pPagesList);
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pPagesList->Add(pPageDict, pDoc);
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pPages->SetAtInteger(FX_BSTRC("Count"), nPages + 1);
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pPageDict->SetAtReference(FX_BSTRC("Parent"), pDoc, pPages->GetObjNum());
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_PtrArray stack;
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        stack.Add(pPages);
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, stack) < 0) {
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return -1;
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pageList.InsertAt(iPage, pPageDict->GetObjNum());
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return iPage;
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage)
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pDict = FX_NEW CPDF_Dictionary;
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pDict->SetAtName("Type", "Page");
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD dwObjNum = AddIndirectObject(pDict);
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) {
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ReleaseIndirectObject(dwObjNum);
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pDict;
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint _PDF_GetStandardFontName(CFX_ByteString& name);
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Font* CPDF_Document::AddStandardFont(FX_LPCSTR font, CPDF_FontEncoding* pEncoding)
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_ByteString name(font, -1);
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (_PDF_GetStandardFontName(name) < 0) {
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return GetPageData()->GetStandardFont(name, pEncoding);
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::DeletePage(int iPage)
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pRoot = GetRoot();
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pRoot == NULL) {
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pPages = pRoot->GetDict("Pages");
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPages == NULL) {
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nPages = pPages->GetInteger("Count");
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (iPage < 0 || iPage >= nPages) {
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_PtrArray stack;
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    stack.Add(pPages);
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (InsertDeletePDFPage(this, pPages, iPage, NULL, FALSE, stack) < 0) {
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PageList.RemoveAt(iPage);
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Object* FPDFAPI_GetPageAttr(CPDF_Dictionary* pPageDict, FX_BSTR name);
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid FPDFAPI_FlatPageAttr(CPDF_Dictionary* pPageDict, FX_BSTR name)
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPageDict->KeyExist(name)) {
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Object* pObj = FPDFAPI_GetPageAttr(pPageDict, name);
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj) {
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pPageDict->SetAt(name, pObj->Clone());
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1206