| OLD | NEW |
| (Empty) |
| 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 "core/fpdfapi/fpdf_font/font_int.h" | |
| 8 | |
| 9 #include "core/fpdfapi/cpdf_modulemgr.h" | |
| 10 #include "core/fpdfapi/fpdf_page/cpdf_form.h" | |
| 11 #include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" | |
| 12 #include "core/fpdfapi/fpdf_page/pageint.h" | |
| 13 #include "core/fpdfapi/fpdf_parser/cpdf_array.h" | |
| 14 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" | |
| 15 #include "core/fpdfapi/fpdf_parser/cpdf_document.h" | |
| 16 #include "core/fpdfapi/fpdf_parser/cpdf_name.h" | |
| 17 #include "core/fpdfapi/fpdf_parser/cpdf_number.h" | |
| 18 #include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" | |
| 19 #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" | |
| 20 #include "core/fxcrt/fx_ext.h" | |
| 21 #include "core/fxge/fx_freetype.h" | |
| 22 #include "third_party/base/numerics/safe_conversions.h" | |
| 23 #include "third_party/base/stl_util.h" | |
| 24 | |
| 25 int TT2PDF(int m, FXFT_Face face) { | |
| 26 int upm = FXFT_Get_Face_UnitsPerEM(face); | |
| 27 if (upm == 0) | |
| 28 return m; | |
| 29 return pdfium::base::checked_cast<int>( | |
| 30 (static_cast<double>(m) * 1000 + upm / 2) / upm); | |
| 31 } | |
| 32 | |
| 33 bool FT_UseTTCharmap(FXFT_Face face, int platform_id, int encoding_id) { | |
| 34 auto* pCharMap = FXFT_Get_Face_Charmaps(face); | |
| 35 for (int i = 0; i < FXFT_Get_Face_CharmapCount(face); i++) { | |
| 36 if (FXFT_Get_Charmap_PlatformID(pCharMap[i]) == platform_id && | |
| 37 FXFT_Get_Charmap_EncodingID(pCharMap[i]) == encoding_id) { | |
| 38 FXFT_Set_Charmap(face, pCharMap[i]); | |
| 39 return true; | |
| 40 } | |
| 41 } | |
| 42 return false; | |
| 43 } | |
| 44 | |
| 45 CFX_StockFontArray::CFX_StockFontArray() {} | |
| 46 | |
| 47 CFX_StockFontArray::~CFX_StockFontArray() { | |
| 48 for (size_t i = 0; i < FX_ArraySize(m_StockFonts); ++i) { | |
| 49 if (!m_StockFonts[i]) | |
| 50 continue; | |
| 51 CPDF_Dictionary* pFontDict = m_StockFonts[i]->GetFontDict(); | |
| 52 if (pFontDict) | |
| 53 pFontDict->Release(); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 CPDF_Font* CFX_StockFontArray::GetFont(uint32_t index) const { | |
| 58 if (index >= FX_ArraySize(m_StockFonts)) | |
| 59 return nullptr; | |
| 60 return m_StockFonts[index].get(); | |
| 61 } | |
| 62 | |
| 63 CPDF_Font* CFX_StockFontArray::SetFont(uint32_t index, | |
| 64 std::unique_ptr<CPDF_Font> pFont) { | |
| 65 CPDF_Font* result = pFont.get(); | |
| 66 if (index < FX_ArraySize(m_StockFonts)) | |
| 67 m_StockFonts[index] = std::move(pFont); | |
| 68 return result; | |
| 69 } | |
| 70 | |
| 71 CPDF_FontGlobals::CPDF_FontGlobals() { | |
| 72 FXSYS_memset(m_EmbeddedCharsets, 0, sizeof(m_EmbeddedCharsets)); | |
| 73 FXSYS_memset(m_EmbeddedToUnicodes, 0, sizeof(m_EmbeddedToUnicodes)); | |
| 74 } | |
| 75 | |
| 76 CPDF_FontGlobals::~CPDF_FontGlobals() {} | |
| 77 | |
| 78 CPDF_Font* CPDF_FontGlobals::Find(CPDF_Document* pDoc, uint32_t index) { | |
| 79 auto it = m_StockMap.find(pDoc); | |
| 80 if (it == m_StockMap.end()) | |
| 81 return nullptr; | |
| 82 return it->second ? it->second->GetFont(index) : nullptr; | |
| 83 } | |
| 84 | |
| 85 CPDF_Font* CPDF_FontGlobals::Set(CPDF_Document* pDoc, | |
| 86 uint32_t index, | |
| 87 std::unique_ptr<CPDF_Font> pFont) { | |
| 88 if (!pdfium::ContainsKey(m_StockMap, pDoc)) | |
| 89 m_StockMap[pDoc].reset(new CFX_StockFontArray); | |
| 90 return m_StockMap[pDoc]->SetFont(index, std::move(pFont)); | |
| 91 } | |
| 92 | |
| 93 void CPDF_FontGlobals::Clear(CPDF_Document* pDoc) { | |
| 94 m_StockMap.erase(pDoc); | |
| 95 } | |
| 96 | |
| 97 CFX_WideString CPDF_ToUnicodeMap::Lookup(uint32_t charcode) const { | |
| 98 auto it = m_Map.find(charcode); | |
| 99 if (it != m_Map.end()) { | |
| 100 uint32_t value = it->second; | |
| 101 FX_WCHAR unicode = (FX_WCHAR)(value & 0xffff); | |
| 102 if (unicode != 0xffff) { | |
| 103 return unicode; | |
| 104 } | |
| 105 const FX_WCHAR* buf = m_MultiCharBuf.GetBuffer(); | |
| 106 uint32_t buf_len = m_MultiCharBuf.GetLength(); | |
| 107 if (!buf || buf_len == 0) { | |
| 108 return CFX_WideString(); | |
| 109 } | |
| 110 uint32_t index = value >> 16; | |
| 111 if (index >= buf_len) { | |
| 112 return CFX_WideString(); | |
| 113 } | |
| 114 uint32_t len = buf[index]; | |
| 115 if (index + len < index || index + len >= buf_len) { | |
| 116 return CFX_WideString(); | |
| 117 } | |
| 118 return CFX_WideString(buf + index + 1, len); | |
| 119 } | |
| 120 if (m_pBaseMap) { | |
| 121 return m_pBaseMap->UnicodeFromCID((uint16_t)charcode); | |
| 122 } | |
| 123 return CFX_WideString(); | |
| 124 } | |
| 125 | |
| 126 uint32_t CPDF_ToUnicodeMap::ReverseLookup(FX_WCHAR unicode) const { | |
| 127 for (const auto& pair : m_Map) { | |
| 128 if (pair.second == static_cast<uint32_t>(unicode)) | |
| 129 return pair.first; | |
| 130 } | |
| 131 return 0; | |
| 132 } | |
| 133 | |
| 134 // Static. | |
| 135 uint32_t CPDF_ToUnicodeMap::StringToCode(const CFX_ByteStringC& str) { | |
| 136 int len = str.GetLength(); | |
| 137 if (len == 0) | |
| 138 return 0; | |
| 139 | |
| 140 uint32_t result = 0; | |
| 141 if (str[0] == '<') { | |
| 142 for (int i = 1; i < len && std::isxdigit(str[i]); ++i) | |
| 143 result = result * 16 + FXSYS_toHexDigit(str.CharAt(i)); | |
| 144 return result; | |
| 145 } | |
| 146 | |
| 147 for (int i = 0; i < len && std::isdigit(str[i]); ++i) | |
| 148 result = result * 10 + FXSYS_toDecimalDigit(str.CharAt(i)); | |
| 149 | |
| 150 return result; | |
| 151 } | |
| 152 | |
| 153 static CFX_WideString StringDataAdd(CFX_WideString str) { | |
| 154 CFX_WideString ret; | |
| 155 int len = str.GetLength(); | |
| 156 FX_WCHAR value = 1; | |
| 157 for (int i = len - 1; i >= 0; --i) { | |
| 158 FX_WCHAR ch = str[i] + value; | |
| 159 if (ch < str[i]) { | |
| 160 ret.Insert(0, 0); | |
| 161 } else { | |
| 162 ret.Insert(0, ch); | |
| 163 value = 0; | |
| 164 } | |
| 165 } | |
| 166 if (value) { | |
| 167 ret.Insert(0, value); | |
| 168 } | |
| 169 return ret; | |
| 170 } | |
| 171 | |
| 172 // Static. | |
| 173 CFX_WideString CPDF_ToUnicodeMap::StringToWideString( | |
| 174 const CFX_ByteStringC& str) { | |
| 175 int len = str.GetLength(); | |
| 176 if (len == 0) | |
| 177 return CFX_WideString(); | |
| 178 | |
| 179 CFX_WideString result; | |
| 180 if (str[0] == '<') { | |
| 181 int byte_pos = 0; | |
| 182 FX_WCHAR ch = 0; | |
| 183 for (int i = 1; i < len && std::isxdigit(str[i]); ++i) { | |
| 184 ch = ch * 16 + FXSYS_toHexDigit(str[i]); | |
| 185 byte_pos++; | |
| 186 if (byte_pos == 4) { | |
| 187 result += ch; | |
| 188 byte_pos = 0; | |
| 189 ch = 0; | |
| 190 } | |
| 191 } | |
| 192 return result; | |
| 193 } | |
| 194 return result; | |
| 195 } | |
| 196 | |
| 197 CPDF_ToUnicodeMap::CPDF_ToUnicodeMap() : m_pBaseMap(nullptr) {} | |
| 198 | |
| 199 CPDF_ToUnicodeMap::~CPDF_ToUnicodeMap() {} | |
| 200 | |
| 201 void CPDF_ToUnicodeMap::Load(CPDF_Stream* pStream) { | |
| 202 CIDSet cid_set = CIDSET_UNKNOWN; | |
| 203 CPDF_StreamAcc stream; | |
| 204 stream.LoadAllData(pStream, FALSE); | |
| 205 CPDF_SimpleParser parser(stream.GetData(), stream.GetSize()); | |
| 206 while (1) { | |
| 207 CFX_ByteStringC word = parser.GetWord(); | |
| 208 if (word.IsEmpty()) { | |
| 209 break; | |
| 210 } | |
| 211 if (word == "beginbfchar") { | |
| 212 while (1) { | |
| 213 word = parser.GetWord(); | |
| 214 if (word.IsEmpty() || word == "endbfchar") { | |
| 215 break; | |
| 216 } | |
| 217 uint32_t srccode = StringToCode(word); | |
| 218 word = parser.GetWord(); | |
| 219 CFX_WideString destcode = StringToWideString(word); | |
| 220 int len = destcode.GetLength(); | |
| 221 if (len == 0) { | |
| 222 continue; | |
| 223 } | |
| 224 if (len == 1) { | |
| 225 m_Map[srccode] = destcode.GetAt(0); | |
| 226 } else { | |
| 227 m_Map[srccode] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff; | |
| 228 m_MultiCharBuf.AppendChar(destcode.GetLength()); | |
| 229 m_MultiCharBuf << destcode; | |
| 230 } | |
| 231 } | |
| 232 } else if (word == "beginbfrange") { | |
| 233 while (1) { | |
| 234 CFX_ByteString low, high; | |
| 235 low = parser.GetWord(); | |
| 236 if (low.IsEmpty() || low == "endbfrange") { | |
| 237 break; | |
| 238 } | |
| 239 high = parser.GetWord(); | |
| 240 uint32_t lowcode = StringToCode(low.AsStringC()); | |
| 241 uint32_t highcode = | |
| 242 (lowcode & 0xffffff00) | (StringToCode(high.AsStringC()) & 0xff); | |
| 243 if (highcode == (uint32_t)-1) { | |
| 244 break; | |
| 245 } | |
| 246 CFX_ByteString start(parser.GetWord()); | |
| 247 if (start == "[") { | |
| 248 for (uint32_t code = lowcode; code <= highcode; code++) { | |
| 249 CFX_ByteString dest(parser.GetWord()); | |
| 250 CFX_WideString destcode = StringToWideString(dest.AsStringC()); | |
| 251 int len = destcode.GetLength(); | |
| 252 if (len == 0) { | |
| 253 continue; | |
| 254 } | |
| 255 if (len == 1) { | |
| 256 m_Map[code] = destcode.GetAt(0); | |
| 257 } else { | |
| 258 m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff; | |
| 259 m_MultiCharBuf.AppendChar(destcode.GetLength()); | |
| 260 m_MultiCharBuf << destcode; | |
| 261 } | |
| 262 } | |
| 263 parser.GetWord(); | |
| 264 } else { | |
| 265 CFX_WideString destcode = StringToWideString(start.AsStringC()); | |
| 266 int len = destcode.GetLength(); | |
| 267 uint32_t value = 0; | |
| 268 if (len == 1) { | |
| 269 value = StringToCode(start.AsStringC()); | |
| 270 for (uint32_t code = lowcode; code <= highcode; code++) { | |
| 271 m_Map[code] = value++; | |
| 272 } | |
| 273 } else { | |
| 274 for (uint32_t code = lowcode; code <= highcode; code++) { | |
| 275 CFX_WideString retcode; | |
| 276 if (code == lowcode) { | |
| 277 retcode = destcode; | |
| 278 } else { | |
| 279 retcode = StringDataAdd(destcode); | |
| 280 } | |
| 281 m_Map[code] = m_MultiCharBuf.GetLength() * 0x10000 + 0xffff; | |
| 282 m_MultiCharBuf.AppendChar(retcode.GetLength()); | |
| 283 m_MultiCharBuf << retcode; | |
| 284 destcode = retcode; | |
| 285 } | |
| 286 } | |
| 287 } | |
| 288 } | |
| 289 } else if (word == "/Adobe-Korea1-UCS2") { | |
| 290 cid_set = CIDSET_KOREA1; | |
| 291 } else if (word == "/Adobe-Japan1-UCS2") { | |
| 292 cid_set = CIDSET_JAPAN1; | |
| 293 } else if (word == "/Adobe-CNS1-UCS2") { | |
| 294 cid_set = CIDSET_CNS1; | |
| 295 } else if (word == "/Adobe-GB1-UCS2") { | |
| 296 cid_set = CIDSET_GB1; | |
| 297 } | |
| 298 } | |
| 299 if (cid_set) { | |
| 300 m_pBaseMap = CPDF_ModuleMgr::Get() | |
| 301 ->GetPageModule() | |
| 302 ->GetFontGlobals() | |
| 303 ->m_CMapManager.GetCID2UnicodeMap(cid_set, FALSE); | |
| 304 } else { | |
| 305 m_pBaseMap = nullptr; | |
| 306 } | |
| 307 } | |
| OLD | NEW |