From 41872fa5ac7448a50f66ad56d7bde8d1aa77db4b Mon Sep 17 00:00:00 2001 From: dsinclair Date: Tue, 4 Oct 2016 11:29:35 -0700 Subject: Move core/fpdfapi/fpdf_page to core/fpdfapi/page BUG=pdfium:603 Review-Url: https://codereview.chromium.org/2386423004 --- core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp | 2 +- core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp | 2 +- core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp | 2 +- core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp | 2 +- core/fpdfapi/cmaps/fpdf_cmaps.cpp | 2 +- core/fpdfapi/cpdf_modulemgr.cpp | 2 +- core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp | 10 +- core/fpdfapi/font/cpdf_cidfont.cpp | 2 +- core/fpdfapi/font/cpdf_font.cpp | 4 +- core/fpdfapi/font/cpdf_type3char.cpp | 8 +- core/fpdfapi/font/cpdf_type3font.cpp | 4 +- core/fpdfapi/font/fpdf_font.cpp | 6 +- core/fpdfapi/font/fpdf_font_cid.cpp | 2 +- core/fpdfapi/fpdf_page/cpdf_allstates.cpp | 175 -- core/fpdfapi/fpdf_page/cpdf_allstates.h | 39 - core/fpdfapi/fpdf_page/cpdf_clippath.cpp | 130 -- core/fpdfapi/fpdf_page/cpdf_clippath.h | 63 - core/fpdfapi/fpdf_page/cpdf_color.cpp | 154 -- core/fpdfapi/fpdf_page/cpdf_color.h | 41 - core/fpdfapi/fpdf_page/cpdf_colorspace.cpp | 1277 --------------- core/fpdfapi/fpdf_page/cpdf_colorspace.h | 121 -- core/fpdfapi/fpdf_page/cpdf_colorstate.cpp | 154 -- core/fpdfapi/fpdf_page/cpdf_colorstate.h | 77 - core/fpdfapi/fpdf_page/cpdf_contentmark.cpp | 125 -- core/fpdfapi/fpdf_page/cpdf_contentmark.h | 64 - core/fpdfapi/fpdf_page/cpdf_contentmarkitem.cpp | 50 - core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h | 46 - core/fpdfapi/fpdf_page/cpdf_countedobject.h | 47 - core/fpdfapi/fpdf_page/cpdf_form.cpp | 61 - core/fpdfapi/fpdf_page/cpdf_form.h | 41 - core/fpdfapi/fpdf_page/cpdf_formobject.cpp | 52 - core/fpdfapi/fpdf_page/cpdf_formobject.h | 37 - core/fpdfapi/fpdf_page/cpdf_generalstate.cpp | 281 ---- core/fpdfapi/fpdf_page/cpdf_generalstate.h | 109 -- core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp | 24 - core/fpdfapi/fpdf_page/cpdf_graphicstates.h | 31 - core/fpdfapi/fpdf_page/cpdf_image.cpp | 411 ----- core/fpdfapi/fpdf_page/cpdf_image.h | 90 -- core/fpdfapi/fpdf_page/cpdf_imageobject.cpp | 84 - core/fpdfapi/fpdf_page/cpdf_imageobject.h | 44 - core/fpdfapi/fpdf_page/cpdf_meshstream.cpp | 217 --- core/fpdfapi/fpdf_page/cpdf_meshstream.h | 76 - core/fpdfapi/fpdf_page/cpdf_page.cpp | 176 -- core/fpdfapi/fpdf_page/cpdf_page.h | 69 - core/fpdfapi/fpdf_page/cpdf_pagemodule.cpp | 35 - core/fpdfapi/fpdf_page/cpdf_pagemodule.h | 33 - core/fpdfapi/fpdf_page/cpdf_pageobject.cpp | 99 -- core/fpdfapi/fpdf_page/cpdf_pageobject.h | 71 - core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp | 77 - core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h | 68 - core/fpdfapi/fpdf_page/cpdf_pageobjectlist.cpp | 16 - core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h | 21 - core/fpdfapi/fpdf_page/cpdf_path.cpp | 73 - core/fpdfapi/fpdf_page/cpdf_path.h | 50 - core/fpdfapi/fpdf_page/cpdf_pathobject.cpp | 66 - core/fpdfapi/fpdf_page/cpdf_pathobject.h | 36 - core/fpdfapi/fpdf_page/cpdf_pattern.cpp | 18 - core/fpdfapi/fpdf_page/cpdf_pattern.h | 45 - core/fpdfapi/fpdf_page/cpdf_psengine.h | 101 -- core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp | 69 - core/fpdfapi/fpdf_page/cpdf_shadingobject.h | 34 - core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp | 97 -- core/fpdfapi/fpdf_page/cpdf_shadingpattern.h | 75 - core/fpdfapi/fpdf_page/cpdf_textobject.cpp | 388 ----- core/fpdfapi/fpdf_page/cpdf_textobject.h | 68 - core/fpdfapi/fpdf_page/cpdf_textstate.cpp | 187 --- core/fpdfapi/fpdf_page/cpdf_textstate.h | 91 -- core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp | 55 - core/fpdfapi/fpdf_page/cpdf_tilingpattern.h | 46 - core/fpdfapi/fpdf_page/fpdf_page_colors.cpp | 235 --- core/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 554 ------- core/fpdfapi/fpdf_page/fpdf_page_func.cpp | 846 ---------- .../fpdf_page/fpdf_page_func_embeddertest.cpp | 20 - core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 1683 -------------------- core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp | 839 ---------- .../fpdf_page/fpdf_page_parser_old_unittest.cpp | 47 - .../fpdf_page/fpdf_page_parser_unittest.cpp | 34 - core/fpdfapi/fpdf_page/pageint.h | 566 ------- core/fpdfapi/fpdf_parser/cpdf_document.cpp | 4 +- .../fpdfapi/fpdf_render/cpdf_progressiverenderer.h | 2 +- core/fpdfapi/fpdf_render/fpdf_render.cpp | 20 +- core/fpdfapi/fpdf_render/fpdf_render_cache.cpp | 4 +- core/fpdfapi/fpdf_render/fpdf_render_image.cpp | 14 +- core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp | 6 +- core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp | 18 +- core/fpdfapi/fpdf_render/fpdf_render_text.cpp | 12 +- core/fpdfapi/fpdf_render/render_int.h | 6 +- core/fpdfapi/page/cpdf_allstates.cpp | 175 ++ core/fpdfapi/page/cpdf_allstates.h | 39 + core/fpdfapi/page/cpdf_clippath.cpp | 130 ++ core/fpdfapi/page/cpdf_clippath.h | 63 + core/fpdfapi/page/cpdf_color.cpp | 154 ++ core/fpdfapi/page/cpdf_color.h | 41 + core/fpdfapi/page/cpdf_colorspace.cpp | 1277 +++++++++++++++ core/fpdfapi/page/cpdf_colorspace.h | 121 ++ core/fpdfapi/page/cpdf_colorstate.cpp | 154 ++ core/fpdfapi/page/cpdf_colorstate.h | 77 + core/fpdfapi/page/cpdf_contentmark.cpp | 125 ++ core/fpdfapi/page/cpdf_contentmark.h | 64 + core/fpdfapi/page/cpdf_contentmarkitem.cpp | 50 + core/fpdfapi/page/cpdf_contentmarkitem.h | 46 + core/fpdfapi/page/cpdf_countedobject.h | 47 + core/fpdfapi/page/cpdf_form.cpp | 61 + core/fpdfapi/page/cpdf_form.h | 41 + core/fpdfapi/page/cpdf_formobject.cpp | 52 + core/fpdfapi/page/cpdf_formobject.h | 37 + core/fpdfapi/page/cpdf_generalstate.cpp | 281 ++++ core/fpdfapi/page/cpdf_generalstate.h | 109 ++ core/fpdfapi/page/cpdf_graphicstates.cpp | 24 + core/fpdfapi/page/cpdf_graphicstates.h | 31 + core/fpdfapi/page/cpdf_image.cpp | 411 +++++ core/fpdfapi/page/cpdf_image.h | 90 ++ core/fpdfapi/page/cpdf_imageobject.cpp | 84 + core/fpdfapi/page/cpdf_imageobject.h | 44 + core/fpdfapi/page/cpdf_meshstream.cpp | 217 +++ core/fpdfapi/page/cpdf_meshstream.h | 76 + core/fpdfapi/page/cpdf_page.cpp | 176 ++ core/fpdfapi/page/cpdf_page.h | 69 + core/fpdfapi/page/cpdf_pagemodule.cpp | 35 + core/fpdfapi/page/cpdf_pagemodule.h | 33 + core/fpdfapi/page/cpdf_pageobject.cpp | 99 ++ core/fpdfapi/page/cpdf_pageobject.h | 71 + core/fpdfapi/page/cpdf_pageobjectholder.cpp | 77 + core/fpdfapi/page/cpdf_pageobjectholder.h | 68 + core/fpdfapi/page/cpdf_pageobjectlist.cpp | 16 + core/fpdfapi/page/cpdf_pageobjectlist.h | 21 + core/fpdfapi/page/cpdf_path.cpp | 73 + core/fpdfapi/page/cpdf_path.h | 50 + core/fpdfapi/page/cpdf_pathobject.cpp | 66 + core/fpdfapi/page/cpdf_pathobject.h | 36 + core/fpdfapi/page/cpdf_pattern.cpp | 18 + core/fpdfapi/page/cpdf_pattern.h | 45 + core/fpdfapi/page/cpdf_psengine.h | 101 ++ core/fpdfapi/page/cpdf_shadingobject.cpp | 69 + core/fpdfapi/page/cpdf_shadingobject.h | 34 + core/fpdfapi/page/cpdf_shadingpattern.cpp | 97 ++ core/fpdfapi/page/cpdf_shadingpattern.h | 75 + core/fpdfapi/page/cpdf_textobject.cpp | 388 +++++ core/fpdfapi/page/cpdf_textobject.h | 68 + core/fpdfapi/page/cpdf_textstate.cpp | 187 +++ core/fpdfapi/page/cpdf_textstate.h | 91 ++ core/fpdfapi/page/cpdf_tilingpattern.cpp | 54 + core/fpdfapi/page/cpdf_tilingpattern.h | 46 + core/fpdfapi/page/fpdf_page_colors.cpp | 234 +++ core/fpdfapi/page/fpdf_page_doc.cpp | 554 +++++++ core/fpdfapi/page/fpdf_page_func.cpp | 845 ++++++++++ core/fpdfapi/page/fpdf_page_func_embeddertest.cpp | 20 + core/fpdfapi/page/fpdf_page_parser.cpp | 1683 ++++++++++++++++++++ core/fpdfapi/page/fpdf_page_parser_old.cpp | 839 ++++++++++ .../fpdfapi/page/fpdf_page_parser_old_unittest.cpp | 47 + core/fpdfapi/page/fpdf_page_parser_unittest.cpp | 34 + core/fpdfapi/page/pageint.h | 566 +++++++ 152 files changed, 11173 insertions(+), 11176 deletions(-) delete mode 100644 core/fpdfapi/fpdf_page/cpdf_allstates.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_allstates.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_clippath.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_clippath.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_color.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_color.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_colorspace.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_colorspace.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_colorstate.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_colorstate.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_contentmark.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_contentmark.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_contentmarkitem.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_countedobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_form.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_form.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_formobject.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_formobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_generalstate.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_generalstate.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_graphicstates.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_image.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_image.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_imageobject.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_imageobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_meshstream.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_meshstream.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_page.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_page.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pagemodule.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pagemodule.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pageobject.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pageobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pageobjectlist.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_path.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_path.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pathobject.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pathobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pattern.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_pattern.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_psengine.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_shadingobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_shadingpattern.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_textobject.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_textobject.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_textstate.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_textstate.h delete mode 100644 core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp delete mode 100644 core/fpdfapi/fpdf_page/cpdf_tilingpattern.h delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_colors.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_doc.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_func.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_parser.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_parser_old_unittest.cpp delete mode 100644 core/fpdfapi/fpdf_page/fpdf_page_parser_unittest.cpp delete mode 100644 core/fpdfapi/fpdf_page/pageint.h create mode 100644 core/fpdfapi/page/cpdf_allstates.cpp create mode 100644 core/fpdfapi/page/cpdf_allstates.h create mode 100644 core/fpdfapi/page/cpdf_clippath.cpp create mode 100644 core/fpdfapi/page/cpdf_clippath.h create mode 100644 core/fpdfapi/page/cpdf_color.cpp create mode 100644 core/fpdfapi/page/cpdf_color.h create mode 100644 core/fpdfapi/page/cpdf_colorspace.cpp create mode 100644 core/fpdfapi/page/cpdf_colorspace.h create mode 100644 core/fpdfapi/page/cpdf_colorstate.cpp create mode 100644 core/fpdfapi/page/cpdf_colorstate.h create mode 100644 core/fpdfapi/page/cpdf_contentmark.cpp create mode 100644 core/fpdfapi/page/cpdf_contentmark.h create mode 100644 core/fpdfapi/page/cpdf_contentmarkitem.cpp create mode 100644 core/fpdfapi/page/cpdf_contentmarkitem.h create mode 100644 core/fpdfapi/page/cpdf_countedobject.h create mode 100644 core/fpdfapi/page/cpdf_form.cpp create mode 100644 core/fpdfapi/page/cpdf_form.h create mode 100644 core/fpdfapi/page/cpdf_formobject.cpp create mode 100644 core/fpdfapi/page/cpdf_formobject.h create mode 100644 core/fpdfapi/page/cpdf_generalstate.cpp create mode 100644 core/fpdfapi/page/cpdf_generalstate.h create mode 100644 core/fpdfapi/page/cpdf_graphicstates.cpp create mode 100644 core/fpdfapi/page/cpdf_graphicstates.h create mode 100644 core/fpdfapi/page/cpdf_image.cpp create mode 100644 core/fpdfapi/page/cpdf_image.h create mode 100644 core/fpdfapi/page/cpdf_imageobject.cpp create mode 100644 core/fpdfapi/page/cpdf_imageobject.h create mode 100644 core/fpdfapi/page/cpdf_meshstream.cpp create mode 100644 core/fpdfapi/page/cpdf_meshstream.h create mode 100644 core/fpdfapi/page/cpdf_page.cpp create mode 100644 core/fpdfapi/page/cpdf_page.h create mode 100644 core/fpdfapi/page/cpdf_pagemodule.cpp create mode 100644 core/fpdfapi/page/cpdf_pagemodule.h create mode 100644 core/fpdfapi/page/cpdf_pageobject.cpp create mode 100644 core/fpdfapi/page/cpdf_pageobject.h create mode 100644 core/fpdfapi/page/cpdf_pageobjectholder.cpp create mode 100644 core/fpdfapi/page/cpdf_pageobjectholder.h create mode 100644 core/fpdfapi/page/cpdf_pageobjectlist.cpp create mode 100644 core/fpdfapi/page/cpdf_pageobjectlist.h create mode 100644 core/fpdfapi/page/cpdf_path.cpp create mode 100644 core/fpdfapi/page/cpdf_path.h create mode 100644 core/fpdfapi/page/cpdf_pathobject.cpp create mode 100644 core/fpdfapi/page/cpdf_pathobject.h create mode 100644 core/fpdfapi/page/cpdf_pattern.cpp create mode 100644 core/fpdfapi/page/cpdf_pattern.h create mode 100644 core/fpdfapi/page/cpdf_psengine.h create mode 100644 core/fpdfapi/page/cpdf_shadingobject.cpp create mode 100644 core/fpdfapi/page/cpdf_shadingobject.h create mode 100644 core/fpdfapi/page/cpdf_shadingpattern.cpp create mode 100644 core/fpdfapi/page/cpdf_shadingpattern.h create mode 100644 core/fpdfapi/page/cpdf_textobject.cpp create mode 100644 core/fpdfapi/page/cpdf_textobject.h create mode 100644 core/fpdfapi/page/cpdf_textstate.cpp create mode 100644 core/fpdfapi/page/cpdf_textstate.h create mode 100644 core/fpdfapi/page/cpdf_tilingpattern.cpp create mode 100644 core/fpdfapi/page/cpdf_tilingpattern.h create mode 100644 core/fpdfapi/page/fpdf_page_colors.cpp create mode 100644 core/fpdfapi/page/fpdf_page_doc.cpp create mode 100644 core/fpdfapi/page/fpdf_page_func.cpp create mode 100644 core/fpdfapi/page/fpdf_page_func_embeddertest.cpp create mode 100644 core/fpdfapi/page/fpdf_page_parser.cpp create mode 100644 core/fpdfapi/page/fpdf_page_parser_old.cpp create mode 100644 core/fpdfapi/page/fpdf_page_parser_old_unittest.cpp create mode 100644 core/fpdfapi/page/fpdf_page_parser_unittest.cpp create mode 100644 core/fpdfapi/page/pageint.h (limited to 'core/fpdfapi') diff --git a/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp b/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp index 8d7fa4b322..a1bbefc1ab 100644 --- a/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp +++ b/core/fpdfapi/cmaps/CNS1/cmaps_cns1.cpp @@ -9,7 +9,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" static const FXCMAP_CMap g_FXCMAP_CNS1_cmaps[] = { diff --git a/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp b/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp index 8c60b3be9f..9d15271e7e 100644 --- a/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp +++ b/core/fpdfapi/cmaps/GB1/cmaps_gb1.cpp @@ -9,7 +9,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" static const FXCMAP_CMap g_FXCMAP_GB1_cmaps[] = { diff --git a/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp b/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp index 5336060dc4..bdf65595ad 100644 --- a/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp +++ b/core/fpdfapi/cmaps/Japan1/cmaps_japan1.cpp @@ -9,7 +9,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" static const FXCMAP_CMap g_FXCMAP_Japan1_cmaps[] = { diff --git a/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp b/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp index cc417bf00c..5e88b3ba17 100644 --- a/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp +++ b/core/fpdfapi/cmaps/Korea1/cmaps_korea1.cpp @@ -9,7 +9,7 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "core/fxcrt/fx_basic.h" static const FXCMAP_CMap g_FXCMAP_Korea1_cmaps[] = { diff --git a/core/fpdfapi/cmaps/fpdf_cmaps.cpp b/core/fpdfapi/cmaps/fpdf_cmaps.cpp index 58a1c082bb..ca01d431f4 100644 --- a/core/fpdfapi/cmaps/fpdf_cmaps.cpp +++ b/core/fpdfapi/cmaps/fpdf_cmaps.cpp @@ -8,7 +8,7 @@ #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" extern "C" { diff --git a/core/fpdfapi/cpdf_modulemgr.cpp b/core/fpdfapi/cpdf_modulemgr.cpp index a8ecc6d154..ff7d95a68e 100644 --- a/core/fpdfapi/cpdf_modulemgr.cpp +++ b/core/fpdfapi/cpdf_modulemgr.cpp @@ -6,7 +6,7 @@ #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "core/fxcodec/fx_codec.h" namespace { diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index e5d9683da6..9cfccb3f7c 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -7,17 +7,17 @@ #include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h" #include "core/fpdfapi/edit/cpdf_creator.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_page.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" #include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/pageint.h" CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& ar, CFX_Matrix& matrix) { ar << matrix.a << " " << matrix.b << " " << matrix.c << " " << matrix.d << " " diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp index e5bbd80a83..9254294d7b 100644 --- a/core/fpdfapi/font/cpdf_cidfont.cpp +++ b/core/fpdfapi/font/cpdf_cidfont.cpp @@ -14,10 +14,10 @@ #include "core/fpdfapi/font/cpdf_fontencoding.h" #include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/font/ttgsubtable.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "third_party/base/numerics/safe_math.h" namespace { diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp index 945681fc9d..f4f95afd1f 100644 --- a/core/fpdfapi/font/cpdf_font.cpp +++ b/core/fpdfapi/font/cpdf_font.cpp @@ -15,13 +15,13 @@ #include "core/fpdfapi/font/cpdf_type1font.h" #include "core/fpdfapi/font/cpdf_type3font.h" #include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_parser/cpdf_name.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxcrt/fx_memory.h" #include "core/fxge/fx_freetype.h" #include "third_party/base/ptr_util.h" diff --git a/core/fpdfapi/font/cpdf_type3char.cpp b/core/fpdfapi/font/cpdf_type3char.cpp index 2114486dec..332287f594 100644 --- a/core/fpdfapi/font/cpdf_type3char.cpp +++ b/core/fpdfapi/font/cpdf_type3char.cpp @@ -6,10 +6,10 @@ #include "core/fpdfapi/font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" #include "core/fxge/fx_dib.h" CPDF_Type3Char::CPDF_Type3Char(CPDF_Form* pForm) diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp index ae301c2e8c..f23d4057cf 100644 --- a/core/fpdfapi/font/cpdf_type3font.cpp +++ b/core/fpdfapi/font/cpdf_type3font.cpp @@ -9,10 +9,10 @@ #include #include "core/fpdfapi/font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxcrt/fx_system.h" #include "third_party/base/stl_util.h" diff --git a/core/fpdfapi/font/fpdf_font.cpp b/core/fpdfapi/font/fpdf_font.cpp index 4763fe5c44..b679b759da 100644 --- a/core/fpdfapi/font/fpdf_font.cpp +++ b/core/fpdfapi/font/fpdf_font.cpp @@ -7,9 +7,6 @@ #include "core/fpdfapi/font/font_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" @@ -17,6 +14,9 @@ #include "core/fpdfapi/fpdf_parser/cpdf_number.h" #include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxcrt/fx_ext.h" #include "core/fxcrt/fx_safe_types.h" #include "core/fxge/fx_freetype.h" diff --git a/core/fpdfapi/font/fpdf_font_cid.cpp b/core/fpdfapi/font/fpdf_font_cid.cpp index 1d8052bc29..95f4701aa2 100644 --- a/core/fpdfapi/font/fpdf_font_cid.cpp +++ b/core/fpdfapi/font/fpdf_font_cid.cpp @@ -9,10 +9,10 @@ #include "core/fpdfapi/cmaps/cmap_int.h" #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/ttgsubtable.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" #include "core/fxcrt/fx_ext.h" #include "core/fxge/fx_freetype.h" diff --git a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp deleted file mode 100644 index 16eb0dfbae..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_allstates.h" - -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fxge/cfx_graphstatedata.h" - -namespace { - -FX_FLOAT ClipFloat(FX_FLOAT f) { - return std::max(0.0f, std::min(1.0f, f)); -} - -} // namespace - -CPDF_AllStates::CPDF_AllStates() { - m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0; - m_TextLeading = 0; - m_TextRise = 0; - m_TextHorzScale = 1.0f; -} - -CPDF_AllStates::~CPDF_AllStates() {} - -void CPDF_AllStates::Copy(const CPDF_AllStates& src) { - CopyStates(src); - m_TextMatrix = src.m_TextMatrix; - m_ParentMatrix = src.m_ParentMatrix; - m_CTM = src.m_CTM; - m_TextX = src.m_TextX; - m_TextY = src.m_TextY; - m_TextLineX = src.m_TextLineX; - m_TextLineY = src.m_TextLineY; - m_TextLeading = src.m_TextLeading; - m_TextRise = src.m_TextRise; - m_TextHorzScale = src.m_TextHorzScale; -} - -void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, - FX_FLOAT phase, - FX_FLOAT scale) { - m_GraphState.SetLineDash(pArray, phase, scale); -} - -void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, - CPDF_StreamContentParser* pParser) { - for (const auto& it : *pGS) { - const CFX_ByteString& key_str = it.first; - CPDF_Object* pElement = it.second; - CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr; - if (!pObject) - continue; - - uint32_t key = key_str.GetID(); - switch (key) { - case FXBSTR_ID('L', 'W', 0, 0): - m_GraphState.SetLineWidth(pObject->GetNumber()); - break; - case FXBSTR_ID('L', 'C', 0, 0): - m_GraphState.SetLineCap( - static_cast(pObject->GetInteger())); - break; - case FXBSTR_ID('L', 'J', 0, 0): - m_GraphState.SetLineJoin( - static_cast(pObject->GetInteger())); - break; - case FXBSTR_ID('M', 'L', 0, 0): - m_GraphState.SetMiterLimit(pObject->GetNumber()); - break; - case FXBSTR_ID('D', 0, 0, 0): { - CPDF_Array* pDash = pObject->AsArray(); - if (!pDash) - break; - - CPDF_Array* pArray = pDash->GetArrayAt(0); - if (!pArray) - break; - - SetLineDash(pArray, pDash->GetNumberAt(1), 1.0f); - break; - } - case FXBSTR_ID('R', 'I', 0, 0): - m_GeneralState.SetRenderIntent(pObject->GetString()); - break; - case FXBSTR_ID('F', 'o', 'n', 't'): { - CPDF_Array* pFont = pObject->AsArray(); - if (!pFont) - break; - - m_TextState.SetFontSize(pFont->GetNumberAt(1)); - m_TextState.SetFont(pParser->FindFont(pFont->GetStringAt(0))); - break; - } - case FXBSTR_ID('T', 'R', 0, 0): - if (pGS->KeyExist("TR2")) { - continue; - } - case FXBSTR_ID('T', 'R', '2', 0): - m_GeneralState.SetTR(pObject && !pObject->IsName() ? pObject : nullptr); - break; - case FXBSTR_ID('B', 'M', 0, 0): { - CPDF_Array* pArray = pObject->AsArray(); - m_GeneralState.SetBlendMode(pArray ? pArray->GetStringAt(0) - : pObject->GetString()); - if (m_GeneralState.GetBlendType() > FXDIB_BLEND_MULTIPLY) - pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(TRUE); - break; - } - case FXBSTR_ID('S', 'M', 'a', 's'): - if (ToDictionary(pObject)) { - m_GeneralState.SetSoftMask(pObject); - m_GeneralState.SetSMaskMatrix(pParser->GetCurStates()->m_CTM); - } else { - m_GeneralState.SetSoftMask(nullptr); - } - break; - case FXBSTR_ID('C', 'A', 0, 0): - m_GeneralState.SetStrokeAlpha(ClipFloat(pObject->GetNumber())); - break; - case FXBSTR_ID('c', 'a', 0, 0): - m_GeneralState.SetFillAlpha(ClipFloat(pObject->GetNumber())); - break; - case FXBSTR_ID('O', 'P', 0, 0): - m_GeneralState.SetStrokeOP(!!pObject->GetInteger()); - if (!pGS->KeyExist("op")) - m_GeneralState.SetFillOP(!!pObject->GetInteger()); - break; - case FXBSTR_ID('o', 'p', 0, 0): - m_GeneralState.SetFillOP(!!pObject->GetInteger()); - break; - case FXBSTR_ID('O', 'P', 'M', 0): - m_GeneralState.SetOPMode(pObject->GetInteger()); - break; - case FXBSTR_ID('B', 'G', 0, 0): - if (pGS->KeyExist("BG2")) { - continue; - } - case FXBSTR_ID('B', 'G', '2', 0): - m_GeneralState.SetBG(pObject); - break; - case FXBSTR_ID('U', 'C', 'R', 0): - if (pGS->KeyExist("UCR2")) { - continue; - } - case FXBSTR_ID('U', 'C', 'R', '2'): - m_GeneralState.SetUCR(pObject); - break; - case FXBSTR_ID('H', 'T', 0, 0): - m_GeneralState.SetHT(pObject); - break; - case FXBSTR_ID('F', 'L', 0, 0): - m_GeneralState.SetFlatness(pObject->GetNumber()); - break; - case FXBSTR_ID('S', 'M', 0, 0): - m_GeneralState.SetSmoothness(pObject->GetNumber()); - break; - case FXBSTR_ID('S', 'A', 0, 0): - m_GeneralState.SetStrokeAdjust(!!pObject->GetInteger()); - break; - case FXBSTR_ID('A', 'I', 'S', 0): - m_GeneralState.SetAlphaSource(!!pObject->GetInteger()); - break; - case FXBSTR_ID('T', 'K', 0, 0): - m_GeneralState.SetTextKnockout(!!pObject->GetInteger()); - break; - } - } - m_GeneralState.SetMatrix(m_CTM); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_allstates.h b/core/fpdfapi/fpdf_page/cpdf_allstates.h deleted file mode 100644 index 44c5d3e57f..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_allstates.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_ALLSTATES_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_ALLSTATES_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Array; -class CPDF_Dictionary; -class CPDF_StreamContentParser; - -class CPDF_AllStates : public CPDF_GraphicStates { - public: - CPDF_AllStates(); - ~CPDF_AllStates() override; - - void Copy(const CPDF_AllStates& src); - void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser); - void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale); - - CFX_Matrix m_TextMatrix; - CFX_Matrix m_CTM; - CFX_Matrix m_ParentMatrix; - FX_FLOAT m_TextX; - FX_FLOAT m_TextY; - FX_FLOAT m_TextLineX; - FX_FLOAT m_TextLineY; - FX_FLOAT m_TextLeading; - FX_FLOAT m_TextRise; - FX_FLOAT m_TextHorzScale; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_ALLSTATES_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_clippath.cpp b/core/fpdfapi/fpdf_page/cpdf_clippath.cpp deleted file mode 100644 index 62f5a37653..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_clippath.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_clippath.h" - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_path.h" -#include "core/fpdfapi/fpdf_page/cpdf_textobject.h" -#include "third_party/base/stl_util.h" - -#define FPDF_CLIPPATH_MAX_TEXTS 1024 - -CPDF_ClipPath::CPDF_ClipPath() {} - -CPDF_ClipPath::CPDF_ClipPath(const CPDF_ClipPath& that) : m_Ref(that.m_Ref) {} - -CPDF_ClipPath::~CPDF_ClipPath() {} - -uint32_t CPDF_ClipPath::GetPathCount() const { - return pdfium::CollectionSize(m_Ref.GetObject()->m_PathAndTypeList); -} - -CPDF_Path CPDF_ClipPath::GetPath(size_t i) const { - return m_Ref.GetObject()->m_PathAndTypeList[i].first; -} - -uint8_t CPDF_ClipPath::GetClipType(size_t i) const { - return m_Ref.GetObject()->m_PathAndTypeList[i].second; -} - -uint32_t CPDF_ClipPath::GetTextCount() const { - return pdfium::CollectionSize(m_Ref.GetObject()->m_TextList); -} - -CPDF_TextObject* CPDF_ClipPath::GetText(size_t i) const { - return m_Ref.GetObject()->m_TextList[i].get(); -} - -CFX_FloatRect CPDF_ClipPath::GetClipBox() const { - CFX_FloatRect rect; - FX_BOOL bStarted = FALSE; - int count = GetPathCount(); - if (count) { - rect = GetPath(0).GetBoundingBox(); - for (int i = 1; i < count; i++) { - CFX_FloatRect path_rect = GetPath(i).GetBoundingBox(); - rect.Intersect(path_rect); - } - bStarted = TRUE; - } - count = GetTextCount(); - if (count) { - CFX_FloatRect layer_rect; - FX_BOOL bLayerStarted = FALSE; - for (int i = 0; i < count; i++) { - CPDF_TextObject* pTextObj = GetText(i); - if (!pTextObj) { - if (!bStarted) { - rect = layer_rect; - bStarted = TRUE; - } else { - rect.Intersect(layer_rect); - } - bLayerStarted = FALSE; - } else { - if (!bLayerStarted) { - layer_rect = CFX_FloatRect(pTextObj->GetBBox(nullptr)); - bLayerStarted = TRUE; - } else { - layer_rect.Union(CFX_FloatRect(pTextObj->GetBBox(nullptr))); - } - } - } - } - return rect; -} - -void CPDF_ClipPath::AppendPath(CPDF_Path path, uint8_t type, bool bAutoMerge) { - PathData* pData = m_Ref.GetPrivateCopy(); - if (!pData->m_PathAndTypeList.empty() && bAutoMerge) { - const CPDF_Path& old_path = pData->m_PathAndTypeList.back().first; - if (old_path.IsRect()) { - CFX_FloatRect old_rect(old_path.GetPointX(0), old_path.GetPointY(0), - old_path.GetPointX(2), old_path.GetPointY(2)); - CFX_FloatRect new_rect = path.GetBoundingBox(); - if (old_rect.Contains(new_rect)) - pData->m_PathAndTypeList.pop_back(); - } - } - pData->m_PathAndTypeList.push_back(std::make_pair(path, type)); -} - -void CPDF_ClipPath::AppendTexts( - std::vector>* pTexts) { - PathData* pData = m_Ref.GetPrivateCopy(); - if (pData->m_TextList.size() + pTexts->size() <= FPDF_CLIPPATH_MAX_TEXTS) { - for (size_t i = 0; i < pTexts->size(); i++) - pData->m_TextList.push_back(std::move((*pTexts)[i])); - pData->m_TextList.push_back(std::unique_ptr()); - } - pTexts->clear(); -} - -void CPDF_ClipPath::Transform(const CFX_Matrix& matrix) { - PathData* pData = m_Ref.GetPrivateCopy(); - for (auto& obj : pData->m_PathAndTypeList) - obj.first.Transform(&matrix); - for (auto& text : pData->m_TextList) { - if (text) - text->Transform(matrix); - } -} - -CPDF_ClipPath::PathData::PathData() {} - -CPDF_ClipPath::PathData::PathData(const PathData& that) { - m_PathAndTypeList = that.m_PathAndTypeList; - - m_TextList.resize(that.m_TextList.size()); - for (size_t i = 0; i < that.m_TextList.size(); ++i) { - if (that.m_TextList[i]) - m_TextList[i].reset(that.m_TextList[i]->Clone()); - } -} - -CPDF_ClipPath::PathData::~PathData() {} diff --git a/core/fpdfapi/fpdf_page/cpdf_clippath.h b/core/fpdfapi/fpdf_page/cpdf_clippath.h deleted file mode 100644 index 81c8ce6619..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_clippath.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_CLIPPATH_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_CLIPPATH_H_ - -#include -#include -#include - -#include "core/fpdfapi/fpdf_page/cpdf_path.h" -#include "core/fxcrt/cfx_count_ref.h" -#include "core/fxcrt/fx_basic.h" -#include "core/fxcrt/fx_coordinates.h" - -class CPDF_Path; -class CPDF_TextObject; - -class CPDF_ClipPath { - public: - CPDF_ClipPath(); - CPDF_ClipPath(const CPDF_ClipPath& that); - ~CPDF_ClipPath(); - - void Emplace() { m_Ref.Emplace(); } - void SetNull() { m_Ref.SetNull(); } - - explicit operator bool() const { return !!m_Ref; } - bool operator==(const CPDF_ClipPath& that) const { - return m_Ref == that.m_Ref; - } - bool operator!=(const CPDF_ClipPath& that) const { return !(*this == that); } - - uint32_t GetPathCount() const; - CPDF_Path GetPath(size_t i) const; - uint8_t GetClipType(size_t i) const; - uint32_t GetTextCount() const; - CPDF_TextObject* GetText(size_t i) const; - CFX_FloatRect GetClipBox() const; - void AppendPath(CPDF_Path path, uint8_t type, bool bAutoMerge); - void AppendTexts(std::vector>* pTexts); - void Transform(const CFX_Matrix& matrix); - - private: - class PathData { - public: - using PathAndTypeData = std::pair; - - PathData(); - PathData(const PathData& that); - ~PathData(); - - std::vector m_PathAndTypeList; - std::vector> m_TextList; - }; - - CFX_CountRef m_Ref; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_CLIPPATH_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_color.cpp b/core/fpdfapi/fpdf_page/cpdf_color.cpp deleted file mode 100644 index ba46d99b80..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_color.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_color.h" - -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fxcrt/fx_system.h" - -CPDF_Color::CPDF_Color() : m_pCS(nullptr), m_pBuffer(nullptr) {} - -CPDF_Color::~CPDF_Color() { - ReleaseBuffer(); - ReleaseColorSpace(); -} - -bool CPDF_Color::IsPattern() const { - return m_pCS && m_pCS->GetFamily() == PDFCS_PATTERN; -} - -void CPDF_Color::ReleaseBuffer() { - if (!m_pBuffer) - return; - - if (m_pCS->GetFamily() == PDFCS_PATTERN) { - PatternValue* pvalue = (PatternValue*)m_pBuffer; - CPDF_Pattern* pPattern = - pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : nullptr; - if (pPattern && pPattern->document()) { - CPDF_DocPageData* pPageData = pPattern->document()->GetPageData(); - if (pPageData) - pPageData->ReleasePattern(pPattern->pattern_obj()); - } - } - FX_Free(m_pBuffer); - m_pBuffer = nullptr; -} - -void CPDF_Color::ReleaseColorSpace() { - if (m_pCS && m_pCS->m_pDocument) { - m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray()); - m_pCS = nullptr; - } -} - -void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) { - if (m_pCS == pCS) { - if (!m_pBuffer) - m_pBuffer = pCS->CreateBuf(); - - ReleaseColorSpace(); - m_pCS = pCS; - return; - } - ReleaseBuffer(); - ReleaseColorSpace(); - - m_pCS = pCS; - if (m_pCS) { - m_pBuffer = pCS->CreateBuf(); - pCS->GetDefaultColor(m_pBuffer); - } -} - -void CPDF_Color::SetValue(FX_FLOAT* comps) { - if (!m_pBuffer) - return; - if (m_pCS->GetFamily() != PDFCS_PATTERN) - FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT)); -} - -void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) { - if (ncomps > MAX_PATTERN_COLORCOMPS) - return; - - if (!IsPattern()) { - FX_Free(m_pBuffer); - m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); - m_pBuffer = m_pCS->CreateBuf(); - } - - CPDF_DocPageData* pDocPageData = nullptr; - PatternValue* pvalue = (PatternValue*)m_pBuffer; - if (pvalue->m_pPattern && pvalue->m_pPattern->document()) { - pDocPageData = pvalue->m_pPattern->document()->GetPageData(); - if (pDocPageData) - pDocPageData->ReleasePattern(pvalue->m_pPattern->pattern_obj()); - } - pvalue->m_nComps = ncomps; - pvalue->m_pPattern = pPattern; - if (ncomps) - FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT)); - - pvalue->m_pCountedPattern = nullptr; - if (pPattern && pPattern->document()) { - if (!pDocPageData) - pDocPageData = pPattern->document()->GetPageData(); - - pvalue->m_pCountedPattern = - pDocPageData->FindPatternPtr(pPattern->pattern_obj()); - } -} - -void CPDF_Color::Copy(const CPDF_Color* pSrc) { - ReleaseBuffer(); - ReleaseColorSpace(); - - m_pCS = pSrc->m_pCS; - if (m_pCS && m_pCS->m_pDocument) { - CPDF_Array* pArray = m_pCS->GetArray(); - if (pArray) - m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray); - } - if (!m_pCS) - return; - - m_pBuffer = m_pCS->CreateBuf(); - FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize()); - if (m_pCS->GetFamily() != PDFCS_PATTERN) - return; - - PatternValue* pValue = reinterpret_cast(m_pBuffer); - CPDF_Pattern* pPattern = pValue->m_pPattern; - if (pPattern && pPattern->document()) { - pValue->m_pPattern = pPattern->document()->GetPageData()->GetPattern( - pPattern->pattern_obj(), FALSE, pPattern->parent_matrix()); - } -} - -FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const { - if (!m_pCS || !m_pBuffer) - return FALSE; - - FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; - if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) - return FALSE; - - R = (int32_t)(r * 255 + 0.5f); - G = (int32_t)(g * 255 + 0.5f); - B = (int32_t)(b * 255 + 0.5f); - return TRUE; -} - -CPDF_Pattern* CPDF_Color::GetPattern() const { - if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) - return nullptr; - - PatternValue* pvalue = (PatternValue*)m_pBuffer; - return pvalue->m_pPattern; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_color.h b/core/fpdfapi/fpdf_page/cpdf_color.h deleted file mode 100644 index 2056ca4cb8..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_color.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_COLOR_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_COLOR_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_colorspace.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Pattern; - -class CPDF_Color { - public: - CPDF_Color(); - ~CPDF_Color(); - - bool IsNull() const { return !m_pBuffer; } - bool IsPattern() const; - - void Copy(const CPDF_Color* pSrc); - - void SetColorSpace(CPDF_ColorSpace* pCS); - void SetValue(FX_FLOAT* comp); - void SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comp, int ncomps); - - FX_BOOL GetRGB(int& R, int& G, int& B) const; - CPDF_Pattern* GetPattern() const; - const CPDF_ColorSpace* GetColorSpace() const { return m_pCS; } - - protected: - void ReleaseBuffer(); - void ReleaseColorSpace(); - - CPDF_ColorSpace* m_pCS; - FX_FLOAT* m_pBuffer; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_COLOR_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp b/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp deleted file mode 100644 index d7469b6d98..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_colorspace.cpp +++ /dev/null @@ -1,1277 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_colorspace.h" - -#include - -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_object.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fpdfapi/fpdf_parser/cpdf_string.h" -#include "core/fxcodec/fx_codec.h" - -namespace { - -const uint8_t g_sRGBSamples1[] = { - 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31, - 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58, - 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68, - 68, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76, - 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, - 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90, - 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96, - 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 101, 101, 101, - 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 106, 106, 106, 107, - 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 110, 111, 111, 111, - 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116, - 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120, -}; - -const uint8_t g_sRGBSamples2[] = { - 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, - 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, - 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, - 174, 175, 175, 176, 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, - 185, 185, 186, 187, 187, 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, - 194, 195, 196, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, 203, - 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 209, 210, 210, 211, 212, - 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 218, 218, 219, 219, 220, - 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228, - 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, - 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, - 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 249, 249, - 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, -}; - -class CPDF_CalGray : public CPDF_ColorSpace { - public: - explicit CPDF_CalGray(CPDF_Document* pDoc); - - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - FX_BOOL SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const override; - - void TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask = FALSE) const override; - - private: - FX_FLOAT m_WhitePoint[3]; - FX_FLOAT m_BlackPoint[3]; - FX_FLOAT m_Gamma; -}; - -class CPDF_CalRGB : public CPDF_ColorSpace { - public: - explicit CPDF_CalRGB(CPDF_Document* pDoc); - - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - FX_BOOL SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const override; - - void TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask = FALSE) const override; - - FX_FLOAT m_WhitePoint[3]; - FX_FLOAT m_BlackPoint[3]; - FX_FLOAT m_Gamma[3]; - FX_FLOAT m_Matrix[9]; - FX_BOOL m_bGamma; - FX_BOOL m_bMatrix; -}; - -class CPDF_LabCS : public CPDF_ColorSpace { - public: - explicit CPDF_LabCS(CPDF_Document* pDoc); - - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - void GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const override; - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - FX_BOOL SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const override; - - void TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask = FALSE) const override; - - FX_FLOAT m_WhitePoint[3]; - FX_FLOAT m_BlackPoint[3]; - FX_FLOAT m_Ranges[4]; -}; - -class CPDF_ICCBasedCS : public CPDF_ColorSpace { - public: - explicit CPDF_ICCBasedCS(CPDF_Document* pDoc); - ~CPDF_ICCBasedCS() override; - - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - FX_BOOL SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const override; - - FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const override; - - void EnableStdConversion(FX_BOOL bEnabled) override; - void TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask = FALSE) const override; - - CPDF_ColorSpace* m_pAlterCS; - CPDF_IccProfile* m_pProfile; - uint8_t* m_pCache; - FX_FLOAT* m_pRanges; - FX_BOOL m_bOwn; -}; - -class CPDF_IndexedCS : public CPDF_ColorSpace { - public: - explicit CPDF_IndexedCS(CPDF_Document* pDoc); - ~CPDF_IndexedCS() override; - - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - CPDF_ColorSpace* GetBaseCS() const override; - - void EnableStdConversion(FX_BOOL bEnabled) override; - - CPDF_ColorSpace* m_pBaseCS; - CPDF_CountedColorSpace* m_pCountedBaseCS; - int m_nBaseComponents; - int m_MaxIndex; - CFX_ByteString m_Table; - FX_FLOAT* m_pCompMinMax; -}; - -class CPDF_SeparationCS : public CPDF_ColorSpace { - public: - explicit CPDF_SeparationCS(CPDF_Document* pDoc); - ~CPDF_SeparationCS() override; - - // CPDF_ColorSpace: - void GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const override; - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - void EnableStdConversion(FX_BOOL bEnabled) override; - - std::unique_ptr m_pAltCS; - std::unique_ptr m_pFunc; - enum { None, All, Colorant } m_Type; -}; - -class CPDF_DeviceNCS : public CPDF_ColorSpace { - public: - explicit CPDF_DeviceNCS(CPDF_Document* pDoc); - ~CPDF_DeviceNCS() override; - - // CPDF_ColorSpace: - void GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const override; - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - void EnableStdConversion(FX_BOOL bEnabled) override; - - std::unique_ptr m_pAltCS; - std::unique_ptr m_pFunc; -}; - -FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) { - if (colorComponent > 1) - colorComponent = 1; - if (colorComponent < 0) - colorComponent = 0; - - int scale = (int)(colorComponent * 1023); - if (scale < 0) - scale = 0; - if (scale < 192) - colorComponent = (g_sRGBSamples1[scale] / 255.0f); - else - colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f); - return colorComponent; -} - -void XYZ_to_sRGB(FX_FLOAT X, - FX_FLOAT Y, - FX_FLOAT Z, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) { - FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z; - FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z; - FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z; - - R = RGB_Conversion(R1); - G = RGB_Conversion(G1); - B = RGB_Conversion(B1); -} - -void XYZ_to_sRGB_WhitePoint(FX_FLOAT X, - FX_FLOAT Y, - FX_FLOAT Z, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B, - FX_FLOAT Xw, - FX_FLOAT Yw, - FX_FLOAT Zw) { - // The following RGB_xyz is based on - // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06} - - FX_FLOAT Rx = 0.64f, Ry = 0.33f; - FX_FLOAT Gx = 0.30f, Gy = 0.60f; - FX_FLOAT Bx = 0.15f, By = 0.06f; - CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy, - 1 - Bx - By); - CFX_Vector_3by1 whitePoint(Xw, Yw, Zw); - CFX_Vector_3by1 XYZ(X, Y, Z); - - CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint); - CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0, - 0, RGB_Sum_XYZ.c); - CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG); - CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ); - - R = RGB_Conversion(RGB.a); - G = RGB_Conversion(RGB.b); - B = RGB_Conversion(RGB.c); -} - -} // namespace - -CPDF_ColorSpace* CPDF_ColorSpace::ColorspaceFromName( - const CFX_ByteString& name) { - if (name == "DeviceRGB" || name == "RGB") - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); - if (name == "DeviceGray" || name == "G") - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); - if (name == "DeviceCMYK" || name == "CMYK") - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); - if (name == "Pattern") - return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); - return nullptr; -} - -CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) { - return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family); -} - -std::unique_ptr CPDF_ColorSpace::Load(CPDF_Document* pDoc, - CPDF_Object* pObj) { - if (!pObj) - return std::unique_ptr(); - - if (pObj->IsName()) { - return std::unique_ptr( - ColorspaceFromName(pObj->GetString())); - } - if (CPDF_Stream* pStream = pObj->AsStream()) { - CPDF_Dictionary* pDict = pStream->GetDict(); - if (!pDict) - return std::unique_ptr(); - - for (const auto& it : *pDict) { - std::unique_ptr pRet; - CPDF_Object* pValue = it.second; - if (ToName(pValue)) - pRet.reset(ColorspaceFromName(pValue->GetString())); - if (pRet) - return pRet; - } - return std::unique_ptr(); - } - - CPDF_Array* pArray = pObj->AsArray(); - if (!pArray || pArray->IsEmpty()) - return std::unique_ptr(); - - CPDF_Object* pFamilyObj = pArray->GetDirectObjectAt(0); - if (!pFamilyObj) - return std::unique_ptr(); - - CFX_ByteString familyname = pFamilyObj->GetString(); - if (pArray->GetCount() == 1) - return std::unique_ptr(ColorspaceFromName(familyname)); - - std::unique_ptr pCS; - uint32_t id = familyname.GetID(); - if (id == FXBSTR_ID('C', 'a', 'l', 'G')) { - pCS.reset(new CPDF_CalGray(pDoc)); - } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) { - pCS.reset(new CPDF_CalRGB(pDoc)); - } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) { - pCS.reset(new CPDF_LabCS(pDoc)); - } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) { - pCS.reset(new CPDF_ICCBasedCS(pDoc)); - } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || - id == FXBSTR_ID('I', 0, 0, 0)) { - pCS.reset(new CPDF_IndexedCS(pDoc)); - } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) { - pCS.reset(new CPDF_SeparationCS(pDoc)); - } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) { - pCS.reset(new CPDF_DeviceNCS(pDoc)); - } else if (id == FXBSTR_ID('P', 'a', 't', 't')) { - pCS.reset(new CPDF_PatternCS(pDoc)); - } else { - return std::unique_ptr(); - } - pCS->m_pArray = pArray; - if (!pCS->v_Load(pDoc, pArray)) - return std::unique_ptr(); - - return pCS; -} - -void CPDF_ColorSpace::Release() { - if (this == GetStockCS(PDFCS_DEVICERGB) || - this == GetStockCS(PDFCS_DEVICEGRAY) || - this == GetStockCS(PDFCS_DEVICECMYK) || - this == GetStockCS(PDFCS_PATTERN)) { - return; - } - delete this; -} - -int CPDF_ColorSpace::GetBufSize() const { - if (m_Family == PDFCS_PATTERN) { - return sizeof(PatternValue); - } - return m_nComponents * sizeof(FX_FLOAT); -} - -FX_FLOAT* CPDF_ColorSpace::CreateBuf() { - int size = GetBufSize(); - uint8_t* pBuf = FX_Alloc(uint8_t, size); - return (FX_FLOAT*)pBuf; -} - -FX_BOOL CPDF_ColorSpace::sRGB() const { - if (m_Family == PDFCS_DEVICERGB) { - return TRUE; - } - if (m_Family != PDFCS_ICCBASED) { - return FALSE; - } - CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this; - return pCS->m_pProfile->m_bsRGB; -} - -FX_BOOL CPDF_ColorSpace::SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const { - return FALSE; -} - -FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const { - if (v_GetCMYK(pBuf, c, m, y, k)) { - return TRUE; - } - FX_FLOAT R, G, B; - if (!GetRGB(pBuf, R, G, B)) { - return FALSE; - } - sRGB_to_AdobeCMYK(R, G, B, c, m, y, k); - return TRUE; -} - -FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf, - FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k) const { - if (v_SetCMYK(pBuf, c, m, y, k)) { - return TRUE; - } - FX_FLOAT R, G, B; - AdobeCMYK_to_sRGB(c, m, y, k, R, G, B); - return SetRGB(pBuf, R, G, B); -} - -void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const { - if (!buf || m_Family == PDFCS_PATTERN) { - return; - } - FX_FLOAT min, max; - for (uint32_t i = 0; i < m_nComponents; i++) { - GetDefaultValue(i, buf[i], min, max); - } -} - -uint32_t CPDF_ColorSpace::CountComponents() const { - return m_nComponents; -} - -void CPDF_ColorSpace::GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const { - value = 0; - min = 0; - max = 1.0f; -} - -void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf, - const uint8_t* src_buf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask) const { - CFX_FixedBufGrow srcbuf(m_nComponents); - FX_FLOAT* src = srcbuf; - FX_FLOAT R, G, B; - for (int i = 0; i < pixels; i++) { - for (uint32_t j = 0; j < m_nComponents; j++) - if (m_Family == PDFCS_INDEXED) { - src[j] = (FX_FLOAT)(*src_buf++); - } else { - src[j] = (FX_FLOAT)(*src_buf++) / 255; - } - GetRGB(src, R, G, B); - *dest_buf++ = (int32_t)(B * 255); - *dest_buf++ = (int32_t)(G * 255); - *dest_buf++ = (int32_t)(R * 255); - } -} - -CPDF_ColorSpace* CPDF_ColorSpace::GetBaseCS() const { - return nullptr; -} - -void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) { - if (bEnabled) - m_dwStdConversion++; - else if (m_dwStdConversion) - m_dwStdConversion--; -} - -CPDF_ColorSpace::CPDF_ColorSpace(CPDF_Document* pDoc, - int family, - uint32_t nComponents) - : m_pDocument(pDoc), - m_Family(family), - m_nComponents(nComponents), - m_pArray(nullptr), - m_dwStdConversion(0) {} - -CPDF_ColorSpace::~CPDF_ColorSpace() {} - -FX_BOOL CPDF_ColorSpace::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - return TRUE; -} - -FX_BOOL CPDF_ColorSpace::v_GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const { - return FALSE; -} - -FX_BOOL CPDF_ColorSpace::v_SetCMYK(FX_FLOAT* pBuf, - FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k) const { - return FALSE; -} - -CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {} - -FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CPDF_Dictionary* pDict = pArray->GetDictAt(1); - if (!pDict) - return FALSE; - - CPDF_Array* pParam = pDict->GetArrayFor("WhitePoint"); - int i; - for (i = 0; i < 3; i++) - m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0; - - pParam = pDict->GetArrayFor("BlackPoint"); - for (i = 0; i < 3; i++) - m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0; - - m_Gamma = pDict->GetNumberFor("Gamma"); - if (m_Gamma == 0) - m_Gamma = 1.0f; - return TRUE; -} - -FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - R = G = B = *pBuf; - return TRUE; -} - -FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const { - if (R == G && R == B) { - *pBuf = R; - return TRUE; - } - return FALSE; -} - -void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask) const { - for (int i = 0; i < pixels; i++) { - *pDestBuf++ = pSrcBuf[i]; - *pDestBuf++ = pSrcBuf[i]; - *pDestBuf++ = pSrcBuf[i]; - } -} - -CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {} - -FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CPDF_Dictionary* pDict = pArray->GetDictAt(1); - if (!pDict) - return FALSE; - - CPDF_Array* pParam = pDict->GetArrayFor("WhitePoint"); - int i; - for (i = 0; i < 3; i++) - m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0; - - pParam = pDict->GetArrayFor("BlackPoint"); - for (i = 0; i < 3; i++) - m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0; - - pParam = pDict->GetArrayFor("Gamma"); - if (pParam) { - m_bGamma = TRUE; - for (i = 0; i < 3; i++) - m_Gamma[i] = pParam->GetNumberAt(i); - } else { - m_bGamma = FALSE; - } - - pParam = pDict->GetArrayFor("Matrix"); - if (pParam) { - m_bMatrix = TRUE; - for (i = 0; i < 9; i++) - m_Matrix[i] = pParam->GetNumberAt(i); - } else { - m_bMatrix = FALSE; - } - return TRUE; -} - -FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - FX_FLOAT A_ = pBuf[0]; - FX_FLOAT B_ = pBuf[1]; - FX_FLOAT C_ = pBuf[2]; - if (m_bGamma) { - A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]); - B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]); - C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]); - } - - FX_FLOAT X; - FX_FLOAT Y; - FX_FLOAT Z; - if (m_bMatrix) { - X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_; - Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_; - Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_; - } else { - X = A_; - Y = B_; - Z = C_; - } - XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1], - m_WhitePoint[2]); - return TRUE; -} - -FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const { - pBuf[0] = R; - pBuf[1] = G; - pBuf[2] = B; - return TRUE; -} - -void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask) const { - if (bTransMask) { - FX_FLOAT Cal[3]; - FX_FLOAT R; - FX_FLOAT G; - FX_FLOAT B; - for (int i = 0; i < pixels; i++) { - Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255; - Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255; - Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255; - GetRGB(Cal, R, G, B); - pDestBuf[0] = FXSYS_round(B * 255); - pDestBuf[1] = FXSYS_round(G * 255); - pDestBuf[2] = FXSYS_round(R * 255); - pSrcBuf += 3; - pDestBuf += 3; - } - } - ReverseRGB(pDestBuf, pSrcBuf, pixels); -} - -CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {} - -void CPDF_LabCS::GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const { - ASSERT(iComponent < 3); - value = 0; - if (iComponent == 0) { - min = 0; - max = 100 * 1.0f; - } else { - min = m_Ranges[iComponent * 2 - 2]; - max = m_Ranges[iComponent * 2 - 1]; - if (value < min) - value = min; - else if (value > max) - value = max; - } -} - -FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CPDF_Dictionary* pDict = pArray->GetDictAt(1); - if (!pDict) - return FALSE; - - CPDF_Array* pParam = pDict->GetArrayFor("WhitePoint"); - int i; - for (i = 0; i < 3; i++) - m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0; - - pParam = pDict->GetArrayFor("BlackPoint"); - for (i = 0; i < 3; i++) - m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0; - - pParam = pDict->GetArrayFor("Range"); - const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f, - 100 * 1.0f}; - for (i = 0; i < 4; i++) - m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i]; - return TRUE; -} - -FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - FX_FLOAT Lstar = pBuf[0]; - FX_FLOAT astar = pBuf[1]; - FX_FLOAT bstar = pBuf[2]; - FX_FLOAT M = (Lstar + 16.0f) / 116.0f; - FX_FLOAT L = M + astar / 500.0f; - FX_FLOAT N = M - bstar / 200.0f; - FX_FLOAT X, Y, Z; - if (L < 0.2069f) - X = 0.957f * 0.12842f * (L - 0.1379f); - else - X = 0.957f * L * L * L; - - if (M < 0.2069f) - Y = 0.12842f * (M - 0.1379f); - else - Y = M * M * M; - - if (N < 0.2069f) - Z = 1.0889f * 0.12842f * (N - 0.1379f); - else - Z = 1.0889f * N * N * N; - - XYZ_to_sRGB(X, Y, Z, R, G, B); - return TRUE; -} - -FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const { - return FALSE; -} - -void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask) const { - for (int i = 0; i < pixels; i++) { - FX_FLOAT lab[3]; - FX_FLOAT R, G, B; - lab[0] = (pSrcBuf[0] * 100 / 255.0f); - lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128); - lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128); - GetRGB(lab, R, G, B); - pDestBuf[0] = (int32_t)(B * 255); - pDestBuf[1] = (int32_t)(G * 255); - pDestBuf[2] = (int32_t)(R * 255); - pDestBuf += 3; - pSrcBuf += 3; - } -} - -CPDF_ICCBasedCS::CPDF_ICCBasedCS(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0), - m_pAlterCS(nullptr), - m_pProfile(nullptr), - m_pCache(nullptr), - m_pRanges(nullptr), - m_bOwn(FALSE) {} - -CPDF_ICCBasedCS::~CPDF_ICCBasedCS() { - FX_Free(m_pCache); - FX_Free(m_pRanges); - if (m_pAlterCS && m_bOwn) - m_pAlterCS->Release(); - if (m_pProfile && m_pDocument) - m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile); -} - -FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CPDF_Stream* pStream = pArray->GetStreamAt(1); - if (!pStream) - return FALSE; - - m_pProfile = pDoc->LoadIccProfile(pStream); - if (!m_pProfile) - return FALSE; - - m_nComponents = - m_pProfile - ->GetComponents(); // Try using the nComponents from ICC profile - CPDF_Dictionary* pDict = pStream->GetDict(); - if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB - CPDF_Object* pAlterCSObj = - pDict ? pDict->GetDirectObjectFor("Alternate") : nullptr; - if (pAlterCSObj) { - std::unique_ptr pAlterCS = - CPDF_ColorSpace::Load(pDoc, pAlterCSObj); - if (pAlterCS) { - if (m_nComponents == 0) { // NO valid ICC profile - if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace - m_nComponents = pAlterCS->CountComponents(); - m_pAlterCS = pAlterCS.release(); - m_bOwn = TRUE; - } else { // No valid alternative colorspace - int32_t nDictComponents = pDict ? pDict->GetIntegerFor("N") : 0; - if (nDictComponents != 1 && nDictComponents != 3 && - nDictComponents != 4) { - return FALSE; - } - m_nComponents = nDictComponents; - } - } else { // Using sRGB - if (pAlterCS->CountComponents() == m_nComponents) { - m_pAlterCS = pAlterCS.release(); - m_bOwn = TRUE; - } - } - } - } - if (!m_pAlterCS) { - if (m_nComponents == 1) - m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); - else if (m_nComponents == 3) - m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); - else if (m_nComponents == 4) - m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); - } - } - CPDF_Array* pRanges = pDict->GetArrayFor("Range"); - m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2); - for (uint32_t i = 0; i < m_nComponents * 2; i++) { - if (pRanges) - m_pRanges[i] = pRanges->GetNumberAt(i); - else if (i % 2) - m_pRanges[i] = 1.0f; - else - m_pRanges[i] = 0; - } - return TRUE; -} - -FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - if (m_pProfile && m_pProfile->m_bsRGB) { - R = pBuf[0]; - G = pBuf[1]; - B = pBuf[2]; - return TRUE; - } - CCodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule(); - if (!m_pProfile->m_pTransform || !pIccModule) { - if (m_pAlterCS) - return m_pAlterCS->GetRGB(pBuf, R, G, B); - - R = 0.0f; - G = 0.0f; - B = 0.0f; - return TRUE; - } - FX_FLOAT rgb[3]; - pIccModule->SetComponents(m_nComponents); - pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb); - R = rgb[0]; - G = rgb[1]; - B = rgb[2]; - return TRUE; -} - -FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const { - return FALSE; -} - -FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const { - if (m_nComponents != 4) - return FALSE; - - c = pBuf[0]; - m = pBuf[1]; - y = pBuf[2]; - k = pBuf[3]; - return TRUE; -} - -void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) { - CPDF_ColorSpace::EnableStdConversion(bEnabled); - if (m_pAlterCS) - m_pAlterCS->EnableStdConversion(bEnabled); -} - -void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask) const { - if (m_pProfile->m_bsRGB) { - ReverseRGB(pDestBuf, pSrcBuf, pixels); - } else if (m_pProfile->m_pTransform) { - int nMaxColors = 1; - for (uint32_t i = 0; i < m_nComponents; i++) { - nMaxColors *= 52; - } - if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) { - CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline( - m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels); - } else { - if (!m_pCache) { - ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3); - uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents); - uint8_t* pSrc = temp_src; - for (int i = 0; i < nMaxColors; i++) { - uint32_t color = i; - uint32_t order = nMaxColors / 52; - for (uint32_t c = 0; c < m_nComponents; c++) { - *pSrc++ = (uint8_t)(color / order * 5); - color %= order; - order /= 52; - } - } - CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline( - m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors); - FX_Free(temp_src); - } - for (int i = 0; i < pixels; i++) { - int index = 0; - for (uint32_t c = 0; c < m_nComponents; c++) { - index = index * 52 + (*pSrcBuf) / 5; - pSrcBuf++; - } - index *= 3; - *pDestBuf++ = m_pCache[index]; - *pDestBuf++ = m_pCache[index + 1]; - *pDestBuf++ = m_pCache[index + 2]; - } - } - } else if (m_pAlterCS) { - m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, - image_height); - } -} - -CPDF_IndexedCS::CPDF_IndexedCS(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1), - m_pBaseCS(nullptr), - m_pCountedBaseCS(nullptr), - m_pCompMinMax(nullptr) {} - -CPDF_IndexedCS::~CPDF_IndexedCS() { - FX_Free(m_pCompMinMax); - CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : nullptr; - if (pCS && m_pDocument) { - m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); - } -} - -FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - if (pArray->GetCount() < 4) { - return FALSE; - } - CPDF_Object* pBaseObj = pArray->GetDirectObjectAt(1); - if (pBaseObj == m_pArray) { - return FALSE; - } - CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); - m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, nullptr); - if (!m_pBaseCS) { - return FALSE; - } - m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); - m_nBaseComponents = m_pBaseCS->CountComponents(); - m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2); - FX_FLOAT defvalue; - for (int i = 0; i < m_nBaseComponents; i++) { - m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], - m_pCompMinMax[i * 2 + 1]); - m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2]; - } - m_MaxIndex = pArray->GetIntegerAt(2); - - CPDF_Object* pTableObj = pArray->GetDirectObjectAt(3); - if (!pTableObj) - return FALSE; - - if (CPDF_String* pString = pTableObj->AsString()) { - m_Table = pString->GetString(); - } else if (CPDF_Stream* pStream = pTableObj->AsStream()) { - CPDF_StreamAcc acc; - acc.LoadAllData(pStream, FALSE); - m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize()); - } - return TRUE; -} - -FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - int index = (int32_t)(*pBuf); - if (index < 0 || index > m_MaxIndex) { - return FALSE; - } - if (m_nBaseComponents) { - if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents || - (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) { - R = G = B = 0; - return FALSE; - } - } - CFX_FixedBufGrow Comps(m_nBaseComponents); - FX_FLOAT* comps = Comps; - const uint8_t* pTable = m_Table.raw_str(); - for (int i = 0; i < m_nBaseComponents; i++) { - comps[i] = - m_pCompMinMax[i * 2] + - m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255; - } - return m_pBaseCS->GetRGB(comps, R, G, B); -} - -CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const { - return m_pBaseCS; -} - -void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) { - CPDF_ColorSpace::EnableStdConversion(bEnabled); - if (m_pBaseCS) { - m_pBaseCS->EnableStdConversion(bEnabled); - } -} - -CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1), - m_pBaseCS(nullptr), - m_pCountedBaseCS(nullptr) {} - -CPDF_PatternCS::~CPDF_PatternCS() { - CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : nullptr; - if (pCS && m_pDocument) { - m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); - } -} - -FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CPDF_Object* pBaseCS = pArray->GetDirectObjectAt(1); - if (pBaseCS == m_pArray) { - return FALSE; - } - CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); - m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, nullptr); - if (m_pBaseCS) { - if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) { - return FALSE; - } - m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); - m_nComponents = m_pBaseCS->CountComponents() + 1; - if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) { - return FALSE; - } - } else { - m_nComponents = 1; - } - return TRUE; -} - -FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - if (m_pBaseCS) { - ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN); - PatternValue* pvalue = (PatternValue*)pBuf; - if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) { - return TRUE; - } - } - R = G = B = 0.75f; - return FALSE; -} - -CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const { - return m_pBaseCS; -} - -CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1) {} - -CPDF_SeparationCS::~CPDF_SeparationCS() {} - -void CPDF_SeparationCS::GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const { - value = 1.0f; - min = 0; - max = 1.0f; -} - -FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CFX_ByteString name = pArray->GetStringAt(1); - if (name == "None") { - m_Type = None; - return TRUE; - } - - m_Type = Colorant; - CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2); - if (pAltCS == m_pArray) - return FALSE; - - m_pAltCS = Load(pDoc, pAltCS); - if (!m_pAltCS) - return FALSE; - - CPDF_Object* pFuncObj = pArray->GetDirectObjectAt(3); - if (pFuncObj && !pFuncObj->IsName()) - m_pFunc = CPDF_Function::Load(pFuncObj); - - if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) - m_pFunc.reset(); - return TRUE; -} - -FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - if (m_Type == None) - return FALSE; - - if (!m_pFunc) { - if (!m_pAltCS) - return FALSE; - - int nComps = m_pAltCS->CountComponents(); - CFX_FixedBufGrow results(nComps); - for (int i = 0; i < nComps; i++) - results[i] = *pBuf; - return m_pAltCS->GetRGB(results, R, G, B); - } - - CFX_FixedBufGrow results(m_pFunc->CountOutputs()); - int nresults = 0; - m_pFunc->Call(pBuf, 1, results, nresults); - if (nresults == 0) - return FALSE; - - if (m_pAltCS) - return m_pAltCS->GetRGB(results, R, G, B); - - R = 0; - G = 0; - B = 0; - return FALSE; -} - -void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) { - CPDF_ColorSpace::EnableStdConversion(bEnabled); - if (m_pAltCS) - m_pAltCS->EnableStdConversion(bEnabled); -} - -CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc) - : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0) {} - -CPDF_DeviceNCS::~CPDF_DeviceNCS() {} - -void CPDF_DeviceNCS::GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const { - value = 1.0f; - min = 0; - max = 1.0f; -} - -FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { - CPDF_Array* pObj = ToArray(pArray->GetDirectObjectAt(1)); - if (!pObj) - return FALSE; - - m_nComponents = pObj->GetCount(); - CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2); - if (!pAltCS || pAltCS == m_pArray) - return FALSE; - - m_pAltCS = Load(pDoc, pAltCS); - m_pFunc = CPDF_Function::Load(pArray->GetDirectObjectAt(3)); - if (!m_pAltCS || !m_pFunc) - return FALSE; - - return m_pFunc->CountOutputs() >= m_pAltCS->CountComponents(); -} - -FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - if (!m_pFunc) - return FALSE; - - CFX_FixedBufGrow results(m_pFunc->CountOutputs()); - int nresults = 0; - m_pFunc->Call(pBuf, m_nComponents, results, nresults); - if (nresults == 0) - return FALSE; - - return m_pAltCS->GetRGB(results, R, G, B); -} - -void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) { - CPDF_ColorSpace::EnableStdConversion(bEnabled); - if (m_pAltCS) { - m_pAltCS->EnableStdConversion(bEnabled); - } -} diff --git a/core/fpdfapi/fpdf_page/cpdf_colorspace.h b/core/fpdfapi/fpdf_page/cpdf_colorspace.h deleted file mode 100644 index 892ec688d0..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_colorspace.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSPACE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSPACE_H_ - -#include - -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/fx_system.h" - -#define PDFCS_DEVICEGRAY 1 -#define PDFCS_DEVICERGB 2 -#define PDFCS_DEVICECMYK 3 -#define PDFCS_CALGRAY 4 -#define PDFCS_CALRGB 5 -#define PDFCS_LAB 6 -#define PDFCS_ICCBASED 7 -#define PDFCS_SEPARATION 8 -#define PDFCS_DEVICEN 9 -#define PDFCS_INDEXED 10 -#define PDFCS_PATTERN 11 - -class CPDF_Array; -class CPDF_Document; -class CPDF_Object; - -class CPDF_ColorSpace { - public: - static CPDF_ColorSpace* GetStockCS(int Family); - static CPDF_ColorSpace* ColorspaceFromName(const CFX_ByteString& name); - static std::unique_ptr Load(CPDF_Document* pDoc, - CPDF_Object* pCSObj); - - void Release(); - - int GetBufSize() const; - FX_FLOAT* CreateBuf(); - void GetDefaultColor(FX_FLOAT* buf) const; - uint32_t CountComponents() const; - int GetFamily() const { return m_Family; } - virtual void GetDefaultValue(int iComponent, - FX_FLOAT& value, - FX_FLOAT& min, - FX_FLOAT& max) const; - - FX_BOOL sRGB() const; - virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const = 0; - virtual FX_BOOL SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const; - - FX_BOOL GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const; - FX_BOOL SetCMYK(FX_FLOAT* pBuf, - FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k) const; - - virtual void TranslateImageLine(uint8_t* dest_buf, - const uint8_t* src_buf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask = FALSE) const; - - CPDF_Array*& GetArray() { return m_pArray; } - virtual CPDF_ColorSpace* GetBaseCS() const; - - virtual void EnableStdConversion(FX_BOOL bEnabled); - - CPDF_Document* const m_pDocument; - - protected: - CPDF_ColorSpace(CPDF_Document* pDoc, int family, uint32_t nComponents); - virtual ~CPDF_ColorSpace(); - - virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); - virtual FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const; - virtual FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, - FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k) const; - - int m_Family; - uint32_t m_nComponents; - CPDF_Array* m_pArray; - uint32_t m_dwStdConversion; -}; - -namespace std { - -// Make std::unique_ptr call Release() rather than -// simply deleting the object. -template <> -struct default_delete { - void operator()(CPDF_ColorSpace* pColorSpace) const { - if (pColorSpace) - pColorSpace->Release(); - } -}; - -} // namespace std - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSPACE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp b/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp deleted file mode 100644 index e74b884d68..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_colorstate.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_colorstate.h" - -#include "core/fpdfapi/fpdf_page/cpdf_pattern.h" -#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" -#include "core/fxge/fx_dib.h" - -CPDF_ColorState::CPDF_ColorState() {} - -CPDF_ColorState::CPDF_ColorState(const CPDF_ColorState& that) - : m_Ref(that.m_Ref) {} - -CPDF_ColorState::~CPDF_ColorState() {} - -void CPDF_ColorState::Emplace() { - m_Ref.Emplace(); -} - -void CPDF_ColorState::SetDefault() { - m_Ref.GetPrivateCopy()->SetDefault(); -} - -uint32_t CPDF_ColorState::GetFillRGB() const { - return m_Ref.GetObject()->m_FillRGB; -} - -void CPDF_ColorState::SetFillRGB(uint32_t rgb) { - m_Ref.GetPrivateCopy()->m_FillRGB = rgb; -} - -uint32_t CPDF_ColorState::GetStrokeRGB() const { - return m_Ref.GetObject()->m_StrokeRGB; -} - -void CPDF_ColorState::SetStrokeRGB(uint32_t rgb) { - m_Ref.GetPrivateCopy()->m_StrokeRGB = rgb; -} - -const CPDF_Color* CPDF_ColorState::GetFillColor() const { - const ColorData* pData = m_Ref.GetObject(); - return pData ? &pData->m_FillColor : nullptr; -} - -CPDF_Color* CPDF_ColorState::GetMutableFillColor() { - return &m_Ref.GetPrivateCopy()->m_FillColor; -} - -bool CPDF_ColorState::HasFillColor() const { - const CPDF_Color* pColor = GetFillColor(); - return pColor && !pColor->IsNull(); -} - -const CPDF_Color* CPDF_ColorState::GetStrokeColor() const { - const ColorData* pData = m_Ref.GetObject(); - return pData ? &pData->m_StrokeColor : nullptr; -} - -CPDF_Color* CPDF_ColorState::GetMutableStrokeColor() { - return &m_Ref.GetPrivateCopy()->m_StrokeColor; -} - -bool CPDF_ColorState::HasStrokeColor() const { - const CPDF_Color* pColor = GetStrokeColor(); - return pColor && !pColor->IsNull(); -} - -void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, - FX_FLOAT* pValue, - uint32_t nValues) { - ColorData* pData = m_Ref.GetPrivateCopy(); - SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues); -} - -void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, - FX_FLOAT* pValue, - uint32_t nValues) { - ColorData* pData = m_Ref.GetPrivateCopy(); - SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues); -} - -void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, - FX_FLOAT* pValue, - uint32_t nValues) { - ColorData* pData = m_Ref.GetPrivateCopy(); - pData->m_FillColor.SetValue(pPattern, pValue, nValues); - int R, G, B; - FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B); - if (CPDF_TilingPattern* pTilingPattern = pPattern->AsTilingPattern()) { - if (!ret && pTilingPattern->colored()) { - pData->m_FillRGB = 0x00BFBFBF; - return; - } - } - pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (uint32_t)-1; -} - -void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, - FX_FLOAT* pValue, - uint32_t nValues) { - ColorData* pData = m_Ref.GetPrivateCopy(); - pData->m_StrokeColor.SetValue(pPattern, pValue, nValues); - int R, G, B; - FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B); - if (CPDF_TilingPattern* pTilingPattern = pPattern->AsTilingPattern()) { - if (!ret && pTilingPattern->colored()) { - pData->m_StrokeRGB = 0x00BFBFBF; - return; - } - } - pData->m_StrokeRGB = - pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (uint32_t)-1; -} - -void CPDF_ColorState::SetColor(CPDF_Color& color, - uint32_t& rgb, - CPDF_ColorSpace* pCS, - FX_FLOAT* pValue, - uint32_t nValues) { - if (pCS) - color.SetColorSpace(pCS); - else if (color.IsNull()) - color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); - - if (color.GetColorSpace()->CountComponents() > nValues) - return; - - color.SetValue(pValue); - int R; - int G; - int B; - rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (uint32_t)-1; -} - -CPDF_ColorState::ColorData::ColorData() : m_FillRGB(0), m_StrokeRGB(0) {} - -CPDF_ColorState::ColorData::ColorData(const ColorData& src) - : m_FillRGB(src.m_FillRGB), m_StrokeRGB(src.m_StrokeRGB) { - m_FillColor.Copy(&src.m_FillColor); - m_StrokeColor.Copy(&src.m_StrokeColor); -} - -CPDF_ColorState::ColorData::~ColorData() {} - -void CPDF_ColorState::ColorData::SetDefault() { - m_FillRGB = 0; - m_StrokeRGB = 0; - m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); - m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_colorstate.h b/core/fpdfapi/fpdf_page/cpdf_colorstate.h deleted file mode 100644 index 9114ad3528..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_colorstate.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSTATE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSTATE_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_color.h" -#include "core/fxcrt/cfx_count_ref.h" -#include "core/fxcrt/fx_basic.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Color; -class CPDF_ColorSpace; -class CPDF_Pattern; - -class CPDF_ColorState { - public: - CPDF_ColorState(); - CPDF_ColorState(const CPDF_ColorState& that); - ~CPDF_ColorState(); - - void Emplace(); - void SetDefault(); - - uint32_t GetFillRGB() const; - void SetFillRGB(uint32_t rgb); - - uint32_t GetStrokeRGB() const; - void SetStrokeRGB(uint32_t rgb); - - const CPDF_Color* GetFillColor() const; - CPDF_Color* GetMutableFillColor(); - bool HasFillColor() const; - - const CPDF_Color* GetStrokeColor() const; - CPDF_Color* GetMutableStrokeColor(); - bool HasStrokeColor() const; - - void SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, uint32_t nValues); - void SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, uint32_t nValues); - void SetFillPattern(CPDF_Pattern* pattern, - FX_FLOAT* pValue, - uint32_t nValues); - void SetStrokePattern(CPDF_Pattern* pattern, - FX_FLOAT* pValue, - uint32_t nValues); - - explicit operator bool() const { return !!m_Ref; } - - private: - class ColorData { - public: - ColorData(); - ColorData(const ColorData& src); - ~ColorData(); - - void SetDefault(); - - uint32_t m_FillRGB; - uint32_t m_StrokeRGB; - CPDF_Color m_FillColor; - CPDF_Color m_StrokeColor; - }; - - void SetColor(CPDF_Color& color, - uint32_t& rgb, - CPDF_ColorSpace* pCS, - FX_FLOAT* pValue, - uint32_t nValues); - - CFX_CountRef m_Ref; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_COLORSTATE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_contentmark.cpp b/core/fpdfapi/fpdf_page/cpdf_contentmark.cpp deleted file mode 100644 index f71206e640..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_contentmark.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_contentmark.h" - -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "third_party/base/stl_util.h" - -CPDF_ContentMark::CPDF_ContentMark() {} - -CPDF_ContentMark::CPDF_ContentMark(const CPDF_ContentMark& that) - : m_Ref(that.m_Ref) {} - -CPDF_ContentMark::~CPDF_ContentMark() {} - -void CPDF_ContentMark::SetNull() { - m_Ref.SetNull(); -} - -int CPDF_ContentMark::CountItems() const { - return m_Ref.GetObject()->CountItems(); -} - -const CPDF_ContentMarkItem& CPDF_ContentMark::GetItem(int i) const { - return m_Ref.GetObject()->GetItem(i); -} - -int CPDF_ContentMark::GetMCID() const { - const MarkData* pData = m_Ref.GetObject(); - return pData ? pData->GetMCID() : -1; -} - -void CPDF_ContentMark::AddMark(const CFX_ByteString& name, - CPDF_Dictionary* pDict, - FX_BOOL bDirect) { - m_Ref.GetPrivateCopy()->AddMark(name, pDict, bDirect); -} - -void CPDF_ContentMark::DeleteLastMark() { - m_Ref.GetPrivateCopy()->DeleteLastMark(); - if (CountItems() == 0) - m_Ref.SetNull(); -} - -bool CPDF_ContentMark::HasMark(const CFX_ByteStringC& mark) const { - const MarkData* pData = m_Ref.GetObject(); - if (!pData) - return false; - - for (int i = 0; i < pData->CountItems(); i++) { - if (pData->GetItem(i).GetName() == mark) - return true; - } - return false; -} - -bool CPDF_ContentMark::LookupMark(const CFX_ByteStringC& mark, - CPDF_Dictionary*& pDict) const { - const MarkData* pData = m_Ref.GetObject(); - if (!pData) - return false; - - for (int i = 0; i < pData->CountItems(); i++) { - const CPDF_ContentMarkItem& item = pData->GetItem(i); - if (item.GetName() == mark) { - pDict = item.GetParam(); - return true; - } - } - return false; -} - -CPDF_ContentMark::MarkData::MarkData() {} - -CPDF_ContentMark::MarkData::MarkData(const MarkData& src) - : m_Marks(src.m_Marks) {} - -CPDF_ContentMark::MarkData::~MarkData() {} - -int CPDF_ContentMark::MarkData::CountItems() const { - return pdfium::CollectionSize(m_Marks); -} - -CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(int index) { - return m_Marks[index]; -} - -const CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem( - int index) const { - return m_Marks[index]; -} - -int CPDF_ContentMark::MarkData::GetMCID() const { - for (const auto& mark : m_Marks) { - CPDF_Dictionary* pDict = mark.GetParam(); - if (pDict && pDict->KeyExist("MCID")) - return pDict->GetIntegerFor("MCID"); - } - return -1; -} - -void CPDF_ContentMark::MarkData::AddMark(const CFX_ByteString& name, - CPDF_Dictionary* pDict, - FX_BOOL bDirect) { - CPDF_ContentMarkItem item; - item.SetName(name); - if (pDict) { - if (bDirect) { - item.SetDirectDict( - std::unique_ptr>( - ToDictionary(pDict->Clone()))); - } else { - item.SetPropertiesDict(pDict); - } - } - m_Marks.push_back(std::move(item)); -} - -void CPDF_ContentMark::MarkData::DeleteLastMark() { - if (!m_Marks.empty()) - m_Marks.pop_back(); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_contentmark.h b/core/fpdfapi/fpdf_page/cpdf_contentmark.h deleted file mode 100644 index 5f38f04337..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_contentmark.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_CONTENTMARK_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_CONTENTMARK_H_ - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h" -#include "core/fxcrt/cfx_count_ref.h" -#include "core/fxcrt/fx_basic.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Dictionary; - -class CPDF_ContentMark { - public: - CPDF_ContentMark(); - CPDF_ContentMark(const CPDF_ContentMark& that); - ~CPDF_ContentMark(); - - void SetNull(); - - int GetMCID() const; - int CountItems() const; - const CPDF_ContentMarkItem& GetItem(int i) const; - - bool HasMark(const CFX_ByteStringC& mark) const; - bool LookupMark(const CFX_ByteStringC& mark, CPDF_Dictionary*& pDict) const; - void AddMark(const CFX_ByteString& name, - CPDF_Dictionary* pDict, - FX_BOOL bDirect); - void DeleteLastMark(); - - explicit operator bool() const { return !!m_Ref; } - - private: - class MarkData { - public: - MarkData(); - MarkData(const MarkData& src); - ~MarkData(); - - int CountItems() const; - CPDF_ContentMarkItem& GetItem(int index); - const CPDF_ContentMarkItem& GetItem(int index) const; - - int GetMCID() const; - void AddMark(const CFX_ByteString& name, - CPDF_Dictionary* pDict, - FX_BOOL bDictNeedClone); - void DeleteLastMark(); - - private: - std::vector m_Marks; - }; - - CFX_CountRef m_Ref; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_CONTENTMARK_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_contentmarkitem.cpp b/core/fpdfapi/fpdf_page/cpdf_contentmarkitem.cpp deleted file mode 100644 index 88c5008e0b..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_contentmarkitem.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h" - -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" - -CPDF_ContentMarkItem::CPDF_ContentMarkItem() - : m_ParamType(None), m_pPropertiesDict(nullptr) {} - -CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& that) - : m_MarkName(that.m_MarkName), - m_ParamType(that.m_ParamType), - m_pPropertiesDict(that.m_pPropertiesDict) { - if (that.m_pDirectDict) - m_pDirectDict.reset(that.m_pDirectDict->Clone()->AsDictionary()); -} - -CPDF_ContentMarkItem::~CPDF_ContentMarkItem() {} - -CPDF_Dictionary* CPDF_ContentMarkItem::GetParam() const { - switch (m_ParamType) { - case PropertiesDict: - return m_pPropertiesDict; - case DirectDict: - return m_pDirectDict.get(); - case None: - default: - return nullptr; - } -} - -FX_BOOL CPDF_ContentMarkItem::HasMCID() const { - CPDF_Dictionary* pDict = GetParam(); - return pDict && pDict->KeyExist("MCID"); -} - -void CPDF_ContentMarkItem::SetDirectDict( - std::unique_ptr> pDict) { - m_ParamType = DirectDict; - m_pDirectDict = std::move(pDict); -} - -void CPDF_ContentMarkItem::SetPropertiesDict(CPDF_Dictionary* pDict) { - m_ParamType = PropertiesDict; - m_pPropertiesDict = pDict; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h b/core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h deleted file mode 100644 index 1cd80a25a4..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_contentmarkitem.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_CONTENTMARKITEM_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_CONTENTMARKITEM_H_ - -#include - -#include "core/fxcrt/fx_memory.h" -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Dictionary; - -class CPDF_ContentMarkItem { - public: - enum ParamType { None, PropertiesDict, DirectDict }; - - CPDF_ContentMarkItem(); - CPDF_ContentMarkItem(const CPDF_ContentMarkItem& that); - ~CPDF_ContentMarkItem(); - - CPDF_ContentMarkItem& operator=(CPDF_ContentMarkItem&& other) = default; - - CFX_ByteString GetName() const { return m_MarkName; } - ParamType GetParamType() const { return m_ParamType; } - CPDF_Dictionary* GetParam() const; - FX_BOOL HasMCID() const; - - void SetName(const CFX_ByteString& name) { m_MarkName = name; } - void SetDirectDict( - std::unique_ptr> pDict); - void SetPropertiesDict(CPDF_Dictionary* pDict); - - private: - CFX_ByteString m_MarkName; - ParamType m_ParamType; - CPDF_Dictionary* m_pPropertiesDict; // not owned. - std::unique_ptr> - m_pDirectDict; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_CONTENTMARKITEM_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_countedobject.h b/core/fpdfapi/fpdf_page/cpdf_countedobject.h deleted file mode 100644 index 6aa6577124..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_countedobject.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_COUNTEDOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_COUNTEDOBJECT_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_colorspace.h" -#include "core/fpdfapi/fpdf_page/cpdf_pattern.h" -#include "core/fxcrt/fx_system.h" - -template -class CPDF_CountedObject { - public: - explicit CPDF_CountedObject(T* ptr) : m_nCount(1), m_pObj(ptr) {} - void reset(T* ptr) { // CAUTION: tosses prior ref counts. - m_nCount = 1; - m_pObj = ptr; - } - void clear() { // Now you're all weak ptrs ... - // Guard against accidental re-entry. - T* pObj = m_pObj; - m_pObj = nullptr; - delete pObj; - } - T* get() const { return m_pObj; } - T* AddRef() { - ASSERT(m_pObj); - ++m_nCount; - return m_pObj; - } - void RemoveRef() { - if (m_nCount) - --m_nCount; - } - size_t use_count() const { return m_nCount; } - - protected: - size_t m_nCount; - T* m_pObj; -}; -using CPDF_CountedColorSpace = CPDF_CountedObject; -using CPDF_CountedPattern = CPDF_CountedObject; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_COUNTEDOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_form.cpp b/core/fpdfapi/fpdf_page/cpdf_form.cpp deleted file mode 100644 index 2823ee5bab..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_form.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_form.h" - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" - -CPDF_Form::CPDF_Form(CPDF_Document* pDoc, - CPDF_Dictionary* pPageResources, - CPDF_Stream* pFormStream, - CPDF_Dictionary* pParentResources) { - m_pDocument = pDoc; - m_pFormStream = pFormStream; - m_pFormDict = pFormStream ? pFormStream->GetDict() : nullptr; - m_pResources = m_pFormDict->GetDictFor("Resources"); - m_pPageResources = pPageResources; - if (!m_pResources) - m_pResources = pParentResources; - if (!m_pResources) - m_pResources = pPageResources; - m_Transparency = 0; - LoadTransInfo(); -} - -CPDF_Form::~CPDF_Form() {} - -void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, - const CFX_Matrix* pParentMatrix, - CPDF_Type3Char* pType3Char, - int level) { - if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) - return; - - m_pParser.reset(new CPDF_ContentParser); - m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, level); - m_ParseState = CONTENT_PARSING; -} - -void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, - const CFX_Matrix* pParentMatrix, - CPDF_Type3Char* pType3Char, - int level) { - StartParse(pGraphicStates, pParentMatrix, pType3Char, level); - ContinueParse(nullptr); -} - -CPDF_Form* CPDF_Form::Clone() const { - CPDF_Form* pCloneForm = - new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources); - for (const auto& pObj : m_PageObjectList) - pCloneForm->m_PageObjectList.emplace_back(pObj->Clone()); - - return pCloneForm; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_form.h b/core/fpdfapi/fpdf_page/cpdf_form.h deleted file mode 100644 index 1b88763d2c..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_form.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_FORM_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_FORM_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h" - -class CPDF_Document; -class CPDF_Dictionary; -class CPDF_Stream; -class CPDF_AllStates; -class CFX_Matrix; -class CPDF_Type3Char; - -class CPDF_Form : public CPDF_PageObjectHolder { - public: - CPDF_Form(CPDF_Document* pDocument, - CPDF_Dictionary* pPageResources, - CPDF_Stream* pFormStream, - CPDF_Dictionary* pParentResources = nullptr); - ~CPDF_Form() override; - - void ParseContent(CPDF_AllStates* pGraphicStates, - const CFX_Matrix* pParentMatrix, - CPDF_Type3Char* pType3Char, - int level = 0); - - CPDF_Form* Clone() const; - - private: - void StartParse(CPDF_AllStates* pGraphicStates, - const CFX_Matrix* pParentMatrix, - CPDF_Type3Char* pType3Char, - int level = 0); -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_FORM_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_formobject.cpp b/core/fpdfapi/fpdf_page/cpdf_formobject.cpp deleted file mode 100644 index d027d1dbf9..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_formobject.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_formobject.h" - -#include "core/fpdfapi/fpdf_page/cpdf_form.h" - -CPDF_FormObject::CPDF_FormObject() {} - -CPDF_FormObject::~CPDF_FormObject() {} - -void CPDF_FormObject::Transform(const CFX_Matrix& matrix) { - m_FormMatrix.Concat(matrix); - CalcBoundingBox(); -} - -bool CPDF_FormObject::IsForm() const { - return true; -} - -CPDF_FormObject* CPDF_FormObject::AsForm() { - return this; -} - -const CPDF_FormObject* CPDF_FormObject::AsForm() const { - return this; -} - -CPDF_FormObject* CPDF_FormObject::Clone() const { - CPDF_FormObject* obj = new CPDF_FormObject; - obj->CopyData(this); - - obj->m_pForm.reset(m_pForm->Clone()); - obj->m_FormMatrix = m_FormMatrix; - return obj; -} - -CPDF_PageObject::Type CPDF_FormObject::GetType() const { - return FORM; -} - -void CPDF_FormObject::CalcBoundingBox() { - CFX_FloatRect form_rect = m_pForm->CalcBoundingBox(); - form_rect.Transform(&m_FormMatrix); - m_Left = form_rect.left; - m_Bottom = form_rect.bottom; - m_Right = form_rect.right; - m_Top = form_rect.top; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_formobject.h b/core/fpdfapi/fpdf_page/cpdf_formobject.h deleted file mode 100644 index d3d92575be..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_formobject.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_FORMOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_FORMOBJECT_H_ - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fxcrt/fx_coordinates.h" - -class CPDF_Form; - -class CPDF_FormObject : public CPDF_PageObject { - public: - CPDF_FormObject(); - ~CPDF_FormObject() override; - - // CPDF_PageObject: - CPDF_FormObject* Clone() const override; - Type GetType() const override; - void Transform(const CFX_Matrix& matrix) override; - bool IsForm() const override; - CPDF_FormObject* AsForm() override; - const CPDF_FormObject* AsForm() const override; - - void CalcBoundingBox(); - const CPDF_Form* form() const { return m_pForm.get(); } - - std::unique_ptr m_pForm; - CFX_Matrix m_FormMatrix; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_FORMOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp b/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp deleted file mode 100644 index e5208f5c30..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_generalstate.h" - -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_render/render_int.h" - -namespace { - -int RI_StringToId(const CFX_ByteString& ri) { - uint32_t id = ri.GetID(); - if (id == FXBSTR_ID('A', 'b', 's', 'o')) - return 1; - - if (id == FXBSTR_ID('S', 'a', 't', 'u')) - return 2; - - if (id == FXBSTR_ID('P', 'e', 'r', 'c')) - return 3; - - return 0; -} - -int GetBlendTypeInternal(const CFX_ByteString& mode) { - switch (mode.GetID()) { - case FXBSTR_ID('N', 'o', 'r', 'm'): - case FXBSTR_ID('C', 'o', 'm', 'p'): - return FXDIB_BLEND_NORMAL; - case FXBSTR_ID('M', 'u', 'l', 't'): - return FXDIB_BLEND_MULTIPLY; - case FXBSTR_ID('S', 'c', 'r', 'e'): - return FXDIB_BLEND_SCREEN; - case FXBSTR_ID('O', 'v', 'e', 'r'): - return FXDIB_BLEND_OVERLAY; - case FXBSTR_ID('D', 'a', 'r', 'k'): - return FXDIB_BLEND_DARKEN; - case FXBSTR_ID('L', 'i', 'g', 'h'): - return FXDIB_BLEND_LIGHTEN; - case FXBSTR_ID('C', 'o', 'l', 'o'): - if (mode.GetLength() == 10) - return FXDIB_BLEND_COLORDODGE; - if (mode.GetLength() == 9) - return FXDIB_BLEND_COLORBURN; - return FXDIB_BLEND_COLOR; - case FXBSTR_ID('H', 'a', 'r', 'd'): - return FXDIB_BLEND_HARDLIGHT; - case FXBSTR_ID('S', 'o', 'f', 't'): - return FXDIB_BLEND_SOFTLIGHT; - case FXBSTR_ID('D', 'i', 'f', 'f'): - return FXDIB_BLEND_DIFFERENCE; - case FXBSTR_ID('E', 'x', 'c', 'l'): - return FXDIB_BLEND_EXCLUSION; - case FXBSTR_ID('H', 'u', 'e', 0): - return FXDIB_BLEND_HUE; - case FXBSTR_ID('S', 'a', 't', 'u'): - return FXDIB_BLEND_SATURATION; - case FXBSTR_ID('L', 'u', 'm', 'i'): - return FXDIB_BLEND_LUMINOSITY; - } - return FXDIB_BLEND_NORMAL; -} - -} // namespace - -CPDF_GeneralState::CPDF_GeneralState() {} - -CPDF_GeneralState::CPDF_GeneralState(const CPDF_GeneralState& that) - : m_Ref(that.m_Ref) {} - -CPDF_GeneralState::~CPDF_GeneralState() {} - -void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri) { - m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri); -} - -int CPDF_GeneralState::GetBlendType() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL; -} - -void CPDF_GeneralState::SetBlendType(int type) { - m_Ref.GetPrivateCopy()->m_BlendType = type; -} - -FX_FLOAT CPDF_GeneralState::GetFillAlpha() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? pData->m_FillAlpha : 1.0f; -} - -void CPDF_GeneralState::SetFillAlpha(FX_FLOAT alpha) { - m_Ref.GetPrivateCopy()->m_FillAlpha = alpha; -} - -FX_FLOAT CPDF_GeneralState::GetStrokeAlpha() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? pData->m_StrokeAlpha : 1.0f; -} - -void CPDF_GeneralState::SetStrokeAlpha(FX_FLOAT alpha) { - m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha; -} - -CPDF_Object* CPDF_GeneralState::GetSoftMask() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? pData->m_pSoftMask : nullptr; -} - -void CPDF_GeneralState::SetSoftMask(CPDF_Object* pObject) { - m_Ref.GetPrivateCopy()->m_pSoftMask = pObject; -} - -CPDF_Object* CPDF_GeneralState::GetTR() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? pData->m_pTR : nullptr; -} - -void CPDF_GeneralState::SetTR(CPDF_Object* pObject) { - m_Ref.GetPrivateCopy()->m_pTR = pObject; -} - -CPDF_TransferFunc* CPDF_GeneralState::GetTransferFunc() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? pData->m_pTransferFunc : nullptr; -} - -void CPDF_GeneralState::SetTransferFunc(CPDF_TransferFunc* pFunc) { - m_Ref.GetPrivateCopy()->m_pTransferFunc = pFunc; -} - -void CPDF_GeneralState::SetBlendMode(const CFX_ByteString& mode) { - StateData* pData = m_Ref.GetPrivateCopy(); - pData->m_BlendMode = mode; - pData->m_BlendType = GetBlendTypeInternal(mode); -} - -const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const { - const StateData* pData = m_Ref.GetObject(); - return pData ? &pData->m_SMaskMatrix : nullptr; -} - -void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) { - m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix; -} - -bool CPDF_GeneralState::GetFillOP() const { - const StateData* pData = m_Ref.GetObject(); - return pData && pData->m_FillOP; -} - -void CPDF_GeneralState::SetFillOP(bool op) { - m_Ref.GetPrivateCopy()->m_FillOP = op; -} - -void CPDF_GeneralState::SetStrokeOP(bool op) { - m_Ref.GetPrivateCopy()->m_StrokeOP = op; -} - -bool CPDF_GeneralState::GetStrokeOP() const { - const StateData* pData = m_Ref.GetObject(); - return pData && pData->m_StrokeOP; -} - -int CPDF_GeneralState::GetOPMode() const { - return m_Ref.GetObject()->m_OPMode; -} - -void CPDF_GeneralState::SetOPMode(int mode) { - m_Ref.GetPrivateCopy()->m_OPMode = mode; -} - -void CPDF_GeneralState::SetBG(CPDF_Object* pObject) { - m_Ref.GetPrivateCopy()->m_pBG = pObject; -} - -void CPDF_GeneralState::SetUCR(CPDF_Object* pObject) { - m_Ref.GetPrivateCopy()->m_pUCR = pObject; -} - -void CPDF_GeneralState::SetHT(CPDF_Object* pObject) { - m_Ref.GetPrivateCopy()->m_pHT = pObject; -} - -void CPDF_GeneralState::SetFlatness(FX_FLOAT flatness) { - m_Ref.GetPrivateCopy()->m_Flatness = flatness; -} - -void CPDF_GeneralState::SetSmoothness(FX_FLOAT smoothness) { - m_Ref.GetPrivateCopy()->m_Smoothness = smoothness; -} - -bool CPDF_GeneralState::GetStrokeAdjust() const { - const StateData* pData = m_Ref.GetObject(); - return pData && pData->m_StrokeAdjust; -} - -void CPDF_GeneralState::SetStrokeAdjust(bool adjust) { - m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust; -} - -void CPDF_GeneralState::SetAlphaSource(bool source) { - m_Ref.GetPrivateCopy()->m_AlphaSource = source; -} - -void CPDF_GeneralState::SetTextKnockout(bool knockout) { - m_Ref.GetPrivateCopy()->m_TextKnockout = knockout; -} - -void CPDF_GeneralState::SetMatrix(const CFX_Matrix& matrix) { - m_Ref.GetPrivateCopy()->m_Matrix = matrix; -} - -CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() { - return &m_Ref.GetPrivateCopy()->m_Matrix; -} - -CPDF_GeneralState::StateData::StateData() - : m_BlendMode("Normal"), - m_BlendType(0), - m_pSoftMask(nullptr), - m_StrokeAlpha(1.0), - m_FillAlpha(1.0f), - m_pTR(nullptr), - m_pTransferFunc(nullptr), - m_RenderIntent(0), - m_StrokeAdjust(false), - m_AlphaSource(false), - m_TextKnockout(false), - m_StrokeOP(false), - m_FillOP(false), - m_OPMode(0), - m_pBG(nullptr), - m_pUCR(nullptr), - m_pHT(nullptr), - m_Flatness(1.0f), - m_Smoothness(0.0f) { - m_SMaskMatrix.SetIdentity(); - m_Matrix.SetIdentity(); -} - -CPDF_GeneralState::StateData::StateData(const StateData& that) - : m_BlendMode(that.m_BlendMode), - m_BlendType(that.m_BlendType), - m_pSoftMask(that.m_pSoftMask), - m_StrokeAlpha(that.m_StrokeAlpha), - m_FillAlpha(that.m_FillAlpha), - m_pTR(that.m_pTR), - m_pTransferFunc(that.m_pTransferFunc), - m_RenderIntent(that.m_RenderIntent), - m_StrokeAdjust(that.m_StrokeAdjust), - m_AlphaSource(that.m_AlphaSource), - m_TextKnockout(that.m_TextKnockout), - m_StrokeOP(that.m_StrokeOP), - m_FillOP(that.m_FillOP), - m_OPMode(that.m_OPMode), - m_pBG(that.m_pBG), - m_pUCR(that.m_pUCR), - m_pHT(that.m_pHT), - m_Flatness(that.m_Flatness), - m_Smoothness(that.m_Smoothness) { - m_Matrix = that.m_Matrix; - m_SMaskMatrix = that.m_SMaskMatrix; - - if (that.m_pTransferFunc && that.m_pTransferFunc->m_pPDFDoc) { - CPDF_DocRenderData* pDocCache = - that.m_pTransferFunc->m_pPDFDoc->GetRenderData(); - if (pDocCache) - m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR); - } -} - -CPDF_GeneralState::StateData::~StateData() { - if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) { - CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData(); - if (pDocCache) - pDocCache->ReleaseTransferFunc(m_pTR); - } -} diff --git a/core/fpdfapi/fpdf_page/cpdf_generalstate.h b/core/fpdfapi/fpdf_page/cpdf_generalstate.h deleted file mode 100644 index 9bcce04894..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_generalstate.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_GENERALSTATE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_GENERALSTATE_H_ - -#include "core/fxcrt/fx_basic.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxge/fx_dib.h" - -class CPDF_Object; -class CPDF_TransferFunc; - -class CPDF_GeneralState { - public: - CPDF_GeneralState(); - CPDF_GeneralState(const CPDF_GeneralState& that); - ~CPDF_GeneralState(); - - void Emplace() { m_Ref.Emplace(); } - explicit operator bool() const { return !!m_Ref; } - - void SetRenderIntent(const CFX_ByteString& ri); - - int GetBlendType() const; - void SetBlendType(int type); - - FX_FLOAT GetFillAlpha() const; - void SetFillAlpha(FX_FLOAT alpha); - - FX_FLOAT GetStrokeAlpha() const; - void SetStrokeAlpha(FX_FLOAT alpha); - - CPDF_Object* GetSoftMask() const; - void SetSoftMask(CPDF_Object* pObject); - - CPDF_Object* GetTR() const; - void SetTR(CPDF_Object* pObject); - - CPDF_TransferFunc* GetTransferFunc() const; - void SetTransferFunc(CPDF_TransferFunc* pFunc); - - void SetBlendMode(const CFX_ByteString& mode); - - const CFX_Matrix* GetSMaskMatrix() const; - void SetSMaskMatrix(const CFX_Matrix& matrix); - - bool GetFillOP() const; - void SetFillOP(bool op); - - bool GetStrokeOP() const; - void SetStrokeOP(bool op); - - int GetOPMode() const; - void SetOPMode(int mode); - - void SetBG(CPDF_Object* pObject); - void SetUCR(CPDF_Object* pObject); - void SetHT(CPDF_Object* pObject); - - void SetFlatness(FX_FLOAT flatness); - void SetSmoothness(FX_FLOAT smoothness); - - bool GetStrokeAdjust() const; - void SetStrokeAdjust(bool adjust); - - void SetAlphaSource(bool source); - void SetTextKnockout(bool knockout); - - void SetMatrix(const CFX_Matrix& matrix); - CFX_Matrix* GetMutableMatrix(); - - private: - class StateData { - public: - StateData(); - StateData(const StateData& that); - ~StateData(); - - CFX_ByteString m_BlendMode; - int m_BlendType; - CPDF_Object* m_pSoftMask; - CFX_Matrix m_SMaskMatrix; - FX_FLOAT m_StrokeAlpha; - FX_FLOAT m_FillAlpha; - CPDF_Object* m_pTR; - CPDF_TransferFunc* m_pTransferFunc; - CFX_Matrix m_Matrix; - int m_RenderIntent; - bool m_StrokeAdjust; - bool m_AlphaSource; - bool m_TextKnockout; - bool m_StrokeOP; - bool m_FillOP; - int m_OPMode; - CPDF_Object* m_pBG; - CPDF_Object* m_pUCR; - CPDF_Object* m_pHT; - FX_FLOAT m_Flatness; - FX_FLOAT m_Smoothness; - }; - - CFX_CountRef m_Ref; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_GENERALSTATE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp b/core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp deleted file mode 100644 index 42f26c1135..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" - -CPDF_GraphicStates::CPDF_GraphicStates() {} - -CPDF_GraphicStates::~CPDF_GraphicStates() {} - -void CPDF_GraphicStates::DefaultStates() { - m_ColorState.Emplace(); - m_ColorState.SetDefault(); -} - -void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src) { - m_ClipPath = src.m_ClipPath; - m_GraphState = src.m_GraphState; - m_ColorState = src.m_ColorState; - m_TextState = src.m_TextState; - m_GeneralState = src.m_GeneralState; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_graphicstates.h b/core/fpdfapi/fpdf_page/cpdf_graphicstates.h deleted file mode 100644 index 6e612153d0..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_graphicstates.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_GRAPHICSTATES_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_GRAPHICSTATES_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_clippath.h" -#include "core/fpdfapi/fpdf_page/cpdf_colorstate.h" -#include "core/fpdfapi/fpdf_page/cpdf_generalstate.h" -#include "core/fpdfapi/fpdf_page/cpdf_textstate.h" -#include "core/fxge/cfx_graphstate.h" - -class CPDF_GraphicStates { - public: - CPDF_GraphicStates(); - virtual ~CPDF_GraphicStates(); - - void CopyStates(const CPDF_GraphicStates& src); - void DefaultStates(); - - CPDF_ClipPath m_ClipPath; - CFX_GraphState m_GraphState; - CPDF_ColorState m_ColorState; - CPDF_TextState m_TextState; - CPDF_GeneralState m_GeneralState; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_GRAPHICSTATES_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_image.cpp b/core/fpdfapi/fpdf_page/cpdf_image.cpp deleted file mode 100644 index 21cec2e442..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_image.cpp +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_image.h" - -#include -#include -#include - -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_page/cpdf_page.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_string.h" -#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" -#include "core/fpdfapi/fpdf_render/render_int.h" -#include "core/fxcodec/fx_codec.h" -#include "core/fxge/fx_dib.h" - -CPDF_Image::CPDF_Image(CPDF_Document* pDoc) - : CPDF_Image(pDoc, nullptr, false) {} - -CPDF_Image::CPDF_Image(CPDF_Document* pDoc, CPDF_Stream* pStream, bool bInline) - : m_pDIBSource(nullptr), - m_pMask(nullptr), - m_MatteColor(0), - m_pStream(pStream), - m_bInline(bInline), - m_pInlineDict(nullptr), - m_Height(0), - m_Width(0), - m_bIsMask(false), - m_bInterpolate(false), - m_pDocument(pDoc), - m_pOC(nullptr) { - if (!pStream) - return; - - CPDF_Dictionary* pDict = pStream->GetDict(); - if (m_bInline) - m_pInlineDict = ToDictionary(pDict->Clone()); - - m_pOC = pDict->GetDictFor("OC"); - m_bIsMask = - !pDict->KeyExist("ColorSpace") || pDict->GetIntegerFor("ImageMask"); - m_bInterpolate = !!pDict->GetIntegerFor("Interpolate"); - m_Height = pDict->GetIntegerFor("Height"); - m_Width = pDict->GetIntegerFor("Width"); -} - -CPDF_Image::~CPDF_Image() { - if (m_bInline) { - if (m_pStream) - m_pStream->Release(); - if (m_pInlineDict) - m_pInlineDict->Release(); - } -} - -CPDF_Image* CPDF_Image::Clone() { - if (m_pStream->GetObjNum()) - return m_pDocument->GetPageData()->GetImage(m_pStream); - - CPDF_Image* pImage = - new CPDF_Image(m_pDocument, ToStream(m_pStream->Clone()), m_bInline); - if (m_bInline) - pImage->SetInlineDict(ToDictionary(m_pInlineDict->CloneDirectObject())); - - return pImage; -} - -CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { - int32_t width; - int32_t height; - int32_t num_comps; - int32_t bits; - bool color_trans; - if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( - pData, size, &width, &height, &num_comps, &bits, &color_trans)) { - return nullptr; - } - - CPDF_Dictionary* pDict = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pDict->SetNameFor("Type", "XObject"); - pDict->SetNameFor("Subtype", "Image"); - pDict->SetIntegerFor("Width", width); - pDict->SetIntegerFor("Height", height); - const FX_CHAR* csname = nullptr; - if (num_comps == 1) { - csname = "DeviceGray"; - } else if (num_comps == 3) { - csname = "DeviceRGB"; - } else if (num_comps == 4) { - csname = "DeviceCMYK"; - CPDF_Array* pDecode = new CPDF_Array; - for (int n = 0; n < 4; n++) { - pDecode->AddInteger(1); - pDecode->AddInteger(0); - } - pDict->SetFor("Decode", pDecode); - } - pDict->SetNameFor("ColorSpace", csname); - pDict->SetIntegerFor("BitsPerComponent", bits); - pDict->SetNameFor("Filter", "DCTDecode"); - if (!color_trans) { - CPDF_Dictionary* pParms = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pDict->SetFor("DecodeParms", pParms); - pParms->SetIntegerFor("ColorTransform", 0); - } - m_bIsMask = FALSE; - m_Width = width; - m_Height = height; - if (!m_pStream) - m_pStream = new CPDF_Stream; - return pDict; -} - -void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) { - uint32_t size = (uint32_t)pFile->GetSize(); - if (!size) - return; - - uint32_t dwEstimateSize = std::min(size, 8192U); - std::vector data(dwEstimateSize); - pFile->ReadBlock(data.data(), 0, dwEstimateSize); - CPDF_Dictionary* pDict = InitJPEG(data.data(), dwEstimateSize); - if (!pDict && size > dwEstimateSize) { - data.resize(size); - pFile->ReadBlock(data.data(), 0, size); - pDict = InitJPEG(data.data(), size); - } - if (!pDict) - return; - - m_pStream->InitStreamFromFile(pFile, pDict); -} - -void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { - int32_t BitmapWidth = pBitmap->GetWidth(); - int32_t BitmapHeight = pBitmap->GetHeight(); - if (BitmapWidth < 1 || BitmapHeight < 1) { - return; - } - uint8_t* src_buf = pBitmap->GetBuffer(); - int32_t src_pitch = pBitmap->GetPitch(); - int32_t bpp = pBitmap->GetBPP(); - - CPDF_Dictionary* pDict = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pDict->SetNameFor("Type", "XObject"); - pDict->SetNameFor("Subtype", "Image"); - pDict->SetIntegerFor("Width", BitmapWidth); - pDict->SetIntegerFor("Height", BitmapHeight); - uint8_t* dest_buf = nullptr; - FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; - if (bpp == 1) { - int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; - int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; - if (!pBitmap->IsAlphaMask()) { - ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, - reset_b); - ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); - } - if (set_a == 0 || reset_a == 0) { - pDict->SetFor("ImageMask", new CPDF_Boolean(TRUE)); - if (reset_a == 0) { - CPDF_Array* pArray = new CPDF_Array; - pArray->AddInteger(1); - pArray->AddInteger(0); - pDict->SetFor("Decode", pArray); - } - } else { - CPDF_Array* pCS = new CPDF_Array; - pCS->AddName("Indexed"); - pCS->AddName("DeviceRGB"); - pCS->AddInteger(1); - CFX_ByteString ct; - FX_CHAR* pBuf = ct.GetBuffer(6); - pBuf[0] = (FX_CHAR)reset_r; - pBuf[1] = (FX_CHAR)reset_g; - pBuf[2] = (FX_CHAR)reset_b; - pBuf[3] = (FX_CHAR)set_r; - pBuf[4] = (FX_CHAR)set_g; - pBuf[5] = (FX_CHAR)set_b; - ct.ReleaseBuffer(6); - pCS->Add(new CPDF_String(ct, TRUE)); - pDict->SetFor("ColorSpace", pCS); - } - pDict->SetIntegerFor("BitsPerComponent", 1); - dest_pitch = (BitmapWidth + 7) / 8; - if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { - opType = 1; - } else { - opType = 0; - } - } else if (bpp == 8) { - int32_t iPalette = pBitmap->GetPaletteSize(); - if (iPalette > 0) { - CPDF_Array* pCS = new CPDF_Array; - pCS->AddName("Indexed"); - pCS->AddName("DeviceRGB"); - pCS->AddInteger(iPalette - 1); - uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); - uint8_t* ptr = pColorTable; - for (int32_t i = 0; i < iPalette; i++) { - uint32_t argb = pBitmap->GetPaletteArgb(i); - ptr[0] = (uint8_t)(argb >> 16); - ptr[1] = (uint8_t)(argb >> 8); - ptr[2] = (uint8_t)argb; - ptr += 3; - } - CPDF_Stream* pCTS = new CPDF_Stream( - pColorTable, iPalette * 3, - new CPDF_Dictionary(m_pDocument->GetByteStringPool())); - pCS->AddReference(m_pDocument, m_pDocument->AddIndirectObject(pCTS)); - pDict->SetReferenceFor("ColorSpace", m_pDocument, - m_pDocument->AddIndirectObject(pCS)); - } else { - pDict->SetNameFor("ColorSpace", "DeviceGray"); - } - pDict->SetIntegerFor("BitsPerComponent", 8); - if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { - dest_pitch = BitmapWidth; - opType = 1; - } else { - opType = 0; - } - } else { - pDict->SetNameFor("ColorSpace", "DeviceRGB"); - pDict->SetIntegerFor("BitsPerComponent", 8); - if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { - dest_pitch = BitmapWidth * 3; - opType = 2; - } else { - opType = 0; - } - } - const CFX_DIBitmap* pMaskBitmap = nullptr; - FX_BOOL bDeleteMask = FALSE; - if (pBitmap->HasAlpha()) { - pMaskBitmap = pBitmap->GetAlphaMask(); - bDeleteMask = TRUE; - } - if (pMaskBitmap) { - int32_t maskWidth = pMaskBitmap->GetWidth(); - int32_t maskHeight = pMaskBitmap->GetHeight(); - uint8_t* mask_buf = nullptr; - FX_STRSIZE mask_size = 0; - CPDF_Dictionary* pMaskDict = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - pMaskDict->SetNameFor("Type", "XObject"); - pMaskDict->SetNameFor("Subtype", "Image"); - pMaskDict->SetIntegerFor("Width", maskWidth); - pMaskDict->SetIntegerFor("Height", maskHeight); - pMaskDict->SetNameFor("ColorSpace", "DeviceGray"); - pMaskDict->SetIntegerFor("BitsPerComponent", 8); - if (pMaskBitmap->GetBPP() == 8 && - (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { - } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { - } else { - mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); - mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. - for (int32_t a = 0; a < maskHeight; a++) { - FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), - maskWidth); - } - } - pMaskDict->SetIntegerFor("Length", mask_size); - pDict->SetReferenceFor("SMask", m_pDocument, - m_pDocument->AddIndirectObject(new CPDF_Stream( - mask_buf, mask_size, pMaskDict))); - if (bDeleteMask) - delete pMaskBitmap; - } - if (opType == 0) { - if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { - } else { - if (pBitmap->GetBPP() == 1) { - } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { - CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); - pNewBitmap->Copy(pBitmap); - pNewBitmap->ConvertFormat(FXDIB_Rgb); - SetImage(pNewBitmap, iCompress); - if (pDict) { - pDict->Release(); - pDict = nullptr; - } - FX_Free(dest_buf); - dest_buf = nullptr; - dest_size = 0; - delete pNewBitmap; - return; - } - } - } else if (opType == 1) { - dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight); - dest_size = dest_pitch * BitmapHeight; // Safe as checked alloc returned. - - uint8_t* pDest = dest_buf; - for (int32_t i = 0; i < BitmapHeight; i++) { - FXSYS_memcpy(pDest, src_buf, dest_pitch); - pDest += dest_pitch; - src_buf += src_pitch; - } - } else if (opType == 2) { - dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight); - dest_size = dest_pitch * BitmapHeight; // Safe as checked alloc returned. - - uint8_t* pDest = dest_buf; - int32_t src_offset = 0; - int32_t dest_offset = 0; - for (int32_t row = 0; row < BitmapHeight; row++) { - src_offset = row * src_pitch; - for (int32_t column = 0; column < BitmapWidth; column++) { - FX_FLOAT alpha = 1; - pDest[dest_offset] = (uint8_t)(src_buf[src_offset + 2] * alpha); - pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha); - pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha); - dest_offset += 3; - src_offset += bpp == 24 ? 3 : 4; - } - - pDest += dest_pitch; - dest_offset = 0; - } - } - if (!m_pStream) - m_pStream = new CPDF_Stream; - - m_pStream->InitStream(dest_buf, dest_size, pDict); - m_bIsMask = pBitmap->IsAlphaMask(); - m_Width = BitmapWidth; - m_Height = BitmapHeight; - FX_Free(dest_buf); -} - -void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { - pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); -} - -CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, - uint32_t* pMatteColor, - FX_BOOL bStdCS, - uint32_t GroupFamily, - FX_BOOL bLoadMask) const { - std::unique_ptr source(new CPDF_DIBSource); - if (source->Load(m_pDocument, m_pStream, - reinterpret_cast(ppMask), pMatteColor, - nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) { - return source.release(); - } - return nullptr; -} - -CFX_DIBSource* CPDF_Image::DetachBitmap() { - CFX_DIBSource* pBitmap = m_pDIBSource; - m_pDIBSource = nullptr; - return pBitmap; -} - -CFX_DIBSource* CPDF_Image::DetachMask() { - CFX_DIBSource* pBitmap = m_pMask; - m_pMask = nullptr; - return pBitmap; -} - -FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, - CPDF_Dictionary* pPageResource, - FX_BOOL bStdCS, - uint32_t GroupFamily, - FX_BOOL bLoadMask) { - std::unique_ptr source(new CPDF_DIBSource); - int ret = - source->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, - pPageResource, bStdCS, GroupFamily, bLoadMask); - if (ret == 2) { - m_pDIBSource = source.release(); - return TRUE; - } - if (!ret) { - m_pDIBSource = nullptr; - return FALSE; - } - m_pMask = source->DetachMask(); - m_MatteColor = source->GetMatteColor(); - m_pDIBSource = source.release(); - return FALSE; -} - -FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) { - CPDF_DIBSource* pSource = static_cast(m_pDIBSource); - int ret = pSource->ContinueLoadDIBSource(pPause); - if (ret == 2) { - return TRUE; - } - if (!ret) { - delete m_pDIBSource; - m_pDIBSource = nullptr; - return FALSE; - } - m_pMask = pSource->DetachMask(); - m_MatteColor = pSource->GetMatteColor(); - return FALSE; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_image.h b/core/fpdfapi/fpdf_page/cpdf_image.h deleted file mode 100644 index 4254202c9d..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_image.h +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_IMAGE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_IMAGE_H_ - -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" -#include "core/fxcrt/fx_system.h" - -#define PDF_IMAGE_NO_COMPRESS 0x0000 -#define PDF_IMAGE_LOSSY_COMPRESS 0x0001 -#define PDF_IMAGE_LOSSLESS_COMPRESS 0x0002 -#define PDF_IMAGE_MASK_LOSSY_COMPRESS 0x0004 -#define PDF_IMAGE_MASK_LOSSLESS_COMPRESS 0x0008 - -class CFX_DIBitmap; -class CFX_DIBSource; -class CPDF_Dictionay; -class CPDF_Document; -class CPDF_Page; -class IFX_FileRead; -class IFX_FileWrite; -class IFX_Pause; - -class CPDF_Image { - public: - explicit CPDF_Image(CPDF_Document* pDoc); - CPDF_Image(CPDF_Document* pDoc, CPDF_Stream* pStream, bool bInline); - ~CPDF_Image(); - - CPDF_Image* Clone(); - - CPDF_Dictionary* GetInlineDict() const { return m_pInlineDict; } - CPDF_Stream* GetStream() const { return m_pStream; } - CPDF_Dictionary* GetDict() const { - return m_pStream ? m_pStream->GetDict() : nullptr; - } - CPDF_Dictionary* GetOC() const { return m_pOC; } - CPDF_Document* GetDocument() const { return m_pDocument; } - - int32_t GetPixelHeight() const { return m_Height; } - int32_t GetPixelWidth() const { return m_Width; } - - bool IsInline() const { return m_bInline; } - bool IsMask() const { return m_bIsMask; } - bool IsInterpol() const { return m_bInterpolate; } - - CFX_DIBSource* LoadDIBSource(CFX_DIBSource** ppMask = nullptr, - uint32_t* pMatteColor = nullptr, - FX_BOOL bStdCS = FALSE, - uint32_t GroupFamily = 0, - FX_BOOL bLoadMask = FALSE) const; - - void SetInlineDict(CPDF_Dictionary* pDict) { m_pInlineDict = pDict; } - void SetImage(const CFX_DIBitmap* pDIBitmap, int32_t iCompress); - void SetJpegImage(IFX_FileRead* pFile); - - void ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pDIBitmap); - - FX_BOOL StartLoadDIBSource(CPDF_Dictionary* pFormResource, - CPDF_Dictionary* pPageResource, - FX_BOOL bStdCS = FALSE, - uint32_t GroupFamily = 0, - FX_BOOL bLoadMask = FALSE); - FX_BOOL Continue(IFX_Pause* pPause); - CFX_DIBSource* DetachBitmap(); - CFX_DIBSource* DetachMask(); - - CFX_DIBSource* m_pDIBSource; - CFX_DIBSource* m_pMask; - uint32_t m_MatteColor; - - private: - CPDF_Dictionary* InitJPEG(uint8_t* pData, uint32_t size); - - CPDF_Stream* m_pStream; - const bool m_bInline; - CPDF_Dictionary* m_pInlineDict; - int32_t m_Height; - int32_t m_Width; - bool m_bIsMask; - bool m_bInterpolate; - CPDF_Document* const m_pDocument; - CPDF_Dictionary* m_pOC; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_IMAGE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp b/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp deleted file mode 100644 index 74351b024d..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_imageobject.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" - -CPDF_ImageObject::CPDF_ImageObject() - : m_pImage(nullptr), m_pImageOwned(false) {} - -CPDF_ImageObject::~CPDF_ImageObject() { - Release(); -} - -CPDF_ImageObject* CPDF_ImageObject::Clone() const { - CPDF_ImageObject* obj = new CPDF_ImageObject; - obj->CopyData(this); - - obj->m_pImage = m_pImage->Clone(); - obj->m_Matrix = m_Matrix; - return obj; -} - -CPDF_PageObject::Type CPDF_ImageObject::GetType() const { - return IMAGE; -} - -void CPDF_ImageObject::Transform(const CFX_Matrix& matrix) { - m_Matrix.Concat(matrix); - CalcBoundingBox(); -} - -bool CPDF_ImageObject::IsImage() const { - return true; -} - -CPDF_ImageObject* CPDF_ImageObject::AsImage() { - return this; -} - -const CPDF_ImageObject* CPDF_ImageObject::AsImage() const { - return this; -} - -void CPDF_ImageObject::CalcBoundingBox() { - m_Left = m_Bottom = 0; - m_Right = m_Top = 1.0f; - m_Matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); -} - -void CPDF_ImageObject::SetOwnedImage(std::unique_ptr pImage) { - Release(); - m_pImage = pImage.release(); - m_pImageOwned = true; -} - -void CPDF_ImageObject::SetUnownedImage(CPDF_Image* pImage) { - Release(); - m_pImage = pImage; - m_pImageOwned = false; -} - -void CPDF_ImageObject::Release() { - if (m_pImageOwned) { - delete m_pImage; - m_pImage = nullptr; - m_pImageOwned = false; - return; - } - - if (!m_pImage) - return; - - CPDF_DocPageData* pPageData = m_pImage->GetDocument()->GetPageData(); - pPageData->ReleaseImage(m_pImage->GetStream()); - m_pImage = nullptr; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_imageobject.h b/core/fpdfapi/fpdf_page/cpdf_imageobject.h deleted file mode 100644 index e61dd5ac36..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_imageobject.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_IMAGEOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_IMAGEOBJECT_H_ - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fxcrt/fx_coordinates.h" - -class CPDF_Image; - -class CPDF_ImageObject : public CPDF_PageObject { - public: - CPDF_ImageObject(); - ~CPDF_ImageObject() override; - - // CPDF_PageObject - CPDF_ImageObject* Clone() const override; - Type GetType() const override; - void Transform(const CFX_Matrix& matrix) override; - bool IsImage() const override; - CPDF_ImageObject* AsImage() override; - const CPDF_ImageObject* AsImage() const override; - - void CalcBoundingBox(); - CPDF_Image* GetImage() const { return m_pImage; } - void SetOwnedImage(std::unique_ptr pImage); - void SetUnownedImage(CPDF_Image* pImage); - - CFX_Matrix m_Matrix; - - private: - void Release(); - - CPDF_Image* m_pImage; - bool m_pImageOwned; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_IMAGEOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp b/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp deleted file mode 100644 index 9e707365ec..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_meshstream.cpp +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" - -#include "core/fpdfapi/fpdf_page/cpdf_colorspace.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" - -namespace { - -// See PDF Reference 1.7, page 315, table 4.32. (Also table 4.33 and 4.34) -bool ShouldCheckBPC(ShadingType type) { - switch (type) { - case kFreeFormGouraudTriangleMeshShading: - case kLatticeFormGouraudTriangleMeshShading: - case kCoonsPatchMeshShading: - case kTensorProductPatchMeshShading: - return true; - default: - return false; - } -} - -// Same references as ShouldCheckBPC() above. -bool IsValidBitsPerComponent(uint32_t x) { - switch (x) { - case 1: - case 2: - case 4: - case 8: - case 12: - case 16: - return true; - default: - return false; - } -} - -// Same references as ShouldCheckBPC() above. -bool IsValidBitsPerCoordinate(uint32_t x) { - switch (x) { - case 1: - case 2: - case 4: - case 8: - case 12: - case 16: - case 24: - case 32: - return true; - default: - return false; - } -} - -// See PDF Reference 1.7, page 315, table 4.32. (Also table 4.34) -bool ShouldCheckBitsPerFlag(ShadingType type) { - switch (type) { - case kFreeFormGouraudTriangleMeshShading: - case kCoonsPatchMeshShading: - case kTensorProductPatchMeshShading: - return true; - default: - return false; - } -} - -// Same references as ShouldCheckBitsPerFlag() above. -bool IsValidBitsPerFlag(uint32_t x) { - switch (x) { - case 2: - case 4: - case 8: - return true; - default: - return false; - } -} - -} // namespace - -CPDF_MeshStream::CPDF_MeshStream( - ShadingType type, - const std::vector>& funcs, - CPDF_Stream* pShadingStream, - CPDF_ColorSpace* pCS) - : m_type(type), - m_funcs(funcs), - m_pShadingStream(pShadingStream), - m_pCS(pCS), - m_nCoordBits(0), - m_nComponentBits(0), - m_nFlagBits(0), - m_nComponents(0), - m_CoordMax(0), - m_ComponentMax(0), - m_xmin(0), - m_xmax(0), - m_ymin(0), - m_ymax(0) { - memset(&m_ColorMin, 0, sizeof(m_ColorMin)); - memset(&m_ColorMax, 0, sizeof(m_ColorMax)); -} - -bool CPDF_MeshStream::Load() { - m_Stream.LoadAllData(m_pShadingStream); - m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); - CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); - m_nCoordBits = pDict->GetIntegerFor("BitsPerCoordinate"); - m_nComponentBits = pDict->GetIntegerFor("BitsPerComponent"); - if (ShouldCheckBPC(m_type)) { - if (!IsValidBitsPerCoordinate(m_nCoordBits)) - return false; - if (!IsValidBitsPerComponent(m_nComponentBits)) - return false; - } - - m_nFlagBits = pDict->GetIntegerFor("BitsPerFlag"); - if (ShouldCheckBitsPerFlag(m_type) && !IsValidBitsPerFlag(m_nFlagBits)) - return false; - - uint32_t nComponents = m_pCS->CountComponents(); - if (nComponents > kMaxComponents) - return false; - - m_nComponents = m_funcs.empty() ? nComponents : 1; - CPDF_Array* pDecode = pDict->GetArrayFor("Decode"); - if (!pDecode || pDecode->GetCount() != 4 + m_nComponents * 2) - return false; - - m_xmin = pDecode->GetNumberAt(0); - m_xmax = pDecode->GetNumberAt(1); - m_ymin = pDecode->GetNumberAt(2); - m_ymax = pDecode->GetNumberAt(3); - for (uint32_t i = 0; i < m_nComponents; ++i) { - m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4); - m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5); - } - - if (ShouldCheckBPC(m_type)) { - m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; - m_ComponentMax = (1 << m_nComponentBits) - 1; - } - return true; -} - -uint32_t CPDF_MeshStream::GetFlag() { - ASSERT(ShouldCheckBitsPerFlag(m_type)); - return m_BitStream.GetBits(m_nFlagBits) & 0x03; -} - -void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { - ASSERT(ShouldCheckBPC(m_type)); - if (m_nCoordBits == 32) { - x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * - (m_xmax - m_xmin) / (double)m_CoordMax); - y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * - (m_ymax - m_ymin) / (double)m_CoordMax); - } else { - x = m_xmin + - m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; - y = m_ymin + - m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; - } -} - -void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { - ASSERT(ShouldCheckBPC(m_type)); - FX_FLOAT color_value[kMaxComponents]; - for (uint32_t i = 0; i < m_nComponents; ++i) { - color_value[i] = m_ColorMin[i] + - m_BitStream.GetBits(m_nComponentBits) * - (m_ColorMax[i] - m_ColorMin[i]) / m_ComponentMax; - } - if (m_funcs.empty()) { - m_pCS->GetRGB(color_value, r, g, b); - return; - } - - FX_FLOAT result[kMaxComponents]; - FXSYS_memset(result, 0, sizeof(result)); - int nResults; - for (const auto& func : m_funcs) { - if (func && func->CountOutputs() <= kMaxComponents) - func->Call(color_value, 1, result, nResults); - } - m_pCS->GetRGB(result, r, g, b); -} - -uint32_t CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex, - CFX_Matrix* pObject2Bitmap) { - uint32_t flag = GetFlag(); - GetCoords(vertex.x, vertex.y); - pObject2Bitmap->Transform(vertex.x, vertex.y); - GetColor(vertex.r, vertex.g, vertex.b); - m_BitStream.ByteAlign(); - return flag; -} - -FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, - int count, - CFX_Matrix* pObject2Bitmap) { - for (int i = 0; i < count; i++) { - if (m_BitStream.IsEOF()) - return FALSE; - - GetCoords(vertex[i].x, vertex[i].y); - pObject2Bitmap->Transform(vertex[i].x, vertex[i].y); - GetColor(vertex[i].r, vertex[i].g, vertex[i].b); - m_BitStream.ByteAlign(); - } - return TRUE; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_meshstream.h b/core/fpdfapi/fpdf_page/cpdf_meshstream.h deleted file mode 100644 index 5930cf9833..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_meshstream.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_MESHSTREAM_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_MESHSTREAM_H_ - -#include -#include - -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fxcrt/fx_basic.h" -#include "core/fxcrt/fx_system.h" - -struct CPDF_MeshVertex { - FX_FLOAT x; - FX_FLOAT y; - FX_FLOAT r; - FX_FLOAT g; - FX_FLOAT b; -}; - -class CFX_Matrix; -class CPDF_ColorSpace; -class CPDF_Function; -class CPDF_Stream; - -class CPDF_MeshStream { - public: - CPDF_MeshStream(ShadingType type, - const std::vector>& funcs, - CPDF_Stream* pShadingStream, - CPDF_ColorSpace* pCS); - - bool Load(); - - uint32_t GetFlag(); - void GetCoords(FX_FLOAT& x, FX_FLOAT& y); - void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b); - - uint32_t GetVertex(CPDF_MeshVertex& vertex, CFX_Matrix* pObject2Bitmap); - FX_BOOL GetVertexRow(CPDF_MeshVertex* vertex, - int count, - CFX_Matrix* pObject2Bitmap); - - CFX_BitStream* BitStream() { return &m_BitStream; } - uint32_t ComponentBits() const { return m_nComponentBits; } - uint32_t Components() const { return m_nComponents; } - - private: - static const uint32_t kMaxComponents = 8; - - const ShadingType m_type; - const std::vector>& m_funcs; - CPDF_Stream* const m_pShadingStream; - CPDF_ColorSpace* const m_pCS; - uint32_t m_nCoordBits; - uint32_t m_nComponentBits; - uint32_t m_nFlagBits; - uint32_t m_nComponents; - uint32_t m_CoordMax; - uint32_t m_ComponentMax; - FX_FLOAT m_xmin; - FX_FLOAT m_xmax; - FX_FLOAT m_ymin; - FX_FLOAT m_ymax; - FX_FLOAT m_ColorMin[kMaxComponents]; - FX_FLOAT m_ColorMax[kMaxComponents]; - CPDF_StreamAcc m_Stream; - CFX_BitStream m_BitStream; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_MESHSTREAM_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_page.cpp b/core/fpdfapi/fpdf_page/cpdf_page.cpp deleted file mode 100644 index 7c4b2bb203..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_page.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_page.h" - -#include - -#include "core/fpdfapi/cpdf_pagerendercontext.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_object.h" -#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" -#include "third_party/base/stl_util.h" - -CPDF_Page::CPDF_Page(CPDF_Document* pDocument, - CPDF_Dictionary* pPageDict, - bool bPageCache) - : m_PageWidth(100), - m_PageHeight(100), - m_pView(nullptr), - m_pPageRender(bPageCache ? new CPDF_PageRenderCache(this) : nullptr) { - m_pFormDict = pPageDict; - m_pDocument = pDocument; - if (!pPageDict) - return; - - CPDF_Object* pageAttr = GetPageAttr("Resources"); - m_pResources = pageAttr ? pageAttr->GetDict() : nullptr; - m_pPageResources = m_pResources; - CPDF_Object* pRotate = GetPageAttr("Rotate"); - int rotate = pRotate ? pRotate->GetInteger() / 90 % 4 : 0; - if (rotate < 0) - rotate += 4; - - CPDF_Array* pMediaBox = ToArray(GetPageAttr("MediaBox")); - CFX_FloatRect mediabox; - if (pMediaBox) { - mediabox = pMediaBox->GetRect(); - mediabox.Normalize(); - } - if (mediabox.IsEmpty()) - mediabox = CFX_FloatRect(0, 0, 612, 792); - - CPDF_Array* pCropBox = ToArray(GetPageAttr("CropBox")); - if (pCropBox) { - m_BBox = pCropBox->GetRect(); - m_BBox.Normalize(); - } - if (m_BBox.IsEmpty()) - m_BBox = mediabox; - else - m_BBox.Intersect(mediabox); - - m_PageWidth = m_BBox.right - m_BBox.left; - m_PageHeight = m_BBox.top - m_BBox.bottom; - if (rotate % 2) - std::swap(m_PageWidth, m_PageHeight); - - switch (rotate) { - case 0: - m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); - break; - case 1: - m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); - break; - case 2: - m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); - break; - case 3: - m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); - break; - } - - m_Transparency = PDFTRANS_ISOLATED; - LoadTransInfo(); -} - -CPDF_Page::~CPDF_Page() {} - -void CPDF_Page::StartParse() { - if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) - return; - - m_pParser.reset(new CPDF_ContentParser); - m_pParser->Start(this); - m_ParseState = CONTENT_PARSING; -} - -void CPDF_Page::ParseContent() { - StartParse(); - ContinueParse(nullptr); -} - -void CPDF_Page::SetRenderContext( - std::unique_ptr pContext) { - m_pRenderContext = std::move(pContext); -} - -CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteString& name) const { - CPDF_Dictionary* pPageDict = m_pFormDict; - std::set visited; - while (1) { - visited.insert(pPageDict); - if (CPDF_Object* pObj = pPageDict->GetDirectObjectFor(name)) - return pObj; - - pPageDict = pPageDict->GetDictFor("Parent"); - if (!pPageDict || pdfium::ContainsKey(visited, pPageDict)) - break; - } - return nullptr; -} - -void CPDF_Page::GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const { - if (m_PageWidth == 0 || m_PageHeight == 0) { - return; - } - CFX_Matrix display_matrix; - int x0 = 0; - int y0 = 0; - int x1 = 0; - int y1 = 0; - int x2 = 0; - int y2 = 0; - iRotate %= 4; - switch (iRotate) { - case 0: - x0 = xPos; - y0 = yPos + ySize; - x1 = xPos; - y1 = yPos; - x2 = xPos + xSize; - y2 = yPos + ySize; - break; - case 1: - x0 = xPos; - y0 = yPos; - x1 = xPos + xSize; - y1 = yPos; - x2 = xPos; - y2 = yPos + ySize; - break; - case 2: - x0 = xPos + xSize; - y0 = yPos; - x1 = xPos + xSize; - y1 = yPos + ySize; - x2 = xPos; - y2 = yPos; - break; - case 3: - x0 = xPos + xSize; - y0 = yPos + ySize; - x1 = xPos; - y1 = yPos + ySize; - x2 = xPos + xSize; - y2 = yPos; - break; - } - display_matrix.Set( - ((FX_FLOAT)(x2 - x0)) / m_PageWidth, ((FX_FLOAT)(y2 - y0)) / m_PageWidth, - ((FX_FLOAT)(x1 - x0)) / m_PageHeight, - ((FX_FLOAT)(y1 - y0)) / m_PageHeight, (FX_FLOAT)x0, (FX_FLOAT)y0); - matrix = m_PageMatrix; - matrix.Concat(display_matrix); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_page.h b/core/fpdfapi/fpdf_page/cpdf_page.h deleted file mode 100644 index 13f51986a2..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_page.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGE_H_ - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h" -#include "core/fxcrt/fx_basic.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Dictionary; -class CPDF_Document; -class CPDF_Object; -class CPDF_PageRenderCache; -class CPDF_PageRenderContext; - -class CPDF_Page : public CPDF_PageObjectHolder { - public: - class View {}; // Caller implements as desired, empty here due to layering. - - CPDF_Page(CPDF_Document* pDocument, - CPDF_Dictionary* pPageDict, - bool bPageCache); - ~CPDF_Page() override; - - void ParseContent(); - - void GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const; - - FX_FLOAT GetPageWidth() const { return m_PageWidth; } - FX_FLOAT GetPageHeight() const { return m_PageHeight; } - CFX_FloatRect GetPageBBox() const { return m_BBox; } - const CFX_Matrix& GetPageMatrix() const { return m_PageMatrix; } - CPDF_Object* GetPageAttr(const CFX_ByteString& name) const; - CPDF_PageRenderCache* GetRenderCache() const { return m_pPageRender.get(); } - - CPDF_PageRenderContext* GetRenderContext() const { - return m_pRenderContext.get(); - } - void SetRenderContext(std::unique_ptr pContext); - - View* GetView() const { return m_pView; } - void SetView(View* pView) { m_pView = pView; } - - protected: - friend class CPDF_ContentParser; - - void StartParse(); - - FX_FLOAT m_PageWidth; - FX_FLOAT m_PageHeight; - CFX_Matrix m_PageMatrix; - View* m_pView; - std::unique_ptr m_pPageRender; - std::unique_ptr m_pRenderContext; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pagemodule.cpp b/core/fpdfapi/fpdf_page/cpdf_pagemodule.cpp deleted file mode 100644 index c22c8fbc46..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pagemodule.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" - -CPDF_PageModule::CPDF_PageModule() - : m_StockGrayCS(nullptr, PDFCS_DEVICEGRAY), - m_StockRGBCS(nullptr, PDFCS_DEVICERGB), - m_StockCMYKCS(nullptr, PDFCS_DEVICECMYK), - m_StockPatternCS(nullptr) {} - -CPDF_PageModule::~CPDF_PageModule() {} - -CPDF_FontGlobals* CPDF_PageModule::GetFontGlobals() { - return &m_FontGlobals; -} - -CPDF_ColorSpace* CPDF_PageModule::GetStockCS(int family) { - if (family == PDFCS_DEVICEGRAY) - return &m_StockGrayCS; - if (family == PDFCS_DEVICERGB) - return &m_StockRGBCS; - if (family == PDFCS_DEVICECMYK) - return &m_StockCMYKCS; - if (family == PDFCS_PATTERN) - return &m_StockPatternCS; - return nullptr; -} - -void CPDF_PageModule::ClearStockFont(CPDF_Document* pDoc) { - m_FontGlobals.Clear(pDoc); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_pagemodule.h b/core/fpdfapi/fpdf_page/cpdf_pagemodule.h deleted file mode 100644 index 35316cd0bf..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pagemodule.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEMODULE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEMODULE_H_ - -#include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_colorspace.h" -#include "core/fpdfapi/fpdf_page/pageint.h" - -class CPDF_Document; - -class CPDF_PageModule { - public: - CPDF_PageModule(); - ~CPDF_PageModule(); - - CPDF_FontGlobals* GetFontGlobals(); - CPDF_ColorSpace* GetStockCS(int family); - void ClearStockFont(CPDF_Document* pDoc); - - private: - CPDF_FontGlobals m_FontGlobals; - CPDF_DeviceCS m_StockGrayCS; - CPDF_DeviceCS m_StockRGBCS; - CPDF_DeviceCS m_StockCMYKCS; - CPDF_PatternCS m_StockPatternCS; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEMODULE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobject.cpp b/core/fpdfapi/fpdf_page/cpdf_pageobject.cpp deleted file mode 100644 index 4015587304..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pageobject.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" - -CPDF_PageObject::CPDF_PageObject() {} - -CPDF_PageObject::~CPDF_PageObject() {} - -bool CPDF_PageObject::IsText() const { - return false; -} - -bool CPDF_PageObject::IsPath() const { - return false; -} - -bool CPDF_PageObject::IsImage() const { - return false; -} - -bool CPDF_PageObject::IsShading() const { - return false; -} - -bool CPDF_PageObject::IsForm() const { - return false; -} - -CPDF_TextObject* CPDF_PageObject::AsText() { - return nullptr; -} - -const CPDF_TextObject* CPDF_PageObject::AsText() const { - return nullptr; -} - -CPDF_PathObject* CPDF_PageObject::AsPath() { - return nullptr; -} - -const CPDF_PathObject* CPDF_PageObject::AsPath() const { - return nullptr; -} - -CPDF_ImageObject* CPDF_PageObject::AsImage() { - return nullptr; -} - -const CPDF_ImageObject* CPDF_PageObject::AsImage() const { - return nullptr; -} - -CPDF_ShadingObject* CPDF_PageObject::AsShading() { - return nullptr; -} - -const CPDF_ShadingObject* CPDF_PageObject::AsShading() const { - return nullptr; -} - -CPDF_FormObject* CPDF_PageObject::AsForm() { - return nullptr; -} - -const CPDF_FormObject* CPDF_PageObject::AsForm() const { - return nullptr; -} - -void CPDF_PageObject::CopyData(const CPDF_PageObject* pSrc) { - CopyStates(*pSrc); - m_Left = pSrc->m_Left; - m_Right = pSrc->m_Right; - m_Top = pSrc->m_Top; - m_Bottom = pSrc->m_Bottom; -} - -void CPDF_PageObject::TransformClipPath(CFX_Matrix& matrix) { - if (!m_ClipPath) - return; - m_ClipPath.Transform(matrix); -} - -void CPDF_PageObject::TransformGeneralState(CFX_Matrix& matrix) { - if (!m_GeneralState) - return; - m_GeneralState.GetMutableMatrix()->Concat(matrix); -} - -FX_RECT CPDF_PageObject::GetBBox(const CFX_Matrix* pMatrix) const { - CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top); - if (pMatrix) { - pMatrix->TransformRect(rect); - } - return rect.GetOuterRect(); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobject.h b/core/fpdfapi/fpdf_page/cpdf_pageobject.h deleted file mode 100644 index 359bc2bdb4..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pageobject.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECT_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_contentmark.h" -#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_TextObject; -class CPDF_PathObject; -class CPDF_ImageObject; -class CPDF_ShadingObject; -class CPDF_FormObject; - -class CPDF_PageObject : public CPDF_GraphicStates { - public: - enum Type { - TEXT = 1, - PATH, - IMAGE, - SHADING, - FORM, - }; - - CPDF_PageObject(); - ~CPDF_PageObject() override; - - virtual CPDF_PageObject* Clone() const = 0; - virtual Type GetType() const = 0; - virtual void Transform(const CFX_Matrix& matrix) = 0; - virtual bool IsText() const; - virtual bool IsPath() const; - virtual bool IsImage() const; - virtual bool IsShading() const; - virtual bool IsForm() const; - virtual CPDF_TextObject* AsText(); - virtual const CPDF_TextObject* AsText() const; - virtual CPDF_PathObject* AsPath(); - virtual const CPDF_PathObject* AsPath() const; - virtual CPDF_ImageObject* AsImage(); - virtual const CPDF_ImageObject* AsImage() const; - virtual CPDF_ShadingObject* AsShading(); - virtual const CPDF_ShadingObject* AsShading() const; - virtual CPDF_FormObject* AsForm(); - virtual const CPDF_FormObject* AsForm() const; - - void TransformClipPath(CFX_Matrix& matrix); - void TransformGeneralState(CFX_Matrix& matrix); - FX_RECT GetBBox(const CFX_Matrix* pMatrix) const; - - FX_FLOAT m_Left; - FX_FLOAT m_Right; - FX_FLOAT m_Top; - FX_FLOAT m_Bottom; - CPDF_ContentMark m_ContentMark; - - protected: - void CopyData(const CPDF_PageObject* pSrcObject); - - private: - CPDF_PageObject(const CPDF_PageObject& src) = delete; - void operator=(const CPDF_PageObject& src) = delete; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp b/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp deleted file mode 100644 index fd92e598cd..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h" - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" - -CPDF_PageObjectHolder::CPDF_PageObjectHolder() - : m_pFormDict(nullptr), - m_pFormStream(nullptr), - m_pDocument(nullptr), - m_pPageResources(nullptr), - m_pResources(nullptr), - m_Transparency(0), - m_bBackgroundAlphaNeeded(FALSE), - m_bHasImageMask(FALSE), - m_ParseState(CONTENT_NOT_PARSED) {} - -CPDF_PageObjectHolder::~CPDF_PageObjectHolder() {} - -void CPDF_PageObjectHolder::ContinueParse(IFX_Pause* pPause) { - if (!m_pParser) { - return; - } - m_pParser->Continue(pPause); - if (m_pParser->GetStatus() == CPDF_ContentParser::Done) { - m_ParseState = CONTENT_PARSED; - m_pParser.reset(); - } -} - -void CPDF_PageObjectHolder::Transform(const CFX_Matrix& matrix) { - for (auto& pObj : m_PageObjectList) - pObj->Transform(matrix); -} - -CFX_FloatRect CPDF_PageObjectHolder::CalcBoundingBox() const { - if (m_PageObjectList.empty()) - return CFX_FloatRect(0, 0, 0, 0); - - FX_FLOAT left = 1000000.0f; - FX_FLOAT right = -1000000.0f; - FX_FLOAT bottom = 1000000.0f; - FX_FLOAT top = -1000000.0f; - for (const auto& pObj : m_PageObjectList) { - left = std::min(left, pObj->m_Left); - right = std::max(right, pObj->m_Right); - bottom = std::min(bottom, pObj->m_Bottom); - top = std::max(top, pObj->m_Top); - } - return CFX_FloatRect(left, bottom, right, top); -} - -void CPDF_PageObjectHolder::LoadTransInfo() { - if (!m_pFormDict) { - return; - } - CPDF_Dictionary* pGroup = m_pFormDict->GetDictFor("Group"); - if (!pGroup) { - return; - } - if (pGroup->GetStringFor("S") != "Transparency") { - return; - } - m_Transparency |= PDFTRANS_GROUP; - if (pGroup->GetIntegerFor("I")) { - m_Transparency |= PDFTRANS_ISOLATED; - } - if (pGroup->GetIntegerFor("K")) { - m_Transparency |= PDFTRANS_KNOCKOUT; - } -} diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h b/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h deleted file mode 100644 index a8845552f7..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECTHOLDER_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECTHOLDER_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class IFX_Pause; -class CPDF_Dictionary; -class CPDF_Stream; -class CPDF_Document; -class CPDF_ContentParser; - -#define PDFTRANS_GROUP 0x0100 -#define PDFTRANS_ISOLATED 0x0200 -#define PDFTRANS_KNOCKOUT 0x0400 - -class CPDF_PageObjectHolder { - public: - CPDF_PageObjectHolder(); - virtual ~CPDF_PageObjectHolder(); - - void ContinueParse(IFX_Pause* pPause); - bool IsParsed() const { return m_ParseState == CONTENT_PARSED; } - - CPDF_PageObjectList* GetPageObjectList() { return &m_PageObjectList; } - const CPDF_PageObjectList* GetPageObjectList() const { - return &m_PageObjectList; - } - - FX_BOOL BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; } - void SetBackgroundAlphaNeeded(FX_BOOL needed) { - m_bBackgroundAlphaNeeded = needed; - } - - FX_BOOL HasImageMask() const { return m_bHasImageMask; } - void SetHasImageMask(FX_BOOL value) { m_bHasImageMask = value; } - - void Transform(const CFX_Matrix& matrix); - CFX_FloatRect CalcBoundingBox() const; - - CPDF_Dictionary* m_pFormDict; - CPDF_Stream* m_pFormStream; - CPDF_Document* m_pDocument; - CPDF_Dictionary* m_pPageResources; - CPDF_Dictionary* m_pResources; - CFX_FloatRect m_BBox; - int m_Transparency; - - protected: - enum ParseState { CONTENT_NOT_PARSED, CONTENT_PARSING, CONTENT_PARSED }; - - void LoadTransInfo(); - - FX_BOOL m_bBackgroundAlphaNeeded; - FX_BOOL m_bHasImageMask; - ParseState m_ParseState; - std::unique_ptr m_pParser; - CPDF_PageObjectList m_PageObjectList; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECTHOLDER_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobjectlist.cpp b/core/fpdfapi/fpdf_page/cpdf_pageobjectlist.cpp deleted file mode 100644 index e433431551..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pageobjectlist.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h" - -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "third_party/base/stl_util.h" - -CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) { - if (index < 0 || index >= pdfium::CollectionSize(*this)) - return nullptr; - return (*this)[index].get(); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h b/core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h deleted file mode 100644 index 360bb26e8b..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECTLIST_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECTLIST_H_ - -#include -#include - -class CPDF_PageObject; - -class CPDF_PageObjectList - : public std::deque> { - public: - CPDF_PageObject* GetPageObjectByIndex(int index); -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PAGEOBJECTLIST_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_path.cpp b/core/fpdfapi/fpdf_page/cpdf_path.cpp deleted file mode 100644 index 2c80cc3d12..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_path.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_path.h" - -CPDF_Path::CPDF_Path() {} - -CPDF_Path::CPDF_Path(const CPDF_Path& that) : m_Ref(that.m_Ref) {} - -CPDF_Path::~CPDF_Path() {} - -int CPDF_Path::GetPointCount() const { - return m_Ref.GetObject()->GetPointCount(); -} - -void CPDF_Path::SetPointCount(int count) { - m_Ref.GetPrivateCopy()->SetPointCount(count); -} - -const FX_PATHPOINT* CPDF_Path::GetPoints() const { - return m_Ref.GetObject()->GetPoints(); -} - -FX_PATHPOINT* CPDF_Path::GetMutablePoints() { - return m_Ref.GetPrivateCopy()->GetPoints(); -} - -int CPDF_Path::GetFlag(int index) const { - return m_Ref.GetObject()->GetFlag(index); -} - -FX_FLOAT CPDF_Path::GetPointX(int index) const { - return m_Ref.GetObject()->GetPointX(index); -} - -FX_FLOAT CPDF_Path::GetPointY(int index) const { - return m_Ref.GetObject()->GetPointY(index); -} - -CFX_FloatRect CPDF_Path::GetBoundingBox() const { - return m_Ref.GetObject()->GetBoundingBox(); -} - -CFX_FloatRect CPDF_Path::GetBoundingBox(FX_FLOAT line_width, - FX_FLOAT miter_limit) const { - return m_Ref.GetObject()->GetBoundingBox(line_width, miter_limit); -} - -FX_BOOL CPDF_Path::IsRect() const { - return m_Ref.GetObject()->IsRect(); -} - -void CPDF_Path::Transform(const CFX_Matrix* pMatrix) { - m_Ref.GetPrivateCopy()->Transform(pMatrix); -} - -void CPDF_Path::Append(const CPDF_Path& other, const CFX_Matrix* pMatrix) { - m_Ref.GetPrivateCopy()->Append(other.GetObject(), pMatrix); -} - -void CPDF_Path::Append(const CFX_PathData* pData, const CFX_Matrix* pMatrix) { - m_Ref.GetPrivateCopy()->Append(pData, pMatrix); -} - -void CPDF_Path::AppendRect(FX_FLOAT left, - FX_FLOAT bottom, - FX_FLOAT right, - FX_FLOAT top) { - m_Ref.GetPrivateCopy()->AppendRect(left, bottom, right, top); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_path.h b/core/fpdfapi/fpdf_page/cpdf_path.h deleted file mode 100644 index 3f77b05d5b..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_path.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PATH_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PATH_H_ - -#include "core/fxcrt/cfx_count_ref.h" -#include "core/fxcrt/fx_system.h" -#include "core/fxge/cfx_fxgedevice.h" -#include "core/fxge/cfx_pathdata.h" -#include "core/fxge/cfx_renderdevice.h" - -class CPDF_Path { - public: - CPDF_Path(); - CPDF_Path(const CPDF_Path& that); - ~CPDF_Path(); - - void Emplace() { m_Ref.Emplace(); } - explicit operator bool() const { return !!m_Ref; } - - int GetPointCount() const; - void SetPointCount(int count); - const FX_PATHPOINT* GetPoints() const; - FX_PATHPOINT* GetMutablePoints(); - - int GetFlag(int index) const; - FX_FLOAT GetPointX(int index) const; - FX_FLOAT GetPointY(int index) const; - CFX_FloatRect GetBoundingBox() const; - CFX_FloatRect GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const; - - FX_BOOL IsRect() const; - void Transform(const CFX_Matrix* pMatrix); - - void Append(const CPDF_Path& other, const CFX_Matrix* pMatrix); - void Append(const CFX_PathData* pData, const CFX_Matrix* pMatrix); - void AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top); - - // TODO(tsepez): Remove when all access thru this class. - const CFX_PathData* GetObject() const { return m_Ref.GetObject(); } - - private: - CFX_CountRef m_Ref; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PATH_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp b/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp deleted file mode 100644 index 94385de6e0..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pathobject.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_pathobject.h" - -CPDF_PathObject::CPDF_PathObject() {} - -CPDF_PathObject::~CPDF_PathObject() {} - -CPDF_PathObject* CPDF_PathObject::Clone() const { - CPDF_PathObject* obj = new CPDF_PathObject; - obj->CopyData(this); - - obj->m_Path = m_Path; - obj->m_FillType = m_FillType; - obj->m_bStroke = m_bStroke; - obj->m_Matrix = m_Matrix; - return obj; -} - -CPDF_PageObject::Type CPDF_PathObject::GetType() const { - return PATH; -} - -void CPDF_PathObject::Transform(const CFX_Matrix& matrix) { - m_Matrix.Concat(matrix); - CalcBoundingBox(); -} - -bool CPDF_PathObject::IsPath() const { - return true; -} - -CPDF_PathObject* CPDF_PathObject::AsPath() { - return this; -} - -const CPDF_PathObject* CPDF_PathObject::AsPath() const { - return this; -} - -void CPDF_PathObject::CalcBoundingBox() { - if (!m_Path) - return; - CFX_FloatRect rect; - FX_FLOAT width = m_GraphState.GetLineWidth(); - if (m_bStroke && width != 0) { - rect = m_Path.GetBoundingBox(width, m_GraphState.GetMiterLimit()); - } else { - rect = m_Path.GetBoundingBox(); - } - rect.Transform(&m_Matrix); - if (width == 0 && m_bStroke) { - rect.left += -0.5f; - rect.right += 0.5f; - rect.bottom += -0.5f; - rect.top += 0.5f; - } - m_Left = rect.left; - m_Right = rect.right; - m_Top = rect.top; - m_Bottom = rect.bottom; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_pathobject.h b/core/fpdfapi/fpdf_page/cpdf_pathobject.h deleted file mode 100644 index ee40322076..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pathobject.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PATHOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PATHOBJECT_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_path.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_PathObject : public CPDF_PageObject { - public: - CPDF_PathObject(); - ~CPDF_PathObject() override; - - // CPDF_PageObject - CPDF_PathObject* Clone() const override; - Type GetType() const override; - void Transform(const CFX_Matrix& maxtrix) override; - bool IsPath() const override; - CPDF_PathObject* AsPath() override; - const CPDF_PathObject* AsPath() const override; - - void CalcBoundingBox(); - - CPDF_Path m_Path; - int m_FillType; - FX_BOOL m_bStroke; - CFX_Matrix m_Matrix; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PATHOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_pattern.cpp b/core/fpdfapi/fpdf_page/cpdf_pattern.cpp deleted file mode 100644 index f8bc9a555f..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pattern.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_pattern.h" - -CPDF_Pattern::CPDF_Pattern(PatternType type, - CPDF_Document* pDoc, - CPDF_Object* pObj, - const CFX_Matrix& parentMatrix) - : m_PatternType(type), - m_pDocument(pDoc), - m_pPatternObj(pObj), - m_ParentMatrix(parentMatrix) {} - -CPDF_Pattern::~CPDF_Pattern() {} diff --git a/core/fpdfapi/fpdf_page/cpdf_pattern.h b/core/fpdfapi/fpdf_page/cpdf_pattern.h deleted file mode 100644 index 52be26a823..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_pattern.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PATTERN_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PATTERN_H_ - -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Document; -class CPDF_Object; -class CPDF_ShadingPattern; -class CPDF_TilingPattern; - -class CPDF_Pattern { - public: - enum PatternType { TILING = 1, SHADING }; - - virtual ~CPDF_Pattern(); - - virtual CPDF_TilingPattern* AsTilingPattern() = 0; - virtual CPDF_ShadingPattern* AsShadingPattern() = 0; - - CPDF_Document* document() { return m_pDocument; } - CPDF_Object* pattern_obj() { return m_pPatternObj; } - CFX_Matrix* pattern_to_form() { return &m_Pattern2Form; } - const CFX_Matrix& parent_matrix() const { return m_ParentMatrix; } - - protected: - CPDF_Pattern(PatternType type, - CPDF_Document* pDoc, - CPDF_Object* pObj, - const CFX_Matrix& parentMatrix); - - const PatternType m_PatternType; - CPDF_Document* const m_pDocument; - CPDF_Object* const m_pPatternObj; - CFX_Matrix m_Pattern2Form; - const CFX_Matrix m_ParentMatrix; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PATTERN_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_psengine.h b/core/fpdfapi/fpdf_page/cpdf_psengine.h deleted file mode 100644 index 81e3204fc3..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_psengine.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PSENGINE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PSENGINE_H_ - -#include -#include - -#include "core/fxcrt/fx_system.h" - -class CPDF_PSEngine; -class CPDF_PSOP; -class CPDF_SimpleParser; - -enum PDF_PSOP { - PSOP_ADD, - PSOP_SUB, - PSOP_MUL, - PSOP_DIV, - PSOP_IDIV, - PSOP_MOD, - PSOP_NEG, - PSOP_ABS, - PSOP_CEILING, - PSOP_FLOOR, - PSOP_ROUND, - PSOP_TRUNCATE, - PSOP_SQRT, - PSOP_SIN, - PSOP_COS, - PSOP_ATAN, - PSOP_EXP, - PSOP_LN, - PSOP_LOG, - PSOP_CVI, - PSOP_CVR, - PSOP_EQ, - PSOP_NE, - PSOP_GT, - PSOP_GE, - PSOP_LT, - PSOP_LE, - PSOP_AND, - PSOP_OR, - PSOP_XOR, - PSOP_NOT, - PSOP_BITSHIFT, - PSOP_TRUE, - PSOP_FALSE, - PSOP_IF, - PSOP_IFELSE, - PSOP_POP, - PSOP_EXCH, - PSOP_DUP, - PSOP_COPY, - PSOP_INDEX, - PSOP_ROLL, - PSOP_PROC, - PSOP_CONST -}; - -constexpr uint32_t PSENGINE_STACKSIZE = 100; - -class CPDF_PSProc { - public: - CPDF_PSProc(); - ~CPDF_PSProc(); - - FX_BOOL Parse(CPDF_SimpleParser* parser, int depth); - FX_BOOL Execute(CPDF_PSEngine* pEngine); - - private: - static const int kMaxDepth = 128; - std::vector> m_Operators; -}; - -class CPDF_PSEngine { - public: - CPDF_PSEngine(); - ~CPDF_PSEngine(); - - FX_BOOL Parse(const FX_CHAR* str, int size); - FX_BOOL Execute(); - FX_BOOL DoOperator(PDF_PSOP op); - void Reset() { m_StackCount = 0; } - void Push(FX_FLOAT value); - void Push(int value) { Push((FX_FLOAT)value); } - FX_FLOAT Pop(); - uint32_t GetStackSize() const { return m_StackCount; } - - private: - FX_FLOAT m_Stack[PSENGINE_STACKSIZE]; - uint32_t m_StackCount; - CPDF_PSProc m_MainProc; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PSENGINE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp b/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp deleted file mode 100644 index 49d0f60353..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_shadingobject.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_shadingobject.h" - -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" - -CPDF_ShadingObject::CPDF_ShadingObject() : m_pShading(nullptr) {} - -CPDF_ShadingObject::~CPDF_ShadingObject() {} - -CPDF_ShadingObject* CPDF_ShadingObject::Clone() const { - CPDF_ShadingObject* obj = new CPDF_ShadingObject; - obj->CopyData(this); - - obj->m_pShading = m_pShading; - if (obj->m_pShading && obj->m_pShading->document()) { - CPDF_DocPageData* pDocPageData = obj->m_pShading->document()->GetPageData(); - CPDF_Pattern* pattern = pDocPageData->GetPattern( - obj->m_pShading->GetShadingObject(), m_pShading->IsShadingObject(), - obj->m_pShading->parent_matrix()); - obj->m_pShading = pattern ? pattern->AsShadingPattern() : nullptr; - } - obj->m_Matrix = m_Matrix; - return obj; -} - -CPDF_PageObject::Type CPDF_ShadingObject::GetType() const { - return SHADING; -} - -void CPDF_ShadingObject::Transform(const CFX_Matrix& matrix) { - if (m_ClipPath) - m_ClipPath.Transform(matrix); - - m_Matrix.Concat(matrix); - if (m_ClipPath) { - CalcBoundingBox(); - } else { - matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); - } -} - -bool CPDF_ShadingObject::IsShading() const { - return true; -} - -CPDF_ShadingObject* CPDF_ShadingObject::AsShading() { - return this; -} - -const CPDF_ShadingObject* CPDF_ShadingObject::AsShading() const { - return this; -} - -void CPDF_ShadingObject::CalcBoundingBox() { - if (!m_ClipPath) - return; - CFX_FloatRect rect = m_ClipPath.GetClipBox(); - m_Left = rect.left; - m_Bottom = rect.bottom; - m_Right = rect.right; - m_Top = rect.top; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingobject.h b/core/fpdfapi/fpdf_page/cpdf_shadingobject.h deleted file mode 100644 index ff5e3f52dd..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_shadingobject.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGOBJECT_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fxcrt/fx_coordinates.h" - -class CPDF_ShadingPattern; - -class CPDF_ShadingObject : public CPDF_PageObject { - public: - CPDF_ShadingObject(); - ~CPDF_ShadingObject() override; - - // CPDF_PageObject - CPDF_ShadingObject* Clone() const override; - Type GetType() const override; - void Transform(const CFX_Matrix& matrix) override; - bool IsShading() const override; - CPDF_ShadingObject* AsShading() override; - const CPDF_ShadingObject* AsShading() const override; - - void CalcBoundingBox(); - - CPDF_ShadingPattern* m_pShading; - CFX_Matrix m_Matrix; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp b/core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp deleted file mode 100644 index 8b74d1275e..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_shadingpattern.cpp +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" - -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_object.h" - -namespace { - -ShadingType ToShadingType(int type) { - return (type > static_cast(kInvalidShading) && - type < static_cast(kMaxShading)) - ? static_cast(type) - : kInvalidShading; -} - -} // namespace - -CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, - CPDF_Object* pPatternObj, - FX_BOOL bShading, - const CFX_Matrix& parentMatrix) - : CPDF_Pattern(SHADING, - pDoc, - bShading ? nullptr : pPatternObj, - parentMatrix), - m_ShadingType(kInvalidShading), - m_bShadingObj(bShading), - m_pShadingObj(pPatternObj), - m_pCS(nullptr), - m_pCountedCS(nullptr) { - if (!bShading) { - CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); - m_Pattern2Form = pDict->GetMatrixFor("Matrix"); - m_pShadingObj = pDict->GetDirectObjectFor("Shading"); - m_Pattern2Form.Concat(parentMatrix); - } -} - -CPDF_ShadingPattern::~CPDF_ShadingPattern() { - CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->get() : nullptr; - if (pCS && m_pDocument) - m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); -} - -CPDF_TilingPattern* CPDF_ShadingPattern::AsTilingPattern() { - return nullptr; -} - -CPDF_ShadingPattern* CPDF_ShadingPattern::AsShadingPattern() { - return this; -} - -bool CPDF_ShadingPattern::Load() { - if (m_ShadingType != kInvalidShading) - return TRUE; - - CPDF_Dictionary* pShadingDict = - m_pShadingObj ? m_pShadingObj->GetDict() : nullptr; - if (!pShadingDict) - return FALSE; - - m_pFunctions.clear(); - CPDF_Object* pFunc = pShadingDict->GetDirectObjectFor("Function"); - if (pFunc) { - if (CPDF_Array* pArray = pFunc->AsArray()) { - m_pFunctions.resize(std::min(pArray->GetCount(), 4)); - for (size_t i = 0; i < m_pFunctions.size(); ++i) - m_pFunctions[i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i)); - } else { - m_pFunctions.push_back(CPDF_Function::Load(pFunc)); - } - } - CPDF_Object* pCSObj = pShadingDict->GetDirectObjectFor("ColorSpace"); - if (!pCSObj) - return FALSE; - - CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); - m_pCS = pDocPageData->GetColorSpace(pCSObj, nullptr); - if (m_pCS) - m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray()); - - m_ShadingType = ToShadingType(pShadingDict->GetIntegerFor("ShadingType")); - - // We expect to have a stream if our shading type is a mesh. - if (IsMeshShading() && !ToStream(m_pShadingObj)) - return FALSE; - - return TRUE; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_shadingpattern.h b/core/fpdfapi/fpdf_page/cpdf_shadingpattern.h deleted file mode 100644 index e2bcef268a..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_shadingpattern.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGPATTERN_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGPATTERN_H_ - -#include -#include - -#include "core/fpdfapi/fpdf_page/cpdf_countedobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pattern.h" -#include "core/fxcrt/fx_system.h" - -enum ShadingType { - kInvalidShading = 0, - kFunctionBasedShading = 1, - kAxialShading = 2, - kRadialShading = 3, - kFreeFormGouraudTriangleMeshShading = 4, - kLatticeFormGouraudTriangleMeshShading = 5, - kCoonsPatchMeshShading = 6, - kTensorProductPatchMeshShading = 7, - kMaxShading = 8 -}; - -class CFX_Matrix; -class CPDF_ColorSpace; -class CPDF_Document; -class CPDF_Function; -class CPDF_Object; - -class CPDF_ShadingPattern : public CPDF_Pattern { - public: - CPDF_ShadingPattern(CPDF_Document* pDoc, - CPDF_Object* pPatternObj, - FX_BOOL bShading, - const CFX_Matrix& parentMatrix); - ~CPDF_ShadingPattern() override; - - CPDF_TilingPattern* AsTilingPattern() override; - CPDF_ShadingPattern* AsShadingPattern() override; - - bool IsMeshShading() const { - return m_ShadingType == kFreeFormGouraudTriangleMeshShading || - m_ShadingType == kLatticeFormGouraudTriangleMeshShading || - m_ShadingType == kCoonsPatchMeshShading || - m_ShadingType == kTensorProductPatchMeshShading; - } - bool Load(); - - ShadingType GetShadingType() const { return m_ShadingType; } - FX_BOOL IsShadingObject() const { return m_bShadingObj; } - CPDF_Object* GetShadingObject() const { return m_pShadingObj; } - CPDF_ColorSpace* GetCS() const { return m_pCS; } - const std::vector>& GetFuncs() const { - return m_pFunctions; - } - - private: - ShadingType m_ShadingType; - FX_BOOL m_bShadingObj; - CPDF_Object* m_pShadingObj; - - // Still keep |m_pCS| as some CPDF_ColorSpace (name object) are not managed - // as counted objects. Refer to CPDF_DocPageData::GetColorSpace. - CPDF_ColorSpace* m_pCS; - - CPDF_CountedColorSpace* m_pCountedCS; - std::vector> m_pFunctions; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_SHADINGPATTERN_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp deleted file mode 100644 index 97f6ad2bcd..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_textobject.h" - -#include "core/fpdfapi/font/cpdf_cidfont.h" -#include "core/fpdfapi/font/cpdf_font.h" - -CPDF_TextObject::CPDF_TextObject() - : m_PosX(0), - m_PosY(0), - m_nChars(0), - m_pCharCodes(nullptr), - m_pCharPos(nullptr) {} - -CPDF_TextObject::~CPDF_TextObject() { - if (m_nChars > 1) { - FX_Free(m_pCharCodes); - } - FX_Free(m_pCharPos); -} - -int CPDF_TextObject::CountItems() const { - return m_nChars; -} - -void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const { - pInfo->m_CharCode = - m_nChars == 1 ? (uint32_t)(uintptr_t)m_pCharCodes : m_pCharCodes[index]; - pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0; - pInfo->m_OriginY = 0; - if (pInfo->m_CharCode == CPDF_Font::kInvalidCharCode) { - return; - } - CPDF_Font* pFont = m_TextState.GetFont(); - if (!pFont->IsCIDFont()) { - return; - } - if (!pFont->AsCIDFont()->IsVertWriting()) { - return; - } - uint16_t CID = pFont->AsCIDFont()->CIDFromCharCode(pInfo->m_CharCode); - pInfo->m_OriginY = pInfo->m_OriginX; - pInfo->m_OriginX = 0; - short vx, vy; - pFont->AsCIDFont()->GetVertOrigin(CID, vx, vy); - FX_FLOAT fontsize = m_TextState.GetFontSize(); - pInfo->m_OriginX -= fontsize * vx / 1000; - pInfo->m_OriginY -= fontsize * vy / 1000; -} - -int CPDF_TextObject::CountChars() const { - if (m_nChars == 1) { - return 1; - } - int count = 0; - for (int i = 0; i < m_nChars; ++i) - if (m_pCharCodes[i] != CPDF_Font::kInvalidCharCode) { - ++count; - } - return count; -} - -void CPDF_TextObject::GetCharInfo(int index, - uint32_t& charcode, - FX_FLOAT& kerning) const { - if (m_nChars == 1) { - charcode = (uint32_t)(uintptr_t)m_pCharCodes; - kerning = 0; - return; - } - int count = 0; - for (int i = 0; i < m_nChars; ++i) { - if (m_pCharCodes[i] != CPDF_Font::kInvalidCharCode) { - if (count == index) { - charcode = m_pCharCodes[i]; - if (i == m_nChars - 1 || - m_pCharCodes[i + 1] != CPDF_Font::kInvalidCharCode) { - kerning = 0; - } else { - kerning = m_pCharPos[i]; - } - return; - } - ++count; - } - } -} - -void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const { - if (m_nChars == 1) { - GetItemInfo(0, pInfo); - return; - } - int count = 0; - for (int i = 0; i < m_nChars; ++i) { - uint32_t charcode = m_pCharCodes[i]; - if (charcode == CPDF_Font::kInvalidCharCode) { - continue; - } - if (count == index) { - GetItemInfo(i, pInfo); - break; - } - ++count; - } -} - -CPDF_TextObject* CPDF_TextObject::Clone() const { - CPDF_TextObject* obj = new CPDF_TextObject; - obj->CopyData(this); - - obj->m_nChars = m_nChars; - if (m_nChars > 1) { - obj->m_pCharCodes = FX_Alloc(uint32_t, m_nChars); - FXSYS_memcpy(obj->m_pCharCodes, m_pCharCodes, m_nChars * sizeof(uint32_t)); - obj->m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); - FXSYS_memcpy(obj->m_pCharPos, m_pCharPos, - (m_nChars - 1) * sizeof(FX_FLOAT)); - } else { - obj->m_pCharCodes = m_pCharCodes; - } - obj->m_PosX = m_PosX; - obj->m_PosY = m_PosY; - return obj; -} - -CPDF_PageObject::Type CPDF_TextObject::GetType() const { - return TEXT; -} - -void CPDF_TextObject::Transform(const CFX_Matrix& matrix) { - CFX_Matrix text_matrix; - GetTextMatrix(&text_matrix); - text_matrix.Concat(matrix); - - FX_FLOAT* pTextMatrix = m_TextState.GetMutableMatrix(); - pTextMatrix[0] = text_matrix.GetA(); - pTextMatrix[1] = text_matrix.GetC(); - pTextMatrix[2] = text_matrix.GetB(); - pTextMatrix[3] = text_matrix.GetD(); - m_PosX = text_matrix.GetE(); - m_PosY = text_matrix.GetF(); - CalcPositionData(nullptr, nullptr, 0); -} - -bool CPDF_TextObject::IsText() const { - return true; -} - -CPDF_TextObject* CPDF_TextObject::AsText() { - return this; -} - -const CPDF_TextObject* CPDF_TextObject::AsText() const { - return this; -} - -void CPDF_TextObject::GetTextMatrix(CFX_Matrix* pMatrix) const { - const FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); - pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], - m_PosX, m_PosY); -} - -void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, - FX_FLOAT* pKerning, - int nsegs) { - if (m_nChars > 1) { - FX_Free(m_pCharCodes); - m_pCharCodes = nullptr; - } - FX_Free(m_pCharPos); - m_pCharPos = nullptr; - CPDF_Font* pFont = m_TextState.GetFont(); - m_nChars = 0; - for (int i = 0; i < nsegs; ++i) { - m_nChars += pFont->CountChar(pStrs[i].c_str(), pStrs[i].GetLength()); - } - m_nChars += nsegs - 1; - if (m_nChars > 1) { - m_pCharCodes = FX_Alloc(uint32_t, m_nChars); - m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); - int index = 0; - for (int i = 0; i < nsegs; ++i) { - const FX_CHAR* segment = pStrs[i].c_str(); - int len = pStrs[i].GetLength(); - int offset = 0; - while (offset < len) { - m_pCharCodes[index++] = pFont->GetNextChar(segment, len, offset); - } - if (i != nsegs - 1) { - m_pCharPos[index - 1] = pKerning[i]; - m_pCharCodes[index++] = CPDF_Font::kInvalidCharCode; - } - } - } else { - int offset = 0; - m_pCharCodes = (uint32_t*)(uintptr_t)pFont->GetNextChar( - pStrs[0].c_str(), pStrs[0].GetLength(), offset); - } -} - -void CPDF_TextObject::SetText(const CFX_ByteString& str) { - SetSegments(&str, nullptr, 1); - RecalcPositionData(); -} - -FX_FLOAT CPDF_TextObject::GetCharWidth(uint32_t charcode) const { - FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; - CPDF_Font* pFont = m_TextState.GetFont(); - FX_BOOL bVertWriting = FALSE; - CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); - if (pCIDFont) { - bVertWriting = pCIDFont->IsVertWriting(); - } - if (!bVertWriting) - return pFont->GetCharWidthF(charcode) * fontsize; - - uint16_t CID = pCIDFont->CIDFromCharCode(charcode); - return pCIDFont->GetVertWidth(CID) * fontsize; -} - -FX_FLOAT CPDF_TextObject::GetPosX() const { - return m_PosX; -} - -FX_FLOAT CPDF_TextObject::GetPosY() const { - return m_PosY; -} - -CPDF_Font* CPDF_TextObject::GetFont() const { - return m_TextState.GetFont(); -} - -FX_FLOAT CPDF_TextObject::GetFontSize() const { - return m_TextState.GetFontSize(); -} - -void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, - FX_FLOAT* pTextAdvanceY, - FX_FLOAT horz_scale) { - FX_FLOAT curpos = 0; - FX_FLOAT min_x = 10000 * 1.0f; - FX_FLOAT max_x = -10000 * 1.0f; - FX_FLOAT min_y = 10000 * 1.0f; - FX_FLOAT max_y = -10000 * 1.0f; - CPDF_Font* pFont = m_TextState.GetFont(); - FX_BOOL bVertWriting = FALSE; - CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); - if (pCIDFont) { - bVertWriting = pCIDFont->IsVertWriting(); - } - FX_FLOAT fontsize = m_TextState.GetFontSize(); - for (int i = 0; i < m_nChars; ++i) { - uint32_t charcode = - m_nChars == 1 ? (uint32_t)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; - if (i > 0) { - if (charcode == CPDF_Font::kInvalidCharCode) { - curpos -= (m_pCharPos[i - 1] * fontsize) / 1000; - continue; - } - m_pCharPos[i - 1] = curpos; - } - FX_RECT char_rect = pFont->GetCharBBox(charcode); - FX_FLOAT charwidth; - if (!bVertWriting) { - if (min_y > char_rect.top) { - min_y = (FX_FLOAT)char_rect.top; - } - if (max_y < char_rect.top) { - max_y = (FX_FLOAT)char_rect.top; - } - if (min_y > char_rect.bottom) { - min_y = (FX_FLOAT)char_rect.bottom; - } - if (max_y < char_rect.bottom) { - max_y = (FX_FLOAT)char_rect.bottom; - } - FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000; - FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000; - if (min_x > char_left) { - min_x = char_left; - } - if (max_x < char_left) { - max_x = char_left; - } - if (min_x > char_right) { - min_x = char_right; - } - if (max_x < char_right) { - max_x = char_right; - } - charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; - } else { - uint16_t CID = pCIDFont->CIDFromCharCode(charcode); - short vx; - short vy; - pCIDFont->GetVertOrigin(CID, vx, vy); - char_rect.left -= vx; - char_rect.right -= vx; - char_rect.top -= vy; - char_rect.bottom -= vy; - if (min_x > char_rect.left) { - min_x = (FX_FLOAT)char_rect.left; - } - if (max_x < char_rect.left) { - max_x = (FX_FLOAT)char_rect.left; - } - if (min_x > char_rect.right) { - min_x = (FX_FLOAT)char_rect.right; - } - if (max_x < char_rect.right) { - max_x = (FX_FLOAT)char_rect.right; - } - FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000; - FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000; - if (min_y > char_top) { - min_y = char_top; - } - if (max_y < char_top) { - max_y = char_top; - } - if (min_y > char_bottom) { - min_y = char_bottom; - } - if (max_y < char_bottom) { - max_y = char_bottom; - } - charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; - } - curpos += charwidth; - if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) { - curpos += m_TextState.GetWordSpace(); - } - curpos += m_TextState.GetCharSpace(); - } - if (bVertWriting) { - if (pTextAdvanceX) { - *pTextAdvanceX = 0; - } - if (pTextAdvanceY) { - *pTextAdvanceY = curpos; - } - min_x = min_x * fontsize / 1000; - max_x = max_x * fontsize / 1000; - } else { - if (pTextAdvanceX) { - *pTextAdvanceX = curpos * horz_scale; - } - if (pTextAdvanceY) { - *pTextAdvanceY = 0; - } - min_y = min_y * fontsize / 1000; - max_y = max_y * fontsize / 1000; - } - CFX_Matrix matrix; - GetTextMatrix(&matrix); - m_Left = min_x; - m_Right = max_x; - m_Bottom = min_y; - m_Top = max_y; - matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); - if (TextRenderingModeIsStrokeMode(m_TextState.GetTextMode())) { - FX_FLOAT half_width = m_GraphState.GetLineWidth() / 2; - m_Left -= half_width; - m_Right += half_width; - m_Top += half_width; - m_Bottom -= half_width; - } -} - -void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) { - FX_FLOAT dx = x - m_PosX; - FX_FLOAT dy = y - m_PosY; - m_PosX = x; - m_PosY = y; - m_Left += dx; - m_Right += dx; - m_Top += dy; - m_Bottom += dy; -} - -void CPDF_TextObject::RecalcPositionData() { - CalcPositionData(nullptr, nullptr, 1); -} diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.h b/core/fpdfapi/fpdf_page/cpdf_textobject.h deleted file mode 100644 index 05a08a9c89..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_TEXTOBJECT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_TEXTOBJECT_H_ - -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/fx_system.h" - -struct CPDF_TextObjectItem { - uint32_t m_CharCode; - FX_FLOAT m_OriginX; - FX_FLOAT m_OriginY; -}; - -class CPDF_TextObject : public CPDF_PageObject { - public: - CPDF_TextObject(); - ~CPDF_TextObject() override; - - // CPDF_PageObject - CPDF_TextObject* Clone() const override; - Type GetType() const override; - void Transform(const CFX_Matrix& matrix) override; - bool IsText() const override; - CPDF_TextObject* AsText() override; - const CPDF_TextObject* AsText() const override; - - int CountItems() const; - void GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const; - int CountChars() const; - void GetCharInfo(int index, uint32_t& charcode, FX_FLOAT& kerning) const; - void GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const; - FX_FLOAT GetCharWidth(uint32_t charcode) const; - FX_FLOAT GetPosX() const; - FX_FLOAT GetPosY() const; - void GetTextMatrix(CFX_Matrix* pMatrix) const; - CPDF_Font* GetFont() const; - FX_FLOAT GetFontSize() const; - - void SetText(const CFX_ByteString& text); - void SetPosition(FX_FLOAT x, FX_FLOAT y); - - void RecalcPositionData(); - - protected: - friend class CPDF_RenderStatus; - friend class CPDF_StreamContentParser; - friend class CPDF_TextRenderer; - - void SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs); - - void CalcPositionData(FX_FLOAT* pTextAdvanceX, - FX_FLOAT* pTextAdvanceY, - FX_FLOAT horz_scale); - - FX_FLOAT m_PosX; - FX_FLOAT m_PosY; - int m_nChars; - uint32_t* m_pCharCodes; - FX_FLOAT* m_pCharPos; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_TEXTOBJECT_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_textstate.cpp b/core/fpdfapi/fpdf_page/cpdf_textstate.cpp deleted file mode 100644 index 800af23861..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_textstate.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_textstate.h" - -#include "core/fpdfapi/font/cpdf_font.h" -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" - -CPDF_TextState::CPDF_TextState() {} -CPDF_TextState::~CPDF_TextState() {} - -void CPDF_TextState::Emplace() { - m_Ref.Emplace(); -} - -CPDF_Font* CPDF_TextState::GetFont() const { - return m_Ref.GetObject()->m_pFont; -} - -void CPDF_TextState::SetFont(CPDF_Font* pFont) { - m_Ref.GetPrivateCopy()->SetFont(pFont); -} - -FX_FLOAT CPDF_TextState::GetFontSize() const { - return m_Ref.GetObject()->m_FontSize; -} - -void CPDF_TextState::SetFontSize(FX_FLOAT size) { - m_Ref.GetPrivateCopy()->m_FontSize = size; -} - -const FX_FLOAT* CPDF_TextState::GetMatrix() const { - return m_Ref.GetObject()->m_Matrix; -} - -FX_FLOAT* CPDF_TextState::GetMutableMatrix() { - return m_Ref.GetPrivateCopy()->m_Matrix; -} - -FX_FLOAT CPDF_TextState::GetCharSpace() const { - return m_Ref.GetObject()->m_CharSpace; -} - -void CPDF_TextState::SetCharSpace(FX_FLOAT sp) { - m_Ref.GetPrivateCopy()->m_CharSpace = sp; -} - -FX_FLOAT CPDF_TextState::GetWordSpace() const { - return m_Ref.GetObject()->m_WordSpace; -} - -void CPDF_TextState::SetWordSpace(FX_FLOAT sp) { - m_Ref.GetPrivateCopy()->m_WordSpace = sp; -} - -FX_FLOAT CPDF_TextState::GetFontSizeV() const { - return m_Ref.GetObject()->GetFontSizeV(); -} - -FX_FLOAT CPDF_TextState::GetFontSizeH() const { - return m_Ref.GetObject()->GetFontSizeH(); -} - -FX_FLOAT CPDF_TextState::GetBaselineAngle() const { - return m_Ref.GetObject()->GetBaselineAngle(); -} - -FX_FLOAT CPDF_TextState::GetShearAngle() const { - return m_Ref.GetObject()->GetShearAngle(); -} - -TextRenderingMode CPDF_TextState::GetTextMode() const { - return m_Ref.GetObject()->m_TextMode; -} - -void CPDF_TextState::SetTextMode(TextRenderingMode mode) { - m_Ref.GetPrivateCopy()->m_TextMode = mode; -} - -const FX_FLOAT* CPDF_TextState::GetCTM() const { - return m_Ref.GetObject()->m_CTM; -} - -FX_FLOAT* CPDF_TextState::GetMutableCTM() { - return m_Ref.GetPrivateCopy()->m_CTM; -} - -CPDF_TextState::TextData::TextData() - : m_pFont(nullptr), - m_pDocument(nullptr), - m_FontSize(1.0f), - m_CharSpace(0), - m_WordSpace(0), - m_TextMode(TextRenderingMode::MODE_FILL) { - m_Matrix[0] = m_Matrix[3] = 1.0f; - m_Matrix[1] = m_Matrix[2] = 0; - m_CTM[0] = m_CTM[3] = 1.0f; - m_CTM[1] = m_CTM[2] = 0; -} - -CPDF_TextState::TextData::TextData(const TextData& that) - : m_pFont(that.m_pFont), - m_pDocument(that.m_pDocument), - m_FontSize(that.m_FontSize), - m_CharSpace(that.m_CharSpace), - m_WordSpace(that.m_WordSpace), - m_TextMode(that.m_TextMode) { - for (int i = 0; i < 4; ++i) - m_Matrix[i] = that.m_Matrix[i]; - - for (int i = 0; i < 4; ++i) - m_CTM[i] = that.m_CTM[i]; - - if (m_pDocument && m_pFont) { - m_pFont = - m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE); - } -} - -CPDF_TextState::TextData::~TextData() { - if (m_pDocument && m_pFont) { - CPDF_DocPageData* pPageData = m_pDocument->GetPageData(); - if (pPageData && !pPageData->IsForceClear()) - pPageData->ReleaseFont(m_pFont->GetFontDict()); - } -} - -void CPDF_TextState::TextData::SetFont(CPDF_Font* pFont) { - CPDF_Document* pDoc = m_pDocument; - CPDF_DocPageData* pPageData = pDoc ? pDoc->GetPageData() : nullptr; - if (pPageData && m_pFont && !pPageData->IsForceClear()) - pPageData->ReleaseFont(m_pFont->GetFontDict()); - - m_pDocument = pFont ? pFont->m_pDocument : nullptr; - m_pFont = pFont; -} - -FX_FLOAT CPDF_TextState::TextData::GetFontSizeV() const { - return FXSYS_fabs(FXSYS_sqrt2(m_Matrix[1], m_Matrix[3]) * m_FontSize); -} - -FX_FLOAT CPDF_TextState::TextData::GetFontSizeH() const { - return FXSYS_fabs(FXSYS_sqrt2(m_Matrix[0], m_Matrix[2]) * m_FontSize); -} - -FX_FLOAT CPDF_TextState::TextData::GetBaselineAngle() const { - return FXSYS_atan2(m_Matrix[2], m_Matrix[0]); -} - -FX_FLOAT CPDF_TextState::TextData::GetShearAngle() const { - return GetBaselineAngle() + FXSYS_atan2(m_Matrix[1], m_Matrix[3]); -} - -bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode) { - if (iMode < 0 || iMode > 7) - return false; - *mode = static_cast(iMode); - return true; -} - -bool TextRenderingModeIsClipMode(const TextRenderingMode& mode) { - switch (mode) { - case TextRenderingMode::MODE_FILL_CLIP: - case TextRenderingMode::MODE_STROKE_CLIP: - case TextRenderingMode::MODE_FILL_STROKE_CLIP: - case TextRenderingMode::MODE_CLIP: - return true; - default: - return false; - } -} - -bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode) { - switch (mode) { - case TextRenderingMode::MODE_STROKE: - case TextRenderingMode::MODE_FILL_STROKE: - case TextRenderingMode::MODE_STROKE_CLIP: - case TextRenderingMode::MODE_FILL_STROKE_CLIP: - return true; - default: - return false; - } -} diff --git a/core/fpdfapi/fpdf_page/cpdf_textstate.h b/core/fpdfapi/fpdf_page/cpdf_textstate.h deleted file mode 100644 index 0c615b270b..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_textstate.h +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_TEXTSTATE_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_TEXTSTATE_H_ - -#include "core/fxcrt/cfx_count_ref.h" -#include "core/fxcrt/fx_basic.h" - -class CPDF_Document; -class CPDF_Font; - -// See PDF Reference 1.7, page 402, table 5.3. -enum class TextRenderingMode { - MODE_FILL = 0, - MODE_STROKE = 1, - MODE_FILL_STROKE = 2, - MODE_INVISIBLE = 3, - MODE_FILL_CLIP = 4, - MODE_STROKE_CLIP = 5, - MODE_FILL_STROKE_CLIP = 6, - MODE_CLIP = 7, -}; - -class CPDF_TextState { - public: - CPDF_TextState(); - ~CPDF_TextState(); - - void Emplace(); - - CPDF_Font* GetFont() const; - void SetFont(CPDF_Font* pFont); - - FX_FLOAT GetFontSize() const; - void SetFontSize(FX_FLOAT size); - - const FX_FLOAT* GetMatrix() const; - FX_FLOAT* GetMutableMatrix(); - - FX_FLOAT GetCharSpace() const; - void SetCharSpace(FX_FLOAT sp); - - FX_FLOAT GetWordSpace() const; - void SetWordSpace(FX_FLOAT sp); - - FX_FLOAT GetFontSizeV() const; - FX_FLOAT GetFontSizeH() const; - FX_FLOAT GetBaselineAngle() const; - FX_FLOAT GetShearAngle() const; - - TextRenderingMode GetTextMode() const; - void SetTextMode(TextRenderingMode mode); - - const FX_FLOAT* GetCTM() const; - FX_FLOAT* GetMutableCTM(); - - private: - class TextData { - public: - TextData(); - TextData(const TextData& src); - ~TextData(); - - void SetFont(CPDF_Font* pFont); - FX_FLOAT GetFontSizeV() const; - FX_FLOAT GetFontSizeH() const; - FX_FLOAT GetBaselineAngle() const; - FX_FLOAT GetShearAngle() const; - - CPDF_Font* m_pFont; - CPDF_Document* m_pDocument; - FX_FLOAT m_FontSize; - FX_FLOAT m_CharSpace; - FX_FLOAT m_WordSpace; - TextRenderingMode m_TextMode; - FX_FLOAT m_Matrix[4]; - FX_FLOAT m_CTM[4]; - }; - - CFX_CountRef m_Ref; -}; - -bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode); -bool TextRenderingModeIsClipMode(const TextRenderingMode& mode); -bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode); - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_TEXTSTATE_H_ diff --git a/core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp b/core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp deleted file mode 100644 index 42f4aaa955..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_tilingpattern.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" - -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_object.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" - -CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc, - CPDF_Object* pPatternObj, - const CFX_Matrix& parentMatrix) - : CPDF_Pattern(TILING, pDoc, pPatternObj, parentMatrix) { - CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); - m_Pattern2Form = pDict->GetMatrixFor("Matrix"); - m_bColored = pDict->GetIntegerFor("PaintType") == 1; - m_Pattern2Form.Concat(parentMatrix); -} - -CPDF_TilingPattern::~CPDF_TilingPattern() { -} - -CPDF_TilingPattern* CPDF_TilingPattern::AsTilingPattern() { - return this; -} - -CPDF_ShadingPattern* CPDF_TilingPattern::AsShadingPattern() { - return nullptr; -} - -FX_BOOL CPDF_TilingPattern::Load() { - if (m_pForm) - return TRUE; - - CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); - if (!pDict) - return FALSE; - - m_bColored = pDict->GetIntegerFor("PaintType") == 1; - m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberFor("XStep")); - m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberFor("YStep")); - - CPDF_Stream* pStream = m_pPatternObj->AsStream(); - if (!pStream) - return FALSE; - - m_pForm.reset(new CPDF_Form(m_pDocument, nullptr, pStream)); - m_pForm->ParseContent(nullptr, &m_ParentMatrix, nullptr); - m_BBox = pDict->GetRectFor("BBox"); - return TRUE; -} diff --git a/core/fpdfapi/fpdf_page/cpdf_tilingpattern.h b/core/fpdfapi/fpdf_page/cpdf_tilingpattern.h deleted file mode 100644 index 7ff2068f75..0000000000 --- a/core/fpdfapi/fpdf_page/cpdf_tilingpattern.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_TILINGPATTERN_H_ -#define CORE_FPDFAPI_FPDF_PAGE_CPDF_TILINGPATTERN_H_ - -#include - -#include "core/fpdfapi/fpdf_page/cpdf_pattern.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_system.h" - -class CPDF_Document; -class CPDF_Form; -class CPDF_Object; - -class CPDF_TilingPattern : public CPDF_Pattern { - public: - CPDF_TilingPattern(CPDF_Document* pDoc, - CPDF_Object* pPatternObj, - const CFX_Matrix& parentMatrix); - ~CPDF_TilingPattern() override; - - CPDF_TilingPattern* AsTilingPattern() override; - CPDF_ShadingPattern* AsShadingPattern() override; - - FX_BOOL Load(); - - bool colored() const { return m_bColored; } - const CFX_FloatRect& bbox() const { return m_BBox; } - FX_FLOAT x_step() const { return m_XStep; } - FX_FLOAT y_step() const { return m_YStep; } - CPDF_Form* form() const { return m_pForm.get(); } - - private: - bool m_bColored; - CFX_FloatRect m_BBox; - FX_FLOAT m_XStep; - FX_FLOAT m_YStep; - std::unique_ptr m_pForm; -}; - -#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_TILINGPATTERN_H_ diff --git a/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp b/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp deleted file mode 100644 index 472e8751d7..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_colors.cpp +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/pageint.h" - -#include - -#include - -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fpdfapi/fpdf_parser/cpdf_string.h" -#include "core/fxcodec/fx_codec.h" - -namespace { - -uint32_t ComponentsForFamily(int family) { - if (family == PDFCS_DEVICERGB) - return 3; - if (family == PDFCS_DEVICEGRAY) - return 1; - return 4; -} - -} // namespace - -void sRGB_to_AdobeCMYK(FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) { - c = 1.0f - R; - m = 1.0f - G; - y = 1.0f - B; - k = c; - if (m < k) { - k = m; - } - if (y < k) { - k = y; - } -} - -void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) { - if (pDestBuf == pSrcBuf) { - for (int i = 0; i < pixels; i++) { - uint8_t temp = pDestBuf[2]; - pDestBuf[2] = pDestBuf[0]; - pDestBuf[0] = temp; - pDestBuf += 3; - } - } else { - for (int i = 0; i < pixels; i++) { - *pDestBuf++ = pSrcBuf[2]; - *pDestBuf++ = pSrcBuf[1]; - *pDestBuf++ = pSrcBuf[0]; - pSrcBuf += 3; - } - } -} - -CPDF_DeviceCS::CPDF_DeviceCS(CPDF_Document* pDoc, int family) - : CPDF_ColorSpace(pDoc, family, ComponentsForFamily(family)) {} - -FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const { - if (m_Family == PDFCS_DEVICERGB) { - R = pBuf[0]; - if (R < 0) { - R = 0; - } else if (R > 1) { - R = 1; - } - G = pBuf[1]; - if (G < 0) { - G = 0; - } else if (G > 1) { - G = 1; - } - B = pBuf[2]; - if (B < 0) { - B = 0; - } else if (B > 1) { - B = 1; - } - } else if (m_Family == PDFCS_DEVICEGRAY) { - R = *pBuf; - if (R < 0) { - R = 0; - } else if (R > 1) { - R = 1; - } - G = B = R; - } else if (m_Family == PDFCS_DEVICECMYK) { - if (!m_dwStdConversion) { - AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B); - } else { - FX_FLOAT k = pBuf[3]; - R = 1.0f - std::min(1.0f, pBuf[0] + k); - G = 1.0f - std::min(1.0f, pBuf[1] + k); - B = 1.0f - std::min(1.0f, pBuf[2] + k); - } - } else { - ASSERT(m_Family == PDFCS_PATTERN); - R = G = B = 0; - return FALSE; - } - return TRUE; -} -FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const { - if (m_Family != PDFCS_DEVICECMYK) { - return FALSE; - } - c = pBuf[0]; - m = pBuf[1]; - y = pBuf[2]; - k = pBuf[3]; - return TRUE; -} -FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const { - if (m_Family == PDFCS_DEVICERGB) { - pBuf[0] = R; - pBuf[1] = G; - pBuf[2] = B; - return TRUE; - } - if (m_Family == PDFCS_DEVICEGRAY) { - if (R == G && R == B) { - *pBuf = R; - return TRUE; - } - return FALSE; - } - if (m_Family == PDFCS_DEVICECMYK) { - sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]); - return TRUE; - } - return FALSE; -} -FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, - FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k) const { - if (m_Family == PDFCS_DEVICERGB) { - AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]); - return TRUE; - } - if (m_Family == PDFCS_DEVICECMYK) { - pBuf[0] = c; - pBuf[1] = m; - pBuf[2] = y; - pBuf[3] = k; - return TRUE; - } - return FALSE; -} - -void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask) const { - if (bTransMask && m_Family == PDFCS_DEVICECMYK) { - for (int i = 0; i < pixels; i++) { - int k = 255 - pSrcBuf[3]; - pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255; - pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255; - pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255; - pDestBuf += 3; - pSrcBuf += 4; - } - return; - } - if (m_Family == PDFCS_DEVICERGB) { - ReverseRGB(pDestBuf, pSrcBuf, pixels); - } else if (m_Family == PDFCS_DEVICEGRAY) { - for (int i = 0; i < pixels; i++) { - *pDestBuf++ = pSrcBuf[i]; - *pDestBuf++ = pSrcBuf[i]; - *pDestBuf++ = pSrcBuf[i]; - } - } else { - for (int i = 0; i < pixels; i++) { - if (!m_dwStdConversion) { - AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3], - pDestBuf[2], pDestBuf[1], pDestBuf[0]); - } else { - uint8_t k = pSrcBuf[3]; - pDestBuf[2] = 255 - std::min(255, pSrcBuf[0] + k); - pDestBuf[1] = 255 - std::min(255, pSrcBuf[1] + k); - pDestBuf[0] = 255 - std::min(255, pSrcBuf[2] + k); - } - pSrcBuf += 4; - pDestBuf += 3; - } - } -} - -CPDF_IccProfile::CPDF_IccProfile(const uint8_t* pData, uint32_t dwSize) - : m_bsRGB(FALSE), m_pTransform(nullptr), m_nSrcComponents(0) { - if (dwSize == 3144 && - FXSYS_memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0) { - m_bsRGB = TRUE; - m_nSrcComponents = 3; - } else if (CPDF_ModuleMgr::Get()->GetIccModule()) { - m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB( - pData, dwSize, m_nSrcComponents); - } -} -CPDF_IccProfile::~CPDF_IccProfile() { - if (m_pTransform) { - CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform); - } -} - diff --git a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp deleted file mode 100644 index 4b1eaa3064..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp +++ /dev/null @@ -1,554 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/pageint.h" - -#include -#include - -#include "core/fdrm/crypto/fx_crypt.h" -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/font/cpdf_type1font.h" -#include "core/fpdfapi/font/font_int.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/cpdf_pattern.h" -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" -#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "third_party/base/stl_util.h" - -void CPDF_ModuleMgr::InitPageModule() { - m_pPageModule.reset(new CPDF_PageModule); -} - -CPDF_DocPageData::CPDF_DocPageData(CPDF_Document* pPDFDoc) - : m_pPDFDoc(pPDFDoc), m_bForceClear(FALSE) {} - -CPDF_DocPageData::~CPDF_DocPageData() { - Clear(FALSE); - Clear(TRUE); - - for (auto& it : m_PatternMap) - delete it.second; - m_PatternMap.clear(); - - for (auto& it : m_FontMap) - delete it.second; - m_FontMap.clear(); - - for (auto& it : m_ColorSpaceMap) - delete it.second; - m_ColorSpaceMap.clear(); -} - -void CPDF_DocPageData::Clear(FX_BOOL bForceRelease) { - m_bForceClear = bForceRelease; - - for (auto& it : m_PatternMap) { - CPDF_CountedPattern* ptData = it.second; - if (!ptData->get()) - continue; - - if (bForceRelease || ptData->use_count() < 2) - ptData->clear(); - } - - for (auto& it : m_FontMap) { - CPDF_CountedFont* fontData = it.second; - if (!fontData->get()) - continue; - - if (bForceRelease || fontData->use_count() < 2) { - fontData->clear(); - } - } - - for (auto& it : m_ColorSpaceMap) { - CPDF_CountedColorSpace* csData = it.second; - if (!csData->get()) - continue; - - if (bForceRelease || csData->use_count() < 2) { - csData->get()->Release(); - csData->reset(nullptr); - } - } - - for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end();) { - auto curr_it = it++; - CPDF_CountedIccProfile* ipData = curr_it->second; - if (!ipData->get()) - continue; - - if (bForceRelease || ipData->use_count() < 2) { - for (auto hash_it = m_HashProfileMap.begin(); - hash_it != m_HashProfileMap.end(); ++hash_it) { - if (curr_it->first == hash_it->second) { - m_HashProfileMap.erase(hash_it); - break; - } - } - delete ipData->get(); - delete ipData; - m_IccProfileMap.erase(curr_it); - } - } - - for (auto it = m_FontFileMap.begin(); it != m_FontFileMap.end();) { - auto curr_it = it++; - CPDF_CountedStreamAcc* pCountedFont = curr_it->second; - if (!pCountedFont->get()) - continue; - - if (bForceRelease || pCountedFont->use_count() < 2) { - delete pCountedFont->get(); - delete pCountedFont; - m_FontFileMap.erase(curr_it); - } - } - - for (auto it = m_ImageMap.begin(); it != m_ImageMap.end();) { - auto curr_it = it++; - CPDF_CountedImage* pCountedImage = curr_it->second; - if (!pCountedImage->get()) - continue; - - if (bForceRelease || pCountedImage->use_count() < 2) { - delete pCountedImage->get(); - delete pCountedImage; - m_ImageMap.erase(curr_it); - } - } -} - -CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, - FX_BOOL findOnly) { - if (!pFontDict) - return nullptr; - - CPDF_CountedFont* pFontData = nullptr; - auto it = m_FontMap.find(pFontDict); - if (it != m_FontMap.end()) { - pFontData = it->second; - if (pFontData->get()) { - return pFontData->AddRef(); - } - } - - if (findOnly) - return nullptr; - - std::unique_ptr pFont = CPDF_Font::Create(m_pPDFDoc, pFontDict); - if (!pFont) - return nullptr; - - if (pFontData) { - pFontData->reset(pFont.release()); - } else { - pFontData = new CPDF_CountedFont(pFont.release()); - m_FontMap[pFontDict] = pFontData; - } - return pFontData->AddRef(); -} - -CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, - CPDF_FontEncoding* pEncoding) { - if (fontName.IsEmpty()) - return nullptr; - - for (auto& it : m_FontMap) { - CPDF_CountedFont* fontData = it.second; - CPDF_Font* pFont = fontData->get(); - if (!pFont) - continue; - if (pFont->GetBaseFont() != fontName) - continue; - if (pFont->IsEmbedded()) - continue; - if (!pFont->IsType1Font()) - continue; - if (pFont->GetFontDict()->KeyExist("Widths")) - continue; - - CPDF_Type1Font* pT1Font = pFont->AsType1Font(); - if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) - continue; - - return fontData->AddRef(); - } - - CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPDFDoc->GetByteStringPool()); - pDict->SetNameFor("Type", "Font"); - pDict->SetNameFor("Subtype", "Type1"); - pDict->SetNameFor("BaseFont", fontName); - if (pEncoding) { - pDict->SetFor("Encoding", - pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); - } - m_pPDFDoc->AddIndirectObject(pDict); - std::unique_ptr pFont = CPDF_Font::Create(m_pPDFDoc, pDict); - if (!pFont) - return nullptr; - - CPDF_CountedFont* fontData = new CPDF_CountedFont(pFont.release()); - m_FontMap[pDict] = fontData; - return fontData->AddRef(); -} - -void CPDF_DocPageData::ReleaseFont(const CPDF_Dictionary* pFontDict) { - if (!pFontDict) - return; - - auto it = m_FontMap.find(pFontDict); - if (it == m_FontMap.end()) - return; - - CPDF_CountedFont* pFontData = it->second; - if (!pFontData->get()) - return; - - pFontData->RemoveRef(); - if (pFontData->use_count() > 1) - return; - - // We have font data only in m_FontMap cache. Clean it. - pFontData->clear(); -} - -CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace( - CPDF_Object* pCSObj, - const CPDF_Dictionary* pResources) { - std::set visited; - return GetColorSpaceImpl(pCSObj, pResources, &visited); -} - -CPDF_ColorSpace* CPDF_DocPageData::GetColorSpaceImpl( - CPDF_Object* pCSObj, - const CPDF_Dictionary* pResources, - std::set* pVisited) { - if (!pCSObj) - return nullptr; - - if (pdfium::ContainsKey(*pVisited, pCSObj)) - return nullptr; - - if (pCSObj->IsName()) { - CFX_ByteString name = pCSObj->GetString(); - CPDF_ColorSpace* pCS = CPDF_ColorSpace::ColorspaceFromName(name); - if (!pCS && pResources) { - CPDF_Dictionary* pList = pResources->GetDictFor("ColorSpace"); - if (pList) { - pdfium::ScopedSetInsertion insertion(pVisited, pCSObj); - return GetColorSpaceImpl(pList->GetDirectObjectFor(name), nullptr, - pVisited); - } - } - if (!pCS || !pResources) - return pCS; - - CPDF_Dictionary* pColorSpaces = pResources->GetDictFor("ColorSpace"); - if (!pColorSpaces) - return pCS; - - CPDF_Object* pDefaultCS = nullptr; - switch (pCS->GetFamily()) { - case PDFCS_DEVICERGB: - pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB"); - break; - case PDFCS_DEVICEGRAY: - pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultGray"); - break; - case PDFCS_DEVICECMYK: - pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultCMYK"); - break; - } - if (!pDefaultCS) - return pCS; - - pdfium::ScopedSetInsertion insertion(pVisited, pCSObj); - return GetColorSpaceImpl(pDefaultCS, nullptr, pVisited); - } - - CPDF_Array* pArray = pCSObj->AsArray(); - if (!pArray || pArray->IsEmpty()) - return nullptr; - - if (pArray->GetCount() == 1) { - pdfium::ScopedSetInsertion insertion(pVisited, pCSObj); - return GetColorSpaceImpl(pArray->GetDirectObjectAt(0), pResources, - pVisited); - } - - CPDF_CountedColorSpace* csData = nullptr; - auto it = m_ColorSpaceMap.find(pCSObj); - if (it != m_ColorSpaceMap.end()) { - csData = it->second; - if (csData->get()) { - return csData->AddRef(); - } - } - - std::unique_ptr pCS = - CPDF_ColorSpace::Load(m_pPDFDoc, pArray); - if (!pCS) - return nullptr; - - if (!csData) { - csData = new CPDF_CountedColorSpace(pCS.release()); - m_ColorSpaceMap[pCSObj] = csData; - } else { - csData->reset(pCS.release()); - } - return csData->AddRef(); -} - -CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) { - if (!pCSObj) - return nullptr; - - auto it = m_ColorSpaceMap.find(pCSObj); - if (it != m_ColorSpaceMap.end()) - return it->second->AddRef(); - - return nullptr; -} - -void CPDF_DocPageData::ReleaseColorSpace(const CPDF_Object* pColorSpace) { - if (!pColorSpace) - return; - - auto it = m_ColorSpaceMap.find(pColorSpace); - if (it == m_ColorSpaceMap.end()) - return; - - CPDF_CountedColorSpace* pCountedColorSpace = it->second; - if (!pCountedColorSpace->get()) - return; - - pCountedColorSpace->RemoveRef(); - if (pCountedColorSpace->use_count() > 1) - return; - - // We have item only in m_ColorSpaceMap cache. Clean it. - pCountedColorSpace->get()->Release(); - pCountedColorSpace->reset(nullptr); -} - -CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, - FX_BOOL bShading, - const CFX_Matrix& matrix) { - if (!pPatternObj) - return nullptr; - - CPDF_CountedPattern* ptData = nullptr; - auto it = m_PatternMap.find(pPatternObj); - if (it != m_PatternMap.end()) { - ptData = it->second; - if (ptData->get()) { - return ptData->AddRef(); - } - } - CPDF_Pattern* pPattern = nullptr; - if (bShading) { - pPattern = new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, TRUE, matrix); - } else { - CPDF_Dictionary* pDict = pPatternObj ? pPatternObj->GetDict() : nullptr; - if (pDict) { - int type = pDict->GetIntegerFor("PatternType"); - if (type == CPDF_Pattern::TILING) { - pPattern = new CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix); - } else if (type == CPDF_Pattern::SHADING) { - pPattern = - new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix); - } - } - } - if (!pPattern) - return nullptr; - - if (!ptData) { - ptData = new CPDF_CountedPattern(pPattern); - m_PatternMap[pPatternObj] = ptData; - } else { - ptData->reset(pPattern); - } - return ptData->AddRef(); -} - -void CPDF_DocPageData::ReleasePattern(const CPDF_Object* pPatternObj) { - if (!pPatternObj) - return; - - auto it = m_PatternMap.find(pPatternObj); - if (it == m_PatternMap.end()) - return; - - CPDF_CountedPattern* pPattern = it->second; - if (!pPattern->get()) - return; - - pPattern->RemoveRef(); - if (pPattern->use_count() > 1) - return; - - // We have item only in m_PatternMap cache. Clean it. - pPattern->clear(); -} - -CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) { - if (!pImageStream) - return nullptr; - - const uint32_t dwImageObjNum = pImageStream->GetObjNum(); - auto it = m_ImageMap.find(dwImageObjNum); - if (it != m_ImageMap.end()) - return it->second->AddRef(); - - CPDF_CountedImage* pCountedImage = new CPDF_CountedImage( - new CPDF_Image(m_pPDFDoc, pImageStream->AsStream(), false)); - m_ImageMap[dwImageObjNum] = pCountedImage; - return pCountedImage->AddRef(); -} - -void CPDF_DocPageData::ReleaseImage(const CPDF_Object* pImageStream) { - if (!pImageStream) - return; - - uint32_t dwObjNum = pImageStream->GetObjNum(); - if (!dwObjNum) - return; - - auto it = m_ImageMap.find(dwObjNum); - if (it == m_ImageMap.end()) - return; - - CPDF_CountedImage* pCountedImage = it->second; - if (!pCountedImage) - return; - - pCountedImage->RemoveRef(); - if (pCountedImage->use_count() > 1) - return; - - // We have item only in m_ImageMap cache. Clean it. - delete pCountedImage->get(); - delete pCountedImage; - m_ImageMap.erase(it); -} - -CPDF_IccProfile* CPDF_DocPageData::GetIccProfile( - CPDF_Stream* pIccProfileStream) { - if (!pIccProfileStream) - return nullptr; - - auto it = m_IccProfileMap.find(pIccProfileStream); - if (it != m_IccProfileMap.end()) - return it->second->AddRef(); - - CPDF_StreamAcc stream; - stream.LoadAllData(pIccProfileStream, FALSE); - uint8_t digest[20]; - CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest); - CFX_ByteString bsDigest(digest, 20); - auto hash_it = m_HashProfileMap.find(bsDigest); - if (hash_it != m_HashProfileMap.end()) { - auto it_copied_stream = m_IccProfileMap.find(hash_it->second); - if (it_copied_stream != m_IccProfileMap.end()) - return it_copied_stream->second->AddRef(); - } - CPDF_IccProfile* pProfile = - new CPDF_IccProfile(stream.GetData(), stream.GetSize()); - CPDF_CountedIccProfile* ipData = new CPDF_CountedIccProfile(pProfile); - m_IccProfileMap[pIccProfileStream] = ipData; - m_HashProfileMap[bsDigest] = pIccProfileStream; - return ipData->AddRef(); -} - -void CPDF_DocPageData::ReleaseIccProfile(const CPDF_IccProfile* pIccProfile) { - ASSERT(pIccProfile); - - for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end(); ++it) { - CPDF_CountedIccProfile* profile = it->second; - if (profile->get() != pIccProfile) - continue; - - profile->RemoveRef(); - if (profile->use_count() > 1) - continue; - // We have item only in m_IccProfileMap cache. Clean it. - delete profile->get(); - delete profile; - m_IccProfileMap.erase(it); - return; - } -} - -CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc( - CPDF_Stream* pFontStream) { - ASSERT(pFontStream); - - auto it = m_FontFileMap.find(pFontStream); - if (it != m_FontFileMap.end()) - return it->second->AddRef(); - - CPDF_Dictionary* pFontDict = pFontStream->GetDict(); - int32_t org_size = pFontDict->GetIntegerFor("Length1") + - pFontDict->GetIntegerFor("Length2") + - pFontDict->GetIntegerFor("Length3"); - org_size = std::max(org_size, 0); - - CPDF_StreamAcc* pFontFile = new CPDF_StreamAcc; - pFontFile->LoadAllData(pFontStream, FALSE, org_size); - - CPDF_CountedStreamAcc* pCountedFont = new CPDF_CountedStreamAcc(pFontFile); - m_FontFileMap[pFontStream] = pCountedFont; - return pCountedFont->AddRef(); -} - -void CPDF_DocPageData::ReleaseFontFileStreamAcc( - const CPDF_Stream* pFontStream) { - if (!pFontStream) - return; - - auto it = m_FontFileMap.find(pFontStream); - if (it == m_FontFileMap.end()) - return; - - CPDF_CountedStreamAcc* pCountedStream = it->second; - if (!pCountedStream) - return; - - pCountedStream->RemoveRef(); - if (pCountedStream->use_count() > 1) - return; - - // We have item only in m_FontFileMap cache. Clean it. - delete pCountedStream->get(); - delete pCountedStream; - m_FontFileMap.erase(it); -} - -CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr( - CPDF_Object* pCSObj) const { - if (!pCSObj) - return nullptr; - - auto it = m_ColorSpaceMap.find(pCSObj); - return it != m_ColorSpaceMap.end() ? it->second : nullptr; -} - -CPDF_CountedPattern* CPDF_DocPageData::FindPatternPtr( - CPDF_Object* pPatternObj) const { - if (!pPatternObj) - return nullptr; - - auto it = m_PatternMap.find(pPatternObj); - return it != m_PatternMap.end() ? it->second : nullptr; -} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp deleted file mode 100644 index eb487577c8..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp +++ /dev/null @@ -1,846 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/pageint.h" - -#include - -#include -#include -#include -#include - -#include "core/fpdfapi/fpdf_page/cpdf_psengine.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fxcrt/fx_safe_types.h" -#include "third_party/base/numerics/safe_conversions_impl.h" - -class CPDF_PSOP { - public: - explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) { - ASSERT(m_op != PSOP_CONST); - ASSERT(m_op != PSOP_PROC); - } - explicit CPDF_PSOP(FX_FLOAT value) : m_op(PSOP_CONST), m_value(value) {} - explicit CPDF_PSOP(std::unique_ptr proc) - : m_op(PSOP_PROC), m_value(0), m_proc(std::move(proc)) {} - - FX_FLOAT GetFloatValue() const { - if (m_op == PSOP_CONST) - return m_value; - - ASSERT(false); - return 0; - } - CPDF_PSProc* GetProc() const { - if (m_op == PSOP_PROC) - return m_proc.get(); - ASSERT(false); - return nullptr; - } - - PDF_PSOP GetOp() const { return m_op; } - - private: - const PDF_PSOP m_op; - const FX_FLOAT m_value; - std::unique_ptr m_proc; -}; - -FX_BOOL CPDF_PSEngine::Execute() { - return m_MainProc.Execute(this); -} - -CPDF_PSProc::CPDF_PSProc() {} -CPDF_PSProc::~CPDF_PSProc() {} - -FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) { - for (size_t i = 0; i < m_Operators.size(); ++i) { - const PDF_PSOP op = m_Operators[i]->GetOp(); - if (op == PSOP_PROC) - continue; - - if (op == PSOP_CONST) { - pEngine->Push(m_Operators[i]->GetFloatValue()); - continue; - } - - if (op == PSOP_IF) { - if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC) - return FALSE; - - if (static_cast(pEngine->Pop())) - m_Operators[i - 1]->GetProc()->Execute(pEngine); - } else if (op == PSOP_IFELSE) { - if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC || - m_Operators[i - 2]->GetOp() != PSOP_PROC) { - return FALSE; - } - size_t offset = static_cast(pEngine->Pop()) ? 2 : 1; - m_Operators[i - offset]->GetProc()->Execute(pEngine); - } else { - pEngine->DoOperator(op); - } - } - return TRUE; -} - -CPDF_PSEngine::CPDF_PSEngine() { - m_StackCount = 0; -} -CPDF_PSEngine::~CPDF_PSEngine() {} -void CPDF_PSEngine::Push(FX_FLOAT v) { - if (m_StackCount == PSENGINE_STACKSIZE) { - return; - } - m_Stack[m_StackCount++] = v; -} -FX_FLOAT CPDF_PSEngine::Pop() { - if (m_StackCount == 0) { - return 0; - } - return m_Stack[--m_StackCount]; -} -const struct PDF_PSOpName { - const FX_CHAR* name; - PDF_PSOP op; -} PDF_PSOpNames[] = {{"add", PSOP_ADD}, {"sub", PSOP_SUB}, - {"mul", PSOP_MUL}, {"div", PSOP_DIV}, - {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD}, - {"neg", PSOP_NEG}, {"abs", PSOP_ABS}, - {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR}, - {"round", PSOP_ROUND}, {"truncate", PSOP_TRUNCATE}, - {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN}, - {"cos", PSOP_COS}, {"atan", PSOP_ATAN}, - {"exp", PSOP_EXP}, {"ln", PSOP_LN}, - {"log", PSOP_LOG}, {"cvi", PSOP_CVI}, - {"cvr", PSOP_CVR}, {"eq", PSOP_EQ}, - {"ne", PSOP_NE}, {"gt", PSOP_GT}, - {"ge", PSOP_GE}, {"lt", PSOP_LT}, - {"le", PSOP_LE}, {"and", PSOP_AND}, - {"or", PSOP_OR}, {"xor", PSOP_XOR}, - {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT}, - {"true", PSOP_TRUE}, {"false", PSOP_FALSE}, - {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE}, - {"pop", PSOP_POP}, {"exch", PSOP_EXCH}, - {"dup", PSOP_DUP}, {"copy", PSOP_COPY}, - {"index", PSOP_INDEX}, {"roll", PSOP_ROLL}}; - -FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* str, int size) { - CPDF_SimpleParser parser((uint8_t*)str, size); - CFX_ByteStringC word = parser.GetWord(); - if (word != "{") { - return FALSE; - } - return m_MainProc.Parse(&parser, 0); -} - -FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser* parser, int depth) { - if (depth > kMaxDepth) - return FALSE; - - while (1) { - CFX_ByteStringC word = parser->GetWord(); - if (word.IsEmpty()) { - return FALSE; - } - if (word == "}") { - return TRUE; - } - if (word == "{") { - std::unique_ptr proc(new CPDF_PSProc); - std::unique_ptr op(new CPDF_PSOP(std::move(proc))); - m_Operators.push_back(std::move(op)); - if (!m_Operators.back()->GetProc()->Parse(parser, depth + 1)) { - return FALSE; - } - } else { - bool found = false; - for (const PDF_PSOpName& op_name : PDF_PSOpNames) { - if (word == CFX_ByteStringC(op_name.name)) { - std::unique_ptr op(new CPDF_PSOP(op_name.op)); - m_Operators.push_back(std::move(op)); - found = true; - break; - } - } - if (!found) { - std::unique_ptr op(new CPDF_PSOP(FX_atof(word))); - m_Operators.push_back(std::move(op)); - } - } - } -} - -FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) { - int i1, i2; - FX_FLOAT d1, d2; - switch (op) { - case PSOP_ADD: - d1 = Pop(); - d2 = Pop(); - Push(d1 + d2); - break; - case PSOP_SUB: - d2 = Pop(); - d1 = Pop(); - Push(d1 - d2); - break; - case PSOP_MUL: - d1 = Pop(); - d2 = Pop(); - Push(d1 * d2); - break; - case PSOP_DIV: - d2 = Pop(); - d1 = Pop(); - Push(d1 / d2); - break; - case PSOP_IDIV: - i2 = (int)Pop(); - i1 = (int)Pop(); - Push(i2 ? i1 / i2 : 0); - break; - case PSOP_MOD: - i2 = (int)Pop(); - i1 = (int)Pop(); - Push(i2 ? i1 % i2 : 0); - break; - case PSOP_NEG: - d1 = Pop(); - Push(-d1); - break; - case PSOP_ABS: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_fabs(d1)); - break; - case PSOP_CEILING: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_ceil(d1)); - break; - case PSOP_FLOOR: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_floor(d1)); - break; - case PSOP_ROUND: - d1 = Pop(); - Push(FXSYS_round(d1)); - break; - case PSOP_TRUNCATE: - i1 = (int)Pop(); - Push(i1); - break; - case PSOP_SQRT: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_sqrt(d1)); - break; - case PSOP_SIN: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_sin(d1 * FX_PI / 180.0f)); - break; - case PSOP_COS: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_cos(d1 * FX_PI / 180.0f)); - break; - case PSOP_ATAN: - d2 = Pop(); - d1 = Pop(); - d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / FX_PI); - if (d1 < 0) { - d1 += 360; - } - Push(d1); - break; - case PSOP_EXP: - d2 = Pop(); - d1 = Pop(); - Push((FX_FLOAT)FXSYS_pow(d1, d2)); - break; - case PSOP_LN: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_log(d1)); - break; - case PSOP_LOG: - d1 = Pop(); - Push((FX_FLOAT)FXSYS_log10(d1)); - break; - case PSOP_CVI: - i1 = (int)Pop(); - Push(i1); - break; - case PSOP_CVR: - break; - case PSOP_EQ: - d2 = Pop(); - d1 = Pop(); - Push((int)(d1 == d2)); - break; - case PSOP_NE: - d2 = Pop(); - d1 = Pop(); - Push((int)(d1 != d2)); - break; - case PSOP_GT: - d2 = Pop(); - d1 = Pop(); - Push((int)(d1 > d2)); - break; - case PSOP_GE: - d2 = Pop(); - d1 = Pop(); - Push((int)(d1 >= d2)); - break; - case PSOP_LT: - d2 = Pop(); - d1 = Pop(); - Push((int)(d1 < d2)); - break; - case PSOP_LE: - d2 = Pop(); - d1 = Pop(); - Push((int)(d1 <= d2)); - break; - case PSOP_AND: - i1 = (int)Pop(); - i2 = (int)Pop(); - Push(i1 & i2); - break; - case PSOP_OR: - i1 = (int)Pop(); - i2 = (int)Pop(); - Push(i1 | i2); - break; - case PSOP_XOR: - i1 = (int)Pop(); - i2 = (int)Pop(); - Push(i1 ^ i2); - break; - case PSOP_NOT: - i1 = (int)Pop(); - Push((int)!i1); - break; - case PSOP_BITSHIFT: { - int shift = (int)Pop(); - int i = (int)Pop(); - if (shift > 0) { - Push(i << shift); - } else { - Push(i >> -shift); - } - break; - } - case PSOP_TRUE: - Push(1); - break; - case PSOP_FALSE: - Push(0); - break; - case PSOP_POP: - Pop(); - break; - case PSOP_EXCH: - d2 = Pop(); - d1 = Pop(); - Push(d2); - Push(d1); - break; - case PSOP_DUP: - d1 = Pop(); - Push(d1); - Push(d1); - break; - case PSOP_COPY: { - int n = static_cast(Pop()); - if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE || - n > static_cast(m_StackCount)) - break; - for (int i = 0; i < n; i++) - m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n]; - m_StackCount += n; - break; - } - case PSOP_INDEX: { - int n = static_cast(Pop()); - if (n < 0 || n >= static_cast(m_StackCount)) - break; - Push(m_Stack[m_StackCount - n - 1]); - break; - } - case PSOP_ROLL: { - int j = static_cast(Pop()); - int n = static_cast(Pop()); - if (m_StackCount == 0) - break; - if (n < 0 || n > static_cast(m_StackCount)) - break; - if (j < 0) { - for (int i = 0; i < -j; i++) { - FX_FLOAT first = m_Stack[m_StackCount - n]; - for (int ii = 0; ii < n - 1; ii++) - m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1]; - m_Stack[m_StackCount - 1] = first; - } - } else { - for (int i = 0; i < j; i++) { - FX_FLOAT last = m_Stack[m_StackCount - 1]; - int ii; - for (ii = 0; ii < n - 1; ii++) - m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2]; - m_Stack[m_StackCount - ii - 1] = last; - } - } - break; - } - default: - break; - } - return TRUE; -} - -// See PDF Reference 1.7, page 170, table 3.36. -bool IsValidBitsPerSample(uint32_t x) { - switch (x) { - case 1: - case 2: - case 4: - case 8: - case 12: - case 16: - case 24: - case 32: - return true; - default: - return false; - } -} - -// See PDF Reference 1.7, page 170. -FX_FLOAT PDF_Interpolate(FX_FLOAT x, - FX_FLOAT xmin, - FX_FLOAT xmax, - FX_FLOAT ymin, - FX_FLOAT ymax) { - FX_FLOAT divisor = xmax - xmin; - return ymin + (divisor ? (x - xmin) * (ymax - ymin) / divisor : 0); -} - -class CPDF_PSFunc : public CPDF_Function { - public: - CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {} - ~CPDF_PSFunc() override {} - - // CPDF_Function - FX_BOOL v_Init(CPDF_Object* pObj) override; - FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; - - private: - CPDF_PSEngine m_PS; -}; - -FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) { - CPDF_StreamAcc acc; - acc.LoadAllData(pObj->AsStream(), FALSE); - return m_PS.Parse(reinterpret_cast(acc.GetData()), - acc.GetSize()); -} - -FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { - CPDF_PSEngine& PS = const_cast(m_PS); - PS.Reset(); - for (uint32_t i = 0; i < m_nInputs; i++) - PS.Push(inputs[i]); - PS.Execute(); - if (PS.GetStackSize() < m_nOutputs) - return FALSE; - for (uint32_t i = 0; i < m_nOutputs; i++) - results[m_nOutputs - i - 1] = PS.Pop(); - return TRUE; -} - - -CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {} - -CPDF_SampledFunc::~CPDF_SampledFunc() {} - -FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { - CPDF_Stream* pStream = pObj->AsStream(); - if (!pStream) - return false; - - CPDF_Dictionary* pDict = pStream->GetDict(); - CPDF_Array* pSize = pDict->GetArrayFor("Size"); - CPDF_Array* pEncode = pDict->GetArrayFor("Encode"); - CPDF_Array* pDecode = pDict->GetArrayFor("Decode"); - m_nBitsPerSample = pDict->GetIntegerFor("BitsPerSample"); - if (!IsValidBitsPerSample(m_nBitsPerSample)) - return FALSE; - - m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); - m_pSampleStream.reset(new CPDF_StreamAcc); - m_pSampleStream->LoadAllData(pStream, FALSE); - FX_SAFE_UINT32 nTotalSampleBits = 1; - m_EncodeInfo.resize(m_nInputs); - for (uint32_t i = 0; i < m_nInputs; i++) { - m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; - if (!pSize && i == 0) - m_EncodeInfo[i].sizes = pDict->GetIntegerFor("Size"); - nTotalSampleBits *= m_EncodeInfo[i].sizes; - if (pEncode) { - m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); - m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); - } else { - m_EncodeInfo[i].encode_min = 0; - m_EncodeInfo[i].encode_max = - m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1; - } - } - nTotalSampleBits *= m_nBitsPerSample; - nTotalSampleBits *= m_nOutputs; - FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; - nTotalSampleBytes += 7; - nTotalSampleBytes /= 8; - if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || - nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { - return FALSE; - } - m_DecodeInfo.resize(m_nOutputs); - for (uint32_t i = 0; i < m_nOutputs; i++) { - if (pDecode) { - m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); - m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); - } else { - m_DecodeInfo[i].decode_min = m_pRanges[i * 2]; - m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; - } - } - return TRUE; -} - -FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { - int pos = 0; - CFX_FixedBufGrow encoded_input_buf(m_nInputs); - FX_FLOAT* encoded_input = encoded_input_buf; - CFX_FixedBufGrow int_buf(m_nInputs * 2); - uint32_t* index = int_buf; - uint32_t* blocksize = index + m_nInputs; - for (uint32_t i = 0; i < m_nInputs; i++) { - if (i == 0) - blocksize[i] = 1; - else - blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes; - encoded_input[i] = - PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], - m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max); - index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), - m_EncodeInfo[i].sizes - 1); - pos += index[i] * blocksize[i]; - } - FX_SAFE_INT32 bits_to_output = m_nOutputs; - bits_to_output *= m_nBitsPerSample; - if (!bits_to_output.IsValid()) - return FALSE; - - FX_SAFE_INT32 bitpos = pos; - bitpos *= bits_to_output.ValueOrDie(); - if (!bitpos.IsValid()) - return FALSE; - - FX_SAFE_INT32 range_check = bitpos; - range_check += bits_to_output.ValueOrDie(); - if (!range_check.IsValid()) - return FALSE; - - const uint8_t* pSampleData = m_pSampleStream->GetData(); - if (!pSampleData) - return FALSE; - - for (uint32_t j = 0; j < m_nOutputs; j++) { - uint32_t sample = - GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, - m_nBitsPerSample); - FX_FLOAT encoded = (FX_FLOAT)sample; - for (uint32_t i = 0; i < m_nInputs; i++) { - if (index[i] == m_EncodeInfo[i].sizes - 1) { - if (index[i] == 0) - encoded = encoded_input[i] * (FX_FLOAT)sample; - } else { - FX_SAFE_INT32 bitpos2 = blocksize[i]; - bitpos2 += pos; - bitpos2 *= m_nOutputs; - bitpos2 += j; - bitpos2 *= m_nBitsPerSample; - if (!bitpos2.IsValid()) - return FALSE; - uint32_t sample1 = - GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); - encoded += (encoded_input[i] - index[i]) * - ((FX_FLOAT)sample1 - (FX_FLOAT)sample); - } - } - results[j] = - PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, - m_DecodeInfo[j].decode_min, m_DecodeInfo[j].decode_max); - } - return TRUE; -} - -CPDF_ExpIntFunc::CPDF_ExpIntFunc() - : CPDF_Function(Type::kType2ExpotentialInterpolation), - m_pBeginValues(nullptr), - m_pEndValues(nullptr) {} - -CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { - FX_Free(m_pBeginValues); - FX_Free(m_pEndValues); -} -FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { - CPDF_Dictionary* pDict = pObj->GetDict(); - if (!pDict) { - return FALSE; - } - CPDF_Array* pArray0 = pDict->GetArrayFor("C0"); - if (m_nOutputs == 0) { - m_nOutputs = 1; - if (pArray0) { - m_nOutputs = pArray0->GetCount(); - } - } - CPDF_Array* pArray1 = pDict->GetArrayFor("C1"); - m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); - m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); - for (uint32_t i = 0; i < m_nOutputs; i++) { - m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f; - m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f; - } - m_Exponent = pDict->GetFloatFor("N"); - m_nOrigOutputs = m_nOutputs; - if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) { - return FALSE; - } - m_nOutputs *= m_nInputs; - return TRUE; -} -FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { - for (uint32_t i = 0; i < m_nInputs; i++) - for (uint32_t j = 0; j < m_nOrigOutputs; j++) { - results[i * m_nOrigOutputs + j] = - m_pBeginValues[j] + - (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * - (m_pEndValues[j] - m_pBeginValues[j]); - } - return TRUE; -} - -CPDF_StitchFunc::CPDF_StitchFunc() - : CPDF_Function(Type::kType3Stitching), - m_pBounds(nullptr), - m_pEncode(nullptr) {} - -CPDF_StitchFunc::~CPDF_StitchFunc() { - FX_Free(m_pBounds); - FX_Free(m_pEncode); -} - -FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { - CPDF_Dictionary* pDict = pObj->GetDict(); - if (!pDict) { - return FALSE; - } - if (m_nInputs != kRequiredNumInputs) { - return FALSE; - } - CPDF_Array* pArray = pDict->GetArrayFor("Functions"); - if (!pArray) { - return FALSE; - } - uint32_t nSubs = pArray->GetCount(); - if (nSubs == 0) - return FALSE; - m_nOutputs = 0; - for (uint32_t i = 0; i < nSubs; i++) { - CPDF_Object* pSub = pArray->GetDirectObjectAt(i); - if (pSub == pObj) - return FALSE; - std::unique_ptr pFunc(CPDF_Function::Load(pSub)); - if (!pFunc) - return FALSE; - // Check that the input dimensionality is 1, and that all output - // dimensionalities are the same. - if (pFunc->CountInputs() != kRequiredNumInputs) - return FALSE; - if (pFunc->CountOutputs() != m_nOutputs) { - if (m_nOutputs) - return FALSE; - - m_nOutputs = pFunc->CountOutputs(); - } - - m_pSubFunctions.push_back(std::move(pFunc)); - } - m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); - m_pBounds[0] = m_pDomains[0]; - pArray = pDict->GetArrayFor("Bounds"); - if (!pArray) - return FALSE; - for (uint32_t i = 0; i < nSubs - 1; i++) - m_pBounds[i + 1] = pArray->GetFloatAt(i); - m_pBounds[nSubs] = m_pDomains[1]; - m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); - pArray = pDict->GetArrayFor("Encode"); - if (!pArray) - return FALSE; - - for (uint32_t i = 0; i < nSubs * 2; i++) - m_pEncode[i] = pArray->GetFloatAt(i); - return TRUE; -} - -FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { - FX_FLOAT input = inputs[0]; - size_t i; - for (i = 0; i < m_pSubFunctions.size() - 1; i++) { - if (input < m_pBounds[i + 1]) - break; - } - input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], - m_pEncode[i * 2], m_pEncode[i * 2 + 1]); - int nresults; - m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); - return TRUE; -} - -// static -std::unique_ptr CPDF_Function::Load(CPDF_Object* pFuncObj) { - std::unique_ptr pFunc; - if (!pFuncObj) - return pFunc; - - int iType = -1; - if (CPDF_Stream* pStream = pFuncObj->AsStream()) - iType = pStream->GetDict()->GetIntegerFor("FunctionType"); - else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary()) - iType = pDict->GetIntegerFor("FunctionType"); - - Type type = IntegerToFunctionType(iType); - if (type == Type::kType0Sampled) - pFunc.reset(new CPDF_SampledFunc()); - else if (type == Type::kType2ExpotentialInterpolation) - pFunc.reset(new CPDF_ExpIntFunc()); - else if (type == Type::kType3Stitching) - pFunc.reset(new CPDF_StitchFunc()); - else if (type == Type::kType4PostScript) - pFunc.reset(new CPDF_PSFunc()); - - if (!pFunc || !pFunc->Init(pFuncObj)) - return std::unique_ptr(); - return pFunc; -} - -// static -CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) { - switch (iType) { - case 0: - case 2: - case 3: - case 4: - return static_cast(iType); - default: - return Type::kTypeInvalid; - } -} - -CPDF_Function::CPDF_Function(Type type) - : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {} - -CPDF_Function::~CPDF_Function() { - FX_Free(m_pDomains); - FX_Free(m_pRanges); -} - -FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { - CPDF_Stream* pStream = pObj->AsStream(); - CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); - - CPDF_Array* pDomains = pDict->GetArrayFor("Domain"); - if (!pDomains) - return FALSE; - - m_nInputs = pDomains->GetCount() / 2; - if (m_nInputs == 0) - return FALSE; - - m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2); - for (uint32_t i = 0; i < m_nInputs * 2; i++) { - m_pDomains[i] = pDomains->GetFloatAt(i); - } - CPDF_Array* pRanges = pDict->GetArrayFor("Range"); - m_nOutputs = 0; - if (pRanges) { - m_nOutputs = pRanges->GetCount() / 2; - m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); - for (uint32_t i = 0; i < m_nOutputs * 2; i++) - m_pRanges[i] = pRanges->GetFloatAt(i); - } - uint32_t old_outputs = m_nOutputs; - if (!v_Init(pObj)) - return FALSE; - if (m_pRanges && m_nOutputs > old_outputs) { - m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); - if (m_pRanges) { - FXSYS_memset(m_pRanges + (old_outputs * 2), 0, - sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); - } - } - return TRUE; -} - -FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, - uint32_t ninputs, - FX_FLOAT* results, - int& nresults) const { - if (m_nInputs != ninputs) { - return FALSE; - } - nresults = m_nOutputs; - for (uint32_t i = 0; i < m_nInputs; i++) { - if (inputs[i] < m_pDomains[i * 2]) - inputs[i] = m_pDomains[i * 2]; - else if (inputs[i] > m_pDomains[i * 2 + 1]) - inputs[i] = m_pDomains[i * 2] + 1; - } - v_Call(inputs, results); - if (m_pRanges) { - for (uint32_t i = 0; i < m_nOutputs; i++) { - if (results[i] < m_pRanges[i * 2]) - results[i] = m_pRanges[i * 2]; - else if (results[i] > m_pRanges[i * 2 + 1]) - results[i] = m_pRanges[i * 2 + 1]; - } - } - return TRUE; -} - -const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const { - return m_Type == Type::kType0Sampled - ? static_cast(this) - : nullptr; -} - -const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const { - return m_Type == Type::kType2ExpotentialInterpolation - ? static_cast(this) - : nullptr; -} - -const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const { - return m_Type == Type::kType3Stitching - ? static_cast(this) - : nullptr; -} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp deleted file mode 100644 index 2892036882..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_func_embeddertest.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "testing/embedder_test.h" -#include "testing/gtest/include/gtest/gtest.h" - -class FPDFPageFuncEmbeddertest : public EmbedderTest {}; - -TEST_F(FPDFPageFuncEmbeddertest, Bug_551460) { - // Should not crash under ASan. - // Tests that the number of inputs is not simply calculated from the domain - // and trusted. The number of inputs has to be 1. - EXPECT_TRUE(OpenDocument("bug_551460.pdf")); - FPDF_PAGE page = LoadPage(0); - EXPECT_NE(nullptr, page); - FPDF_BITMAP bitmap = RenderPage(page); - FPDFBitmap_Destroy(bitmap); - UnloadPage(page); -} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp deleted file mode 100644 index c0059b8a77..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ /dev/null @@ -1,1683 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/pageint.h" - -#include -#include -#include - -#include "core/fpdfapi/edit/cpdf_creator.h" -#include "core/fpdfapi/font/cpdf_font.h" -#include "core/fpdfapi/font/cpdf_type3font.h" -#include "core/fpdfapi/fpdf_page/cpdf_allstates.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_formobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pathobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_shadingobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" -#include "core/fpdfapi/fpdf_page/cpdf_textobject.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_name.h" -#include "core/fpdfapi/fpdf_parser/cpdf_number.h" -#include "core/fpdfapi/fpdf_parser/cpdf_reference.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" -#include "core/fxcrt/fx_safe_types.h" -#include "core/fxge/cfx_graphstatedata.h" -#include "core/fxge/cfx_pathdata.h" -#include "third_party/base/ptr_util.h" - -namespace { - -const int kSingleCoordinatePair = 1; -const int kTensorCoordinatePairs = 16; -const int kCoonsCoordinatePairs = 12; -const int kSingleColorPerPatch = 1; -const int kQuadColorsPerPatch = 4; - -const char kPathOperatorSubpath = 'm'; -const char kPathOperatorLine = 'l'; -const char kPathOperatorCubicBezier1 = 'c'; -const char kPathOperatorCubicBezier2 = 'v'; -const char kPathOperatorCubicBezier3 = 'y'; -const char kPathOperatorClosePath = 'h'; -const char kPathOperatorRectangle[] = "re"; - -struct PDF_AbbrPair { - const FX_CHAR* abbr; - const FX_CHAR* full_name; -}; - -const PDF_AbbrPair PDF_InlineKeyAbbr[] = { - {"BPC", "BitsPerComponent"}, {"CS", "ColorSpace"}, {"D", "Decode"}, - {"DP", "DecodeParms"}, {"F", "Filter"}, {"H", "Height"}, - {"IM", "ImageMask"}, {"I", "Interpolate"}, {"W", "Width"}, -}; - -const PDF_AbbrPair PDF_InlineValueAbbr[] = { - {"G", "DeviceGray"}, {"RGB", "DeviceRGB"}, - {"CMYK", "DeviceCMYK"}, {"I", "Indexed"}, - {"AHx", "ASCIIHexDecode"}, {"A85", "ASCII85Decode"}, - {"LZW", "LZWDecode"}, {"Fl", "FlateDecode"}, - {"RL", "RunLengthDecode"}, {"CCF", "CCITTFaxDecode"}, - {"DCT", "DCTDecode"}, -}; - -struct AbbrReplacementOp { - bool is_replace_key; - CFX_ByteString key; - CFX_ByteStringC replacement; -}; - -class CPDF_StreamParserAutoClearer { - public: - CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable, - CPDF_StreamParser* new_parser) - : scoped_variable_(scoped_variable) { - *scoped_variable_ = new_parser; - } - ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = nullptr; } - - private: - CPDF_StreamParser** scoped_variable_; -}; - -CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, - size_t count, - const CFX_ByteStringC& abbr) { - auto it = std::find_if( - table, table + count, - [abbr](const PDF_AbbrPair& pair) { return pair.abbr == abbr; }); - return it != table + count ? CFX_ByteStringC(it->full_name) - : CFX_ByteStringC(); -} - -CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, - const CFX_Matrix& matrix) { - ShadingType type = pShading->GetShadingType(); - CPDF_Stream* pStream = ToStream(pShading->GetShadingObject()); - CPDF_ColorSpace* pCS = pShading->GetCS(); - if (!pStream || !pCS) - return CFX_FloatRect(0, 0, 0, 0); - - CPDF_MeshStream stream(type, pShading->GetFuncs(), pStream, pCS); - if (!stream.Load()) - return CFX_FloatRect(0, 0, 0, 0); - - CFX_FloatRect rect; - bool bStarted = false; - bool bGouraud = type == kFreeFormGouraudTriangleMeshShading || - type == kLatticeFormGouraudTriangleMeshShading; - - int point_count = kSingleCoordinatePair; - if (type == kTensorProductPatchMeshShading) - point_count = kTensorCoordinatePairs; - else if (type == kCoonsPatchMeshShading) - point_count = kCoonsCoordinatePairs; - - int color_count = kSingleColorPerPatch; - if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading) - color_count = kQuadColorsPerPatch; - - while (!stream.BitStream()->IsEOF()) { - uint32_t flag = 0; - if (type != kLatticeFormGouraudTriangleMeshShading) - flag = stream.GetFlag(); - - if (!bGouraud && flag) { - point_count -= 4; - color_count -= 2; - } - - for (int i = 0; i < point_count; i++) { - FX_FLOAT x; - FX_FLOAT y; - stream.GetCoords(x, y); - if (bStarted) { - rect.UpdateRect(x, y); - } else { - rect.InitRect(x, y); - bStarted = true; - } - } - FX_SAFE_UINT32 nBits = stream.Components(); - nBits *= stream.ComponentBits(); - nBits *= color_count; - if (!nBits.IsValid()) - break; - - stream.BitStream()->SkipBits(nBits.ValueOrDie()); - if (bGouraud) - stream.BitStream()->ByteAlign(); - } - rect.Transform(&matrix); - return rect; -} - -} // namespace - -CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { - return PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), - abbr); -} - -CFX_ByteStringC PDF_FindValueAbbreviationForTesting( - const CFX_ByteStringC& abbr) { - return PDF_FindFullName(PDF_InlineValueAbbr, - FX_ArraySize(PDF_InlineValueAbbr), abbr); -} - -bool IsPathOperator(const uint8_t* buf, size_t len) { - if (len == 1) { - uint8_t op = buf[0]; - return op == kPathOperatorSubpath || op == kPathOperatorLine || - op == kPathOperatorCubicBezier1 || op == kPathOperatorCubicBezier2 || - op == kPathOperatorCubicBezier3; - } - if (len == 2) { - return buf[0] == kPathOperatorRectangle[0] && - buf[1] == kPathOperatorRectangle[1]; - } - return false; -} - -CPDF_StreamContentParser::CPDF_StreamContentParser( - CPDF_Document* pDocument, - CPDF_Dictionary* pPageResources, - CPDF_Dictionary* pParentResources, - const CFX_Matrix* pmtContentToUser, - CPDF_PageObjectHolder* pObjHolder, - CPDF_Dictionary* pResources, - CFX_FloatRect* pBBox, - CPDF_AllStates* pStates, - int level) - : m_pDocument(pDocument), - m_pPageResources(pPageResources), - m_pParentResources(pParentResources), - m_pResources(pResources), - m_pObjectHolder(pObjHolder), - m_Level(level), - m_ParamStartPos(0), - m_ParamCount(0), - m_pCurStates(new CPDF_AllStates), - m_pLastTextObject(nullptr), - m_DefFontSize(0), - m_pPathPoints(nullptr), - m_PathPointCount(0), - m_PathAllocSize(0), - m_PathCurrentX(0.0f), - m_PathCurrentY(0.0f), - m_PathClipType(0), - m_pLastImage(nullptr), - m_pLastImageDict(nullptr), - m_pLastCloneImageDict(nullptr), - m_bReleaseLastDict(TRUE), - m_bColored(FALSE), - m_bResourceMissing(FALSE) { - if (pmtContentToUser) - m_mtContentToUser = *pmtContentToUser; - if (!m_pResources) - m_pResources = m_pParentResources; - if (!m_pResources) - m_pResources = m_pPageResources; - if (pBBox) - m_BBox = *pBBox; - if (pStates) { - m_pCurStates->Copy(*pStates); - } else { - m_pCurStates->m_GeneralState.Emplace(); - m_pCurStates->m_GraphState.Emplace(); - m_pCurStates->m_TextState.Emplace(); - m_pCurStates->m_ColorState.Emplace(); - } - for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) { - m_Type3Data[i] = 0.0; - } -} - -CPDF_StreamContentParser::~CPDF_StreamContentParser() { - ClearAllParams(); - FX_Free(m_pPathPoints); - if (m_pLastImageDict) { - m_pLastImageDict->Release(); - } - if (m_pLastCloneImageDict) { - m_pLastCloneImageDict->Release(); - } -} - -int CPDF_StreamContentParser::GetNextParamPos() { - if (m_ParamCount == PARAM_BUF_SIZE) { - m_ParamStartPos++; - if (m_ParamStartPos == PARAM_BUF_SIZE) { - m_ParamStartPos = 0; - } - if (m_ParamBuf[m_ParamStartPos].m_Type == 0) { - if (CPDF_Object* pObject = m_ParamBuf[m_ParamStartPos].m_pObject) - pObject->Release(); - } - return m_ParamStartPos; - } - int index = m_ParamStartPos + m_ParamCount; - if (index >= PARAM_BUF_SIZE) { - index -= PARAM_BUF_SIZE; - } - m_ParamCount++; - return index; -} - -void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) { - CFX_ByteStringC bsName(name, len); - ContentParam& param = m_ParamBuf[GetNextParamPos()]; - if (len > 32) { - param.m_Type = ContentParam::OBJECT; - param.m_pObject = new CPDF_Name( - m_pDocument->GetByteStringPool()->Intern(PDF_NameDecode(bsName))); - } else { - param.m_Type = ContentParam::NAME; - if (bsName.Find('#') == -1) { - FXSYS_memcpy(param.m_Name.m_Buffer, name, len); - param.m_Name.m_Len = len; - } else { - CFX_ByteString str = PDF_NameDecode(bsName); - FXSYS_memcpy(param.m_Name.m_Buffer, str.c_str(), str.GetLength()); - param.m_Name.m_Len = str.GetLength(); - } - } -} - -void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len) { - ContentParam& param = m_ParamBuf[GetNextParamPos()]; - param.m_Type = ContentParam::NUMBER; - param.m_Number.m_bInteger = - FX_atonum(CFX_ByteStringC(str, len), ¶m.m_Number.m_Integer); -} - -void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) { - ContentParam& param = m_ParamBuf[GetNextParamPos()]; - param.m_Type = ContentParam::OBJECT; - param.m_pObject = pObj; -} - -void CPDF_StreamContentParser::ClearAllParams() { - uint32_t index = m_ParamStartPos; - for (uint32_t i = 0; i < m_ParamCount; i++) { - if (m_ParamBuf[index].m_Type == 0) { - if (CPDF_Object* pObject = m_ParamBuf[index].m_pObject) - pObject->Release(); - } - index++; - if (index == PARAM_BUF_SIZE) { - index = 0; - } - } - m_ParamStartPos = 0; - m_ParamCount = 0; -} - -CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) { - if (index >= m_ParamCount) { - return nullptr; - } - int real_index = m_ParamStartPos + m_ParamCount - index - 1; - if (real_index >= PARAM_BUF_SIZE) { - real_index -= PARAM_BUF_SIZE; - } - ContentParam& param = m_ParamBuf[real_index]; - if (param.m_Type == ContentParam::NUMBER) { - CPDF_Number* pNumber = param.m_Number.m_bInteger - ? new CPDF_Number(param.m_Number.m_Integer) - : new CPDF_Number(param.m_Number.m_Float); - - param.m_Type = ContentParam::OBJECT; - param.m_pObject = pNumber; - return pNumber; - } - if (param.m_Type == ContentParam::NAME) { - CPDF_Name* pName = new CPDF_Name(m_pDocument->GetByteStringPool()->Intern( - CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len))); - param.m_Type = ContentParam::OBJECT; - param.m_pObject = pName; - return pName; - } - if (param.m_Type == ContentParam::OBJECT) { - return param.m_pObject; - } - ASSERT(FALSE); - return nullptr; -} - -CFX_ByteString CPDF_StreamContentParser::GetString(uint32_t index) { - if (index >= m_ParamCount) { - return CFX_ByteString(); - } - int real_index = m_ParamStartPos + m_ParamCount - index - 1; - if (real_index >= PARAM_BUF_SIZE) { - real_index -= PARAM_BUF_SIZE; - } - ContentParam& param = m_ParamBuf[real_index]; - if (param.m_Type == ContentParam::NAME) { - return CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len); - } - if (param.m_Type == 0 && param.m_pObject) { - return param.m_pObject->GetString(); - } - return CFX_ByteString(); -} - -FX_FLOAT CPDF_StreamContentParser::GetNumber(uint32_t index) { - if (index >= m_ParamCount) { - return 0; - } - int real_index = m_ParamStartPos + m_ParamCount - index - 1; - if (real_index >= PARAM_BUF_SIZE) { - real_index -= PARAM_BUF_SIZE; - } - ContentParam& param = m_ParamBuf[real_index]; - if (param.m_Type == ContentParam::NUMBER) { - return param.m_Number.m_bInteger ? (FX_FLOAT)param.m_Number.m_Integer - : param.m_Number.m_Float; - } - if (param.m_Type == 0 && param.m_pObject) { - return param.m_pObject->GetNumber(); - } - return 0; -} - -void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, - FX_BOOL bColor, - FX_BOOL bText, - FX_BOOL bGraph) { - pObj->m_GeneralState = m_pCurStates->m_GeneralState; - pObj->m_ClipPath = m_pCurStates->m_ClipPath; - pObj->m_ContentMark = m_CurContentMark; - if (bColor) { - pObj->m_ColorState = m_pCurStates->m_ColorState; - } - if (bGraph) { - pObj->m_GraphState = m_pCurStates->m_GraphState; - } - if (bText) { - pObj->m_TextState = m_pCurStates->m_TextState; - } -} - -// static -CPDF_StreamContentParser::OpCodes -CPDF_StreamContentParser::InitializeOpCodes() { - return OpCodes({ - {FXBSTR_ID('"', 0, 0, 0), - &CPDF_StreamContentParser::Handle_NextLineShowText_Space}, - {FXBSTR_ID('\'', 0, 0, 0), - &CPDF_StreamContentParser::Handle_NextLineShowText}, - {FXBSTR_ID('B', 0, 0, 0), - &CPDF_StreamContentParser::Handle_FillStrokePath}, - {FXBSTR_ID('B', '*', 0, 0), - &CPDF_StreamContentParser::Handle_EOFillStrokePath}, - {FXBSTR_ID('B', 'D', 'C', 0), - &CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary}, - {FXBSTR_ID('B', 'I', 0, 0), &CPDF_StreamContentParser::Handle_BeginImage}, - {FXBSTR_ID('B', 'M', 'C', 0), - &CPDF_StreamContentParser::Handle_BeginMarkedContent}, - {FXBSTR_ID('B', 'T', 0, 0), &CPDF_StreamContentParser::Handle_BeginText}, - {FXBSTR_ID('C', 'S', 0, 0), - &CPDF_StreamContentParser::Handle_SetColorSpace_Stroke}, - {FXBSTR_ID('D', 'P', 0, 0), - &CPDF_StreamContentParser::Handle_MarkPlace_Dictionary}, - {FXBSTR_ID('D', 'o', 0, 0), - &CPDF_StreamContentParser::Handle_ExecuteXObject}, - {FXBSTR_ID('E', 'I', 0, 0), &CPDF_StreamContentParser::Handle_EndImage}, - {FXBSTR_ID('E', 'M', 'C', 0), - &CPDF_StreamContentParser::Handle_EndMarkedContent}, - {FXBSTR_ID('E', 'T', 0, 0), &CPDF_StreamContentParser::Handle_EndText}, - {FXBSTR_ID('F', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPathOld}, - {FXBSTR_ID('G', 0, 0, 0), - &CPDF_StreamContentParser::Handle_SetGray_Stroke}, - {FXBSTR_ID('I', 'D', 0, 0), - &CPDF_StreamContentParser::Handle_BeginImageData}, - {FXBSTR_ID('J', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineCap}, - {FXBSTR_ID('K', 0, 0, 0), - &CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke}, - {FXBSTR_ID('M', 0, 0, 0), - &CPDF_StreamContentParser::Handle_SetMiterLimit}, - {FXBSTR_ID('M', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace}, - {FXBSTR_ID('Q', 0, 0, 0), - &CPDF_StreamContentParser::Handle_RestoreGraphState}, - {FXBSTR_ID('R', 'G', 0, 0), - &CPDF_StreamContentParser::Handle_SetRGBColor_Stroke}, - {FXBSTR_ID('S', 0, 0, 0), &CPDF_StreamContentParser::Handle_StrokePath}, - {FXBSTR_ID('S', 'C', 0, 0), - &CPDF_StreamContentParser::Handle_SetColor_Stroke}, - {FXBSTR_ID('S', 'C', 'N', 0), - &CPDF_StreamContentParser::Handle_SetColorPS_Stroke}, - {FXBSTR_ID('T', '*', 0, 0), - &CPDF_StreamContentParser::Handle_MoveToNextLine}, - {FXBSTR_ID('T', 'D', 0, 0), - &CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading}, - {FXBSTR_ID('T', 'J', 0, 0), - &CPDF_StreamContentParser::Handle_ShowText_Positioning}, - {FXBSTR_ID('T', 'L', 0, 0), - &CPDF_StreamContentParser::Handle_SetTextLeading}, - {FXBSTR_ID('T', 'c', 0, 0), - &CPDF_StreamContentParser::Handle_SetCharSpace}, - {FXBSTR_ID('T', 'd', 0, 0), - &CPDF_StreamContentParser::Handle_MoveTextPoint}, - {FXBSTR_ID('T', 'f', 0, 0), &CPDF_StreamContentParser::Handle_SetFont}, - {FXBSTR_ID('T', 'j', 0, 0), &CPDF_StreamContentParser::Handle_ShowText}, - {FXBSTR_ID('T', 'm', 0, 0), - &CPDF_StreamContentParser::Handle_SetTextMatrix}, - {FXBSTR_ID('T', 'r', 0, 0), - &CPDF_StreamContentParser::Handle_SetTextRenderMode}, - {FXBSTR_ID('T', 's', 0, 0), - &CPDF_StreamContentParser::Handle_SetTextRise}, - {FXBSTR_ID('T', 'w', 0, 0), - &CPDF_StreamContentParser::Handle_SetWordSpace}, - {FXBSTR_ID('T', 'z', 0, 0), - &CPDF_StreamContentParser::Handle_SetHorzScale}, - {FXBSTR_ID('W', 0, 0, 0), &CPDF_StreamContentParser::Handle_Clip}, - {FXBSTR_ID('W', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOClip}, - {FXBSTR_ID('b', 0, 0, 0), - &CPDF_StreamContentParser::Handle_CloseFillStrokePath}, - {FXBSTR_ID('b', '*', 0, 0), - &CPDF_StreamContentParser::Handle_CloseEOFillStrokePath}, - {FXBSTR_ID('c', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_123}, - {FXBSTR_ID('c', 'm', 0, 0), - &CPDF_StreamContentParser::Handle_ConcatMatrix}, - {FXBSTR_ID('c', 's', 0, 0), - &CPDF_StreamContentParser::Handle_SetColorSpace_Fill}, - {FXBSTR_ID('d', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetDash}, - {FXBSTR_ID('d', '0', 0, 0), - &CPDF_StreamContentParser::Handle_SetCharWidth}, - {FXBSTR_ID('d', '1', 0, 0), - &CPDF_StreamContentParser::Handle_SetCachedDevice}, - {FXBSTR_ID('f', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPath}, - {FXBSTR_ID('f', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillPath}, - {FXBSTR_ID('g', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Fill}, - {FXBSTR_ID('g', 's', 0, 0), - &CPDF_StreamContentParser::Handle_SetExtendGraphState}, - {FXBSTR_ID('h', 0, 0, 0), &CPDF_StreamContentParser::Handle_ClosePath}, - {FXBSTR_ID('i', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetFlat}, - {FXBSTR_ID('j', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineJoin}, - {FXBSTR_ID('k', 0, 0, 0), - &CPDF_StreamContentParser::Handle_SetCMYKColor_Fill}, - {FXBSTR_ID('l', 0, 0, 0), &CPDF_StreamContentParser::Handle_LineTo}, - {FXBSTR_ID('m', 0, 0, 0), &CPDF_StreamContentParser::Handle_MoveTo}, - {FXBSTR_ID('n', 0, 0, 0), &CPDF_StreamContentParser::Handle_EndPath}, - {FXBSTR_ID('q', 0, 0, 0), - &CPDF_StreamContentParser::Handle_SaveGraphState}, - {FXBSTR_ID('r', 'e', 0, 0), &CPDF_StreamContentParser::Handle_Rectangle}, - {FXBSTR_ID('r', 'g', 0, 0), - &CPDF_StreamContentParser::Handle_SetRGBColor_Fill}, - {FXBSTR_ID('r', 'i', 0, 0), - &CPDF_StreamContentParser::Handle_SetRenderIntent}, - {FXBSTR_ID('s', 0, 0, 0), - &CPDF_StreamContentParser::Handle_CloseStrokePath}, - {FXBSTR_ID('s', 'c', 0, 0), - &CPDF_StreamContentParser::Handle_SetColor_Fill}, - {FXBSTR_ID('s', 'c', 'n', 0), - &CPDF_StreamContentParser::Handle_SetColorPS_Fill}, - {FXBSTR_ID('s', 'h', 0, 0), &CPDF_StreamContentParser::Handle_ShadeFill}, - {FXBSTR_ID('v', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_23}, - {FXBSTR_ID('w', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineWidth}, - {FXBSTR_ID('y', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_13}, - }); -} - -void CPDF_StreamContentParser::OnOperator(const FX_CHAR* op) { - int i = 0; - uint32_t opid = 0; - while (i < 4 && op[i]) { - opid = (opid << 8) + op[i]; - i++; - } - while (i < 4) { - opid <<= 8; - i++; - } - - static const OpCodes s_OpCodes = InitializeOpCodes(); - - auto it = s_OpCodes.find(opid); - if (it != s_OpCodes.end()) - (this->*it->second)(); -} - -void CPDF_StreamContentParser::Handle_CloseFillStrokePath() { - Handle_ClosePath(); - AddPathObject(FXFILL_WINDING, TRUE); -} - -void CPDF_StreamContentParser::Handle_FillStrokePath() { - AddPathObject(FXFILL_WINDING, TRUE); -} - -void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() { - AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); - AddPathObject(FXFILL_ALTERNATE, TRUE); -} - -void CPDF_StreamContentParser::Handle_EOFillStrokePath() { - AddPathObject(FXFILL_ALTERNATE, TRUE); -} - -void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() { - CFX_ByteString tag = GetString(1); - CPDF_Object* pProperty = GetObject(0); - if (!pProperty) { - return; - } - FX_BOOL bDirect = TRUE; - if (pProperty->IsName()) { - pProperty = FindResourceObj("Properties", pProperty->GetString()); - if (!pProperty) - return; - bDirect = FALSE; - } - if (CPDF_Dictionary* pDict = pProperty->AsDictionary()) { - m_CurContentMark.AddMark(tag, pDict, bDirect); - } -} - -void CPDF_StreamContentParser::Handle_BeginImage() { - FX_FILESIZE savePos = m_pSyntax->GetPos(); - CPDF_Dictionary* pDict = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); - while (1) { - CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); - if (type == CPDF_StreamParser::Keyword) { - CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), - m_pSyntax->GetWordSize()); - if (bsKeyword != "ID") { - m_pSyntax->SetPos(savePos); - pDict->Release(); - return; - } - } - if (type != CPDF_StreamParser::Name) { - break; - } - CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, - m_pSyntax->GetWordSize() - 1); - std::unique_ptr> pObj( - m_pSyntax->ReadNextObject(false, 0)); - if (!key.IsEmpty()) { - uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; - if (dwObjNum) - pDict->SetReferenceFor(key, m_pDocument, dwObjNum); - else - pDict->SetFor(key, pObj.release()); - } - } - PDF_ReplaceAbbr(pDict); - CPDF_Object* pCSObj = nullptr; - if (pDict->KeyExist("ColorSpace")) { - pCSObj = pDict->GetDirectObjectFor("ColorSpace"); - if (pCSObj->IsName()) { - CFX_ByteString name = pCSObj->GetString(); - if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") { - pCSObj = FindResourceObj("ColorSpace", name); - if (pCSObj && !pCSObj->GetObjNum()) { - pCSObj = pCSObj->Clone(); - pDict->SetFor("ColorSpace", pCSObj); - } - } - } - } - CPDF_Stream* pStream = - m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj); - while (1) { - CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); - if (type == CPDF_StreamParser::EndOfData) { - break; - } - if (type != CPDF_StreamParser::Keyword) { - continue; - } - if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && - m_pSyntax->GetWordBuf()[1] == 'I') { - break; - } - } - pDict->SetNameFor("Subtype", "Image"); - CPDF_ImageObject* pImgObj = AddImage(pStream, nullptr, true); - if (!pImgObj) { - if (pStream) { - pStream->Release(); - } else { - pDict->Release(); - } - } -} - -void CPDF_StreamContentParser::Handle_BeginMarkedContent() { - m_CurContentMark.AddMark(GetString(0), nullptr, FALSE); -} - -void CPDF_StreamContentParser::Handle_BeginText() { - m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); - OnChangeTextMatrix(); - m_pCurStates->m_TextX = 0; - m_pCurStates->m_TextY = 0; - m_pCurStates->m_TextLineX = 0; - m_pCurStates->m_TextLineY = 0; -} - -void CPDF_StreamContentParser::Handle_CurveTo_123() { - AddPathPoint(GetNumber(5), GetNumber(4), FXPT_BEZIERTO); - AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); -} - -void CPDF_StreamContentParser::Handle_ConcatMatrix() { - CFX_Matrix new_matrix(GetNumber(5), GetNumber(4), GetNumber(3), GetNumber(2), - GetNumber(1), GetNumber(0)); - new_matrix.Concat(m_pCurStates->m_CTM); - m_pCurStates->m_CTM = new_matrix; - OnChangeTextMatrix(); -} - -void CPDF_StreamContentParser::Handle_SetColorSpace_Fill() { - CPDF_ColorSpace* pCS = FindColorSpace(GetString(0)); - if (!pCS) - return; - - m_pCurStates->m_ColorState.GetMutableFillColor()->SetColorSpace(pCS); -} - -void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke() { - CPDF_ColorSpace* pCS = FindColorSpace(GetString(0)); - if (!pCS) - return; - - m_pCurStates->m_ColorState.GetMutableStrokeColor()->SetColorSpace(pCS); -} - -void CPDF_StreamContentParser::Handle_SetDash() { - CPDF_Array* pArray = ToArray(GetObject(1)); - if (!pArray) - return; - - m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f); -} - -void CPDF_StreamContentParser::Handle_SetCharWidth() { - m_Type3Data[0] = GetNumber(1); - m_Type3Data[1] = GetNumber(0); - m_bColored = TRUE; -} - -void CPDF_StreamContentParser::Handle_SetCachedDevice() { - for (int i = 0; i < 6; i++) { - m_Type3Data[i] = GetNumber(5 - i); - } - m_bColored = FALSE; -} - -void CPDF_StreamContentParser::Handle_ExecuteXObject() { - CFX_ByteString name = GetString(0); - if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() && - m_pLastImage->GetStream()->GetObjNum()) { - AddImage(nullptr, m_pLastImage, false); - return; - } - - CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name)); - if (!pXObject) { - m_bResourceMissing = TRUE; - return; - } - - CFX_ByteString type; - if (pXObject->GetDict()) - type = pXObject->GetDict()->GetStringFor("Subtype"); - - if (type == "Image") { - CPDF_ImageObject* pObj = AddImage(pXObject, nullptr, false); - m_LastImageName = name; - m_pLastImage = pObj->GetImage(); - if (!m_pObjectHolder->HasImageMask()) - m_pObjectHolder->SetHasImageMask(m_pLastImage->IsMask()); - } else if (type == "Form") { - AddForm(pXObject); - } -} - -void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) { - std::unique_ptr pFormObj(new CPDF_FormObject); - pFormObj->m_pForm.reset( - new CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources)); - pFormObj->m_FormMatrix = m_pCurStates->m_CTM; - pFormObj->m_FormMatrix.Concat(m_mtContentToUser); - CPDF_AllStates status; - status.m_GeneralState = m_pCurStates->m_GeneralState; - status.m_GraphState = m_pCurStates->m_GraphState; - status.m_ColorState = m_pCurStates->m_ColorState; - status.m_TextState = m_pCurStates->m_TextState; - pFormObj->m_pForm->ParseContent(&status, nullptr, nullptr, m_Level + 1); - if (!m_pObjectHolder->BackgroundAlphaNeeded() && - pFormObj->m_pForm->BackgroundAlphaNeeded()) { - m_pObjectHolder->SetBackgroundAlphaNeeded(TRUE); - } - pFormObj->CalcBoundingBox(); - SetGraphicStates(pFormObj.get(), TRUE, TRUE, TRUE); - m_pObjectHolder->GetPageObjectList()->push_back(std::move(pFormObj)); -} - -CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, - CPDF_Image* pImage, - bool bInline) { - if (!pStream && !pImage) - return nullptr; - - CFX_Matrix ImageMatrix = m_pCurStates->m_CTM; - ImageMatrix.Concat(m_mtContentToUser); - - std::unique_ptr pImageObj(new CPDF_ImageObject); - if (pImage) { - pImageObj->SetUnownedImage( - m_pDocument->GetPageData()->GetImage(pImage->GetStream())); - } else if (pStream->GetObjNum()) { - pImageObj->SetUnownedImage(m_pDocument->LoadImageF(pStream)); - } else { - pImageObj->SetOwnedImage( - pdfium::MakeUnique(m_pDocument, pStream, bInline)); - } - SetGraphicStates(pImageObj.get(), pImageObj->GetImage()->IsMask(), FALSE, - FALSE); - pImageObj->m_Matrix = ImageMatrix; - pImageObj->CalcBoundingBox(); - CPDF_ImageObject* pRet = pImageObj.get(); - m_pObjectHolder->GetPageObjectList()->push_back(std::move(pImageObj)); - return pRet; -} - -void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {} - -void CPDF_StreamContentParser::Handle_EndImage() {} - -void CPDF_StreamContentParser::Handle_EndMarkedContent() { - if (m_CurContentMark) - m_CurContentMark.DeleteLastMark(); -} - -void CPDF_StreamContentParser::Handle_EndText() { - if (m_ClipTextList.empty()) - return; - - if (TextRenderingModeIsClipMode(m_pCurStates->m_TextState.GetTextMode())) - m_pCurStates->m_ClipPath.AppendTexts(&m_ClipTextList); - - m_ClipTextList.clear(); -} - -void CPDF_StreamContentParser::Handle_FillPath() { - AddPathObject(FXFILL_WINDING, FALSE); -} - -void CPDF_StreamContentParser::Handle_FillPathOld() { - AddPathObject(FXFILL_WINDING, FALSE); -} - -void CPDF_StreamContentParser::Handle_EOFillPath() { - AddPathObject(FXFILL_ALTERNATE, FALSE); -} - -void CPDF_StreamContentParser::Handle_SetGray_Fill() { - FX_FLOAT value = GetNumber(0); - CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); - m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1); -} - -void CPDF_StreamContentParser::Handle_SetGray_Stroke() { - FX_FLOAT value = GetNumber(0); - CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); - m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1); -} - -void CPDF_StreamContentParser::Handle_SetExtendGraphState() { - CFX_ByteString name = GetString(0); - CPDF_Dictionary* pGS = ToDictionary(FindResourceObj("ExtGState", name)); - if (!pGS) { - m_bResourceMissing = TRUE; - return; - } - m_pCurStates->ProcessExtGS(pGS, this); -} - -void CPDF_StreamContentParser::Handle_ClosePath() { - if (m_PathPointCount == 0) { - return; - } - if (m_PathStartX != m_PathCurrentX || m_PathStartY != m_PathCurrentY) { - AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); - } else if (m_pPathPoints[m_PathPointCount - 1].m_Flag != FXPT_MOVETO) { - m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; - } -} - -void CPDF_StreamContentParser::Handle_SetFlat() { - m_pCurStates->m_GeneralState.SetFlatness(GetNumber(0)); -} - -void CPDF_StreamContentParser::Handle_BeginImageData() {} - -void CPDF_StreamContentParser::Handle_SetLineJoin() { - m_pCurStates->m_GraphState.SetLineJoin( - static_cast(GetInteger(0))); -} - -void CPDF_StreamContentParser::Handle_SetLineCap() { - m_pCurStates->m_GraphState.SetLineCap( - static_cast(GetInteger(0))); -} - -void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() { - if (m_ParamCount != 4) - return; - - FX_FLOAT values[4]; - for (int i = 0; i < 4; i++) { - values[i] = GetNumber(3 - i); - } - CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); - m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4); -} - -void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke() { - if (m_ParamCount != 4) - return; - - FX_FLOAT values[4]; - for (int i = 0; i < 4; i++) { - values[i] = GetNumber(3 - i); - } - CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); - m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4); -} - -void CPDF_StreamContentParser::Handle_LineTo() { - if (m_ParamCount != 2) - return; - - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO); -} - -void CPDF_StreamContentParser::Handle_MoveTo() { - if (m_ParamCount != 2) - return; - - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO); - ParsePathObject(); -} - -void CPDF_StreamContentParser::Handle_SetMiterLimit() { - m_pCurStates->m_GraphState.SetMiterLimit(GetNumber(0)); -} - -void CPDF_StreamContentParser::Handle_MarkPlace() {} - -void CPDF_StreamContentParser::Handle_EndPath() { - AddPathObject(0, FALSE); -} - -void CPDF_StreamContentParser::Handle_SaveGraphState() { - std::unique_ptr pStates(new CPDF_AllStates); - pStates->Copy(*m_pCurStates); - m_StateStack.push_back(std::move(pStates)); -} - -void CPDF_StreamContentParser::Handle_RestoreGraphState() { - if (m_StateStack.empty()) - return; - std::unique_ptr pStates = std::move(m_StateStack.back()); - m_StateStack.pop_back(); - m_pCurStates->Copy(*pStates); -} - -void CPDF_StreamContentParser::Handle_Rectangle() { - FX_FLOAT x = GetNumber(3), y = GetNumber(2); - FX_FLOAT w = GetNumber(1), h = GetNumber(0); - AddPathRect(x, y, w, h); -} - -void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT w, - FX_FLOAT h) { - AddPathPoint(x, y, FXPT_MOVETO); - AddPathPoint(x + w, y, FXPT_LINETO); - AddPathPoint(x + w, y + h, FXPT_LINETO); - AddPathPoint(x, y + h, FXPT_LINETO); - AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE); -} - -void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() { - if (m_ParamCount != 3) - return; - - FX_FLOAT values[3]; - for (int i = 0; i < 3; i++) { - values[i] = GetNumber(2 - i); - } - CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); - m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3); -} - -void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke() { - if (m_ParamCount != 3) - return; - - FX_FLOAT values[3]; - for (int i = 0; i < 3; i++) { - values[i] = GetNumber(2 - i); - } - CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); - m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3); -} - -void CPDF_StreamContentParser::Handle_SetRenderIntent() {} - -void CPDF_StreamContentParser::Handle_CloseStrokePath() { - Handle_ClosePath(); - AddPathObject(0, TRUE); -} - -void CPDF_StreamContentParser::Handle_StrokePath() { - AddPathObject(0, TRUE); -} - -void CPDF_StreamContentParser::Handle_SetColor_Fill() { - FX_FLOAT values[4]; - int nargs = m_ParamCount; - if (nargs > 4) { - nargs = 4; - } - for (int i = 0; i < nargs; i++) { - values[i] = GetNumber(nargs - i - 1); - } - m_pCurStates->m_ColorState.SetFillColor(nullptr, values, nargs); -} - -void CPDF_StreamContentParser::Handle_SetColor_Stroke() { - FX_FLOAT values[4]; - int nargs = m_ParamCount; - if (nargs > 4) { - nargs = 4; - } - for (int i = 0; i < nargs; i++) { - values[i] = GetNumber(nargs - i - 1); - } - m_pCurStates->m_ColorState.SetStrokeColor(nullptr, values, nargs); -} - -void CPDF_StreamContentParser::Handle_SetColorPS_Fill() { - CPDF_Object* pLastParam = GetObject(0); - if (!pLastParam) { - return; - } - uint32_t nargs = m_ParamCount; - uint32_t nvalues = nargs; - if (pLastParam->IsName()) - nvalues--; - FX_FLOAT* values = nullptr; - if (nvalues) { - values = FX_Alloc(FX_FLOAT, nvalues); - for (uint32_t i = 0; i < nvalues; i++) { - values[i] = GetNumber(nargs - i - 1); - } - } - if (nvalues != nargs) { - CPDF_Pattern* pPattern = FindPattern(GetString(0), false); - if (pPattern) { - m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); - } - } else { - m_pCurStates->m_ColorState.SetFillColor(nullptr, values, nvalues); - } - FX_Free(values); -} - -void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { - CPDF_Object* pLastParam = GetObject(0); - if (!pLastParam) { - return; - } - int nargs = m_ParamCount; - int nvalues = nargs; - if (pLastParam->IsName()) - nvalues--; - - FX_FLOAT* values = nullptr; - if (nvalues) { - values = FX_Alloc(FX_FLOAT, nvalues); - for (int i = 0; i < nvalues; i++) { - values[i] = GetNumber(nargs - i - 1); - } - } - if (nvalues != nargs) { - CPDF_Pattern* pPattern = FindPattern(GetString(0), false); - if (pPattern) { - m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); - } - } else { - m_pCurStates->m_ColorState.SetStrokeColor(nullptr, values, nvalues); - } - FX_Free(values); -} - -void CPDF_StreamContentParser::Handle_ShadeFill() { - CPDF_Pattern* pPattern = FindPattern(GetString(0), true); - if (!pPattern) - return; - - CPDF_ShadingPattern* pShading = pPattern->AsShadingPattern(); - if (!pShading) - return; - - if (!pShading->IsShadingObject() || !pShading->Load()) - return; - - std::unique_ptr pObj(new CPDF_ShadingObject); - pObj->m_pShading = pShading; - SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE); - pObj->m_Matrix = m_pCurStates->m_CTM; - pObj->m_Matrix.Concat(m_mtContentToUser); - CFX_FloatRect bbox = - pObj->m_ClipPath ? pObj->m_ClipPath.GetClipBox() : m_BBox; - if (pShading->IsMeshShading()) - bbox.Intersect(GetShadingBBox(pShading, pObj->m_Matrix)); - pObj->m_Left = bbox.left; - pObj->m_Right = bbox.right; - pObj->m_Top = bbox.top; - pObj->m_Bottom = bbox.bottom; - m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj)); -} - -void CPDF_StreamContentParser::Handle_SetCharSpace() { - m_pCurStates->m_TextState.SetCharSpace(GetNumber(0)); -} - -void CPDF_StreamContentParser::Handle_MoveTextPoint() { - m_pCurStates->m_TextLineX += GetNumber(1); - m_pCurStates->m_TextLineY += GetNumber(0); - m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; - m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; -} - -void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading() { - Handle_MoveTextPoint(); - m_pCurStates->m_TextLeading = -GetNumber(0); -} - -void CPDF_StreamContentParser::Handle_SetFont() { - FX_FLOAT fs = GetNumber(0); - if (fs == 0) { - fs = m_DefFontSize; - } - m_pCurStates->m_TextState.SetFontSize(fs); - CPDF_Font* pFont = FindFont(GetString(1)); - if (pFont) { - m_pCurStates->m_TextState.SetFont(pFont); - } -} - -CPDF_Object* CPDF_StreamContentParser::FindResourceObj( - const CFX_ByteString& type, - const CFX_ByteString& name) { - if (!m_pResources) - return nullptr; - CPDF_Dictionary* pDict = m_pResources->GetDictFor(type); - if (pDict) - return pDict->GetDirectObjectFor(name); - if (m_pResources == m_pPageResources || !m_pPageResources) - return nullptr; - - CPDF_Dictionary* pPageDict = m_pPageResources->GetDictFor(type); - return pPageDict ? pPageDict->GetDirectObjectFor(name) : nullptr; -} - -CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name) { - CPDF_Dictionary* pFontDict = ToDictionary(FindResourceObj("Font", name)); - if (!pFontDict) { - m_bResourceMissing = TRUE; - return CPDF_Font::GetStockFont(m_pDocument, "Helvetica"); - } - - CPDF_Font* pFont = m_pDocument->LoadFont(pFontDict); - if (pFont && pFont->IsType3Font()) { - pFont->AsType3Font()->SetPageResources(m_pResources); - pFont->AsType3Font()->CheckType3FontMetrics(); - } - return pFont; -} - -CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace( - const CFX_ByteString& name) { - if (name == "Pattern") { - return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); - } - if (name == "DeviceGray" || name == "DeviceCMYK" || name == "DeviceRGB") { - CFX_ByteString defname = "Default"; - defname += name.Mid(7); - CPDF_Object* pDefObj = FindResourceObj("ColorSpace", defname); - if (!pDefObj) { - if (name == "DeviceGray") { - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); - } - if (name == "DeviceRGB") { - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); - } - return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); - } - return m_pDocument->LoadColorSpace(pDefObj); - } - CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name); - if (!pCSObj) { - m_bResourceMissing = TRUE; - return nullptr; - } - return m_pDocument->LoadColorSpace(pCSObj); -} - -CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, - bool bShading) { - CPDF_Object* pPattern = - FindResourceObj(bShading ? "Shading" : "Pattern", name); - if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { - m_bResourceMissing = TRUE; - return nullptr; - } - return m_pDocument->LoadPattern(pPattern, bShading, - m_pCurStates->m_ParentMatrix); -} - -void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) { - m_pCurStates->m_TextMatrix.Transform(x, y, x, y); - ConvertUserSpace(x, y); -} - -void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) { - m_pCurStates->m_CTM.Transform(x, y, x, y); - m_mtContentToUser.Transform(x, y, x, y); -} - -void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, - FX_FLOAT fInitKerning, - FX_FLOAT* pKerning, - int nsegs) { - CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont(); - if (!pFont) { - return; - } - if (fInitKerning != 0) { - if (!pFont->IsVertWriting()) { - m_pCurStates->m_TextX -= - (fInitKerning * m_pCurStates->m_TextState.GetFontSize()) / 1000; - } else { - m_pCurStates->m_TextY -= - (fInitKerning * m_pCurStates->m_TextState.GetFontSize()) / 1000; - } - } - if (nsegs == 0) { - return; - } - const TextRenderingMode text_mode = - pFont->IsType3Font() ? TextRenderingMode::MODE_FILL - : m_pCurStates->m_TextState.GetTextMode(); - { - std::unique_ptr pText(new CPDF_TextObject); - m_pLastTextObject = pText.get(); - SetGraphicStates(m_pLastTextObject, TRUE, TRUE, TRUE); - if (TextRenderingModeIsStrokeMode(text_mode)) { - FX_FLOAT* pCTM = pText->m_TextState.GetMutableCTM(); - pCTM[0] = m_pCurStates->m_CTM.a; - pCTM[1] = m_pCurStates->m_CTM.c; - pCTM[2] = m_pCurStates->m_CTM.b; - pCTM[3] = m_pCurStates->m_CTM.d; - } - pText->SetSegments(pStrs, pKerning, nsegs); - pText->m_PosX = m_pCurStates->m_TextX; - pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise; - ConvertTextSpace(pText->m_PosX, pText->m_PosY); - FX_FLOAT x_advance; - FX_FLOAT y_advance; - pText->CalcPositionData(&x_advance, &y_advance, - m_pCurStates->m_TextHorzScale); - m_pCurStates->m_TextX += x_advance; - m_pCurStates->m_TextY += y_advance; - if (TextRenderingModeIsClipMode(text_mode)) { - m_ClipTextList.push_back( - std::unique_ptr(pText->Clone())); - } - m_pObjectHolder->GetPageObjectList()->push_back(std::move(pText)); - } - if (pKerning && pKerning[nsegs - 1] != 0) { - if (!pFont->IsVertWriting()) { - m_pCurStates->m_TextX -= - (pKerning[nsegs - 1] * m_pCurStates->m_TextState.GetFontSize()) / - 1000; - } else { - m_pCurStates->m_TextY -= - (pKerning[nsegs - 1] * m_pCurStates->m_TextState.GetFontSize()) / - 1000; - } - } -} - -void CPDF_StreamContentParser::Handle_ShowText() { - CFX_ByteString str = GetString(0); - if (str.IsEmpty()) { - return; - } - AddTextObject(&str, 0, nullptr, 1); -} - -void CPDF_StreamContentParser::Handle_ShowText_Positioning() { - CPDF_Array* pArray = ToArray(GetObject(0)); - if (!pArray) - return; - - size_t n = pArray->GetCount(); - size_t nsegs = 0; - for (size_t i = 0; i < n; i++) { - if (pArray->GetDirectObjectAt(i)->IsString()) - nsegs++; - } - if (nsegs == 0) { - for (size_t i = 0; i < n; i++) { - m_pCurStates->m_TextX -= - (pArray->GetNumberAt(i) * m_pCurStates->m_TextState.GetFontSize()) / - 1000; - } - return; - } - CFX_ByteString* pStrs = new CFX_ByteString[nsegs]; - FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs); - size_t iSegment = 0; - FX_FLOAT fInitKerning = 0; - for (size_t i = 0; i < n; i++) { - CPDF_Object* pObj = pArray->GetDirectObjectAt(i); - if (pObj->IsString()) { - CFX_ByteString str = pObj->GetString(); - if (str.IsEmpty()) { - continue; - } - pStrs[iSegment] = str; - pKerning[iSegment++] = 0; - } else { - FX_FLOAT num = pObj ? pObj->GetNumber() : 0; - if (iSegment == 0) { - fInitKerning += num; - } else { - pKerning[iSegment - 1] += num; - } - } - } - AddTextObject(pStrs, fInitKerning, pKerning, iSegment); - delete[] pStrs; - FX_Free(pKerning); -} - -void CPDF_StreamContentParser::Handle_SetTextLeading() { - m_pCurStates->m_TextLeading = GetNumber(0); -} - -void CPDF_StreamContentParser::Handle_SetTextMatrix() { - m_pCurStates->m_TextMatrix.Set(GetNumber(5), GetNumber(4), GetNumber(3), - GetNumber(2), GetNumber(1), GetNumber(0)); - OnChangeTextMatrix(); - m_pCurStates->m_TextX = 0; - m_pCurStates->m_TextY = 0; - m_pCurStates->m_TextLineX = 0; - m_pCurStates->m_TextLineY = 0; -} - -void CPDF_StreamContentParser::OnChangeTextMatrix() { - CFX_Matrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f); - text_matrix.Concat(m_pCurStates->m_TextMatrix); - text_matrix.Concat(m_pCurStates->m_CTM); - text_matrix.Concat(m_mtContentToUser); - FX_FLOAT* pTextMatrix = m_pCurStates->m_TextState.GetMutableMatrix(); - pTextMatrix[0] = text_matrix.a; - pTextMatrix[1] = text_matrix.c; - pTextMatrix[2] = text_matrix.b; - pTextMatrix[3] = text_matrix.d; -} - -void CPDF_StreamContentParser::Handle_SetTextRenderMode() { - TextRenderingMode mode; - if (SetTextRenderingModeFromInt(GetInteger(0), &mode)) - m_pCurStates->m_TextState.SetTextMode(mode); -} - -void CPDF_StreamContentParser::Handle_SetTextRise() { - m_pCurStates->m_TextRise = GetNumber(0); -} - -void CPDF_StreamContentParser::Handle_SetWordSpace() { - m_pCurStates->m_TextState.SetWordSpace(GetNumber(0)); -} - -void CPDF_StreamContentParser::Handle_SetHorzScale() { - if (m_ParamCount != 1) { - return; - } - m_pCurStates->m_TextHorzScale = GetNumber(0) / 100; - OnChangeTextMatrix(); -} - -void CPDF_StreamContentParser::Handle_MoveToNextLine() { - m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading; - m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; - m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; -} - -void CPDF_StreamContentParser::Handle_CurveTo_23() { - AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); - AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); -} - -void CPDF_StreamContentParser::Handle_SetLineWidth() { - m_pCurStates->m_GraphState.SetLineWidth(GetNumber(0)); -} - -void CPDF_StreamContentParser::Handle_Clip() { - m_PathClipType = FXFILL_WINDING; -} - -void CPDF_StreamContentParser::Handle_EOClip() { - m_PathClipType = FXFILL_ALTERNATE; -} - -void CPDF_StreamContentParser::Handle_CurveTo_13() { - AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); -} - -void CPDF_StreamContentParser::Handle_NextLineShowText() { - Handle_MoveToNextLine(); - Handle_ShowText(); -} - -void CPDF_StreamContentParser::Handle_NextLineShowText_Space() { - m_pCurStates->m_TextState.SetWordSpace(GetNumber(2)); - m_pCurStates->m_TextState.SetCharSpace(GetNumber(1)); - Handle_NextLineShowText(); -} - -void CPDF_StreamContentParser::Handle_Invalid() {} - -void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) { - m_PathCurrentX = x; - m_PathCurrentY = y; - if (flag == FXPT_MOVETO) { - m_PathStartX = x; - m_PathStartY = y; - if (m_PathPointCount && - m_pPathPoints[m_PathPointCount - 1].m_Flag == FXPT_MOVETO) { - m_pPathPoints[m_PathPointCount - 1].m_PointX = x; - m_pPathPoints[m_PathPointCount - 1].m_PointY = y; - return; - } - } else if (m_PathPointCount == 0) { - return; - } - m_PathPointCount++; - if (m_PathPointCount > m_PathAllocSize) { - int newsize = m_PathPointCount + 256; - FX_PATHPOINT* pNewPoints = FX_Alloc(FX_PATHPOINT, newsize); - if (m_PathAllocSize) { - FXSYS_memcpy(pNewPoints, m_pPathPoints, - m_PathAllocSize * sizeof(FX_PATHPOINT)); - FX_Free(m_pPathPoints); - } - m_pPathPoints = pNewPoints; - m_PathAllocSize = newsize; - } - m_pPathPoints[m_PathPointCount - 1].m_Flag = flag; - m_pPathPoints[m_PathPointCount - 1].m_PointX = x; - m_pPathPoints[m_PathPointCount - 1].m_PointY = y; -} - -void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke) { - int PathPointCount = m_PathPointCount; - uint8_t PathClipType = m_PathClipType; - m_PathPointCount = 0; - m_PathClipType = 0; - if (PathPointCount <= 1) { - if (PathPointCount && PathClipType) { - CPDF_Path path; - path.AppendRect(0, 0, 0, 0); - m_pCurStates->m_ClipPath.AppendPath(path, FXFILL_WINDING, TRUE); - } - return; - } - if (PathPointCount && - m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) { - PathPointCount--; - } - CPDF_Path Path; - Path.SetPointCount(PathPointCount); - FXSYS_memcpy(Path.GetMutablePoints(), m_pPathPoints, - sizeof(FX_PATHPOINT) * PathPointCount); - CFX_Matrix matrix = m_pCurStates->m_CTM; - matrix.Concat(m_mtContentToUser); - if (bStroke || FillType) { - std::unique_ptr pPathObj(new CPDF_PathObject); - pPathObj->m_bStroke = bStroke; - pPathObj->m_FillType = FillType; - pPathObj->m_Path = Path; - pPathObj->m_Matrix = matrix; - SetGraphicStates(pPathObj.get(), TRUE, FALSE, TRUE); - pPathObj->CalcBoundingBox(); - m_pObjectHolder->GetPageObjectList()->push_back(std::move(pPathObj)); - } - if (PathClipType) { - if (!matrix.IsIdentity()) { - Path.Transform(&matrix); - matrix.SetIdentity(); - } - m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE); - } -} - -uint32_t CPDF_StreamContentParser::Parse(const uint8_t* pData, - uint32_t dwSize, - uint32_t max_cost) { - if (m_Level > _FPDF_MAX_FORM_LEVEL_) { - return dwSize; - } - uint32_t InitObjCount = m_pObjectHolder->GetPageObjectList()->size(); - CPDF_StreamParser syntax(pData, dwSize, m_pDocument->GetByteStringPool()); - CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); - while (1) { - uint32_t cost = m_pObjectHolder->GetPageObjectList()->size() - InitObjCount; - if (max_cost && cost >= max_cost) { - break; - } - switch (syntax.ParseNextElement()) { - case CPDF_StreamParser::EndOfData: - return m_pSyntax->GetPos(); - case CPDF_StreamParser::Keyword: - OnOperator((char*)syntax.GetWordBuf()); - ClearAllParams(); - break; - case CPDF_StreamParser::Number: - AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize()); - break; - case CPDF_StreamParser::Name: - AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, - syntax.GetWordSize() - 1); - break; - default: - AddObjectParam(syntax.GetObject()); - } - } - return m_pSyntax->GetPos(); -} - -void CPDF_StreamContentParser::ParsePathObject() { - FX_FLOAT params[6] = {}; - int nParams = 0; - int last_pos = m_pSyntax->GetPos(); - while (1) { - CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); - FX_BOOL bProcessed = TRUE; - switch (type) { - case CPDF_StreamParser::EndOfData: - return; - case CPDF_StreamParser::Keyword: { - int len = m_pSyntax->GetWordSize(); - if (len == 1) { - switch (m_pSyntax->GetWordBuf()[0]) { - case kPathOperatorSubpath: - AddPathPoint(params[0], params[1], FXPT_MOVETO); - nParams = 0; - break; - case kPathOperatorLine: - AddPathPoint(params[0], params[1], FXPT_LINETO); - nParams = 0; - break; - case kPathOperatorCubicBezier1: - AddPathPoint(params[0], params[1], FXPT_BEZIERTO); - AddPathPoint(params[2], params[3], FXPT_BEZIERTO); - AddPathPoint(params[4], params[5], FXPT_BEZIERTO); - nParams = 0; - break; - case kPathOperatorCubicBezier2: - AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); - AddPathPoint(params[0], params[1], FXPT_BEZIERTO); - AddPathPoint(params[2], params[3], FXPT_BEZIERTO); - nParams = 0; - break; - case kPathOperatorCubicBezier3: - AddPathPoint(params[0], params[1], FXPT_BEZIERTO); - AddPathPoint(params[2], params[3], FXPT_BEZIERTO); - AddPathPoint(params[2], params[3], FXPT_BEZIERTO); - nParams = 0; - break; - case kPathOperatorClosePath: - Handle_ClosePath(); - nParams = 0; - break; - default: - bProcessed = FALSE; - break; - } - } else if (len == 2) { - if (m_pSyntax->GetWordBuf()[0] == kPathOperatorRectangle[0] && - m_pSyntax->GetWordBuf()[1] == kPathOperatorRectangle[1]) { - AddPathRect(params[0], params[1], params[2], params[3]); - nParams = 0; - } else { - bProcessed = FALSE; - } - } else { - bProcessed = FALSE; - } - if (bProcessed) { - last_pos = m_pSyntax->GetPos(); - } - break; - } - case CPDF_StreamParser::Number: { - if (nParams == 6) - break; - - int value; - bool bInteger = FX_atonum( - CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), - &value); - params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value; - break; - } - default: - bProcessed = FALSE; - } - if (!bProcessed) { - m_pSyntax->SetPos(last_pos); - return; - } - } -} - -void PDF_ReplaceAbbr(CPDF_Object* pObj) { - switch (pObj->GetType()) { - case CPDF_Object::DICTIONARY: { - CPDF_Dictionary* pDict = pObj->AsDictionary(); - std::vector replacements; - for (const auto& it : *pDict) { - CFX_ByteString key = it.first; - CPDF_Object* value = it.second; - CFX_ByteStringC fullname = - PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), - key.AsStringC()); - if (!fullname.IsEmpty()) { - AbbrReplacementOp op; - op.is_replace_key = true; - op.key = key; - op.replacement = fullname; - replacements.push_back(op); - key = fullname; - } - - if (value->IsName()) { - CFX_ByteString name = value->GetString(); - fullname = PDF_FindFullName(PDF_InlineValueAbbr, - FX_ArraySize(PDF_InlineValueAbbr), - name.AsStringC()); - if (!fullname.IsEmpty()) { - AbbrReplacementOp op; - op.is_replace_key = false; - op.key = key; - op.replacement = fullname; - replacements.push_back(op); - } - } else { - PDF_ReplaceAbbr(value); - } - } - for (const auto& op : replacements) { - if (op.is_replace_key) - pDict->ReplaceKey(op.key, CFX_ByteString(op.replacement)); - else - pDict->SetNameFor(op.key, CFX_ByteString(op.replacement)); - } - break; - } - case CPDF_Object::ARRAY: { - CPDF_Array* pArray = pObj->AsArray(); - for (size_t i = 0; i < pArray->GetCount(); i++) { - CPDF_Object* pElement = pArray->GetObjectAt(i); - if (pElement->IsName()) { - CFX_ByteString name = pElement->GetString(); - CFX_ByteStringC fullname = PDF_FindFullName( - PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), - name.AsStringC()); - if (!fullname.IsEmpty()) { - pArray->SetAt(i, new CPDF_Name(CFX_ByteString(fullname))); - } - } else { - PDF_ReplaceAbbr(pElement); - } - } - break; - } - default: - break; - } -} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp deleted file mode 100644 index 3c3104b8ab..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp +++ /dev/null @@ -1,839 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "core/fpdfapi/fpdf_page/pageint.h" - -#include - -#include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/font/cpdf_type3char.h" -#include "core/fpdfapi/fpdf_page/cpdf_allstates.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_page.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_path.h" -#include "core/fpdfapi/fpdf_parser/cpdf_array.h" -#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" -#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" -#include "core/fpdfapi/fpdf_parser/cpdf_document.h" -#include "core/fpdfapi/fpdf_parser/cpdf_name.h" -#include "core/fpdfapi/fpdf_parser/cpdf_null.h" -#include "core/fpdfapi/fpdf_parser/cpdf_number.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" -#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" -#include "core/fpdfapi/fpdf_parser/cpdf_string.h" -#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" -#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h" -#include "core/fxcodec/fx_codec.h" -#include "core/fxcrt/fx_ext.h" -#include "core/fxcrt/fx_safe_types.h" -#include "core/fxge/cfx_fxgedevice.h" -#include "core/fxge/cfx_renderdevice.h" - -namespace { - -const uint32_t kMaxNestedArrayLevel = 512; -const uint32_t kMaxWordBuffer = 256; -const FX_STRSIZE kMaxStringLength = 32767; - -} // namespace - -CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize) - : m_pBuf(pData), - m_Size(dwSize), - m_Pos(0), - m_pLastObj(nullptr), - m_pPool(nullptr) {} - -CPDF_StreamParser::CPDF_StreamParser( - const uint8_t* pData, - uint32_t dwSize, - const CFX_WeakPtr& pPool) - : m_pBuf(pData), - m_Size(dwSize), - m_Pos(0), - m_pLastObj(nullptr), - m_pPool(pPool) {} - -CPDF_StreamParser::~CPDF_StreamParser() { - if (m_pLastObj) { - m_pLastObj->Release(); - } -} - -uint32_t DecodeAllScanlines(CCodec_ScanlineDecoder* pDecoder, - uint8_t*& dest_buf, - uint32_t& dest_size) { - if (!pDecoder) { - return FX_INVALID_OFFSET; - } - int ncomps = pDecoder->CountComps(); - int bpc = pDecoder->GetBPC(); - int width = pDecoder->GetWidth(); - int height = pDecoder->GetHeight(); - int pitch = (width * ncomps * bpc + 7) / 8; - if (height == 0 || pitch > (1 << 30) / height) { - delete pDecoder; - return FX_INVALID_OFFSET; - } - dest_buf = FX_Alloc2D(uint8_t, pitch, height); - dest_size = pitch * height; // Safe since checked alloc returned. - for (int row = 0; row < height; row++) { - const uint8_t* pLine = pDecoder->GetScanline(row); - if (!pLine) - break; - - FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch); - } - uint32_t srcoff = pDecoder->GetSrcOffset(); - delete pDecoder; - return srcoff; -} - -CCodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( - const uint8_t* src_buf, - uint32_t src_size, - int width, - int height, - const CPDF_Dictionary* pParams); - -uint32_t PDF_DecodeInlineStream(const uint8_t* src_buf, - uint32_t limit, - int width, - int height, - CFX_ByteString& decoder, - CPDF_Dictionary* pParam, - uint8_t*& dest_buf, - uint32_t& dest_size) { - if (decoder == "CCITTFaxDecode" || decoder == "CCF") { - CCodec_ScanlineDecoder* pDecoder = - FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam); - return DecodeAllScanlines(pDecoder, dest_buf, dest_size); - } - if (decoder == "ASCII85Decode" || decoder == "A85") { - return A85Decode(src_buf, limit, dest_buf, dest_size); - } - if (decoder == "ASCIIHexDecode" || decoder == "AHx") { - return HexDecode(src_buf, limit, dest_buf, dest_size); - } - if (decoder == "FlateDecode" || decoder == "Fl") { - return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size, - dest_buf, dest_size); - } - if (decoder == "LZWDecode" || decoder == "LZW") { - return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf, - dest_size); - } - if (decoder == "DCTDecode" || decoder == "DCT") { - CCodec_ScanlineDecoder* pDecoder = - CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( - src_buf, limit, width, height, 0, - pParam ? pParam->GetIntegerFor("ColorTransform", 1) : 1); - return DecodeAllScanlines(pDecoder, dest_buf, dest_size); - } - if (decoder == "RunLengthDecode" || decoder == "RL") { - return RunLengthDecode(src_buf, limit, dest_buf, dest_size); - } - dest_size = 0; - dest_buf = 0; - return (uint32_t)-1; -} - -CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, - CPDF_Dictionary* pDict, - CPDF_Object* pCSObj) { - if (m_Pos == m_Size) - return nullptr; - - if (PDFCharIsWhitespace(m_pBuf[m_Pos])) - m_Pos++; - - CFX_ByteString Decoder; - CPDF_Dictionary* pParam = nullptr; - CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter"); - if (pFilter) { - if (CPDF_Array* pArray = pFilter->AsArray()) { - Decoder = pArray->GetStringAt(0); - CPDF_Array* pParams = pDict->GetArrayFor("DecodeParms"); - if (pParams) - pParam = pParams->GetDictAt(0); - } else { - Decoder = pFilter->GetString(); - pParam = pDict->GetDictFor("DecodeParms"); - } - } - uint32_t width = pDict->GetIntegerFor("Width"); - uint32_t height = pDict->GetIntegerFor("Height"); - uint32_t OrigSize = 0; - if (pCSObj) { - uint32_t bpc = pDict->GetIntegerFor("BitsPerComponent"); - uint32_t nComponents = 1; - CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); - if (pCS) { - nComponents = pCS->CountComponents(); - pDoc->GetPageData()->ReleaseColorSpace(pCSObj); - } else { - nComponents = 3; - } - uint32_t pitch = width; - if (bpc && pitch > INT_MAX / bpc) - return nullptr; - - pitch *= bpc; - if (nComponents && pitch > INT_MAX / nComponents) - return nullptr; - - pitch *= nComponents; - if (pitch > INT_MAX - 7) - return nullptr; - - pitch += 7; - pitch /= 8; - OrigSize = pitch; - } else { - if (width > INT_MAX - 7) - return nullptr; - - OrigSize = ((width + 7) / 8); - } - if (height && OrigSize > INT_MAX / height) - return nullptr; - - OrigSize *= height; - uint8_t* pData = nullptr; - uint32_t dwStreamSize; - if (Decoder.IsEmpty()) { - if (OrigSize > m_Size - m_Pos) { - OrigSize = m_Size - m_Pos; - } - pData = FX_Alloc(uint8_t, OrigSize); - FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); - dwStreamSize = OrigSize; - m_Pos += OrigSize; - } else { - uint32_t dwDestSize = OrigSize; - dwStreamSize = - PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, - Decoder, pParam, pData, dwDestSize); - FX_Free(pData); - if ((int)dwStreamSize < 0) - return nullptr; - - uint32_t dwSavePos = m_Pos; - m_Pos += dwStreamSize; - while (1) { - uint32_t dwPrevPos = m_Pos; - CPDF_StreamParser::SyntaxType type = ParseNextElement(); - if (type == CPDF_StreamParser::EndOfData) - break; - - if (type != CPDF_StreamParser::Keyword) { - dwStreamSize += m_Pos - dwPrevPos; - continue; - } - if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && - GetWordBuf()[1] == 'I') { - m_Pos = dwPrevPos; - break; - } - dwStreamSize += m_Pos - dwPrevPos; - } - m_Pos = dwSavePos; - pData = FX_Alloc(uint8_t, dwStreamSize); - FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); - m_Pos += dwStreamSize; - } - pDict->SetIntegerFor("Length", (int)dwStreamSize); - return new CPDF_Stream(pData, dwStreamSize, pDict); -} - -CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { - if (m_pLastObj) { - m_pLastObj->Release(); - m_pLastObj = nullptr; - } - - m_WordSize = 0; - FX_BOOL bIsNumber = TRUE; - if (!PositionIsInBounds()) - return EndOfData; - - int ch = m_pBuf[m_Pos++]; - while (1) { - while (PDFCharIsWhitespace(ch)) { - if (!PositionIsInBounds()) - return EndOfData; - - ch = m_pBuf[m_Pos++]; - } - - if (ch != '%') - break; - - while (1) { - if (!PositionIsInBounds()) - return EndOfData; - - ch = m_pBuf[m_Pos++]; - if (PDFCharIsLineEnding(ch)) - break; - } - } - - if (PDFCharIsDelimiter(ch) && ch != '/') { - m_Pos--; - m_pLastObj = ReadNextObject(false, 0); - return Others; - } - - while (1) { - if (m_WordSize < kMaxWordBuffer) - m_WordBuffer[m_WordSize++] = ch; - - if (!PDFCharIsNumeric(ch)) - bIsNumber = FALSE; - - if (!PositionIsInBounds()) - break; - - ch = m_pBuf[m_Pos++]; - - if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { - m_Pos--; - break; - } - } - - m_WordBuffer[m_WordSize] = 0; - if (bIsNumber) - return Number; - - if (m_WordBuffer[0] == '/') - return Name; - - if (m_WordSize == 4) { - if (memcmp(m_WordBuffer, "true", 4) == 0) { - m_pLastObj = new CPDF_Boolean(TRUE); - return Others; - } - if (memcmp(m_WordBuffer, "null", 4) == 0) { - m_pLastObj = new CPDF_Null; - return Others; - } - } else if (m_WordSize == 5) { - if (memcmp(m_WordBuffer, "false", 5) == 0) { - m_pLastObj = new CPDF_Boolean(FALSE); - return Others; - } - } - return Keyword; -} - -CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, - uint32_t dwInArrayLevel) { - FX_BOOL bIsNumber; - GetNextWord(bIsNumber); - if (!m_WordSize) - return nullptr; - - if (bIsNumber) { - m_WordBuffer[m_WordSize] = 0; - return new CPDF_Number(CFX_ByteStringC(m_WordBuffer, m_WordSize)); - } - - int first_char = m_WordBuffer[0]; - if (first_char == '/') { - CFX_ByteString name = - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); - return new CPDF_Name(m_pPool ? m_pPool->Intern(name) : name); - } - - if (first_char == '(') { - CFX_ByteString str = ReadString(); - return new CPDF_String(m_pPool ? m_pPool->Intern(str) : str, FALSE); - } - - if (first_char == '<') { - if (m_WordSize == 1) - return new CPDF_String(ReadHexString(), TRUE); - - CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPool); - while (1) { - GetNextWord(bIsNumber); - if (m_WordSize == 2 && m_WordBuffer[0] == '>') - break; - - if (!m_WordSize || m_WordBuffer[0] != '/') { - pDict->Release(); - return nullptr; - } - - CFX_ByteString key = - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); - CPDF_Object* pObj = ReadNextObject(true, 0); - if (!pObj) { - pDict->Release(); - return nullptr; - } - - if (key.IsEmpty()) - pObj->Release(); - else - pDict->SetFor(key, pObj); - } - return pDict; - } - - if (first_char == '[') { - if ((!bAllowNestedArray && dwInArrayLevel) || - dwInArrayLevel > kMaxNestedArrayLevel) { - return nullptr; - } - - CPDF_Array* pArray = new CPDF_Array; - while (1) { - CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1); - if (pObj) { - pArray->Add(pObj); - continue; - } - - if (!m_WordSize || m_WordBuffer[0] == ']') - break; - } - return pArray; - } - - if (m_WordSize == 5 && !memcmp(m_WordBuffer, "false", 5)) - return new CPDF_Boolean(FALSE); - - if (m_WordSize == 4) { - if (memcmp(m_WordBuffer, "true", 4) == 0) - return new CPDF_Boolean(TRUE); - - if (memcmp(m_WordBuffer, "null", 4) == 0) - return new CPDF_Null; - } - - return nullptr; -} - -void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) { - m_WordSize = 0; - bIsNumber = TRUE; - if (!PositionIsInBounds()) - return; - - int ch = m_pBuf[m_Pos++]; - while (1) { - while (PDFCharIsWhitespace(ch)) { - if (!PositionIsInBounds()) { - return; - } - ch = m_pBuf[m_Pos++]; - } - - if (ch != '%') - break; - - while (1) { - if (!PositionIsInBounds()) - return; - ch = m_pBuf[m_Pos++]; - if (PDFCharIsLineEnding(ch)) - break; - } - } - - if (PDFCharIsDelimiter(ch)) { - bIsNumber = FALSE; - m_WordBuffer[m_WordSize++] = ch; - if (ch == '/') { - while (1) { - if (!PositionIsInBounds()) - return; - ch = m_pBuf[m_Pos++]; - if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) { - m_Pos--; - return; - } - - if (m_WordSize < kMaxWordBuffer) - m_WordBuffer[m_WordSize++] = ch; - } - } else if (ch == '<') { - if (!PositionIsInBounds()) - return; - ch = m_pBuf[m_Pos++]; - if (ch == '<') - m_WordBuffer[m_WordSize++] = ch; - else - m_Pos--; - } else if (ch == '>') { - if (!PositionIsInBounds()) - return; - ch = m_pBuf[m_Pos++]; - if (ch == '>') - m_WordBuffer[m_WordSize++] = ch; - else - m_Pos--; - } - return; - } - - while (1) { - if (m_WordSize < kMaxWordBuffer) - m_WordBuffer[m_WordSize++] = ch; - if (!PDFCharIsNumeric(ch)) - bIsNumber = FALSE; - - if (!PositionIsInBounds()) - return; - ch = m_pBuf[m_Pos++]; - if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { - m_Pos--; - break; - } - } -} - -CFX_ByteString CPDF_StreamParser::ReadString() { - if (!PositionIsInBounds()) - return CFX_ByteString(); - - uint8_t ch = m_pBuf[m_Pos++]; - CFX_ByteTextBuf buf; - int parlevel = 0; - int status = 0; - int iEscCode = 0; - while (1) { - switch (status) { - case 0: - if (ch == ')') { - if (parlevel == 0) { - if (buf.GetLength() > kMaxStringLength) { - return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); - } - return buf.MakeString(); - } - parlevel--; - buf.AppendChar(')'); - } else if (ch == '(') { - parlevel++; - buf.AppendChar('('); - } else if (ch == '\\') { - status = 1; - } else { - buf.AppendChar((char)ch); - } - break; - case 1: - if (ch >= '0' && ch <= '7') { - iEscCode = FXSYS_toDecimalDigit(static_cast(ch)); - status = 2; - break; - } - if (ch == 'n') { - buf.AppendChar('\n'); - } else if (ch == 'r') { - buf.AppendChar('\r'); - } else if (ch == 't') { - buf.AppendChar('\t'); - } else if (ch == 'b') { - buf.AppendChar('\b'); - } else if (ch == 'f') { - buf.AppendChar('\f'); - } else if (ch == '\r') { - status = 4; - break; - } else if (ch == '\n') { - } else { - buf.AppendChar(ch); - } - status = 0; - break; - case 2: - if (ch >= '0' && ch <= '7') { - iEscCode = - iEscCode * 8 + FXSYS_toDecimalDigit(static_cast(ch)); - status = 3; - } else { - buf.AppendChar(iEscCode); - status = 0; - continue; - } - break; - case 3: - if (ch >= '0' && ch <= '7') { - iEscCode = - iEscCode * 8 + FXSYS_toDecimalDigit(static_cast(ch)); - buf.AppendChar(iEscCode); - status = 0; - } else { - buf.AppendChar(iEscCode); - status = 0; - continue; - } - break; - case 4: - status = 0; - if (ch != '\n') { - continue; - } - break; - } - if (!PositionIsInBounds()) - break; - - ch = m_pBuf[m_Pos++]; - } - if (PositionIsInBounds()) - ++m_Pos; - - if (buf.GetLength() > kMaxStringLength) { - return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); - } - return buf.MakeString(); -} - -CFX_ByteString CPDF_StreamParser::ReadHexString() { - if (!PositionIsInBounds()) - return CFX_ByteString(); - - CFX_ByteTextBuf buf; - bool bFirst = true; - int code = 0; - while (PositionIsInBounds()) { - int ch = m_pBuf[m_Pos++]; - - if (ch == '>') - break; - - if (!std::isxdigit(ch)) - continue; - - int val = FXSYS_toHexDigit(ch); - if (bFirst) { - code = val * 16; - } else { - code += val; - buf.AppendByte((uint8_t)code); - } - bFirst = !bFirst; - } - if (!bFirst) - buf.AppendChar((char)code); - - if (buf.GetLength() > kMaxStringLength) - return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); - - return buf.MakeString(); -} - -bool CPDF_StreamParser::PositionIsInBounds() const { - return m_Pos < m_Size; -} - -CPDF_ContentParser::CPDF_ContentParser() - : m_Status(Ready), - m_InternalStage(STAGE_GETCONTENT), - m_pObjectHolder(nullptr), - m_bForm(false), - m_pType3Char(nullptr), - m_pData(nullptr), - m_Size(0), - m_CurrentOffset(0) {} - -CPDF_ContentParser::~CPDF_ContentParser() { - if (!m_pSingleStream) - FX_Free(m_pData); -} - -void CPDF_ContentParser::Start(CPDF_Page* pPage) { - if (m_Status != Ready || !pPage || !pPage->m_pDocument || - !pPage->m_pFormDict) { - m_Status = Done; - return; - } - m_pObjectHolder = pPage; - m_bForm = FALSE; - m_Status = ToBeContinued; - m_InternalStage = STAGE_GETCONTENT; - m_CurrentOffset = 0; - - CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectFor("Contents"); - if (!pContent) { - m_Status = Done; - return; - } - if (CPDF_Stream* pStream = pContent->AsStream()) { - m_nStreams = 0; - m_pSingleStream.reset(new CPDF_StreamAcc); - m_pSingleStream->LoadAllData(pStream, FALSE); - } else if (CPDF_Array* pArray = pContent->AsArray()) { - m_nStreams = pArray->GetCount(); - if (m_nStreams) - m_StreamArray.resize(m_nStreams); - else - m_Status = Done; - } else { - m_Status = Done; - } -} - -void CPDF_ContentParser::Start(CPDF_Form* pForm, - CPDF_AllStates* pGraphicStates, - const CFX_Matrix* pParentMatrix, - CPDF_Type3Char* pType3Char, - int level) { - m_pType3Char = pType3Char; - m_pObjectHolder = pForm; - m_bForm = TRUE; - CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixFor("Matrix"); - if (pGraphicStates) { - form_matrix.Concat(pGraphicStates->m_CTM); - } - CPDF_Array* pBBox = pForm->m_pFormDict->GetArrayFor("BBox"); - CFX_FloatRect form_bbox; - CPDF_Path ClipPath; - if (pBBox) { - form_bbox = pBBox->GetRect(); - ClipPath.Emplace(); - ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, - form_bbox.top); - ClipPath.Transform(&form_matrix); - if (pParentMatrix) { - ClipPath.Transform(pParentMatrix); - } - form_bbox.Transform(&form_matrix); - if (pParentMatrix) { - form_bbox.Transform(pParentMatrix); - } - } - CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictFor("Resources"); - m_pParser.reset(new CPDF_StreamContentParser( - pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, - pParentMatrix, pForm, pResources, &form_bbox, pGraphicStates, level)); - m_pParser->GetCurStates()->m_CTM = form_matrix; - m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; - if (ClipPath) { - m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, - TRUE); - } - if (pForm->m_Transparency & PDFTRANS_GROUP) { - CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState; - pState->SetBlendType(FXDIB_BLEND_NORMAL); - pState->SetStrokeAlpha(1.0f); - pState->SetFillAlpha(1.0f); - pState->SetSoftMask(nullptr); - } - m_nStreams = 0; - m_pSingleStream.reset(new CPDF_StreamAcc); - m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); - m_pData = (uint8_t*)m_pSingleStream->GetData(); - m_Size = m_pSingleStream->GetSize(); - m_Status = ToBeContinued; - m_InternalStage = STAGE_PARSE; - m_CurrentOffset = 0; -} - -void CPDF_ContentParser::Continue(IFX_Pause* pPause) { - int steps = 0; - while (m_Status == ToBeContinued) { - if (m_InternalStage == STAGE_GETCONTENT) { - if (m_CurrentOffset == m_nStreams) { - if (!m_StreamArray.empty()) { - FX_SAFE_UINT32 safeSize = 0; - for (const auto& stream : m_StreamArray) { - safeSize += stream->GetSize(); - safeSize += 1; - } - if (!safeSize.IsValid()) { - m_Status = Done; - return; - } - m_Size = safeSize.ValueOrDie(); - m_pData = FX_Alloc(uint8_t, m_Size); - uint32_t pos = 0; - for (const auto& stream : m_StreamArray) { - FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize()); - pos += stream->GetSize(); - m_pData[pos++] = ' '; - } - m_StreamArray.clear(); - } else { - m_pData = (uint8_t*)m_pSingleStream->GetData(); - m_Size = m_pSingleStream->GetSize(); - } - m_InternalStage = STAGE_PARSE; - m_CurrentOffset = 0; - } else { - CPDF_Array* pContent = - m_pObjectHolder->m_pFormDict->GetArrayFor("Contents"); - m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc); - CPDF_Stream* pStreamObj = ToStream( - pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr); - m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); - m_CurrentOffset++; - } - } - if (m_InternalStage == STAGE_PARSE) { - if (!m_pParser) { - m_pParser.reset(new CPDF_StreamContentParser( - m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources, - nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources, - &m_pObjectHolder->m_BBox, nullptr, 0)); - m_pParser->GetCurStates()->m_ColorState.SetDefault(); - } - if (m_CurrentOffset >= m_Size) { - m_InternalStage = STAGE_CHECKCLIP; - } else { - m_CurrentOffset += - m_pParser->Parse(m_pData + m_CurrentOffset, - m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); - } - } - if (m_InternalStage == STAGE_CHECKCLIP) { - if (m_pType3Char) { - m_pType3Char->m_bColored = m_pParser->IsColored(); - m_pType3Char->m_Width = - FXSYS_round(m_pParser->GetType3Data()[0] * 1000); - m_pType3Char->m_BBox.left = - FXSYS_round(m_pParser->GetType3Data()[2] * 1000); - m_pType3Char->m_BBox.bottom = - FXSYS_round(m_pParser->GetType3Data()[3] * 1000); - m_pType3Char->m_BBox.right = - FXSYS_round(m_pParser->GetType3Data()[4] * 1000); - m_pType3Char->m_BBox.top = - FXSYS_round(m_pParser->GetType3Data()[5] * 1000); - } - for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) { - if (!pObj->m_ClipPath) - continue; - if (pObj->m_ClipPath.GetPathCount() != 1) - continue; - if (pObj->m_ClipPath.GetTextCount()) - continue; - CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); - if (!ClipPath.IsRect() || pObj->IsShading()) - continue; - CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), - ClipPath.GetPointX(2), ClipPath.GetPointY(2)); - CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, - pObj->m_Top); - if (old_rect.Contains(obj_rect)) { - pObj->m_ClipPath.SetNull(); - } - } - m_Status = Done; - return; - } - steps++; - if (pPause && pPause->NeedToPauseNow()) { - break; - } - } -} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_old_unittest.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_old_unittest.cpp deleted file mode 100644 index ff15b21d73..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser_old_unittest.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(fpdf_page_parser_old, ReadHexString) { - { - // Position out of bounds. - uint8_t data[] = "12ab>"; - CPDF_StreamParser parser(data, 5); - parser.SetPos(6); - EXPECT_EQ("", parser.ReadHexString()); - } - - { - // Regular conversion. - uint8_t data[] = "1A2b>abcd"; - CPDF_StreamParser parser(data, 5); - EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); - EXPECT_EQ(5u, parser.GetPos()); - } - - { - // Missing ending > - uint8_t data[] = "1A2b"; - CPDF_StreamParser parser(data, 5); - EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); - EXPECT_EQ(5u, parser.GetPos()); - } - - { - // Uneven number of bytes. - uint8_t data[] = "1A2>asdf"; - CPDF_StreamParser parser(data, 5); - EXPECT_EQ("\x1a\x20", parser.ReadHexString()); - EXPECT_EQ(4u, parser.GetPos()); - } - - { - uint8_t data[] = ">"; - CPDF_StreamParser parser(data, 5); - EXPECT_EQ("", parser.ReadHexString()); - EXPECT_EQ(1u, parser.GetPos()); - } -} diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_unittest.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_unittest.cpp deleted file mode 100644 index 3da36a8f8c..0000000000 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser_unittest.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/fpdfapi/fpdf_page/pageint.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(fpdf_page_parser, PDF_FindKeyAbbreviation) { - EXPECT_EQ(CFX_ByteStringC("BitsPerComponent"), - PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("BPC"))); - EXPECT_EQ(CFX_ByteStringC("Width"), - PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("W"))); - EXPECT_EQ(CFX_ByteStringC(""), - PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC(""))); - EXPECT_EQ(CFX_ByteStringC(""), - PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("NoInList"))); - // Prefix should not match. - EXPECT_EQ(CFX_ByteStringC(""), - PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("WW"))); -} - -TEST(fpdf_page_parser, PDF_FindValueAbbreviation) { - EXPECT_EQ(CFX_ByteStringC("DeviceGray"), - PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("G"))); - EXPECT_EQ(CFX_ByteStringC("DCTDecode"), - PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("DCT"))); - EXPECT_EQ(CFX_ByteStringC(""), - PDF_FindValueAbbreviationForTesting(CFX_ByteStringC(""))); - EXPECT_EQ(CFX_ByteStringC(""), - PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("NoInList"))); - // Prefix should not match. - EXPECT_EQ(CFX_ByteStringC(""), - PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("II"))); -} diff --git a/core/fpdfapi/fpdf_page/pageint.h b/core/fpdfapi/fpdf_page/pageint.h deleted file mode 100644 index 3c10702b9e..0000000000 --- a/core/fpdfapi/fpdf_page/pageint.h +++ /dev/null @@ -1,566 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef CORE_FPDFAPI_FPDF_PAGE_PAGEINT_H_ -#define CORE_FPDFAPI_FPDF_PAGE_PAGEINT_H_ - -#include -#include -#include -#include -#include - -#include "core/fpdfapi/fpdf_page/cpdf_contentmark.h" -#include "core/fpdfapi/fpdf_page/cpdf_countedobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectholder.h" -#include "core/fxcrt/cfx_string_pool_template.h" -#include "core/fxcrt/cfx_weak_ptr.h" -#include "core/fxge/cfx_pathdata.h" -#include "core/fxge/cfx_renderdevice.h" - -class CPDF_AllStates; -class CPDF_ColorSpace; -class CPDF_ExpIntFunc; -class CPDF_Font; -class CPDF_FontEncoding; -class CPDF_Form; -class CPDF_IccProfile; -class CPDF_Image; -class CPDF_ImageObject; -class CPDF_Page; -class CPDF_Pattern; -class CPDF_SampledFunc; -class CPDF_StitchFunc; -class CPDF_StreamAcc; -class CPDF_TextObject; -class CPDF_Type3Char; - -#define PARSE_STEP_LIMIT 100 - -class CPDF_StreamParser { - public: - enum SyntaxType { EndOfData, Number, Keyword, Name, Others }; - - CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize); - CPDF_StreamParser(const uint8_t* pData, - uint32_t dwSize, - const CFX_WeakPtr& pPool); - ~CPDF_StreamParser(); - - CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, - CPDF_Dictionary* pDict, - CPDF_Object* pCSObj); - SyntaxType ParseNextElement(); - uint8_t* GetWordBuf() { return m_WordBuffer; } - uint32_t GetWordSize() const { return m_WordSize; } - CPDF_Object* GetObject() { - CPDF_Object* pObj = m_pLastObj; - m_pLastObj = nullptr; - return pObj; - } - uint32_t GetPos() const { return m_Pos; } - void SetPos(uint32_t pos) { m_Pos = pos; } - CPDF_Object* ReadNextObject(bool bAllowNestedArray, uint32_t dwInArrayLevel); - - protected: - friend class fpdf_page_parser_old_ReadHexString_Test; - - void GetNextWord(FX_BOOL& bIsNumber); - CFX_ByteString ReadString(); - CFX_ByteString ReadHexString(); - - const uint8_t* m_pBuf; - uint32_t m_Size; // Length in bytes of m_pBuf. - uint32_t m_Pos; // Current byte position within m_pBuf. - uint8_t m_WordBuffer[256]; - uint32_t m_WordSize; - CPDF_Object* m_pLastObj; - CFX_WeakPtr m_pPool; - - private: - bool PositionIsInBounds() const; -}; - -#define PARAM_BUF_SIZE 16 -struct ContentParam { - enum Type { OBJECT = 0, NUMBER, NAME }; - Type m_Type; - union { - struct { - bool m_bInteger; - union { - int m_Integer; - FX_FLOAT m_Float; - }; - } m_Number; - CPDF_Object* m_pObject; - struct { - int m_Len; - char m_Buffer[32]; - } m_Name; - }; -}; -#define _FPDF_MAX_FORM_LEVEL_ 30 -#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4 -class CPDF_StreamContentParser { - public: - CPDF_StreamContentParser(CPDF_Document* pDoc, - CPDF_Dictionary* pPageResources, - CPDF_Dictionary* pParentResources, - const CFX_Matrix* pmtContentToUser, - CPDF_PageObjectHolder* pObjectHolder, - CPDF_Dictionary* pResources, - CFX_FloatRect* pBBox, - CPDF_AllStates* pAllStates, - int level); - ~CPDF_StreamContentParser(); - - CPDF_PageObjectHolder* GetPageObjectHolder() const { return m_pObjectHolder; } - CPDF_AllStates* GetCurStates() const { return m_pCurStates.get(); } - FX_BOOL IsColored() const { return m_bColored; } - const FX_FLOAT* GetType3Data() const { return m_Type3Data; } - - void AddNumberParam(const FX_CHAR* str, int len); - void AddObjectParam(CPDF_Object* pObj); - void AddNameParam(const FX_CHAR* name, int size); - int GetNextParamPos(); - void ClearAllParams(); - CPDF_Object* GetObject(uint32_t index); - CFX_ByteString GetString(uint32_t index); - FX_FLOAT GetNumber(uint32_t index); - int GetInteger(uint32_t index) { return (int32_t)(GetNumber(index)); } - void OnOperator(const FX_CHAR* op); - void BigCaseCaller(int index); - uint32_t GetParsePos() { return m_pSyntax->GetPos(); } - void AddTextObject(CFX_ByteString* pText, - FX_FLOAT fInitKerning, - FX_FLOAT* pKerning, - int count); - - void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y); - void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y); - void OnChangeTextMatrix(); - uint32_t Parse(const uint8_t* pData, uint32_t dwSize, uint32_t max_cost); - void ParsePathObject(); - void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag); - void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h); - void AddPathObject(int FillType, FX_BOOL bStroke); - CPDF_ImageObject* AddImage(CPDF_Stream* pStream, - CPDF_Image* pImage, - bool bInline); - void AddDuplicateImage(); - void AddForm(CPDF_Stream* pStream); - void SetGraphicStates(CPDF_PageObject* pObj, - FX_BOOL bColor, - FX_BOOL bText, - FX_BOOL bGraph); - void SaveStates(CPDF_AllStates* pState); - void RestoreStates(CPDF_AllStates* pState); - CPDF_Font* FindFont(const CFX_ByteString& name); - CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name); - CPDF_Pattern* FindPattern(const CFX_ByteString& name, bool bShading); - CPDF_Object* FindResourceObj(const CFX_ByteString& type, - const CFX_ByteString& name); - - protected: - using OpCodes = - std::unordered_map; - static OpCodes InitializeOpCodes(); - - void Handle_CloseFillStrokePath(); - void Handle_FillStrokePath(); - void Handle_CloseEOFillStrokePath(); - void Handle_EOFillStrokePath(); - void Handle_BeginMarkedContent_Dictionary(); - void Handle_BeginImage(); - void Handle_BeginMarkedContent(); - void Handle_BeginText(); - void Handle_CurveTo_123(); - void Handle_ConcatMatrix(); - void Handle_SetColorSpace_Fill(); - void Handle_SetColorSpace_Stroke(); - void Handle_SetDash(); - void Handle_SetCharWidth(); - void Handle_SetCachedDevice(); - void Handle_ExecuteXObject(); - void Handle_MarkPlace_Dictionary(); - void Handle_EndImage(); - void Handle_EndMarkedContent(); - void Handle_EndText(); - void Handle_FillPath(); - void Handle_FillPathOld(); - void Handle_EOFillPath(); - void Handle_SetGray_Fill(); - void Handle_SetGray_Stroke(); - void Handle_SetExtendGraphState(); - void Handle_ClosePath(); - void Handle_SetFlat(); - void Handle_BeginImageData(); - void Handle_SetLineJoin(); - void Handle_SetLineCap(); - void Handle_SetCMYKColor_Fill(); - void Handle_SetCMYKColor_Stroke(); - void Handle_LineTo(); - void Handle_MoveTo(); - void Handle_SetMiterLimit(); - void Handle_MarkPlace(); - void Handle_EndPath(); - void Handle_SaveGraphState(); - void Handle_RestoreGraphState(); - void Handle_Rectangle(); - void Handle_SetRGBColor_Fill(); - void Handle_SetRGBColor_Stroke(); - void Handle_SetRenderIntent(); - void Handle_CloseStrokePath(); - void Handle_StrokePath(); - void Handle_SetColor_Fill(); - void Handle_SetColor_Stroke(); - void Handle_SetColorPS_Fill(); - void Handle_SetColorPS_Stroke(); - void Handle_ShadeFill(); - void Handle_SetCharSpace(); - void Handle_MoveTextPoint(); - void Handle_MoveTextPoint_SetLeading(); - void Handle_SetFont(); - void Handle_ShowText(); - void Handle_ShowText_Positioning(); - void Handle_SetTextLeading(); - void Handle_SetTextMatrix(); - void Handle_SetTextRenderMode(); - void Handle_SetTextRise(); - void Handle_SetWordSpace(); - void Handle_SetHorzScale(); - void Handle_MoveToNextLine(); - void Handle_CurveTo_23(); - void Handle_SetLineWidth(); - void Handle_Clip(); - void Handle_EOClip(); - void Handle_CurveTo_13(); - void Handle_NextLineShowText(); - void Handle_NextLineShowText_Space(); - void Handle_Invalid(); - - CPDF_Document* const m_pDocument; - CPDF_Dictionary* m_pPageResources; - CPDF_Dictionary* m_pParentResources; - CPDF_Dictionary* m_pResources; - CPDF_PageObjectHolder* m_pObjectHolder; - int m_Level; - CFX_Matrix m_mtContentToUser; - CFX_FloatRect m_BBox; - ContentParam m_ParamBuf[PARAM_BUF_SIZE]; - uint32_t m_ParamStartPos; - uint32_t m_ParamCount; - CPDF_StreamParser* m_pSyntax; - std::unique_ptr m_pCurStates; - CPDF_ContentMark m_CurContentMark; - std::vector> m_ClipTextList; - CPDF_TextObject* m_pLastTextObject; - FX_FLOAT m_DefFontSize; - FX_PATHPOINT* m_pPathPoints; - int m_PathPointCount; - int m_PathAllocSize; - FX_FLOAT m_PathStartX; - FX_FLOAT m_PathStartY; - FX_FLOAT m_PathCurrentX; - FX_FLOAT m_PathCurrentY; - uint8_t m_PathClipType; - CFX_ByteString m_LastImageName; - CPDF_Image* m_pLastImage; - CFX_BinaryBuf m_LastImageDict; - CFX_BinaryBuf m_LastImageData; - CPDF_Dictionary* m_pLastImageDict; - CPDF_Dictionary* m_pLastCloneImageDict; - FX_BOOL m_bReleaseLastDict; - FX_BOOL m_bSameLastDict; - FX_BOOL m_bColored; - FX_FLOAT m_Type3Data[6]; - FX_BOOL m_bResourceMissing; - std::vector> m_StateStack; -}; -class CPDF_ContentParser { - public: - enum ParseStatus { Ready, ToBeContinued, Done }; - - CPDF_ContentParser(); - ~CPDF_ContentParser(); - - ParseStatus GetStatus() const { return m_Status; } - void Start(CPDF_Page* pPage); - void Start(CPDF_Form* pForm, - CPDF_AllStates* pGraphicStates, - const CFX_Matrix* pParentMatrix, - CPDF_Type3Char* pType3Char, - int level); - void Continue(IFX_Pause* pPause); - - private: - enum InternalStage { - STAGE_GETCONTENT = 1, - STAGE_PARSE, - STAGE_CHECKCLIP, - }; - - ParseStatus m_Status; - InternalStage m_InternalStage; - CPDF_PageObjectHolder* m_pObjectHolder; - FX_BOOL m_bForm; - CPDF_Type3Char* m_pType3Char; - uint32_t m_nStreams; - std::unique_ptr m_pSingleStream; - std::vector> m_StreamArray; - uint8_t* m_pData; - uint32_t m_Size; - uint32_t m_CurrentOffset; - std::unique_ptr m_pParser; -}; - -class CPDF_DocPageData { - public: - explicit CPDF_DocPageData(CPDF_Document* pPDFDoc); - ~CPDF_DocPageData(); - - void Clear(FX_BOOL bRelease = FALSE); - CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly); - CPDF_Font* GetStandardFont(const CFX_ByteString& fontName, - CPDF_FontEncoding* pEncoding); - void ReleaseFont(const CPDF_Dictionary* pFontDict); - CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, - const CPDF_Dictionary* pResources); - CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj); - void ReleaseColorSpace(const CPDF_Object* pColorSpace); - CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, - FX_BOOL bShading, - const CFX_Matrix& matrix); - void ReleasePattern(const CPDF_Object* pPatternObj); - CPDF_Image* GetImage(CPDF_Object* pImageStream); - void ReleaseImage(const CPDF_Object* pImageStream); - CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream); - void ReleaseIccProfile(const CPDF_IccProfile* pIccProfile); - CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream); - void ReleaseFontFileStreamAcc(const CPDF_Stream* pFontStream); - FX_BOOL IsForceClear() const { return m_bForceClear; } - CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const; - CPDF_CountedPattern* FindPatternPtr(CPDF_Object* pPatternObj) const; - - private: - using CPDF_CountedFont = CPDF_CountedObject; - using CPDF_CountedIccProfile = CPDF_CountedObject; - using CPDF_CountedImage = CPDF_CountedObject; - using CPDF_CountedStreamAcc = CPDF_CountedObject; - - using CPDF_ColorSpaceMap = - std::map; - using CPDF_FontFileMap = std::map; - using CPDF_FontMap = std::map; - using CPDF_IccProfileMap = - std::map; - using CPDF_ImageMap = std::map; - using CPDF_PatternMap = std::map; - - CPDF_ColorSpace* GetColorSpaceImpl(CPDF_Object* pCSObj, - const CPDF_Dictionary* pResources, - std::set* pVisited); - - CPDF_Document* const m_pPDFDoc; - FX_BOOL m_bForceClear; - std::map m_HashProfileMap; - CPDF_ColorSpaceMap m_ColorSpaceMap; - CPDF_FontFileMap m_FontFileMap; - CPDF_FontMap m_FontMap; - CPDF_IccProfileMap m_IccProfileMap; - CPDF_ImageMap m_ImageMap; - CPDF_PatternMap m_PatternMap; -}; - -class CPDF_Function { - public: - enum class Type { - kTypeInvalid = -1, - kType0Sampled = 0, - kType2ExpotentialInterpolation = 2, - kType3Stitching = 3, - kType4PostScript = 4, - }; - - static std::unique_ptr Load(CPDF_Object* pFuncObj); - static Type IntegerToFunctionType(int iType); - - virtual ~CPDF_Function(); - FX_BOOL Call(FX_FLOAT* inputs, - uint32_t ninputs, - FX_FLOAT* results, - int& nresults) const; - uint32_t CountInputs() const { return m_nInputs; } - uint32_t CountOutputs() const { return m_nOutputs; } - FX_FLOAT GetDomain(int i) const { return m_pDomains[i]; } - FX_FLOAT GetRange(int i) const { return m_pRanges[i]; } - - const CPDF_SampledFunc* ToSampledFunc() const; - const CPDF_ExpIntFunc* ToExpIntFunc() const; - const CPDF_StitchFunc* ToStitchFunc() const; - - protected: - explicit CPDF_Function(Type type); - - FX_BOOL Init(CPDF_Object* pObj); - virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0; - virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0; - - uint32_t m_nInputs; - uint32_t m_nOutputs; - FX_FLOAT* m_pDomains; - FX_FLOAT* m_pRanges; - const Type m_Type; -}; - -class CPDF_ExpIntFunc : public CPDF_Function { - public: - CPDF_ExpIntFunc(); - ~CPDF_ExpIntFunc() override; - - // CPDF_Function - FX_BOOL v_Init(CPDF_Object* pObj) override; - FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; - - uint32_t m_nOrigOutputs; - FX_FLOAT m_Exponent; - FX_FLOAT* m_pBeginValues; - FX_FLOAT* m_pEndValues; -}; - -class CPDF_SampledFunc : public CPDF_Function { - public: - struct SampleEncodeInfo { - FX_FLOAT encode_max; - FX_FLOAT encode_min; - uint32_t sizes; - }; - - struct SampleDecodeInfo { - FX_FLOAT decode_max; - FX_FLOAT decode_min; - }; - - CPDF_SampledFunc(); - ~CPDF_SampledFunc() override; - - // CPDF_Function - FX_BOOL v_Init(CPDF_Object* pObj) override; - FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; - - const std::vector& GetEncodeInfo() const { - return m_EncodeInfo; - } - uint32_t GetBitsPerSample() const { return m_nBitsPerSample; } - const CPDF_StreamAcc* GetSampleStream() const { - return m_pSampleStream.get(); - } - - private: - std::vector m_EncodeInfo; - std::vector m_DecodeInfo; - uint32_t m_nBitsPerSample; - uint32_t m_SampleMax; - std::unique_ptr m_pSampleStream; -}; - -class CPDF_StitchFunc : public CPDF_Function { - public: - CPDF_StitchFunc(); - ~CPDF_StitchFunc() override; - - // CPDF_Function - FX_BOOL v_Init(CPDF_Object* pObj) override; - FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; - - const std::vector>& GetSubFunctions() const { - return m_pSubFunctions; - } - FX_FLOAT GetBound(size_t i) const { return m_pBounds[i]; } - - private: - std::vector> m_pSubFunctions; - FX_FLOAT* m_pBounds; - FX_FLOAT* m_pEncode; - - static const uint32_t kRequiredNumInputs = 1; -}; - -class CPDF_IccProfile { - public: - CPDF_IccProfile(const uint8_t* pData, uint32_t dwSize); - ~CPDF_IccProfile(); - uint32_t GetComponents() const { return m_nSrcComponents; } - FX_BOOL m_bsRGB; - void* m_pTransform; - - private: - uint32_t m_nSrcComponents; -}; - -class CPDF_DeviceCS : public CPDF_ColorSpace { - public: - CPDF_DeviceCS(CPDF_Document* pDoc, int family); - - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - FX_BOOL SetRGB(FX_FLOAT* pBuf, - FX_FLOAT R, - FX_FLOAT G, - FX_FLOAT B) const override; - FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, - FX_FLOAT& c, - FX_FLOAT& m, - FX_FLOAT& y, - FX_FLOAT& k) const override; - FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, - FX_FLOAT c, - FX_FLOAT m, - FX_FLOAT y, - FX_FLOAT k) const override; - void TranslateImageLine(uint8_t* pDestBuf, - const uint8_t* pSrcBuf, - int pixels, - int image_width, - int image_height, - FX_BOOL bTransMask = FALSE) const override; -}; - -class CPDF_PatternCS : public CPDF_ColorSpace { - public: - explicit CPDF_PatternCS(CPDF_Document* pDoc); - ~CPDF_PatternCS() override; - FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; - FX_BOOL GetRGB(FX_FLOAT* pBuf, - FX_FLOAT& R, - FX_FLOAT& G, - FX_FLOAT& B) const override; - CPDF_ColorSpace* GetBaseCS() const override; - - private: - CPDF_ColorSpace* m_pBaseCS; - CPDF_CountedColorSpace* m_pCountedBaseCS; -}; - -#define MAX_PATTERN_COLORCOMPS 16 -struct PatternValue { - CPDF_Pattern* m_pPattern; - CPDF_CountedPattern* m_pCountedPattern; - int m_nComps; - FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS]; -}; - -CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr); -CFX_ByteStringC PDF_FindValueAbbreviationForTesting( - const CFX_ByteStringC& abbr); - -void PDF_ReplaceAbbr(CPDF_Object* pObj); -bool IsPathOperator(const uint8_t* buf, size_t len); - -#endif // CORE_FPDFAPI_FPDF_PAGE_PAGEINT_H_ diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp index 811f3a9f95..21469af179 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_document.cpp @@ -12,14 +12,14 @@ #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/cpdf_fontencoding.h" -#include "core/fpdfapi/fpdf_page/cpdf_pagemodule.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_parser.h" #include "core/fpdfapi/fpdf_parser/cpdf_reference.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream.h" #include "core/fpdfapi/fpdf_render/render_int.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxcodec/JBig2_DocumentContext.h" #include "core/fxge/cfx_unicodeencoding.h" #include "core/fxge/fx_font.h" diff --git a/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h b/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h index 5ba3a55453..a488269d8d 100644 --- a/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h +++ b/core/fpdfapi/fpdf_render/cpdf_progressiverenderer.h @@ -9,8 +9,8 @@ #include -#include "core/fpdfapi/fpdf_page/cpdf_pageobjectlist.h" #include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h" +#include "core/fpdfapi/page/cpdf_pageobjectlist.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp index cb1b2042fb..c3085f1155 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render.cpp @@ -11,16 +11,6 @@ #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/font/cpdf_type3char.h" #include "core/fpdfapi/font/cpdf_type3font.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_formobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_page.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pathobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_textobject.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" @@ -29,6 +19,16 @@ #include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h" #include "core/fpdfapi/fpdf_render/cpdf_textrenderer.h" #include "core/fpdfapi/fpdf_render/cpdf_type3cache.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_formobject.h" +#include "core/fpdfapi/page/cpdf_graphicstates.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fpdfdoc/cpdf_occontext.h" #include "core/fxge/cfx_fxgedevice.h" #include "core/fxge/cfx_graphstatedata.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp b/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp index 33b0f3bca5..758a2d7738 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_cache.cpp @@ -6,11 +6,11 @@ #include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" -#include "core/fpdfapi/fpdf_page/cpdf_page.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h" #include "core/fpdfapi/fpdf_render/render_int.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/pageint.h" struct CACHEINFO { uint32_t time; diff --git a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp index d0bca1a17a..c6b0af8822 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_image.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_image.cpp @@ -10,19 +10,19 @@ #include #include -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_page.h" -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" -#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" #include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h" #include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/cpdf_shadingpattern.h" +#include "core/fpdfapi/page/cpdf_tilingpattern.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fpdfdoc/cpdf_occontext.h" #include "core/fxcodec/fx_codec.h" #include "core/fxcrt/fx_safe_types.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp index d040871ac6..4321a9b75e 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp @@ -11,13 +11,13 @@ #include #include "core/fpdfapi/cpdf_modulemgr.h" -#include "core/fpdfapi/fpdf_page/cpdf_image.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxcodec/fx_codec.h" #include "core/fxcrt/fx_safe_types.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp index 55887204ef..3c96e799b2 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_pattern.cpp @@ -8,19 +8,19 @@ #include -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" -#include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pathobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_shadingobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" -#include "core/fpdfapi/fpdf_page/cpdf_tilingpattern.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_array.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_render/cpdf_rendercontext.h" #include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_graphicstates.h" +#include "core/fpdfapi/page/cpdf_meshstream.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_shadingobject.h" +#include "core/fpdfapi/page/cpdf_shadingpattern.h" +#include "core/fpdfapi/page/cpdf_tilingpattern.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxge/cfx_fxgedevice.h" #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" diff --git a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp index 2554f645d4..b15e8f793e 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp @@ -12,17 +12,17 @@ #include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/font/cpdf_type3char.h" #include "core/fpdfapi/font/cpdf_type3font.h" -#include "core/fpdfapi/fpdf_page/cpdf_form.h" -#include "core/fpdfapi/fpdf_page/cpdf_imageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pageobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_pathobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_textobject.h" -#include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" #include "core/fpdfapi/fpdf_parser/cpdf_document.h" #include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h" #include "core/fpdfapi/fpdf_render/cpdf_textrenderer.h" #include "core/fpdfapi/fpdf_render/cpdf_type3cache.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "core/fpdfapi/page/pageint.h" #include "core/fxge/cfx_facecache.h" #include "core/fxge/cfx_fxgedevice.h" #include "core/fxge/cfx_gemodule.h" diff --git a/core/fpdfapi/fpdf_render/render_int.h b/core/fpdfapi/fpdf_render/render_int.h index c913d56a7f..aea618465e 100644 --- a/core/fpdfapi/fpdf_render/render_int.h +++ b/core/fpdfapi/fpdf_render/render_int.h @@ -11,11 +11,11 @@ #include #include -#include "core/fpdfapi/fpdf_page/cpdf_clippath.h" -#include "core/fpdfapi/fpdf_page/cpdf_countedobject.h" -#include "core/fpdfapi/fpdf_page/cpdf_graphicstates.h" #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" #include "core/fpdfapi/fpdf_render/cpdf_renderoptions.h" +#include "core/fpdfapi/page/cpdf_clippath.h" +#include "core/fpdfapi/page/cpdf_countedobject.h" +#include "core/fpdfapi/page/cpdf_graphicstates.h" #include "core/fxge/cfx_fxgedevice.h" #include "core/fxge/cfx_renderdevice.h" diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp new file mode 100644 index 0000000000..f4a99c3206 --- /dev/null +++ b/core/fpdfapi/page/cpdf_allstates.cpp @@ -0,0 +1,175 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_allstates.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/page/pageint.h" +#include "core/fxge/cfx_graphstatedata.h" + +namespace { + +FX_FLOAT ClipFloat(FX_FLOAT f) { + return std::max(0.0f, std::min(1.0f, f)); +} + +} // namespace + +CPDF_AllStates::CPDF_AllStates() { + m_TextX = m_TextY = m_TextLineX = m_TextLineY = 0; + m_TextLeading = 0; + m_TextRise = 0; + m_TextHorzScale = 1.0f; +} + +CPDF_AllStates::~CPDF_AllStates() {} + +void CPDF_AllStates::Copy(const CPDF_AllStates& src) { + CopyStates(src); + m_TextMatrix = src.m_TextMatrix; + m_ParentMatrix = src.m_ParentMatrix; + m_CTM = src.m_CTM; + m_TextX = src.m_TextX; + m_TextY = src.m_TextY; + m_TextLineX = src.m_TextLineX; + m_TextLineY = src.m_TextLineY; + m_TextLeading = src.m_TextLeading; + m_TextRise = src.m_TextRise; + m_TextHorzScale = src.m_TextHorzScale; +} + +void CPDF_AllStates::SetLineDash(CPDF_Array* pArray, + FX_FLOAT phase, + FX_FLOAT scale) { + m_GraphState.SetLineDash(pArray, phase, scale); +} + +void CPDF_AllStates::ProcessExtGS(CPDF_Dictionary* pGS, + CPDF_StreamContentParser* pParser) { + for (const auto& it : *pGS) { + const CFX_ByteString& key_str = it.first; + CPDF_Object* pElement = it.second; + CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr; + if (!pObject) + continue; + + uint32_t key = key_str.GetID(); + switch (key) { + case FXBSTR_ID('L', 'W', 0, 0): + m_GraphState.SetLineWidth(pObject->GetNumber()); + break; + case FXBSTR_ID('L', 'C', 0, 0): + m_GraphState.SetLineCap( + static_cast(pObject->GetInteger())); + break; + case FXBSTR_ID('L', 'J', 0, 0): + m_GraphState.SetLineJoin( + static_cast(pObject->GetInteger())); + break; + case FXBSTR_ID('M', 'L', 0, 0): + m_GraphState.SetMiterLimit(pObject->GetNumber()); + break; + case FXBSTR_ID('D', 0, 0, 0): { + CPDF_Array* pDash = pObject->AsArray(); + if (!pDash) + break; + + CPDF_Array* pArray = pDash->GetArrayAt(0); + if (!pArray) + break; + + SetLineDash(pArray, pDash->GetNumberAt(1), 1.0f); + break; + } + case FXBSTR_ID('R', 'I', 0, 0): + m_GeneralState.SetRenderIntent(pObject->GetString()); + break; + case FXBSTR_ID('F', 'o', 'n', 't'): { + CPDF_Array* pFont = pObject->AsArray(); + if (!pFont) + break; + + m_TextState.SetFontSize(pFont->GetNumberAt(1)); + m_TextState.SetFont(pParser->FindFont(pFont->GetStringAt(0))); + break; + } + case FXBSTR_ID('T', 'R', 0, 0): + if (pGS->KeyExist("TR2")) { + continue; + } + case FXBSTR_ID('T', 'R', '2', 0): + m_GeneralState.SetTR(pObject && !pObject->IsName() ? pObject : nullptr); + break; + case FXBSTR_ID('B', 'M', 0, 0): { + CPDF_Array* pArray = pObject->AsArray(); + m_GeneralState.SetBlendMode(pArray ? pArray->GetStringAt(0) + : pObject->GetString()); + if (m_GeneralState.GetBlendType() > FXDIB_BLEND_MULTIPLY) + pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(TRUE); + break; + } + case FXBSTR_ID('S', 'M', 'a', 's'): + if (ToDictionary(pObject)) { + m_GeneralState.SetSoftMask(pObject); + m_GeneralState.SetSMaskMatrix(pParser->GetCurStates()->m_CTM); + } else { + m_GeneralState.SetSoftMask(nullptr); + } + break; + case FXBSTR_ID('C', 'A', 0, 0): + m_GeneralState.SetStrokeAlpha(ClipFloat(pObject->GetNumber())); + break; + case FXBSTR_ID('c', 'a', 0, 0): + m_GeneralState.SetFillAlpha(ClipFloat(pObject->GetNumber())); + break; + case FXBSTR_ID('O', 'P', 0, 0): + m_GeneralState.SetStrokeOP(!!pObject->GetInteger()); + if (!pGS->KeyExist("op")) + m_GeneralState.SetFillOP(!!pObject->GetInteger()); + break; + case FXBSTR_ID('o', 'p', 0, 0): + m_GeneralState.SetFillOP(!!pObject->GetInteger()); + break; + case FXBSTR_ID('O', 'P', 'M', 0): + m_GeneralState.SetOPMode(pObject->GetInteger()); + break; + case FXBSTR_ID('B', 'G', 0, 0): + if (pGS->KeyExist("BG2")) { + continue; + } + case FXBSTR_ID('B', 'G', '2', 0): + m_GeneralState.SetBG(pObject); + break; + case FXBSTR_ID('U', 'C', 'R', 0): + if (pGS->KeyExist("UCR2")) { + continue; + } + case FXBSTR_ID('U', 'C', 'R', '2'): + m_GeneralState.SetUCR(pObject); + break; + case FXBSTR_ID('H', 'T', 0, 0): + m_GeneralState.SetHT(pObject); + break; + case FXBSTR_ID('F', 'L', 0, 0): + m_GeneralState.SetFlatness(pObject->GetNumber()); + break; + case FXBSTR_ID('S', 'M', 0, 0): + m_GeneralState.SetSmoothness(pObject->GetNumber()); + break; + case FXBSTR_ID('S', 'A', 0, 0): + m_GeneralState.SetStrokeAdjust(!!pObject->GetInteger()); + break; + case FXBSTR_ID('A', 'I', 'S', 0): + m_GeneralState.SetAlphaSource(!!pObject->GetInteger()); + break; + case FXBSTR_ID('T', 'K', 0, 0): + m_GeneralState.SetTextKnockout(!!pObject->GetInteger()); + break; + } + } + m_GeneralState.SetMatrix(m_CTM); +} diff --git a/core/fpdfapi/page/cpdf_allstates.h b/core/fpdfapi/page/cpdf_allstates.h new file mode 100644 index 0000000000..1aa680a2ce --- /dev/null +++ b/core/fpdfapi/page/cpdf_allstates.h @@ -0,0 +1,39 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_ALLSTATES_H_ +#define CORE_FPDFAPI_PAGE_CPDF_ALLSTATES_H_ + +#include "core/fpdfapi/page/cpdf_graphicstates.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Array; +class CPDF_Dictionary; +class CPDF_StreamContentParser; + +class CPDF_AllStates : public CPDF_GraphicStates { + public: + CPDF_AllStates(); + ~CPDF_AllStates() override; + + void Copy(const CPDF_AllStates& src); + void ProcessExtGS(CPDF_Dictionary* pGS, CPDF_StreamContentParser* pParser); + void SetLineDash(CPDF_Array*, FX_FLOAT, FX_FLOAT scale); + + CFX_Matrix m_TextMatrix; + CFX_Matrix m_CTM; + CFX_Matrix m_ParentMatrix; + FX_FLOAT m_TextX; + FX_FLOAT m_TextY; + FX_FLOAT m_TextLineX; + FX_FLOAT m_TextLineY; + FX_FLOAT m_TextLeading; + FX_FLOAT m_TextRise; + FX_FLOAT m_TextHorzScale; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_ALLSTATES_H_ diff --git a/core/fpdfapi/page/cpdf_clippath.cpp b/core/fpdfapi/page/cpdf_clippath.cpp new file mode 100644 index 0000000000..8c268a1b5e --- /dev/null +++ b/core/fpdfapi/page/cpdf_clippath.cpp @@ -0,0 +1,130 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_clippath.h" + +#include + +#include "core/fpdfapi/page/cpdf_path.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "third_party/base/stl_util.h" + +#define FPDF_CLIPPATH_MAX_TEXTS 1024 + +CPDF_ClipPath::CPDF_ClipPath() {} + +CPDF_ClipPath::CPDF_ClipPath(const CPDF_ClipPath& that) : m_Ref(that.m_Ref) {} + +CPDF_ClipPath::~CPDF_ClipPath() {} + +uint32_t CPDF_ClipPath::GetPathCount() const { + return pdfium::CollectionSize(m_Ref.GetObject()->m_PathAndTypeList); +} + +CPDF_Path CPDF_ClipPath::GetPath(size_t i) const { + return m_Ref.GetObject()->m_PathAndTypeList[i].first; +} + +uint8_t CPDF_ClipPath::GetClipType(size_t i) const { + return m_Ref.GetObject()->m_PathAndTypeList[i].second; +} + +uint32_t CPDF_ClipPath::GetTextCount() const { + return pdfium::CollectionSize(m_Ref.GetObject()->m_TextList); +} + +CPDF_TextObject* CPDF_ClipPath::GetText(size_t i) const { + return m_Ref.GetObject()->m_TextList[i].get(); +} + +CFX_FloatRect CPDF_ClipPath::GetClipBox() const { + CFX_FloatRect rect; + FX_BOOL bStarted = FALSE; + int count = GetPathCount(); + if (count) { + rect = GetPath(0).GetBoundingBox(); + for (int i = 1; i < count; i++) { + CFX_FloatRect path_rect = GetPath(i).GetBoundingBox(); + rect.Intersect(path_rect); + } + bStarted = TRUE; + } + count = GetTextCount(); + if (count) { + CFX_FloatRect layer_rect; + FX_BOOL bLayerStarted = FALSE; + for (int i = 0; i < count; i++) { + CPDF_TextObject* pTextObj = GetText(i); + if (!pTextObj) { + if (!bStarted) { + rect = layer_rect; + bStarted = TRUE; + } else { + rect.Intersect(layer_rect); + } + bLayerStarted = FALSE; + } else { + if (!bLayerStarted) { + layer_rect = CFX_FloatRect(pTextObj->GetBBox(nullptr)); + bLayerStarted = TRUE; + } else { + layer_rect.Union(CFX_FloatRect(pTextObj->GetBBox(nullptr))); + } + } + } + } + return rect; +} + +void CPDF_ClipPath::AppendPath(CPDF_Path path, uint8_t type, bool bAutoMerge) { + PathData* pData = m_Ref.GetPrivateCopy(); + if (!pData->m_PathAndTypeList.empty() && bAutoMerge) { + const CPDF_Path& old_path = pData->m_PathAndTypeList.back().first; + if (old_path.IsRect()) { + CFX_FloatRect old_rect(old_path.GetPointX(0), old_path.GetPointY(0), + old_path.GetPointX(2), old_path.GetPointY(2)); + CFX_FloatRect new_rect = path.GetBoundingBox(); + if (old_rect.Contains(new_rect)) + pData->m_PathAndTypeList.pop_back(); + } + } + pData->m_PathAndTypeList.push_back(std::make_pair(path, type)); +} + +void CPDF_ClipPath::AppendTexts( + std::vector>* pTexts) { + PathData* pData = m_Ref.GetPrivateCopy(); + if (pData->m_TextList.size() + pTexts->size() <= FPDF_CLIPPATH_MAX_TEXTS) { + for (size_t i = 0; i < pTexts->size(); i++) + pData->m_TextList.push_back(std::move((*pTexts)[i])); + pData->m_TextList.push_back(std::unique_ptr()); + } + pTexts->clear(); +} + +void CPDF_ClipPath::Transform(const CFX_Matrix& matrix) { + PathData* pData = m_Ref.GetPrivateCopy(); + for (auto& obj : pData->m_PathAndTypeList) + obj.first.Transform(&matrix); + for (auto& text : pData->m_TextList) { + if (text) + text->Transform(matrix); + } +} + +CPDF_ClipPath::PathData::PathData() {} + +CPDF_ClipPath::PathData::PathData(const PathData& that) { + m_PathAndTypeList = that.m_PathAndTypeList; + + m_TextList.resize(that.m_TextList.size()); + for (size_t i = 0; i < that.m_TextList.size(); ++i) { + if (that.m_TextList[i]) + m_TextList[i].reset(that.m_TextList[i]->Clone()); + } +} + +CPDF_ClipPath::PathData::~PathData() {} diff --git a/core/fpdfapi/page/cpdf_clippath.h b/core/fpdfapi/page/cpdf_clippath.h new file mode 100644 index 0000000000..25fc3860da --- /dev/null +++ b/core/fpdfapi/page/cpdf_clippath.h @@ -0,0 +1,63 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_CLIPPATH_H_ +#define CORE_FPDFAPI_PAGE_CPDF_CLIPPATH_H_ + +#include +#include +#include + +#include "core/fpdfapi/page/cpdf_path.h" +#include "core/fxcrt/cfx_count_ref.h" +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_coordinates.h" + +class CPDF_Path; +class CPDF_TextObject; + +class CPDF_ClipPath { + public: + CPDF_ClipPath(); + CPDF_ClipPath(const CPDF_ClipPath& that); + ~CPDF_ClipPath(); + + void Emplace() { m_Ref.Emplace(); } + void SetNull() { m_Ref.SetNull(); } + + explicit operator bool() const { return !!m_Ref; } + bool operator==(const CPDF_ClipPath& that) const { + return m_Ref == that.m_Ref; + } + bool operator!=(const CPDF_ClipPath& that) const { return !(*this == that); } + + uint32_t GetPathCount() const; + CPDF_Path GetPath(size_t i) const; + uint8_t GetClipType(size_t i) const; + uint32_t GetTextCount() const; + CPDF_TextObject* GetText(size_t i) const; + CFX_FloatRect GetClipBox() const; + void AppendPath(CPDF_Path path, uint8_t type, bool bAutoMerge); + void AppendTexts(std::vector>* pTexts); + void Transform(const CFX_Matrix& matrix); + + private: + class PathData { + public: + using PathAndTypeData = std::pair; + + PathData(); + PathData(const PathData& that); + ~PathData(); + + std::vector m_PathAndTypeList; + std::vector> m_TextList; + }; + + CFX_CountRef m_Ref; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_CLIPPATH_H_ diff --git a/core/fpdfapi/page/cpdf_color.cpp b/core/fpdfapi/page/cpdf_color.cpp new file mode 100644 index 0000000000..ec49777d47 --- /dev/null +++ b/core/fpdfapi/page/cpdf_color.cpp @@ -0,0 +1,154 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_color.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/page/pageint.h" +#include "core/fxcrt/fx_system.h" + +CPDF_Color::CPDF_Color() : m_pCS(nullptr), m_pBuffer(nullptr) {} + +CPDF_Color::~CPDF_Color() { + ReleaseBuffer(); + ReleaseColorSpace(); +} + +bool CPDF_Color::IsPattern() const { + return m_pCS && m_pCS->GetFamily() == PDFCS_PATTERN; +} + +void CPDF_Color::ReleaseBuffer() { + if (!m_pBuffer) + return; + + if (m_pCS->GetFamily() == PDFCS_PATTERN) { + PatternValue* pvalue = (PatternValue*)m_pBuffer; + CPDF_Pattern* pPattern = + pvalue->m_pCountedPattern ? pvalue->m_pCountedPattern->get() : nullptr; + if (pPattern && pPattern->document()) { + CPDF_DocPageData* pPageData = pPattern->document()->GetPageData(); + if (pPageData) + pPageData->ReleasePattern(pPattern->pattern_obj()); + } + } + FX_Free(m_pBuffer); + m_pBuffer = nullptr; +} + +void CPDF_Color::ReleaseColorSpace() { + if (m_pCS && m_pCS->m_pDocument) { + m_pCS->m_pDocument->GetPageData()->ReleaseColorSpace(m_pCS->GetArray()); + m_pCS = nullptr; + } +} + +void CPDF_Color::SetColorSpace(CPDF_ColorSpace* pCS) { + if (m_pCS == pCS) { + if (!m_pBuffer) + m_pBuffer = pCS->CreateBuf(); + + ReleaseColorSpace(); + m_pCS = pCS; + return; + } + ReleaseBuffer(); + ReleaseColorSpace(); + + m_pCS = pCS; + if (m_pCS) { + m_pBuffer = pCS->CreateBuf(); + pCS->GetDefaultColor(m_pBuffer); + } +} + +void CPDF_Color::SetValue(FX_FLOAT* comps) { + if (!m_pBuffer) + return; + if (m_pCS->GetFamily() != PDFCS_PATTERN) + FXSYS_memcpy(m_pBuffer, comps, m_pCS->CountComponents() * sizeof(FX_FLOAT)); +} + +void CPDF_Color::SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comps, int ncomps) { + if (ncomps > MAX_PATTERN_COLORCOMPS) + return; + + if (!IsPattern()) { + FX_Free(m_pBuffer); + m_pCS = CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); + m_pBuffer = m_pCS->CreateBuf(); + } + + CPDF_DocPageData* pDocPageData = nullptr; + PatternValue* pvalue = (PatternValue*)m_pBuffer; + if (pvalue->m_pPattern && pvalue->m_pPattern->document()) { + pDocPageData = pvalue->m_pPattern->document()->GetPageData(); + if (pDocPageData) + pDocPageData->ReleasePattern(pvalue->m_pPattern->pattern_obj()); + } + pvalue->m_nComps = ncomps; + pvalue->m_pPattern = pPattern; + if (ncomps) + FXSYS_memcpy(pvalue->m_Comps, comps, ncomps * sizeof(FX_FLOAT)); + + pvalue->m_pCountedPattern = nullptr; + if (pPattern && pPattern->document()) { + if (!pDocPageData) + pDocPageData = pPattern->document()->GetPageData(); + + pvalue->m_pCountedPattern = + pDocPageData->FindPatternPtr(pPattern->pattern_obj()); + } +} + +void CPDF_Color::Copy(const CPDF_Color* pSrc) { + ReleaseBuffer(); + ReleaseColorSpace(); + + m_pCS = pSrc->m_pCS; + if (m_pCS && m_pCS->m_pDocument) { + CPDF_Array* pArray = m_pCS->GetArray(); + if (pArray) + m_pCS = m_pCS->m_pDocument->GetPageData()->GetCopiedColorSpace(pArray); + } + if (!m_pCS) + return; + + m_pBuffer = m_pCS->CreateBuf(); + FXSYS_memcpy(m_pBuffer, pSrc->m_pBuffer, m_pCS->GetBufSize()); + if (m_pCS->GetFamily() != PDFCS_PATTERN) + return; + + PatternValue* pValue = reinterpret_cast(m_pBuffer); + CPDF_Pattern* pPattern = pValue->m_pPattern; + if (pPattern && pPattern->document()) { + pValue->m_pPattern = pPattern->document()->GetPageData()->GetPattern( + pPattern->pattern_obj(), FALSE, pPattern->parent_matrix()); + } +} + +FX_BOOL CPDF_Color::GetRGB(int& R, int& G, int& B) const { + if (!m_pCS || !m_pBuffer) + return FALSE; + + FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; + if (!m_pCS->GetRGB(m_pBuffer, r, g, b)) + return FALSE; + + R = (int32_t)(r * 255 + 0.5f); + G = (int32_t)(g * 255 + 0.5f); + B = (int32_t)(b * 255 + 0.5f); + return TRUE; +} + +CPDF_Pattern* CPDF_Color::GetPattern() const { + if (!m_pBuffer || m_pCS->GetFamily() != PDFCS_PATTERN) + return nullptr; + + PatternValue* pvalue = (PatternValue*)m_pBuffer; + return pvalue->m_pPattern; +} diff --git a/core/fpdfapi/page/cpdf_color.h b/core/fpdfapi/page/cpdf_color.h new file mode 100644 index 0000000000..3eb839a684 --- /dev/null +++ b/core/fpdfapi/page/cpdf_color.h @@ -0,0 +1,41 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_COLOR_H_ +#define CORE_FPDFAPI_PAGE_CPDF_COLOR_H_ + +#include "core/fpdfapi/page/cpdf_colorspace.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Pattern; + +class CPDF_Color { + public: + CPDF_Color(); + ~CPDF_Color(); + + bool IsNull() const { return !m_pBuffer; } + bool IsPattern() const; + + void Copy(const CPDF_Color* pSrc); + + void SetColorSpace(CPDF_ColorSpace* pCS); + void SetValue(FX_FLOAT* comp); + void SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comp, int ncomps); + + FX_BOOL GetRGB(int& R, int& G, int& B) const; + CPDF_Pattern* GetPattern() const; + const CPDF_ColorSpace* GetColorSpace() const { return m_pCS; } + + protected: + void ReleaseBuffer(); + void ReleaseColorSpace(); + + CPDF_ColorSpace* m_pCS; + FX_FLOAT* m_pBuffer; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_COLOR_H_ diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp new file mode 100644 index 0000000000..b43792b19c --- /dev/null +++ b/core/fpdfapi/page/cpdf_colorspace.cpp @@ -0,0 +1,1277 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_colorspace.h" + +#include + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_object.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/fpdf_parser/cpdf_string.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/pageint.h" +#include "core/fxcodec/fx_codec.h" + +namespace { + +const uint8_t g_sRGBSamples1[] = { + 0, 3, 6, 10, 13, 15, 18, 20, 22, 23, 25, 27, 28, 30, 31, + 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 58, + 59, 60, 61, 61, 62, 62, 63, 64, 64, 65, 66, 66, 67, 67, 68, + 68, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 76, 76, + 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, + 84, 84, 85, 85, 85, 86, 86, 87, 87, 88, 88, 88, 89, 89, 90, + 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96, + 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 100, 100, 101, 101, 101, + 102, 102, 102, 103, 103, 103, 104, 104, 104, 105, 105, 106, 106, 106, 107, + 107, 107, 108, 108, 108, 109, 109, 109, 110, 110, 110, 110, 111, 111, 111, + 112, 112, 112, 113, 113, 113, 114, 114, 114, 115, 115, 115, 115, 116, 116, + 116, 117, 117, 117, 118, 118, 118, 118, 119, 119, 119, 120, +}; + +const uint8_t g_sRGBSamples2[] = { + 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, + 150, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, + 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, + 174, 175, 175, 176, 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, + 185, 185, 186, 187, 187, 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, + 194, 195, 196, 196, 197, 197, 198, 199, 199, 200, 200, 201, 202, 202, 203, + 203, 204, 205, 205, 206, 206, 207, 208, 208, 209, 209, 210, 210, 211, 212, + 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 218, 218, 219, 219, 220, + 220, 221, 221, 222, 222, 223, 223, 224, 224, 225, 226, 226, 227, 227, 228, + 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, 233, 234, 234, 235, 235, + 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240, 241, 241, 242, 242, + 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 249, 249, + 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255, +}; + +class CPDF_CalGray : public CPDF_ColorSpace { + public: + explicit CPDF_CalGray(CPDF_Document* pDoc); + + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const override; + + void TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const override; + + private: + FX_FLOAT m_WhitePoint[3]; + FX_FLOAT m_BlackPoint[3]; + FX_FLOAT m_Gamma; +}; + +class CPDF_CalRGB : public CPDF_ColorSpace { + public: + explicit CPDF_CalRGB(CPDF_Document* pDoc); + + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const override; + + void TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const override; + + FX_FLOAT m_WhitePoint[3]; + FX_FLOAT m_BlackPoint[3]; + FX_FLOAT m_Gamma[3]; + FX_FLOAT m_Matrix[9]; + FX_BOOL m_bGamma; + FX_BOOL m_bMatrix; +}; + +class CPDF_LabCS : public CPDF_ColorSpace { + public: + explicit CPDF_LabCS(CPDF_Document* pDoc); + + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + + void GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const override; + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const override; + + void TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const override; + + FX_FLOAT m_WhitePoint[3]; + FX_FLOAT m_BlackPoint[3]; + FX_FLOAT m_Ranges[4]; +}; + +class CPDF_ICCBasedCS : public CPDF_ColorSpace { + public: + explicit CPDF_ICCBasedCS(CPDF_Document* pDoc); + ~CPDF_ICCBasedCS() override; + + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const override; + + FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const override; + + void EnableStdConversion(FX_BOOL bEnabled) override; + void TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const override; + + CPDF_ColorSpace* m_pAlterCS; + CPDF_IccProfile* m_pProfile; + uint8_t* m_pCache; + FX_FLOAT* m_pRanges; + FX_BOOL m_bOwn; +}; + +class CPDF_IndexedCS : public CPDF_ColorSpace { + public: + explicit CPDF_IndexedCS(CPDF_Document* pDoc); + ~CPDF_IndexedCS() override; + + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + CPDF_ColorSpace* GetBaseCS() const override; + + void EnableStdConversion(FX_BOOL bEnabled) override; + + CPDF_ColorSpace* m_pBaseCS; + CPDF_CountedColorSpace* m_pCountedBaseCS; + int m_nBaseComponents; + int m_MaxIndex; + CFX_ByteString m_Table; + FX_FLOAT* m_pCompMinMax; +}; + +class CPDF_SeparationCS : public CPDF_ColorSpace { + public: + explicit CPDF_SeparationCS(CPDF_Document* pDoc); + ~CPDF_SeparationCS() override; + + // CPDF_ColorSpace: + void GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const override; + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + void EnableStdConversion(FX_BOOL bEnabled) override; + + std::unique_ptr m_pAltCS; + std::unique_ptr m_pFunc; + enum { None, All, Colorant } m_Type; +}; + +class CPDF_DeviceNCS : public CPDF_ColorSpace { + public: + explicit CPDF_DeviceNCS(CPDF_Document* pDoc); + ~CPDF_DeviceNCS() override; + + // CPDF_ColorSpace: + void GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const override; + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + void EnableStdConversion(FX_BOOL bEnabled) override; + + std::unique_ptr m_pAltCS; + std::unique_ptr m_pFunc; +}; + +FX_FLOAT RGB_Conversion(FX_FLOAT colorComponent) { + if (colorComponent > 1) + colorComponent = 1; + if (colorComponent < 0) + colorComponent = 0; + + int scale = (int)(colorComponent * 1023); + if (scale < 0) + scale = 0; + if (scale < 192) + colorComponent = (g_sRGBSamples1[scale] / 255.0f); + else + colorComponent = (g_sRGBSamples2[scale / 4 - 48] / 255.0f); + return colorComponent; +} + +void XYZ_to_sRGB(FX_FLOAT X, + FX_FLOAT Y, + FX_FLOAT Z, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) { + FX_FLOAT R1 = 3.2410f * X - 1.5374f * Y - 0.4986f * Z; + FX_FLOAT G1 = -0.9692f * X + 1.8760f * Y + 0.0416f * Z; + FX_FLOAT B1 = 0.0556f * X - 0.2040f * Y + 1.0570f * Z; + + R = RGB_Conversion(R1); + G = RGB_Conversion(G1); + B = RGB_Conversion(B1); +} + +void XYZ_to_sRGB_WhitePoint(FX_FLOAT X, + FX_FLOAT Y, + FX_FLOAT Z, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B, + FX_FLOAT Xw, + FX_FLOAT Yw, + FX_FLOAT Zw) { + // The following RGB_xyz is based on + // sRGB value {Rx,Ry}={0.64, 0.33}, {Gx,Gy}={0.30, 0.60}, {Bx,By}={0.15, 0.06} + + FX_FLOAT Rx = 0.64f, Ry = 0.33f; + FX_FLOAT Gx = 0.30f, Gy = 0.60f; + FX_FLOAT Bx = 0.15f, By = 0.06f; + CFX_Matrix_3by3 RGB_xyz(Rx, Gx, Bx, Ry, Gy, By, 1 - Rx - Ry, 1 - Gx - Gy, + 1 - Bx - By); + CFX_Vector_3by1 whitePoint(Xw, Yw, Zw); + CFX_Vector_3by1 XYZ(X, Y, Z); + + CFX_Vector_3by1 RGB_Sum_XYZ = RGB_xyz.Inverse().TransformVector(whitePoint); + CFX_Matrix_3by3 RGB_SUM_XYZ_DIAG(RGB_Sum_XYZ.a, 0, 0, 0, RGB_Sum_XYZ.b, 0, 0, + 0, RGB_Sum_XYZ.c); + CFX_Matrix_3by3 M = RGB_xyz.Multiply(RGB_SUM_XYZ_DIAG); + CFX_Vector_3by1 RGB = M.Inverse().TransformVector(XYZ); + + R = RGB_Conversion(RGB.a); + G = RGB_Conversion(RGB.b); + B = RGB_Conversion(RGB.c); +} + +} // namespace + +CPDF_ColorSpace* CPDF_ColorSpace::ColorspaceFromName( + const CFX_ByteString& name) { + if (name == "DeviceRGB" || name == "RGB") + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + if (name == "DeviceGray" || name == "G") + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + if (name == "DeviceCMYK" || name == "CMYK") + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + if (name == "Pattern") + return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); + return nullptr; +} + +CPDF_ColorSpace* CPDF_ColorSpace::GetStockCS(int family) { + return CPDF_ModuleMgr::Get()->GetPageModule()->GetStockCS(family); +} + +std::unique_ptr CPDF_ColorSpace::Load(CPDF_Document* pDoc, + CPDF_Object* pObj) { + if (!pObj) + return std::unique_ptr(); + + if (pObj->IsName()) { + return std::unique_ptr( + ColorspaceFromName(pObj->GetString())); + } + if (CPDF_Stream* pStream = pObj->AsStream()) { + CPDF_Dictionary* pDict = pStream->GetDict(); + if (!pDict) + return std::unique_ptr(); + + for (const auto& it : *pDict) { + std::unique_ptr pRet; + CPDF_Object* pValue = it.second; + if (ToName(pValue)) + pRet.reset(ColorspaceFromName(pValue->GetString())); + if (pRet) + return pRet; + } + return std::unique_ptr(); + } + + CPDF_Array* pArray = pObj->AsArray(); + if (!pArray || pArray->IsEmpty()) + return std::unique_ptr(); + + CPDF_Object* pFamilyObj = pArray->GetDirectObjectAt(0); + if (!pFamilyObj) + return std::unique_ptr(); + + CFX_ByteString familyname = pFamilyObj->GetString(); + if (pArray->GetCount() == 1) + return std::unique_ptr(ColorspaceFromName(familyname)); + + std::unique_ptr pCS; + uint32_t id = familyname.GetID(); + if (id == FXBSTR_ID('C', 'a', 'l', 'G')) { + pCS.reset(new CPDF_CalGray(pDoc)); + } else if (id == FXBSTR_ID('C', 'a', 'l', 'R')) { + pCS.reset(new CPDF_CalRGB(pDoc)); + } else if (id == FXBSTR_ID('L', 'a', 'b', 0)) { + pCS.reset(new CPDF_LabCS(pDoc)); + } else if (id == FXBSTR_ID('I', 'C', 'C', 'B')) { + pCS.reset(new CPDF_ICCBasedCS(pDoc)); + } else if (id == FXBSTR_ID('I', 'n', 'd', 'e') || + id == FXBSTR_ID('I', 0, 0, 0)) { + pCS.reset(new CPDF_IndexedCS(pDoc)); + } else if (id == FXBSTR_ID('S', 'e', 'p', 'a')) { + pCS.reset(new CPDF_SeparationCS(pDoc)); + } else if (id == FXBSTR_ID('D', 'e', 'v', 'i')) { + pCS.reset(new CPDF_DeviceNCS(pDoc)); + } else if (id == FXBSTR_ID('P', 'a', 't', 't')) { + pCS.reset(new CPDF_PatternCS(pDoc)); + } else { + return std::unique_ptr(); + } + pCS->m_pArray = pArray; + if (!pCS->v_Load(pDoc, pArray)) + return std::unique_ptr(); + + return pCS; +} + +void CPDF_ColorSpace::Release() { + if (this == GetStockCS(PDFCS_DEVICERGB) || + this == GetStockCS(PDFCS_DEVICEGRAY) || + this == GetStockCS(PDFCS_DEVICECMYK) || + this == GetStockCS(PDFCS_PATTERN)) { + return; + } + delete this; +} + +int CPDF_ColorSpace::GetBufSize() const { + if (m_Family == PDFCS_PATTERN) { + return sizeof(PatternValue); + } + return m_nComponents * sizeof(FX_FLOAT); +} + +FX_FLOAT* CPDF_ColorSpace::CreateBuf() { + int size = GetBufSize(); + uint8_t* pBuf = FX_Alloc(uint8_t, size); + return (FX_FLOAT*)pBuf; +} + +FX_BOOL CPDF_ColorSpace::sRGB() const { + if (m_Family == PDFCS_DEVICERGB) { + return TRUE; + } + if (m_Family != PDFCS_ICCBASED) { + return FALSE; + } + CPDF_ICCBasedCS* pCS = (CPDF_ICCBasedCS*)this; + return pCS->m_pProfile->m_bsRGB; +} + +FX_BOOL CPDF_ColorSpace::SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const { + return FALSE; +} + +FX_BOOL CPDF_ColorSpace::GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const { + if (v_GetCMYK(pBuf, c, m, y, k)) { + return TRUE; + } + FX_FLOAT R, G, B; + if (!GetRGB(pBuf, R, G, B)) { + return FALSE; + } + sRGB_to_AdobeCMYK(R, G, B, c, m, y, k); + return TRUE; +} + +FX_BOOL CPDF_ColorSpace::SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const { + if (v_SetCMYK(pBuf, c, m, y, k)) { + return TRUE; + } + FX_FLOAT R, G, B; + AdobeCMYK_to_sRGB(c, m, y, k, R, G, B); + return SetRGB(pBuf, R, G, B); +} + +void CPDF_ColorSpace::GetDefaultColor(FX_FLOAT* buf) const { + if (!buf || m_Family == PDFCS_PATTERN) { + return; + } + FX_FLOAT min, max; + for (uint32_t i = 0; i < m_nComponents; i++) { + GetDefaultValue(i, buf[i], min, max); + } +} + +uint32_t CPDF_ColorSpace::CountComponents() const { + return m_nComponents; +} + +void CPDF_ColorSpace::GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const { + value = 0; + min = 0; + max = 1.0f; +} + +void CPDF_ColorSpace::TranslateImageLine(uint8_t* dest_buf, + const uint8_t* src_buf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask) const { + CFX_FixedBufGrow srcbuf(m_nComponents); + FX_FLOAT* src = srcbuf; + FX_FLOAT R, G, B; + for (int i = 0; i < pixels; i++) { + for (uint32_t j = 0; j < m_nComponents; j++) + if (m_Family == PDFCS_INDEXED) { + src[j] = (FX_FLOAT)(*src_buf++); + } else { + src[j] = (FX_FLOAT)(*src_buf++) / 255; + } + GetRGB(src, R, G, B); + *dest_buf++ = (int32_t)(B * 255); + *dest_buf++ = (int32_t)(G * 255); + *dest_buf++ = (int32_t)(R * 255); + } +} + +CPDF_ColorSpace* CPDF_ColorSpace::GetBaseCS() const { + return nullptr; +} + +void CPDF_ColorSpace::EnableStdConversion(FX_BOOL bEnabled) { + if (bEnabled) + m_dwStdConversion++; + else if (m_dwStdConversion) + m_dwStdConversion--; +} + +CPDF_ColorSpace::CPDF_ColorSpace(CPDF_Document* pDoc, + int family, + uint32_t nComponents) + : m_pDocument(pDoc), + m_Family(family), + m_nComponents(nComponents), + m_pArray(nullptr), + m_dwStdConversion(0) {} + +CPDF_ColorSpace::~CPDF_ColorSpace() {} + +FX_BOOL CPDF_ColorSpace::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + return TRUE; +} + +FX_BOOL CPDF_ColorSpace::v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const { + return FALSE; +} + +FX_BOOL CPDF_ColorSpace::v_SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const { + return FALSE; +} + +CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY, 1) {} + +FX_BOOL CPDF_CalGray::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CPDF_Dictionary* pDict = pArray->GetDictAt(1); + if (!pDict) + return FALSE; + + CPDF_Array* pParam = pDict->GetArrayFor("WhitePoint"); + int i; + for (i = 0; i < 3; i++) + m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0; + + pParam = pDict->GetArrayFor("BlackPoint"); + for (i = 0; i < 3; i++) + m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0; + + m_Gamma = pDict->GetNumberFor("Gamma"); + if (m_Gamma == 0) + m_Gamma = 1.0f; + return TRUE; +} + +FX_BOOL CPDF_CalGray::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + R = G = B = *pBuf; + return TRUE; +} + +FX_BOOL CPDF_CalGray::SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const { + if (R == G && R == B) { + *pBuf = R; + return TRUE; + } + return FALSE; +} + +void CPDF_CalGray::TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask) const { + for (int i = 0; i < pixels; i++) { + *pDestBuf++ = pSrcBuf[i]; + *pDestBuf++ = pSrcBuf[i]; + *pDestBuf++ = pSrcBuf[i]; + } +} + +CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_CALRGB, 3) {} + +FX_BOOL CPDF_CalRGB::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CPDF_Dictionary* pDict = pArray->GetDictAt(1); + if (!pDict) + return FALSE; + + CPDF_Array* pParam = pDict->GetArrayFor("WhitePoint"); + int i; + for (i = 0; i < 3; i++) + m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0; + + pParam = pDict->GetArrayFor("BlackPoint"); + for (i = 0; i < 3; i++) + m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0; + + pParam = pDict->GetArrayFor("Gamma"); + if (pParam) { + m_bGamma = TRUE; + for (i = 0; i < 3; i++) + m_Gamma[i] = pParam->GetNumberAt(i); + } else { + m_bGamma = FALSE; + } + + pParam = pDict->GetArrayFor("Matrix"); + if (pParam) { + m_bMatrix = TRUE; + for (i = 0; i < 9; i++) + m_Matrix[i] = pParam->GetNumberAt(i); + } else { + m_bMatrix = FALSE; + } + return TRUE; +} + +FX_BOOL CPDF_CalRGB::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + FX_FLOAT A_ = pBuf[0]; + FX_FLOAT B_ = pBuf[1]; + FX_FLOAT C_ = pBuf[2]; + if (m_bGamma) { + A_ = (FX_FLOAT)FXSYS_pow(A_, m_Gamma[0]); + B_ = (FX_FLOAT)FXSYS_pow(B_, m_Gamma[1]); + C_ = (FX_FLOAT)FXSYS_pow(C_, m_Gamma[2]); + } + + FX_FLOAT X; + FX_FLOAT Y; + FX_FLOAT Z; + if (m_bMatrix) { + X = m_Matrix[0] * A_ + m_Matrix[3] * B_ + m_Matrix[6] * C_; + Y = m_Matrix[1] * A_ + m_Matrix[4] * B_ + m_Matrix[7] * C_; + Z = m_Matrix[2] * A_ + m_Matrix[5] * B_ + m_Matrix[8] * C_; + } else { + X = A_; + Y = B_; + Z = C_; + } + XYZ_to_sRGB_WhitePoint(X, Y, Z, R, G, B, m_WhitePoint[0], m_WhitePoint[1], + m_WhitePoint[2]); + return TRUE; +} + +FX_BOOL CPDF_CalRGB::SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const { + pBuf[0] = R; + pBuf[1] = G; + pBuf[2] = B; + return TRUE; +} + +void CPDF_CalRGB::TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask) const { + if (bTransMask) { + FX_FLOAT Cal[3]; + FX_FLOAT R; + FX_FLOAT G; + FX_FLOAT B; + for (int i = 0; i < pixels; i++) { + Cal[0] = ((FX_FLOAT)pSrcBuf[2]) / 255; + Cal[1] = ((FX_FLOAT)pSrcBuf[1]) / 255; + Cal[2] = ((FX_FLOAT)pSrcBuf[0]) / 255; + GetRGB(Cal, R, G, B); + pDestBuf[0] = FXSYS_round(B * 255); + pDestBuf[1] = FXSYS_round(G * 255); + pDestBuf[2] = FXSYS_round(R * 255); + pSrcBuf += 3; + pDestBuf += 3; + } + } + ReverseRGB(pDestBuf, pSrcBuf, pixels); +} + +CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_LAB, 3) {} + +void CPDF_LabCS::GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const { + ASSERT(iComponent < 3); + value = 0; + if (iComponent == 0) { + min = 0; + max = 100 * 1.0f; + } else { + min = m_Ranges[iComponent * 2 - 2]; + max = m_Ranges[iComponent * 2 - 1]; + if (value < min) + value = min; + else if (value > max) + value = max; + } +} + +FX_BOOL CPDF_LabCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CPDF_Dictionary* pDict = pArray->GetDictAt(1); + if (!pDict) + return FALSE; + + CPDF_Array* pParam = pDict->GetArrayFor("WhitePoint"); + int i; + for (i = 0; i < 3; i++) + m_WhitePoint[i] = pParam ? pParam->GetNumberAt(i) : 0; + + pParam = pDict->GetArrayFor("BlackPoint"); + for (i = 0; i < 3; i++) + m_BlackPoint[i] = pParam ? pParam->GetNumberAt(i) : 0; + + pParam = pDict->GetArrayFor("Range"); + const FX_FLOAT def_ranges[4] = {-100 * 1.0f, 100 * 1.0f, -100 * 1.0f, + 100 * 1.0f}; + for (i = 0; i < 4; i++) + m_Ranges[i] = pParam ? pParam->GetNumberAt(i) : def_ranges[i]; + return TRUE; +} + +FX_BOOL CPDF_LabCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + FX_FLOAT Lstar = pBuf[0]; + FX_FLOAT astar = pBuf[1]; + FX_FLOAT bstar = pBuf[2]; + FX_FLOAT M = (Lstar + 16.0f) / 116.0f; + FX_FLOAT L = M + astar / 500.0f; + FX_FLOAT N = M - bstar / 200.0f; + FX_FLOAT X, Y, Z; + if (L < 0.2069f) + X = 0.957f * 0.12842f * (L - 0.1379f); + else + X = 0.957f * L * L * L; + + if (M < 0.2069f) + Y = 0.12842f * (M - 0.1379f); + else + Y = M * M * M; + + if (N < 0.2069f) + Z = 1.0889f * 0.12842f * (N - 0.1379f); + else + Z = 1.0889f * N * N * N; + + XYZ_to_sRGB(X, Y, Z, R, G, B); + return TRUE; +} + +FX_BOOL CPDF_LabCS::SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const { + return FALSE; +} + +void CPDF_LabCS::TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask) const { + for (int i = 0; i < pixels; i++) { + FX_FLOAT lab[3]; + FX_FLOAT R, G, B; + lab[0] = (pSrcBuf[0] * 100 / 255.0f); + lab[1] = (FX_FLOAT)(pSrcBuf[1] - 128); + lab[2] = (FX_FLOAT)(pSrcBuf[2] - 128); + GetRGB(lab, R, G, B); + pDestBuf[0] = (int32_t)(B * 255); + pDestBuf[1] = (int32_t)(G * 255); + pDestBuf[2] = (int32_t)(R * 255); + pDestBuf += 3; + pSrcBuf += 3; + } +} + +CPDF_ICCBasedCS::CPDF_ICCBasedCS(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_ICCBASED, 0), + m_pAlterCS(nullptr), + m_pProfile(nullptr), + m_pCache(nullptr), + m_pRanges(nullptr), + m_bOwn(FALSE) {} + +CPDF_ICCBasedCS::~CPDF_ICCBasedCS() { + FX_Free(m_pCache); + FX_Free(m_pRanges); + if (m_pAlterCS && m_bOwn) + m_pAlterCS->Release(); + if (m_pProfile && m_pDocument) + m_pDocument->GetPageData()->ReleaseIccProfile(m_pProfile); +} + +FX_BOOL CPDF_ICCBasedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CPDF_Stream* pStream = pArray->GetStreamAt(1); + if (!pStream) + return FALSE; + + m_pProfile = pDoc->LoadIccProfile(pStream); + if (!m_pProfile) + return FALSE; + + m_nComponents = + m_pProfile + ->GetComponents(); // Try using the nComponents from ICC profile + CPDF_Dictionary* pDict = pStream->GetDict(); + if (!m_pProfile->m_pTransform) { // No valid ICC profile or using sRGB + CPDF_Object* pAlterCSObj = + pDict ? pDict->GetDirectObjectFor("Alternate") : nullptr; + if (pAlterCSObj) { + std::unique_ptr pAlterCS = + CPDF_ColorSpace::Load(pDoc, pAlterCSObj); + if (pAlterCS) { + if (m_nComponents == 0) { // NO valid ICC profile + if (pAlterCS->CountComponents() > 0) { // Use Alternative colorspace + m_nComponents = pAlterCS->CountComponents(); + m_pAlterCS = pAlterCS.release(); + m_bOwn = TRUE; + } else { // No valid alternative colorspace + int32_t nDictComponents = pDict ? pDict->GetIntegerFor("N") : 0; + if (nDictComponents != 1 && nDictComponents != 3 && + nDictComponents != 4) { + return FALSE; + } + m_nComponents = nDictComponents; + } + } else { // Using sRGB + if (pAlterCS->CountComponents() == m_nComponents) { + m_pAlterCS = pAlterCS.release(); + m_bOwn = TRUE; + } + } + } + } + if (!m_pAlterCS) { + if (m_nComponents == 1) + m_pAlterCS = GetStockCS(PDFCS_DEVICEGRAY); + else if (m_nComponents == 3) + m_pAlterCS = GetStockCS(PDFCS_DEVICERGB); + else if (m_nComponents == 4) + m_pAlterCS = GetStockCS(PDFCS_DEVICECMYK); + } + } + CPDF_Array* pRanges = pDict->GetArrayFor("Range"); + m_pRanges = FX_Alloc2D(FX_FLOAT, m_nComponents, 2); + for (uint32_t i = 0; i < m_nComponents * 2; i++) { + if (pRanges) + m_pRanges[i] = pRanges->GetNumberAt(i); + else if (i % 2) + m_pRanges[i] = 1.0f; + else + m_pRanges[i] = 0; + } + return TRUE; +} + +FX_BOOL CPDF_ICCBasedCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + if (m_pProfile && m_pProfile->m_bsRGB) { + R = pBuf[0]; + G = pBuf[1]; + B = pBuf[2]; + return TRUE; + } + CCodec_IccModule* pIccModule = CPDF_ModuleMgr::Get()->GetIccModule(); + if (!m_pProfile->m_pTransform || !pIccModule) { + if (m_pAlterCS) + return m_pAlterCS->GetRGB(pBuf, R, G, B); + + R = 0.0f; + G = 0.0f; + B = 0.0f; + return TRUE; + } + FX_FLOAT rgb[3]; + pIccModule->SetComponents(m_nComponents); + pIccModule->Translate(m_pProfile->m_pTransform, pBuf, rgb); + R = rgb[0]; + G = rgb[1]; + B = rgb[2]; + return TRUE; +} + +FX_BOOL CPDF_ICCBasedCS::SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const { + return FALSE; +} + +FX_BOOL CPDF_ICCBasedCS::v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const { + if (m_nComponents != 4) + return FALSE; + + c = pBuf[0]; + m = pBuf[1]; + y = pBuf[2]; + k = pBuf[3]; + return TRUE; +} + +void CPDF_ICCBasedCS::EnableStdConversion(FX_BOOL bEnabled) { + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pAlterCS) + m_pAlterCS->EnableStdConversion(bEnabled); +} + +void CPDF_ICCBasedCS::TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask) const { + if (m_pProfile->m_bsRGB) { + ReverseRGB(pDestBuf, pSrcBuf, pixels); + } else if (m_pProfile->m_pTransform) { + int nMaxColors = 1; + for (uint32_t i = 0; i < m_nComponents; i++) { + nMaxColors *= 52; + } + if (m_nComponents > 3 || image_width * image_height < nMaxColors * 3 / 2) { + CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline( + m_pProfile->m_pTransform, pDestBuf, pSrcBuf, pixels); + } else { + if (!m_pCache) { + ((CPDF_ICCBasedCS*)this)->m_pCache = FX_Alloc2D(uint8_t, nMaxColors, 3); + uint8_t* temp_src = FX_Alloc2D(uint8_t, nMaxColors, m_nComponents); + uint8_t* pSrc = temp_src; + for (int i = 0; i < nMaxColors; i++) { + uint32_t color = i; + uint32_t order = nMaxColors / 52; + for (uint32_t c = 0; c < m_nComponents; c++) { + *pSrc++ = (uint8_t)(color / order * 5); + color %= order; + order /= 52; + } + } + CPDF_ModuleMgr::Get()->GetIccModule()->TranslateScanline( + m_pProfile->m_pTransform, m_pCache, temp_src, nMaxColors); + FX_Free(temp_src); + } + for (int i = 0; i < pixels; i++) { + int index = 0; + for (uint32_t c = 0; c < m_nComponents; c++) { + index = index * 52 + (*pSrcBuf) / 5; + pSrcBuf++; + } + index *= 3; + *pDestBuf++ = m_pCache[index]; + *pDestBuf++ = m_pCache[index + 1]; + *pDestBuf++ = m_pCache[index + 2]; + } + } + } else if (m_pAlterCS) { + m_pAlterCS->TranslateImageLine(pDestBuf, pSrcBuf, pixels, image_width, + image_height); + } +} + +CPDF_IndexedCS::CPDF_IndexedCS(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_INDEXED, 1), + m_pBaseCS(nullptr), + m_pCountedBaseCS(nullptr), + m_pCompMinMax(nullptr) {} + +CPDF_IndexedCS::~CPDF_IndexedCS() { + FX_Free(m_pCompMinMax); + CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : nullptr; + if (pCS && m_pDocument) { + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); + } +} + +FX_BOOL CPDF_IndexedCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + if (pArray->GetCount() < 4) { + return FALSE; + } + CPDF_Object* pBaseObj = pArray->GetDirectObjectAt(1); + if (pBaseObj == m_pArray) { + return FALSE; + } + CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); + m_pBaseCS = pDocPageData->GetColorSpace(pBaseObj, nullptr); + if (!m_pBaseCS) { + return FALSE; + } + m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); + m_nBaseComponents = m_pBaseCS->CountComponents(); + m_pCompMinMax = FX_Alloc2D(FX_FLOAT, m_nBaseComponents, 2); + FX_FLOAT defvalue; + for (int i = 0; i < m_nBaseComponents; i++) { + m_pBaseCS->GetDefaultValue(i, defvalue, m_pCompMinMax[i * 2], + m_pCompMinMax[i * 2 + 1]); + m_pCompMinMax[i * 2 + 1] -= m_pCompMinMax[i * 2]; + } + m_MaxIndex = pArray->GetIntegerAt(2); + + CPDF_Object* pTableObj = pArray->GetDirectObjectAt(3); + if (!pTableObj) + return FALSE; + + if (CPDF_String* pString = pTableObj->AsString()) { + m_Table = pString->GetString(); + } else if (CPDF_Stream* pStream = pTableObj->AsStream()) { + CPDF_StreamAcc acc; + acc.LoadAllData(pStream, FALSE); + m_Table = CFX_ByteStringC(acc.GetData(), acc.GetSize()); + } + return TRUE; +} + +FX_BOOL CPDF_IndexedCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + int index = (int32_t)(*pBuf); + if (index < 0 || index > m_MaxIndex) { + return FALSE; + } + if (m_nBaseComponents) { + if (index == INT_MAX || (index + 1) > INT_MAX / m_nBaseComponents || + (index + 1) * m_nBaseComponents > (int)m_Table.GetLength()) { + R = G = B = 0; + return FALSE; + } + } + CFX_FixedBufGrow Comps(m_nBaseComponents); + FX_FLOAT* comps = Comps; + const uint8_t* pTable = m_Table.raw_str(); + for (int i = 0; i < m_nBaseComponents; i++) { + comps[i] = + m_pCompMinMax[i * 2] + + m_pCompMinMax[i * 2 + 1] * pTable[index * m_nBaseComponents + i] / 255; + } + return m_pBaseCS->GetRGB(comps, R, G, B); +} + +CPDF_ColorSpace* CPDF_IndexedCS::GetBaseCS() const { + return m_pBaseCS; +} + +void CPDF_IndexedCS::EnableStdConversion(FX_BOOL bEnabled) { + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pBaseCS) { + m_pBaseCS->EnableStdConversion(bEnabled); + } +} + +CPDF_PatternCS::CPDF_PatternCS(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_PATTERN, 1), + m_pBaseCS(nullptr), + m_pCountedBaseCS(nullptr) {} + +CPDF_PatternCS::~CPDF_PatternCS() { + CPDF_ColorSpace* pCS = m_pCountedBaseCS ? m_pCountedBaseCS->get() : nullptr; + if (pCS && m_pDocument) { + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); + } +} + +FX_BOOL CPDF_PatternCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CPDF_Object* pBaseCS = pArray->GetDirectObjectAt(1); + if (pBaseCS == m_pArray) { + return FALSE; + } + CPDF_DocPageData* pDocPageData = pDoc->GetPageData(); + m_pBaseCS = pDocPageData->GetColorSpace(pBaseCS, nullptr); + if (m_pBaseCS) { + if (m_pBaseCS->GetFamily() == PDFCS_PATTERN) { + return FALSE; + } + m_pCountedBaseCS = pDocPageData->FindColorSpacePtr(m_pBaseCS->GetArray()); + m_nComponents = m_pBaseCS->CountComponents() + 1; + if (m_pBaseCS->CountComponents() > MAX_PATTERN_COLORCOMPS) { + return FALSE; + } + } else { + m_nComponents = 1; + } + return TRUE; +} + +FX_BOOL CPDF_PatternCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + if (m_pBaseCS) { + ASSERT(m_pBaseCS->GetFamily() != PDFCS_PATTERN); + PatternValue* pvalue = (PatternValue*)pBuf; + if (m_pBaseCS->GetRGB(pvalue->m_Comps, R, G, B)) { + return TRUE; + } + } + R = G = B = 0.75f; + return FALSE; +} + +CPDF_ColorSpace* CPDF_PatternCS::GetBaseCS() const { + return m_pBaseCS; +} + +CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION, 1) {} + +CPDF_SeparationCS::~CPDF_SeparationCS() {} + +void CPDF_SeparationCS::GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const { + value = 1.0f; + min = 0; + max = 1.0f; +} + +FX_BOOL CPDF_SeparationCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CFX_ByteString name = pArray->GetStringAt(1); + if (name == "None") { + m_Type = None; + return TRUE; + } + + m_Type = Colorant; + CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2); + if (pAltCS == m_pArray) + return FALSE; + + m_pAltCS = Load(pDoc, pAltCS); + if (!m_pAltCS) + return FALSE; + + CPDF_Object* pFuncObj = pArray->GetDirectObjectAt(3); + if (pFuncObj && !pFuncObj->IsName()) + m_pFunc = CPDF_Function::Load(pFuncObj); + + if (m_pFunc && m_pFunc->CountOutputs() < m_pAltCS->CountComponents()) + m_pFunc.reset(); + return TRUE; +} + +FX_BOOL CPDF_SeparationCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + if (m_Type == None) + return FALSE; + + if (!m_pFunc) { + if (!m_pAltCS) + return FALSE; + + int nComps = m_pAltCS->CountComponents(); + CFX_FixedBufGrow results(nComps); + for (int i = 0; i < nComps; i++) + results[i] = *pBuf; + return m_pAltCS->GetRGB(results, R, G, B); + } + + CFX_FixedBufGrow results(m_pFunc->CountOutputs()); + int nresults = 0; + m_pFunc->Call(pBuf, 1, results, nresults); + if (nresults == 0) + return FALSE; + + if (m_pAltCS) + return m_pAltCS->GetRGB(results, R, G, B); + + R = 0; + G = 0; + B = 0; + return FALSE; +} + +void CPDF_SeparationCS::EnableStdConversion(FX_BOOL bEnabled) { + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pAltCS) + m_pAltCS->EnableStdConversion(bEnabled); +} + +CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc) + : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN, 0) {} + +CPDF_DeviceNCS::~CPDF_DeviceNCS() {} + +void CPDF_DeviceNCS::GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const { + value = 1.0f; + min = 0; + max = 1.0f; +} + +FX_BOOL CPDF_DeviceNCS::v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) { + CPDF_Array* pObj = ToArray(pArray->GetDirectObjectAt(1)); + if (!pObj) + return FALSE; + + m_nComponents = pObj->GetCount(); + CPDF_Object* pAltCS = pArray->GetDirectObjectAt(2); + if (!pAltCS || pAltCS == m_pArray) + return FALSE; + + m_pAltCS = Load(pDoc, pAltCS); + m_pFunc = CPDF_Function::Load(pArray->GetDirectObjectAt(3)); + if (!m_pAltCS || !m_pFunc) + return FALSE; + + return m_pFunc->CountOutputs() >= m_pAltCS->CountComponents(); +} + +FX_BOOL CPDF_DeviceNCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + if (!m_pFunc) + return FALSE; + + CFX_FixedBufGrow results(m_pFunc->CountOutputs()); + int nresults = 0; + m_pFunc->Call(pBuf, m_nComponents, results, nresults); + if (nresults == 0) + return FALSE; + + return m_pAltCS->GetRGB(results, R, G, B); +} + +void CPDF_DeviceNCS::EnableStdConversion(FX_BOOL bEnabled) { + CPDF_ColorSpace::EnableStdConversion(bEnabled); + if (m_pAltCS) { + m_pAltCS->EnableStdConversion(bEnabled); + } +} diff --git a/core/fpdfapi/page/cpdf_colorspace.h b/core/fpdfapi/page/cpdf_colorspace.h new file mode 100644 index 0000000000..78311ce195 --- /dev/null +++ b/core/fpdfapi/page/cpdf_colorspace.h @@ -0,0 +1,121 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_COLORSPACE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_COLORSPACE_H_ + +#include + +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/fx_system.h" + +#define PDFCS_DEVICEGRAY 1 +#define PDFCS_DEVICERGB 2 +#define PDFCS_DEVICECMYK 3 +#define PDFCS_CALGRAY 4 +#define PDFCS_CALRGB 5 +#define PDFCS_LAB 6 +#define PDFCS_ICCBASED 7 +#define PDFCS_SEPARATION 8 +#define PDFCS_DEVICEN 9 +#define PDFCS_INDEXED 10 +#define PDFCS_PATTERN 11 + +class CPDF_Array; +class CPDF_Document; +class CPDF_Object; + +class CPDF_ColorSpace { + public: + static CPDF_ColorSpace* GetStockCS(int Family); + static CPDF_ColorSpace* ColorspaceFromName(const CFX_ByteString& name); + static std::unique_ptr Load(CPDF_Document* pDoc, + CPDF_Object* pCSObj); + + void Release(); + + int GetBufSize() const; + FX_FLOAT* CreateBuf(); + void GetDefaultColor(FX_FLOAT* buf) const; + uint32_t CountComponents() const; + int GetFamily() const { return m_Family; } + virtual void GetDefaultValue(int iComponent, + FX_FLOAT& value, + FX_FLOAT& min, + FX_FLOAT& max) const; + + FX_BOOL sRGB() const; + virtual FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const = 0; + virtual FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const; + + FX_BOOL GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const; + FX_BOOL SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const; + + virtual void TranslateImageLine(uint8_t* dest_buf, + const uint8_t* src_buf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const; + + CPDF_Array*& GetArray() { return m_pArray; } + virtual CPDF_ColorSpace* GetBaseCS() const; + + virtual void EnableStdConversion(FX_BOOL bEnabled); + + CPDF_Document* const m_pDocument; + + protected: + CPDF_ColorSpace(CPDF_Document* pDoc, int family, uint32_t nComponents); + virtual ~CPDF_ColorSpace(); + + virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray); + virtual FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const; + virtual FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const; + + int m_Family; + uint32_t m_nComponents; + CPDF_Array* m_pArray; + uint32_t m_dwStdConversion; +}; + +namespace std { + +// Make std::unique_ptr call Release() rather than +// simply deleting the object. +template <> +struct default_delete { + void operator()(CPDF_ColorSpace* pColorSpace) const { + if (pColorSpace) + pColorSpace->Release(); + } +}; + +} // namespace std + +#endif // CORE_FPDFAPI_PAGE_CPDF_COLORSPACE_H_ diff --git a/core/fpdfapi/page/cpdf_colorstate.cpp b/core/fpdfapi/page/cpdf_colorstate.cpp new file mode 100644 index 0000000000..da583122af --- /dev/null +++ b/core/fpdfapi/page/cpdf_colorstate.cpp @@ -0,0 +1,154 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_colorstate.h" + +#include "core/fpdfapi/page/cpdf_pattern.h" +#include "core/fpdfapi/page/cpdf_tilingpattern.h" +#include "core/fxge/fx_dib.h" + +CPDF_ColorState::CPDF_ColorState() {} + +CPDF_ColorState::CPDF_ColorState(const CPDF_ColorState& that) + : m_Ref(that.m_Ref) {} + +CPDF_ColorState::~CPDF_ColorState() {} + +void CPDF_ColorState::Emplace() { + m_Ref.Emplace(); +} + +void CPDF_ColorState::SetDefault() { + m_Ref.GetPrivateCopy()->SetDefault(); +} + +uint32_t CPDF_ColorState::GetFillRGB() const { + return m_Ref.GetObject()->m_FillRGB; +} + +void CPDF_ColorState::SetFillRGB(uint32_t rgb) { + m_Ref.GetPrivateCopy()->m_FillRGB = rgb; +} + +uint32_t CPDF_ColorState::GetStrokeRGB() const { + return m_Ref.GetObject()->m_StrokeRGB; +} + +void CPDF_ColorState::SetStrokeRGB(uint32_t rgb) { + m_Ref.GetPrivateCopy()->m_StrokeRGB = rgb; +} + +const CPDF_Color* CPDF_ColorState::GetFillColor() const { + const ColorData* pData = m_Ref.GetObject(); + return pData ? &pData->m_FillColor : nullptr; +} + +CPDF_Color* CPDF_ColorState::GetMutableFillColor() { + return &m_Ref.GetPrivateCopy()->m_FillColor; +} + +bool CPDF_ColorState::HasFillColor() const { + const CPDF_Color* pColor = GetFillColor(); + return pColor && !pColor->IsNull(); +} + +const CPDF_Color* CPDF_ColorState::GetStrokeColor() const { + const ColorData* pData = m_Ref.GetObject(); + return pData ? &pData->m_StrokeColor : nullptr; +} + +CPDF_Color* CPDF_ColorState::GetMutableStrokeColor() { + return &m_Ref.GetPrivateCopy()->m_StrokeColor; +} + +bool CPDF_ColorState::HasStrokeColor() const { + const CPDF_Color* pColor = GetStrokeColor(); + return pColor && !pColor->IsNull(); +} + +void CPDF_ColorState::SetFillColor(CPDF_ColorSpace* pCS, + FX_FLOAT* pValue, + uint32_t nValues) { + ColorData* pData = m_Ref.GetPrivateCopy(); + SetColor(pData->m_FillColor, pData->m_FillRGB, pCS, pValue, nValues); +} + +void CPDF_ColorState::SetStrokeColor(CPDF_ColorSpace* pCS, + FX_FLOAT* pValue, + uint32_t nValues) { + ColorData* pData = m_Ref.GetPrivateCopy(); + SetColor(pData->m_StrokeColor, pData->m_StrokeRGB, pCS, pValue, nValues); +} + +void CPDF_ColorState::SetFillPattern(CPDF_Pattern* pPattern, + FX_FLOAT* pValue, + uint32_t nValues) { + ColorData* pData = m_Ref.GetPrivateCopy(); + pData->m_FillColor.SetValue(pPattern, pValue, nValues); + int R, G, B; + FX_BOOL ret = pData->m_FillColor.GetRGB(R, G, B); + if (CPDF_TilingPattern* pTilingPattern = pPattern->AsTilingPattern()) { + if (!ret && pTilingPattern->colored()) { + pData->m_FillRGB = 0x00BFBFBF; + return; + } + } + pData->m_FillRGB = ret ? FXSYS_RGB(R, G, B) : (uint32_t)-1; +} + +void CPDF_ColorState::SetStrokePattern(CPDF_Pattern* pPattern, + FX_FLOAT* pValue, + uint32_t nValues) { + ColorData* pData = m_Ref.GetPrivateCopy(); + pData->m_StrokeColor.SetValue(pPattern, pValue, nValues); + int R, G, B; + FX_BOOL ret = pData->m_StrokeColor.GetRGB(R, G, B); + if (CPDF_TilingPattern* pTilingPattern = pPattern->AsTilingPattern()) { + if (!ret && pTilingPattern->colored()) { + pData->m_StrokeRGB = 0x00BFBFBF; + return; + } + } + pData->m_StrokeRGB = + pData->m_StrokeColor.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (uint32_t)-1; +} + +void CPDF_ColorState::SetColor(CPDF_Color& color, + uint32_t& rgb, + CPDF_ColorSpace* pCS, + FX_FLOAT* pValue, + uint32_t nValues) { + if (pCS) + color.SetColorSpace(pCS); + else if (color.IsNull()) + color.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); + + if (color.GetColorSpace()->CountComponents() > nValues) + return; + + color.SetValue(pValue); + int R; + int G; + int B; + rgb = color.GetRGB(R, G, B) ? FXSYS_RGB(R, G, B) : (uint32_t)-1; +} + +CPDF_ColorState::ColorData::ColorData() : m_FillRGB(0), m_StrokeRGB(0) {} + +CPDF_ColorState::ColorData::ColorData(const ColorData& src) + : m_FillRGB(src.m_FillRGB), m_StrokeRGB(src.m_StrokeRGB) { + m_FillColor.Copy(&src.m_FillColor); + m_StrokeColor.Copy(&src.m_StrokeColor); +} + +CPDF_ColorState::ColorData::~ColorData() {} + +void CPDF_ColorState::ColorData::SetDefault() { + m_FillRGB = 0; + m_StrokeRGB = 0; + m_FillColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); + m_StrokeColor.SetColorSpace(CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY)); +} diff --git a/core/fpdfapi/page/cpdf_colorstate.h b/core/fpdfapi/page/cpdf_colorstate.h new file mode 100644 index 0000000000..916abed7ee --- /dev/null +++ b/core/fpdfapi/page/cpdf_colorstate.h @@ -0,0 +1,77 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_COLORSTATE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_COLORSTATE_H_ + +#include "core/fpdfapi/page/cpdf_color.h" +#include "core/fxcrt/cfx_count_ref.h" +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Color; +class CPDF_ColorSpace; +class CPDF_Pattern; + +class CPDF_ColorState { + public: + CPDF_ColorState(); + CPDF_ColorState(const CPDF_ColorState& that); + ~CPDF_ColorState(); + + void Emplace(); + void SetDefault(); + + uint32_t GetFillRGB() const; + void SetFillRGB(uint32_t rgb); + + uint32_t GetStrokeRGB() const; + void SetStrokeRGB(uint32_t rgb); + + const CPDF_Color* GetFillColor() const; + CPDF_Color* GetMutableFillColor(); + bool HasFillColor() const; + + const CPDF_Color* GetStrokeColor() const; + CPDF_Color* GetMutableStrokeColor(); + bool HasStrokeColor() const; + + void SetFillColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, uint32_t nValues); + void SetStrokeColor(CPDF_ColorSpace* pCS, FX_FLOAT* pValue, uint32_t nValues); + void SetFillPattern(CPDF_Pattern* pattern, + FX_FLOAT* pValue, + uint32_t nValues); + void SetStrokePattern(CPDF_Pattern* pattern, + FX_FLOAT* pValue, + uint32_t nValues); + + explicit operator bool() const { return !!m_Ref; } + + private: + class ColorData { + public: + ColorData(); + ColorData(const ColorData& src); + ~ColorData(); + + void SetDefault(); + + uint32_t m_FillRGB; + uint32_t m_StrokeRGB; + CPDF_Color m_FillColor; + CPDF_Color m_StrokeColor; + }; + + void SetColor(CPDF_Color& color, + uint32_t& rgb, + CPDF_ColorSpace* pCS, + FX_FLOAT* pValue, + uint32_t nValues); + + CFX_CountRef m_Ref; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_COLORSTATE_H_ diff --git a/core/fpdfapi/page/cpdf_contentmark.cpp b/core/fpdfapi/page/cpdf_contentmark.cpp new file mode 100644 index 0000000000..b455b4f28a --- /dev/null +++ b/core/fpdfapi/page/cpdf_contentmark.cpp @@ -0,0 +1,125 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_contentmark.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "third_party/base/stl_util.h" + +CPDF_ContentMark::CPDF_ContentMark() {} + +CPDF_ContentMark::CPDF_ContentMark(const CPDF_ContentMark& that) + : m_Ref(that.m_Ref) {} + +CPDF_ContentMark::~CPDF_ContentMark() {} + +void CPDF_ContentMark::SetNull() { + m_Ref.SetNull(); +} + +int CPDF_ContentMark::CountItems() const { + return m_Ref.GetObject()->CountItems(); +} + +const CPDF_ContentMarkItem& CPDF_ContentMark::GetItem(int i) const { + return m_Ref.GetObject()->GetItem(i); +} + +int CPDF_ContentMark::GetMCID() const { + const MarkData* pData = m_Ref.GetObject(); + return pData ? pData->GetMCID() : -1; +} + +void CPDF_ContentMark::AddMark(const CFX_ByteString& name, + CPDF_Dictionary* pDict, + FX_BOOL bDirect) { + m_Ref.GetPrivateCopy()->AddMark(name, pDict, bDirect); +} + +void CPDF_ContentMark::DeleteLastMark() { + m_Ref.GetPrivateCopy()->DeleteLastMark(); + if (CountItems() == 0) + m_Ref.SetNull(); +} + +bool CPDF_ContentMark::HasMark(const CFX_ByteStringC& mark) const { + const MarkData* pData = m_Ref.GetObject(); + if (!pData) + return false; + + for (int i = 0; i < pData->CountItems(); i++) { + if (pData->GetItem(i).GetName() == mark) + return true; + } + return false; +} + +bool CPDF_ContentMark::LookupMark(const CFX_ByteStringC& mark, + CPDF_Dictionary*& pDict) const { + const MarkData* pData = m_Ref.GetObject(); + if (!pData) + return false; + + for (int i = 0; i < pData->CountItems(); i++) { + const CPDF_ContentMarkItem& item = pData->GetItem(i); + if (item.GetName() == mark) { + pDict = item.GetParam(); + return true; + } + } + return false; +} + +CPDF_ContentMark::MarkData::MarkData() {} + +CPDF_ContentMark::MarkData::MarkData(const MarkData& src) + : m_Marks(src.m_Marks) {} + +CPDF_ContentMark::MarkData::~MarkData() {} + +int CPDF_ContentMark::MarkData::CountItems() const { + return pdfium::CollectionSize(m_Marks); +} + +CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem(int index) { + return m_Marks[index]; +} + +const CPDF_ContentMarkItem& CPDF_ContentMark::MarkData::GetItem( + int index) const { + return m_Marks[index]; +} + +int CPDF_ContentMark::MarkData::GetMCID() const { + for (const auto& mark : m_Marks) { + CPDF_Dictionary* pDict = mark.GetParam(); + if (pDict && pDict->KeyExist("MCID")) + return pDict->GetIntegerFor("MCID"); + } + return -1; +} + +void CPDF_ContentMark::MarkData::AddMark(const CFX_ByteString& name, + CPDF_Dictionary* pDict, + FX_BOOL bDirect) { + CPDF_ContentMarkItem item; + item.SetName(name); + if (pDict) { + if (bDirect) { + item.SetDirectDict( + std::unique_ptr>( + ToDictionary(pDict->Clone()))); + } else { + item.SetPropertiesDict(pDict); + } + } + m_Marks.push_back(std::move(item)); +} + +void CPDF_ContentMark::MarkData::DeleteLastMark() { + if (!m_Marks.empty()) + m_Marks.pop_back(); +} diff --git a/core/fpdfapi/page/cpdf_contentmark.h b/core/fpdfapi/page/cpdf_contentmark.h new file mode 100644 index 0000000000..9d137faa35 --- /dev/null +++ b/core/fpdfapi/page/cpdf_contentmark.h @@ -0,0 +1,64 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_CONTENTMARK_H_ +#define CORE_FPDFAPI_PAGE_CPDF_CONTENTMARK_H_ + +#include + +#include "core/fpdfapi/page/cpdf_contentmarkitem.h" +#include "core/fxcrt/cfx_count_ref.h" +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Dictionary; + +class CPDF_ContentMark { + public: + CPDF_ContentMark(); + CPDF_ContentMark(const CPDF_ContentMark& that); + ~CPDF_ContentMark(); + + void SetNull(); + + int GetMCID() const; + int CountItems() const; + const CPDF_ContentMarkItem& GetItem(int i) const; + + bool HasMark(const CFX_ByteStringC& mark) const; + bool LookupMark(const CFX_ByteStringC& mark, CPDF_Dictionary*& pDict) const; + void AddMark(const CFX_ByteString& name, + CPDF_Dictionary* pDict, + FX_BOOL bDirect); + void DeleteLastMark(); + + explicit operator bool() const { return !!m_Ref; } + + private: + class MarkData { + public: + MarkData(); + MarkData(const MarkData& src); + ~MarkData(); + + int CountItems() const; + CPDF_ContentMarkItem& GetItem(int index); + const CPDF_ContentMarkItem& GetItem(int index) const; + + int GetMCID() const; + void AddMark(const CFX_ByteString& name, + CPDF_Dictionary* pDict, + FX_BOOL bDictNeedClone); + void DeleteLastMark(); + + private: + std::vector m_Marks; + }; + + CFX_CountRef m_Ref; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_CONTENTMARK_H_ diff --git a/core/fpdfapi/page/cpdf_contentmarkitem.cpp b/core/fpdfapi/page/cpdf_contentmarkitem.cpp new file mode 100644 index 0000000000..90e36d1215 --- /dev/null +++ b/core/fpdfapi/page/cpdf_contentmarkitem.cpp @@ -0,0 +1,50 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_contentmarkitem.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" + +CPDF_ContentMarkItem::CPDF_ContentMarkItem() + : m_ParamType(None), m_pPropertiesDict(nullptr) {} + +CPDF_ContentMarkItem::CPDF_ContentMarkItem(const CPDF_ContentMarkItem& that) + : m_MarkName(that.m_MarkName), + m_ParamType(that.m_ParamType), + m_pPropertiesDict(that.m_pPropertiesDict) { + if (that.m_pDirectDict) + m_pDirectDict.reset(that.m_pDirectDict->Clone()->AsDictionary()); +} + +CPDF_ContentMarkItem::~CPDF_ContentMarkItem() {} + +CPDF_Dictionary* CPDF_ContentMarkItem::GetParam() const { + switch (m_ParamType) { + case PropertiesDict: + return m_pPropertiesDict; + case DirectDict: + return m_pDirectDict.get(); + case None: + default: + return nullptr; + } +} + +FX_BOOL CPDF_ContentMarkItem::HasMCID() const { + CPDF_Dictionary* pDict = GetParam(); + return pDict && pDict->KeyExist("MCID"); +} + +void CPDF_ContentMarkItem::SetDirectDict( + std::unique_ptr> pDict) { + m_ParamType = DirectDict; + m_pDirectDict = std::move(pDict); +} + +void CPDF_ContentMarkItem::SetPropertiesDict(CPDF_Dictionary* pDict) { + m_ParamType = PropertiesDict; + m_pPropertiesDict = pDict; +} diff --git a/core/fpdfapi/page/cpdf_contentmarkitem.h b/core/fpdfapi/page/cpdf_contentmarkitem.h new file mode 100644 index 0000000000..ef691e252c --- /dev/null +++ b/core/fpdfapi/page/cpdf_contentmarkitem.h @@ -0,0 +1,46 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_CONTENTMARKITEM_H_ +#define CORE_FPDFAPI_PAGE_CPDF_CONTENTMARKITEM_H_ + +#include + +#include "core/fxcrt/fx_memory.h" +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Dictionary; + +class CPDF_ContentMarkItem { + public: + enum ParamType { None, PropertiesDict, DirectDict }; + + CPDF_ContentMarkItem(); + CPDF_ContentMarkItem(const CPDF_ContentMarkItem& that); + ~CPDF_ContentMarkItem(); + + CPDF_ContentMarkItem& operator=(CPDF_ContentMarkItem&& other) = default; + + CFX_ByteString GetName() const { return m_MarkName; } + ParamType GetParamType() const { return m_ParamType; } + CPDF_Dictionary* GetParam() const; + FX_BOOL HasMCID() const; + + void SetName(const CFX_ByteString& name) { m_MarkName = name; } + void SetDirectDict( + std::unique_ptr> pDict); + void SetPropertiesDict(CPDF_Dictionary* pDict); + + private: + CFX_ByteString m_MarkName; + ParamType m_ParamType; + CPDF_Dictionary* m_pPropertiesDict; // not owned. + std::unique_ptr> + m_pDirectDict; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_CONTENTMARKITEM_H_ diff --git a/core/fpdfapi/page/cpdf_countedobject.h b/core/fpdfapi/page/cpdf_countedobject.h new file mode 100644 index 0000000000..97d710cf76 --- /dev/null +++ b/core/fpdfapi/page/cpdf_countedobject.h @@ -0,0 +1,47 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_COUNTEDOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_COUNTEDOBJECT_H_ + +#include "core/fpdfapi/page/cpdf_colorspace.h" +#include "core/fpdfapi/page/cpdf_pattern.h" +#include "core/fxcrt/fx_system.h" + +template +class CPDF_CountedObject { + public: + explicit CPDF_CountedObject(T* ptr) : m_nCount(1), m_pObj(ptr) {} + void reset(T* ptr) { // CAUTION: tosses prior ref counts. + m_nCount = 1; + m_pObj = ptr; + } + void clear() { // Now you're all weak ptrs ... + // Guard against accidental re-entry. + T* pObj = m_pObj; + m_pObj = nullptr; + delete pObj; + } + T* get() const { return m_pObj; } + T* AddRef() { + ASSERT(m_pObj); + ++m_nCount; + return m_pObj; + } + void RemoveRef() { + if (m_nCount) + --m_nCount; + } + size_t use_count() const { return m_nCount; } + + protected: + size_t m_nCount; + T* m_pObj; +}; +using CPDF_CountedColorSpace = CPDF_CountedObject; +using CPDF_CountedPattern = CPDF_CountedObject; + +#endif // CORE_FPDFAPI_PAGE_CPDF_COUNTEDOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_form.cpp b/core/fpdfapi/page/cpdf_form.cpp new file mode 100644 index 0000000000..73e8139369 --- /dev/null +++ b/core/fpdfapi/page/cpdf_form.cpp @@ -0,0 +1,61 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_form.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" +#include "core/fpdfapi/page/pageint.h" + +CPDF_Form::CPDF_Form(CPDF_Document* pDoc, + CPDF_Dictionary* pPageResources, + CPDF_Stream* pFormStream, + CPDF_Dictionary* pParentResources) { + m_pDocument = pDoc; + m_pFormStream = pFormStream; + m_pFormDict = pFormStream ? pFormStream->GetDict() : nullptr; + m_pResources = m_pFormDict->GetDictFor("Resources"); + m_pPageResources = pPageResources; + if (!m_pResources) + m_pResources = pParentResources; + if (!m_pResources) + m_pResources = pPageResources; + m_Transparency = 0; + LoadTransInfo(); +} + +CPDF_Form::~CPDF_Form() {} + +void CPDF_Form::StartParse(CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level) { + if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) + return; + + m_pParser.reset(new CPDF_ContentParser); + m_pParser->Start(this, pGraphicStates, pParentMatrix, pType3Char, level); + m_ParseState = CONTENT_PARSING; +} + +void CPDF_Form::ParseContent(CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level) { + StartParse(pGraphicStates, pParentMatrix, pType3Char, level); + ContinueParse(nullptr); +} + +CPDF_Form* CPDF_Form::Clone() const { + CPDF_Form* pCloneForm = + new CPDF_Form(m_pDocument, m_pPageResources, m_pFormStream, m_pResources); + for (const auto& pObj : m_PageObjectList) + pCloneForm->m_PageObjectList.emplace_back(pObj->Clone()); + + return pCloneForm; +} diff --git a/core/fpdfapi/page/cpdf_form.h b/core/fpdfapi/page/cpdf_form.h new file mode 100644 index 0000000000..1208e327bd --- /dev/null +++ b/core/fpdfapi/page/cpdf_form.h @@ -0,0 +1,41 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_FORM_H_ +#define CORE_FPDFAPI_PAGE_CPDF_FORM_H_ + +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" + +class CPDF_Document; +class CPDF_Dictionary; +class CPDF_Stream; +class CPDF_AllStates; +class CFX_Matrix; +class CPDF_Type3Char; + +class CPDF_Form : public CPDF_PageObjectHolder { + public: + CPDF_Form(CPDF_Document* pDocument, + CPDF_Dictionary* pPageResources, + CPDF_Stream* pFormStream, + CPDF_Dictionary* pParentResources = nullptr); + ~CPDF_Form() override; + + void ParseContent(CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level = 0); + + CPDF_Form* Clone() const; + + private: + void StartParse(CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level = 0); +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_FORM_H_ diff --git a/core/fpdfapi/page/cpdf_formobject.cpp b/core/fpdfapi/page/cpdf_formobject.cpp new file mode 100644 index 0000000000..dd3c2c2036 --- /dev/null +++ b/core/fpdfapi/page/cpdf_formobject.cpp @@ -0,0 +1,52 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_formobject.h" + +#include "core/fpdfapi/page/cpdf_form.h" + +CPDF_FormObject::CPDF_FormObject() {} + +CPDF_FormObject::~CPDF_FormObject() {} + +void CPDF_FormObject::Transform(const CFX_Matrix& matrix) { + m_FormMatrix.Concat(matrix); + CalcBoundingBox(); +} + +bool CPDF_FormObject::IsForm() const { + return true; +} + +CPDF_FormObject* CPDF_FormObject::AsForm() { + return this; +} + +const CPDF_FormObject* CPDF_FormObject::AsForm() const { + return this; +} + +CPDF_FormObject* CPDF_FormObject::Clone() const { + CPDF_FormObject* obj = new CPDF_FormObject; + obj->CopyData(this); + + obj->m_pForm.reset(m_pForm->Clone()); + obj->m_FormMatrix = m_FormMatrix; + return obj; +} + +CPDF_PageObject::Type CPDF_FormObject::GetType() const { + return FORM; +} + +void CPDF_FormObject::CalcBoundingBox() { + CFX_FloatRect form_rect = m_pForm->CalcBoundingBox(); + form_rect.Transform(&m_FormMatrix); + m_Left = form_rect.left; + m_Bottom = form_rect.bottom; + m_Right = form_rect.right; + m_Top = form_rect.top; +} diff --git a/core/fpdfapi/page/cpdf_formobject.h b/core/fpdfapi/page/cpdf_formobject.h new file mode 100644 index 0000000000..0fdc692019 --- /dev/null +++ b/core/fpdfapi/page/cpdf_formobject.h @@ -0,0 +1,37 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_FORMOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_FORMOBJECT_H_ + +#include + +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fxcrt/fx_coordinates.h" + +class CPDF_Form; + +class CPDF_FormObject : public CPDF_PageObject { + public: + CPDF_FormObject(); + ~CPDF_FormObject() override; + + // CPDF_PageObject: + CPDF_FormObject* Clone() const override; + Type GetType() const override; + void Transform(const CFX_Matrix& matrix) override; + bool IsForm() const override; + CPDF_FormObject* AsForm() override; + const CPDF_FormObject* AsForm() const override; + + void CalcBoundingBox(); + const CPDF_Form* form() const { return m_pForm.get(); } + + std::unique_ptr m_pForm; + CFX_Matrix m_FormMatrix; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_FORMOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_generalstate.cpp b/core/fpdfapi/page/cpdf_generalstate.cpp new file mode 100644 index 0000000000..4b082c0946 --- /dev/null +++ b/core/fpdfapi/page/cpdf_generalstate.cpp @@ -0,0 +1,281 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_generalstate.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_render/render_int.h" + +namespace { + +int RI_StringToId(const CFX_ByteString& ri) { + uint32_t id = ri.GetID(); + if (id == FXBSTR_ID('A', 'b', 's', 'o')) + return 1; + + if (id == FXBSTR_ID('S', 'a', 't', 'u')) + return 2; + + if (id == FXBSTR_ID('P', 'e', 'r', 'c')) + return 3; + + return 0; +} + +int GetBlendTypeInternal(const CFX_ByteString& mode) { + switch (mode.GetID()) { + case FXBSTR_ID('N', 'o', 'r', 'm'): + case FXBSTR_ID('C', 'o', 'm', 'p'): + return FXDIB_BLEND_NORMAL; + case FXBSTR_ID('M', 'u', 'l', 't'): + return FXDIB_BLEND_MULTIPLY; + case FXBSTR_ID('S', 'c', 'r', 'e'): + return FXDIB_BLEND_SCREEN; + case FXBSTR_ID('O', 'v', 'e', 'r'): + return FXDIB_BLEND_OVERLAY; + case FXBSTR_ID('D', 'a', 'r', 'k'): + return FXDIB_BLEND_DARKEN; + case FXBSTR_ID('L', 'i', 'g', 'h'): + return FXDIB_BLEND_LIGHTEN; + case FXBSTR_ID('C', 'o', 'l', 'o'): + if (mode.GetLength() == 10) + return FXDIB_BLEND_COLORDODGE; + if (mode.GetLength() == 9) + return FXDIB_BLEND_COLORBURN; + return FXDIB_BLEND_COLOR; + case FXBSTR_ID('H', 'a', 'r', 'd'): + return FXDIB_BLEND_HARDLIGHT; + case FXBSTR_ID('S', 'o', 'f', 't'): + return FXDIB_BLEND_SOFTLIGHT; + case FXBSTR_ID('D', 'i', 'f', 'f'): + return FXDIB_BLEND_DIFFERENCE; + case FXBSTR_ID('E', 'x', 'c', 'l'): + return FXDIB_BLEND_EXCLUSION; + case FXBSTR_ID('H', 'u', 'e', 0): + return FXDIB_BLEND_HUE; + case FXBSTR_ID('S', 'a', 't', 'u'): + return FXDIB_BLEND_SATURATION; + case FXBSTR_ID('L', 'u', 'm', 'i'): + return FXDIB_BLEND_LUMINOSITY; + } + return FXDIB_BLEND_NORMAL; +} + +} // namespace + +CPDF_GeneralState::CPDF_GeneralState() {} + +CPDF_GeneralState::CPDF_GeneralState(const CPDF_GeneralState& that) + : m_Ref(that.m_Ref) {} + +CPDF_GeneralState::~CPDF_GeneralState() {} + +void CPDF_GeneralState::SetRenderIntent(const CFX_ByteString& ri) { + m_Ref.GetPrivateCopy()->m_RenderIntent = RI_StringToId(ri); +} + +int CPDF_GeneralState::GetBlendType() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL; +} + +void CPDF_GeneralState::SetBlendType(int type) { + m_Ref.GetPrivateCopy()->m_BlendType = type; +} + +FX_FLOAT CPDF_GeneralState::GetFillAlpha() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? pData->m_FillAlpha : 1.0f; +} + +void CPDF_GeneralState::SetFillAlpha(FX_FLOAT alpha) { + m_Ref.GetPrivateCopy()->m_FillAlpha = alpha; +} + +FX_FLOAT CPDF_GeneralState::GetStrokeAlpha() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? pData->m_StrokeAlpha : 1.0f; +} + +void CPDF_GeneralState::SetStrokeAlpha(FX_FLOAT alpha) { + m_Ref.GetPrivateCopy()->m_StrokeAlpha = alpha; +} + +CPDF_Object* CPDF_GeneralState::GetSoftMask() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? pData->m_pSoftMask : nullptr; +} + +void CPDF_GeneralState::SetSoftMask(CPDF_Object* pObject) { + m_Ref.GetPrivateCopy()->m_pSoftMask = pObject; +} + +CPDF_Object* CPDF_GeneralState::GetTR() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? pData->m_pTR : nullptr; +} + +void CPDF_GeneralState::SetTR(CPDF_Object* pObject) { + m_Ref.GetPrivateCopy()->m_pTR = pObject; +} + +CPDF_TransferFunc* CPDF_GeneralState::GetTransferFunc() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? pData->m_pTransferFunc : nullptr; +} + +void CPDF_GeneralState::SetTransferFunc(CPDF_TransferFunc* pFunc) { + m_Ref.GetPrivateCopy()->m_pTransferFunc = pFunc; +} + +void CPDF_GeneralState::SetBlendMode(const CFX_ByteString& mode) { + StateData* pData = m_Ref.GetPrivateCopy(); + pData->m_BlendMode = mode; + pData->m_BlendType = GetBlendTypeInternal(mode); +} + +const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const { + const StateData* pData = m_Ref.GetObject(); + return pData ? &pData->m_SMaskMatrix : nullptr; +} + +void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) { + m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix; +} + +bool CPDF_GeneralState::GetFillOP() const { + const StateData* pData = m_Ref.GetObject(); + return pData && pData->m_FillOP; +} + +void CPDF_GeneralState::SetFillOP(bool op) { + m_Ref.GetPrivateCopy()->m_FillOP = op; +} + +void CPDF_GeneralState::SetStrokeOP(bool op) { + m_Ref.GetPrivateCopy()->m_StrokeOP = op; +} + +bool CPDF_GeneralState::GetStrokeOP() const { + const StateData* pData = m_Ref.GetObject(); + return pData && pData->m_StrokeOP; +} + +int CPDF_GeneralState::GetOPMode() const { + return m_Ref.GetObject()->m_OPMode; +} + +void CPDF_GeneralState::SetOPMode(int mode) { + m_Ref.GetPrivateCopy()->m_OPMode = mode; +} + +void CPDF_GeneralState::SetBG(CPDF_Object* pObject) { + m_Ref.GetPrivateCopy()->m_pBG = pObject; +} + +void CPDF_GeneralState::SetUCR(CPDF_Object* pObject) { + m_Ref.GetPrivateCopy()->m_pUCR = pObject; +} + +void CPDF_GeneralState::SetHT(CPDF_Object* pObject) { + m_Ref.GetPrivateCopy()->m_pHT = pObject; +} + +void CPDF_GeneralState::SetFlatness(FX_FLOAT flatness) { + m_Ref.GetPrivateCopy()->m_Flatness = flatness; +} + +void CPDF_GeneralState::SetSmoothness(FX_FLOAT smoothness) { + m_Ref.GetPrivateCopy()->m_Smoothness = smoothness; +} + +bool CPDF_GeneralState::GetStrokeAdjust() const { + const StateData* pData = m_Ref.GetObject(); + return pData && pData->m_StrokeAdjust; +} + +void CPDF_GeneralState::SetStrokeAdjust(bool adjust) { + m_Ref.GetPrivateCopy()->m_StrokeAdjust = adjust; +} + +void CPDF_GeneralState::SetAlphaSource(bool source) { + m_Ref.GetPrivateCopy()->m_AlphaSource = source; +} + +void CPDF_GeneralState::SetTextKnockout(bool knockout) { + m_Ref.GetPrivateCopy()->m_TextKnockout = knockout; +} + +void CPDF_GeneralState::SetMatrix(const CFX_Matrix& matrix) { + m_Ref.GetPrivateCopy()->m_Matrix = matrix; +} + +CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() { + return &m_Ref.GetPrivateCopy()->m_Matrix; +} + +CPDF_GeneralState::StateData::StateData() + : m_BlendMode("Normal"), + m_BlendType(0), + m_pSoftMask(nullptr), + m_StrokeAlpha(1.0), + m_FillAlpha(1.0f), + m_pTR(nullptr), + m_pTransferFunc(nullptr), + m_RenderIntent(0), + m_StrokeAdjust(false), + m_AlphaSource(false), + m_TextKnockout(false), + m_StrokeOP(false), + m_FillOP(false), + m_OPMode(0), + m_pBG(nullptr), + m_pUCR(nullptr), + m_pHT(nullptr), + m_Flatness(1.0f), + m_Smoothness(0.0f) { + m_SMaskMatrix.SetIdentity(); + m_Matrix.SetIdentity(); +} + +CPDF_GeneralState::StateData::StateData(const StateData& that) + : m_BlendMode(that.m_BlendMode), + m_BlendType(that.m_BlendType), + m_pSoftMask(that.m_pSoftMask), + m_StrokeAlpha(that.m_StrokeAlpha), + m_FillAlpha(that.m_FillAlpha), + m_pTR(that.m_pTR), + m_pTransferFunc(that.m_pTransferFunc), + m_RenderIntent(that.m_RenderIntent), + m_StrokeAdjust(that.m_StrokeAdjust), + m_AlphaSource(that.m_AlphaSource), + m_TextKnockout(that.m_TextKnockout), + m_StrokeOP(that.m_StrokeOP), + m_FillOP(that.m_FillOP), + m_OPMode(that.m_OPMode), + m_pBG(that.m_pBG), + m_pUCR(that.m_pUCR), + m_pHT(that.m_pHT), + m_Flatness(that.m_Flatness), + m_Smoothness(that.m_Smoothness) { + m_Matrix = that.m_Matrix; + m_SMaskMatrix = that.m_SMaskMatrix; + + if (that.m_pTransferFunc && that.m_pTransferFunc->m_pPDFDoc) { + CPDF_DocRenderData* pDocCache = + that.m_pTransferFunc->m_pPDFDoc->GetRenderData(); + if (pDocCache) + m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR); + } +} + +CPDF_GeneralState::StateData::~StateData() { + if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) { + CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData(); + if (pDocCache) + pDocCache->ReleaseTransferFunc(m_pTR); + } +} diff --git a/core/fpdfapi/page/cpdf_generalstate.h b/core/fpdfapi/page/cpdf_generalstate.h new file mode 100644 index 0000000000..8c6b0622f4 --- /dev/null +++ b/core/fpdfapi/page/cpdf_generalstate.h @@ -0,0 +1,109 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_GENERALSTATE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_GENERALSTATE_H_ + +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxge/fx_dib.h" + +class CPDF_Object; +class CPDF_TransferFunc; + +class CPDF_GeneralState { + public: + CPDF_GeneralState(); + CPDF_GeneralState(const CPDF_GeneralState& that); + ~CPDF_GeneralState(); + + void Emplace() { m_Ref.Emplace(); } + explicit operator bool() const { return !!m_Ref; } + + void SetRenderIntent(const CFX_ByteString& ri); + + int GetBlendType() const; + void SetBlendType(int type); + + FX_FLOAT GetFillAlpha() const; + void SetFillAlpha(FX_FLOAT alpha); + + FX_FLOAT GetStrokeAlpha() const; + void SetStrokeAlpha(FX_FLOAT alpha); + + CPDF_Object* GetSoftMask() const; + void SetSoftMask(CPDF_Object* pObject); + + CPDF_Object* GetTR() const; + void SetTR(CPDF_Object* pObject); + + CPDF_TransferFunc* GetTransferFunc() const; + void SetTransferFunc(CPDF_TransferFunc* pFunc); + + void SetBlendMode(const CFX_ByteString& mode); + + const CFX_Matrix* GetSMaskMatrix() const; + void SetSMaskMatrix(const CFX_Matrix& matrix); + + bool GetFillOP() const; + void SetFillOP(bool op); + + bool GetStrokeOP() const; + void SetStrokeOP(bool op); + + int GetOPMode() const; + void SetOPMode(int mode); + + void SetBG(CPDF_Object* pObject); + void SetUCR(CPDF_Object* pObject); + void SetHT(CPDF_Object* pObject); + + void SetFlatness(FX_FLOAT flatness); + void SetSmoothness(FX_FLOAT smoothness); + + bool GetStrokeAdjust() const; + void SetStrokeAdjust(bool adjust); + + void SetAlphaSource(bool source); + void SetTextKnockout(bool knockout); + + void SetMatrix(const CFX_Matrix& matrix); + CFX_Matrix* GetMutableMatrix(); + + private: + class StateData { + public: + StateData(); + StateData(const StateData& that); + ~StateData(); + + CFX_ByteString m_BlendMode; + int m_BlendType; + CPDF_Object* m_pSoftMask; + CFX_Matrix m_SMaskMatrix; + FX_FLOAT m_StrokeAlpha; + FX_FLOAT m_FillAlpha; + CPDF_Object* m_pTR; + CPDF_TransferFunc* m_pTransferFunc; + CFX_Matrix m_Matrix; + int m_RenderIntent; + bool m_StrokeAdjust; + bool m_AlphaSource; + bool m_TextKnockout; + bool m_StrokeOP; + bool m_FillOP; + int m_OPMode; + CPDF_Object* m_pBG; + CPDF_Object* m_pUCR; + CPDF_Object* m_pHT; + FX_FLOAT m_Flatness; + FX_FLOAT m_Smoothness; + }; + + CFX_CountRef m_Ref; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_GENERALSTATE_H_ diff --git a/core/fpdfapi/page/cpdf_graphicstates.cpp b/core/fpdfapi/page/cpdf_graphicstates.cpp new file mode 100644 index 0000000000..962bc0a89e --- /dev/null +++ b/core/fpdfapi/page/cpdf_graphicstates.cpp @@ -0,0 +1,24 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_graphicstates.h" + +CPDF_GraphicStates::CPDF_GraphicStates() {} + +CPDF_GraphicStates::~CPDF_GraphicStates() {} + +void CPDF_GraphicStates::DefaultStates() { + m_ColorState.Emplace(); + m_ColorState.SetDefault(); +} + +void CPDF_GraphicStates::CopyStates(const CPDF_GraphicStates& src) { + m_ClipPath = src.m_ClipPath; + m_GraphState = src.m_GraphState; + m_ColorState = src.m_ColorState; + m_TextState = src.m_TextState; + m_GeneralState = src.m_GeneralState; +} diff --git a/core/fpdfapi/page/cpdf_graphicstates.h b/core/fpdfapi/page/cpdf_graphicstates.h new file mode 100644 index 0000000000..b7e7fa2056 --- /dev/null +++ b/core/fpdfapi/page/cpdf_graphicstates.h @@ -0,0 +1,31 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_GRAPHICSTATES_H_ +#define CORE_FPDFAPI_PAGE_CPDF_GRAPHICSTATES_H_ + +#include "core/fpdfapi/page/cpdf_clippath.h" +#include "core/fpdfapi/page/cpdf_colorstate.h" +#include "core/fpdfapi/page/cpdf_generalstate.h" +#include "core/fpdfapi/page/cpdf_textstate.h" +#include "core/fxge/cfx_graphstate.h" + +class CPDF_GraphicStates { + public: + CPDF_GraphicStates(); + virtual ~CPDF_GraphicStates(); + + void CopyStates(const CPDF_GraphicStates& src); + void DefaultStates(); + + CPDF_ClipPath m_ClipPath; + CFX_GraphState m_GraphState; + CPDF_ColorState m_ColorState; + CPDF_TextState m_TextState; + CPDF_GeneralState m_GeneralState; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_GRAPHICSTATES_H_ diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp new file mode 100644 index 0000000000..eb59dc750e --- /dev/null +++ b/core/fpdfapi/page/cpdf_image.cpp @@ -0,0 +1,411 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_image.h" + +#include +#include +#include + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_string.h" +#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" +#include "core/fpdfapi/fpdf_render/render_int.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/pageint.h" +#include "core/fxcodec/fx_codec.h" +#include "core/fxge/fx_dib.h" + +CPDF_Image::CPDF_Image(CPDF_Document* pDoc) + : CPDF_Image(pDoc, nullptr, false) {} + +CPDF_Image::CPDF_Image(CPDF_Document* pDoc, CPDF_Stream* pStream, bool bInline) + : m_pDIBSource(nullptr), + m_pMask(nullptr), + m_MatteColor(0), + m_pStream(pStream), + m_bInline(bInline), + m_pInlineDict(nullptr), + m_Height(0), + m_Width(0), + m_bIsMask(false), + m_bInterpolate(false), + m_pDocument(pDoc), + m_pOC(nullptr) { + if (!pStream) + return; + + CPDF_Dictionary* pDict = pStream->GetDict(); + if (m_bInline) + m_pInlineDict = ToDictionary(pDict->Clone()); + + m_pOC = pDict->GetDictFor("OC"); + m_bIsMask = + !pDict->KeyExist("ColorSpace") || pDict->GetIntegerFor("ImageMask"); + m_bInterpolate = !!pDict->GetIntegerFor("Interpolate"); + m_Height = pDict->GetIntegerFor("Height"); + m_Width = pDict->GetIntegerFor("Width"); +} + +CPDF_Image::~CPDF_Image() { + if (m_bInline) { + if (m_pStream) + m_pStream->Release(); + if (m_pInlineDict) + m_pInlineDict->Release(); + } +} + +CPDF_Image* CPDF_Image::Clone() { + if (m_pStream->GetObjNum()) + return m_pDocument->GetPageData()->GetImage(m_pStream); + + CPDF_Image* pImage = + new CPDF_Image(m_pDocument, ToStream(m_pStream->Clone()), m_bInline); + if (m_bInline) + pImage->SetInlineDict(ToDictionary(m_pInlineDict->CloneDirectObject())); + + return pImage; +} + +CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { + int32_t width; + int32_t height; + int32_t num_comps; + int32_t bits; + bool color_trans; + if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo( + pData, size, &width, &height, &num_comps, &bits, &color_trans)) { + return nullptr; + } + + CPDF_Dictionary* pDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); + pDict->SetNameFor("Type", "XObject"); + pDict->SetNameFor("Subtype", "Image"); + pDict->SetIntegerFor("Width", width); + pDict->SetIntegerFor("Height", height); + const FX_CHAR* csname = nullptr; + if (num_comps == 1) { + csname = "DeviceGray"; + } else if (num_comps == 3) { + csname = "DeviceRGB"; + } else if (num_comps == 4) { + csname = "DeviceCMYK"; + CPDF_Array* pDecode = new CPDF_Array; + for (int n = 0; n < 4; n++) { + pDecode->AddInteger(1); + pDecode->AddInteger(0); + } + pDict->SetFor("Decode", pDecode); + } + pDict->SetNameFor("ColorSpace", csname); + pDict->SetIntegerFor("BitsPerComponent", bits); + pDict->SetNameFor("Filter", "DCTDecode"); + if (!color_trans) { + CPDF_Dictionary* pParms = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); + pDict->SetFor("DecodeParms", pParms); + pParms->SetIntegerFor("ColorTransform", 0); + } + m_bIsMask = FALSE; + m_Width = width; + m_Height = height; + if (!m_pStream) + m_pStream = new CPDF_Stream; + return pDict; +} + +void CPDF_Image::SetJpegImage(IFX_FileRead* pFile) { + uint32_t size = (uint32_t)pFile->GetSize(); + if (!size) + return; + + uint32_t dwEstimateSize = std::min(size, 8192U); + std::vector data(dwEstimateSize); + pFile->ReadBlock(data.data(), 0, dwEstimateSize); + CPDF_Dictionary* pDict = InitJPEG(data.data(), dwEstimateSize); + if (!pDict && size > dwEstimateSize) { + data.resize(size); + pFile->ReadBlock(data.data(), 0, size); + pDict = InitJPEG(data.data(), size); + } + if (!pDict) + return; + + m_pStream->InitStreamFromFile(pFile, pDict); +} + +void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { + int32_t BitmapWidth = pBitmap->GetWidth(); + int32_t BitmapHeight = pBitmap->GetHeight(); + if (BitmapWidth < 1 || BitmapHeight < 1) { + return; + } + uint8_t* src_buf = pBitmap->GetBuffer(); + int32_t src_pitch = pBitmap->GetPitch(); + int32_t bpp = pBitmap->GetBPP(); + + CPDF_Dictionary* pDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); + pDict->SetNameFor("Type", "XObject"); + pDict->SetNameFor("Subtype", "Image"); + pDict->SetIntegerFor("Width", BitmapWidth); + pDict->SetIntegerFor("Height", BitmapHeight); + uint8_t* dest_buf = nullptr; + FX_STRSIZE dest_pitch = 0, dest_size = 0, opType = -1; + if (bpp == 1) { + int32_t reset_a = 0, reset_r = 0, reset_g = 0, reset_b = 0; + int32_t set_a = 0, set_r = 0, set_g = 0, set_b = 0; + if (!pBitmap->IsAlphaMask()) { + ArgbDecode(pBitmap->GetPaletteArgb(0), reset_a, reset_r, reset_g, + reset_b); + ArgbDecode(pBitmap->GetPaletteArgb(1), set_a, set_r, set_g, set_b); + } + if (set_a == 0 || reset_a == 0) { + pDict->SetFor("ImageMask", new CPDF_Boolean(TRUE)); + if (reset_a == 0) { + CPDF_Array* pArray = new CPDF_Array; + pArray->AddInteger(1); + pArray->AddInteger(0); + pDict->SetFor("Decode", pArray); + } + } else { + CPDF_Array* pCS = new CPDF_Array; + pCS->AddName("Indexed"); + pCS->AddName("DeviceRGB"); + pCS->AddInteger(1); + CFX_ByteString ct; + FX_CHAR* pBuf = ct.GetBuffer(6); + pBuf[0] = (FX_CHAR)reset_r; + pBuf[1] = (FX_CHAR)reset_g; + pBuf[2] = (FX_CHAR)reset_b; + pBuf[3] = (FX_CHAR)set_r; + pBuf[4] = (FX_CHAR)set_g; + pBuf[5] = (FX_CHAR)set_b; + ct.ReleaseBuffer(6); + pCS->Add(new CPDF_String(ct, TRUE)); + pDict->SetFor("ColorSpace", pCS); + } + pDict->SetIntegerFor("BitsPerComponent", 1); + dest_pitch = (BitmapWidth + 7) / 8; + if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { + opType = 1; + } else { + opType = 0; + } + } else if (bpp == 8) { + int32_t iPalette = pBitmap->GetPaletteSize(); + if (iPalette > 0) { + CPDF_Array* pCS = new CPDF_Array; + pCS->AddName("Indexed"); + pCS->AddName("DeviceRGB"); + pCS->AddInteger(iPalette - 1); + uint8_t* pColorTable = FX_Alloc2D(uint8_t, iPalette, 3); + uint8_t* ptr = pColorTable; + for (int32_t i = 0; i < iPalette; i++) { + uint32_t argb = pBitmap->GetPaletteArgb(i); + ptr[0] = (uint8_t)(argb >> 16); + ptr[1] = (uint8_t)(argb >> 8); + ptr[2] = (uint8_t)argb; + ptr += 3; + } + CPDF_Stream* pCTS = new CPDF_Stream( + pColorTable, iPalette * 3, + new CPDF_Dictionary(m_pDocument->GetByteStringPool())); + pCS->AddReference(m_pDocument, m_pDocument->AddIndirectObject(pCTS)); + pDict->SetReferenceFor("ColorSpace", m_pDocument, + m_pDocument->AddIndirectObject(pCS)); + } else { + pDict->SetNameFor("ColorSpace", "DeviceGray"); + } + pDict->SetIntegerFor("BitsPerComponent", 8); + if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { + dest_pitch = BitmapWidth; + opType = 1; + } else { + opType = 0; + } + } else { + pDict->SetNameFor("ColorSpace", "DeviceRGB"); + pDict->SetIntegerFor("BitsPerComponent", 8); + if ((iCompress & 0x03) == PDF_IMAGE_NO_COMPRESS) { + dest_pitch = BitmapWidth * 3; + opType = 2; + } else { + opType = 0; + } + } + const CFX_DIBitmap* pMaskBitmap = nullptr; + FX_BOOL bDeleteMask = FALSE; + if (pBitmap->HasAlpha()) { + pMaskBitmap = pBitmap->GetAlphaMask(); + bDeleteMask = TRUE; + } + if (pMaskBitmap) { + int32_t maskWidth = pMaskBitmap->GetWidth(); + int32_t maskHeight = pMaskBitmap->GetHeight(); + uint8_t* mask_buf = nullptr; + FX_STRSIZE mask_size = 0; + CPDF_Dictionary* pMaskDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); + pMaskDict->SetNameFor("Type", "XObject"); + pMaskDict->SetNameFor("Subtype", "Image"); + pMaskDict->SetIntegerFor("Width", maskWidth); + pMaskDict->SetIntegerFor("Height", maskHeight); + pMaskDict->SetNameFor("ColorSpace", "DeviceGray"); + pMaskDict->SetIntegerFor("BitsPerComponent", 8); + if (pMaskBitmap->GetBPP() == 8 && + (iCompress & PDF_IMAGE_MASK_LOSSY_COMPRESS) != 0) { + } else if (pMaskBitmap->GetFormat() == FXDIB_1bppMask) { + } else { + mask_buf = FX_Alloc2D(uint8_t, maskHeight, maskWidth); + mask_size = maskHeight * maskWidth; // Safe since checked alloc returned. + for (int32_t a = 0; a < maskHeight; a++) { + FXSYS_memcpy(mask_buf + a * maskWidth, pMaskBitmap->GetScanline(a), + maskWidth); + } + } + pMaskDict->SetIntegerFor("Length", mask_size); + pDict->SetReferenceFor("SMask", m_pDocument, + m_pDocument->AddIndirectObject(new CPDF_Stream( + mask_buf, mask_size, pMaskDict))); + if (bDeleteMask) + delete pMaskBitmap; + } + if (opType == 0) { + if (iCompress & PDF_IMAGE_LOSSLESS_COMPRESS) { + } else { + if (pBitmap->GetBPP() == 1) { + } else if (pBitmap->GetBPP() >= 8 && pBitmap->GetPalette()) { + CFX_DIBitmap* pNewBitmap = new CFX_DIBitmap(); + pNewBitmap->Copy(pBitmap); + pNewBitmap->ConvertFormat(FXDIB_Rgb); + SetImage(pNewBitmap, iCompress); + if (pDict) { + pDict->Release(); + pDict = nullptr; + } + FX_Free(dest_buf); + dest_buf = nullptr; + dest_size = 0; + delete pNewBitmap; + return; + } + } + } else if (opType == 1) { + dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight); + dest_size = dest_pitch * BitmapHeight; // Safe as checked alloc returned. + + uint8_t* pDest = dest_buf; + for (int32_t i = 0; i < BitmapHeight; i++) { + FXSYS_memcpy(pDest, src_buf, dest_pitch); + pDest += dest_pitch; + src_buf += src_pitch; + } + } else if (opType == 2) { + dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight); + dest_size = dest_pitch * BitmapHeight; // Safe as checked alloc returned. + + uint8_t* pDest = dest_buf; + int32_t src_offset = 0; + int32_t dest_offset = 0; + for (int32_t row = 0; row < BitmapHeight; row++) { + src_offset = row * src_pitch; + for (int32_t column = 0; column < BitmapWidth; column++) { + FX_FLOAT alpha = 1; + pDest[dest_offset] = (uint8_t)(src_buf[src_offset + 2] * alpha); + pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha); + pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha); + dest_offset += 3; + src_offset += bpp == 24 ? 3 : 4; + } + + pDest += dest_pitch; + dest_offset = 0; + } + } + if (!m_pStream) + m_pStream = new CPDF_Stream; + + m_pStream->InitStream(dest_buf, dest_size, pDict); + m_bIsMask = pBitmap->IsAlphaMask(); + m_Width = BitmapWidth; + m_Height = BitmapHeight; + FX_Free(dest_buf); +} + +void CPDF_Image::ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pBitmap) { + pPage->GetRenderCache()->ResetBitmap(m_pStream, pBitmap); +} + +CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, + uint32_t* pMatteColor, + FX_BOOL bStdCS, + uint32_t GroupFamily, + FX_BOOL bLoadMask) const { + std::unique_ptr source(new CPDF_DIBSource); + if (source->Load(m_pDocument, m_pStream, + reinterpret_cast(ppMask), pMatteColor, + nullptr, nullptr, bStdCS, GroupFamily, bLoadMask)) { + return source.release(); + } + return nullptr; +} + +CFX_DIBSource* CPDF_Image::DetachBitmap() { + CFX_DIBSource* pBitmap = m_pDIBSource; + m_pDIBSource = nullptr; + return pBitmap; +} + +CFX_DIBSource* CPDF_Image::DetachMask() { + CFX_DIBSource* pBitmap = m_pMask; + m_pMask = nullptr; + return pBitmap; +} + +FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, + CPDF_Dictionary* pPageResource, + FX_BOOL bStdCS, + uint32_t GroupFamily, + FX_BOOL bLoadMask) { + std::unique_ptr source(new CPDF_DIBSource); + int ret = + source->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, + pPageResource, bStdCS, GroupFamily, bLoadMask); + if (ret == 2) { + m_pDIBSource = source.release(); + return TRUE; + } + if (!ret) { + m_pDIBSource = nullptr; + return FALSE; + } + m_pMask = source->DetachMask(); + m_MatteColor = source->GetMatteColor(); + m_pDIBSource = source.release(); + return FALSE; +} + +FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) { + CPDF_DIBSource* pSource = static_cast(m_pDIBSource); + int ret = pSource->ContinueLoadDIBSource(pPause); + if (ret == 2) { + return TRUE; + } + if (!ret) { + delete m_pDIBSource; + m_pDIBSource = nullptr; + return FALSE; + } + m_pMask = pSource->DetachMask(); + m_MatteColor = pSource->GetMatteColor(); + return FALSE; +} diff --git a/core/fpdfapi/page/cpdf_image.h b/core/fpdfapi/page/cpdf_image.h new file mode 100644 index 0000000000..0bf806c13e --- /dev/null +++ b/core/fpdfapi/page/cpdf_image.h @@ -0,0 +1,90 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_IMAGE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_IMAGE_H_ + +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fxcrt/fx_system.h" + +#define PDF_IMAGE_NO_COMPRESS 0x0000 +#define PDF_IMAGE_LOSSY_COMPRESS 0x0001 +#define PDF_IMAGE_LOSSLESS_COMPRESS 0x0002 +#define PDF_IMAGE_MASK_LOSSY_COMPRESS 0x0004 +#define PDF_IMAGE_MASK_LOSSLESS_COMPRESS 0x0008 + +class CFX_DIBitmap; +class CFX_DIBSource; +class CPDF_Dictionay; +class CPDF_Document; +class CPDF_Page; +class IFX_FileRead; +class IFX_FileWrite; +class IFX_Pause; + +class CPDF_Image { + public: + explicit CPDF_Image(CPDF_Document* pDoc); + CPDF_Image(CPDF_Document* pDoc, CPDF_Stream* pStream, bool bInline); + ~CPDF_Image(); + + CPDF_Image* Clone(); + + CPDF_Dictionary* GetInlineDict() const { return m_pInlineDict; } + CPDF_Stream* GetStream() const { return m_pStream; } + CPDF_Dictionary* GetDict() const { + return m_pStream ? m_pStream->GetDict() : nullptr; + } + CPDF_Dictionary* GetOC() const { return m_pOC; } + CPDF_Document* GetDocument() const { return m_pDocument; } + + int32_t GetPixelHeight() const { return m_Height; } + int32_t GetPixelWidth() const { return m_Width; } + + bool IsInline() const { return m_bInline; } + bool IsMask() const { return m_bIsMask; } + bool IsInterpol() const { return m_bInterpolate; } + + CFX_DIBSource* LoadDIBSource(CFX_DIBSource** ppMask = nullptr, + uint32_t* pMatteColor = nullptr, + FX_BOOL bStdCS = FALSE, + uint32_t GroupFamily = 0, + FX_BOOL bLoadMask = FALSE) const; + + void SetInlineDict(CPDF_Dictionary* pDict) { m_pInlineDict = pDict; } + void SetImage(const CFX_DIBitmap* pDIBitmap, int32_t iCompress); + void SetJpegImage(IFX_FileRead* pFile); + + void ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pDIBitmap); + + FX_BOOL StartLoadDIBSource(CPDF_Dictionary* pFormResource, + CPDF_Dictionary* pPageResource, + FX_BOOL bStdCS = FALSE, + uint32_t GroupFamily = 0, + FX_BOOL bLoadMask = FALSE); + FX_BOOL Continue(IFX_Pause* pPause); + CFX_DIBSource* DetachBitmap(); + CFX_DIBSource* DetachMask(); + + CFX_DIBSource* m_pDIBSource; + CFX_DIBSource* m_pMask; + uint32_t m_MatteColor; + + private: + CPDF_Dictionary* InitJPEG(uint8_t* pData, uint32_t size); + + CPDF_Stream* m_pStream; + const bool m_bInline; + CPDF_Dictionary* m_pInlineDict; + int32_t m_Height; + int32_t m_Width; + bool m_bIsMask; + bool m_bInterpolate; + CPDF_Document* const m_pDocument; + CPDF_Dictionary* m_pOC; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_IMAGE_H_ diff --git a/core/fpdfapi/page/cpdf_imageobject.cpp b/core/fpdfapi/page/cpdf_imageobject.cpp new file mode 100644 index 0000000000..8be2cf3c76 --- /dev/null +++ b/core/fpdfapi/page/cpdf_imageobject.cpp @@ -0,0 +1,84 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_imageobject.h" + +#include + +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/pageint.h" + +CPDF_ImageObject::CPDF_ImageObject() + : m_pImage(nullptr), m_pImageOwned(false) {} + +CPDF_ImageObject::~CPDF_ImageObject() { + Release(); +} + +CPDF_ImageObject* CPDF_ImageObject::Clone() const { + CPDF_ImageObject* obj = new CPDF_ImageObject; + obj->CopyData(this); + + obj->m_pImage = m_pImage->Clone(); + obj->m_Matrix = m_Matrix; + return obj; +} + +CPDF_PageObject::Type CPDF_ImageObject::GetType() const { + return IMAGE; +} + +void CPDF_ImageObject::Transform(const CFX_Matrix& matrix) { + m_Matrix.Concat(matrix); + CalcBoundingBox(); +} + +bool CPDF_ImageObject::IsImage() const { + return true; +} + +CPDF_ImageObject* CPDF_ImageObject::AsImage() { + return this; +} + +const CPDF_ImageObject* CPDF_ImageObject::AsImage() const { + return this; +} + +void CPDF_ImageObject::CalcBoundingBox() { + m_Left = m_Bottom = 0; + m_Right = m_Top = 1.0f; + m_Matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); +} + +void CPDF_ImageObject::SetOwnedImage(std::unique_ptr pImage) { + Release(); + m_pImage = pImage.release(); + m_pImageOwned = true; +} + +void CPDF_ImageObject::SetUnownedImage(CPDF_Image* pImage) { + Release(); + m_pImage = pImage; + m_pImageOwned = false; +} + +void CPDF_ImageObject::Release() { + if (m_pImageOwned) { + delete m_pImage; + m_pImage = nullptr; + m_pImageOwned = false; + return; + } + + if (!m_pImage) + return; + + CPDF_DocPageData* pPageData = m_pImage->GetDocument()->GetPageData(); + pPageData->ReleaseImage(m_pImage->GetStream()); + m_pImage = nullptr; +} diff --git a/core/fpdfapi/page/cpdf_imageobject.h b/core/fpdfapi/page/cpdf_imageobject.h new file mode 100644 index 0000000000..fd99d3d612 --- /dev/null +++ b/core/fpdfapi/page/cpdf_imageobject.h @@ -0,0 +1,44 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_IMAGEOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_IMAGEOBJECT_H_ + +#include + +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fxcrt/fx_coordinates.h" + +class CPDF_Image; + +class CPDF_ImageObject : public CPDF_PageObject { + public: + CPDF_ImageObject(); + ~CPDF_ImageObject() override; + + // CPDF_PageObject + CPDF_ImageObject* Clone() const override; + Type GetType() const override; + void Transform(const CFX_Matrix& matrix) override; + bool IsImage() const override; + CPDF_ImageObject* AsImage() override; + const CPDF_ImageObject* AsImage() const override; + + void CalcBoundingBox(); + CPDF_Image* GetImage() const { return m_pImage; } + void SetOwnedImage(std::unique_ptr pImage); + void SetUnownedImage(CPDF_Image* pImage); + + CFX_Matrix m_Matrix; + + private: + void Release(); + + CPDF_Image* m_pImage; + bool m_pImageOwned; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_IMAGEOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp new file mode 100644 index 0000000000..bd877a0920 --- /dev/null +++ b/core/fpdfapi/page/cpdf_meshstream.cpp @@ -0,0 +1,217 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_meshstream.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/page/cpdf_colorspace.h" +#include "core/fpdfapi/page/pageint.h" + +namespace { + +// See PDF Reference 1.7, page 315, table 4.32. (Also table 4.33 and 4.34) +bool ShouldCheckBPC(ShadingType type) { + switch (type) { + case kFreeFormGouraudTriangleMeshShading: + case kLatticeFormGouraudTriangleMeshShading: + case kCoonsPatchMeshShading: + case kTensorProductPatchMeshShading: + return true; + default: + return false; + } +} + +// Same references as ShouldCheckBPC() above. +bool IsValidBitsPerComponent(uint32_t x) { + switch (x) { + case 1: + case 2: + case 4: + case 8: + case 12: + case 16: + return true; + default: + return false; + } +} + +// Same references as ShouldCheckBPC() above. +bool IsValidBitsPerCoordinate(uint32_t x) { + switch (x) { + case 1: + case 2: + case 4: + case 8: + case 12: + case 16: + case 24: + case 32: + return true; + default: + return false; + } +} + +// See PDF Reference 1.7, page 315, table 4.32. (Also table 4.34) +bool ShouldCheckBitsPerFlag(ShadingType type) { + switch (type) { + case kFreeFormGouraudTriangleMeshShading: + case kCoonsPatchMeshShading: + case kTensorProductPatchMeshShading: + return true; + default: + return false; + } +} + +// Same references as ShouldCheckBitsPerFlag() above. +bool IsValidBitsPerFlag(uint32_t x) { + switch (x) { + case 2: + case 4: + case 8: + return true; + default: + return false; + } +} + +} // namespace + +CPDF_MeshStream::CPDF_MeshStream( + ShadingType type, + const std::vector>& funcs, + CPDF_Stream* pShadingStream, + CPDF_ColorSpace* pCS) + : m_type(type), + m_funcs(funcs), + m_pShadingStream(pShadingStream), + m_pCS(pCS), + m_nCoordBits(0), + m_nComponentBits(0), + m_nFlagBits(0), + m_nComponents(0), + m_CoordMax(0), + m_ComponentMax(0), + m_xmin(0), + m_xmax(0), + m_ymin(0), + m_ymax(0) { + memset(&m_ColorMin, 0, sizeof(m_ColorMin)); + memset(&m_ColorMax, 0, sizeof(m_ColorMax)); +} + +bool CPDF_MeshStream::Load() { + m_Stream.LoadAllData(m_pShadingStream); + m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize()); + CPDF_Dictionary* pDict = m_pShadingStream->GetDict(); + m_nCoordBits = pDict->GetIntegerFor("BitsPerCoordinate"); + m_nComponentBits = pDict->GetIntegerFor("BitsPerComponent"); + if (ShouldCheckBPC(m_type)) { + if (!IsValidBitsPerCoordinate(m_nCoordBits)) + return false; + if (!IsValidBitsPerComponent(m_nComponentBits)) + return false; + } + + m_nFlagBits = pDict->GetIntegerFor("BitsPerFlag"); + if (ShouldCheckBitsPerFlag(m_type) && !IsValidBitsPerFlag(m_nFlagBits)) + return false; + + uint32_t nComponents = m_pCS->CountComponents(); + if (nComponents > kMaxComponents) + return false; + + m_nComponents = m_funcs.empty() ? nComponents : 1; + CPDF_Array* pDecode = pDict->GetArrayFor("Decode"); + if (!pDecode || pDecode->GetCount() != 4 + m_nComponents * 2) + return false; + + m_xmin = pDecode->GetNumberAt(0); + m_xmax = pDecode->GetNumberAt(1); + m_ymin = pDecode->GetNumberAt(2); + m_ymax = pDecode->GetNumberAt(3); + for (uint32_t i = 0; i < m_nComponents; ++i) { + m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4); + m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5); + } + + if (ShouldCheckBPC(m_type)) { + m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1; + m_ComponentMax = (1 << m_nComponentBits) - 1; + } + return true; +} + +uint32_t CPDF_MeshStream::GetFlag() { + ASSERT(ShouldCheckBitsPerFlag(m_type)); + return m_BitStream.GetBits(m_nFlagBits) & 0x03; +} + +void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { + ASSERT(ShouldCheckBPC(m_type)); + if (m_nCoordBits == 32) { + x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * + (m_xmax - m_xmin) / (double)m_CoordMax); + y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) * + (m_ymax - m_ymin) / (double)m_CoordMax); + } else { + x = m_xmin + + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; + y = m_ymin + + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; + } +} + +void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { + ASSERT(ShouldCheckBPC(m_type)); + FX_FLOAT color_value[kMaxComponents]; + for (uint32_t i = 0; i < m_nComponents; ++i) { + color_value[i] = m_ColorMin[i] + + m_BitStream.GetBits(m_nComponentBits) * + (m_ColorMax[i] - m_ColorMin[i]) / m_ComponentMax; + } + if (m_funcs.empty()) { + m_pCS->GetRGB(color_value, r, g, b); + return; + } + + FX_FLOAT result[kMaxComponents]; + FXSYS_memset(result, 0, sizeof(result)); + int nResults; + for (const auto& func : m_funcs) { + if (func && func->CountOutputs() <= kMaxComponents) + func->Call(color_value, 1, result, nResults); + } + m_pCS->GetRGB(result, r, g, b); +} + +uint32_t CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex, + CFX_Matrix* pObject2Bitmap) { + uint32_t flag = GetFlag(); + GetCoords(vertex.x, vertex.y); + pObject2Bitmap->Transform(vertex.x, vertex.y); + GetColor(vertex.r, vertex.g, vertex.b); + m_BitStream.ByteAlign(); + return flag; +} + +FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, + int count, + CFX_Matrix* pObject2Bitmap) { + for (int i = 0; i < count; i++) { + if (m_BitStream.IsEOF()) + return FALSE; + + GetCoords(vertex[i].x, vertex[i].y); + pObject2Bitmap->Transform(vertex[i].x, vertex[i].y); + GetColor(vertex[i].r, vertex[i].g, vertex[i].b); + m_BitStream.ByteAlign(); + } + return TRUE; +} diff --git a/core/fpdfapi/page/cpdf_meshstream.h b/core/fpdfapi/page/cpdf_meshstream.h new file mode 100644 index 0000000000..a2ac9ae868 --- /dev/null +++ b/core/fpdfapi/page/cpdf_meshstream.h @@ -0,0 +1,76 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_MESHSTREAM_H_ +#define CORE_FPDFAPI_PAGE_CPDF_MESHSTREAM_H_ + +#include +#include + +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/page/cpdf_shadingpattern.h" +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_system.h" + +struct CPDF_MeshVertex { + FX_FLOAT x; + FX_FLOAT y; + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; +}; + +class CFX_Matrix; +class CPDF_ColorSpace; +class CPDF_Function; +class CPDF_Stream; + +class CPDF_MeshStream { + public: + CPDF_MeshStream(ShadingType type, + const std::vector>& funcs, + CPDF_Stream* pShadingStream, + CPDF_ColorSpace* pCS); + + bool Load(); + + uint32_t GetFlag(); + void GetCoords(FX_FLOAT& x, FX_FLOAT& y); + void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b); + + uint32_t GetVertex(CPDF_MeshVertex& vertex, CFX_Matrix* pObject2Bitmap); + FX_BOOL GetVertexRow(CPDF_MeshVertex* vertex, + int count, + CFX_Matrix* pObject2Bitmap); + + CFX_BitStream* BitStream() { return &m_BitStream; } + uint32_t ComponentBits() const { return m_nComponentBits; } + uint32_t Components() const { return m_nComponents; } + + private: + static const uint32_t kMaxComponents = 8; + + const ShadingType m_type; + const std::vector>& m_funcs; + CPDF_Stream* const m_pShadingStream; + CPDF_ColorSpace* const m_pCS; + uint32_t m_nCoordBits; + uint32_t m_nComponentBits; + uint32_t m_nFlagBits; + uint32_t m_nComponents; + uint32_t m_CoordMax; + uint32_t m_ComponentMax; + FX_FLOAT m_xmin; + FX_FLOAT m_xmax; + FX_FLOAT m_ymin; + FX_FLOAT m_ymax; + FX_FLOAT m_ColorMin[kMaxComponents]; + FX_FLOAT m_ColorMax[kMaxComponents]; + CPDF_StreamAcc m_Stream; + CFX_BitStream m_BitStream; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_MESHSTREAM_H_ diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp new file mode 100644 index 0000000000..f471760c91 --- /dev/null +++ b/core/fpdfapi/page/cpdf_page.cpp @@ -0,0 +1,176 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_page.h" + +#include + +#include "core/fpdfapi/cpdf_pagerendercontext.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_object.h" +#include "core/fpdfapi/fpdf_render/cpdf_pagerendercache.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/pageint.h" +#include "third_party/base/stl_util.h" + +CPDF_Page::CPDF_Page(CPDF_Document* pDocument, + CPDF_Dictionary* pPageDict, + bool bPageCache) + : m_PageWidth(100), + m_PageHeight(100), + m_pView(nullptr), + m_pPageRender(bPageCache ? new CPDF_PageRenderCache(this) : nullptr) { + m_pFormDict = pPageDict; + m_pDocument = pDocument; + if (!pPageDict) + return; + + CPDF_Object* pageAttr = GetPageAttr("Resources"); + m_pResources = pageAttr ? pageAttr->GetDict() : nullptr; + m_pPageResources = m_pResources; + CPDF_Object* pRotate = GetPageAttr("Rotate"); + int rotate = pRotate ? pRotate->GetInteger() / 90 % 4 : 0; + if (rotate < 0) + rotate += 4; + + CPDF_Array* pMediaBox = ToArray(GetPageAttr("MediaBox")); + CFX_FloatRect mediabox; + if (pMediaBox) { + mediabox = pMediaBox->GetRect(); + mediabox.Normalize(); + } + if (mediabox.IsEmpty()) + mediabox = CFX_FloatRect(0, 0, 612, 792); + + CPDF_Array* pCropBox = ToArray(GetPageAttr("CropBox")); + if (pCropBox) { + m_BBox = pCropBox->GetRect(); + m_BBox.Normalize(); + } + if (m_BBox.IsEmpty()) + m_BBox = mediabox; + else + m_BBox.Intersect(mediabox); + + m_PageWidth = m_BBox.right - m_BBox.left; + m_PageHeight = m_BBox.top - m_BBox.bottom; + if (rotate % 2) + std::swap(m_PageWidth, m_PageHeight); + + switch (rotate) { + case 0: + m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); + break; + case 1: + m_PageMatrix.Set(0, -1.0f, 1.0f, 0, -m_BBox.bottom, m_BBox.right); + break; + case 2: + m_PageMatrix.Set(-1.0f, 0, 0, -1.0f, m_BBox.right, m_BBox.top); + break; + case 3: + m_PageMatrix.Set(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); + break; + } + + m_Transparency = PDFTRANS_ISOLATED; + LoadTransInfo(); +} + +CPDF_Page::~CPDF_Page() {} + +void CPDF_Page::StartParse() { + if (m_ParseState == CONTENT_PARSED || m_ParseState == CONTENT_PARSING) + return; + + m_pParser.reset(new CPDF_ContentParser); + m_pParser->Start(this); + m_ParseState = CONTENT_PARSING; +} + +void CPDF_Page::ParseContent() { + StartParse(); + ContinueParse(nullptr); +} + +void CPDF_Page::SetRenderContext( + std::unique_ptr pContext) { + m_pRenderContext = std::move(pContext); +} + +CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteString& name) const { + CPDF_Dictionary* pPageDict = m_pFormDict; + std::set visited; + while (1) { + visited.insert(pPageDict); + if (CPDF_Object* pObj = pPageDict->GetDirectObjectFor(name)) + return pObj; + + pPageDict = pPageDict->GetDictFor("Parent"); + if (!pPageDict || pdfium::ContainsKey(visited, pPageDict)) + break; + } + return nullptr; +} + +void CPDF_Page::GetDisplayMatrix(CFX_Matrix& matrix, + int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const { + if (m_PageWidth == 0 || m_PageHeight == 0) { + return; + } + CFX_Matrix display_matrix; + int x0 = 0; + int y0 = 0; + int x1 = 0; + int y1 = 0; + int x2 = 0; + int y2 = 0; + iRotate %= 4; + switch (iRotate) { + case 0: + x0 = xPos; + y0 = yPos + ySize; + x1 = xPos; + y1 = yPos; + x2 = xPos + xSize; + y2 = yPos + ySize; + break; + case 1: + x0 = xPos; + y0 = yPos; + x1 = xPos + xSize; + y1 = yPos; + x2 = xPos; + y2 = yPos + ySize; + break; + case 2: + x0 = xPos + xSize; + y0 = yPos; + x1 = xPos + xSize; + y1 = yPos + ySize; + x2 = xPos; + y2 = yPos; + break; + case 3: + x0 = xPos + xSize; + y0 = yPos + ySize; + x1 = xPos; + y1 = yPos + ySize; + x2 = xPos + xSize; + y2 = yPos; + break; + } + display_matrix.Set( + ((FX_FLOAT)(x2 - x0)) / m_PageWidth, ((FX_FLOAT)(y2 - y0)) / m_PageWidth, + ((FX_FLOAT)(x1 - x0)) / m_PageHeight, + ((FX_FLOAT)(y1 - y0)) / m_PageHeight, (FX_FLOAT)x0, (FX_FLOAT)y0); + matrix = m_PageMatrix; + matrix.Concat(display_matrix); +} diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h new file mode 100644 index 0000000000..a542e33dbc --- /dev/null +++ b/core/fpdfapi/page/cpdf_page.h @@ -0,0 +1,69 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PAGE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PAGE_H_ + +#include + +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" +#include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Dictionary; +class CPDF_Document; +class CPDF_Object; +class CPDF_PageRenderCache; +class CPDF_PageRenderContext; + +class CPDF_Page : public CPDF_PageObjectHolder { + public: + class View {}; // Caller implements as desired, empty here due to layering. + + CPDF_Page(CPDF_Document* pDocument, + CPDF_Dictionary* pPageDict, + bool bPageCache); + ~CPDF_Page() override; + + void ParseContent(); + + void GetDisplayMatrix(CFX_Matrix& matrix, + int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const; + + FX_FLOAT GetPageWidth() const { return m_PageWidth; } + FX_FLOAT GetPageHeight() const { return m_PageHeight; } + CFX_FloatRect GetPageBBox() const { return m_BBox; } + const CFX_Matrix& GetPageMatrix() const { return m_PageMatrix; } + CPDF_Object* GetPageAttr(const CFX_ByteString& name) const; + CPDF_PageRenderCache* GetRenderCache() const { return m_pPageRender.get(); } + + CPDF_PageRenderContext* GetRenderContext() const { + return m_pRenderContext.get(); + } + void SetRenderContext(std::unique_ptr pContext); + + View* GetView() const { return m_pView; } + void SetView(View* pView) { m_pView = pView; } + + protected: + friend class CPDF_ContentParser; + + void StartParse(); + + FX_FLOAT m_PageWidth; + FX_FLOAT m_PageHeight; + CFX_Matrix m_PageMatrix; + View* m_pView; + std::unique_ptr m_pPageRender; + std::unique_ptr m_pRenderContext; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PAGE_H_ diff --git a/core/fpdfapi/page/cpdf_pagemodule.cpp b/core/fpdfapi/page/cpdf_pagemodule.cpp new file mode 100644 index 0000000000..80edf2cdd0 --- /dev/null +++ b/core/fpdfapi/page/cpdf_pagemodule.cpp @@ -0,0 +1,35 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_pagemodule.h" + +CPDF_PageModule::CPDF_PageModule() + : m_StockGrayCS(nullptr, PDFCS_DEVICEGRAY), + m_StockRGBCS(nullptr, PDFCS_DEVICERGB), + m_StockCMYKCS(nullptr, PDFCS_DEVICECMYK), + m_StockPatternCS(nullptr) {} + +CPDF_PageModule::~CPDF_PageModule() {} + +CPDF_FontGlobals* CPDF_PageModule::GetFontGlobals() { + return &m_FontGlobals; +} + +CPDF_ColorSpace* CPDF_PageModule::GetStockCS(int family) { + if (family == PDFCS_DEVICEGRAY) + return &m_StockGrayCS; + if (family == PDFCS_DEVICERGB) + return &m_StockRGBCS; + if (family == PDFCS_DEVICECMYK) + return &m_StockCMYKCS; + if (family == PDFCS_PATTERN) + return &m_StockPatternCS; + return nullptr; +} + +void CPDF_PageModule::ClearStockFont(CPDF_Document* pDoc) { + m_FontGlobals.Clear(pDoc); +} diff --git a/core/fpdfapi/page/cpdf_pagemodule.h b/core/fpdfapi/page/cpdf_pagemodule.h new file mode 100644 index 0000000000..4aa19da2bb --- /dev/null +++ b/core/fpdfapi/page/cpdf_pagemodule.h @@ -0,0 +1,33 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PAGEMODULE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PAGEMODULE_H_ + +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/page/cpdf_colorspace.h" +#include "core/fpdfapi/page/pageint.h" + +class CPDF_Document; + +class CPDF_PageModule { + public: + CPDF_PageModule(); + ~CPDF_PageModule(); + + CPDF_FontGlobals* GetFontGlobals(); + CPDF_ColorSpace* GetStockCS(int family); + void ClearStockFont(CPDF_Document* pDoc); + + private: + CPDF_FontGlobals m_FontGlobals; + CPDF_DeviceCS m_StockGrayCS; + CPDF_DeviceCS m_StockRGBCS; + CPDF_DeviceCS m_StockCMYKCS; + CPDF_PatternCS m_StockPatternCS; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PAGEMODULE_H_ diff --git a/core/fpdfapi/page/cpdf_pageobject.cpp b/core/fpdfapi/page/cpdf_pageobject.cpp new file mode 100644 index 0000000000..c0e031e7ed --- /dev/null +++ b/core/fpdfapi/page/cpdf_pageobject.cpp @@ -0,0 +1,99 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_pageobject.h" + +CPDF_PageObject::CPDF_PageObject() {} + +CPDF_PageObject::~CPDF_PageObject() {} + +bool CPDF_PageObject::IsText() const { + return false; +} + +bool CPDF_PageObject::IsPath() const { + return false; +} + +bool CPDF_PageObject::IsImage() const { + return false; +} + +bool CPDF_PageObject::IsShading() const { + return false; +} + +bool CPDF_PageObject::IsForm() const { + return false; +} + +CPDF_TextObject* CPDF_PageObject::AsText() { + return nullptr; +} + +const CPDF_TextObject* CPDF_PageObject::AsText() const { + return nullptr; +} + +CPDF_PathObject* CPDF_PageObject::AsPath() { + return nullptr; +} + +const CPDF_PathObject* CPDF_PageObject::AsPath() const { + return nullptr; +} + +CPDF_ImageObject* CPDF_PageObject::AsImage() { + return nullptr; +} + +const CPDF_ImageObject* CPDF_PageObject::AsImage() const { + return nullptr; +} + +CPDF_ShadingObject* CPDF_PageObject::AsShading() { + return nullptr; +} + +const CPDF_ShadingObject* CPDF_PageObject::AsShading() const { + return nullptr; +} + +CPDF_FormObject* CPDF_PageObject::AsForm() { + return nullptr; +} + +const CPDF_FormObject* CPDF_PageObject::AsForm() const { + return nullptr; +} + +void CPDF_PageObject::CopyData(const CPDF_PageObject* pSrc) { + CopyStates(*pSrc); + m_Left = pSrc->m_Left; + m_Right = pSrc->m_Right; + m_Top = pSrc->m_Top; + m_Bottom = pSrc->m_Bottom; +} + +void CPDF_PageObject::TransformClipPath(CFX_Matrix& matrix) { + if (!m_ClipPath) + return; + m_ClipPath.Transform(matrix); +} + +void CPDF_PageObject::TransformGeneralState(CFX_Matrix& matrix) { + if (!m_GeneralState) + return; + m_GeneralState.GetMutableMatrix()->Concat(matrix); +} + +FX_RECT CPDF_PageObject::GetBBox(const CFX_Matrix* pMatrix) const { + CFX_FloatRect rect(m_Left, m_Bottom, m_Right, m_Top); + if (pMatrix) { + pMatrix->TransformRect(rect); + } + return rect.GetOuterRect(); +} diff --git a/core/fpdfapi/page/cpdf_pageobject.h b/core/fpdfapi/page/cpdf_pageobject.h new file mode 100644 index 0000000000..97cac7e9aa --- /dev/null +++ b/core/fpdfapi/page/cpdf_pageobject.h @@ -0,0 +1,71 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECT_H_ + +#include "core/fpdfapi/page/cpdf_contentmark.h" +#include "core/fpdfapi/page/cpdf_graphicstates.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_TextObject; +class CPDF_PathObject; +class CPDF_ImageObject; +class CPDF_ShadingObject; +class CPDF_FormObject; + +class CPDF_PageObject : public CPDF_GraphicStates { + public: + enum Type { + TEXT = 1, + PATH, + IMAGE, + SHADING, + FORM, + }; + + CPDF_PageObject(); + ~CPDF_PageObject() override; + + virtual CPDF_PageObject* Clone() const = 0; + virtual Type GetType() const = 0; + virtual void Transform(const CFX_Matrix& matrix) = 0; + virtual bool IsText() const; + virtual bool IsPath() const; + virtual bool IsImage() const; + virtual bool IsShading() const; + virtual bool IsForm() const; + virtual CPDF_TextObject* AsText(); + virtual const CPDF_TextObject* AsText() const; + virtual CPDF_PathObject* AsPath(); + virtual const CPDF_PathObject* AsPath() const; + virtual CPDF_ImageObject* AsImage(); + virtual const CPDF_ImageObject* AsImage() const; + virtual CPDF_ShadingObject* AsShading(); + virtual const CPDF_ShadingObject* AsShading() const; + virtual CPDF_FormObject* AsForm(); + virtual const CPDF_FormObject* AsForm() const; + + void TransformClipPath(CFX_Matrix& matrix); + void TransformGeneralState(CFX_Matrix& matrix); + FX_RECT GetBBox(const CFX_Matrix* pMatrix) const; + + FX_FLOAT m_Left; + FX_FLOAT m_Right; + FX_FLOAT m_Top; + FX_FLOAT m_Bottom; + CPDF_ContentMark m_ContentMark; + + protected: + void CopyData(const CPDF_PageObject* pSrcObject); + + private: + CPDF_PageObject(const CPDF_PageObject& src) = delete; + void operator=(const CPDF_PageObject& src) = delete; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.cpp b/core/fpdfapi/page/cpdf_pageobjectholder.cpp new file mode 100644 index 0000000000..bd7830de4d --- /dev/null +++ b/core/fpdfapi/page/cpdf_pageobjectholder.cpp @@ -0,0 +1,77 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/pageint.h" + +CPDF_PageObjectHolder::CPDF_PageObjectHolder() + : m_pFormDict(nullptr), + m_pFormStream(nullptr), + m_pDocument(nullptr), + m_pPageResources(nullptr), + m_pResources(nullptr), + m_Transparency(0), + m_bBackgroundAlphaNeeded(FALSE), + m_bHasImageMask(FALSE), + m_ParseState(CONTENT_NOT_PARSED) {} + +CPDF_PageObjectHolder::~CPDF_PageObjectHolder() {} + +void CPDF_PageObjectHolder::ContinueParse(IFX_Pause* pPause) { + if (!m_pParser) { + return; + } + m_pParser->Continue(pPause); + if (m_pParser->GetStatus() == CPDF_ContentParser::Done) { + m_ParseState = CONTENT_PARSED; + m_pParser.reset(); + } +} + +void CPDF_PageObjectHolder::Transform(const CFX_Matrix& matrix) { + for (auto& pObj : m_PageObjectList) + pObj->Transform(matrix); +} + +CFX_FloatRect CPDF_PageObjectHolder::CalcBoundingBox() const { + if (m_PageObjectList.empty()) + return CFX_FloatRect(0, 0, 0, 0); + + FX_FLOAT left = 1000000.0f; + FX_FLOAT right = -1000000.0f; + FX_FLOAT bottom = 1000000.0f; + FX_FLOAT top = -1000000.0f; + for (const auto& pObj : m_PageObjectList) { + left = std::min(left, pObj->m_Left); + right = std::max(right, pObj->m_Right); + bottom = std::min(bottom, pObj->m_Bottom); + top = std::max(top, pObj->m_Top); + } + return CFX_FloatRect(left, bottom, right, top); +} + +void CPDF_PageObjectHolder::LoadTransInfo() { + if (!m_pFormDict) { + return; + } + CPDF_Dictionary* pGroup = m_pFormDict->GetDictFor("Group"); + if (!pGroup) { + return; + } + if (pGroup->GetStringFor("S") != "Transparency") { + return; + } + m_Transparency |= PDFTRANS_GROUP; + if (pGroup->GetIntegerFor("I")) { + m_Transparency |= PDFTRANS_ISOLATED; + } + if (pGroup->GetIntegerFor("K")) { + m_Transparency |= PDFTRANS_KNOCKOUT; + } +} diff --git a/core/fpdfapi/page/cpdf_pageobjectholder.h b/core/fpdfapi/page/cpdf_pageobjectholder.h new file mode 100644 index 0000000000..96a0a80838 --- /dev/null +++ b/core/fpdfapi/page/cpdf_pageobjectholder.h @@ -0,0 +1,68 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ + +#include "core/fpdfapi/page/cpdf_pageobjectlist.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class IFX_Pause; +class CPDF_Dictionary; +class CPDF_Stream; +class CPDF_Document; +class CPDF_ContentParser; + +#define PDFTRANS_GROUP 0x0100 +#define PDFTRANS_ISOLATED 0x0200 +#define PDFTRANS_KNOCKOUT 0x0400 + +class CPDF_PageObjectHolder { + public: + CPDF_PageObjectHolder(); + virtual ~CPDF_PageObjectHolder(); + + void ContinueParse(IFX_Pause* pPause); + bool IsParsed() const { return m_ParseState == CONTENT_PARSED; } + + CPDF_PageObjectList* GetPageObjectList() { return &m_PageObjectList; } + const CPDF_PageObjectList* GetPageObjectList() const { + return &m_PageObjectList; + } + + FX_BOOL BackgroundAlphaNeeded() const { return m_bBackgroundAlphaNeeded; } + void SetBackgroundAlphaNeeded(FX_BOOL needed) { + m_bBackgroundAlphaNeeded = needed; + } + + FX_BOOL HasImageMask() const { return m_bHasImageMask; } + void SetHasImageMask(FX_BOOL value) { m_bHasImageMask = value; } + + void Transform(const CFX_Matrix& matrix); + CFX_FloatRect CalcBoundingBox() const; + + CPDF_Dictionary* m_pFormDict; + CPDF_Stream* m_pFormStream; + CPDF_Document* m_pDocument; + CPDF_Dictionary* m_pPageResources; + CPDF_Dictionary* m_pResources; + CFX_FloatRect m_BBox; + int m_Transparency; + + protected: + enum ParseState { CONTENT_NOT_PARSED, CONTENT_PARSING, CONTENT_PARSED }; + + void LoadTransInfo(); + + FX_BOOL m_bBackgroundAlphaNeeded; + FX_BOOL m_bHasImageMask; + ParseState m_ParseState; + std::unique_ptr m_pParser; + CPDF_PageObjectList m_PageObjectList; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTHOLDER_H_ diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.cpp b/core/fpdfapi/page/cpdf_pageobjectlist.cpp new file mode 100644 index 0000000000..02b590e413 --- /dev/null +++ b/core/fpdfapi/page/cpdf_pageobjectlist.cpp @@ -0,0 +1,16 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_pageobjectlist.h" + +#include "core/fpdfapi/page/pageint.h" +#include "third_party/base/stl_util.h" + +CPDF_PageObject* CPDF_PageObjectList::GetPageObjectByIndex(int index) { + if (index < 0 || index >= pdfium::CollectionSize(*this)) + return nullptr; + return (*this)[index].get(); +} diff --git a/core/fpdfapi/page/cpdf_pageobjectlist.h b/core/fpdfapi/page/cpdf_pageobjectlist.h new file mode 100644 index 0000000000..b4505371f8 --- /dev/null +++ b/core/fpdfapi/page/cpdf_pageobjectlist.h @@ -0,0 +1,21 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTLIST_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTLIST_H_ + +#include +#include + +class CPDF_PageObject; + +class CPDF_PageObjectList + : public std::deque> { + public: + CPDF_PageObject* GetPageObjectByIndex(int index); +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PAGEOBJECTLIST_H_ diff --git a/core/fpdfapi/page/cpdf_path.cpp b/core/fpdfapi/page/cpdf_path.cpp new file mode 100644 index 0000000000..e80edf798e --- /dev/null +++ b/core/fpdfapi/page/cpdf_path.cpp @@ -0,0 +1,73 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_path.h" + +CPDF_Path::CPDF_Path() {} + +CPDF_Path::CPDF_Path(const CPDF_Path& that) : m_Ref(that.m_Ref) {} + +CPDF_Path::~CPDF_Path() {} + +int CPDF_Path::GetPointCount() const { + return m_Ref.GetObject()->GetPointCount(); +} + +void CPDF_Path::SetPointCount(int count) { + m_Ref.GetPrivateCopy()->SetPointCount(count); +} + +const FX_PATHPOINT* CPDF_Path::GetPoints() const { + return m_Ref.GetObject()->GetPoints(); +} + +FX_PATHPOINT* CPDF_Path::GetMutablePoints() { + return m_Ref.GetPrivateCopy()->GetPoints(); +} + +int CPDF_Path::GetFlag(int index) const { + return m_Ref.GetObject()->GetFlag(index); +} + +FX_FLOAT CPDF_Path::GetPointX(int index) const { + return m_Ref.GetObject()->GetPointX(index); +} + +FX_FLOAT CPDF_Path::GetPointY(int index) const { + return m_Ref.GetObject()->GetPointY(index); +} + +CFX_FloatRect CPDF_Path::GetBoundingBox() const { + return m_Ref.GetObject()->GetBoundingBox(); +} + +CFX_FloatRect CPDF_Path::GetBoundingBox(FX_FLOAT line_width, + FX_FLOAT miter_limit) const { + return m_Ref.GetObject()->GetBoundingBox(line_width, miter_limit); +} + +FX_BOOL CPDF_Path::IsRect() const { + return m_Ref.GetObject()->IsRect(); +} + +void CPDF_Path::Transform(const CFX_Matrix* pMatrix) { + m_Ref.GetPrivateCopy()->Transform(pMatrix); +} + +void CPDF_Path::Append(const CPDF_Path& other, const CFX_Matrix* pMatrix) { + m_Ref.GetPrivateCopy()->Append(other.GetObject(), pMatrix); +} + +void CPDF_Path::Append(const CFX_PathData* pData, const CFX_Matrix* pMatrix) { + m_Ref.GetPrivateCopy()->Append(pData, pMatrix); +} + +void CPDF_Path::AppendRect(FX_FLOAT left, + FX_FLOAT bottom, + FX_FLOAT right, + FX_FLOAT top) { + m_Ref.GetPrivateCopy()->AppendRect(left, bottom, right, top); +} diff --git a/core/fpdfapi/page/cpdf_path.h b/core/fpdfapi/page/cpdf_path.h new file mode 100644 index 0000000000..6322f08ba2 --- /dev/null +++ b/core/fpdfapi/page/cpdf_path.h @@ -0,0 +1,50 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PATH_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PATH_H_ + +#include "core/fxcrt/cfx_count_ref.h" +#include "core/fxcrt/fx_system.h" +#include "core/fxge/cfx_fxgedevice.h" +#include "core/fxge/cfx_pathdata.h" +#include "core/fxge/cfx_renderdevice.h" + +class CPDF_Path { + public: + CPDF_Path(); + CPDF_Path(const CPDF_Path& that); + ~CPDF_Path(); + + void Emplace() { m_Ref.Emplace(); } + explicit operator bool() const { return !!m_Ref; } + + int GetPointCount() const; + void SetPointCount(int count); + const FX_PATHPOINT* GetPoints() const; + FX_PATHPOINT* GetMutablePoints(); + + int GetFlag(int index) const; + FX_FLOAT GetPointX(int index) const; + FX_FLOAT GetPointY(int index) const; + CFX_FloatRect GetBoundingBox() const; + CFX_FloatRect GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const; + + FX_BOOL IsRect() const; + void Transform(const CFX_Matrix* pMatrix); + + void Append(const CPDF_Path& other, const CFX_Matrix* pMatrix); + void Append(const CFX_PathData* pData, const CFX_Matrix* pMatrix); + void AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top); + + // TODO(tsepez): Remove when all access thru this class. + const CFX_PathData* GetObject() const { return m_Ref.GetObject(); } + + private: + CFX_CountRef m_Ref; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PATH_H_ diff --git a/core/fpdfapi/page/cpdf_pathobject.cpp b/core/fpdfapi/page/cpdf_pathobject.cpp new file mode 100644 index 0000000000..a25f7891a6 --- /dev/null +++ b/core/fpdfapi/page/cpdf_pathobject.cpp @@ -0,0 +1,66 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_pathobject.h" + +CPDF_PathObject::CPDF_PathObject() {} + +CPDF_PathObject::~CPDF_PathObject() {} + +CPDF_PathObject* CPDF_PathObject::Clone() const { + CPDF_PathObject* obj = new CPDF_PathObject; + obj->CopyData(this); + + obj->m_Path = m_Path; + obj->m_FillType = m_FillType; + obj->m_bStroke = m_bStroke; + obj->m_Matrix = m_Matrix; + return obj; +} + +CPDF_PageObject::Type CPDF_PathObject::GetType() const { + return PATH; +} + +void CPDF_PathObject::Transform(const CFX_Matrix& matrix) { + m_Matrix.Concat(matrix); + CalcBoundingBox(); +} + +bool CPDF_PathObject::IsPath() const { + return true; +} + +CPDF_PathObject* CPDF_PathObject::AsPath() { + return this; +} + +const CPDF_PathObject* CPDF_PathObject::AsPath() const { + return this; +} + +void CPDF_PathObject::CalcBoundingBox() { + if (!m_Path) + return; + CFX_FloatRect rect; + FX_FLOAT width = m_GraphState.GetLineWidth(); + if (m_bStroke && width != 0) { + rect = m_Path.GetBoundingBox(width, m_GraphState.GetMiterLimit()); + } else { + rect = m_Path.GetBoundingBox(); + } + rect.Transform(&m_Matrix); + if (width == 0 && m_bStroke) { + rect.left += -0.5f; + rect.right += 0.5f; + rect.bottom += -0.5f; + rect.top += 0.5f; + } + m_Left = rect.left; + m_Right = rect.right; + m_Top = rect.top; + m_Bottom = rect.bottom; +} diff --git a/core/fpdfapi/page/cpdf_pathobject.h b/core/fpdfapi/page/cpdf_pathobject.h new file mode 100644 index 0000000000..65578a1bab --- /dev/null +++ b/core/fpdfapi/page/cpdf_pathobject.h @@ -0,0 +1,36 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PATHOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PATHOBJECT_H_ + +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_path.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_PathObject : public CPDF_PageObject { + public: + CPDF_PathObject(); + ~CPDF_PathObject() override; + + // CPDF_PageObject + CPDF_PathObject* Clone() const override; + Type GetType() const override; + void Transform(const CFX_Matrix& maxtrix) override; + bool IsPath() const override; + CPDF_PathObject* AsPath() override; + const CPDF_PathObject* AsPath() const override; + + void CalcBoundingBox(); + + CPDF_Path m_Path; + int m_FillType; + FX_BOOL m_bStroke; + CFX_Matrix m_Matrix; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PATHOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_pattern.cpp b/core/fpdfapi/page/cpdf_pattern.cpp new file mode 100644 index 0000000000..b0a2d81bca --- /dev/null +++ b/core/fpdfapi/page/cpdf_pattern.cpp @@ -0,0 +1,18 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_pattern.h" + +CPDF_Pattern::CPDF_Pattern(PatternType type, + CPDF_Document* pDoc, + CPDF_Object* pObj, + const CFX_Matrix& parentMatrix) + : m_PatternType(type), + m_pDocument(pDoc), + m_pPatternObj(pObj), + m_ParentMatrix(parentMatrix) {} + +CPDF_Pattern::~CPDF_Pattern() {} diff --git a/core/fpdfapi/page/cpdf_pattern.h b/core/fpdfapi/page/cpdf_pattern.h new file mode 100644 index 0000000000..d44965ff16 --- /dev/null +++ b/core/fpdfapi/page/cpdf_pattern.h @@ -0,0 +1,45 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PATTERN_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PATTERN_H_ + +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Document; +class CPDF_Object; +class CPDF_ShadingPattern; +class CPDF_TilingPattern; + +class CPDF_Pattern { + public: + enum PatternType { TILING = 1, SHADING }; + + virtual ~CPDF_Pattern(); + + virtual CPDF_TilingPattern* AsTilingPattern() = 0; + virtual CPDF_ShadingPattern* AsShadingPattern() = 0; + + CPDF_Document* document() { return m_pDocument; } + CPDF_Object* pattern_obj() { return m_pPatternObj; } + CFX_Matrix* pattern_to_form() { return &m_Pattern2Form; } + const CFX_Matrix& parent_matrix() const { return m_ParentMatrix; } + + protected: + CPDF_Pattern(PatternType type, + CPDF_Document* pDoc, + CPDF_Object* pObj, + const CFX_Matrix& parentMatrix); + + const PatternType m_PatternType; + CPDF_Document* const m_pDocument; + CPDF_Object* const m_pPatternObj; + CFX_Matrix m_Pattern2Form; + const CFX_Matrix m_ParentMatrix; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PATTERN_H_ diff --git a/core/fpdfapi/page/cpdf_psengine.h b/core/fpdfapi/page/cpdf_psengine.h new file mode 100644 index 0000000000..d3eec6629c --- /dev/null +++ b/core/fpdfapi/page/cpdf_psengine.h @@ -0,0 +1,101 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_ + +#include +#include + +#include "core/fxcrt/fx_system.h" + +class CPDF_PSEngine; +class CPDF_PSOP; +class CPDF_SimpleParser; + +enum PDF_PSOP { + PSOP_ADD, + PSOP_SUB, + PSOP_MUL, + PSOP_DIV, + PSOP_IDIV, + PSOP_MOD, + PSOP_NEG, + PSOP_ABS, + PSOP_CEILING, + PSOP_FLOOR, + PSOP_ROUND, + PSOP_TRUNCATE, + PSOP_SQRT, + PSOP_SIN, + PSOP_COS, + PSOP_ATAN, + PSOP_EXP, + PSOP_LN, + PSOP_LOG, + PSOP_CVI, + PSOP_CVR, + PSOP_EQ, + PSOP_NE, + PSOP_GT, + PSOP_GE, + PSOP_LT, + PSOP_LE, + PSOP_AND, + PSOP_OR, + PSOP_XOR, + PSOP_NOT, + PSOP_BITSHIFT, + PSOP_TRUE, + PSOP_FALSE, + PSOP_IF, + PSOP_IFELSE, + PSOP_POP, + PSOP_EXCH, + PSOP_DUP, + PSOP_COPY, + PSOP_INDEX, + PSOP_ROLL, + PSOP_PROC, + PSOP_CONST +}; + +constexpr uint32_t PSENGINE_STACKSIZE = 100; + +class CPDF_PSProc { + public: + CPDF_PSProc(); + ~CPDF_PSProc(); + + FX_BOOL Parse(CPDF_SimpleParser* parser, int depth); + FX_BOOL Execute(CPDF_PSEngine* pEngine); + + private: + static const int kMaxDepth = 128; + std::vector> m_Operators; +}; + +class CPDF_PSEngine { + public: + CPDF_PSEngine(); + ~CPDF_PSEngine(); + + FX_BOOL Parse(const FX_CHAR* str, int size); + FX_BOOL Execute(); + FX_BOOL DoOperator(PDF_PSOP op); + void Reset() { m_StackCount = 0; } + void Push(FX_FLOAT value); + void Push(int value) { Push((FX_FLOAT)value); } + FX_FLOAT Pop(); + uint32_t GetStackSize() const { return m_StackCount; } + + private: + FX_FLOAT m_Stack[PSENGINE_STACKSIZE]; + uint32_t m_StackCount; + CPDF_PSProc m_MainProc; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_PSENGINE_H_ diff --git a/core/fpdfapi/page/cpdf_shadingobject.cpp b/core/fpdfapi/page/cpdf_shadingobject.cpp new file mode 100644 index 0000000000..28a154374f --- /dev/null +++ b/core/fpdfapi/page/cpdf_shadingobject.cpp @@ -0,0 +1,69 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_shadingobject.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/page/cpdf_shadingpattern.h" +#include "core/fpdfapi/page/pageint.h" + +CPDF_ShadingObject::CPDF_ShadingObject() : m_pShading(nullptr) {} + +CPDF_ShadingObject::~CPDF_ShadingObject() {} + +CPDF_ShadingObject* CPDF_ShadingObject::Clone() const { + CPDF_ShadingObject* obj = new CPDF_ShadingObject; + obj->CopyData(this); + + obj->m_pShading = m_pShading; + if (obj->m_pShading && obj->m_pShading->document()) { + CPDF_DocPageData* pDocPageData = obj->m_pShading->document()->GetPageData(); + CPDF_Pattern* pattern = pDocPageData->GetPattern( + obj->m_pShading->GetShadingObject(), m_pShading->IsShadingObject(), + obj->m_pShading->parent_matrix()); + obj->m_pShading = pattern ? pattern->AsShadingPattern() : nullptr; + } + obj->m_Matrix = m_Matrix; + return obj; +} + +CPDF_PageObject::Type CPDF_ShadingObject::GetType() const { + return SHADING; +} + +void CPDF_ShadingObject::Transform(const CFX_Matrix& matrix) { + if (m_ClipPath) + m_ClipPath.Transform(matrix); + + m_Matrix.Concat(matrix); + if (m_ClipPath) { + CalcBoundingBox(); + } else { + matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); + } +} + +bool CPDF_ShadingObject::IsShading() const { + return true; +} + +CPDF_ShadingObject* CPDF_ShadingObject::AsShading() { + return this; +} + +const CPDF_ShadingObject* CPDF_ShadingObject::AsShading() const { + return this; +} + +void CPDF_ShadingObject::CalcBoundingBox() { + if (!m_ClipPath) + return; + CFX_FloatRect rect = m_ClipPath.GetClipBox(); + m_Left = rect.left; + m_Bottom = rect.bottom; + m_Right = rect.right; + m_Top = rect.top; +} diff --git a/core/fpdfapi/page/cpdf_shadingobject.h b/core/fpdfapi/page/cpdf_shadingobject.h new file mode 100644 index 0000000000..ed5679a83b --- /dev/null +++ b/core/fpdfapi/page/cpdf_shadingobject.h @@ -0,0 +1,34 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_SHADINGOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_SHADINGOBJECT_H_ + +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fxcrt/fx_coordinates.h" + +class CPDF_ShadingPattern; + +class CPDF_ShadingObject : public CPDF_PageObject { + public: + CPDF_ShadingObject(); + ~CPDF_ShadingObject() override; + + // CPDF_PageObject + CPDF_ShadingObject* Clone() const override; + Type GetType() const override; + void Transform(const CFX_Matrix& matrix) override; + bool IsShading() const override; + CPDF_ShadingObject* AsShading() override; + const CPDF_ShadingObject* AsShading() const override; + + void CalcBoundingBox(); + + CPDF_ShadingPattern* m_pShading; + CFX_Matrix m_Matrix; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_SHADINGOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_shadingpattern.cpp b/core/fpdfapi/page/cpdf_shadingpattern.cpp new file mode 100644 index 0000000000..5b52e84fb7 --- /dev/null +++ b/core/fpdfapi/page/cpdf_shadingpattern.cpp @@ -0,0 +1,97 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_shadingpattern.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_object.h" +#include "core/fpdfapi/page/pageint.h" + +namespace { + +ShadingType ToShadingType(int type) { + return (type > static_cast(kInvalidShading) && + type < static_cast(kMaxShading)) + ? static_cast(type) + : kInvalidShading; +} + +} // namespace + +CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc, + CPDF_Object* pPatternObj, + FX_BOOL bShading, + const CFX_Matrix& parentMatrix) + : CPDF_Pattern(SHADING, + pDoc, + bShading ? nullptr : pPatternObj, + parentMatrix), + m_ShadingType(kInvalidShading), + m_bShadingObj(bShading), + m_pShadingObj(pPatternObj), + m_pCS(nullptr), + m_pCountedCS(nullptr) { + if (!bShading) { + CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); + m_Pattern2Form = pDict->GetMatrixFor("Matrix"); + m_pShadingObj = pDict->GetDirectObjectFor("Shading"); + m_Pattern2Form.Concat(parentMatrix); + } +} + +CPDF_ShadingPattern::~CPDF_ShadingPattern() { + CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->get() : nullptr; + if (pCS && m_pDocument) + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); +} + +CPDF_TilingPattern* CPDF_ShadingPattern::AsTilingPattern() { + return nullptr; +} + +CPDF_ShadingPattern* CPDF_ShadingPattern::AsShadingPattern() { + return this; +} + +bool CPDF_ShadingPattern::Load() { + if (m_ShadingType != kInvalidShading) + return TRUE; + + CPDF_Dictionary* pShadingDict = + m_pShadingObj ? m_pShadingObj->GetDict() : nullptr; + if (!pShadingDict) + return FALSE; + + m_pFunctions.clear(); + CPDF_Object* pFunc = pShadingDict->GetDirectObjectFor("Function"); + if (pFunc) { + if (CPDF_Array* pArray = pFunc->AsArray()) { + m_pFunctions.resize(std::min(pArray->GetCount(), 4)); + for (size_t i = 0; i < m_pFunctions.size(); ++i) + m_pFunctions[i] = CPDF_Function::Load(pArray->GetDirectObjectAt(i)); + } else { + m_pFunctions.push_back(CPDF_Function::Load(pFunc)); + } + } + CPDF_Object* pCSObj = pShadingDict->GetDirectObjectFor("ColorSpace"); + if (!pCSObj) + return FALSE; + + CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); + m_pCS = pDocPageData->GetColorSpace(pCSObj, nullptr); + if (m_pCS) + m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray()); + + m_ShadingType = ToShadingType(pShadingDict->GetIntegerFor("ShadingType")); + + // We expect to have a stream if our shading type is a mesh. + if (IsMeshShading() && !ToStream(m_pShadingObj)) + return FALSE; + + return TRUE; +} diff --git a/core/fpdfapi/page/cpdf_shadingpattern.h b/core/fpdfapi/page/cpdf_shadingpattern.h new file mode 100644 index 0000000000..6f5978f8a5 --- /dev/null +++ b/core/fpdfapi/page/cpdf_shadingpattern.h @@ -0,0 +1,75 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_SHADINGPATTERN_H_ +#define CORE_FPDFAPI_PAGE_CPDF_SHADINGPATTERN_H_ + +#include +#include + +#include "core/fpdfapi/page/cpdf_countedobject.h" +#include "core/fpdfapi/page/cpdf_pattern.h" +#include "core/fxcrt/fx_system.h" + +enum ShadingType { + kInvalidShading = 0, + kFunctionBasedShading = 1, + kAxialShading = 2, + kRadialShading = 3, + kFreeFormGouraudTriangleMeshShading = 4, + kLatticeFormGouraudTriangleMeshShading = 5, + kCoonsPatchMeshShading = 6, + kTensorProductPatchMeshShading = 7, + kMaxShading = 8 +}; + +class CFX_Matrix; +class CPDF_ColorSpace; +class CPDF_Document; +class CPDF_Function; +class CPDF_Object; + +class CPDF_ShadingPattern : public CPDF_Pattern { + public: + CPDF_ShadingPattern(CPDF_Document* pDoc, + CPDF_Object* pPatternObj, + FX_BOOL bShading, + const CFX_Matrix& parentMatrix); + ~CPDF_ShadingPattern() override; + + CPDF_TilingPattern* AsTilingPattern() override; + CPDF_ShadingPattern* AsShadingPattern() override; + + bool IsMeshShading() const { + return m_ShadingType == kFreeFormGouraudTriangleMeshShading || + m_ShadingType == kLatticeFormGouraudTriangleMeshShading || + m_ShadingType == kCoonsPatchMeshShading || + m_ShadingType == kTensorProductPatchMeshShading; + } + bool Load(); + + ShadingType GetShadingType() const { return m_ShadingType; } + FX_BOOL IsShadingObject() const { return m_bShadingObj; } + CPDF_Object* GetShadingObject() const { return m_pShadingObj; } + CPDF_ColorSpace* GetCS() const { return m_pCS; } + const std::vector>& GetFuncs() const { + return m_pFunctions; + } + + private: + ShadingType m_ShadingType; + FX_BOOL m_bShadingObj; + CPDF_Object* m_pShadingObj; + + // Still keep |m_pCS| as some CPDF_ColorSpace (name object) are not managed + // as counted objects. Refer to CPDF_DocPageData::GetColorSpace. + CPDF_ColorSpace* m_pCS; + + CPDF_CountedColorSpace* m_pCountedCS; + std::vector> m_pFunctions; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_SHADINGPATTERN_H_ diff --git a/core/fpdfapi/page/cpdf_textobject.cpp b/core/fpdfapi/page/cpdf_textobject.cpp new file mode 100644 index 0000000000..0b44522835 --- /dev/null +++ b/core/fpdfapi/page/cpdf_textobject.cpp @@ -0,0 +1,388 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_textobject.h" + +#include "core/fpdfapi/font/cpdf_cidfont.h" +#include "core/fpdfapi/font/cpdf_font.h" + +CPDF_TextObject::CPDF_TextObject() + : m_PosX(0), + m_PosY(0), + m_nChars(0), + m_pCharCodes(nullptr), + m_pCharPos(nullptr) {} + +CPDF_TextObject::~CPDF_TextObject() { + if (m_nChars > 1) { + FX_Free(m_pCharCodes); + } + FX_Free(m_pCharPos); +} + +int CPDF_TextObject::CountItems() const { + return m_nChars; +} + +void CPDF_TextObject::GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const { + pInfo->m_CharCode = + m_nChars == 1 ? (uint32_t)(uintptr_t)m_pCharCodes : m_pCharCodes[index]; + pInfo->m_OriginX = index ? m_pCharPos[index - 1] : 0; + pInfo->m_OriginY = 0; + if (pInfo->m_CharCode == CPDF_Font::kInvalidCharCode) { + return; + } + CPDF_Font* pFont = m_TextState.GetFont(); + if (!pFont->IsCIDFont()) { + return; + } + if (!pFont->AsCIDFont()->IsVertWriting()) { + return; + } + uint16_t CID = pFont->AsCIDFont()->CIDFromCharCode(pInfo->m_CharCode); + pInfo->m_OriginY = pInfo->m_OriginX; + pInfo->m_OriginX = 0; + short vx, vy; + pFont->AsCIDFont()->GetVertOrigin(CID, vx, vy); + FX_FLOAT fontsize = m_TextState.GetFontSize(); + pInfo->m_OriginX -= fontsize * vx / 1000; + pInfo->m_OriginY -= fontsize * vy / 1000; +} + +int CPDF_TextObject::CountChars() const { + if (m_nChars == 1) { + return 1; + } + int count = 0; + for (int i = 0; i < m_nChars; ++i) + if (m_pCharCodes[i] != CPDF_Font::kInvalidCharCode) { + ++count; + } + return count; +} + +void CPDF_TextObject::GetCharInfo(int index, + uint32_t& charcode, + FX_FLOAT& kerning) const { + if (m_nChars == 1) { + charcode = (uint32_t)(uintptr_t)m_pCharCodes; + kerning = 0; + return; + } + int count = 0; + for (int i = 0; i < m_nChars; ++i) { + if (m_pCharCodes[i] != CPDF_Font::kInvalidCharCode) { + if (count == index) { + charcode = m_pCharCodes[i]; + if (i == m_nChars - 1 || + m_pCharCodes[i + 1] != CPDF_Font::kInvalidCharCode) { + kerning = 0; + } else { + kerning = m_pCharPos[i]; + } + return; + } + ++count; + } + } +} + +void CPDF_TextObject::GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const { + if (m_nChars == 1) { + GetItemInfo(0, pInfo); + return; + } + int count = 0; + for (int i = 0; i < m_nChars; ++i) { + uint32_t charcode = m_pCharCodes[i]; + if (charcode == CPDF_Font::kInvalidCharCode) { + continue; + } + if (count == index) { + GetItemInfo(i, pInfo); + break; + } + ++count; + } +} + +CPDF_TextObject* CPDF_TextObject::Clone() const { + CPDF_TextObject* obj = new CPDF_TextObject; + obj->CopyData(this); + + obj->m_nChars = m_nChars; + if (m_nChars > 1) { + obj->m_pCharCodes = FX_Alloc(uint32_t, m_nChars); + FXSYS_memcpy(obj->m_pCharCodes, m_pCharCodes, m_nChars * sizeof(uint32_t)); + obj->m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); + FXSYS_memcpy(obj->m_pCharPos, m_pCharPos, + (m_nChars - 1) * sizeof(FX_FLOAT)); + } else { + obj->m_pCharCodes = m_pCharCodes; + } + obj->m_PosX = m_PosX; + obj->m_PosY = m_PosY; + return obj; +} + +CPDF_PageObject::Type CPDF_TextObject::GetType() const { + return TEXT; +} + +void CPDF_TextObject::Transform(const CFX_Matrix& matrix) { + CFX_Matrix text_matrix; + GetTextMatrix(&text_matrix); + text_matrix.Concat(matrix); + + FX_FLOAT* pTextMatrix = m_TextState.GetMutableMatrix(); + pTextMatrix[0] = text_matrix.GetA(); + pTextMatrix[1] = text_matrix.GetC(); + pTextMatrix[2] = text_matrix.GetB(); + pTextMatrix[3] = text_matrix.GetD(); + m_PosX = text_matrix.GetE(); + m_PosY = text_matrix.GetF(); + CalcPositionData(nullptr, nullptr, 0); +} + +bool CPDF_TextObject::IsText() const { + return true; +} + +CPDF_TextObject* CPDF_TextObject::AsText() { + return this; +} + +const CPDF_TextObject* CPDF_TextObject::AsText() const { + return this; +} + +void CPDF_TextObject::GetTextMatrix(CFX_Matrix* pMatrix) const { + const FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); + pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], + m_PosX, m_PosY); +} + +void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, + FX_FLOAT* pKerning, + int nsegs) { + if (m_nChars > 1) { + FX_Free(m_pCharCodes); + m_pCharCodes = nullptr; + } + FX_Free(m_pCharPos); + m_pCharPos = nullptr; + CPDF_Font* pFont = m_TextState.GetFont(); + m_nChars = 0; + for (int i = 0; i < nsegs; ++i) { + m_nChars += pFont->CountChar(pStrs[i].c_str(), pStrs[i].GetLength()); + } + m_nChars += nsegs - 1; + if (m_nChars > 1) { + m_pCharCodes = FX_Alloc(uint32_t, m_nChars); + m_pCharPos = FX_Alloc(FX_FLOAT, m_nChars - 1); + int index = 0; + for (int i = 0; i < nsegs; ++i) { + const FX_CHAR* segment = pStrs[i].c_str(); + int len = pStrs[i].GetLength(); + int offset = 0; + while (offset < len) { + m_pCharCodes[index++] = pFont->GetNextChar(segment, len, offset); + } + if (i != nsegs - 1) { + m_pCharPos[index - 1] = pKerning[i]; + m_pCharCodes[index++] = CPDF_Font::kInvalidCharCode; + } + } + } else { + int offset = 0; + m_pCharCodes = (uint32_t*)(uintptr_t)pFont->GetNextChar( + pStrs[0].c_str(), pStrs[0].GetLength(), offset); + } +} + +void CPDF_TextObject::SetText(const CFX_ByteString& str) { + SetSegments(&str, nullptr, 1); + RecalcPositionData(); +} + +FX_FLOAT CPDF_TextObject::GetCharWidth(uint32_t charcode) const { + FX_FLOAT fontsize = m_TextState.GetFontSize() / 1000; + CPDF_Font* pFont = m_TextState.GetFont(); + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + if (!bVertWriting) + return pFont->GetCharWidthF(charcode) * fontsize; + + uint16_t CID = pCIDFont->CIDFromCharCode(charcode); + return pCIDFont->GetVertWidth(CID) * fontsize; +} + +FX_FLOAT CPDF_TextObject::GetPosX() const { + return m_PosX; +} + +FX_FLOAT CPDF_TextObject::GetPosY() const { + return m_PosY; +} + +CPDF_Font* CPDF_TextObject::GetFont() const { + return m_TextState.GetFont(); +} + +FX_FLOAT CPDF_TextObject::GetFontSize() const { + return m_TextState.GetFontSize(); +} + +void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, + FX_FLOAT* pTextAdvanceY, + FX_FLOAT horz_scale) { + FX_FLOAT curpos = 0; + FX_FLOAT min_x = 10000 * 1.0f; + FX_FLOAT max_x = -10000 * 1.0f; + FX_FLOAT min_y = 10000 * 1.0f; + FX_FLOAT max_y = -10000 * 1.0f; + CPDF_Font* pFont = m_TextState.GetFont(); + FX_BOOL bVertWriting = FALSE; + CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); + if (pCIDFont) { + bVertWriting = pCIDFont->IsVertWriting(); + } + FX_FLOAT fontsize = m_TextState.GetFontSize(); + for (int i = 0; i < m_nChars; ++i) { + uint32_t charcode = + m_nChars == 1 ? (uint32_t)(uintptr_t)m_pCharCodes : m_pCharCodes[i]; + if (i > 0) { + if (charcode == CPDF_Font::kInvalidCharCode) { + curpos -= (m_pCharPos[i - 1] * fontsize) / 1000; + continue; + } + m_pCharPos[i - 1] = curpos; + } + FX_RECT char_rect = pFont->GetCharBBox(charcode); + FX_FLOAT charwidth; + if (!bVertWriting) { + if (min_y > char_rect.top) { + min_y = (FX_FLOAT)char_rect.top; + } + if (max_y < char_rect.top) { + max_y = (FX_FLOAT)char_rect.top; + } + if (min_y > char_rect.bottom) { + min_y = (FX_FLOAT)char_rect.bottom; + } + if (max_y < char_rect.bottom) { + max_y = (FX_FLOAT)char_rect.bottom; + } + FX_FLOAT char_left = curpos + char_rect.left * fontsize / 1000; + FX_FLOAT char_right = curpos + char_rect.right * fontsize / 1000; + if (min_x > char_left) { + min_x = char_left; + } + if (max_x < char_left) { + max_x = char_left; + } + if (min_x > char_right) { + min_x = char_right; + } + if (max_x < char_right) { + max_x = char_right; + } + charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; + } else { + uint16_t CID = pCIDFont->CIDFromCharCode(charcode); + short vx; + short vy; + pCIDFont->GetVertOrigin(CID, vx, vy); + char_rect.left -= vx; + char_rect.right -= vx; + char_rect.top -= vy; + char_rect.bottom -= vy; + if (min_x > char_rect.left) { + min_x = (FX_FLOAT)char_rect.left; + } + if (max_x < char_rect.left) { + max_x = (FX_FLOAT)char_rect.left; + } + if (min_x > char_rect.right) { + min_x = (FX_FLOAT)char_rect.right; + } + if (max_x < char_rect.right) { + max_x = (FX_FLOAT)char_rect.right; + } + FX_FLOAT char_top = curpos + char_rect.top * fontsize / 1000; + FX_FLOAT char_bottom = curpos + char_rect.bottom * fontsize / 1000; + if (min_y > char_top) { + min_y = char_top; + } + if (max_y < char_top) { + max_y = char_top; + } + if (min_y > char_bottom) { + min_y = char_bottom; + } + if (max_y < char_bottom) { + max_y = char_bottom; + } + charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; + } + curpos += charwidth; + if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) { + curpos += m_TextState.GetWordSpace(); + } + curpos += m_TextState.GetCharSpace(); + } + if (bVertWriting) { + if (pTextAdvanceX) { + *pTextAdvanceX = 0; + } + if (pTextAdvanceY) { + *pTextAdvanceY = curpos; + } + min_x = min_x * fontsize / 1000; + max_x = max_x * fontsize / 1000; + } else { + if (pTextAdvanceX) { + *pTextAdvanceX = curpos * horz_scale; + } + if (pTextAdvanceY) { + *pTextAdvanceY = 0; + } + min_y = min_y * fontsize / 1000; + max_y = max_y * fontsize / 1000; + } + CFX_Matrix matrix; + GetTextMatrix(&matrix); + m_Left = min_x; + m_Right = max_x; + m_Bottom = min_y; + m_Top = max_y; + matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); + if (TextRenderingModeIsStrokeMode(m_TextState.GetTextMode())) { + FX_FLOAT half_width = m_GraphState.GetLineWidth() / 2; + m_Left -= half_width; + m_Right += half_width; + m_Top += half_width; + m_Bottom -= half_width; + } +} + +void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) { + FX_FLOAT dx = x - m_PosX; + FX_FLOAT dy = y - m_PosY; + m_PosX = x; + m_PosY = y; + m_Left += dx; + m_Right += dx; + m_Top += dy; + m_Bottom += dy; +} + +void CPDF_TextObject::RecalcPositionData() { + CalcPositionData(nullptr, nullptr, 1); +} diff --git a/core/fpdfapi/page/cpdf_textobject.h b/core/fpdfapi/page/cpdf_textobject.h new file mode 100644 index 0000000000..23da997aeb --- /dev/null +++ b/core/fpdfapi/page/cpdf_textobject.h @@ -0,0 +1,68 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_TEXTOBJECT_H_ +#define CORE_FPDFAPI_PAGE_CPDF_TEXTOBJECT_H_ + +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/fx_system.h" + +struct CPDF_TextObjectItem { + uint32_t m_CharCode; + FX_FLOAT m_OriginX; + FX_FLOAT m_OriginY; +}; + +class CPDF_TextObject : public CPDF_PageObject { + public: + CPDF_TextObject(); + ~CPDF_TextObject() override; + + // CPDF_PageObject + CPDF_TextObject* Clone() const override; + Type GetType() const override; + void Transform(const CFX_Matrix& matrix) override; + bool IsText() const override; + CPDF_TextObject* AsText() override; + const CPDF_TextObject* AsText() const override; + + int CountItems() const; + void GetItemInfo(int index, CPDF_TextObjectItem* pInfo) const; + int CountChars() const; + void GetCharInfo(int index, uint32_t& charcode, FX_FLOAT& kerning) const; + void GetCharInfo(int index, CPDF_TextObjectItem* pInfo) const; + FX_FLOAT GetCharWidth(uint32_t charcode) const; + FX_FLOAT GetPosX() const; + FX_FLOAT GetPosY() const; + void GetTextMatrix(CFX_Matrix* pMatrix) const; + CPDF_Font* GetFont() const; + FX_FLOAT GetFontSize() const; + + void SetText(const CFX_ByteString& text); + void SetPosition(FX_FLOAT x, FX_FLOAT y); + + void RecalcPositionData(); + + protected: + friend class CPDF_RenderStatus; + friend class CPDF_StreamContentParser; + friend class CPDF_TextRenderer; + + void SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs); + + void CalcPositionData(FX_FLOAT* pTextAdvanceX, + FX_FLOAT* pTextAdvanceY, + FX_FLOAT horz_scale); + + FX_FLOAT m_PosX; + FX_FLOAT m_PosY; + int m_nChars; + uint32_t* m_pCharCodes; + FX_FLOAT* m_pCharPos; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_TEXTOBJECT_H_ diff --git a/core/fpdfapi/page/cpdf_textstate.cpp b/core/fpdfapi/page/cpdf_textstate.cpp new file mode 100644 index 0000000000..ef19b87ae2 --- /dev/null +++ b/core/fpdfapi/page/cpdf_textstate.cpp @@ -0,0 +1,187 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_textstate.h" + +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/page/pageint.h" + +CPDF_TextState::CPDF_TextState() {} +CPDF_TextState::~CPDF_TextState() {} + +void CPDF_TextState::Emplace() { + m_Ref.Emplace(); +} + +CPDF_Font* CPDF_TextState::GetFont() const { + return m_Ref.GetObject()->m_pFont; +} + +void CPDF_TextState::SetFont(CPDF_Font* pFont) { + m_Ref.GetPrivateCopy()->SetFont(pFont); +} + +FX_FLOAT CPDF_TextState::GetFontSize() const { + return m_Ref.GetObject()->m_FontSize; +} + +void CPDF_TextState::SetFontSize(FX_FLOAT size) { + m_Ref.GetPrivateCopy()->m_FontSize = size; +} + +const FX_FLOAT* CPDF_TextState::GetMatrix() const { + return m_Ref.GetObject()->m_Matrix; +} + +FX_FLOAT* CPDF_TextState::GetMutableMatrix() { + return m_Ref.GetPrivateCopy()->m_Matrix; +} + +FX_FLOAT CPDF_TextState::GetCharSpace() const { + return m_Ref.GetObject()->m_CharSpace; +} + +void CPDF_TextState::SetCharSpace(FX_FLOAT sp) { + m_Ref.GetPrivateCopy()->m_CharSpace = sp; +} + +FX_FLOAT CPDF_TextState::GetWordSpace() const { + return m_Ref.GetObject()->m_WordSpace; +} + +void CPDF_TextState::SetWordSpace(FX_FLOAT sp) { + m_Ref.GetPrivateCopy()->m_WordSpace = sp; +} + +FX_FLOAT CPDF_TextState::GetFontSizeV() const { + return m_Ref.GetObject()->GetFontSizeV(); +} + +FX_FLOAT CPDF_TextState::GetFontSizeH() const { + return m_Ref.GetObject()->GetFontSizeH(); +} + +FX_FLOAT CPDF_TextState::GetBaselineAngle() const { + return m_Ref.GetObject()->GetBaselineAngle(); +} + +FX_FLOAT CPDF_TextState::GetShearAngle() const { + return m_Ref.GetObject()->GetShearAngle(); +} + +TextRenderingMode CPDF_TextState::GetTextMode() const { + return m_Ref.GetObject()->m_TextMode; +} + +void CPDF_TextState::SetTextMode(TextRenderingMode mode) { + m_Ref.GetPrivateCopy()->m_TextMode = mode; +} + +const FX_FLOAT* CPDF_TextState::GetCTM() const { + return m_Ref.GetObject()->m_CTM; +} + +FX_FLOAT* CPDF_TextState::GetMutableCTM() { + return m_Ref.GetPrivateCopy()->m_CTM; +} + +CPDF_TextState::TextData::TextData() + : m_pFont(nullptr), + m_pDocument(nullptr), + m_FontSize(1.0f), + m_CharSpace(0), + m_WordSpace(0), + m_TextMode(TextRenderingMode::MODE_FILL) { + m_Matrix[0] = m_Matrix[3] = 1.0f; + m_Matrix[1] = m_Matrix[2] = 0; + m_CTM[0] = m_CTM[3] = 1.0f; + m_CTM[1] = m_CTM[2] = 0; +} + +CPDF_TextState::TextData::TextData(const TextData& that) + : m_pFont(that.m_pFont), + m_pDocument(that.m_pDocument), + m_FontSize(that.m_FontSize), + m_CharSpace(that.m_CharSpace), + m_WordSpace(that.m_WordSpace), + m_TextMode(that.m_TextMode) { + for (int i = 0; i < 4; ++i) + m_Matrix[i] = that.m_Matrix[i]; + + for (int i = 0; i < 4; ++i) + m_CTM[i] = that.m_CTM[i]; + + if (m_pDocument && m_pFont) { + m_pFont = + m_pDocument->GetPageData()->GetFont(m_pFont->GetFontDict(), FALSE); + } +} + +CPDF_TextState::TextData::~TextData() { + if (m_pDocument && m_pFont) { + CPDF_DocPageData* pPageData = m_pDocument->GetPageData(); + if (pPageData && !pPageData->IsForceClear()) + pPageData->ReleaseFont(m_pFont->GetFontDict()); + } +} + +void CPDF_TextState::TextData::SetFont(CPDF_Font* pFont) { + CPDF_Document* pDoc = m_pDocument; + CPDF_DocPageData* pPageData = pDoc ? pDoc->GetPageData() : nullptr; + if (pPageData && m_pFont && !pPageData->IsForceClear()) + pPageData->ReleaseFont(m_pFont->GetFontDict()); + + m_pDocument = pFont ? pFont->m_pDocument : nullptr; + m_pFont = pFont; +} + +FX_FLOAT CPDF_TextState::TextData::GetFontSizeV() const { + return FXSYS_fabs(FXSYS_sqrt2(m_Matrix[1], m_Matrix[3]) * m_FontSize); +} + +FX_FLOAT CPDF_TextState::TextData::GetFontSizeH() const { + return FXSYS_fabs(FXSYS_sqrt2(m_Matrix[0], m_Matrix[2]) * m_FontSize); +} + +FX_FLOAT CPDF_TextState::TextData::GetBaselineAngle() const { + return FXSYS_atan2(m_Matrix[2], m_Matrix[0]); +} + +FX_FLOAT CPDF_TextState::TextData::GetShearAngle() const { + return GetBaselineAngle() + FXSYS_atan2(m_Matrix[1], m_Matrix[3]); +} + +bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode) { + if (iMode < 0 || iMode > 7) + return false; + *mode = static_cast(iMode); + return true; +} + +bool TextRenderingModeIsClipMode(const TextRenderingMode& mode) { + switch (mode) { + case TextRenderingMode::MODE_FILL_CLIP: + case TextRenderingMode::MODE_STROKE_CLIP: + case TextRenderingMode::MODE_FILL_STROKE_CLIP: + case TextRenderingMode::MODE_CLIP: + return true; + default: + return false; + } +} + +bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode) { + switch (mode) { + case TextRenderingMode::MODE_STROKE: + case TextRenderingMode::MODE_FILL_STROKE: + case TextRenderingMode::MODE_STROKE_CLIP: + case TextRenderingMode::MODE_FILL_STROKE_CLIP: + return true; + default: + return false; + } +} diff --git a/core/fpdfapi/page/cpdf_textstate.h b/core/fpdfapi/page/cpdf_textstate.h new file mode 100644 index 0000000000..e76e376c3b --- /dev/null +++ b/core/fpdfapi/page/cpdf_textstate.h @@ -0,0 +1,91 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_TEXTSTATE_H_ +#define CORE_FPDFAPI_PAGE_CPDF_TEXTSTATE_H_ + +#include "core/fxcrt/cfx_count_ref.h" +#include "core/fxcrt/fx_basic.h" + +class CPDF_Document; +class CPDF_Font; + +// See PDF Reference 1.7, page 402, table 5.3. +enum class TextRenderingMode { + MODE_FILL = 0, + MODE_STROKE = 1, + MODE_FILL_STROKE = 2, + MODE_INVISIBLE = 3, + MODE_FILL_CLIP = 4, + MODE_STROKE_CLIP = 5, + MODE_FILL_STROKE_CLIP = 6, + MODE_CLIP = 7, +}; + +class CPDF_TextState { + public: + CPDF_TextState(); + ~CPDF_TextState(); + + void Emplace(); + + CPDF_Font* GetFont() const; + void SetFont(CPDF_Font* pFont); + + FX_FLOAT GetFontSize() const; + void SetFontSize(FX_FLOAT size); + + const FX_FLOAT* GetMatrix() const; + FX_FLOAT* GetMutableMatrix(); + + FX_FLOAT GetCharSpace() const; + void SetCharSpace(FX_FLOAT sp); + + FX_FLOAT GetWordSpace() const; + void SetWordSpace(FX_FLOAT sp); + + FX_FLOAT GetFontSizeV() const; + FX_FLOAT GetFontSizeH() const; + FX_FLOAT GetBaselineAngle() const; + FX_FLOAT GetShearAngle() const; + + TextRenderingMode GetTextMode() const; + void SetTextMode(TextRenderingMode mode); + + const FX_FLOAT* GetCTM() const; + FX_FLOAT* GetMutableCTM(); + + private: + class TextData { + public: + TextData(); + TextData(const TextData& src); + ~TextData(); + + void SetFont(CPDF_Font* pFont); + FX_FLOAT GetFontSizeV() const; + FX_FLOAT GetFontSizeH() const; + FX_FLOAT GetBaselineAngle() const; + FX_FLOAT GetShearAngle() const; + + CPDF_Font* m_pFont; + CPDF_Document* m_pDocument; + FX_FLOAT m_FontSize; + FX_FLOAT m_CharSpace; + FX_FLOAT m_WordSpace; + TextRenderingMode m_TextMode; + FX_FLOAT m_Matrix[4]; + FX_FLOAT m_CTM[4]; + }; + + CFX_CountRef m_Ref; +}; + +bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode); +bool TextRenderingModeIsClipMode(const TextRenderingMode& mode); +bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode); + +#endif // CORE_FPDFAPI_PAGE_CPDF_TEXTSTATE_H_ diff --git a/core/fpdfapi/page/cpdf_tilingpattern.cpp b/core/fpdfapi/page/cpdf_tilingpattern.cpp new file mode 100644 index 0000000000..1ddc3c6ebc --- /dev/null +++ b/core/fpdfapi/page/cpdf_tilingpattern.cpp @@ -0,0 +1,54 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/cpdf_tilingpattern.h" + +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_object.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/page/cpdf_form.h" + +CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc, + CPDF_Object* pPatternObj, + const CFX_Matrix& parentMatrix) + : CPDF_Pattern(TILING, pDoc, pPatternObj, parentMatrix) { + CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); + m_Pattern2Form = pDict->GetMatrixFor("Matrix"); + m_bColored = pDict->GetIntegerFor("PaintType") == 1; + m_Pattern2Form.Concat(parentMatrix); +} + +CPDF_TilingPattern::~CPDF_TilingPattern() {} + +CPDF_TilingPattern* CPDF_TilingPattern::AsTilingPattern() { + return this; +} + +CPDF_ShadingPattern* CPDF_TilingPattern::AsShadingPattern() { + return nullptr; +} + +FX_BOOL CPDF_TilingPattern::Load() { + if (m_pForm) + return TRUE; + + CPDF_Dictionary* pDict = m_pPatternObj->GetDict(); + if (!pDict) + return FALSE; + + m_bColored = pDict->GetIntegerFor("PaintType") == 1; + m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberFor("XStep")); + m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberFor("YStep")); + + CPDF_Stream* pStream = m_pPatternObj->AsStream(); + if (!pStream) + return FALSE; + + m_pForm.reset(new CPDF_Form(m_pDocument, nullptr, pStream)); + m_pForm->ParseContent(nullptr, &m_ParentMatrix, nullptr); + m_BBox = pDict->GetRectFor("BBox"); + return TRUE; +} diff --git a/core/fpdfapi/page/cpdf_tilingpattern.h b/core/fpdfapi/page/cpdf_tilingpattern.h new file mode 100644 index 0000000000..3c9ffb206d --- /dev/null +++ b/core/fpdfapi/page/cpdf_tilingpattern.h @@ -0,0 +1,46 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_CPDF_TILINGPATTERN_H_ +#define CORE_FPDFAPI_PAGE_CPDF_TILINGPATTERN_H_ + +#include + +#include "core/fpdfapi/page/cpdf_pattern.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CPDF_Document; +class CPDF_Form; +class CPDF_Object; + +class CPDF_TilingPattern : public CPDF_Pattern { + public: + CPDF_TilingPattern(CPDF_Document* pDoc, + CPDF_Object* pPatternObj, + const CFX_Matrix& parentMatrix); + ~CPDF_TilingPattern() override; + + CPDF_TilingPattern* AsTilingPattern() override; + CPDF_ShadingPattern* AsShadingPattern() override; + + FX_BOOL Load(); + + bool colored() const { return m_bColored; } + const CFX_FloatRect& bbox() const { return m_BBox; } + FX_FLOAT x_step() const { return m_XStep; } + FX_FLOAT y_step() const { return m_YStep; } + CPDF_Form* form() const { return m_pForm.get(); } + + private: + bool m_bColored; + CFX_FloatRect m_BBox; + FX_FLOAT m_XStep; + FX_FLOAT m_YStep; + std::unique_ptr m_pForm; +}; + +#endif // CORE_FPDFAPI_PAGE_CPDF_TILINGPATTERN_H_ diff --git a/core/fpdfapi/page/fpdf_page_colors.cpp b/core/fpdfapi/page/fpdf_page_colors.cpp new file mode 100644 index 0000000000..d6500b716b --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_colors.cpp @@ -0,0 +1,234 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/pageint.h" + +#include + +#include + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/fpdf_parser/cpdf_string.h" +#include "core/fxcodec/fx_codec.h" + +namespace { + +uint32_t ComponentsForFamily(int family) { + if (family == PDFCS_DEVICERGB) + return 3; + if (family == PDFCS_DEVICEGRAY) + return 1; + return 4; +} + +} // namespace + +void sRGB_to_AdobeCMYK(FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) { + c = 1.0f - R; + m = 1.0f - G; + y = 1.0f - B; + k = c; + if (m < k) { + k = m; + } + if (y < k) { + k = y; + } +} + +void ReverseRGB(uint8_t* pDestBuf, const uint8_t* pSrcBuf, int pixels) { + if (pDestBuf == pSrcBuf) { + for (int i = 0; i < pixels; i++) { + uint8_t temp = pDestBuf[2]; + pDestBuf[2] = pDestBuf[0]; + pDestBuf[0] = temp; + pDestBuf += 3; + } + } else { + for (int i = 0; i < pixels; i++) { + *pDestBuf++ = pSrcBuf[2]; + *pDestBuf++ = pSrcBuf[1]; + *pDestBuf++ = pSrcBuf[0]; + pSrcBuf += 3; + } + } +} + +CPDF_DeviceCS::CPDF_DeviceCS(CPDF_Document* pDoc, int family) + : CPDF_ColorSpace(pDoc, family, ComponentsForFamily(family)) {} + +FX_BOOL CPDF_DeviceCS::GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const { + if (m_Family == PDFCS_DEVICERGB) { + R = pBuf[0]; + if (R < 0) { + R = 0; + } else if (R > 1) { + R = 1; + } + G = pBuf[1]; + if (G < 0) { + G = 0; + } else if (G > 1) { + G = 1; + } + B = pBuf[2]; + if (B < 0) { + B = 0; + } else if (B > 1) { + B = 1; + } + } else if (m_Family == PDFCS_DEVICEGRAY) { + R = *pBuf; + if (R < 0) { + R = 0; + } else if (R > 1) { + R = 1; + } + G = B = R; + } else if (m_Family == PDFCS_DEVICECMYK) { + if (!m_dwStdConversion) { + AdobeCMYK_to_sRGB(pBuf[0], pBuf[1], pBuf[2], pBuf[3], R, G, B); + } else { + FX_FLOAT k = pBuf[3]; + R = 1.0f - std::min(1.0f, pBuf[0] + k); + G = 1.0f - std::min(1.0f, pBuf[1] + k); + B = 1.0f - std::min(1.0f, pBuf[2] + k); + } + } else { + ASSERT(m_Family == PDFCS_PATTERN); + R = G = B = 0; + return FALSE; + } + return TRUE; +} +FX_BOOL CPDF_DeviceCS::v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const { + if (m_Family != PDFCS_DEVICECMYK) { + return FALSE; + } + c = pBuf[0]; + m = pBuf[1]; + y = pBuf[2]; + k = pBuf[3]; + return TRUE; +} +FX_BOOL CPDF_DeviceCS::SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const { + if (m_Family == PDFCS_DEVICERGB) { + pBuf[0] = R; + pBuf[1] = G; + pBuf[2] = B; + return TRUE; + } + if (m_Family == PDFCS_DEVICEGRAY) { + if (R == G && R == B) { + *pBuf = R; + return TRUE; + } + return FALSE; + } + if (m_Family == PDFCS_DEVICECMYK) { + sRGB_to_AdobeCMYK(R, G, B, pBuf[0], pBuf[1], pBuf[2], pBuf[3]); + return TRUE; + } + return FALSE; +} +FX_BOOL CPDF_DeviceCS::v_SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const { + if (m_Family == PDFCS_DEVICERGB) { + AdobeCMYK_to_sRGB(c, m, y, k, pBuf[0], pBuf[1], pBuf[2]); + return TRUE; + } + if (m_Family == PDFCS_DEVICECMYK) { + pBuf[0] = c; + pBuf[1] = m; + pBuf[2] = y; + pBuf[3] = k; + return TRUE; + } + return FALSE; +} + +void CPDF_DeviceCS::TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask) const { + if (bTransMask && m_Family == PDFCS_DEVICECMYK) { + for (int i = 0; i < pixels; i++) { + int k = 255 - pSrcBuf[3]; + pDestBuf[0] = ((255 - pSrcBuf[0]) * k) / 255; + pDestBuf[1] = ((255 - pSrcBuf[1]) * k) / 255; + pDestBuf[2] = ((255 - pSrcBuf[2]) * k) / 255; + pDestBuf += 3; + pSrcBuf += 4; + } + return; + } + if (m_Family == PDFCS_DEVICERGB) { + ReverseRGB(pDestBuf, pSrcBuf, pixels); + } else if (m_Family == PDFCS_DEVICEGRAY) { + for (int i = 0; i < pixels; i++) { + *pDestBuf++ = pSrcBuf[i]; + *pDestBuf++ = pSrcBuf[i]; + *pDestBuf++ = pSrcBuf[i]; + } + } else { + for (int i = 0; i < pixels; i++) { + if (!m_dwStdConversion) { + AdobeCMYK_to_sRGB1(pSrcBuf[0], pSrcBuf[1], pSrcBuf[2], pSrcBuf[3], + pDestBuf[2], pDestBuf[1], pDestBuf[0]); + } else { + uint8_t k = pSrcBuf[3]; + pDestBuf[2] = 255 - std::min(255, pSrcBuf[0] + k); + pDestBuf[1] = 255 - std::min(255, pSrcBuf[1] + k); + pDestBuf[0] = 255 - std::min(255, pSrcBuf[2] + k); + } + pSrcBuf += 4; + pDestBuf += 3; + } + } +} + +CPDF_IccProfile::CPDF_IccProfile(const uint8_t* pData, uint32_t dwSize) + : m_bsRGB(FALSE), m_pTransform(nullptr), m_nSrcComponents(0) { + if (dwSize == 3144 && + FXSYS_memcmp(pData + 0x190, "sRGB IEC61966-2.1", 17) == 0) { + m_bsRGB = TRUE; + m_nSrcComponents = 3; + } else if (CPDF_ModuleMgr::Get()->GetIccModule()) { + m_pTransform = CPDF_ModuleMgr::Get()->GetIccModule()->CreateTransform_sRGB( + pData, dwSize, m_nSrcComponents); + } +} +CPDF_IccProfile::~CPDF_IccProfile() { + if (m_pTransform) { + CPDF_ModuleMgr::Get()->GetIccModule()->DestroyTransform(m_pTransform); + } +} diff --git a/core/fpdfapi/page/fpdf_page_doc.cpp b/core/fpdfapi/page/fpdf_page_doc.cpp new file mode 100644 index 0000000000..f11f1b288f --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_doc.cpp @@ -0,0 +1,554 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/pageint.h" + +#include +#include + +#include "core/fdrm/crypto/fx_crypt.h" +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/cpdf_type1font.h" +#include "core/fpdfapi/font/font_int.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_pagemodule.h" +#include "core/fpdfapi/page/cpdf_pattern.h" +#include "core/fpdfapi/page/cpdf_shadingpattern.h" +#include "core/fpdfapi/page/cpdf_tilingpattern.h" +#include "third_party/base/stl_util.h" + +void CPDF_ModuleMgr::InitPageModule() { + m_pPageModule.reset(new CPDF_PageModule); +} + +CPDF_DocPageData::CPDF_DocPageData(CPDF_Document* pPDFDoc) + : m_pPDFDoc(pPDFDoc), m_bForceClear(FALSE) {} + +CPDF_DocPageData::~CPDF_DocPageData() { + Clear(FALSE); + Clear(TRUE); + + for (auto& it : m_PatternMap) + delete it.second; + m_PatternMap.clear(); + + for (auto& it : m_FontMap) + delete it.second; + m_FontMap.clear(); + + for (auto& it : m_ColorSpaceMap) + delete it.second; + m_ColorSpaceMap.clear(); +} + +void CPDF_DocPageData::Clear(FX_BOOL bForceRelease) { + m_bForceClear = bForceRelease; + + for (auto& it : m_PatternMap) { + CPDF_CountedPattern* ptData = it.second; + if (!ptData->get()) + continue; + + if (bForceRelease || ptData->use_count() < 2) + ptData->clear(); + } + + for (auto& it : m_FontMap) { + CPDF_CountedFont* fontData = it.second; + if (!fontData->get()) + continue; + + if (bForceRelease || fontData->use_count() < 2) { + fontData->clear(); + } + } + + for (auto& it : m_ColorSpaceMap) { + CPDF_CountedColorSpace* csData = it.second; + if (!csData->get()) + continue; + + if (bForceRelease || csData->use_count() < 2) { + csData->get()->Release(); + csData->reset(nullptr); + } + } + + for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end();) { + auto curr_it = it++; + CPDF_CountedIccProfile* ipData = curr_it->second; + if (!ipData->get()) + continue; + + if (bForceRelease || ipData->use_count() < 2) { + for (auto hash_it = m_HashProfileMap.begin(); + hash_it != m_HashProfileMap.end(); ++hash_it) { + if (curr_it->first == hash_it->second) { + m_HashProfileMap.erase(hash_it); + break; + } + } + delete ipData->get(); + delete ipData; + m_IccProfileMap.erase(curr_it); + } + } + + for (auto it = m_FontFileMap.begin(); it != m_FontFileMap.end();) { + auto curr_it = it++; + CPDF_CountedStreamAcc* pCountedFont = curr_it->second; + if (!pCountedFont->get()) + continue; + + if (bForceRelease || pCountedFont->use_count() < 2) { + delete pCountedFont->get(); + delete pCountedFont; + m_FontFileMap.erase(curr_it); + } + } + + for (auto it = m_ImageMap.begin(); it != m_ImageMap.end();) { + auto curr_it = it++; + CPDF_CountedImage* pCountedImage = curr_it->second; + if (!pCountedImage->get()) + continue; + + if (bForceRelease || pCountedImage->use_count() < 2) { + delete pCountedImage->get(); + delete pCountedImage; + m_ImageMap.erase(curr_it); + } + } +} + +CPDF_Font* CPDF_DocPageData::GetFont(CPDF_Dictionary* pFontDict, + FX_BOOL findOnly) { + if (!pFontDict) + return nullptr; + + CPDF_CountedFont* pFontData = nullptr; + auto it = m_FontMap.find(pFontDict); + if (it != m_FontMap.end()) { + pFontData = it->second; + if (pFontData->get()) { + return pFontData->AddRef(); + } + } + + if (findOnly) + return nullptr; + + std::unique_ptr pFont = CPDF_Font::Create(m_pPDFDoc, pFontDict); + if (!pFont) + return nullptr; + + if (pFontData) { + pFontData->reset(pFont.release()); + } else { + pFontData = new CPDF_CountedFont(pFont.release()); + m_FontMap[pFontDict] = pFontData; + } + return pFontData->AddRef(); +} + +CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, + CPDF_FontEncoding* pEncoding) { + if (fontName.IsEmpty()) + return nullptr; + + for (auto& it : m_FontMap) { + CPDF_CountedFont* fontData = it.second; + CPDF_Font* pFont = fontData->get(); + if (!pFont) + continue; + if (pFont->GetBaseFont() != fontName) + continue; + if (pFont->IsEmbedded()) + continue; + if (!pFont->IsType1Font()) + continue; + if (pFont->GetFontDict()->KeyExist("Widths")) + continue; + + CPDF_Type1Font* pT1Font = pFont->AsType1Font(); + if (pEncoding && !pT1Font->GetEncoding()->IsIdentical(pEncoding)) + continue; + + return fontData->AddRef(); + } + + CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPDFDoc->GetByteStringPool()); + pDict->SetNameFor("Type", "Font"); + pDict->SetNameFor("Subtype", "Type1"); + pDict->SetNameFor("BaseFont", fontName); + if (pEncoding) { + pDict->SetFor("Encoding", + pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); + } + m_pPDFDoc->AddIndirectObject(pDict); + std::unique_ptr pFont = CPDF_Font::Create(m_pPDFDoc, pDict); + if (!pFont) + return nullptr; + + CPDF_CountedFont* fontData = new CPDF_CountedFont(pFont.release()); + m_FontMap[pDict] = fontData; + return fontData->AddRef(); +} + +void CPDF_DocPageData::ReleaseFont(const CPDF_Dictionary* pFontDict) { + if (!pFontDict) + return; + + auto it = m_FontMap.find(pFontDict); + if (it == m_FontMap.end()) + return; + + CPDF_CountedFont* pFontData = it->second; + if (!pFontData->get()) + return; + + pFontData->RemoveRef(); + if (pFontData->use_count() > 1) + return; + + // We have font data only in m_FontMap cache. Clean it. + pFontData->clear(); +} + +CPDF_ColorSpace* CPDF_DocPageData::GetColorSpace( + CPDF_Object* pCSObj, + const CPDF_Dictionary* pResources) { + std::set visited; + return GetColorSpaceImpl(pCSObj, pResources, &visited); +} + +CPDF_ColorSpace* CPDF_DocPageData::GetColorSpaceImpl( + CPDF_Object* pCSObj, + const CPDF_Dictionary* pResources, + std::set* pVisited) { + if (!pCSObj) + return nullptr; + + if (pdfium::ContainsKey(*pVisited, pCSObj)) + return nullptr; + + if (pCSObj->IsName()) { + CFX_ByteString name = pCSObj->GetString(); + CPDF_ColorSpace* pCS = CPDF_ColorSpace::ColorspaceFromName(name); + if (!pCS && pResources) { + CPDF_Dictionary* pList = pResources->GetDictFor("ColorSpace"); + if (pList) { + pdfium::ScopedSetInsertion insertion(pVisited, pCSObj); + return GetColorSpaceImpl(pList->GetDirectObjectFor(name), nullptr, + pVisited); + } + } + if (!pCS || !pResources) + return pCS; + + CPDF_Dictionary* pColorSpaces = pResources->GetDictFor("ColorSpace"); + if (!pColorSpaces) + return pCS; + + CPDF_Object* pDefaultCS = nullptr; + switch (pCS->GetFamily()) { + case PDFCS_DEVICERGB: + pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultRGB"); + break; + case PDFCS_DEVICEGRAY: + pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultGray"); + break; + case PDFCS_DEVICECMYK: + pDefaultCS = pColorSpaces->GetDirectObjectFor("DefaultCMYK"); + break; + } + if (!pDefaultCS) + return pCS; + + pdfium::ScopedSetInsertion insertion(pVisited, pCSObj); + return GetColorSpaceImpl(pDefaultCS, nullptr, pVisited); + } + + CPDF_Array* pArray = pCSObj->AsArray(); + if (!pArray || pArray->IsEmpty()) + return nullptr; + + if (pArray->GetCount() == 1) { + pdfium::ScopedSetInsertion insertion(pVisited, pCSObj); + return GetColorSpaceImpl(pArray->GetDirectObjectAt(0), pResources, + pVisited); + } + + CPDF_CountedColorSpace* csData = nullptr; + auto it = m_ColorSpaceMap.find(pCSObj); + if (it != m_ColorSpaceMap.end()) { + csData = it->second; + if (csData->get()) { + return csData->AddRef(); + } + } + + std::unique_ptr pCS = + CPDF_ColorSpace::Load(m_pPDFDoc, pArray); + if (!pCS) + return nullptr; + + if (!csData) { + csData = new CPDF_CountedColorSpace(pCS.release()); + m_ColorSpaceMap[pCSObj] = csData; + } else { + csData->reset(pCS.release()); + } + return csData->AddRef(); +} + +CPDF_ColorSpace* CPDF_DocPageData::GetCopiedColorSpace(CPDF_Object* pCSObj) { + if (!pCSObj) + return nullptr; + + auto it = m_ColorSpaceMap.find(pCSObj); + if (it != m_ColorSpaceMap.end()) + return it->second->AddRef(); + + return nullptr; +} + +void CPDF_DocPageData::ReleaseColorSpace(const CPDF_Object* pColorSpace) { + if (!pColorSpace) + return; + + auto it = m_ColorSpaceMap.find(pColorSpace); + if (it == m_ColorSpaceMap.end()) + return; + + CPDF_CountedColorSpace* pCountedColorSpace = it->second; + if (!pCountedColorSpace->get()) + return; + + pCountedColorSpace->RemoveRef(); + if (pCountedColorSpace->use_count() > 1) + return; + + // We have item only in m_ColorSpaceMap cache. Clean it. + pCountedColorSpace->get()->Release(); + pCountedColorSpace->reset(nullptr); +} + +CPDF_Pattern* CPDF_DocPageData::GetPattern(CPDF_Object* pPatternObj, + FX_BOOL bShading, + const CFX_Matrix& matrix) { + if (!pPatternObj) + return nullptr; + + CPDF_CountedPattern* ptData = nullptr; + auto it = m_PatternMap.find(pPatternObj); + if (it != m_PatternMap.end()) { + ptData = it->second; + if (ptData->get()) { + return ptData->AddRef(); + } + } + CPDF_Pattern* pPattern = nullptr; + if (bShading) { + pPattern = new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, TRUE, matrix); + } else { + CPDF_Dictionary* pDict = pPatternObj ? pPatternObj->GetDict() : nullptr; + if (pDict) { + int type = pDict->GetIntegerFor("PatternType"); + if (type == CPDF_Pattern::TILING) { + pPattern = new CPDF_TilingPattern(m_pPDFDoc, pPatternObj, matrix); + } else if (type == CPDF_Pattern::SHADING) { + pPattern = + new CPDF_ShadingPattern(m_pPDFDoc, pPatternObj, FALSE, matrix); + } + } + } + if (!pPattern) + return nullptr; + + if (!ptData) { + ptData = new CPDF_CountedPattern(pPattern); + m_PatternMap[pPatternObj] = ptData; + } else { + ptData->reset(pPattern); + } + return ptData->AddRef(); +} + +void CPDF_DocPageData::ReleasePattern(const CPDF_Object* pPatternObj) { + if (!pPatternObj) + return; + + auto it = m_PatternMap.find(pPatternObj); + if (it == m_PatternMap.end()) + return; + + CPDF_CountedPattern* pPattern = it->second; + if (!pPattern->get()) + return; + + pPattern->RemoveRef(); + if (pPattern->use_count() > 1) + return; + + // We have item only in m_PatternMap cache. Clean it. + pPattern->clear(); +} + +CPDF_Image* CPDF_DocPageData::GetImage(CPDF_Object* pImageStream) { + if (!pImageStream) + return nullptr; + + const uint32_t dwImageObjNum = pImageStream->GetObjNum(); + auto it = m_ImageMap.find(dwImageObjNum); + if (it != m_ImageMap.end()) + return it->second->AddRef(); + + CPDF_CountedImage* pCountedImage = new CPDF_CountedImage( + new CPDF_Image(m_pPDFDoc, pImageStream->AsStream(), false)); + m_ImageMap[dwImageObjNum] = pCountedImage; + return pCountedImage->AddRef(); +} + +void CPDF_DocPageData::ReleaseImage(const CPDF_Object* pImageStream) { + if (!pImageStream) + return; + + uint32_t dwObjNum = pImageStream->GetObjNum(); + if (!dwObjNum) + return; + + auto it = m_ImageMap.find(dwObjNum); + if (it == m_ImageMap.end()) + return; + + CPDF_CountedImage* pCountedImage = it->second; + if (!pCountedImage) + return; + + pCountedImage->RemoveRef(); + if (pCountedImage->use_count() > 1) + return; + + // We have item only in m_ImageMap cache. Clean it. + delete pCountedImage->get(); + delete pCountedImage; + m_ImageMap.erase(it); +} + +CPDF_IccProfile* CPDF_DocPageData::GetIccProfile( + CPDF_Stream* pIccProfileStream) { + if (!pIccProfileStream) + return nullptr; + + auto it = m_IccProfileMap.find(pIccProfileStream); + if (it != m_IccProfileMap.end()) + return it->second->AddRef(); + + CPDF_StreamAcc stream; + stream.LoadAllData(pIccProfileStream, FALSE); + uint8_t digest[20]; + CRYPT_SHA1Generate(stream.GetData(), stream.GetSize(), digest); + CFX_ByteString bsDigest(digest, 20); + auto hash_it = m_HashProfileMap.find(bsDigest); + if (hash_it != m_HashProfileMap.end()) { + auto it_copied_stream = m_IccProfileMap.find(hash_it->second); + if (it_copied_stream != m_IccProfileMap.end()) + return it_copied_stream->second->AddRef(); + } + CPDF_IccProfile* pProfile = + new CPDF_IccProfile(stream.GetData(), stream.GetSize()); + CPDF_CountedIccProfile* ipData = new CPDF_CountedIccProfile(pProfile); + m_IccProfileMap[pIccProfileStream] = ipData; + m_HashProfileMap[bsDigest] = pIccProfileStream; + return ipData->AddRef(); +} + +void CPDF_DocPageData::ReleaseIccProfile(const CPDF_IccProfile* pIccProfile) { + ASSERT(pIccProfile); + + for (auto it = m_IccProfileMap.begin(); it != m_IccProfileMap.end(); ++it) { + CPDF_CountedIccProfile* profile = it->second; + if (profile->get() != pIccProfile) + continue; + + profile->RemoveRef(); + if (profile->use_count() > 1) + continue; + // We have item only in m_IccProfileMap cache. Clean it. + delete profile->get(); + delete profile; + m_IccProfileMap.erase(it); + return; + } +} + +CPDF_StreamAcc* CPDF_DocPageData::GetFontFileStreamAcc( + CPDF_Stream* pFontStream) { + ASSERT(pFontStream); + + auto it = m_FontFileMap.find(pFontStream); + if (it != m_FontFileMap.end()) + return it->second->AddRef(); + + CPDF_Dictionary* pFontDict = pFontStream->GetDict(); + int32_t org_size = pFontDict->GetIntegerFor("Length1") + + pFontDict->GetIntegerFor("Length2") + + pFontDict->GetIntegerFor("Length3"); + org_size = std::max(org_size, 0); + + CPDF_StreamAcc* pFontFile = new CPDF_StreamAcc; + pFontFile->LoadAllData(pFontStream, FALSE, org_size); + + CPDF_CountedStreamAcc* pCountedFont = new CPDF_CountedStreamAcc(pFontFile); + m_FontFileMap[pFontStream] = pCountedFont; + return pCountedFont->AddRef(); +} + +void CPDF_DocPageData::ReleaseFontFileStreamAcc( + const CPDF_Stream* pFontStream) { + if (!pFontStream) + return; + + auto it = m_FontFileMap.find(pFontStream); + if (it == m_FontFileMap.end()) + return; + + CPDF_CountedStreamAcc* pCountedStream = it->second; + if (!pCountedStream) + return; + + pCountedStream->RemoveRef(); + if (pCountedStream->use_count() > 1) + return; + + // We have item only in m_FontFileMap cache. Clean it. + delete pCountedStream->get(); + delete pCountedStream; + m_FontFileMap.erase(it); +} + +CPDF_CountedColorSpace* CPDF_DocPageData::FindColorSpacePtr( + CPDF_Object* pCSObj) const { + if (!pCSObj) + return nullptr; + + auto it = m_ColorSpaceMap.find(pCSObj); + return it != m_ColorSpaceMap.end() ? it->second : nullptr; +} + +CPDF_CountedPattern* CPDF_DocPageData::FindPatternPtr( + CPDF_Object* pPatternObj) const { + if (!pPatternObj) + return nullptr; + + auto it = m_PatternMap.find(pPatternObj); + return it != m_PatternMap.end() ? it->second : nullptr; +} diff --git a/core/fpdfapi/page/fpdf_page_func.cpp b/core/fpdfapi/page/fpdf_page_func.cpp new file mode 100644 index 0000000000..e11d8dd754 --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_func.cpp @@ -0,0 +1,845 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/pageint.h" + +#include + +#include +#include +#include +#include + +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_simple_parser.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/page/cpdf_psengine.h" +#include "core/fxcrt/fx_safe_types.h" +#include "third_party/base/numerics/safe_conversions_impl.h" + +class CPDF_PSOP { + public: + explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) { + ASSERT(m_op != PSOP_CONST); + ASSERT(m_op != PSOP_PROC); + } + explicit CPDF_PSOP(FX_FLOAT value) : m_op(PSOP_CONST), m_value(value) {} + explicit CPDF_PSOP(std::unique_ptr proc) + : m_op(PSOP_PROC), m_value(0), m_proc(std::move(proc)) {} + + FX_FLOAT GetFloatValue() const { + if (m_op == PSOP_CONST) + return m_value; + + ASSERT(false); + return 0; + } + CPDF_PSProc* GetProc() const { + if (m_op == PSOP_PROC) + return m_proc.get(); + ASSERT(false); + return nullptr; + } + + PDF_PSOP GetOp() const { return m_op; } + + private: + const PDF_PSOP m_op; + const FX_FLOAT m_value; + std::unique_ptr m_proc; +}; + +FX_BOOL CPDF_PSEngine::Execute() { + return m_MainProc.Execute(this); +} + +CPDF_PSProc::CPDF_PSProc() {} +CPDF_PSProc::~CPDF_PSProc() {} + +FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) { + for (size_t i = 0; i < m_Operators.size(); ++i) { + const PDF_PSOP op = m_Operators[i]->GetOp(); + if (op == PSOP_PROC) + continue; + + if (op == PSOP_CONST) { + pEngine->Push(m_Operators[i]->GetFloatValue()); + continue; + } + + if (op == PSOP_IF) { + if (i == 0 || m_Operators[i - 1]->GetOp() != PSOP_PROC) + return FALSE; + + if (static_cast(pEngine->Pop())) + m_Operators[i - 1]->GetProc()->Execute(pEngine); + } else if (op == PSOP_IFELSE) { + if (i < 2 || m_Operators[i - 1]->GetOp() != PSOP_PROC || + m_Operators[i - 2]->GetOp() != PSOP_PROC) { + return FALSE; + } + size_t offset = static_cast(pEngine->Pop()) ? 2 : 1; + m_Operators[i - offset]->GetProc()->Execute(pEngine); + } else { + pEngine->DoOperator(op); + } + } + return TRUE; +} + +CPDF_PSEngine::CPDF_PSEngine() { + m_StackCount = 0; +} +CPDF_PSEngine::~CPDF_PSEngine() {} +void CPDF_PSEngine::Push(FX_FLOAT v) { + if (m_StackCount == PSENGINE_STACKSIZE) { + return; + } + m_Stack[m_StackCount++] = v; +} +FX_FLOAT CPDF_PSEngine::Pop() { + if (m_StackCount == 0) { + return 0; + } + return m_Stack[--m_StackCount]; +} +const struct PDF_PSOpName { + const FX_CHAR* name; + PDF_PSOP op; +} PDF_PSOpNames[] = {{"add", PSOP_ADD}, {"sub", PSOP_SUB}, + {"mul", PSOP_MUL}, {"div", PSOP_DIV}, + {"idiv", PSOP_IDIV}, {"mod", PSOP_MOD}, + {"neg", PSOP_NEG}, {"abs", PSOP_ABS}, + {"ceiling", PSOP_CEILING}, {"floor", PSOP_FLOOR}, + {"round", PSOP_ROUND}, {"truncate", PSOP_TRUNCATE}, + {"sqrt", PSOP_SQRT}, {"sin", PSOP_SIN}, + {"cos", PSOP_COS}, {"atan", PSOP_ATAN}, + {"exp", PSOP_EXP}, {"ln", PSOP_LN}, + {"log", PSOP_LOG}, {"cvi", PSOP_CVI}, + {"cvr", PSOP_CVR}, {"eq", PSOP_EQ}, + {"ne", PSOP_NE}, {"gt", PSOP_GT}, + {"ge", PSOP_GE}, {"lt", PSOP_LT}, + {"le", PSOP_LE}, {"and", PSOP_AND}, + {"or", PSOP_OR}, {"xor", PSOP_XOR}, + {"not", PSOP_NOT}, {"bitshift", PSOP_BITSHIFT}, + {"true", PSOP_TRUE}, {"false", PSOP_FALSE}, + {"if", PSOP_IF}, {"ifelse", PSOP_IFELSE}, + {"pop", PSOP_POP}, {"exch", PSOP_EXCH}, + {"dup", PSOP_DUP}, {"copy", PSOP_COPY}, + {"index", PSOP_INDEX}, {"roll", PSOP_ROLL}}; + +FX_BOOL CPDF_PSEngine::Parse(const FX_CHAR* str, int size) { + CPDF_SimpleParser parser((uint8_t*)str, size); + CFX_ByteStringC word = parser.GetWord(); + if (word != "{") { + return FALSE; + } + return m_MainProc.Parse(&parser, 0); +} + +FX_BOOL CPDF_PSProc::Parse(CPDF_SimpleParser* parser, int depth) { + if (depth > kMaxDepth) + return FALSE; + + while (1) { + CFX_ByteStringC word = parser->GetWord(); + if (word.IsEmpty()) { + return FALSE; + } + if (word == "}") { + return TRUE; + } + if (word == "{") { + std::unique_ptr proc(new CPDF_PSProc); + std::unique_ptr op(new CPDF_PSOP(std::move(proc))); + m_Operators.push_back(std::move(op)); + if (!m_Operators.back()->GetProc()->Parse(parser, depth + 1)) { + return FALSE; + } + } else { + bool found = false; + for (const PDF_PSOpName& op_name : PDF_PSOpNames) { + if (word == CFX_ByteStringC(op_name.name)) { + std::unique_ptr op(new CPDF_PSOP(op_name.op)); + m_Operators.push_back(std::move(op)); + found = true; + break; + } + } + if (!found) { + std::unique_ptr op(new CPDF_PSOP(FX_atof(word))); + m_Operators.push_back(std::move(op)); + } + } + } +} + +FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) { + int i1, i2; + FX_FLOAT d1, d2; + switch (op) { + case PSOP_ADD: + d1 = Pop(); + d2 = Pop(); + Push(d1 + d2); + break; + case PSOP_SUB: + d2 = Pop(); + d1 = Pop(); + Push(d1 - d2); + break; + case PSOP_MUL: + d1 = Pop(); + d2 = Pop(); + Push(d1 * d2); + break; + case PSOP_DIV: + d2 = Pop(); + d1 = Pop(); + Push(d1 / d2); + break; + case PSOP_IDIV: + i2 = (int)Pop(); + i1 = (int)Pop(); + Push(i2 ? i1 / i2 : 0); + break; + case PSOP_MOD: + i2 = (int)Pop(); + i1 = (int)Pop(); + Push(i2 ? i1 % i2 : 0); + break; + case PSOP_NEG: + d1 = Pop(); + Push(-d1); + break; + case PSOP_ABS: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_fabs(d1)); + break; + case PSOP_CEILING: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_ceil(d1)); + break; + case PSOP_FLOOR: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_floor(d1)); + break; + case PSOP_ROUND: + d1 = Pop(); + Push(FXSYS_round(d1)); + break; + case PSOP_TRUNCATE: + i1 = (int)Pop(); + Push(i1); + break; + case PSOP_SQRT: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_sqrt(d1)); + break; + case PSOP_SIN: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_sin(d1 * FX_PI / 180.0f)); + break; + case PSOP_COS: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_cos(d1 * FX_PI / 180.0f)); + break; + case PSOP_ATAN: + d2 = Pop(); + d1 = Pop(); + d1 = (FX_FLOAT)(FXSYS_atan2(d1, d2) * 180.0 / FX_PI); + if (d1 < 0) { + d1 += 360; + } + Push(d1); + break; + case PSOP_EXP: + d2 = Pop(); + d1 = Pop(); + Push((FX_FLOAT)FXSYS_pow(d1, d2)); + break; + case PSOP_LN: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_log(d1)); + break; + case PSOP_LOG: + d1 = Pop(); + Push((FX_FLOAT)FXSYS_log10(d1)); + break; + case PSOP_CVI: + i1 = (int)Pop(); + Push(i1); + break; + case PSOP_CVR: + break; + case PSOP_EQ: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 == d2)); + break; + case PSOP_NE: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 != d2)); + break; + case PSOP_GT: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 > d2)); + break; + case PSOP_GE: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 >= d2)); + break; + case PSOP_LT: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 < d2)); + break; + case PSOP_LE: + d2 = Pop(); + d1 = Pop(); + Push((int)(d1 <= d2)); + break; + case PSOP_AND: + i1 = (int)Pop(); + i2 = (int)Pop(); + Push(i1 & i2); + break; + case PSOP_OR: + i1 = (int)Pop(); + i2 = (int)Pop(); + Push(i1 | i2); + break; + case PSOP_XOR: + i1 = (int)Pop(); + i2 = (int)Pop(); + Push(i1 ^ i2); + break; + case PSOP_NOT: + i1 = (int)Pop(); + Push((int)!i1); + break; + case PSOP_BITSHIFT: { + int shift = (int)Pop(); + int i = (int)Pop(); + if (shift > 0) { + Push(i << shift); + } else { + Push(i >> -shift); + } + break; + } + case PSOP_TRUE: + Push(1); + break; + case PSOP_FALSE: + Push(0); + break; + case PSOP_POP: + Pop(); + break; + case PSOP_EXCH: + d2 = Pop(); + d1 = Pop(); + Push(d2); + Push(d1); + break; + case PSOP_DUP: + d1 = Pop(); + Push(d1); + Push(d1); + break; + case PSOP_COPY: { + int n = static_cast(Pop()); + if (n < 0 || m_StackCount + n > PSENGINE_STACKSIZE || + n > static_cast(m_StackCount)) + break; + for (int i = 0; i < n; i++) + m_Stack[m_StackCount + i] = m_Stack[m_StackCount + i - n]; + m_StackCount += n; + break; + } + case PSOP_INDEX: { + int n = static_cast(Pop()); + if (n < 0 || n >= static_cast(m_StackCount)) + break; + Push(m_Stack[m_StackCount - n - 1]); + break; + } + case PSOP_ROLL: { + int j = static_cast(Pop()); + int n = static_cast(Pop()); + if (m_StackCount == 0) + break; + if (n < 0 || n > static_cast(m_StackCount)) + break; + if (j < 0) { + for (int i = 0; i < -j; i++) { + FX_FLOAT first = m_Stack[m_StackCount - n]; + for (int ii = 0; ii < n - 1; ii++) + m_Stack[m_StackCount - n + ii] = m_Stack[m_StackCount - n + ii + 1]; + m_Stack[m_StackCount - 1] = first; + } + } else { + for (int i = 0; i < j; i++) { + FX_FLOAT last = m_Stack[m_StackCount - 1]; + int ii; + for (ii = 0; ii < n - 1; ii++) + m_Stack[m_StackCount - ii - 1] = m_Stack[m_StackCount - ii - 2]; + m_Stack[m_StackCount - ii - 1] = last; + } + } + break; + } + default: + break; + } + return TRUE; +} + +// See PDF Reference 1.7, page 170, table 3.36. +bool IsValidBitsPerSample(uint32_t x) { + switch (x) { + case 1: + case 2: + case 4: + case 8: + case 12: + case 16: + case 24: + case 32: + return true; + default: + return false; + } +} + +// See PDF Reference 1.7, page 170. +FX_FLOAT PDF_Interpolate(FX_FLOAT x, + FX_FLOAT xmin, + FX_FLOAT xmax, + FX_FLOAT ymin, + FX_FLOAT ymax) { + FX_FLOAT divisor = xmax - xmin; + return ymin + (divisor ? (x - xmin) * (ymax - ymin) / divisor : 0); +} + +class CPDF_PSFunc : public CPDF_Function { + public: + CPDF_PSFunc() : CPDF_Function(Type::kType4PostScript) {} + ~CPDF_PSFunc() override {} + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + private: + CPDF_PSEngine m_PS; +}; + +FX_BOOL CPDF_PSFunc::v_Init(CPDF_Object* pObj) { + CPDF_StreamAcc acc; + acc.LoadAllData(pObj->AsStream(), FALSE); + return m_PS.Parse(reinterpret_cast(acc.GetData()), + acc.GetSize()); +} + +FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { + CPDF_PSEngine& PS = const_cast(m_PS); + PS.Reset(); + for (uint32_t i = 0; i < m_nInputs; i++) + PS.Push(inputs[i]); + PS.Execute(); + if (PS.GetStackSize() < m_nOutputs) + return FALSE; + for (uint32_t i = 0; i < m_nOutputs; i++) + results[m_nOutputs - i - 1] = PS.Pop(); + return TRUE; +} + +CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {} + +CPDF_SampledFunc::~CPDF_SampledFunc() {} + +FX_BOOL CPDF_SampledFunc::v_Init(CPDF_Object* pObj) { + CPDF_Stream* pStream = pObj->AsStream(); + if (!pStream) + return false; + + CPDF_Dictionary* pDict = pStream->GetDict(); + CPDF_Array* pSize = pDict->GetArrayFor("Size"); + CPDF_Array* pEncode = pDict->GetArrayFor("Encode"); + CPDF_Array* pDecode = pDict->GetArrayFor("Decode"); + m_nBitsPerSample = pDict->GetIntegerFor("BitsPerSample"); + if (!IsValidBitsPerSample(m_nBitsPerSample)) + return FALSE; + + m_SampleMax = 0xffffffff >> (32 - m_nBitsPerSample); + m_pSampleStream.reset(new CPDF_StreamAcc); + m_pSampleStream->LoadAllData(pStream, FALSE); + FX_SAFE_UINT32 nTotalSampleBits = 1; + m_EncodeInfo.resize(m_nInputs); + for (uint32_t i = 0; i < m_nInputs; i++) { + m_EncodeInfo[i].sizes = pSize ? pSize->GetIntegerAt(i) : 0; + if (!pSize && i == 0) + m_EncodeInfo[i].sizes = pDict->GetIntegerFor("Size"); + nTotalSampleBits *= m_EncodeInfo[i].sizes; + if (pEncode) { + m_EncodeInfo[i].encode_min = pEncode->GetFloatAt(i * 2); + m_EncodeInfo[i].encode_max = pEncode->GetFloatAt(i * 2 + 1); + } else { + m_EncodeInfo[i].encode_min = 0; + m_EncodeInfo[i].encode_max = + m_EncodeInfo[i].sizes == 1 ? 1 : (FX_FLOAT)m_EncodeInfo[i].sizes - 1; + } + } + nTotalSampleBits *= m_nBitsPerSample; + nTotalSampleBits *= m_nOutputs; + FX_SAFE_UINT32 nTotalSampleBytes = nTotalSampleBits; + nTotalSampleBytes += 7; + nTotalSampleBytes /= 8; + if (!nTotalSampleBytes.IsValid() || nTotalSampleBytes.ValueOrDie() == 0 || + nTotalSampleBytes.ValueOrDie() > m_pSampleStream->GetSize()) { + return FALSE; + } + m_DecodeInfo.resize(m_nOutputs); + for (uint32_t i = 0; i < m_nOutputs; i++) { + if (pDecode) { + m_DecodeInfo[i].decode_min = pDecode->GetFloatAt(2 * i); + m_DecodeInfo[i].decode_max = pDecode->GetFloatAt(2 * i + 1); + } else { + m_DecodeInfo[i].decode_min = m_pRanges[i * 2]; + m_DecodeInfo[i].decode_max = m_pRanges[i * 2 + 1]; + } + } + return TRUE; +} + +FX_BOOL CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { + int pos = 0; + CFX_FixedBufGrow encoded_input_buf(m_nInputs); + FX_FLOAT* encoded_input = encoded_input_buf; + CFX_FixedBufGrow int_buf(m_nInputs * 2); + uint32_t* index = int_buf; + uint32_t* blocksize = index + m_nInputs; + for (uint32_t i = 0; i < m_nInputs; i++) { + if (i == 0) + blocksize[i] = 1; + else + blocksize[i] = blocksize[i - 1] * m_EncodeInfo[i - 1].sizes; + encoded_input[i] = + PDF_Interpolate(inputs[i], m_pDomains[i * 2], m_pDomains[i * 2 + 1], + m_EncodeInfo[i].encode_min, m_EncodeInfo[i].encode_max); + index[i] = std::min((uint32_t)std::max(0.f, encoded_input[i]), + m_EncodeInfo[i].sizes - 1); + pos += index[i] * blocksize[i]; + } + FX_SAFE_INT32 bits_to_output = m_nOutputs; + bits_to_output *= m_nBitsPerSample; + if (!bits_to_output.IsValid()) + return FALSE; + + FX_SAFE_INT32 bitpos = pos; + bitpos *= bits_to_output.ValueOrDie(); + if (!bitpos.IsValid()) + return FALSE; + + FX_SAFE_INT32 range_check = bitpos; + range_check += bits_to_output.ValueOrDie(); + if (!range_check.IsValid()) + return FALSE; + + const uint8_t* pSampleData = m_pSampleStream->GetData(); + if (!pSampleData) + return FALSE; + + for (uint32_t j = 0; j < m_nOutputs; j++) { + uint32_t sample = + GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, + m_nBitsPerSample); + FX_FLOAT encoded = (FX_FLOAT)sample; + for (uint32_t i = 0; i < m_nInputs; i++) { + if (index[i] == m_EncodeInfo[i].sizes - 1) { + if (index[i] == 0) + encoded = encoded_input[i] * (FX_FLOAT)sample; + } else { + FX_SAFE_INT32 bitpos2 = blocksize[i]; + bitpos2 += pos; + bitpos2 *= m_nOutputs; + bitpos2 += j; + bitpos2 *= m_nBitsPerSample; + if (!bitpos2.IsValid()) + return FALSE; + uint32_t sample1 = + GetBits32(pSampleData, bitpos2.ValueOrDie(), m_nBitsPerSample); + encoded += (encoded_input[i] - index[i]) * + ((FX_FLOAT)sample1 - (FX_FLOAT)sample); + } + } + results[j] = + PDF_Interpolate(encoded, 0, (FX_FLOAT)m_SampleMax, + m_DecodeInfo[j].decode_min, m_DecodeInfo[j].decode_max); + } + return TRUE; +} + +CPDF_ExpIntFunc::CPDF_ExpIntFunc() + : CPDF_Function(Type::kType2ExpotentialInterpolation), + m_pBeginValues(nullptr), + m_pEndValues(nullptr) {} + +CPDF_ExpIntFunc::~CPDF_ExpIntFunc() { + FX_Free(m_pBeginValues); + FX_Free(m_pEndValues); +} +FX_BOOL CPDF_ExpIntFunc::v_Init(CPDF_Object* pObj) { + CPDF_Dictionary* pDict = pObj->GetDict(); + if (!pDict) { + return FALSE; + } + CPDF_Array* pArray0 = pDict->GetArrayFor("C0"); + if (m_nOutputs == 0) { + m_nOutputs = 1; + if (pArray0) { + m_nOutputs = pArray0->GetCount(); + } + } + CPDF_Array* pArray1 = pDict->GetArrayFor("C1"); + m_pBeginValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); + m_pEndValues = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); + for (uint32_t i = 0; i < m_nOutputs; i++) { + m_pBeginValues[i] = pArray0 ? pArray0->GetFloatAt(i) : 0.0f; + m_pEndValues[i] = pArray1 ? pArray1->GetFloatAt(i) : 1.0f; + } + m_Exponent = pDict->GetFloatFor("N"); + m_nOrigOutputs = m_nOutputs; + if (m_nOutputs && m_nInputs > INT_MAX / m_nOutputs) { + return FALSE; + } + m_nOutputs *= m_nInputs; + return TRUE; +} +FX_BOOL CPDF_ExpIntFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { + for (uint32_t i = 0; i < m_nInputs; i++) + for (uint32_t j = 0; j < m_nOrigOutputs; j++) { + results[i * m_nOrigOutputs + j] = + m_pBeginValues[j] + + (FX_FLOAT)FXSYS_pow(inputs[i], m_Exponent) * + (m_pEndValues[j] - m_pBeginValues[j]); + } + return TRUE; +} + +CPDF_StitchFunc::CPDF_StitchFunc() + : CPDF_Function(Type::kType3Stitching), + m_pBounds(nullptr), + m_pEncode(nullptr) {} + +CPDF_StitchFunc::~CPDF_StitchFunc() { + FX_Free(m_pBounds); + FX_Free(m_pEncode); +} + +FX_BOOL CPDF_StitchFunc::v_Init(CPDF_Object* pObj) { + CPDF_Dictionary* pDict = pObj->GetDict(); + if (!pDict) { + return FALSE; + } + if (m_nInputs != kRequiredNumInputs) { + return FALSE; + } + CPDF_Array* pArray = pDict->GetArrayFor("Functions"); + if (!pArray) { + return FALSE; + } + uint32_t nSubs = pArray->GetCount(); + if (nSubs == 0) + return FALSE; + m_nOutputs = 0; + for (uint32_t i = 0; i < nSubs; i++) { + CPDF_Object* pSub = pArray->GetDirectObjectAt(i); + if (pSub == pObj) + return FALSE; + std::unique_ptr pFunc(CPDF_Function::Load(pSub)); + if (!pFunc) + return FALSE; + // Check that the input dimensionality is 1, and that all output + // dimensionalities are the same. + if (pFunc->CountInputs() != kRequiredNumInputs) + return FALSE; + if (pFunc->CountOutputs() != m_nOutputs) { + if (m_nOutputs) + return FALSE; + + m_nOutputs = pFunc->CountOutputs(); + } + + m_pSubFunctions.push_back(std::move(pFunc)); + } + m_pBounds = FX_Alloc(FX_FLOAT, nSubs + 1); + m_pBounds[0] = m_pDomains[0]; + pArray = pDict->GetArrayFor("Bounds"); + if (!pArray) + return FALSE; + for (uint32_t i = 0; i < nSubs - 1; i++) + m_pBounds[i + 1] = pArray->GetFloatAt(i); + m_pBounds[nSubs] = m_pDomains[1]; + m_pEncode = FX_Alloc2D(FX_FLOAT, nSubs, 2); + pArray = pDict->GetArrayFor("Encode"); + if (!pArray) + return FALSE; + + for (uint32_t i = 0; i < nSubs * 2; i++) + m_pEncode[i] = pArray->GetFloatAt(i); + return TRUE; +} + +FX_BOOL CPDF_StitchFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* outputs) const { + FX_FLOAT input = inputs[0]; + size_t i; + for (i = 0; i < m_pSubFunctions.size() - 1; i++) { + if (input < m_pBounds[i + 1]) + break; + } + input = PDF_Interpolate(input, m_pBounds[i], m_pBounds[i + 1], + m_pEncode[i * 2], m_pEncode[i * 2 + 1]); + int nresults; + m_pSubFunctions[i]->Call(&input, kRequiredNumInputs, outputs, nresults); + return TRUE; +} + +// static +std::unique_ptr CPDF_Function::Load(CPDF_Object* pFuncObj) { + std::unique_ptr pFunc; + if (!pFuncObj) + return pFunc; + + int iType = -1; + if (CPDF_Stream* pStream = pFuncObj->AsStream()) + iType = pStream->GetDict()->GetIntegerFor("FunctionType"); + else if (CPDF_Dictionary* pDict = pFuncObj->AsDictionary()) + iType = pDict->GetIntegerFor("FunctionType"); + + Type type = IntegerToFunctionType(iType); + if (type == Type::kType0Sampled) + pFunc.reset(new CPDF_SampledFunc()); + else if (type == Type::kType2ExpotentialInterpolation) + pFunc.reset(new CPDF_ExpIntFunc()); + else if (type == Type::kType3Stitching) + pFunc.reset(new CPDF_StitchFunc()); + else if (type == Type::kType4PostScript) + pFunc.reset(new CPDF_PSFunc()); + + if (!pFunc || !pFunc->Init(pFuncObj)) + return std::unique_ptr(); + return pFunc; +} + +// static +CPDF_Function::Type CPDF_Function::IntegerToFunctionType(int iType) { + switch (iType) { + case 0: + case 2: + case 3: + case 4: + return static_cast(iType); + default: + return Type::kTypeInvalid; + } +} + +CPDF_Function::CPDF_Function(Type type) + : m_pDomains(nullptr), m_pRanges(nullptr), m_Type(type) {} + +CPDF_Function::~CPDF_Function() { + FX_Free(m_pDomains); + FX_Free(m_pRanges); +} + +FX_BOOL CPDF_Function::Init(CPDF_Object* pObj) { + CPDF_Stream* pStream = pObj->AsStream(); + CPDF_Dictionary* pDict = pStream ? pStream->GetDict() : pObj->AsDictionary(); + + CPDF_Array* pDomains = pDict->GetArrayFor("Domain"); + if (!pDomains) + return FALSE; + + m_nInputs = pDomains->GetCount() / 2; + if (m_nInputs == 0) + return FALSE; + + m_pDomains = FX_Alloc2D(FX_FLOAT, m_nInputs, 2); + for (uint32_t i = 0; i < m_nInputs * 2; i++) { + m_pDomains[i] = pDomains->GetFloatAt(i); + } + CPDF_Array* pRanges = pDict->GetArrayFor("Range"); + m_nOutputs = 0; + if (pRanges) { + m_nOutputs = pRanges->GetCount() / 2; + m_pRanges = FX_Alloc2D(FX_FLOAT, m_nOutputs, 2); + for (uint32_t i = 0; i < m_nOutputs * 2; i++) + m_pRanges[i] = pRanges->GetFloatAt(i); + } + uint32_t old_outputs = m_nOutputs; + if (!v_Init(pObj)) + return FALSE; + if (m_pRanges && m_nOutputs > old_outputs) { + m_pRanges = FX_Realloc(FX_FLOAT, m_pRanges, m_nOutputs * 2); + if (m_pRanges) { + FXSYS_memset(m_pRanges + (old_outputs * 2), 0, + sizeof(FX_FLOAT) * (m_nOutputs - old_outputs) * 2); + } + } + return TRUE; +} + +FX_BOOL CPDF_Function::Call(FX_FLOAT* inputs, + uint32_t ninputs, + FX_FLOAT* results, + int& nresults) const { + if (m_nInputs != ninputs) { + return FALSE; + } + nresults = m_nOutputs; + for (uint32_t i = 0; i < m_nInputs; i++) { + if (inputs[i] < m_pDomains[i * 2]) + inputs[i] = m_pDomains[i * 2]; + else if (inputs[i] > m_pDomains[i * 2 + 1]) + inputs[i] = m_pDomains[i * 2] + 1; + } + v_Call(inputs, results); + if (m_pRanges) { + for (uint32_t i = 0; i < m_nOutputs; i++) { + if (results[i] < m_pRanges[i * 2]) + results[i] = m_pRanges[i * 2]; + else if (results[i] > m_pRanges[i * 2 + 1]) + results[i] = m_pRanges[i * 2 + 1]; + } + } + return TRUE; +} + +const CPDF_SampledFunc* CPDF_Function::ToSampledFunc() const { + return m_Type == Type::kType0Sampled + ? static_cast(this) + : nullptr; +} + +const CPDF_ExpIntFunc* CPDF_Function::ToExpIntFunc() const { + return m_Type == Type::kType2ExpotentialInterpolation + ? static_cast(this) + : nullptr; +} + +const CPDF_StitchFunc* CPDF_Function::ToStitchFunc() const { + return m_Type == Type::kType3Stitching + ? static_cast(this) + : nullptr; +} diff --git a/core/fpdfapi/page/fpdf_page_func_embeddertest.cpp b/core/fpdfapi/page/fpdf_page_func_embeddertest.cpp new file mode 100644 index 0000000000..2892036882 --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_func_embeddertest.cpp @@ -0,0 +1,20 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "testing/embedder_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +class FPDFPageFuncEmbeddertest : public EmbedderTest {}; + +TEST_F(FPDFPageFuncEmbeddertest, Bug_551460) { + // Should not crash under ASan. + // Tests that the number of inputs is not simply calculated from the domain + // and trusted. The number of inputs has to be 1. + EXPECT_TRUE(OpenDocument("bug_551460.pdf")); + FPDF_PAGE page = LoadPage(0); + EXPECT_NE(nullptr, page); + FPDF_BITMAP bitmap = RenderPage(page); + FPDFBitmap_Destroy(bitmap); + UnloadPage(page); +} diff --git a/core/fpdfapi/page/fpdf_page_parser.cpp b/core/fpdfapi/page/fpdf_page_parser.cpp new file mode 100644 index 0000000000..e19d99a971 --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_parser.cpp @@ -0,0 +1,1683 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/pageint.h" + +#include +#include +#include + +#include "core/fpdfapi/edit/cpdf_creator.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_type3font.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_name.h" +#include "core/fpdfapi/fpdf_parser/cpdf_number.h" +#include "core/fpdfapi/fpdf_parser/cpdf_reference.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" +#include "core/fpdfapi/page/cpdf_allstates.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_formobject.h" +#include "core/fpdfapi/page/cpdf_image.h" +#include "core/fpdfapi/page/cpdf_imageobject.h" +#include "core/fpdfapi/page/cpdf_meshstream.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_shadingobject.h" +#include "core/fpdfapi/page/cpdf_shadingpattern.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "core/fxcrt/fx_safe_types.h" +#include "core/fxge/cfx_graphstatedata.h" +#include "core/fxge/cfx_pathdata.h" +#include "third_party/base/ptr_util.h" + +namespace { + +const int kSingleCoordinatePair = 1; +const int kTensorCoordinatePairs = 16; +const int kCoonsCoordinatePairs = 12; +const int kSingleColorPerPatch = 1; +const int kQuadColorsPerPatch = 4; + +const char kPathOperatorSubpath = 'm'; +const char kPathOperatorLine = 'l'; +const char kPathOperatorCubicBezier1 = 'c'; +const char kPathOperatorCubicBezier2 = 'v'; +const char kPathOperatorCubicBezier3 = 'y'; +const char kPathOperatorClosePath = 'h'; +const char kPathOperatorRectangle[] = "re"; + +struct PDF_AbbrPair { + const FX_CHAR* abbr; + const FX_CHAR* full_name; +}; + +const PDF_AbbrPair PDF_InlineKeyAbbr[] = { + {"BPC", "BitsPerComponent"}, {"CS", "ColorSpace"}, {"D", "Decode"}, + {"DP", "DecodeParms"}, {"F", "Filter"}, {"H", "Height"}, + {"IM", "ImageMask"}, {"I", "Interpolate"}, {"W", "Width"}, +}; + +const PDF_AbbrPair PDF_InlineValueAbbr[] = { + {"G", "DeviceGray"}, {"RGB", "DeviceRGB"}, + {"CMYK", "DeviceCMYK"}, {"I", "Indexed"}, + {"AHx", "ASCIIHexDecode"}, {"A85", "ASCII85Decode"}, + {"LZW", "LZWDecode"}, {"Fl", "FlateDecode"}, + {"RL", "RunLengthDecode"}, {"CCF", "CCITTFaxDecode"}, + {"DCT", "DCTDecode"}, +}; + +struct AbbrReplacementOp { + bool is_replace_key; + CFX_ByteString key; + CFX_ByteStringC replacement; +}; + +class CPDF_StreamParserAutoClearer { + public: + CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable, + CPDF_StreamParser* new_parser) + : scoped_variable_(scoped_variable) { + *scoped_variable_ = new_parser; + } + ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = nullptr; } + + private: + CPDF_StreamParser** scoped_variable_; +}; + +CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, + size_t count, + const CFX_ByteStringC& abbr) { + auto it = std::find_if( + table, table + count, + [abbr](const PDF_AbbrPair& pair) { return pair.abbr == abbr; }); + return it != table + count ? CFX_ByteStringC(it->full_name) + : CFX_ByteStringC(); +} + +CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, + const CFX_Matrix& matrix) { + ShadingType type = pShading->GetShadingType(); + CPDF_Stream* pStream = ToStream(pShading->GetShadingObject()); + CPDF_ColorSpace* pCS = pShading->GetCS(); + if (!pStream || !pCS) + return CFX_FloatRect(0, 0, 0, 0); + + CPDF_MeshStream stream(type, pShading->GetFuncs(), pStream, pCS); + if (!stream.Load()) + return CFX_FloatRect(0, 0, 0, 0); + + CFX_FloatRect rect; + bool bStarted = false; + bool bGouraud = type == kFreeFormGouraudTriangleMeshShading || + type == kLatticeFormGouraudTriangleMeshShading; + + int point_count = kSingleCoordinatePair; + if (type == kTensorProductPatchMeshShading) + point_count = kTensorCoordinatePairs; + else if (type == kCoonsPatchMeshShading) + point_count = kCoonsCoordinatePairs; + + int color_count = kSingleColorPerPatch; + if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading) + color_count = kQuadColorsPerPatch; + + while (!stream.BitStream()->IsEOF()) { + uint32_t flag = 0; + if (type != kLatticeFormGouraudTriangleMeshShading) + flag = stream.GetFlag(); + + if (!bGouraud && flag) { + point_count -= 4; + color_count -= 2; + } + + for (int i = 0; i < point_count; i++) { + FX_FLOAT x; + FX_FLOAT y; + stream.GetCoords(x, y); + if (bStarted) { + rect.UpdateRect(x, y); + } else { + rect.InitRect(x, y); + bStarted = true; + } + } + FX_SAFE_UINT32 nBits = stream.Components(); + nBits *= stream.ComponentBits(); + nBits *= color_count; + if (!nBits.IsValid()) + break; + + stream.BitStream()->SkipBits(nBits.ValueOrDie()); + if (bGouraud) + stream.BitStream()->ByteAlign(); + } + rect.Transform(&matrix); + return rect; +} + +} // namespace + +CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { + return PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), + abbr); +} + +CFX_ByteStringC PDF_FindValueAbbreviationForTesting( + const CFX_ByteStringC& abbr) { + return PDF_FindFullName(PDF_InlineValueAbbr, + FX_ArraySize(PDF_InlineValueAbbr), abbr); +} + +bool IsPathOperator(const uint8_t* buf, size_t len) { + if (len == 1) { + uint8_t op = buf[0]; + return op == kPathOperatorSubpath || op == kPathOperatorLine || + op == kPathOperatorCubicBezier1 || op == kPathOperatorCubicBezier2 || + op == kPathOperatorCubicBezier3; + } + if (len == 2) { + return buf[0] == kPathOperatorRectangle[0] && + buf[1] == kPathOperatorRectangle[1]; + } + return false; +} + +CPDF_StreamContentParser::CPDF_StreamContentParser( + CPDF_Document* pDocument, + CPDF_Dictionary* pPageResources, + CPDF_Dictionary* pParentResources, + const CFX_Matrix* pmtContentToUser, + CPDF_PageObjectHolder* pObjHolder, + CPDF_Dictionary* pResources, + CFX_FloatRect* pBBox, + CPDF_AllStates* pStates, + int level) + : m_pDocument(pDocument), + m_pPageResources(pPageResources), + m_pParentResources(pParentResources), + m_pResources(pResources), + m_pObjectHolder(pObjHolder), + m_Level(level), + m_ParamStartPos(0), + m_ParamCount(0), + m_pCurStates(new CPDF_AllStates), + m_pLastTextObject(nullptr), + m_DefFontSize(0), + m_pPathPoints(nullptr), + m_PathPointCount(0), + m_PathAllocSize(0), + m_PathCurrentX(0.0f), + m_PathCurrentY(0.0f), + m_PathClipType(0), + m_pLastImage(nullptr), + m_pLastImageDict(nullptr), + m_pLastCloneImageDict(nullptr), + m_bReleaseLastDict(TRUE), + m_bColored(FALSE), + m_bResourceMissing(FALSE) { + if (pmtContentToUser) + m_mtContentToUser = *pmtContentToUser; + if (!m_pResources) + m_pResources = m_pParentResources; + if (!m_pResources) + m_pResources = m_pPageResources; + if (pBBox) + m_BBox = *pBBox; + if (pStates) { + m_pCurStates->Copy(*pStates); + } else { + m_pCurStates->m_GeneralState.Emplace(); + m_pCurStates->m_GraphState.Emplace(); + m_pCurStates->m_TextState.Emplace(); + m_pCurStates->m_ColorState.Emplace(); + } + for (size_t i = 0; i < FX_ArraySize(m_Type3Data); ++i) { + m_Type3Data[i] = 0.0; + } +} + +CPDF_StreamContentParser::~CPDF_StreamContentParser() { + ClearAllParams(); + FX_Free(m_pPathPoints); + if (m_pLastImageDict) { + m_pLastImageDict->Release(); + } + if (m_pLastCloneImageDict) { + m_pLastCloneImageDict->Release(); + } +} + +int CPDF_StreamContentParser::GetNextParamPos() { + if (m_ParamCount == PARAM_BUF_SIZE) { + m_ParamStartPos++; + if (m_ParamStartPos == PARAM_BUF_SIZE) { + m_ParamStartPos = 0; + } + if (m_ParamBuf[m_ParamStartPos].m_Type == 0) { + if (CPDF_Object* pObject = m_ParamBuf[m_ParamStartPos].m_pObject) + pObject->Release(); + } + return m_ParamStartPos; + } + int index = m_ParamStartPos + m_ParamCount; + if (index >= PARAM_BUF_SIZE) { + index -= PARAM_BUF_SIZE; + } + m_ParamCount++; + return index; +} + +void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) { + CFX_ByteStringC bsName(name, len); + ContentParam& param = m_ParamBuf[GetNextParamPos()]; + if (len > 32) { + param.m_Type = ContentParam::OBJECT; + param.m_pObject = new CPDF_Name( + m_pDocument->GetByteStringPool()->Intern(PDF_NameDecode(bsName))); + } else { + param.m_Type = ContentParam::NAME; + if (bsName.Find('#') == -1) { + FXSYS_memcpy(param.m_Name.m_Buffer, name, len); + param.m_Name.m_Len = len; + } else { + CFX_ByteString str = PDF_NameDecode(bsName); + FXSYS_memcpy(param.m_Name.m_Buffer, str.c_str(), str.GetLength()); + param.m_Name.m_Len = str.GetLength(); + } + } +} + +void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len) { + ContentParam& param = m_ParamBuf[GetNextParamPos()]; + param.m_Type = ContentParam::NUMBER; + param.m_Number.m_bInteger = + FX_atonum(CFX_ByteStringC(str, len), ¶m.m_Number.m_Integer); +} + +void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) { + ContentParam& param = m_ParamBuf[GetNextParamPos()]; + param.m_Type = ContentParam::OBJECT; + param.m_pObject = pObj; +} + +void CPDF_StreamContentParser::ClearAllParams() { + uint32_t index = m_ParamStartPos; + for (uint32_t i = 0; i < m_ParamCount; i++) { + if (m_ParamBuf[index].m_Type == 0) { + if (CPDF_Object* pObject = m_ParamBuf[index].m_pObject) + pObject->Release(); + } + index++; + if (index == PARAM_BUF_SIZE) { + index = 0; + } + } + m_ParamStartPos = 0; + m_ParamCount = 0; +} + +CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) { + if (index >= m_ParamCount) { + return nullptr; + } + int real_index = m_ParamStartPos + m_ParamCount - index - 1; + if (real_index >= PARAM_BUF_SIZE) { + real_index -= PARAM_BUF_SIZE; + } + ContentParam& param = m_ParamBuf[real_index]; + if (param.m_Type == ContentParam::NUMBER) { + CPDF_Number* pNumber = param.m_Number.m_bInteger + ? new CPDF_Number(param.m_Number.m_Integer) + : new CPDF_Number(param.m_Number.m_Float); + + param.m_Type = ContentParam::OBJECT; + param.m_pObject = pNumber; + return pNumber; + } + if (param.m_Type == ContentParam::NAME) { + CPDF_Name* pName = new CPDF_Name(m_pDocument->GetByteStringPool()->Intern( + CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len))); + param.m_Type = ContentParam::OBJECT; + param.m_pObject = pName; + return pName; + } + if (param.m_Type == ContentParam::OBJECT) { + return param.m_pObject; + } + ASSERT(FALSE); + return nullptr; +} + +CFX_ByteString CPDF_StreamContentParser::GetString(uint32_t index) { + if (index >= m_ParamCount) { + return CFX_ByteString(); + } + int real_index = m_ParamStartPos + m_ParamCount - index - 1; + if (real_index >= PARAM_BUF_SIZE) { + real_index -= PARAM_BUF_SIZE; + } + ContentParam& param = m_ParamBuf[real_index]; + if (param.m_Type == ContentParam::NAME) { + return CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len); + } + if (param.m_Type == 0 && param.m_pObject) { + return param.m_pObject->GetString(); + } + return CFX_ByteString(); +} + +FX_FLOAT CPDF_StreamContentParser::GetNumber(uint32_t index) { + if (index >= m_ParamCount) { + return 0; + } + int real_index = m_ParamStartPos + m_ParamCount - index - 1; + if (real_index >= PARAM_BUF_SIZE) { + real_index -= PARAM_BUF_SIZE; + } + ContentParam& param = m_ParamBuf[real_index]; + if (param.m_Type == ContentParam::NUMBER) { + return param.m_Number.m_bInteger ? (FX_FLOAT)param.m_Number.m_Integer + : param.m_Number.m_Float; + } + if (param.m_Type == 0 && param.m_pObject) { + return param.m_pObject->GetNumber(); + } + return 0; +} + +void CPDF_StreamContentParser::SetGraphicStates(CPDF_PageObject* pObj, + FX_BOOL bColor, + FX_BOOL bText, + FX_BOOL bGraph) { + pObj->m_GeneralState = m_pCurStates->m_GeneralState; + pObj->m_ClipPath = m_pCurStates->m_ClipPath; + pObj->m_ContentMark = m_CurContentMark; + if (bColor) { + pObj->m_ColorState = m_pCurStates->m_ColorState; + } + if (bGraph) { + pObj->m_GraphState = m_pCurStates->m_GraphState; + } + if (bText) { + pObj->m_TextState = m_pCurStates->m_TextState; + } +} + +// static +CPDF_StreamContentParser::OpCodes +CPDF_StreamContentParser::InitializeOpCodes() { + return OpCodes({ + {FXBSTR_ID('"', 0, 0, 0), + &CPDF_StreamContentParser::Handle_NextLineShowText_Space}, + {FXBSTR_ID('\'', 0, 0, 0), + &CPDF_StreamContentParser::Handle_NextLineShowText}, + {FXBSTR_ID('B', 0, 0, 0), + &CPDF_StreamContentParser::Handle_FillStrokePath}, + {FXBSTR_ID('B', '*', 0, 0), + &CPDF_StreamContentParser::Handle_EOFillStrokePath}, + {FXBSTR_ID('B', 'D', 'C', 0), + &CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary}, + {FXBSTR_ID('B', 'I', 0, 0), &CPDF_StreamContentParser::Handle_BeginImage}, + {FXBSTR_ID('B', 'M', 'C', 0), + &CPDF_StreamContentParser::Handle_BeginMarkedContent}, + {FXBSTR_ID('B', 'T', 0, 0), &CPDF_StreamContentParser::Handle_BeginText}, + {FXBSTR_ID('C', 'S', 0, 0), + &CPDF_StreamContentParser::Handle_SetColorSpace_Stroke}, + {FXBSTR_ID('D', 'P', 0, 0), + &CPDF_StreamContentParser::Handle_MarkPlace_Dictionary}, + {FXBSTR_ID('D', 'o', 0, 0), + &CPDF_StreamContentParser::Handle_ExecuteXObject}, + {FXBSTR_ID('E', 'I', 0, 0), &CPDF_StreamContentParser::Handle_EndImage}, + {FXBSTR_ID('E', 'M', 'C', 0), + &CPDF_StreamContentParser::Handle_EndMarkedContent}, + {FXBSTR_ID('E', 'T', 0, 0), &CPDF_StreamContentParser::Handle_EndText}, + {FXBSTR_ID('F', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPathOld}, + {FXBSTR_ID('G', 0, 0, 0), + &CPDF_StreamContentParser::Handle_SetGray_Stroke}, + {FXBSTR_ID('I', 'D', 0, 0), + &CPDF_StreamContentParser::Handle_BeginImageData}, + {FXBSTR_ID('J', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineCap}, + {FXBSTR_ID('K', 0, 0, 0), + &CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke}, + {FXBSTR_ID('M', 0, 0, 0), + &CPDF_StreamContentParser::Handle_SetMiterLimit}, + {FXBSTR_ID('M', 'P', 0, 0), &CPDF_StreamContentParser::Handle_MarkPlace}, + {FXBSTR_ID('Q', 0, 0, 0), + &CPDF_StreamContentParser::Handle_RestoreGraphState}, + {FXBSTR_ID('R', 'G', 0, 0), + &CPDF_StreamContentParser::Handle_SetRGBColor_Stroke}, + {FXBSTR_ID('S', 0, 0, 0), &CPDF_StreamContentParser::Handle_StrokePath}, + {FXBSTR_ID('S', 'C', 0, 0), + &CPDF_StreamContentParser::Handle_SetColor_Stroke}, + {FXBSTR_ID('S', 'C', 'N', 0), + &CPDF_StreamContentParser::Handle_SetColorPS_Stroke}, + {FXBSTR_ID('T', '*', 0, 0), + &CPDF_StreamContentParser::Handle_MoveToNextLine}, + {FXBSTR_ID('T', 'D', 0, 0), + &CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading}, + {FXBSTR_ID('T', 'J', 0, 0), + &CPDF_StreamContentParser::Handle_ShowText_Positioning}, + {FXBSTR_ID('T', 'L', 0, 0), + &CPDF_StreamContentParser::Handle_SetTextLeading}, + {FXBSTR_ID('T', 'c', 0, 0), + &CPDF_StreamContentParser::Handle_SetCharSpace}, + {FXBSTR_ID('T', 'd', 0, 0), + &CPDF_StreamContentParser::Handle_MoveTextPoint}, + {FXBSTR_ID('T', 'f', 0, 0), &CPDF_StreamContentParser::Handle_SetFont}, + {FXBSTR_ID('T', 'j', 0, 0), &CPDF_StreamContentParser::Handle_ShowText}, + {FXBSTR_ID('T', 'm', 0, 0), + &CPDF_StreamContentParser::Handle_SetTextMatrix}, + {FXBSTR_ID('T', 'r', 0, 0), + &CPDF_StreamContentParser::Handle_SetTextRenderMode}, + {FXBSTR_ID('T', 's', 0, 0), + &CPDF_StreamContentParser::Handle_SetTextRise}, + {FXBSTR_ID('T', 'w', 0, 0), + &CPDF_StreamContentParser::Handle_SetWordSpace}, + {FXBSTR_ID('T', 'z', 0, 0), + &CPDF_StreamContentParser::Handle_SetHorzScale}, + {FXBSTR_ID('W', 0, 0, 0), &CPDF_StreamContentParser::Handle_Clip}, + {FXBSTR_ID('W', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOClip}, + {FXBSTR_ID('b', 0, 0, 0), + &CPDF_StreamContentParser::Handle_CloseFillStrokePath}, + {FXBSTR_ID('b', '*', 0, 0), + &CPDF_StreamContentParser::Handle_CloseEOFillStrokePath}, + {FXBSTR_ID('c', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_123}, + {FXBSTR_ID('c', 'm', 0, 0), + &CPDF_StreamContentParser::Handle_ConcatMatrix}, + {FXBSTR_ID('c', 's', 0, 0), + &CPDF_StreamContentParser::Handle_SetColorSpace_Fill}, + {FXBSTR_ID('d', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetDash}, + {FXBSTR_ID('d', '0', 0, 0), + &CPDF_StreamContentParser::Handle_SetCharWidth}, + {FXBSTR_ID('d', '1', 0, 0), + &CPDF_StreamContentParser::Handle_SetCachedDevice}, + {FXBSTR_ID('f', 0, 0, 0), &CPDF_StreamContentParser::Handle_FillPath}, + {FXBSTR_ID('f', '*', 0, 0), &CPDF_StreamContentParser::Handle_EOFillPath}, + {FXBSTR_ID('g', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetGray_Fill}, + {FXBSTR_ID('g', 's', 0, 0), + &CPDF_StreamContentParser::Handle_SetExtendGraphState}, + {FXBSTR_ID('h', 0, 0, 0), &CPDF_StreamContentParser::Handle_ClosePath}, + {FXBSTR_ID('i', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetFlat}, + {FXBSTR_ID('j', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineJoin}, + {FXBSTR_ID('k', 0, 0, 0), + &CPDF_StreamContentParser::Handle_SetCMYKColor_Fill}, + {FXBSTR_ID('l', 0, 0, 0), &CPDF_StreamContentParser::Handle_LineTo}, + {FXBSTR_ID('m', 0, 0, 0), &CPDF_StreamContentParser::Handle_MoveTo}, + {FXBSTR_ID('n', 0, 0, 0), &CPDF_StreamContentParser::Handle_EndPath}, + {FXBSTR_ID('q', 0, 0, 0), + &CPDF_StreamContentParser::Handle_SaveGraphState}, + {FXBSTR_ID('r', 'e', 0, 0), &CPDF_StreamContentParser::Handle_Rectangle}, + {FXBSTR_ID('r', 'g', 0, 0), + &CPDF_StreamContentParser::Handle_SetRGBColor_Fill}, + {FXBSTR_ID('r', 'i', 0, 0), + &CPDF_StreamContentParser::Handle_SetRenderIntent}, + {FXBSTR_ID('s', 0, 0, 0), + &CPDF_StreamContentParser::Handle_CloseStrokePath}, + {FXBSTR_ID('s', 'c', 0, 0), + &CPDF_StreamContentParser::Handle_SetColor_Fill}, + {FXBSTR_ID('s', 'c', 'n', 0), + &CPDF_StreamContentParser::Handle_SetColorPS_Fill}, + {FXBSTR_ID('s', 'h', 0, 0), &CPDF_StreamContentParser::Handle_ShadeFill}, + {FXBSTR_ID('v', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_23}, + {FXBSTR_ID('w', 0, 0, 0), &CPDF_StreamContentParser::Handle_SetLineWidth}, + {FXBSTR_ID('y', 0, 0, 0), &CPDF_StreamContentParser::Handle_CurveTo_13}, + }); +} + +void CPDF_StreamContentParser::OnOperator(const FX_CHAR* op) { + int i = 0; + uint32_t opid = 0; + while (i < 4 && op[i]) { + opid = (opid << 8) + op[i]; + i++; + } + while (i < 4) { + opid <<= 8; + i++; + } + + static const OpCodes s_OpCodes = InitializeOpCodes(); + + auto it = s_OpCodes.find(opid); + if (it != s_OpCodes.end()) + (this->*it->second)(); +} + +void CPDF_StreamContentParser::Handle_CloseFillStrokePath() { + Handle_ClosePath(); + AddPathObject(FXFILL_WINDING, TRUE); +} + +void CPDF_StreamContentParser::Handle_FillStrokePath() { + AddPathObject(FXFILL_WINDING, TRUE); +} + +void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() { + AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); + AddPathObject(FXFILL_ALTERNATE, TRUE); +} + +void CPDF_StreamContentParser::Handle_EOFillStrokePath() { + AddPathObject(FXFILL_ALTERNATE, TRUE); +} + +void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() { + CFX_ByteString tag = GetString(1); + CPDF_Object* pProperty = GetObject(0); + if (!pProperty) { + return; + } + FX_BOOL bDirect = TRUE; + if (pProperty->IsName()) { + pProperty = FindResourceObj("Properties", pProperty->GetString()); + if (!pProperty) + return; + bDirect = FALSE; + } + if (CPDF_Dictionary* pDict = pProperty->AsDictionary()) { + m_CurContentMark.AddMark(tag, pDict, bDirect); + } +} + +void CPDF_StreamContentParser::Handle_BeginImage() { + FX_FILESIZE savePos = m_pSyntax->GetPos(); + CPDF_Dictionary* pDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); + while (1) { + CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); + if (type == CPDF_StreamParser::Keyword) { + CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), + m_pSyntax->GetWordSize()); + if (bsKeyword != "ID") { + m_pSyntax->SetPos(savePos); + pDict->Release(); + return; + } + } + if (type != CPDF_StreamParser::Name) { + break; + } + CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, + m_pSyntax->GetWordSize() - 1); + std::unique_ptr> pObj( + m_pSyntax->ReadNextObject(false, 0)); + if (!key.IsEmpty()) { + uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; + if (dwObjNum) + pDict->SetReferenceFor(key, m_pDocument, dwObjNum); + else + pDict->SetFor(key, pObj.release()); + } + } + PDF_ReplaceAbbr(pDict); + CPDF_Object* pCSObj = nullptr; + if (pDict->KeyExist("ColorSpace")) { + pCSObj = pDict->GetDirectObjectFor("ColorSpace"); + if (pCSObj->IsName()) { + CFX_ByteString name = pCSObj->GetString(); + if (name != "DeviceRGB" && name != "DeviceGray" && name != "DeviceCMYK") { + pCSObj = FindResourceObj("ColorSpace", name); + if (pCSObj && !pCSObj->GetObjNum()) { + pCSObj = pCSObj->Clone(); + pDict->SetFor("ColorSpace", pCSObj); + } + } + } + } + CPDF_Stream* pStream = + m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSObj); + while (1) { + CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); + if (type == CPDF_StreamParser::EndOfData) { + break; + } + if (type != CPDF_StreamParser::Keyword) { + continue; + } + if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && + m_pSyntax->GetWordBuf()[1] == 'I') { + break; + } + } + pDict->SetNameFor("Subtype", "Image"); + CPDF_ImageObject* pImgObj = AddImage(pStream, nullptr, true); + if (!pImgObj) { + if (pStream) { + pStream->Release(); + } else { + pDict->Release(); + } + } +} + +void CPDF_StreamContentParser::Handle_BeginMarkedContent() { + m_CurContentMark.AddMark(GetString(0), nullptr, FALSE); +} + +void CPDF_StreamContentParser::Handle_BeginText() { + m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); + OnChangeTextMatrix(); + m_pCurStates->m_TextX = 0; + m_pCurStates->m_TextY = 0; + m_pCurStates->m_TextLineX = 0; + m_pCurStates->m_TextLineY = 0; +} + +void CPDF_StreamContentParser::Handle_CurveTo_123() { + AddPathPoint(GetNumber(5), GetNumber(4), FXPT_BEZIERTO); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); +} + +void CPDF_StreamContentParser::Handle_ConcatMatrix() { + CFX_Matrix new_matrix(GetNumber(5), GetNumber(4), GetNumber(3), GetNumber(2), + GetNumber(1), GetNumber(0)); + new_matrix.Concat(m_pCurStates->m_CTM); + m_pCurStates->m_CTM = new_matrix; + OnChangeTextMatrix(); +} + +void CPDF_StreamContentParser::Handle_SetColorSpace_Fill() { + CPDF_ColorSpace* pCS = FindColorSpace(GetString(0)); + if (!pCS) + return; + + m_pCurStates->m_ColorState.GetMutableFillColor()->SetColorSpace(pCS); +} + +void CPDF_StreamContentParser::Handle_SetColorSpace_Stroke() { + CPDF_ColorSpace* pCS = FindColorSpace(GetString(0)); + if (!pCS) + return; + + m_pCurStates->m_ColorState.GetMutableStrokeColor()->SetColorSpace(pCS); +} + +void CPDF_StreamContentParser::Handle_SetDash() { + CPDF_Array* pArray = ToArray(GetObject(1)); + if (!pArray) + return; + + m_pCurStates->SetLineDash(pArray, GetNumber(0), 1.0f); +} + +void CPDF_StreamContentParser::Handle_SetCharWidth() { + m_Type3Data[0] = GetNumber(1); + m_Type3Data[1] = GetNumber(0); + m_bColored = TRUE; +} + +void CPDF_StreamContentParser::Handle_SetCachedDevice() { + for (int i = 0; i < 6; i++) { + m_Type3Data[i] = GetNumber(5 - i); + } + m_bColored = FALSE; +} + +void CPDF_StreamContentParser::Handle_ExecuteXObject() { + CFX_ByteString name = GetString(0); + if (name == m_LastImageName && m_pLastImage && m_pLastImage->GetStream() && + m_pLastImage->GetStream()->GetObjNum()) { + AddImage(nullptr, m_pLastImage, false); + return; + } + + CPDF_Stream* pXObject = ToStream(FindResourceObj("XObject", name)); + if (!pXObject) { + m_bResourceMissing = TRUE; + return; + } + + CFX_ByteString type; + if (pXObject->GetDict()) + type = pXObject->GetDict()->GetStringFor("Subtype"); + + if (type == "Image") { + CPDF_ImageObject* pObj = AddImage(pXObject, nullptr, false); + m_LastImageName = name; + m_pLastImage = pObj->GetImage(); + if (!m_pObjectHolder->HasImageMask()) + m_pObjectHolder->SetHasImageMask(m_pLastImage->IsMask()); + } else if (type == "Form") { + AddForm(pXObject); + } +} + +void CPDF_StreamContentParser::AddForm(CPDF_Stream* pStream) { + std::unique_ptr pFormObj(new CPDF_FormObject); + pFormObj->m_pForm.reset( + new CPDF_Form(m_pDocument, m_pPageResources, pStream, m_pResources)); + pFormObj->m_FormMatrix = m_pCurStates->m_CTM; + pFormObj->m_FormMatrix.Concat(m_mtContentToUser); + CPDF_AllStates status; + status.m_GeneralState = m_pCurStates->m_GeneralState; + status.m_GraphState = m_pCurStates->m_GraphState; + status.m_ColorState = m_pCurStates->m_ColorState; + status.m_TextState = m_pCurStates->m_TextState; + pFormObj->m_pForm->ParseContent(&status, nullptr, nullptr, m_Level + 1); + if (!m_pObjectHolder->BackgroundAlphaNeeded() && + pFormObj->m_pForm->BackgroundAlphaNeeded()) { + m_pObjectHolder->SetBackgroundAlphaNeeded(TRUE); + } + pFormObj->CalcBoundingBox(); + SetGraphicStates(pFormObj.get(), TRUE, TRUE, TRUE); + m_pObjectHolder->GetPageObjectList()->push_back(std::move(pFormObj)); +} + +CPDF_ImageObject* CPDF_StreamContentParser::AddImage(CPDF_Stream* pStream, + CPDF_Image* pImage, + bool bInline) { + if (!pStream && !pImage) + return nullptr; + + CFX_Matrix ImageMatrix = m_pCurStates->m_CTM; + ImageMatrix.Concat(m_mtContentToUser); + + std::unique_ptr pImageObj(new CPDF_ImageObject); + if (pImage) { + pImageObj->SetUnownedImage( + m_pDocument->GetPageData()->GetImage(pImage->GetStream())); + } else if (pStream->GetObjNum()) { + pImageObj->SetUnownedImage(m_pDocument->LoadImageF(pStream)); + } else { + pImageObj->SetOwnedImage( + pdfium::MakeUnique(m_pDocument, pStream, bInline)); + } + SetGraphicStates(pImageObj.get(), pImageObj->GetImage()->IsMask(), FALSE, + FALSE); + pImageObj->m_Matrix = ImageMatrix; + pImageObj->CalcBoundingBox(); + CPDF_ImageObject* pRet = pImageObj.get(); + m_pObjectHolder->GetPageObjectList()->push_back(std::move(pImageObj)); + return pRet; +} + +void CPDF_StreamContentParser::Handle_MarkPlace_Dictionary() {} + +void CPDF_StreamContentParser::Handle_EndImage() {} + +void CPDF_StreamContentParser::Handle_EndMarkedContent() { + if (m_CurContentMark) + m_CurContentMark.DeleteLastMark(); +} + +void CPDF_StreamContentParser::Handle_EndText() { + if (m_ClipTextList.empty()) + return; + + if (TextRenderingModeIsClipMode(m_pCurStates->m_TextState.GetTextMode())) + m_pCurStates->m_ClipPath.AppendTexts(&m_ClipTextList); + + m_ClipTextList.clear(); +} + +void CPDF_StreamContentParser::Handle_FillPath() { + AddPathObject(FXFILL_WINDING, FALSE); +} + +void CPDF_StreamContentParser::Handle_FillPathOld() { + AddPathObject(FXFILL_WINDING, FALSE); +} + +void CPDF_StreamContentParser::Handle_EOFillPath() { + AddPathObject(FXFILL_ALTERNATE, FALSE); +} + +void CPDF_StreamContentParser::Handle_SetGray_Fill() { + FX_FLOAT value = GetNumber(0); + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + m_pCurStates->m_ColorState.SetFillColor(pCS, &value, 1); +} + +void CPDF_StreamContentParser::Handle_SetGray_Stroke() { + FX_FLOAT value = GetNumber(0); + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + m_pCurStates->m_ColorState.SetStrokeColor(pCS, &value, 1); +} + +void CPDF_StreamContentParser::Handle_SetExtendGraphState() { + CFX_ByteString name = GetString(0); + CPDF_Dictionary* pGS = ToDictionary(FindResourceObj("ExtGState", name)); + if (!pGS) { + m_bResourceMissing = TRUE; + return; + } + m_pCurStates->ProcessExtGS(pGS, this); +} + +void CPDF_StreamContentParser::Handle_ClosePath() { + if (m_PathPointCount == 0) { + return; + } + if (m_PathStartX != m_PathCurrentX || m_PathStartY != m_PathCurrentY) { + AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); + } else if (m_pPathPoints[m_PathPointCount - 1].m_Flag != FXPT_MOVETO) { + m_pPathPoints[m_PathPointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; + } +} + +void CPDF_StreamContentParser::Handle_SetFlat() { + m_pCurStates->m_GeneralState.SetFlatness(GetNumber(0)); +} + +void CPDF_StreamContentParser::Handle_BeginImageData() {} + +void CPDF_StreamContentParser::Handle_SetLineJoin() { + m_pCurStates->m_GraphState.SetLineJoin( + static_cast(GetInteger(0))); +} + +void CPDF_StreamContentParser::Handle_SetLineCap() { + m_pCurStates->m_GraphState.SetLineCap( + static_cast(GetInteger(0))); +} + +void CPDF_StreamContentParser::Handle_SetCMYKColor_Fill() { + if (m_ParamCount != 4) + return; + + FX_FLOAT values[4]; + for (int i = 0; i < 4; i++) { + values[i] = GetNumber(3 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + m_pCurStates->m_ColorState.SetFillColor(pCS, values, 4); +} + +void CPDF_StreamContentParser::Handle_SetCMYKColor_Stroke() { + if (m_ParamCount != 4) + return; + + FX_FLOAT values[4]; + for (int i = 0; i < 4; i++) { + values[i] = GetNumber(3 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 4); +} + +void CPDF_StreamContentParser::Handle_LineTo() { + if (m_ParamCount != 2) + return; + + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO); +} + +void CPDF_StreamContentParser::Handle_MoveTo() { + if (m_ParamCount != 2) + return; + + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO); + ParsePathObject(); +} + +void CPDF_StreamContentParser::Handle_SetMiterLimit() { + m_pCurStates->m_GraphState.SetMiterLimit(GetNumber(0)); +} + +void CPDF_StreamContentParser::Handle_MarkPlace() {} + +void CPDF_StreamContentParser::Handle_EndPath() { + AddPathObject(0, FALSE); +} + +void CPDF_StreamContentParser::Handle_SaveGraphState() { + std::unique_ptr pStates(new CPDF_AllStates); + pStates->Copy(*m_pCurStates); + m_StateStack.push_back(std::move(pStates)); +} + +void CPDF_StreamContentParser::Handle_RestoreGraphState() { + if (m_StateStack.empty()) + return; + std::unique_ptr pStates = std::move(m_StateStack.back()); + m_StateStack.pop_back(); + m_pCurStates->Copy(*pStates); +} + +void CPDF_StreamContentParser::Handle_Rectangle() { + FX_FLOAT x = GetNumber(3), y = GetNumber(2); + FX_FLOAT w = GetNumber(1), h = GetNumber(0); + AddPathRect(x, y, w, h); +} + +void CPDF_StreamContentParser::AddPathRect(FX_FLOAT x, + FX_FLOAT y, + FX_FLOAT w, + FX_FLOAT h) { + AddPathPoint(x, y, FXPT_MOVETO); + AddPathPoint(x + w, y, FXPT_LINETO); + AddPathPoint(x + w, y + h, FXPT_LINETO); + AddPathPoint(x, y + h, FXPT_LINETO); + AddPathPoint(x, y, FXPT_LINETO | FXPT_CLOSEFIGURE); +} + +void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() { + if (m_ParamCount != 3) + return; + + FX_FLOAT values[3]; + for (int i = 0; i < 3; i++) { + values[i] = GetNumber(2 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + m_pCurStates->m_ColorState.SetFillColor(pCS, values, 3); +} + +void CPDF_StreamContentParser::Handle_SetRGBColor_Stroke() { + if (m_ParamCount != 3) + return; + + FX_FLOAT values[3]; + for (int i = 0; i < 3; i++) { + values[i] = GetNumber(2 - i); + } + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + m_pCurStates->m_ColorState.SetStrokeColor(pCS, values, 3); +} + +void CPDF_StreamContentParser::Handle_SetRenderIntent() {} + +void CPDF_StreamContentParser::Handle_CloseStrokePath() { + Handle_ClosePath(); + AddPathObject(0, TRUE); +} + +void CPDF_StreamContentParser::Handle_StrokePath() { + AddPathObject(0, TRUE); +} + +void CPDF_StreamContentParser::Handle_SetColor_Fill() { + FX_FLOAT values[4]; + int nargs = m_ParamCount; + if (nargs > 4) { + nargs = 4; + } + for (int i = 0; i < nargs; i++) { + values[i] = GetNumber(nargs - i - 1); + } + m_pCurStates->m_ColorState.SetFillColor(nullptr, values, nargs); +} + +void CPDF_StreamContentParser::Handle_SetColor_Stroke() { + FX_FLOAT values[4]; + int nargs = m_ParamCount; + if (nargs > 4) { + nargs = 4; + } + for (int i = 0; i < nargs; i++) { + values[i] = GetNumber(nargs - i - 1); + } + m_pCurStates->m_ColorState.SetStrokeColor(nullptr, values, nargs); +} + +void CPDF_StreamContentParser::Handle_SetColorPS_Fill() { + CPDF_Object* pLastParam = GetObject(0); + if (!pLastParam) { + return; + } + uint32_t nargs = m_ParamCount; + uint32_t nvalues = nargs; + if (pLastParam->IsName()) + nvalues--; + FX_FLOAT* values = nullptr; + if (nvalues) { + values = FX_Alloc(FX_FLOAT, nvalues); + for (uint32_t i = 0; i < nvalues; i++) { + values[i] = GetNumber(nargs - i - 1); + } + } + if (nvalues != nargs) { + CPDF_Pattern* pPattern = FindPattern(GetString(0), false); + if (pPattern) { + m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); + } + } else { + m_pCurStates->m_ColorState.SetFillColor(nullptr, values, nvalues); + } + FX_Free(values); +} + +void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { + CPDF_Object* pLastParam = GetObject(0); + if (!pLastParam) { + return; + } + int nargs = m_ParamCount; + int nvalues = nargs; + if (pLastParam->IsName()) + nvalues--; + + FX_FLOAT* values = nullptr; + if (nvalues) { + values = FX_Alloc(FX_FLOAT, nvalues); + for (int i = 0; i < nvalues; i++) { + values[i] = GetNumber(nargs - i - 1); + } + } + if (nvalues != nargs) { + CPDF_Pattern* pPattern = FindPattern(GetString(0), false); + if (pPattern) { + m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); + } + } else { + m_pCurStates->m_ColorState.SetStrokeColor(nullptr, values, nvalues); + } + FX_Free(values); +} + +void CPDF_StreamContentParser::Handle_ShadeFill() { + CPDF_Pattern* pPattern = FindPattern(GetString(0), true); + if (!pPattern) + return; + + CPDF_ShadingPattern* pShading = pPattern->AsShadingPattern(); + if (!pShading) + return; + + if (!pShading->IsShadingObject() || !pShading->Load()) + return; + + std::unique_ptr pObj(new CPDF_ShadingObject); + pObj->m_pShading = pShading; + SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE); + pObj->m_Matrix = m_pCurStates->m_CTM; + pObj->m_Matrix.Concat(m_mtContentToUser); + CFX_FloatRect bbox = + pObj->m_ClipPath ? pObj->m_ClipPath.GetClipBox() : m_BBox; + if (pShading->IsMeshShading()) + bbox.Intersect(GetShadingBBox(pShading, pObj->m_Matrix)); + pObj->m_Left = bbox.left; + pObj->m_Right = bbox.right; + pObj->m_Top = bbox.top; + pObj->m_Bottom = bbox.bottom; + m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj)); +} + +void CPDF_StreamContentParser::Handle_SetCharSpace() { + m_pCurStates->m_TextState.SetCharSpace(GetNumber(0)); +} + +void CPDF_StreamContentParser::Handle_MoveTextPoint() { + m_pCurStates->m_TextLineX += GetNumber(1); + m_pCurStates->m_TextLineY += GetNumber(0); + m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; + m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; +} + +void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading() { + Handle_MoveTextPoint(); + m_pCurStates->m_TextLeading = -GetNumber(0); +} + +void CPDF_StreamContentParser::Handle_SetFont() { + FX_FLOAT fs = GetNumber(0); + if (fs == 0) { + fs = m_DefFontSize; + } + m_pCurStates->m_TextState.SetFontSize(fs); + CPDF_Font* pFont = FindFont(GetString(1)); + if (pFont) { + m_pCurStates->m_TextState.SetFont(pFont); + } +} + +CPDF_Object* CPDF_StreamContentParser::FindResourceObj( + const CFX_ByteString& type, + const CFX_ByteString& name) { + if (!m_pResources) + return nullptr; + CPDF_Dictionary* pDict = m_pResources->GetDictFor(type); + if (pDict) + return pDict->GetDirectObjectFor(name); + if (m_pResources == m_pPageResources || !m_pPageResources) + return nullptr; + + CPDF_Dictionary* pPageDict = m_pPageResources->GetDictFor(type); + return pPageDict ? pPageDict->GetDirectObjectFor(name) : nullptr; +} + +CPDF_Font* CPDF_StreamContentParser::FindFont(const CFX_ByteString& name) { + CPDF_Dictionary* pFontDict = ToDictionary(FindResourceObj("Font", name)); + if (!pFontDict) { + m_bResourceMissing = TRUE; + return CPDF_Font::GetStockFont(m_pDocument, "Helvetica"); + } + + CPDF_Font* pFont = m_pDocument->LoadFont(pFontDict); + if (pFont && pFont->IsType3Font()) { + pFont->AsType3Font()->SetPageResources(m_pResources); + pFont->AsType3Font()->CheckType3FontMetrics(); + } + return pFont; +} + +CPDF_ColorSpace* CPDF_StreamContentParser::FindColorSpace( + const CFX_ByteString& name) { + if (name == "Pattern") { + return CPDF_ColorSpace::GetStockCS(PDFCS_PATTERN); + } + if (name == "DeviceGray" || name == "DeviceCMYK" || name == "DeviceRGB") { + CFX_ByteString defname = "Default"; + defname += name.Mid(7); + CPDF_Object* pDefObj = FindResourceObj("ColorSpace", defname); + if (!pDefObj) { + if (name == "DeviceGray") { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY); + } + if (name == "DeviceRGB") { + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + } + return CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + } + return m_pDocument->LoadColorSpace(pDefObj); + } + CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name); + if (!pCSObj) { + m_bResourceMissing = TRUE; + return nullptr; + } + return m_pDocument->LoadColorSpace(pCSObj); +} + +CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, + bool bShading) { + CPDF_Object* pPattern = + FindResourceObj(bShading ? "Shading" : "Pattern", name); + if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { + m_bResourceMissing = TRUE; + return nullptr; + } + return m_pDocument->LoadPattern(pPattern, bShading, + m_pCurStates->m_ParentMatrix); +} + +void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) { + m_pCurStates->m_TextMatrix.Transform(x, y, x, y); + ConvertUserSpace(x, y); +} + +void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) { + m_pCurStates->m_CTM.Transform(x, y, x, y); + m_mtContentToUser.Transform(x, y, x, y); +} + +void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, + FX_FLOAT fInitKerning, + FX_FLOAT* pKerning, + int nsegs) { + CPDF_Font* pFont = m_pCurStates->m_TextState.GetFont(); + if (!pFont) { + return; + } + if (fInitKerning != 0) { + if (!pFont->IsVertWriting()) { + m_pCurStates->m_TextX -= + (fInitKerning * m_pCurStates->m_TextState.GetFontSize()) / 1000; + } else { + m_pCurStates->m_TextY -= + (fInitKerning * m_pCurStates->m_TextState.GetFontSize()) / 1000; + } + } + if (nsegs == 0) { + return; + } + const TextRenderingMode text_mode = + pFont->IsType3Font() ? TextRenderingMode::MODE_FILL + : m_pCurStates->m_TextState.GetTextMode(); + { + std::unique_ptr pText(new CPDF_TextObject); + m_pLastTextObject = pText.get(); + SetGraphicStates(m_pLastTextObject, TRUE, TRUE, TRUE); + if (TextRenderingModeIsStrokeMode(text_mode)) { + FX_FLOAT* pCTM = pText->m_TextState.GetMutableCTM(); + pCTM[0] = m_pCurStates->m_CTM.a; + pCTM[1] = m_pCurStates->m_CTM.c; + pCTM[2] = m_pCurStates->m_CTM.b; + pCTM[3] = m_pCurStates->m_CTM.d; + } + pText->SetSegments(pStrs, pKerning, nsegs); + pText->m_PosX = m_pCurStates->m_TextX; + pText->m_PosY = m_pCurStates->m_TextY + m_pCurStates->m_TextRise; + ConvertTextSpace(pText->m_PosX, pText->m_PosY); + FX_FLOAT x_advance; + FX_FLOAT y_advance; + pText->CalcPositionData(&x_advance, &y_advance, + m_pCurStates->m_TextHorzScale); + m_pCurStates->m_TextX += x_advance; + m_pCurStates->m_TextY += y_advance; + if (TextRenderingModeIsClipMode(text_mode)) { + m_ClipTextList.push_back( + std::unique_ptr(pText->Clone())); + } + m_pObjectHolder->GetPageObjectList()->push_back(std::move(pText)); + } + if (pKerning && pKerning[nsegs - 1] != 0) { + if (!pFont->IsVertWriting()) { + m_pCurStates->m_TextX -= + (pKerning[nsegs - 1] * m_pCurStates->m_TextState.GetFontSize()) / + 1000; + } else { + m_pCurStates->m_TextY -= + (pKerning[nsegs - 1] * m_pCurStates->m_TextState.GetFontSize()) / + 1000; + } + } +} + +void CPDF_StreamContentParser::Handle_ShowText() { + CFX_ByteString str = GetString(0); + if (str.IsEmpty()) { + return; + } + AddTextObject(&str, 0, nullptr, 1); +} + +void CPDF_StreamContentParser::Handle_ShowText_Positioning() { + CPDF_Array* pArray = ToArray(GetObject(0)); + if (!pArray) + return; + + size_t n = pArray->GetCount(); + size_t nsegs = 0; + for (size_t i = 0; i < n; i++) { + if (pArray->GetDirectObjectAt(i)->IsString()) + nsegs++; + } + if (nsegs == 0) { + for (size_t i = 0; i < n; i++) { + m_pCurStates->m_TextX -= + (pArray->GetNumberAt(i) * m_pCurStates->m_TextState.GetFontSize()) / + 1000; + } + return; + } + CFX_ByteString* pStrs = new CFX_ByteString[nsegs]; + FX_FLOAT* pKerning = FX_Alloc(FX_FLOAT, nsegs); + size_t iSegment = 0; + FX_FLOAT fInitKerning = 0; + for (size_t i = 0; i < n; i++) { + CPDF_Object* pObj = pArray->GetDirectObjectAt(i); + if (pObj->IsString()) { + CFX_ByteString str = pObj->GetString(); + if (str.IsEmpty()) { + continue; + } + pStrs[iSegment] = str; + pKerning[iSegment++] = 0; + } else { + FX_FLOAT num = pObj ? pObj->GetNumber() : 0; + if (iSegment == 0) { + fInitKerning += num; + } else { + pKerning[iSegment - 1] += num; + } + } + } + AddTextObject(pStrs, fInitKerning, pKerning, iSegment); + delete[] pStrs; + FX_Free(pKerning); +} + +void CPDF_StreamContentParser::Handle_SetTextLeading() { + m_pCurStates->m_TextLeading = GetNumber(0); +} + +void CPDF_StreamContentParser::Handle_SetTextMatrix() { + m_pCurStates->m_TextMatrix.Set(GetNumber(5), GetNumber(4), GetNumber(3), + GetNumber(2), GetNumber(1), GetNumber(0)); + OnChangeTextMatrix(); + m_pCurStates->m_TextX = 0; + m_pCurStates->m_TextY = 0; + m_pCurStates->m_TextLineX = 0; + m_pCurStates->m_TextLineY = 0; +} + +void CPDF_StreamContentParser::OnChangeTextMatrix() { + CFX_Matrix text_matrix(m_pCurStates->m_TextHorzScale, 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f); + text_matrix.Concat(m_pCurStates->m_TextMatrix); + text_matrix.Concat(m_pCurStates->m_CTM); + text_matrix.Concat(m_mtContentToUser); + FX_FLOAT* pTextMatrix = m_pCurStates->m_TextState.GetMutableMatrix(); + pTextMatrix[0] = text_matrix.a; + pTextMatrix[1] = text_matrix.c; + pTextMatrix[2] = text_matrix.b; + pTextMatrix[3] = text_matrix.d; +} + +void CPDF_StreamContentParser::Handle_SetTextRenderMode() { + TextRenderingMode mode; + if (SetTextRenderingModeFromInt(GetInteger(0), &mode)) + m_pCurStates->m_TextState.SetTextMode(mode); +} + +void CPDF_StreamContentParser::Handle_SetTextRise() { + m_pCurStates->m_TextRise = GetNumber(0); +} + +void CPDF_StreamContentParser::Handle_SetWordSpace() { + m_pCurStates->m_TextState.SetWordSpace(GetNumber(0)); +} + +void CPDF_StreamContentParser::Handle_SetHorzScale() { + if (m_ParamCount != 1) { + return; + } + m_pCurStates->m_TextHorzScale = GetNumber(0) / 100; + OnChangeTextMatrix(); +} + +void CPDF_StreamContentParser::Handle_MoveToNextLine() { + m_pCurStates->m_TextLineY -= m_pCurStates->m_TextLeading; + m_pCurStates->m_TextX = m_pCurStates->m_TextLineX; + m_pCurStates->m_TextY = m_pCurStates->m_TextLineY; +} + +void CPDF_StreamContentParser::Handle_CurveTo_23() { + AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); +} + +void CPDF_StreamContentParser::Handle_SetLineWidth() { + m_pCurStates->m_GraphState.SetLineWidth(GetNumber(0)); +} + +void CPDF_StreamContentParser::Handle_Clip() { + m_PathClipType = FXFILL_WINDING; +} + +void CPDF_StreamContentParser::Handle_EOClip() { + m_PathClipType = FXFILL_ALTERNATE; +} + +void CPDF_StreamContentParser::Handle_CurveTo_13() { + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_BEZIERTO); +} + +void CPDF_StreamContentParser::Handle_NextLineShowText() { + Handle_MoveToNextLine(); + Handle_ShowText(); +} + +void CPDF_StreamContentParser::Handle_NextLineShowText_Space() { + m_pCurStates->m_TextState.SetWordSpace(GetNumber(2)); + m_pCurStates->m_TextState.SetCharSpace(GetNumber(1)); + Handle_NextLineShowText(); +} + +void CPDF_StreamContentParser::Handle_Invalid() {} + +void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) { + m_PathCurrentX = x; + m_PathCurrentY = y; + if (flag == FXPT_MOVETO) { + m_PathStartX = x; + m_PathStartY = y; + if (m_PathPointCount && + m_pPathPoints[m_PathPointCount - 1].m_Flag == FXPT_MOVETO) { + m_pPathPoints[m_PathPointCount - 1].m_PointX = x; + m_pPathPoints[m_PathPointCount - 1].m_PointY = y; + return; + } + } else if (m_PathPointCount == 0) { + return; + } + m_PathPointCount++; + if (m_PathPointCount > m_PathAllocSize) { + int newsize = m_PathPointCount + 256; + FX_PATHPOINT* pNewPoints = FX_Alloc(FX_PATHPOINT, newsize); + if (m_PathAllocSize) { + FXSYS_memcpy(pNewPoints, m_pPathPoints, + m_PathAllocSize * sizeof(FX_PATHPOINT)); + FX_Free(m_pPathPoints); + } + m_pPathPoints = pNewPoints; + m_PathAllocSize = newsize; + } + m_pPathPoints[m_PathPointCount - 1].m_Flag = flag; + m_pPathPoints[m_PathPointCount - 1].m_PointX = x; + m_pPathPoints[m_PathPointCount - 1].m_PointY = y; +} + +void CPDF_StreamContentParser::AddPathObject(int FillType, FX_BOOL bStroke) { + int PathPointCount = m_PathPointCount; + uint8_t PathClipType = m_PathClipType; + m_PathPointCount = 0; + m_PathClipType = 0; + if (PathPointCount <= 1) { + if (PathPointCount && PathClipType) { + CPDF_Path path; + path.AppendRect(0, 0, 0, 0); + m_pCurStates->m_ClipPath.AppendPath(path, FXFILL_WINDING, TRUE); + } + return; + } + if (PathPointCount && + m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) { + PathPointCount--; + } + CPDF_Path Path; + Path.SetPointCount(PathPointCount); + FXSYS_memcpy(Path.GetMutablePoints(), m_pPathPoints, + sizeof(FX_PATHPOINT) * PathPointCount); + CFX_Matrix matrix = m_pCurStates->m_CTM; + matrix.Concat(m_mtContentToUser); + if (bStroke || FillType) { + std::unique_ptr pPathObj(new CPDF_PathObject); + pPathObj->m_bStroke = bStroke; + pPathObj->m_FillType = FillType; + pPathObj->m_Path = Path; + pPathObj->m_Matrix = matrix; + SetGraphicStates(pPathObj.get(), TRUE, FALSE, TRUE); + pPathObj->CalcBoundingBox(); + m_pObjectHolder->GetPageObjectList()->push_back(std::move(pPathObj)); + } + if (PathClipType) { + if (!matrix.IsIdentity()) { + Path.Transform(&matrix); + matrix.SetIdentity(); + } + m_pCurStates->m_ClipPath.AppendPath(Path, PathClipType, TRUE); + } +} + +uint32_t CPDF_StreamContentParser::Parse(const uint8_t* pData, + uint32_t dwSize, + uint32_t max_cost) { + if (m_Level > _FPDF_MAX_FORM_LEVEL_) { + return dwSize; + } + uint32_t InitObjCount = m_pObjectHolder->GetPageObjectList()->size(); + CPDF_StreamParser syntax(pData, dwSize, m_pDocument->GetByteStringPool()); + CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); + while (1) { + uint32_t cost = m_pObjectHolder->GetPageObjectList()->size() - InitObjCount; + if (max_cost && cost >= max_cost) { + break; + } + switch (syntax.ParseNextElement()) { + case CPDF_StreamParser::EndOfData: + return m_pSyntax->GetPos(); + case CPDF_StreamParser::Keyword: + OnOperator((char*)syntax.GetWordBuf()); + ClearAllParams(); + break; + case CPDF_StreamParser::Number: + AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize()); + break; + case CPDF_StreamParser::Name: + AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, + syntax.GetWordSize() - 1); + break; + default: + AddObjectParam(syntax.GetObject()); + } + } + return m_pSyntax->GetPos(); +} + +void CPDF_StreamContentParser::ParsePathObject() { + FX_FLOAT params[6] = {}; + int nParams = 0; + int last_pos = m_pSyntax->GetPos(); + while (1) { + CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); + FX_BOOL bProcessed = TRUE; + switch (type) { + case CPDF_StreamParser::EndOfData: + return; + case CPDF_StreamParser::Keyword: { + int len = m_pSyntax->GetWordSize(); + if (len == 1) { + switch (m_pSyntax->GetWordBuf()[0]) { + case kPathOperatorSubpath: + AddPathPoint(params[0], params[1], FXPT_MOVETO); + nParams = 0; + break; + case kPathOperatorLine: + AddPathPoint(params[0], params[1], FXPT_LINETO); + nParams = 0; + break; + case kPathOperatorCubicBezier1: + AddPathPoint(params[0], params[1], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + AddPathPoint(params[4], params[5], FXPT_BEZIERTO); + nParams = 0; + break; + case kPathOperatorCubicBezier2: + AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); + AddPathPoint(params[0], params[1], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + nParams = 0; + break; + case kPathOperatorCubicBezier3: + AddPathPoint(params[0], params[1], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + AddPathPoint(params[2], params[3], FXPT_BEZIERTO); + nParams = 0; + break; + case kPathOperatorClosePath: + Handle_ClosePath(); + nParams = 0; + break; + default: + bProcessed = FALSE; + break; + } + } else if (len == 2) { + if (m_pSyntax->GetWordBuf()[0] == kPathOperatorRectangle[0] && + m_pSyntax->GetWordBuf()[1] == kPathOperatorRectangle[1]) { + AddPathRect(params[0], params[1], params[2], params[3]); + nParams = 0; + } else { + bProcessed = FALSE; + } + } else { + bProcessed = FALSE; + } + if (bProcessed) { + last_pos = m_pSyntax->GetPos(); + } + break; + } + case CPDF_StreamParser::Number: { + if (nParams == 6) + break; + + int value; + bool bInteger = FX_atonum( + CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), + &value); + params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value; + break; + } + default: + bProcessed = FALSE; + } + if (!bProcessed) { + m_pSyntax->SetPos(last_pos); + return; + } + } +} + +void PDF_ReplaceAbbr(CPDF_Object* pObj) { + switch (pObj->GetType()) { + case CPDF_Object::DICTIONARY: { + CPDF_Dictionary* pDict = pObj->AsDictionary(); + std::vector replacements; + for (const auto& it : *pDict) { + CFX_ByteString key = it.first; + CPDF_Object* value = it.second; + CFX_ByteStringC fullname = + PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), + key.AsStringC()); + if (!fullname.IsEmpty()) { + AbbrReplacementOp op; + op.is_replace_key = true; + op.key = key; + op.replacement = fullname; + replacements.push_back(op); + key = fullname; + } + + if (value->IsName()) { + CFX_ByteString name = value->GetString(); + fullname = PDF_FindFullName(PDF_InlineValueAbbr, + FX_ArraySize(PDF_InlineValueAbbr), + name.AsStringC()); + if (!fullname.IsEmpty()) { + AbbrReplacementOp op; + op.is_replace_key = false; + op.key = key; + op.replacement = fullname; + replacements.push_back(op); + } + } else { + PDF_ReplaceAbbr(value); + } + } + for (const auto& op : replacements) { + if (op.is_replace_key) + pDict->ReplaceKey(op.key, CFX_ByteString(op.replacement)); + else + pDict->SetNameFor(op.key, CFX_ByteString(op.replacement)); + } + break; + } + case CPDF_Object::ARRAY: { + CPDF_Array* pArray = pObj->AsArray(); + for (size_t i = 0; i < pArray->GetCount(); i++) { + CPDF_Object* pElement = pArray->GetObjectAt(i); + if (pElement->IsName()) { + CFX_ByteString name = pElement->GetString(); + CFX_ByteStringC fullname = PDF_FindFullName( + PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), + name.AsStringC()); + if (!fullname.IsEmpty()) { + pArray->SetAt(i, new CPDF_Name(CFX_ByteString(fullname))); + } + } else { + PDF_ReplaceAbbr(pElement); + } + } + break; + } + default: + break; + } +} diff --git a/core/fpdfapi/page/fpdf_page_parser_old.cpp b/core/fpdfapi/page/fpdf_page_parser_old.cpp new file mode 100644 index 0000000000..fb89b14db9 --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_parser_old.cpp @@ -0,0 +1,839 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/fpdfapi/page/pageint.h" + +#include + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/cpdf_type3char.h" +#include "core/fpdfapi/fpdf_parser/cpdf_array.h" +#include "core/fpdfapi/fpdf_parser/cpdf_boolean.h" +#include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" +#include "core/fpdfapi/fpdf_parser/cpdf_document.h" +#include "core/fpdfapi/fpdf_parser/cpdf_name.h" +#include "core/fpdfapi/fpdf_parser/cpdf_null.h" +#include "core/fpdfapi/fpdf_parser/cpdf_number.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream.h" +#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" +#include "core/fpdfapi/fpdf_parser/cpdf_string.h" +#include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" +#include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h" +#include "core/fpdfapi/page/cpdf_allstates.h" +#include "core/fpdfapi/page/cpdf_form.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/cpdf_pageobject.h" +#include "core/fpdfapi/page/cpdf_path.h" +#include "core/fxcodec/fx_codec.h" +#include "core/fxcrt/fx_ext.h" +#include "core/fxcrt/fx_safe_types.h" +#include "core/fxge/cfx_fxgedevice.h" +#include "core/fxge/cfx_renderdevice.h" + +namespace { + +const uint32_t kMaxNestedArrayLevel = 512; +const uint32_t kMaxWordBuffer = 256; +const FX_STRSIZE kMaxStringLength = 32767; + +} // namespace + +CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize) + : m_pBuf(pData), + m_Size(dwSize), + m_Pos(0), + m_pLastObj(nullptr), + m_pPool(nullptr) {} + +CPDF_StreamParser::CPDF_StreamParser( + const uint8_t* pData, + uint32_t dwSize, + const CFX_WeakPtr& pPool) + : m_pBuf(pData), + m_Size(dwSize), + m_Pos(0), + m_pLastObj(nullptr), + m_pPool(pPool) {} + +CPDF_StreamParser::~CPDF_StreamParser() { + if (m_pLastObj) { + m_pLastObj->Release(); + } +} + +uint32_t DecodeAllScanlines(CCodec_ScanlineDecoder* pDecoder, + uint8_t*& dest_buf, + uint32_t& dest_size) { + if (!pDecoder) { + return FX_INVALID_OFFSET; + } + int ncomps = pDecoder->CountComps(); + int bpc = pDecoder->GetBPC(); + int width = pDecoder->GetWidth(); + int height = pDecoder->GetHeight(); + int pitch = (width * ncomps * bpc + 7) / 8; + if (height == 0 || pitch > (1 << 30) / height) { + delete pDecoder; + return FX_INVALID_OFFSET; + } + dest_buf = FX_Alloc2D(uint8_t, pitch, height); + dest_size = pitch * height; // Safe since checked alloc returned. + for (int row = 0; row < height; row++) { + const uint8_t* pLine = pDecoder->GetScanline(row); + if (!pLine) + break; + + FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch); + } + uint32_t srcoff = pDecoder->GetSrcOffset(); + delete pDecoder; + return srcoff; +} + +CCodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( + const uint8_t* src_buf, + uint32_t src_size, + int width, + int height, + const CPDF_Dictionary* pParams); + +uint32_t PDF_DecodeInlineStream(const uint8_t* src_buf, + uint32_t limit, + int width, + int height, + CFX_ByteString& decoder, + CPDF_Dictionary* pParam, + uint8_t*& dest_buf, + uint32_t& dest_size) { + if (decoder == "CCITTFaxDecode" || decoder == "CCF") { + CCodec_ScanlineDecoder* pDecoder = + FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam); + return DecodeAllScanlines(pDecoder, dest_buf, dest_size); + } + if (decoder == "ASCII85Decode" || decoder == "A85") { + return A85Decode(src_buf, limit, dest_buf, dest_size); + } + if (decoder == "ASCIIHexDecode" || decoder == "AHx") { + return HexDecode(src_buf, limit, dest_buf, dest_size); + } + if (decoder == "FlateDecode" || decoder == "Fl") { + return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size, + dest_buf, dest_size); + } + if (decoder == "LZWDecode" || decoder == "LZW") { + return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf, + dest_size); + } + if (decoder == "DCTDecode" || decoder == "DCT") { + CCodec_ScanlineDecoder* pDecoder = + CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( + src_buf, limit, width, height, 0, + pParam ? pParam->GetIntegerFor("ColorTransform", 1) : 1); + return DecodeAllScanlines(pDecoder, dest_buf, dest_size); + } + if (decoder == "RunLengthDecode" || decoder == "RL") { + return RunLengthDecode(src_buf, limit, dest_buf, dest_size); + } + dest_size = 0; + dest_buf = 0; + return (uint32_t)-1; +} + +CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, + CPDF_Dictionary* pDict, + CPDF_Object* pCSObj) { + if (m_Pos == m_Size) + return nullptr; + + if (PDFCharIsWhitespace(m_pBuf[m_Pos])) + m_Pos++; + + CFX_ByteString Decoder; + CPDF_Dictionary* pParam = nullptr; + CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter"); + if (pFilter) { + if (CPDF_Array* pArray = pFilter->AsArray()) { + Decoder = pArray->GetStringAt(0); + CPDF_Array* pParams = pDict->GetArrayFor("DecodeParms"); + if (pParams) + pParam = pParams->GetDictAt(0); + } else { + Decoder = pFilter->GetString(); + pParam = pDict->GetDictFor("DecodeParms"); + } + } + uint32_t width = pDict->GetIntegerFor("Width"); + uint32_t height = pDict->GetIntegerFor("Height"); + uint32_t OrigSize = 0; + if (pCSObj) { + uint32_t bpc = pDict->GetIntegerFor("BitsPerComponent"); + uint32_t nComponents = 1; + CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); + if (pCS) { + nComponents = pCS->CountComponents(); + pDoc->GetPageData()->ReleaseColorSpace(pCSObj); + } else { + nComponents = 3; + } + uint32_t pitch = width; + if (bpc && pitch > INT_MAX / bpc) + return nullptr; + + pitch *= bpc; + if (nComponents && pitch > INT_MAX / nComponents) + return nullptr; + + pitch *= nComponents; + if (pitch > INT_MAX - 7) + return nullptr; + + pitch += 7; + pitch /= 8; + OrigSize = pitch; + } else { + if (width > INT_MAX - 7) + return nullptr; + + OrigSize = ((width + 7) / 8); + } + if (height && OrigSize > INT_MAX / height) + return nullptr; + + OrigSize *= height; + uint8_t* pData = nullptr; + uint32_t dwStreamSize; + if (Decoder.IsEmpty()) { + if (OrigSize > m_Size - m_Pos) { + OrigSize = m_Size - m_Pos; + } + pData = FX_Alloc(uint8_t, OrigSize); + FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); + dwStreamSize = OrigSize; + m_Pos += OrigSize; + } else { + uint32_t dwDestSize = OrigSize; + dwStreamSize = + PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, + Decoder, pParam, pData, dwDestSize); + FX_Free(pData); + if ((int)dwStreamSize < 0) + return nullptr; + + uint32_t dwSavePos = m_Pos; + m_Pos += dwStreamSize; + while (1) { + uint32_t dwPrevPos = m_Pos; + CPDF_StreamParser::SyntaxType type = ParseNextElement(); + if (type == CPDF_StreamParser::EndOfData) + break; + + if (type != CPDF_StreamParser::Keyword) { + dwStreamSize += m_Pos - dwPrevPos; + continue; + } + if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && + GetWordBuf()[1] == 'I') { + m_Pos = dwPrevPos; + break; + } + dwStreamSize += m_Pos - dwPrevPos; + } + m_Pos = dwSavePos; + pData = FX_Alloc(uint8_t, dwStreamSize); + FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); + m_Pos += dwStreamSize; + } + pDict->SetIntegerFor("Length", (int)dwStreamSize); + return new CPDF_Stream(pData, dwStreamSize, pDict); +} + +CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { + if (m_pLastObj) { + m_pLastObj->Release(); + m_pLastObj = nullptr; + } + + m_WordSize = 0; + FX_BOOL bIsNumber = TRUE; + if (!PositionIsInBounds()) + return EndOfData; + + int ch = m_pBuf[m_Pos++]; + while (1) { + while (PDFCharIsWhitespace(ch)) { + if (!PositionIsInBounds()) + return EndOfData; + + ch = m_pBuf[m_Pos++]; + } + + if (ch != '%') + break; + + while (1) { + if (!PositionIsInBounds()) + return EndOfData; + + ch = m_pBuf[m_Pos++]; + if (PDFCharIsLineEnding(ch)) + break; + } + } + + if (PDFCharIsDelimiter(ch) && ch != '/') { + m_Pos--; + m_pLastObj = ReadNextObject(false, 0); + return Others; + } + + while (1) { + if (m_WordSize < kMaxWordBuffer) + m_WordBuffer[m_WordSize++] = ch; + + if (!PDFCharIsNumeric(ch)) + bIsNumber = FALSE; + + if (!PositionIsInBounds()) + break; + + ch = m_pBuf[m_Pos++]; + + if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { + m_Pos--; + break; + } + } + + m_WordBuffer[m_WordSize] = 0; + if (bIsNumber) + return Number; + + if (m_WordBuffer[0] == '/') + return Name; + + if (m_WordSize == 4) { + if (memcmp(m_WordBuffer, "true", 4) == 0) { + m_pLastObj = new CPDF_Boolean(TRUE); + return Others; + } + if (memcmp(m_WordBuffer, "null", 4) == 0) { + m_pLastObj = new CPDF_Null; + return Others; + } + } else if (m_WordSize == 5) { + if (memcmp(m_WordBuffer, "false", 5) == 0) { + m_pLastObj = new CPDF_Boolean(FALSE); + return Others; + } + } + return Keyword; +} + +CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, + uint32_t dwInArrayLevel) { + FX_BOOL bIsNumber; + GetNextWord(bIsNumber); + if (!m_WordSize) + return nullptr; + + if (bIsNumber) { + m_WordBuffer[m_WordSize] = 0; + return new CPDF_Number(CFX_ByteStringC(m_WordBuffer, m_WordSize)); + } + + int first_char = m_WordBuffer[0]; + if (first_char == '/') { + CFX_ByteString name = + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); + return new CPDF_Name(m_pPool ? m_pPool->Intern(name) : name); + } + + if (first_char == '(') { + CFX_ByteString str = ReadString(); + return new CPDF_String(m_pPool ? m_pPool->Intern(str) : str, FALSE); + } + + if (first_char == '<') { + if (m_WordSize == 1) + return new CPDF_String(ReadHexString(), TRUE); + + CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPool); + while (1) { + GetNextWord(bIsNumber); + if (m_WordSize == 2 && m_WordBuffer[0] == '>') + break; + + if (!m_WordSize || m_WordBuffer[0] != '/') { + pDict->Release(); + return nullptr; + } + + CFX_ByteString key = + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); + CPDF_Object* pObj = ReadNextObject(true, 0); + if (!pObj) { + pDict->Release(); + return nullptr; + } + + if (key.IsEmpty()) + pObj->Release(); + else + pDict->SetFor(key, pObj); + } + return pDict; + } + + if (first_char == '[') { + if ((!bAllowNestedArray && dwInArrayLevel) || + dwInArrayLevel > kMaxNestedArrayLevel) { + return nullptr; + } + + CPDF_Array* pArray = new CPDF_Array; + while (1) { + CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1); + if (pObj) { + pArray->Add(pObj); + continue; + } + + if (!m_WordSize || m_WordBuffer[0] == ']') + break; + } + return pArray; + } + + if (m_WordSize == 5 && !memcmp(m_WordBuffer, "false", 5)) + return new CPDF_Boolean(FALSE); + + if (m_WordSize == 4) { + if (memcmp(m_WordBuffer, "true", 4) == 0) + return new CPDF_Boolean(TRUE); + + if (memcmp(m_WordBuffer, "null", 4) == 0) + return new CPDF_Null; + } + + return nullptr; +} + +void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) { + m_WordSize = 0; + bIsNumber = TRUE; + if (!PositionIsInBounds()) + return; + + int ch = m_pBuf[m_Pos++]; + while (1) { + while (PDFCharIsWhitespace(ch)) { + if (!PositionIsInBounds()) { + return; + } + ch = m_pBuf[m_Pos++]; + } + + if (ch != '%') + break; + + while (1) { + if (!PositionIsInBounds()) + return; + ch = m_pBuf[m_Pos++]; + if (PDFCharIsLineEnding(ch)) + break; + } + } + + if (PDFCharIsDelimiter(ch)) { + bIsNumber = FALSE; + m_WordBuffer[m_WordSize++] = ch; + if (ch == '/') { + while (1) { + if (!PositionIsInBounds()) + return; + ch = m_pBuf[m_Pos++]; + if (!PDFCharIsOther(ch) && !PDFCharIsNumeric(ch)) { + m_Pos--; + return; + } + + if (m_WordSize < kMaxWordBuffer) + m_WordBuffer[m_WordSize++] = ch; + } + } else if (ch == '<') { + if (!PositionIsInBounds()) + return; + ch = m_pBuf[m_Pos++]; + if (ch == '<') + m_WordBuffer[m_WordSize++] = ch; + else + m_Pos--; + } else if (ch == '>') { + if (!PositionIsInBounds()) + return; + ch = m_pBuf[m_Pos++]; + if (ch == '>') + m_WordBuffer[m_WordSize++] = ch; + else + m_Pos--; + } + return; + } + + while (1) { + if (m_WordSize < kMaxWordBuffer) + m_WordBuffer[m_WordSize++] = ch; + if (!PDFCharIsNumeric(ch)) + bIsNumber = FALSE; + + if (!PositionIsInBounds()) + return; + ch = m_pBuf[m_Pos++]; + if (PDFCharIsDelimiter(ch) || PDFCharIsWhitespace(ch)) { + m_Pos--; + break; + } + } +} + +CFX_ByteString CPDF_StreamParser::ReadString() { + if (!PositionIsInBounds()) + return CFX_ByteString(); + + uint8_t ch = m_pBuf[m_Pos++]; + CFX_ByteTextBuf buf; + int parlevel = 0; + int status = 0; + int iEscCode = 0; + while (1) { + switch (status) { + case 0: + if (ch == ')') { + if (parlevel == 0) { + if (buf.GetLength() > kMaxStringLength) { + return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); + } + return buf.MakeString(); + } + parlevel--; + buf.AppendChar(')'); + } else if (ch == '(') { + parlevel++; + buf.AppendChar('('); + } else if (ch == '\\') { + status = 1; + } else { + buf.AppendChar((char)ch); + } + break; + case 1: + if (ch >= '0' && ch <= '7') { + iEscCode = FXSYS_toDecimalDigit(static_cast(ch)); + status = 2; + break; + } + if (ch == 'n') { + buf.AppendChar('\n'); + } else if (ch == 'r') { + buf.AppendChar('\r'); + } else if (ch == 't') { + buf.AppendChar('\t'); + } else if (ch == 'b') { + buf.AppendChar('\b'); + } else if (ch == 'f') { + buf.AppendChar('\f'); + } else if (ch == '\r') { + status = 4; + break; + } else if (ch == '\n') { + } else { + buf.AppendChar(ch); + } + status = 0; + break; + case 2: + if (ch >= '0' && ch <= '7') { + iEscCode = + iEscCode * 8 + FXSYS_toDecimalDigit(static_cast(ch)); + status = 3; + } else { + buf.AppendChar(iEscCode); + status = 0; + continue; + } + break; + case 3: + if (ch >= '0' && ch <= '7') { + iEscCode = + iEscCode * 8 + FXSYS_toDecimalDigit(static_cast(ch)); + buf.AppendChar(iEscCode); + status = 0; + } else { + buf.AppendChar(iEscCode); + status = 0; + continue; + } + break; + case 4: + status = 0; + if (ch != '\n') { + continue; + } + break; + } + if (!PositionIsInBounds()) + break; + + ch = m_pBuf[m_Pos++]; + } + if (PositionIsInBounds()) + ++m_Pos; + + if (buf.GetLength() > kMaxStringLength) { + return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); + } + return buf.MakeString(); +} + +CFX_ByteString CPDF_StreamParser::ReadHexString() { + if (!PositionIsInBounds()) + return CFX_ByteString(); + + CFX_ByteTextBuf buf; + bool bFirst = true; + int code = 0; + while (PositionIsInBounds()) { + int ch = m_pBuf[m_Pos++]; + + if (ch == '>') + break; + + if (!std::isxdigit(ch)) + continue; + + int val = FXSYS_toHexDigit(ch); + if (bFirst) { + code = val * 16; + } else { + code += val; + buf.AppendByte((uint8_t)code); + } + bFirst = !bFirst; + } + if (!bFirst) + buf.AppendChar((char)code); + + if (buf.GetLength() > kMaxStringLength) + return CFX_ByteString(buf.GetBuffer(), kMaxStringLength); + + return buf.MakeString(); +} + +bool CPDF_StreamParser::PositionIsInBounds() const { + return m_Pos < m_Size; +} + +CPDF_ContentParser::CPDF_ContentParser() + : m_Status(Ready), + m_InternalStage(STAGE_GETCONTENT), + m_pObjectHolder(nullptr), + m_bForm(false), + m_pType3Char(nullptr), + m_pData(nullptr), + m_Size(0), + m_CurrentOffset(0) {} + +CPDF_ContentParser::~CPDF_ContentParser() { + if (!m_pSingleStream) + FX_Free(m_pData); +} + +void CPDF_ContentParser::Start(CPDF_Page* pPage) { + if (m_Status != Ready || !pPage || !pPage->m_pDocument || + !pPage->m_pFormDict) { + m_Status = Done; + return; + } + m_pObjectHolder = pPage; + m_bForm = FALSE; + m_Status = ToBeContinued; + m_InternalStage = STAGE_GETCONTENT; + m_CurrentOffset = 0; + + CPDF_Object* pContent = pPage->m_pFormDict->GetDirectObjectFor("Contents"); + if (!pContent) { + m_Status = Done; + return; + } + if (CPDF_Stream* pStream = pContent->AsStream()) { + m_nStreams = 0; + m_pSingleStream.reset(new CPDF_StreamAcc); + m_pSingleStream->LoadAllData(pStream, FALSE); + } else if (CPDF_Array* pArray = pContent->AsArray()) { + m_nStreams = pArray->GetCount(); + if (m_nStreams) + m_StreamArray.resize(m_nStreams); + else + m_Status = Done; + } else { + m_Status = Done; + } +} + +void CPDF_ContentParser::Start(CPDF_Form* pForm, + CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level) { + m_pType3Char = pType3Char; + m_pObjectHolder = pForm; + m_bForm = TRUE; + CFX_Matrix form_matrix = pForm->m_pFormDict->GetMatrixFor("Matrix"); + if (pGraphicStates) { + form_matrix.Concat(pGraphicStates->m_CTM); + } + CPDF_Array* pBBox = pForm->m_pFormDict->GetArrayFor("BBox"); + CFX_FloatRect form_bbox; + CPDF_Path ClipPath; + if (pBBox) { + form_bbox = pBBox->GetRect(); + ClipPath.Emplace(); + ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, + form_bbox.top); + ClipPath.Transform(&form_matrix); + if (pParentMatrix) { + ClipPath.Transform(pParentMatrix); + } + form_bbox.Transform(&form_matrix); + if (pParentMatrix) { + form_bbox.Transform(pParentMatrix); + } + } + CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictFor("Resources"); + m_pParser.reset(new CPDF_StreamContentParser( + pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, + pParentMatrix, pForm, pResources, &form_bbox, pGraphicStates, level)); + m_pParser->GetCurStates()->m_CTM = form_matrix; + m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; + if (ClipPath) { + m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, + TRUE); + } + if (pForm->m_Transparency & PDFTRANS_GROUP) { + CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState; + pState->SetBlendType(FXDIB_BLEND_NORMAL); + pState->SetStrokeAlpha(1.0f); + pState->SetFillAlpha(1.0f); + pState->SetSoftMask(nullptr); + } + m_nStreams = 0; + m_pSingleStream.reset(new CPDF_StreamAcc); + m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); + m_pData = (uint8_t*)m_pSingleStream->GetData(); + m_Size = m_pSingleStream->GetSize(); + m_Status = ToBeContinued; + m_InternalStage = STAGE_PARSE; + m_CurrentOffset = 0; +} + +void CPDF_ContentParser::Continue(IFX_Pause* pPause) { + int steps = 0; + while (m_Status == ToBeContinued) { + if (m_InternalStage == STAGE_GETCONTENT) { + if (m_CurrentOffset == m_nStreams) { + if (!m_StreamArray.empty()) { + FX_SAFE_UINT32 safeSize = 0; + for (const auto& stream : m_StreamArray) { + safeSize += stream->GetSize(); + safeSize += 1; + } + if (!safeSize.IsValid()) { + m_Status = Done; + return; + } + m_Size = safeSize.ValueOrDie(); + m_pData = FX_Alloc(uint8_t, m_Size); + uint32_t pos = 0; + for (const auto& stream : m_StreamArray) { + FXSYS_memcpy(m_pData + pos, stream->GetData(), stream->GetSize()); + pos += stream->GetSize(); + m_pData[pos++] = ' '; + } + m_StreamArray.clear(); + } else { + m_pData = (uint8_t*)m_pSingleStream->GetData(); + m_Size = m_pSingleStream->GetSize(); + } + m_InternalStage = STAGE_PARSE; + m_CurrentOffset = 0; + } else { + CPDF_Array* pContent = + m_pObjectHolder->m_pFormDict->GetArrayFor("Contents"); + m_StreamArray[m_CurrentOffset].reset(new CPDF_StreamAcc); + CPDF_Stream* pStreamObj = ToStream( + pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr); + m_StreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); + m_CurrentOffset++; + } + } + if (m_InternalStage == STAGE_PARSE) { + if (!m_pParser) { + m_pParser.reset(new CPDF_StreamContentParser( + m_pObjectHolder->m_pDocument, m_pObjectHolder->m_pPageResources, + nullptr, nullptr, m_pObjectHolder, m_pObjectHolder->m_pResources, + &m_pObjectHolder->m_BBox, nullptr, 0)); + m_pParser->GetCurStates()->m_ColorState.SetDefault(); + } + if (m_CurrentOffset >= m_Size) { + m_InternalStage = STAGE_CHECKCLIP; + } else { + m_CurrentOffset += + m_pParser->Parse(m_pData + m_CurrentOffset, + m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); + } + } + if (m_InternalStage == STAGE_CHECKCLIP) { + if (m_pType3Char) { + m_pType3Char->m_bColored = m_pParser->IsColored(); + m_pType3Char->m_Width = + FXSYS_round(m_pParser->GetType3Data()[0] * 1000); + m_pType3Char->m_BBox.left = + FXSYS_round(m_pParser->GetType3Data()[2] * 1000); + m_pType3Char->m_BBox.bottom = + FXSYS_round(m_pParser->GetType3Data()[3] * 1000); + m_pType3Char->m_BBox.right = + FXSYS_round(m_pParser->GetType3Data()[4] * 1000); + m_pType3Char->m_BBox.top = + FXSYS_round(m_pParser->GetType3Data()[5] * 1000); + } + for (auto& pObj : *m_pObjectHolder->GetPageObjectList()) { + if (!pObj->m_ClipPath) + continue; + if (pObj->m_ClipPath.GetPathCount() != 1) + continue; + if (pObj->m_ClipPath.GetTextCount()) + continue; + CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); + if (!ClipPath.IsRect() || pObj->IsShading()) + continue; + CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), + ClipPath.GetPointX(2), ClipPath.GetPointY(2)); + CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, + pObj->m_Top); + if (old_rect.Contains(obj_rect)) { + pObj->m_ClipPath.SetNull(); + } + } + m_Status = Done; + return; + } + steps++; + if (pPause && pPause->NeedToPauseNow()) { + break; + } + } +} diff --git a/core/fpdfapi/page/fpdf_page_parser_old_unittest.cpp b/core/fpdfapi/page/fpdf_page_parser_old_unittest.cpp new file mode 100644 index 0000000000..52ebf1ef09 --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_parser_old_unittest.cpp @@ -0,0 +1,47 @@ +// Copyright 2015 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fpdfapi/page/pageint.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(fpdf_page_parser_old, ReadHexString) { + { + // Position out of bounds. + uint8_t data[] = "12ab>"; + CPDF_StreamParser parser(data, 5); + parser.SetPos(6); + EXPECT_EQ("", parser.ReadHexString()); + } + + { + // Regular conversion. + uint8_t data[] = "1A2b>abcd"; + CPDF_StreamParser parser(data, 5); + EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); + EXPECT_EQ(5u, parser.GetPos()); + } + + { + // Missing ending > + uint8_t data[] = "1A2b"; + CPDF_StreamParser parser(data, 5); + EXPECT_EQ("\x1a\x2b", parser.ReadHexString()); + EXPECT_EQ(5u, parser.GetPos()); + } + + { + // Uneven number of bytes. + uint8_t data[] = "1A2>asdf"; + CPDF_StreamParser parser(data, 5); + EXPECT_EQ("\x1a\x20", parser.ReadHexString()); + EXPECT_EQ(4u, parser.GetPos()); + } + + { + uint8_t data[] = ">"; + CPDF_StreamParser parser(data, 5); + EXPECT_EQ("", parser.ReadHexString()); + EXPECT_EQ(1u, parser.GetPos()); + } +} diff --git a/core/fpdfapi/page/fpdf_page_parser_unittest.cpp b/core/fpdfapi/page/fpdf_page_parser_unittest.cpp new file mode 100644 index 0000000000..b6eec7bcf7 --- /dev/null +++ b/core/fpdfapi/page/fpdf_page_parser_unittest.cpp @@ -0,0 +1,34 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/fpdfapi/page/pageint.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(fpdf_page_parser, PDF_FindKeyAbbreviation) { + EXPECT_EQ(CFX_ByteStringC("BitsPerComponent"), + PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("BPC"))); + EXPECT_EQ(CFX_ByteStringC("Width"), + PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("W"))); + EXPECT_EQ(CFX_ByteStringC(""), + PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC(""))); + EXPECT_EQ(CFX_ByteStringC(""), + PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("NoInList"))); + // Prefix should not match. + EXPECT_EQ(CFX_ByteStringC(""), + PDF_FindKeyAbbreviationForTesting(CFX_ByteStringC("WW"))); +} + +TEST(fpdf_page_parser, PDF_FindValueAbbreviation) { + EXPECT_EQ(CFX_ByteStringC("DeviceGray"), + PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("G"))); + EXPECT_EQ(CFX_ByteStringC("DCTDecode"), + PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("DCT"))); + EXPECT_EQ(CFX_ByteStringC(""), + PDF_FindValueAbbreviationForTesting(CFX_ByteStringC(""))); + EXPECT_EQ(CFX_ByteStringC(""), + PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("NoInList"))); + // Prefix should not match. + EXPECT_EQ(CFX_ByteStringC(""), + PDF_FindValueAbbreviationForTesting(CFX_ByteStringC("II"))); +} diff --git a/core/fpdfapi/page/pageint.h b/core/fpdfapi/page/pageint.h new file mode 100644 index 0000000000..2d3927d13d --- /dev/null +++ b/core/fpdfapi/page/pageint.h @@ -0,0 +1,566 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef CORE_FPDFAPI_PAGE_PAGEINT_H_ +#define CORE_FPDFAPI_PAGE_PAGEINT_H_ + +#include +#include +#include +#include +#include + +#include "core/fpdfapi/page/cpdf_contentmark.h" +#include "core/fpdfapi/page/cpdf_countedobject.h" +#include "core/fpdfapi/page/cpdf_pageobjectholder.h" +#include "core/fxcrt/cfx_string_pool_template.h" +#include "core/fxcrt/cfx_weak_ptr.h" +#include "core/fxge/cfx_pathdata.h" +#include "core/fxge/cfx_renderdevice.h" + +class CPDF_AllStates; +class CPDF_ColorSpace; +class CPDF_ExpIntFunc; +class CPDF_Font; +class CPDF_FontEncoding; +class CPDF_Form; +class CPDF_IccProfile; +class CPDF_Image; +class CPDF_ImageObject; +class CPDF_Page; +class CPDF_Pattern; +class CPDF_SampledFunc; +class CPDF_StitchFunc; +class CPDF_StreamAcc; +class CPDF_TextObject; +class CPDF_Type3Char; + +#define PARSE_STEP_LIMIT 100 + +class CPDF_StreamParser { + public: + enum SyntaxType { EndOfData, Number, Keyword, Name, Others }; + + CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize); + CPDF_StreamParser(const uint8_t* pData, + uint32_t dwSize, + const CFX_WeakPtr& pPool); + ~CPDF_StreamParser(); + + CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, + CPDF_Dictionary* pDict, + CPDF_Object* pCSObj); + SyntaxType ParseNextElement(); + uint8_t* GetWordBuf() { return m_WordBuffer; } + uint32_t GetWordSize() const { return m_WordSize; } + CPDF_Object* GetObject() { + CPDF_Object* pObj = m_pLastObj; + m_pLastObj = nullptr; + return pObj; + } + uint32_t GetPos() const { return m_Pos; } + void SetPos(uint32_t pos) { m_Pos = pos; } + CPDF_Object* ReadNextObject(bool bAllowNestedArray, uint32_t dwInArrayLevel); + + protected: + friend class fpdf_page_parser_old_ReadHexString_Test; + + void GetNextWord(FX_BOOL& bIsNumber); + CFX_ByteString ReadString(); + CFX_ByteString ReadHexString(); + + const uint8_t* m_pBuf; + uint32_t m_Size; // Length in bytes of m_pBuf. + uint32_t m_Pos; // Current byte position within m_pBuf. + uint8_t m_WordBuffer[256]; + uint32_t m_WordSize; + CPDF_Object* m_pLastObj; + CFX_WeakPtr m_pPool; + + private: + bool PositionIsInBounds() const; +}; + +#define PARAM_BUF_SIZE 16 +struct ContentParam { + enum Type { OBJECT = 0, NUMBER, NAME }; + Type m_Type; + union { + struct { + bool m_bInteger; + union { + int m_Integer; + FX_FLOAT m_Float; + }; + } m_Number; + CPDF_Object* m_pObject; + struct { + int m_Len; + char m_Buffer[32]; + } m_Name; + }; +}; +#define _FPDF_MAX_FORM_LEVEL_ 30 +#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4 +class CPDF_StreamContentParser { + public: + CPDF_StreamContentParser(CPDF_Document* pDoc, + CPDF_Dictionary* pPageResources, + CPDF_Dictionary* pParentResources, + const CFX_Matrix* pmtContentToUser, + CPDF_PageObjectHolder* pObjectHolder, + CPDF_Dictionary* pResources, + CFX_FloatRect* pBBox, + CPDF_AllStates* pAllStates, + int level); + ~CPDF_StreamContentParser(); + + CPDF_PageObjectHolder* GetPageObjectHolder() const { return m_pObjectHolder; } + CPDF_AllStates* GetCurStates() const { return m_pCurStates.get(); } + FX_BOOL IsColored() const { return m_bColored; } + const FX_FLOAT* GetType3Data() const { return m_Type3Data; } + + void AddNumberParam(const FX_CHAR* str, int len); + void AddObjectParam(CPDF_Object* pObj); + void AddNameParam(const FX_CHAR* name, int size); + int GetNextParamPos(); + void ClearAllParams(); + CPDF_Object* GetObject(uint32_t index); + CFX_ByteString GetString(uint32_t index); + FX_FLOAT GetNumber(uint32_t index); + int GetInteger(uint32_t index) { return (int32_t)(GetNumber(index)); } + void OnOperator(const FX_CHAR* op); + void BigCaseCaller(int index); + uint32_t GetParsePos() { return m_pSyntax->GetPos(); } + void AddTextObject(CFX_ByteString* pText, + FX_FLOAT fInitKerning, + FX_FLOAT* pKerning, + int count); + + void ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y); + void ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y); + void OnChangeTextMatrix(); + uint32_t Parse(const uint8_t* pData, uint32_t dwSize, uint32_t max_cost); + void ParsePathObject(); + void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag); + void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h); + void AddPathObject(int FillType, FX_BOOL bStroke); + CPDF_ImageObject* AddImage(CPDF_Stream* pStream, + CPDF_Image* pImage, + bool bInline); + void AddDuplicateImage(); + void AddForm(CPDF_Stream* pStream); + void SetGraphicStates(CPDF_PageObject* pObj, + FX_BOOL bColor, + FX_BOOL bText, + FX_BOOL bGraph); + void SaveStates(CPDF_AllStates* pState); + void RestoreStates(CPDF_AllStates* pState); + CPDF_Font* FindFont(const CFX_ByteString& name); + CPDF_ColorSpace* FindColorSpace(const CFX_ByteString& name); + CPDF_Pattern* FindPattern(const CFX_ByteString& name, bool bShading); + CPDF_Object* FindResourceObj(const CFX_ByteString& type, + const CFX_ByteString& name); + + protected: + using OpCodes = + std::unordered_map; + static OpCodes InitializeOpCodes(); + + void Handle_CloseFillStrokePath(); + void Handle_FillStrokePath(); + void Handle_CloseEOFillStrokePath(); + void Handle_EOFillStrokePath(); + void Handle_BeginMarkedContent_Dictionary(); + void Handle_BeginImage(); + void Handle_BeginMarkedContent(); + void Handle_BeginText(); + void Handle_CurveTo_123(); + void Handle_ConcatMatrix(); + void Handle_SetColorSpace_Fill(); + void Handle_SetColorSpace_Stroke(); + void Handle_SetDash(); + void Handle_SetCharWidth(); + void Handle_SetCachedDevice(); + void Handle_ExecuteXObject(); + void Handle_MarkPlace_Dictionary(); + void Handle_EndImage(); + void Handle_EndMarkedContent(); + void Handle_EndText(); + void Handle_FillPath(); + void Handle_FillPathOld(); + void Handle_EOFillPath(); + void Handle_SetGray_Fill(); + void Handle_SetGray_Stroke(); + void Handle_SetExtendGraphState(); + void Handle_ClosePath(); + void Handle_SetFlat(); + void Handle_BeginImageData(); + void Handle_SetLineJoin(); + void Handle_SetLineCap(); + void Handle_SetCMYKColor_Fill(); + void Handle_SetCMYKColor_Stroke(); + void Handle_LineTo(); + void Handle_MoveTo(); + void Handle_SetMiterLimit(); + void Handle_MarkPlace(); + void Handle_EndPath(); + void Handle_SaveGraphState(); + void Handle_RestoreGraphState(); + void Handle_Rectangle(); + void Handle_SetRGBColor_Fill(); + void Handle_SetRGBColor_Stroke(); + void Handle_SetRenderIntent(); + void Handle_CloseStrokePath(); + void Handle_StrokePath(); + void Handle_SetColor_Fill(); + void Handle_SetColor_Stroke(); + void Handle_SetColorPS_Fill(); + void Handle_SetColorPS_Stroke(); + void Handle_ShadeFill(); + void Handle_SetCharSpace(); + void Handle_MoveTextPoint(); + void Handle_MoveTextPoint_SetLeading(); + void Handle_SetFont(); + void Handle_ShowText(); + void Handle_ShowText_Positioning(); + void Handle_SetTextLeading(); + void Handle_SetTextMatrix(); + void Handle_SetTextRenderMode(); + void Handle_SetTextRise(); + void Handle_SetWordSpace(); + void Handle_SetHorzScale(); + void Handle_MoveToNextLine(); + void Handle_CurveTo_23(); + void Handle_SetLineWidth(); + void Handle_Clip(); + void Handle_EOClip(); + void Handle_CurveTo_13(); + void Handle_NextLineShowText(); + void Handle_NextLineShowText_Space(); + void Handle_Invalid(); + + CPDF_Document* const m_pDocument; + CPDF_Dictionary* m_pPageResources; + CPDF_Dictionary* m_pParentResources; + CPDF_Dictionary* m_pResources; + CPDF_PageObjectHolder* m_pObjectHolder; + int m_Level; + CFX_Matrix m_mtContentToUser; + CFX_FloatRect m_BBox; + ContentParam m_ParamBuf[PARAM_BUF_SIZE]; + uint32_t m_ParamStartPos; + uint32_t m_ParamCount; + CPDF_StreamParser* m_pSyntax; + std::unique_ptr m_pCurStates; + CPDF_ContentMark m_CurContentMark; + std::vector> m_ClipTextList; + CPDF_TextObject* m_pLastTextObject; + FX_FLOAT m_DefFontSize; + FX_PATHPOINT* m_pPathPoints; + int m_PathPointCount; + int m_PathAllocSize; + FX_FLOAT m_PathStartX; + FX_FLOAT m_PathStartY; + FX_FLOAT m_PathCurrentX; + FX_FLOAT m_PathCurrentY; + uint8_t m_PathClipType; + CFX_ByteString m_LastImageName; + CPDF_Image* m_pLastImage; + CFX_BinaryBuf m_LastImageDict; + CFX_BinaryBuf m_LastImageData; + CPDF_Dictionary* m_pLastImageDict; + CPDF_Dictionary* m_pLastCloneImageDict; + FX_BOOL m_bReleaseLastDict; + FX_BOOL m_bSameLastDict; + FX_BOOL m_bColored; + FX_FLOAT m_Type3Data[6]; + FX_BOOL m_bResourceMissing; + std::vector> m_StateStack; +}; +class CPDF_ContentParser { + public: + enum ParseStatus { Ready, ToBeContinued, Done }; + + CPDF_ContentParser(); + ~CPDF_ContentParser(); + + ParseStatus GetStatus() const { return m_Status; } + void Start(CPDF_Page* pPage); + void Start(CPDF_Form* pForm, + CPDF_AllStates* pGraphicStates, + const CFX_Matrix* pParentMatrix, + CPDF_Type3Char* pType3Char, + int level); + void Continue(IFX_Pause* pPause); + + private: + enum InternalStage { + STAGE_GETCONTENT = 1, + STAGE_PARSE, + STAGE_CHECKCLIP, + }; + + ParseStatus m_Status; + InternalStage m_InternalStage; + CPDF_PageObjectHolder* m_pObjectHolder; + FX_BOOL m_bForm; + CPDF_Type3Char* m_pType3Char; + uint32_t m_nStreams; + std::unique_ptr m_pSingleStream; + std::vector> m_StreamArray; + uint8_t* m_pData; + uint32_t m_Size; + uint32_t m_CurrentOffset; + std::unique_ptr m_pParser; +}; + +class CPDF_DocPageData { + public: + explicit CPDF_DocPageData(CPDF_Document* pPDFDoc); + ~CPDF_DocPageData(); + + void Clear(FX_BOOL bRelease = FALSE); + CPDF_Font* GetFont(CPDF_Dictionary* pFontDict, FX_BOOL findOnly); + CPDF_Font* GetStandardFont(const CFX_ByteString& fontName, + CPDF_FontEncoding* pEncoding); + void ReleaseFont(const CPDF_Dictionary* pFontDict); + CPDF_ColorSpace* GetColorSpace(CPDF_Object* pCSObj, + const CPDF_Dictionary* pResources); + CPDF_ColorSpace* GetCopiedColorSpace(CPDF_Object* pCSObj); + void ReleaseColorSpace(const CPDF_Object* pColorSpace); + CPDF_Pattern* GetPattern(CPDF_Object* pPatternObj, + FX_BOOL bShading, + const CFX_Matrix& matrix); + void ReleasePattern(const CPDF_Object* pPatternObj); + CPDF_Image* GetImage(CPDF_Object* pImageStream); + void ReleaseImage(const CPDF_Object* pImageStream); + CPDF_IccProfile* GetIccProfile(CPDF_Stream* pIccProfileStream); + void ReleaseIccProfile(const CPDF_IccProfile* pIccProfile); + CPDF_StreamAcc* GetFontFileStreamAcc(CPDF_Stream* pFontStream); + void ReleaseFontFileStreamAcc(const CPDF_Stream* pFontStream); + FX_BOOL IsForceClear() const { return m_bForceClear; } + CPDF_CountedColorSpace* FindColorSpacePtr(CPDF_Object* pCSObj) const; + CPDF_CountedPattern* FindPatternPtr(CPDF_Object* pPatternObj) const; + + private: + using CPDF_CountedFont = CPDF_CountedObject; + using CPDF_CountedIccProfile = CPDF_CountedObject; + using CPDF_CountedImage = CPDF_CountedObject; + using CPDF_CountedStreamAcc = CPDF_CountedObject; + + using CPDF_ColorSpaceMap = + std::map; + using CPDF_FontFileMap = std::map; + using CPDF_FontMap = std::map; + using CPDF_IccProfileMap = + std::map; + using CPDF_ImageMap = std::map; + using CPDF_PatternMap = std::map; + + CPDF_ColorSpace* GetColorSpaceImpl(CPDF_Object* pCSObj, + const CPDF_Dictionary* pResources, + std::set* pVisited); + + CPDF_Document* const m_pPDFDoc; + FX_BOOL m_bForceClear; + std::map m_HashProfileMap; + CPDF_ColorSpaceMap m_ColorSpaceMap; + CPDF_FontFileMap m_FontFileMap; + CPDF_FontMap m_FontMap; + CPDF_IccProfileMap m_IccProfileMap; + CPDF_ImageMap m_ImageMap; + CPDF_PatternMap m_PatternMap; +}; + +class CPDF_Function { + public: + enum class Type { + kTypeInvalid = -1, + kType0Sampled = 0, + kType2ExpotentialInterpolation = 2, + kType3Stitching = 3, + kType4PostScript = 4, + }; + + static std::unique_ptr Load(CPDF_Object* pFuncObj); + static Type IntegerToFunctionType(int iType); + + virtual ~CPDF_Function(); + FX_BOOL Call(FX_FLOAT* inputs, + uint32_t ninputs, + FX_FLOAT* results, + int& nresults) const; + uint32_t CountInputs() const { return m_nInputs; } + uint32_t CountOutputs() const { return m_nOutputs; } + FX_FLOAT GetDomain(int i) const { return m_pDomains[i]; } + FX_FLOAT GetRange(int i) const { return m_pRanges[i]; } + + const CPDF_SampledFunc* ToSampledFunc() const; + const CPDF_ExpIntFunc* ToExpIntFunc() const; + const CPDF_StitchFunc* ToStitchFunc() const; + + protected: + explicit CPDF_Function(Type type); + + FX_BOOL Init(CPDF_Object* pObj); + virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0; + virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0; + + uint32_t m_nInputs; + uint32_t m_nOutputs; + FX_FLOAT* m_pDomains; + FX_FLOAT* m_pRanges; + const Type m_Type; +}; + +class CPDF_ExpIntFunc : public CPDF_Function { + public: + CPDF_ExpIntFunc(); + ~CPDF_ExpIntFunc() override; + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + uint32_t m_nOrigOutputs; + FX_FLOAT m_Exponent; + FX_FLOAT* m_pBeginValues; + FX_FLOAT* m_pEndValues; +}; + +class CPDF_SampledFunc : public CPDF_Function { + public: + struct SampleEncodeInfo { + FX_FLOAT encode_max; + FX_FLOAT encode_min; + uint32_t sizes; + }; + + struct SampleDecodeInfo { + FX_FLOAT decode_max; + FX_FLOAT decode_min; + }; + + CPDF_SampledFunc(); + ~CPDF_SampledFunc() override; + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + const std::vector& GetEncodeInfo() const { + return m_EncodeInfo; + } + uint32_t GetBitsPerSample() const { return m_nBitsPerSample; } + const CPDF_StreamAcc* GetSampleStream() const { + return m_pSampleStream.get(); + } + + private: + std::vector m_EncodeInfo; + std::vector m_DecodeInfo; + uint32_t m_nBitsPerSample; + uint32_t m_SampleMax; + std::unique_ptr m_pSampleStream; +}; + +class CPDF_StitchFunc : public CPDF_Function { + public: + CPDF_StitchFunc(); + ~CPDF_StitchFunc() override; + + // CPDF_Function + FX_BOOL v_Init(CPDF_Object* pObj) override; + FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override; + + const std::vector>& GetSubFunctions() const { + return m_pSubFunctions; + } + FX_FLOAT GetBound(size_t i) const { return m_pBounds[i]; } + + private: + std::vector> m_pSubFunctions; + FX_FLOAT* m_pBounds; + FX_FLOAT* m_pEncode; + + static const uint32_t kRequiredNumInputs = 1; +}; + +class CPDF_IccProfile { + public: + CPDF_IccProfile(const uint8_t* pData, uint32_t dwSize); + ~CPDF_IccProfile(); + uint32_t GetComponents() const { return m_nSrcComponents; } + FX_BOOL m_bsRGB; + void* m_pTransform; + + private: + uint32_t m_nSrcComponents; +}; + +class CPDF_DeviceCS : public CPDF_ColorSpace { + public: + CPDF_DeviceCS(CPDF_Document* pDoc, int family); + + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + FX_BOOL SetRGB(FX_FLOAT* pBuf, + FX_FLOAT R, + FX_FLOAT G, + FX_FLOAT B) const override; + FX_BOOL v_GetCMYK(FX_FLOAT* pBuf, + FX_FLOAT& c, + FX_FLOAT& m, + FX_FLOAT& y, + FX_FLOAT& k) const override; + FX_BOOL v_SetCMYK(FX_FLOAT* pBuf, + FX_FLOAT c, + FX_FLOAT m, + FX_FLOAT y, + FX_FLOAT k) const override; + void TranslateImageLine(uint8_t* pDestBuf, + const uint8_t* pSrcBuf, + int pixels, + int image_width, + int image_height, + FX_BOOL bTransMask = FALSE) const override; +}; + +class CPDF_PatternCS : public CPDF_ColorSpace { + public: + explicit CPDF_PatternCS(CPDF_Document* pDoc); + ~CPDF_PatternCS() override; + FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override; + FX_BOOL GetRGB(FX_FLOAT* pBuf, + FX_FLOAT& R, + FX_FLOAT& G, + FX_FLOAT& B) const override; + CPDF_ColorSpace* GetBaseCS() const override; + + private: + CPDF_ColorSpace* m_pBaseCS; + CPDF_CountedColorSpace* m_pCountedBaseCS; +}; + +#define MAX_PATTERN_COLORCOMPS 16 +struct PatternValue { + CPDF_Pattern* m_pPattern; + CPDF_CountedPattern* m_pCountedPattern; + int m_nComps; + FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS]; +}; + +CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr); +CFX_ByteStringC PDF_FindValueAbbreviationForTesting( + const CFX_ByteStringC& abbr); + +void PDF_ReplaceAbbr(CPDF_Object* pObj); +bool IsPathOperator(const uint8_t* buf, size_t len); + +#endif // CORE_FPDFAPI_PAGE_PAGEINT_H_ -- cgit v1.2.3