Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_document.cpp

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

Powered by Google App Engine
This is Rietveld 408576698