summaryrefslogtreecommitdiff
path: root/core/fpdfapi/fpdf_parser
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/fpdf_parser')
-rw-r--r--core/fpdfapi/fpdf_parser/cpdf_document.cpp245
-rw-r--r--core/fpdfapi/fpdf_parser/include/cpdf_document.h4
2 files changed, 110 insertions, 139 deletions
diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp
index 8910fa1205..b3fdc7c07f 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);
diff --git a/core/fpdfapi/fpdf_parser/include/cpdf_document.h b/core/fpdfapi/fpdf_parser/include/cpdf_document.h
index 2d315e9d5b..494868ef13 100644
--- a/core/fpdfapi/fpdf_parser/include/cpdf_document.h
+++ b/core/fpdfapi/fpdf_parser/include/cpdf_document.h
@@ -60,8 +60,6 @@ class CPDF_Document : public CPDF_IndirectObjectHolder {
CPDF_DocRenderData* GetRenderData() const { return m_pDocRender.get(); }
- FX_BOOL IsFormStream(uint32_t objnum, FX_BOOL& bForm) const;
-
// |pFontDict| must not be null.
CPDF_Font* LoadFont(CPDF_Dictionary* pFontDict);
CPDF_ColorSpace* LoadColorSpace(CPDF_Object* pCSObj,
@@ -128,6 +126,8 @@ class CPDF_Document : public CPDF_IndirectObjectHolder {
private:
void LoadDocInternal();
+ size_t CalculateEncodingDict(int charset, CPDF_Dictionary* pBaseDict);
+ CPDF_Dictionary* GetPagesDict() const;
};
#endif // CORE_FPDFAPI_FPDF_PARSER_INCLUDE_CPDF_DOCUMENT_H_