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