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/parser/cpdf_document.h" | 7 #include "core/fpdfapi/parser/cpdf_document.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <set> | 10 #include <set> |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 CPDF_Array* pKidList = pPages->GetArrayFor("Kids"); | 249 CPDF_Array* pKidList = pPages->GetArrayFor("Kids"); |
250 if (!pKidList) | 250 if (!pKidList) |
251 return -1; | 251 return -1; |
252 | 252 |
253 for (size_t i = 0; i < pKidList->GetCount(); i++) { | 253 for (size_t i = 0; i < pKidList->GetCount(); i++) { |
254 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); | 254 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); |
255 if (pKid->GetStringFor("Type") == "Page") { | 255 if (pKid->GetStringFor("Type") == "Page") { |
256 if (nPagesToGo == 0) { | 256 if (nPagesToGo == 0) { |
257 if (bInsert) { | 257 if (bInsert) { |
258 pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum())); | 258 pKidList->InsertAt(i, new CPDF_Reference(pDoc, pPage->GetObjNum())); |
259 pPage->SetReferenceFor("Parent", pDoc, pPages); | 259 pPage->SetReferenceFor("Parent", pDoc, pPages->GetObjNum()); |
260 } else { | 260 } else { |
261 pKidList->RemoveAt(i); | 261 pKidList->RemoveAt(i); |
262 } | 262 } |
263 pPages->SetIntegerFor( | 263 pPages->SetIntegerFor( |
264 "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1)); | 264 "Count", pPages->GetIntegerFor("Count") + (bInsert ? 1 : -1)); |
265 return 1; | 265 return 1; |
266 } | 266 } |
267 nPagesToGo--; | 267 nPagesToGo--; |
268 } else { | 268 } else { |
269 int nPages = pKid->GetIntegerFor("Count"); | 269 int nPages = pKid->GetIntegerFor("Count"); |
(...skipping 30 matching lines...) Expand all Loading... |
300 return -1; | 300 return -1; |
301 | 301 |
302 if (iPage == nPages) { | 302 if (iPage == nPages) { |
303 CPDF_Array* pPagesList = pPages->GetArrayFor("Kids"); | 303 CPDF_Array* pPagesList = pPages->GetArrayFor("Kids"); |
304 if (!pPagesList) { | 304 if (!pPagesList) { |
305 pPagesList = new CPDF_Array; | 305 pPagesList = new CPDF_Array; |
306 pPages->SetFor("Kids", pPagesList); | 306 pPages->SetFor("Kids", pPagesList); |
307 } | 307 } |
308 pPagesList->Add(new CPDF_Reference(pDoc, pPageDict->GetObjNum())); | 308 pPagesList->Add(new CPDF_Reference(pDoc, pPageDict->GetObjNum())); |
309 pPages->SetIntegerFor("Count", nPages + 1); | 309 pPages->SetIntegerFor("Count", nPages + 1); |
310 pPageDict->SetReferenceFor("Parent", pDoc, pPages); | 310 pPageDict->SetReferenceFor("Parent", pDoc, pPages->GetObjNum()); |
311 } else { | 311 } else { |
312 std::set<CPDF_Dictionary*> stack = {pPages}; | 312 std::set<CPDF_Dictionary*> stack = {pPages}; |
313 if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0) | 313 if (InsertDeletePDFPage(pDoc, pPages, iPage, pPageDict, TRUE, &stack) < 0) |
314 return -1; | 314 return -1; |
315 } | 315 } |
316 pageList.InsertAt(iPage, pPageDict->GetObjNum()); | 316 pageList.InsertAt(iPage, pPageDict->GetObjNum()); |
317 return iPage; | 317 return iPage; |
318 } | 318 } |
319 | 319 |
320 int CountPages(CPDF_Dictionary* pPages, | 320 int CountPages(CPDF_Dictionary* pPages, |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) { | 686 CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) { |
687 if (!pObj) | 687 if (!pObj) |
688 return nullptr; | 688 return nullptr; |
689 | 689 |
690 ASSERT(pObj->GetObjNum()); | 690 ASSERT(pObj->GetObjNum()); |
691 return m_pDocPage->GetImage(pObj); | 691 return m_pDocPage->GetImage(pObj); |
692 } | 692 } |
693 | 693 |
694 void CPDF_Document::CreateNewDoc() { | 694 void CPDF_Document::CreateNewDoc() { |
695 ASSERT(!m_pRootDict && !m_pInfoDict); | 695 ASSERT(!m_pRootDict && !m_pInfoDict); |
696 m_pRootDict = AddIndirectDictionary(m_pByteStringPool); | 696 m_pRootDict = new CPDF_Dictionary(m_pByteStringPool); |
697 m_pRootDict->SetNameFor("Type", "Catalog"); | 697 m_pRootDict->SetNameFor("Type", "Catalog"); |
| 698 AddIndirectObject(m_pRootDict); |
698 | 699 |
699 CPDF_Dictionary* pPages = AddIndirectDictionary(m_pByteStringPool); | 700 CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool); |
700 pPages->SetNameFor("Type", "Pages"); | 701 pPages->SetNameFor("Type", "Pages"); |
701 pPages->SetNumberFor("Count", 0); | 702 pPages->SetNumberFor("Count", 0); |
702 pPages->SetFor("Kids", new CPDF_Array); | 703 pPages->SetFor("Kids", new CPDF_Array); |
703 | 704 m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages)); |
704 m_pRootDict->SetReferenceFor("Pages", this, pPages); | 705 m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool); |
705 m_pInfoDict = AddIndirectDictionary(m_pByteStringPool); | 706 AddIndirectObject(m_pInfoDict); |
706 } | 707 } |
707 | 708 |
708 CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { | 709 CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { |
709 CPDF_Dictionary* pDict = AddIndirectDictionary(m_pByteStringPool); | 710 CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pByteStringPool); |
710 pDict->SetNameFor("Type", "Page"); | 711 pDict->SetNameFor("Type", "Page"); |
| 712 uint32_t dwObjNum = AddIndirectObject(pDict); |
711 if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) { | 713 if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) { |
712 DeleteIndirectObject(pDict->GetObjNum()); | 714 ReleaseIndirectObject(dwObjNum); |
713 return nullptr; | 715 return nullptr; |
714 } | 716 } |
715 return pDict; | 717 return pDict; |
716 } | 718 } |
717 | 719 |
718 void CPDF_Document::DeletePage(int iPage) { | 720 void CPDF_Document::DeletePage(int iPage) { |
719 CPDF_Dictionary* pPages = GetPagesDict(); | 721 CPDF_Dictionary* pPages = GetPagesDict(); |
720 if (!pPages) | 722 if (!pPages) |
721 return; | 723 return; |
722 | 724 |
(...skipping 18 matching lines...) Expand all Loading... |
741 | 743 |
742 size_t CPDF_Document::CalculateEncodingDict(int charset, | 744 size_t CPDF_Document::CalculateEncodingDict(int charset, |
743 CPDF_Dictionary* pBaseDict) { | 745 CPDF_Dictionary* pBaseDict) { |
744 size_t i; | 746 size_t i; |
745 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { | 747 for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { |
746 if (g_FX_CharsetUnicodes[i].m_Charset == charset) | 748 if (g_FX_CharsetUnicodes[i].m_Charset == charset) |
747 break; | 749 break; |
748 } | 750 } |
749 if (i == FX_ArraySize(g_FX_CharsetUnicodes)) | 751 if (i == FX_ArraySize(g_FX_CharsetUnicodes)) |
750 return i; | 752 return i; |
751 | 753 CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool); |
752 CPDF_Dictionary* pEncodingDict = AddIndirectDictionary(m_pByteStringPool); | |
753 pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); | 754 pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); |
754 CPDF_Array* pArray = new CPDF_Array; | 755 CPDF_Array* pArray = new CPDF_Array; |
755 pArray->AddInteger(128); | 756 pArray->AddInteger(128); |
756 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; | 757 const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; |
757 for (int j = 0; j < 128; j++) { | 758 for (int j = 0; j < 128; j++) { |
758 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); | 759 CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); |
759 pArray->AddName(name.IsEmpty() ? ".notdef" : name); | 760 pArray->AddName(name.IsEmpty() ? ".notdef" : name); |
760 } | 761 } |
761 pEncodingDict->SetFor("Differences", pArray); | 762 pEncodingDict->SetFor("Differences", pArray); |
762 pBaseDict->SetReferenceFor("Encoding", this, pEncodingDict); | 763 pBaseDict->SetReferenceFor("Encoding", this, |
| 764 AddIndirectObject(pEncodingDict)); |
| 765 |
763 return i; | 766 return i; |
764 } | 767 } |
765 | 768 |
766 CPDF_Dictionary* CPDF_Document::ProcessbCJK( | 769 CPDF_Dictionary* CPDF_Document::ProcessbCJK( |
767 CPDF_Dictionary* pBaseDict, | 770 CPDF_Dictionary* pBaseDict, |
768 int charset, | 771 int charset, |
769 FX_BOOL bVert, | 772 FX_BOOL bVert, |
770 CFX_ByteString basefont, | 773 CFX_ByteString basefont, |
771 std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) { | 774 std::function<void(FX_WCHAR, FX_WCHAR, CPDF_Array*)> Insert) { |
772 CPDF_Dictionary* pFontDict = AddIndirectDictionary(m_pByteStringPool); | 775 CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool); |
773 CFX_ByteString cmap; | 776 CFX_ByteString cmap; |
774 CFX_ByteString ordering; | 777 CFX_ByteString ordering; |
775 int supplement = 0; | 778 int supplement = 0; |
776 CPDF_Array* pWidthArray = new CPDF_Array; | 779 CPDF_Array* pWidthArray = new CPDF_Array; |
777 switch (charset) { | 780 switch (charset) { |
778 case FXFONT_CHINESEBIG5_CHARSET: | 781 case FXFONT_CHINESEBIG5_CHARSET: |
779 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; | 782 cmap = bVert ? "ETenms-B5-V" : "ETenms-B5-H"; |
780 ordering = "CNS1"; | 783 ordering = "CNS1"; |
781 supplement = 4; | 784 supplement = 4; |
782 pWidthArray->AddInteger(1); | 785 pWidthArray->AddInteger(1); |
(...skipping 29 matching lines...) Expand all Loading... |
812 Insert(0x7e, 0x7e, pWidthArray); | 815 Insert(0x7e, 0x7e, pWidthArray); |
813 break; | 816 break; |
814 } | 817 } |
815 pBaseDict->SetNameFor("Subtype", "Type0"); | 818 pBaseDict->SetNameFor("Subtype", "Type0"); |
816 pBaseDict->SetNameFor("BaseFont", basefont); | 819 pBaseDict->SetNameFor("BaseFont", basefont); |
817 pBaseDict->SetNameFor("Encoding", cmap); | 820 pBaseDict->SetNameFor("Encoding", cmap); |
818 pFontDict->SetFor("W", pWidthArray); | 821 pFontDict->SetFor("W", pWidthArray); |
819 pFontDict->SetNameFor("Type", "Font"); | 822 pFontDict->SetNameFor("Type", "Font"); |
820 pFontDict->SetNameFor("Subtype", "CIDFontType2"); | 823 pFontDict->SetNameFor("Subtype", "CIDFontType2"); |
821 pFontDict->SetNameFor("BaseFont", basefont); | 824 pFontDict->SetNameFor("BaseFont", basefont); |
822 | |
823 CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool); | 825 CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool); |
824 pCIDSysInfo->SetStringFor("Registry", "Adobe"); | 826 pCIDSysInfo->SetStringFor("Registry", "Adobe"); |
825 pCIDSysInfo->SetStringFor("Ordering", ordering); | 827 pCIDSysInfo->SetStringFor("Ordering", ordering); |
826 pCIDSysInfo->SetIntegerFor("Supplement", supplement); | 828 pCIDSysInfo->SetIntegerFor("Supplement", supplement); |
827 pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo); | 829 pFontDict->SetFor("CIDSystemInfo", pCIDSysInfo); |
828 | |
829 CPDF_Array* pArray = new CPDF_Array; | 830 CPDF_Array* pArray = new CPDF_Array; |
830 pBaseDict->SetFor("DescendantFonts", pArray); | 831 pBaseDict->SetFor("DescendantFonts", pArray); |
831 | 832 pArray->AddReference(this, AddIndirectObject(pFontDict)); |
832 pArray->AddReference(this, pFontDict); | |
833 return pFontDict; | 833 return pFontDict; |
834 } | 834 } |
835 | 835 |
836 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { | 836 CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
837 if (!pFont) | 837 if (!pFont) |
838 return nullptr; | 838 return nullptr; |
839 | 839 |
840 bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET || | 840 bool bCJK = charset == FXFONT_CHINESEBIG5_CHARSET || |
841 charset == FXFONT_GB2312_CHARSET || | 841 charset == FXFONT_GB2312_CHARSET || |
842 charset == FXFONT_HANGUL_CHARSET || | 842 charset == FXFONT_HANGUL_CHARSET || |
843 charset == FXFONT_SHIFTJIS_CHARSET; | 843 charset == FXFONT_SHIFTJIS_CHARSET; |
844 CFX_ByteString basefont = pFont->GetFamilyName(); | 844 CFX_ByteString basefont = pFont->GetFamilyName(); |
845 basefont.Replace(" ", ""); | 845 basefont.Replace(" ", ""); |
846 int flags = | 846 int flags = |
847 CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(), | 847 CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(), |
848 false, false, charset == FXFONT_SYMBOL_CHARSET); | 848 false, false, charset == FXFONT_SYMBOL_CHARSET); |
849 | 849 |
850 CPDF_Dictionary* pBaseDict = AddIndirectDictionary(m_pByteStringPool); | 850 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool); |
851 pBaseDict->SetNameFor("Type", "Font"); | 851 pBaseDict->SetNameFor("Type", "Font"); |
852 std::unique_ptr<CFX_UnicodeEncoding> pEncoding( | 852 std::unique_ptr<CFX_UnicodeEncoding> pEncoding( |
853 new CFX_UnicodeEncoding(pFont)); | 853 new CFX_UnicodeEncoding(pFont)); |
854 CPDF_Dictionary* pFontDict = pBaseDict; | 854 CPDF_Dictionary* pFontDict = pBaseDict; |
855 if (!bCJK) { | 855 if (!bCJK) { |
856 CPDF_Array* pWidths = new CPDF_Array; | 856 CPDF_Array* pWidths = new CPDF_Array; |
857 for (int charcode = 32; charcode < 128; charcode++) { | 857 for (int charcode = 32; charcode < 128; charcode++) { |
858 int glyph_index = pEncoding->GlyphFromCharCode(charcode); | 858 int glyph_index = pEncoding->GlyphFromCharCode(charcode); |
859 int char_width = pFont->GetGlyphWidth(glyph_index); | 859 int char_width = pFont->GetGlyphWidth(glyph_index); |
860 pWidths->AddInteger(char_width); | 860 pWidths->AddInteger(char_width); |
(...skipping 20 matching lines...) Expand all Loading... |
881 ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont, | 881 ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont, |
882 pWidths); | 882 pWidths); |
883 } else { | 883 } else { |
884 pFontDict = ProcessbCJK(pBaseDict, charset, bVert, basefont, | 884 pFontDict = ProcessbCJK(pBaseDict, charset, bVert, basefont, |
885 [pFont, &pEncoding](FX_WCHAR start, FX_WCHAR end, | 885 [pFont, &pEncoding](FX_WCHAR start, FX_WCHAR end, |
886 CPDF_Array* widthArr) { | 886 CPDF_Array* widthArr) { |
887 InsertWidthArray1(pFont, pEncoding.get(), start, | 887 InsertWidthArray1(pFont, pEncoding.get(), start, |
888 end, widthArr); | 888 end, widthArr); |
889 }); | 889 }); |
890 } | 890 } |
| 891 AddIndirectObject(pBaseDict); |
891 int italicangle = | 892 int italicangle = |
892 pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0; | 893 pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0; |
893 FX_RECT bbox; | 894 FX_RECT bbox; |
894 pFont->GetBBox(bbox); | 895 pFont->GetBBox(bbox); |
895 CPDF_Array* pBBox = new CPDF_Array; | 896 CPDF_Array* pBBox = new CPDF_Array; |
896 pBBox->AddInteger(bbox.left); | 897 pBBox->AddInteger(bbox.left); |
897 pBBox->AddInteger(bbox.bottom); | 898 pBBox->AddInteger(bbox.bottom); |
898 pBBox->AddInteger(bbox.right); | 899 pBBox->AddInteger(bbox.right); |
899 pBBox->AddInteger(bbox.top); | 900 pBBox->AddInteger(bbox.top); |
900 int32_t nStemV = 0; | 901 int32_t nStemV = 0; |
901 if (pFont->GetSubstFont()) { | 902 if (pFont->GetSubstFont()) { |
902 nStemV = pFont->GetSubstFont()->m_Weight / 5; | 903 nStemV = pFont->GetSubstFont()->m_Weight / 5; |
903 } else { | 904 } else { |
904 static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'}; | 905 static const FX_CHAR stem_chars[] = {'i', 'I', '!', '1'}; |
905 const size_t count = FX_ArraySize(stem_chars); | 906 const size_t count = FX_ArraySize(stem_chars); |
906 uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]); | 907 uint32_t glyph = pEncoding->GlyphFromCharCode(stem_chars[0]); |
907 nStemV = pFont->GetGlyphWidth(glyph); | 908 nStemV = pFont->GetGlyphWidth(glyph); |
908 for (size_t i = 1; i < count; i++) { | 909 for (size_t i = 1; i < count; i++) { |
909 glyph = pEncoding->GlyphFromCharCode(stem_chars[i]); | 910 glyph = pEncoding->GlyphFromCharCode(stem_chars[i]); |
910 int width = pFont->GetGlyphWidth(glyph); | 911 int width = pFont->GetGlyphWidth(glyph); |
911 if (width > 0 && width < nStemV) | 912 if (width > 0 && width < nStemV) |
912 nStemV = width; | 913 nStemV = width; |
913 } | 914 } |
914 } | 915 } |
915 CPDF_Dictionary* pFontDesc = | 916 CPDF_Dictionary* pFontDesc = |
916 CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), | 917 CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), |
917 pFont->GetDescent(), pBBox, nStemV); | 918 pFont->GetDescent(), pBBox, nStemV); |
918 | |
919 // TODO(tsepez): check |pFontDesc| ownership. | |
920 pFontDict->SetReferenceFor("FontDescriptor", this, | 919 pFontDict->SetReferenceFor("FontDescriptor", this, |
921 AddIndirectObject(UniqueDictionary(pFontDesc))); | 920 AddIndirectObject(pFontDesc)); |
922 | |
923 return LoadFont(pBaseDict); | 921 return LoadFont(pBaseDict); |
924 } | 922 } |
925 | 923 |
926 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 924 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
927 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont, | 925 CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTW* pLogFont, |
928 FX_BOOL bVert, | 926 FX_BOOL bVert, |
929 FX_BOOL bTranslateName) { | 927 FX_BOOL bTranslateName) { |
930 LOGFONTA lfa; | 928 LOGFONTA lfa; |
931 FXSYS_memcpy(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa); | 929 FXSYS_memcpy(&lfa, pLogFont, (char*)lfa.lfFaceName - (char*)&lfa); |
932 CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName); | 930 CFX_ByteString face = CFX_ByteString::FromUnicode(pLogFont->lfFaceName); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 basefont = pLogFont->lfFaceName; | 972 basefont = pLogFont->lfFaceName; |
975 | 973 |
976 int italicangle = ptm->otmItalicAngle / 10; | 974 int italicangle = ptm->otmItalicAngle / 10; |
977 int ascend = ptm->otmrcFontBox.top; | 975 int ascend = ptm->otmrcFontBox.top; |
978 int descend = ptm->otmrcFontBox.bottom; | 976 int descend = ptm->otmrcFontBox.bottom; |
979 int capheight = ptm->otmsCapEmHeight; | 977 int capheight = ptm->otmsCapEmHeight; |
980 int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom, | 978 int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom, |
981 ptm->otmrcFontBox.right, ptm->otmrcFontBox.top}; | 979 ptm->otmrcFontBox.right, ptm->otmrcFontBox.top}; |
982 FX_Free(tm_buf); | 980 FX_Free(tm_buf); |
983 basefont.Replace(" ", ""); | 981 basefont.Replace(" ", ""); |
984 CPDF_Dictionary* pBaseDict = AddIndirectDictionary(m_pByteStringPool); | 982 CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool); |
985 pBaseDict->SetNameFor("Type", "Font"); | 983 pBaseDict->SetNameFor("Type", "Font"); |
986 CPDF_Dictionary* pFontDict = pBaseDict; | 984 CPDF_Dictionary* pFontDict = pBaseDict; |
987 if (!bCJK) { | 985 if (!bCJK) { |
988 if (pLogFont->lfCharSet == FXFONT_ANSI_CHARSET || | 986 if (pLogFont->lfCharSet == FXFONT_ANSI_CHARSET || |
989 pLogFont->lfCharSet == FXFONT_DEFAULT_CHARSET || | 987 pLogFont->lfCharSet == FXFONT_DEFAULT_CHARSET || |
990 pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET) { | 988 pLogFont->lfCharSet == FXFONT_SYMBOL_CHARSET) { |
991 pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding"); | 989 pBaseDict->SetNameFor("Encoding", "WinAnsiEncoding"); |
992 } else { | 990 } else { |
993 CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict); | 991 CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict); |
994 } | 992 } |
995 int char_widths[224]; | 993 int char_widths[224]; |
996 GetCharWidth(hDC, 32, 255, char_widths); | 994 GetCharWidth(hDC, 32, 255, char_widths); |
997 CPDF_Array* pWidths = new CPDF_Array; | 995 CPDF_Array* pWidths = new CPDF_Array; |
998 for (size_t i = 0; i < 224; i++) | 996 for (size_t i = 0; i < 224; i++) |
999 pWidths->AddInteger(char_widths[i]); | 997 pWidths->AddInteger(char_widths[i]); |
1000 ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM, | 998 ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM, |
1001 pLogFont->lfItalic != 0, basefont, pWidths); | 999 pLogFont->lfItalic != 0, basefont, pWidths); |
1002 } else { | 1000 } else { |
1003 pFontDict = | 1001 pFontDict = |
1004 ProcessbCJK(pBaseDict, pLogFont->lfCharSet, bVert, basefont, | 1002 ProcessbCJK(pBaseDict, pLogFont->lfCharSet, bVert, basefont, |
1005 [&hDC](FX_WCHAR start, FX_WCHAR end, CPDF_Array* widthArr) { | 1003 [&hDC](FX_WCHAR start, FX_WCHAR end, CPDF_Array* widthArr) { |
1006 InsertWidthArray(hDC, start, end, widthArr); | 1004 InsertWidthArray(hDC, start, end, widthArr); |
1007 }); | 1005 }); |
1008 } | 1006 } |
| 1007 AddIndirectObject(pBaseDict); |
1009 CPDF_Array* pBBox = new CPDF_Array; | 1008 CPDF_Array* pBBox = new CPDF_Array; |
1010 for (int i = 0; i < 4; i++) | 1009 for (int i = 0; i < 4; i++) |
1011 pBBox->AddInteger(bbox[i]); | 1010 pBBox->AddInteger(bbox[i]); |
1012 CPDF_Dictionary* pFontDesc = | 1011 CPDF_Dictionary* pFontDesc = |
1013 CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, | 1012 CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, |
1014 pBBox, pLogFont->lfWeight / 5); | 1013 pBBox, pLogFont->lfWeight / 5); |
1015 pFontDesc->SetIntegerFor("CapHeight", capheight); | 1014 pFontDesc->SetIntegerFor("CapHeight", capheight); |
1016 | |
1017 // TODO(tsepez): check |pFontDesc| ownership. | |
1018 pFontDict->SetReferenceFor("FontDescriptor", this, | 1015 pFontDict->SetReferenceFor("FontDescriptor", this, |
1019 AddIndirectObject(UniqueObject(pFontDesc))); | 1016 AddIndirectObject(pFontDesc)); |
1020 | |
1021 hFont = SelectObject(hDC, hFont); | 1017 hFont = SelectObject(hDC, hFont); |
1022 DeleteObject(hFont); | 1018 DeleteObject(hFont); |
1023 DeleteDC(hDC); | 1019 DeleteDC(hDC); |
1024 return LoadFont(pBaseDict); | 1020 return LoadFont(pBaseDict); |
1025 } | 1021 } |
1026 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 1022 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
OLD | NEW |