OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 7 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <set> | 10 #include <set> |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 if (widths[i] != *widths) | 193 if (widths[i] != *widths) |
194 break; | 194 break; |
195 } | 195 } |
196 if (i == size) { | 196 if (i == size) { |
197 int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1); | 197 int first = pWidthArray->GetIntegerAt(pWidthArray->GetCount() - 1); |
198 pWidthArray->AddInteger(first + size - 1); | 198 pWidthArray->AddInteger(first + size - 1); |
199 pWidthArray->AddInteger(*widths); | 199 pWidthArray->AddInteger(*widths); |
200 } else { | 200 } else { |
201 CPDF_Array* pWidthArray1 = new CPDF_Array; | 201 CPDF_Array* pWidthArray1 = new CPDF_Array; |
202 pWidthArray->Add(pWidthArray1); | 202 pWidthArray->Add(pWidthArray1); |
203 for (i = 0; i < size; i++) { | 203 for (i = 0; i < size; i++) |
204 pWidthArray1->AddInteger(widths[i]); | 204 pWidthArray1->AddInteger(widths[i]); |
205 } | |
206 } | 205 } |
207 FX_Free(widths); | 206 FX_Free(widths); |
208 } | 207 } |
209 | 208 |
210 CFX_ByteString FPDF_GetPSNameFromTT(HDC hDC) { | 209 CFX_ByteString FPDF_GetPSNameFromTT(HDC hDC) { |
211 CFX_ByteString result; | 210 CFX_ByteString result; |
212 DWORD size = ::GetFontData(hDC, 'eman', 0, nullptr, 0); | 211 DWORD size = ::GetFontData(hDC, 'eman', 0, nullptr, 0); |
213 if (size != GDI_ERROR) { | 212 if (size != GDI_ERROR) { |
214 LPBYTE buffer = FX_Alloc(BYTE, size); | 213 LPBYTE buffer = FX_Alloc(BYTE, size); |
215 ::GetFontData(hDC, 'eman', 0, buffer, size); | 214 ::GetFontData(hDC, 'eman', 0, buffer, size); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 } | 293 } |
295 } | 294 } |
296 return 0; | 295 return 0; |
297 } | 296 } |
298 | 297 |
299 int InsertNewPage(CPDF_Document* pDoc, | 298 int InsertNewPage(CPDF_Document* pDoc, |
300 int iPage, | 299 int iPage, |
301 CPDF_Dictionary* pPageDict, | 300 CPDF_Dictionary* pPageDict, |
302 CFX_ArrayTemplate<uint32_t>& pageList) { | 301 CFX_ArrayTemplate<uint32_t>& pageList) { |
303 CPDF_Dictionary* pRoot = pDoc->GetRoot(); | 302 CPDF_Dictionary* pRoot = pDoc->GetRoot(); |
304 if (!pRoot) | 303 CPDF_Dictionary* pPages = pRoot ? pRoot->GetDictBy("Pages") : nullptr; |
305 return -1; | |
306 | |
307 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); | |
308 if (!pPages) | 304 if (!pPages) |
309 return -1; | 305 return -1; |
310 | 306 |
311 int nPages = pDoc->GetPageCount(); | 307 int nPages = pDoc->GetPageCount(); |
312 if (iPage < 0 || iPage > nPages) | 308 if (iPage < 0 || iPage > nPages) |
313 return -1; | 309 return -1; |
314 | 310 |
315 if (iPage == nPages) { | 311 if (iPage == nPages) { |
316 CPDF_Array* pPagesList = pPages->GetArrayBy("Kids"); | 312 CPDF_Array* pPagesList = pPages->GetArrayBy("Kids"); |
317 if (!pPagesList) { | 313 if (!pPagesList) { |
318 pPagesList = new CPDF_Array; | 314 pPagesList = new CPDF_Array; |
319 pPages->SetAt("Kids", pPagesList); | 315 pPages->SetAt("Kids", pPagesList); |
320 } | 316 } |
321 pPagesList->Add(pPageDict, pDoc); | 317 pPagesList->Add(pPageDict, pDoc); |
322 pPages->SetAtInteger("Count", nPages + 1); | 318 pPages->SetAtInteger("Count", nPages + 1); |
323 pPageDict->SetAtReference("Parent", pDoc, pPages->GetObjNum()); | 319 pPageDict->SetAtReference("Parent", pDoc, pPages->GetObjNum()); |
324 } else { | 320 } else { |
325 std::set<CPDF_Dictionary*> stack = {pPages}; | 321 std::set<CPDF_Dictionary*> stack = {pPages}; |
326 if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0) | 322 if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0) |
327 return -1; | 323 return -1; |
328 } | 324 } |
329 pageList.InsertAt(iPage, pPageDict->GetObjNum()); | 325 pageList.InsertAt(iPage, pPageDict->GetObjNum()); |
330 return iPage; | 326 return iPage; |
331 } | 327 } |
332 | 328 |
333 int CountPages(CPDF_Dictionary* pPages, | 329 int CountPages(CPDF_Dictionary* pPages, |
334 std::set<CPDF_Dictionary*>* visited_pages) { | 330 std::set<CPDF_Dictionary*>* visited_pages) { |
335 int count = pPages->GetIntegerBy("Count"); | 331 int count = pPages->GetIntegerBy("Count"); |
336 if (count > 0 && count < FPDF_PAGE_MAX_NUM) { | 332 if (count > 0 && count < FPDF_PAGE_MAX_NUM) |
337 return count; | 333 return count; |
338 } | |
339 CPDF_Array* pKidList = pPages->GetArrayBy("Kids"); | 334 CPDF_Array* pKidList = pPages->GetArrayBy("Kids"); |
340 if (!pKidList) { | 335 if (!pKidList) |
341 return 0; | 336 return 0; |
342 } | |
343 count = 0; | 337 count = 0; |
344 for (size_t i = 0; i < pKidList->GetCount(); i++) { | 338 for (size_t i = 0; i < pKidList->GetCount(); i++) { |
345 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); | 339 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); |
346 if (!pKid || pdfium::ContainsKey(*visited_pages, pKid)) { | 340 if (!pKid || pdfium::ContainsKey(*visited_pages, pKid)) |
347 continue; | 341 continue; |
348 } | |
349 if (pKid->KeyExist("Kids")) { | 342 if (pKid->KeyExist("Kids")) { |
350 // Use |visited_pages| to help detect circular references of pages. | 343 // Use |visited_pages| to help detect circular references of pages. |
351 pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, | 344 pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, |
352 pKid); | 345 pKid); |
353 count += CountPages(pKid, visited_pages); | 346 count += CountPages(pKid, visited_pages); |
354 } else { | 347 } else { |
355 // This page is a leaf node. | 348 // This page is a leaf node. |
356 count++; | 349 count++; |
357 } | 350 } |
358 } | 351 } |
359 pPages->SetAtInteger("Count", count); | 352 pPages->SetAtInteger("Count", count); |
360 return count; | 353 return count; |
361 } | 354 } |
362 | 355 |
| 356 int CalculateFlags(bool bold, |
| 357 bool italic, |
| 358 bool fixedPitch, |
| 359 bool serif, |
| 360 bool script, |
| 361 bool symbolic) { |
| 362 int flags = 0; |
| 363 if (bold) |
| 364 flags |= PDFFONT_FORCEBOLD; |
| 365 if (italic) |
| 366 flags |= PDFFONT_ITALIC; |
| 367 if (fixedPitch) |
| 368 flags |= PDFFONT_FIXEDPITCH; |
| 369 if (serif) |
| 370 flags |= PDFFONT_SERIF; |
| 371 if (script) |
| 372 flags |= PDFFONT_SCRIPT; |
| 373 if (symbolic) |
| 374 flags |= PDFFONT_SYMBOLIC; |
| 375 else |
| 376 flags |= PDFFONT_NONSYMBOLIC; |
| 377 return flags; |
| 378 } |
| 379 |
| 380 void ProcessNonbCJK(CPDF_Dictionary* pBaseDict, |
| 381 bool bold, |
| 382 bool italic, |
| 383 CFX_ByteString basefont, |
| 384 CPDF_Array* pWidths) { |
| 385 if (bold && italic) |
| 386 basefont += ",BoldItalic"; |
| 387 else if (bold) |
| 388 basefont += ",Bold"; |
| 389 else if (italic) |
| 390 basefont += ",Italic"; |
| 391 pBaseDict->SetAtName("Subtype", "TrueType"); |
| 392 pBaseDict->SetAtName("BaseFont", basefont); |
| 393 pBaseDict->SetAtNumber("FirstChar", 32); |
| 394 pBaseDict->SetAtNumber("LastChar", 255); |
| 395 pBaseDict->SetAt("Widths", pWidths); |
| 396 } |
| 397 |
363 } // namespace | 398 } // namespace |
364 | 399 |
365 CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser) | 400 CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser) |
366 : CPDF_IndirectObjectHolder(), | 401 : CPDF_IndirectObjectHolder(), |
367 m_pParser(std::move(pParser)), | 402 m_pParser(std::move(pParser)), |
368 m_pRootDict(nullptr), | 403 m_pRootDict(nullptr), |
369 m_pInfoDict(nullptr), | 404 m_pInfoDict(nullptr), |
370 m_bLinearized(false), | 405 m_bLinearized(false), |
371 m_iFirstPageNo(0), | 406 m_iFirstPageNo(0), |
372 m_dwFirstPageObjNum(0), | 407 m_dwFirstPageObjNum(0), |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 | 474 |
440 if (level >= FX_MAX_PAGE_LEVEL) | 475 if (level >= FX_MAX_PAGE_LEVEL) |
441 return nullptr; | 476 return nullptr; |
442 | 477 |
443 for (size_t i = 0; i < pKidList->GetCount(); i++) { | 478 for (size_t i = 0; i < pKidList->GetCount(); i++) { |
444 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); | 479 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); |
445 if (!pKid) { | 480 if (!pKid) { |
446 nPagesToGo--; | 481 nPagesToGo--; |
447 continue; | 482 continue; |
448 } | 483 } |
449 if (pKid == pPages) { | 484 if (pKid == pPages) |
450 continue; | 485 continue; |
451 } | |
452 if (!pKid->KeyExist("Kids")) { | 486 if (!pKid->KeyExist("Kids")) { |
453 if (nPagesToGo == 0) { | 487 if (nPagesToGo == 0) |
454 return pKid; | 488 return pKid; |
455 } | 489 |
456 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); | 490 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); |
457 nPagesToGo--; | 491 nPagesToGo--; |
458 } else { | 492 } else { |
459 int nPages = pKid->GetIntegerBy("Count"); | 493 int nPages = pKid->GetIntegerBy("Count"); |
460 if (nPagesToGo < nPages) { | 494 if (nPagesToGo < nPages) |
461 return FindPDFPage(pKid, iPage, nPagesToGo, level + 1); | 495 return FindPDFPage(pKid, iPage, nPagesToGo, level + 1); |
462 } | 496 |
463 nPagesToGo -= nPages; | 497 nPagesToGo -= nPages; |
464 } | 498 } |
465 } | 499 } |
466 return nullptr; | 500 return nullptr; |
467 } | 501 } |
468 | 502 |
| 503 CPDF_Dictionary* CPDF_Document::GetPagesDict() const { |
| 504 CPDF_Dictionary* pRoot = GetRoot(); |
| 505 return pRoot ? pRoot->GetDictBy("Pages") : nullptr; |
| 506 } |
| 507 |
469 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { | 508 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { |
470 if (iPage < 0 || iPage >= m_PageList.GetSize()) | 509 if (iPage < 0 || iPage >= m_PageList.GetSize()) |
471 return nullptr; | 510 return nullptr; |
472 | 511 |
473 if (m_bLinearized && (iPage == m_iFirstPageNo)) { | 512 if (m_bLinearized && (iPage == m_iFirstPageNo)) { |
474 if (CPDF_Dictionary* pDict = | 513 if (CPDF_Dictionary* pDict = |
475 ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) { | 514 ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) { |
476 return pDict; | 515 return pDict; |
477 } | 516 } |
478 } | 517 } |
479 | 518 |
480 int objnum = m_PageList.GetAt(iPage); | 519 int objnum = m_PageList.GetAt(iPage); |
481 if (objnum) { | 520 if (objnum) { |
482 if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum))) | 521 if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum))) |
483 return pDict; | 522 return pDict; |
484 } | 523 } |
485 | 524 |
486 CPDF_Dictionary* pRoot = GetRoot(); | 525 CPDF_Dictionary* pPages = GetPagesDict(); |
487 if (!pRoot) | |
488 return nullptr; | |
489 | |
490 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); | |
491 if (!pPages) | 526 if (!pPages) |
492 return nullptr; | 527 return nullptr; |
493 | 528 |
494 CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0); | 529 CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0); |
495 if (!pPage) | 530 if (!pPage) |
496 return nullptr; | 531 return nullptr; |
497 | 532 |
498 m_PageList.SetAt(iPage, pPage->GetObjNum()); | 533 m_PageList.SetAt(iPage, pPage->GetObjNum()); |
499 return pPage; | 534 return pPage; |
500 } | 535 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 for (uint32_t i = 0; i < nPages; i++) { | 594 for (uint32_t i = 0; i < nPages; i++) { |
560 uint32_t objnum1 = m_PageList.GetAt(i); | 595 uint32_t objnum1 = m_PageList.GetAt(i); |
561 if (objnum1 == objnum) | 596 if (objnum1 == objnum) |
562 return i; | 597 return i; |
563 | 598 |
564 if (!bSkipped && objnum1 == 0) { | 599 if (!bSkipped && objnum1 == 0) { |
565 skip_count = i; | 600 skip_count = i; |
566 bSkipped = true; | 601 bSkipped = true; |
567 } | 602 } |
568 } | 603 } |
569 CPDF_Dictionary* pRoot = GetRoot(); | 604 CPDF_Dictionary* pPages = GetPagesDict(); |
570 if (!pRoot) | |
571 return -1; | |
572 | |
573 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); | |
574 if (!pPages) | 605 if (!pPages) |
575 return -1; | 606 return -1; |
576 | 607 |
577 int index = 0; | 608 int index = 0; |
578 return FindPageIndex(pPages, skip_count, objnum, index); | 609 return FindPageIndex(pPages, skip_count, objnum, index); |
579 } | 610 } |
580 | 611 |
581 int CPDF_Document::GetPageCount() const { | 612 int CPDF_Document::GetPageCount() const { |
582 return m_PageList.GetSize(); | 613 return m_PageList.GetSize(); |
583 } | 614 } |
584 | 615 |
585 int CPDF_Document::RetrievePageCount() const { | 616 int CPDF_Document::RetrievePageCount() const { |
586 CPDF_Dictionary* pRoot = GetRoot(); | 617 CPDF_Dictionary* pPages = GetPagesDict(); |
587 if (!pRoot) | |
588 return 0; | |
589 | |
590 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); | |
591 if (!pPages) | 618 if (!pPages) |
592 return 0; | 619 return 0; |
593 | 620 |
594 if (!pPages->KeyExist("Kids")) | 621 if (!pPages->KeyExist("Kids")) |
595 return 1; | 622 return 1; |
596 | 623 |
597 std::set<CPDF_Dictionary*> visited_pages; | 624 std::set<CPDF_Dictionary*> visited_pages; |
598 visited_pages.insert(pPages); | 625 visited_pages.insert(pPages); |
599 return CountPages(pPages, &visited_pages); | 626 return CountPages(pPages, &visited_pages); |
600 } | 627 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 pDict->SetAtName("Type", "Page"); | 690 pDict->SetAtName("Type", "Page"); |
664 uint32_t dwObjNum = AddIndirectObject(pDict); | 691 uint32_t dwObjNum = AddIndirectObject(pDict); |
665 if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) { | 692 if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) { |
666 ReleaseIndirectObject(dwObjNum); | 693 ReleaseIndirectObject(dwObjNum); |
667 return nullptr; | 694 return nullptr; |
668 } | 695 } |
669 return pDict; | 696 return pDict; |
670 } | 697 } |
671 | 698 |
672 void CPDF_Document::DeletePage(int iPage) { | 699 void CPDF_Document::DeletePage(int iPage) { |
673 CPDF_Dictionary* pRoot = GetRoot(); | 700 CPDF_Dictionary* pPages = GetPagesDict(); |
674 if (!pRoot) | |
675 return; | |
676 | |
677 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); | |
678 if (!pPages) | 701 if (!pPages) |
679 return; | 702 return; |
680 | 703 |
681 int nPages = pPages->GetIntegerBy("Count"); | 704 int nPages = pPages->GetIntegerBy("Count"); |
682 if (iPage < 0 || iPage >= nPages) | 705 if (iPage < 0 || iPage >= nPages) |
683 return; | 706 return; |
684 | 707 |
685 std::set<CPDF_Dictionary*> stack = {pPages}; | 708 std::set<CPDF_Dictionary*> stack = {pPages}; |
686 if (InsertDeletePDFPage(this, pPages, iPage, nullptr, FALSE, &stack) < 0) | 709 if (InsertDeletePDFPage(this, pPages, iPage, nullptr, FALSE, &stack) < 0) |
687 return; | 710 return; |
688 | 711 |
689 m_PageList.RemoveAt(iPage); | 712 m_PageList.RemoveAt(iPage); |
690 } | 713 } |
691 | 714 |
692 CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font, | 715 CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font, |
693 CPDF_FontEncoding* pEncoding) { | 716 CPDF_FontEncoding* pEncoding) { |
694 CFX_ByteString name(font); | 717 CFX_ByteString name(font); |
695 if (PDF_GetStandardFontName(&name) < 0) | 718 if (PDF_GetStandardFontName(&name) < 0) |
696 return nullptr; | 719 return nullptr; |
697 return GetPageData()->GetStandardFont(name, pEncoding); | 720 return GetPageData()->GetStandardFont(name, pEncoding); |
698 } | 721 } |
699 | 722 |
| 723 size_t CPDF_Document::CalculateEncodingDict(int charset, |
| 724 CPDF_Dictionary* pBaseDict) { |
| 725 size_t i; |
| 726 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { |
| 727 if (g_FX_CharsetUnicodes[i].m_Charset == charset) |
| 728 break; |
| 729 } |
| 730 if (i == FX_ArraySize(g_FX_CharsetUnicodes)) |
| 731 return i; |
| 732 CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary; |
| 733 pEncodingDict->SetAtName("BaseEncoding", "WinAnsiEncoding"); |
| 734 CPDF_Array* pArray = new CPDF_Array; |
| 735 pArray->AddInteger(128); |
| 736 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; |
| 737 for (int j = 0; j < 128; j++) { |
| 738 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); |
| 739 pArray->AddName(name.IsEmpty() ? ".notdef" : name); |
| 740 } |
| 741 pEncodingDict->SetAt("Differences", pArray); |
| 742 AddIndirectObject(pEncodingDict); |
| 743 pBaseDict->SetAtReference("Encoding", this, pEncodingDict); |
| 744 return i; |
| 745 } |
| 746 |
700 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { | 747 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
701 if (!pFont) | 748 if (!pFont) |
702 return nullptr; | 749 return nullptr; |
703 | 750 |
704 bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET || | 751 bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET || |
705 charset == FXFONT_GB2312_CHARSET || | 752 charset == FXFONT_GB2312_CHARSET || |
706 charset == FXFONT_HANGEUL_CHARSET || | 753 charset == FXFONT_HANGEUL_CHARSET || |
707 charset == FXFONT_SHIFTJIS_CHARSET; | 754 charset == FXFONT_SHIFTJIS_CHARSET; |
708 CFX_ByteString basefont = pFont->GetFamilyName(); | 755 CFX_ByteString basefont = pFont->GetFamilyName(); |
709 basefont.Replace(" ", ""); | 756 basefont.Replace(" ", ""); |
710 int flags = 0; | 757 int flags = |
711 if (pFont->IsBold()) | 758 CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(), |
712 flags |= PDFFONT_FORCEBOLD; | 759 false, false, charset == FXFONT_SYMBOL_CHARSET); |
713 if (pFont->IsItalic()) | |
714 flags |= PDFFONT_ITALIC; | |
715 if (pFont->IsFixedWidth()) | |
716 flags |= PDFFONT_FIXEDPITCH; | |
717 | 760 |
718 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; | 761 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; |
719 pBaseDict->SetAtName("Type", "Font"); | 762 pBaseDict->SetAtName("Type", "Font"); |
720 std::unique_ptr<CFX_UnicodeEncoding> pEncoding( | 763 std::unique_ptr<CFX_UnicodeEncoding> pEncoding( |
721 new CFX_UnicodeEncoding(pFont)); | 764 new CFX_UnicodeEncoding(pFont)); |
722 CPDF_Dictionary* pFontDict = pBaseDict; | 765 CPDF_Dictionary* pFontDict = pBaseDict; |
723 if (!bCJK) { | 766 if (!bCJK) { |
724 CPDF_Array* pWidths = new CPDF_Array; | 767 CPDF_Array* pWidths = new CPDF_Array; |
725 for (int charcode = 32; charcode < 128; charcode++) { | 768 for (int charcode = 32; charcode < 128; charcode++) { |
726 int glyph_index = pEncoding->GlyphFromCharCode(charcode); | 769 int glyph_index = pEncoding->GlyphFromCharCode(charcode); |
727 int char_width = pFont->GetGlyphWidth(glyph_index); | 770 int char_width = pFont->GetGlyphWidth(glyph_index); |
728 pWidths->AddInteger(char_width); | 771 pWidths->AddInteger(char_width); |
729 } | 772 } |
730 if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET || | 773 if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET || |
731 charset == FXFONT_SYMBOL_CHARSET) { | 774 charset == FXFONT_SYMBOL_CHARSET) { |
732 if (charset == FXFONT_SYMBOL_CHARSET) { | |
733 flags |= PDFFONT_SYMBOLIC; | |
734 } else { | |
735 flags |= PDFFONT_NONSYMBOLIC; | |
736 } | |
737 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding"); | 775 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding"); |
738 for (int charcode = 128; charcode <= 255; charcode++) { | 776 for (int charcode = 128; charcode <= 255; charcode++) { |
739 int glyph_index = pEncoding->GlyphFromCharCode(charcode); | 777 int glyph_index = pEncoding->GlyphFromCharCode(charcode); |
740 int char_width = pFont->GetGlyphWidth(glyph_index); | 778 int char_width = pFont->GetGlyphWidth(glyph_index); |
741 pWidths->AddInteger(char_width); | 779 pWidths->AddInteger(char_width); |
742 } | 780 } |
743 } else { | 781 } else { |
744 flags |= PDFFONT_NONSYMBOLIC; | 782 size_t i = CalculateEncodingDict(charset, pBaseDict); |
745 size_t i; | |
746 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { | |
747 if (g_FX_CharsetUnicodes[i].m_Charset == charset) | |
748 break; | |
749 } | |
750 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) { | 783 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) { |
751 CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary; | |
752 pEncodingDict->SetAtName("BaseEncoding", "WinAnsiEncoding"); | |
753 CPDF_Array* pArray = new CPDF_Array; | |
754 pArray->AddInteger(128); | |
755 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; | 784 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; |
756 for (int j = 0; j < 128; j++) { | 785 for (int j = 0; j < 128; j++) { |
757 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); | |
758 pArray->AddName(name.IsEmpty() ? ".notdef" : name); | |
759 int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]); | 786 int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]); |
760 int char_width = pFont->GetGlyphWidth(glyph_index); | 787 int char_width = pFont->GetGlyphWidth(glyph_index); |
761 pWidths->AddInteger(char_width); | 788 pWidths->AddInteger(char_width); |
762 } | 789 } |
763 pEncodingDict->SetAt("Differences", pArray); | |
764 AddIndirectObject(pEncodingDict); | |
765 pBaseDict->SetAtReference("Encoding", this, pEncodingDict); | |
766 } | 790 } |
767 } | 791 } |
768 if (pFont->IsBold() && pFont->IsItalic()) | 792 ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont, |
769 basefont += ",BoldItalic"; | 793 pWidths); |
770 else if (pFont->IsBold()) | |
771 basefont += ",Bold"; | |
772 else if (pFont->IsItalic()) | |
773 basefont += ",Italic"; | |
774 | |
775 pBaseDict->SetAtName("Subtype", "TrueType"); | |
776 pBaseDict->SetAtName("BaseFont", basefont); | |
777 pBaseDict->SetAtNumber("FirstChar", 32); | |
778 pBaseDict->SetAtNumber("LastChar", 255); | |
779 pBaseDict->SetAt("Widths", pWidths); | |
780 } else { | 794 } else { |
781 flags |= PDFFONT_NONSYMBOLIC; | 795 flags |= PDFFONT_NONSYMBOLIC; |
782 pFontDict = new CPDF_Dictionary; | 796 pFontDict = new CPDF_Dictionary; |
783 CFX_ByteString cmap; | 797 CFX_ByteString cmap; |
784 CFX_ByteString ordering; | 798 CFX_ByteString ordering; |
785 int supplement = 0; | 799 int supplement = 0; |
786 CPDF_Array* pWidthArray = new CPDF_Array; | 800 CPDF_Array* pWidthArray = new CPDF_Array; |
787 switch (charset) { | 801 switch (charset) { |
788 case FXFONT_CHINESEBIG5_CHARSET: | 802 case FXFONT_CHINESEBIG5_CHARSET: |
789 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; | 803 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 if (pFont->GetSubstFont()) { | 875 if (pFont->GetSubstFont()) { |
862 nStemV = pFont->GetSubstFont()->m_Weight / 5; | 876 nStemV = pFont->GetSubstFont()->m_Weight / 5; |
863 } else { | 877 } else { |
864 static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'}; | 878 static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'}; |
865 const size_t count = FX_ArraySize(stem_chars); | 879 const size_t count = FX_ArraySize(stem_chars); |
866 uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]); | 880 uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]); |
867 nStemV = pFont->GetGlyphWidth(glyph); | 881 nStemV = pFont->GetGlyphWidth(glyph); |
868 for (size_t i = 1; i < count; i++) { | 882 for (size_t i = 1; i < count; i++) { |
869 glyph = pEncoding->GlyphFromCharCode(stem_chars[i]); | 883 glyph = pEncoding->GlyphFromCharCode(stem_chars[i]); |
870 int width = pFont->GetGlyphWidth(glyph); | 884 int width = pFont->GetGlyphWidth(glyph); |
871 if (width > 0 && width < nStemV) { | 885 if (width > 0 && width < nStemV) |
872 nStemV = width; | 886 nStemV = width; |
873 } | |
874 } | 887 } |
875 } | 888 } |
876 pFontDesc->SetAtInteger("StemV", nStemV); | 889 pFontDesc->SetAtInteger("StemV", nStemV); |
877 AddIndirectObject(pFontDesc); | 890 AddIndirectObject(pFontDesc); |
878 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); | 891 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); |
879 return LoadFont(pBaseDict); | 892 return LoadFont(pBaseDict); |
880 } | 893 } |
881 | 894 |
882 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 895 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
883 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont, | 896 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont, |
(...skipping 19 matching lines...) Expand all Loading... |
903 hFont = SelectObject(hDC, hFont); | 916 hFont = SelectObject(hDC, hFont); |
904 int tm_size = GetOutlineTextMetrics(hDC, 0, nullptr); | 917 int tm_size = GetOutlineTextMetrics(hDC, 0, nullptr); |
905 if (tm_size == 0) { | 918 if (tm_size == 0) { |
906 hFont = SelectObject(hDC, hFont); | 919 hFont = SelectObject(hDC, hFont); |
907 DeleteObject(hFont); | 920 DeleteObject(hFont); |
908 DeleteDC(hDC); | 921 DeleteDC(hDC); |
909 return nullptr; | 922 return nullptr; |
910 } | 923 } |
911 | 924 |
912 LPBYTE tm_buf = FX_Alloc(BYTE, tm_size); | 925 LPBYTE tm_buf = FX_Alloc(BYTE, tm_size); |
913 OUTLINETEXTMETRIC* ptm = (OUTLINETEXTMETRIC*)tm_buf; | 926 OUTLINETEXTMETRIC* ptm = reinterpret_cast<OUTLINETEXTMETRIC*>(tm_buf); |
914 GetOutlineTextMetrics(hDC, tm_size, ptm); | 927 GetOutlineTextMetrics(hDC, tm_size, ptm); |
915 int flags = 0, italicangle, ascend, descend, capheight, bbox[4]; | 928 int flags = CalculateFlags(false, pLogFont->lfItalic != 0, |
916 if (pLogFont->lfItalic) | 929 (pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH, |
917 flags |= PDFFONT_ITALIC; | 930 (pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN, |
918 if ((pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH) | 931 (pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT, |
919 flags |= PDFFONT_FIXEDPITCH; | 932 pLogFont->lfCharSet == SYMBOL_CHARSET); |
920 if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN) | |
921 flags |= PDFFONT_SERIF; | |
922 if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT) | |
923 flags |= PDFFONT_SCRIPT; | |
924 | 933 |
925 bool bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET || | 934 bool bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET || |
926 pLogFont->lfCharSet == GB2312_CHARSET || | 935 pLogFont->lfCharSet == GB2312_CHARSET || |
927 pLogFont->lfCharSet == HANGEUL_CHARSET || | 936 pLogFont->lfCharSet == HANGEUL_CHARSET || |
928 pLogFont->lfCharSet == SHIFTJIS_CHARSET; | 937 pLogFont->lfCharSet == SHIFTJIS_CHARSET; |
929 CFX_ByteString basefont; | 938 CFX_ByteString basefont; |
930 if (bTranslateName && bCJK) | 939 if (bTranslateName && bCJK) |
931 basefont = FPDF_GetPSNameFromTT(hDC); | 940 basefont = FPDF_GetPSNameFromTT(hDC); |
932 | 941 |
933 if (basefont.IsEmpty()) | 942 if (basefont.IsEmpty()) |
934 basefont = pLogFont->lfFaceName; | 943 basefont = pLogFont->lfFaceName; |
935 | 944 |
936 italicangle = ptm->otmItalicAngle / 10; | 945 int italicangle = ptm->otmItalicAngle / 10; |
937 ascend = ptm->otmrcFontBox.top; | 946 int ascend = ptm->otmrcFontBox.top; |
938 descend = ptm->otmrcFontBox.bottom; | 947 int descend = ptm->otmrcFontBox.bottom; |
939 capheight = ptm->otmsCapEmHeight; | 948 int capheight = ptm->otmsCapEmHeight; |
940 bbox[0] = ptm->otmrcFontBox.left; | 949 int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom, |
941 bbox[1] = ptm->otmrcFontBox.bottom; | 950 ptm->otmrcFontBox.right, ptm->otmrcFontBox.top}; |
942 bbox[2] = ptm->otmrcFontBox.right; | |
943 bbox[3] = ptm->otmrcFontBox.top; | |
944 FX_Free(tm_buf); | 951 FX_Free(tm_buf); |
945 basefont.Replace(" ", ""); | 952 basefont.Replace(" ", ""); |
946 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; | 953 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; |
947 pBaseDict->SetAtName("Type", "Font"); | 954 pBaseDict->SetAtName("Type", "Font"); |
948 CPDF_Dictionary* pFontDict = pBaseDict; | 955 CPDF_Dictionary* pFontDict = pBaseDict; |
949 if (!bCJK) { | 956 if (!bCJK) { |
950 if (pLogFont->lfCharSet == ANSI_CHARSET || | 957 if (pLogFont->lfCharSet == ANSI_CHARSET || |
951 pLogFont->lfCharSet == DEFAULT_CHARSET || | 958 pLogFont->lfCharSet == DEFAULT_CHARSET || |
952 pLogFont->lfCharSet == SYMBOL_CHARSET) { | 959 pLogFont->lfCharSet == SYMBOL_CHARSET) { |
953 if (pLogFont->lfCharSet == SYMBOL_CHARSET) | |
954 flags |= PDFFONT_SYMBOLIC; | |
955 else | |
956 flags |= PDFFONT_NONSYMBOLIC; | |
957 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding"); | 960 pBaseDict->SetAtName("Encoding", "WinAnsiEncoding"); |
958 } else { | 961 } else { |
959 flags |= PDFFONT_NONSYMBOLIC; | 962 CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict); |
960 size_t i; | |
961 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { | |
962 if (g_FX_CharsetUnicodes[i].m_Charset == pLogFont->lfCharSet) | |
963 break; | |
964 } | |
965 if (i < FX_ArraySize(g_FX_CharsetUnicodes)) { | |
966 CPDF_Dictionary* pEncoding = new CPDF_Dictionary; | |
967 pEncoding->SetAtName("BaseEncoding", "WinAnsiEncoding"); | |
968 CPDF_Array* pArray = new CPDF_Array; | |
969 pArray->AddInteger(128); | |
970 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; | |
971 for (int j = 0; j < 128; j++) { | |
972 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); | |
973 pArray->AddName(name.IsEmpty() ? ".notdef" : name); | |
974 } | |
975 pEncoding->SetAt("Differences", pArray); | |
976 AddIndirectObject(pEncoding); | |
977 pBaseDict->SetAtReference("Encoding", this, pEncoding); | |
978 } | |
979 } | 963 } |
980 if (pLogFont->lfWeight > FW_MEDIUM && pLogFont->lfItalic) | |
981 basefont += ",BoldItalic"; | |
982 else if (pLogFont->lfWeight > FW_MEDIUM) | |
983 basefont += ",Bold"; | |
984 else if (pLogFont->lfItalic) | |
985 basefont += ",Italic"; | |
986 | |
987 pBaseDict->SetAtName("Subtype", "TrueType"); | |
988 pBaseDict->SetAtName("BaseFont", basefont); | |
989 pBaseDict->SetAtNumber("FirstChar", 32); | |
990 pBaseDict->SetAtNumber("LastChar", 255); | |
991 int char_widths[224]; | 964 int char_widths[224]; |
992 GetCharWidth(hDC, 32, 255, char_widths); | 965 GetCharWidth(hDC, 32, 255, char_widths); |
993 CPDF_Array* pWidths = new CPDF_Array; | 966 CPDF_Array* pWidths = new CPDF_Array; |
994 for (size_t i = 0; i < 224; i++) | 967 for (size_t i = 0; i < 224; i++) |
995 pWidths->AddInteger(char_widths[i]); | 968 pWidths->AddInteger(char_widths[i]); |
996 | 969 ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM, |
997 pBaseDict->SetAt("Widths", pWidths); | 970 pLogFont->lfItalic != 0, basefont, pWidths); |
998 } else { | 971 } else { |
999 flags |= PDFFONT_NONSYMBOLIC; | |
1000 pFontDict = new CPDF_Dictionary; | 972 pFontDict = new CPDF_Dictionary; |
1001 CFX_ByteString cmap; | 973 CFX_ByteString cmap; |
1002 CFX_ByteString ordering; | 974 CFX_ByteString ordering; |
1003 int supplement = 0; | 975 int supplement = 0; |
1004 CPDF_Array* pWidthArray = new CPDF_Array; | 976 CPDF_Array* pWidthArray = new CPDF_Array; |
1005 switch (pLogFont->lfCharSet) { | 977 switch (pLogFont->lfCharSet) { |
1006 case CHINESEBIG5_CHARSET: | 978 case CHINESEBIG5_CHARSET: |
1007 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; | 979 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; |
1008 ordering = "CNS1"; | 980 ordering = "CNS1"; |
1009 supplement = 4; | 981 supplement = 4; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 pBaseDict->SetAt("DescendantFonts", pArray); | 1027 pBaseDict->SetAt("DescendantFonts", pArray); |
1056 AddIndirectObject(pFontDict); | 1028 AddIndirectObject(pFontDict); |
1057 pArray->AddReference(this, pFontDict); | 1029 pArray->AddReference(this, pFontDict); |
1058 } | 1030 } |
1059 AddIndirectObject(pBaseDict); | 1031 AddIndirectObject(pBaseDict); |
1060 CPDF_Dictionary* pFontDesc = new CPDF_Dictionary; | 1032 CPDF_Dictionary* pFontDesc = new CPDF_Dictionary; |
1061 pFontDesc->SetAtName("Type", "FontDescriptor"); | 1033 pFontDesc->SetAtName("Type", "FontDescriptor"); |
1062 pFontDesc->SetAtName("FontName", basefont); | 1034 pFontDesc->SetAtName("FontName", basefont); |
1063 pFontDesc->SetAtInteger("Flags", flags); | 1035 pFontDesc->SetAtInteger("Flags", flags); |
1064 CPDF_Array* pBBox = new CPDF_Array; | 1036 CPDF_Array* pBBox = new CPDF_Array; |
1065 for (int i = 0; i < 4; i++) { | 1037 for (int i = 0; i < 4; i++) |
1066 pBBox->AddInteger(bbox[i]); | 1038 pBBox->AddInteger(bbox[i]); |
1067 } | |
1068 pFontDesc->SetAt("FontBBox", pBBox); | 1039 pFontDesc->SetAt("FontBBox", pBBox); |
1069 pFontDesc->SetAtInteger("ItalicAngle", italicangle); | 1040 pFontDesc->SetAtInteger("ItalicAngle", italicangle); |
1070 pFontDesc->SetAtInteger("Ascent", ascend); | 1041 pFontDesc->SetAtInteger("Ascent", ascend); |
1071 pFontDesc->SetAtInteger("Descent", descend); | 1042 pFontDesc->SetAtInteger("Descent", descend); |
1072 pFontDesc->SetAtInteger("CapHeight", capheight); | 1043 pFontDesc->SetAtInteger("CapHeight", capheight); |
1073 pFontDesc->SetAtInteger("StemV", pLogFont->lfWeight / 5); | 1044 pFontDesc->SetAtInteger("StemV", pLogFont->lfWeight / 5); |
1074 AddIndirectObject(pFontDesc); | 1045 AddIndirectObject(pFontDesc); |
1075 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); | 1046 pFontDict->SetAtReference("FontDescriptor", this, pFontDesc); |
1076 hFont = SelectObject(hDC, hFont); | 1047 hFont = SelectObject(hDC, hFont); |
1077 DeleteObject(hFont); | 1048 DeleteObject(hFont); |
1078 DeleteDC(hDC); | 1049 DeleteDC(hDC); |
1079 return LoadFont(pBaseDict); | 1050 return LoadFont(pBaseDict); |
1080 } | 1051 } |
1081 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 1052 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
OLD | NEW |