Index: core/fpdfapi/fpdf_parser/cpdf_document.cpp |
diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp |
index 8910fa12055f4bf1639d4d6d0bf6fa07f0ae4fd0..b3fdc7c07f75a37afa12e42eb7c20f648d9d8b59 100644 |
--- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp |
+++ b/core/fpdfapi/fpdf_parser/cpdf_document.cpp |
@@ -200,9 +200,8 @@ void InsertWidthArray(HDC hDC, int start, int end, CPDF_Array* pWidthArray) { |
} else { |
CPDF_Array* pWidthArray1 = new CPDF_Array; |
pWidthArray->Add(pWidthArray1); |
- for (i = 0; i < size; i++) { |
+ for (i = 0; i < size; i++) |
pWidthArray1->AddInteger(widths[i]); |
- } |
} |
FX_Free(widths); |
} |
@@ -301,10 +300,7 @@ int InsertNewPage(CPDF_Document* pDoc, |
CPDF_Dictionary* pPageDict, |
CFX_ArrayTemplate<uint32_t>& pageList) { |
CPDF_Dictionary* pRoot = pDoc->GetRoot(); |
- if (!pRoot) |
- return -1; |
- |
- CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); |
+ CPDF_Dictionary* pPages = pRoot ? pRoot->GetDictBy("Pages") : nullptr; |
if (!pPages) |
return -1; |
@@ -333,19 +329,16 @@ int InsertNewPage(CPDF_Document* pDoc, |
int CountPages(CPDF_Dictionary* pPages, |
std::set<CPDF_Dictionary*>* visited_pages) { |
int count = pPages->GetIntegerBy("Count"); |
- if (count > 0 && count < FPDF_PAGE_MAX_NUM) { |
+ if (count > 0 && count < FPDF_PAGE_MAX_NUM) |
return count; |
- } |
CPDF_Array* pKidList = pPages->GetArrayBy("Kids"); |
- if (!pKidList) { |
+ if (!pKidList) |
return 0; |
- } |
count = 0; |
for (size_t i = 0; i < pKidList->GetCount(); i++) { |
CPDF_Dictionary* pKid = pKidList->GetDictAt(i); |
- if (!pKid || pdfium::ContainsKey(*visited_pages, pKid)) { |
+ if (!pKid || pdfium::ContainsKey(*visited_pages, pKid)) |
continue; |
- } |
if (pKid->KeyExist("Kids")) { |
// Use |visited_pages| to help detect circular references of pages. |
pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, |
@@ -360,6 +353,48 @@ int CountPages(CPDF_Dictionary* pPages, |
return count; |
} |
+int CalculateFlags(bool bold, |
+ bool italic, |
+ bool fixedPitch, |
+ bool serif, |
+ bool script, |
+ bool symbolic) { |
+ int flags = 0; |
+ if (bold) |
+ flags |= PDFFONT_FORCEBOLD; |
+ if (italic) |
+ flags |= PDFFONT_ITALIC; |
+ if (fixedPitch) |
+ flags |= PDFFONT_FIXEDPITCH; |
+ if (serif) |
+ flags |= PDFFONT_SERIF; |
+ if (script) |
+ flags |= PDFFONT_SCRIPT; |
+ if (symbolic) |
+ flags |= PDFFONT_SYMBOLIC; |
+ else |
+ flags |= PDFFONT_NONSYMBOLIC; |
+ return flags; |
+} |
+ |
+void ProcessNonbCJK(CPDF_Dictionary* pBaseDict, |
+ bool bold, |
+ bool italic, |
+ CFX_ByteString basefont, |
+ CPDF_Array* pWidths) { |
+ if (bold && italic) |
+ basefont += ",BoldItalic"; |
+ else if (bold) |
+ basefont += ",Bold"; |
+ else if (italic) |
+ basefont += ",Italic"; |
+ pBaseDict->SetAtName("Subtype", "TrueType"); |
+ pBaseDict->SetAtName("BaseFont", basefont); |
+ pBaseDict->SetAtNumber("FirstChar", 32); |
+ pBaseDict->SetAtNumber("LastChar", 255); |
+ pBaseDict->SetAt("Widths", pWidths); |
+} |
+ |
} // namespace |
CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser) |
@@ -446,26 +481,30 @@ CPDF_Dictionary* CPDF_Document::FindPDFPage(CPDF_Dictionary* pPages, |
nPagesToGo--; |
continue; |
} |
- if (pKid == pPages) { |
+ if (pKid == pPages) |
continue; |
- } |
if (!pKid->KeyExist("Kids")) { |
- if (nPagesToGo == 0) { |
+ if (nPagesToGo == 0) |
return pKid; |
- } |
+ |
m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); |
nPagesToGo--; |
} else { |
int nPages = pKid->GetIntegerBy("Count"); |
- if (nPagesToGo < nPages) { |
+ if (nPagesToGo < nPages) |
return FindPDFPage(pKid, iPage, nPagesToGo, level + 1); |
- } |
+ |
nPagesToGo -= nPages; |
} |
} |
return nullptr; |
} |
+CPDF_Dictionary* CPDF_Document::GetPagesDict() const { |
+ CPDF_Dictionary* pRoot = GetRoot(); |
+ return pRoot ? pRoot->GetDictBy("Pages") : nullptr; |
+} |
+ |
CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { |
if (iPage < 0 || iPage >= m_PageList.GetSize()) |
return nullptr; |
@@ -483,11 +522,7 @@ CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { |
return pDict; |
} |
- CPDF_Dictionary* pRoot = GetRoot(); |
- if (!pRoot) |
- return nullptr; |
- |
- CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); |
+ CPDF_Dictionary* pPages = GetPagesDict(); |
if (!pPages) |
return nullptr; |
@@ -566,11 +601,7 @@ int CPDF_Document::GetPageIndex(uint32_t objnum) { |
bSkipped = true; |
} |
} |
- CPDF_Dictionary* pRoot = GetRoot(); |
- if (!pRoot) |
- return -1; |
- |
- CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); |
+ CPDF_Dictionary* pPages = GetPagesDict(); |
if (!pPages) |
return -1; |
@@ -583,11 +614,7 @@ int CPDF_Document::GetPageCount() const { |
} |
int CPDF_Document::RetrievePageCount() const { |
- CPDF_Dictionary* pRoot = GetRoot(); |
- if (!pRoot) |
- return 0; |
- |
- CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); |
+ CPDF_Dictionary* pPages = GetPagesDict(); |
if (!pPages) |
return 0; |
@@ -670,11 +697,7 @@ CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { |
} |
void CPDF_Document::DeletePage(int iPage) { |
- CPDF_Dictionary* pRoot = GetRoot(); |
- if (!pRoot) |
- return; |
- |
- CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages"); |
+ CPDF_Dictionary* pPages = GetPagesDict(); |
if (!pPages) |
return; |
@@ -697,6 +720,30 @@ CPDF_Font* CPDF_Document::AddStandardFont(const FX_CHAR* font, |
return GetPageData()->GetStandardFont(name, pEncoding); |
} |
+size_t CPDF_Document::CalculateEncodingDict(int charset, |
+ CPDF_Dictionary* pBaseDict) { |
+ size_t i; |
+ for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { |
+ if (g_FX_CharsetUnicodes[i].m_Charset == charset) |
+ break; |
+ } |
+ if (i == FX_ArraySize(g_FX_CharsetUnicodes)) |
+ return i; |
+ CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary; |
+ pEncodingDict->SetAtName("BaseEncoding", "WinAnsiEncoding"); |
+ CPDF_Array* pArray = new CPDF_Array; |
+ pArray->AddInteger(128); |
+ const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; |
+ for (int j = 0; j < 128; j++) { |
+ CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); |
+ pArray->AddName(name.IsEmpty() ? ".notdef" : name); |
+ } |
+ pEncodingDict->SetAt("Differences", pArray); |
+ AddIndirectObject(pEncodingDict); |
+ pBaseDict->SetAtReference("Encoding", this, pEncodingDict); |
+ return i; |
+} |
+ |
CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
if (!pFont) |
return nullptr; |
@@ -707,13 +754,9 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
charset == FXFONT_SHIFTJIS_CHARSET; |
CFX_ByteString basefont = pFont->GetFamilyName(); |
basefont.Replace(" ", ""); |
- int flags = 0; |
- if (pFont->IsBold()) |
- flags |= PDFFONT_FORCEBOLD; |
- if (pFont->IsItalic()) |
- flags |= PDFFONT_ITALIC; |
- if (pFont->IsFixedWidth()) |
- flags |= PDFFONT_FIXEDPITCH; |
+ int flags = |
+ CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(), |
+ false, false, charset == FXFONT_SYMBOL_CHARSET); |
CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; |
pBaseDict->SetAtName("Type", "Font"); |
@@ -729,11 +772,6 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
} |
if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_DEFAULT_CHARSET || |
charset == FXFONT_SYMBOL_CHARSET) { |
- if (charset == FXFONT_SYMBOL_CHARSET) { |
- flags |= PDFFONT_SYMBOLIC; |
- } else { |
- flags |= PDFFONT_NONSYMBOLIC; |
- } |
pBaseDict->SetAtName("Encoding", "WinAnsiEncoding"); |
for (int charcode = 128; charcode <= 255; charcode++) { |
int glyph_index = pEncoding->GlyphFromCharCode(charcode); |
@@ -741,42 +779,18 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
pWidths->AddInteger(char_width); |
} |
} else { |
- flags |= PDFFONT_NONSYMBOLIC; |
- size_t i; |
- for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { |
- if (g_FX_CharsetUnicodes[i].m_Charset == charset) |
- break; |
- } |
+ size_t i = CalculateEncodingDict(charset, pBaseDict); |
if (i < FX_ArraySize(g_FX_CharsetUnicodes)) { |
- CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary; |
- pEncodingDict->SetAtName("BaseEncoding", "WinAnsiEncoding"); |
- CPDF_Array* pArray = new CPDF_Array; |
- pArray->AddInteger(128); |
const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; |
for (int j = 0; j < 128; j++) { |
- CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); |
- pArray->AddName(name.IsEmpty() ? ".notdef" : name); |
int glyph_index = pEncoding->GlyphFromCharCode(pUnicodes[j]); |
int char_width = pFont->GetGlyphWidth(glyph_index); |
pWidths->AddInteger(char_width); |
} |
- pEncodingDict->SetAt("Differences", pArray); |
- AddIndirectObject(pEncodingDict); |
- pBaseDict->SetAtReference("Encoding", this, pEncodingDict); |
} |
} |
- if (pFont->IsBold() && pFont->IsItalic()) |
- basefont += ",BoldItalic"; |
- else if (pFont->IsBold()) |
- basefont += ",Bold"; |
- else if (pFont->IsItalic()) |
- basefont += ",Italic"; |
- |
- pBaseDict->SetAtName("Subtype", "TrueType"); |
- pBaseDict->SetAtName("BaseFont", basefont); |
- pBaseDict->SetAtNumber("FirstChar", 32); |
- pBaseDict->SetAtNumber("LastChar", 255); |
- pBaseDict->SetAt("Widths", pWidths); |
+ ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont, |
+ pWidths); |
} else { |
flags |= PDFFONT_NONSYMBOLIC; |
pFontDict = new CPDF_Dictionary; |
@@ -868,9 +882,8 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { |
for (size_t i = 1; i < count; i++) { |
glyph = pEncoding->GlyphFromCharCode(stem_chars[i]); |
int width = pFont->GetGlyphWidth(glyph); |
- if (width > 0 && width < nStemV) { |
+ if (width > 0 && width < nStemV) |
nStemV = width; |
- } |
} |
} |
pFontDesc->SetAtInteger("StemV", nStemV); |
@@ -910,17 +923,13 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, |
} |
LPBYTE tm_buf = FX_Alloc(BYTE, tm_size); |
- OUTLINETEXTMETRIC* ptm = (OUTLINETEXTMETRIC*)tm_buf; |
+ OUTLINETEXTMETRIC* ptm = reinterpret_cast<OUTLINETEXTMETRIC*>(tm_buf); |
GetOutlineTextMetrics(hDC, tm_size, ptm); |
- int flags = 0, italicangle, ascend, descend, capheight, bbox[4]; |
- if (pLogFont->lfItalic) |
- flags |= PDFFONT_ITALIC; |
- if ((pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH) |
- flags |= PDFFONT_FIXEDPITCH; |
- if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN) |
- flags |= PDFFONT_SERIF; |
- if ((pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT) |
- flags |= PDFFONT_SCRIPT; |
+ int flags = CalculateFlags(false, pLogFont->lfItalic != 0, |
+ (pLogFont->lfPitchAndFamily & 3) == FIXED_PITCH, |
+ (pLogFont->lfPitchAndFamily & 0xf8) == FF_ROMAN, |
+ (pLogFont->lfPitchAndFamily & 0xf8) == FF_SCRIPT, |
+ pLogFont->lfCharSet == SYMBOL_CHARSET); |
bool bCJK = pLogFont->lfCharSet == CHINESEBIG5_CHARSET || |
pLogFont->lfCharSet == GB2312_CHARSET || |
@@ -933,14 +942,12 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, |
if (basefont.IsEmpty()) |
basefont = pLogFont->lfFaceName; |
- italicangle = ptm->otmItalicAngle / 10; |
- ascend = ptm->otmrcFontBox.top; |
- descend = ptm->otmrcFontBox.bottom; |
- capheight = ptm->otmsCapEmHeight; |
- bbox[0] = ptm->otmrcFontBox.left; |
- bbox[1] = ptm->otmrcFontBox.bottom; |
- bbox[2] = ptm->otmrcFontBox.right; |
- bbox[3] = ptm->otmrcFontBox.top; |
+ int italicangle = ptm->otmItalicAngle / 10; |
+ int ascend = ptm->otmrcFontBox.top; |
+ int descend = ptm->otmrcFontBox.bottom; |
+ int capheight = ptm->otmsCapEmHeight; |
+ int bbox[4] = {ptm->otmrcFontBox.left, ptm->otmrcFontBox.bottom, |
+ ptm->otmrcFontBox.right, ptm->otmrcFontBox.top}; |
FX_Free(tm_buf); |
basefont.Replace(" ", ""); |
CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; |
@@ -950,53 +957,18 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, |
if (pLogFont->lfCharSet == ANSI_CHARSET || |
pLogFont->lfCharSet == DEFAULT_CHARSET || |
pLogFont->lfCharSet == SYMBOL_CHARSET) { |
- if (pLogFont->lfCharSet == SYMBOL_CHARSET) |
- flags |= PDFFONT_SYMBOLIC; |
- else |
- flags |= PDFFONT_NONSYMBOLIC; |
pBaseDict->SetAtName("Encoding", "WinAnsiEncoding"); |
} else { |
- flags |= PDFFONT_NONSYMBOLIC; |
- size_t i; |
- for (i = 0; i < FX_ArraySize(g_FX_CharsetUnicodes); ++i) { |
- if (g_FX_CharsetUnicodes[i].m_Charset == pLogFont->lfCharSet) |
- break; |
- } |
- if (i < FX_ArraySize(g_FX_CharsetUnicodes)) { |
- CPDF_Dictionary* pEncoding = new CPDF_Dictionary; |
- pEncoding->SetAtName("BaseEncoding", "WinAnsiEncoding"); |
- CPDF_Array* pArray = new CPDF_Array; |
- pArray->AddInteger(128); |
- const uint16_t* pUnicodes = g_FX_CharsetUnicodes[i].m_pUnicodes; |
- for (int j = 0; j < 128; j++) { |
- CFX_ByteString name = PDF_AdobeNameFromUnicode(pUnicodes[j]); |
- pArray->AddName(name.IsEmpty() ? ".notdef" : name); |
- } |
- pEncoding->SetAt("Differences", pArray); |
- AddIndirectObject(pEncoding); |
- pBaseDict->SetAtReference("Encoding", this, pEncoding); |
- } |
+ CalculateEncodingDict(pLogFont->lfCharSet, pBaseDict); |
} |
- if (pLogFont->lfWeight > FW_MEDIUM && pLogFont->lfItalic) |
- basefont += ",BoldItalic"; |
- else if (pLogFont->lfWeight > FW_MEDIUM) |
- basefont += ",Bold"; |
- else if (pLogFont->lfItalic) |
- basefont += ",Italic"; |
- |
- pBaseDict->SetAtName("Subtype", "TrueType"); |
- pBaseDict->SetAtName("BaseFont", basefont); |
- pBaseDict->SetAtNumber("FirstChar", 32); |
- pBaseDict->SetAtNumber("LastChar", 255); |
int char_widths[224]; |
GetCharWidth(hDC, 32, 255, char_widths); |
CPDF_Array* pWidths = new CPDF_Array; |
for (size_t i = 0; i < 224; i++) |
pWidths->AddInteger(char_widths[i]); |
- |
- pBaseDict->SetAt("Widths", pWidths); |
+ ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM, |
+ pLogFont->lfItalic != 0, basefont, pWidths); |
} else { |
- flags |= PDFFONT_NONSYMBOLIC; |
pFontDict = new CPDF_Dictionary; |
CFX_ByteString cmap; |
CFX_ByteString ordering; |
@@ -1062,9 +1034,8 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, |
pFontDesc->SetAtName("FontName", basefont); |
pFontDesc->SetAtInteger("Flags", flags); |
CPDF_Array* pBBox = new CPDF_Array; |
- for (int i = 0; i < 4; i++) { |
+ for (int i = 0; i < 4; i++) |
pBBox->AddInteger(bbox[i]); |
- } |
pFontDesc->SetAt("FontBBox", pBBox); |
pFontDesc->SetAtInteger("ItalicAngle", italicangle); |
pFontDesc->SetAtInteger("Ascent", ascend); |