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