Chromium Code Reviews| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |