diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-05-14 07:18:41 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-05-14 07:18:41 +0000 |
commit | d80121b833b884c80d2b4aecf53f0026373d0579 (patch) | |
tree | 08922476e2693c4751971fb6ebdbecebb7565764 | |
parent | 4d3acf4ec42bf6e838f9060103aff98fbf170794 (diff) | |
parent | 5ae9d0c6fd838a2967cca72aa5751b51dadc2769 (diff) | |
download | pdfium-oreo-r6-release.tar.gz |
release-request-951b3a8b-6c0c-4d2e-8af4-1c3f7e209f66-for-git_oc-release-4006899 snap-temp-L39600000063784275android-security-8.0.0_r54android-security-8.0.0_r53android-security-8.0.0_r52android-cts-8.0_r9android-cts-8.0_r8android-cts-8.0_r7android-cts-8.0_r6android-cts-8.0_r5android-cts-8.0_r4android-cts-8.0_r3android-cts-8.0_r26android-cts-8.0_r25android-cts-8.0_r24android-cts-8.0_r23android-cts-8.0_r22android-cts-8.0_r21android-cts-8.0_r20android-cts-8.0_r2android-cts-8.0_r19android-cts-8.0_r18android-cts-8.0_r17android-cts-8.0_r16android-cts-8.0_r15android-cts-8.0_r14android-cts-8.0_r13android-cts-8.0_r12android-cts-8.0_r11android-cts-8.0_r10android-cts-8.0_r1android-8.0.0_r9android-8.0.0_r7android-8.0.0_r51android-8.0.0_r50android-8.0.0_r49android-8.0.0_r48android-8.0.0_r47android-8.0.0_r46android-8.0.0_r45android-8.0.0_r44android-8.0.0_r43android-8.0.0_r42android-8.0.0_r41android-8.0.0_r40android-8.0.0_r4android-8.0.0_r39android-8.0.0_r38android-8.0.0_r37android-8.0.0_r36android-8.0.0_r35android-8.0.0_r32android-8.0.0_r31android-8.0.0_r30android-8.0.0_r3android-8.0.0_r29android-8.0.0_r28android-8.0.0_r2android-8.0.0_r17android-8.0.0_r16android-8.0.0_r15android-8.0.0_r13android-8.0.0_r12android-8.0.0_r11android-8.0.0_r10android-8.0.0_r1security-oc-releaseoreo-security-releaseoreo-releaseoreo-r6-releaseoreo-r5-releaseoreo-r4-releaseoreo-r3-releaseoreo-r2-releaseoreo-cts-release
Change-Id: I18c5f743405466b4cb690afb2ea61bfb492784fe
615 files changed, 19255 insertions, 24888 deletions
@@ -4,3 +4,12 @@ buildconfig = "//build/config/BUILDCONFIG.gn" secondary_source = "//build/secondary/" + +default_args = { + v8_extra_library_files = [] + v8_experimental_extra_library_files = [] + v8_enable_inspector = false + + # Turns on compiler optimizations in V8 in Debug build. + v8_optimized_debug = true +} @@ -27,6 +27,7 @@ Lei Zhang <thestig@chromium.org> Lucas Nihlen <luken@chromium.org> Matt Giuca <mgiuca@chromium.org> Michael Doppler <m.doppler@gmail.com> +Miklos Vajna <vmiklos@vmiklos.hu> Nico Weber <thakis@chromium.org> Peter Kasting <pkasting@chromium.org> Raymes Khoury <raymes@chromium.org> @@ -2,12 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build_overrides/v8.gni") import("//testing/test.gni") import("pdfium.gni") config("pdfium_common_config") { cflags = [] + ldflags = [] include_dirs = [ ".", "third_party/freetype/include", @@ -33,16 +33,36 @@ config("pdfium_common_config") { if (pdf_enable_xfa) { defines += [ "PDF_ENABLE_XFA" ] + if (pdf_enable_xfa_bmp) { + defines += [ "PDF_ENABLE_XFA_BMP" ] + } + if (pdf_enable_xfa_gif) { + defines += [ "PDF_ENABLE_XFA_GIF" ] + } + if (pdf_enable_xfa_png) { + defines += [ "PDF_ENABLE_XFA_PNG" ] + } + if (pdf_enable_xfa_tiff) { + defines += [ "PDF_ENABLE_XFA_TIFF" ] + } } if (pdf_use_win32_gdi) { defines += [ "PDFIUM_PRINT_TEXT_WITH_GDI" ] } + + if (use_coverage && is_clang) { + cflags += [ + "--coverage", + "-g", + "-O0", + ] + ldflags += [ "--coverage" ] + } } config("pdfium_core_config") { cflags = [] - ldflags = [] configs = [ ":pdfium_common_config" ] defines = [ "V8_DEPRECATION_WARNINGS" ] if (is_linux) { @@ -56,14 +76,6 @@ config("pdfium_core_config") { if (is_win) { cflags += [ "/wd4267" ] } - if (use_coverage && is_clang) { - cflags += [ - "--coverage", - "-g", - "-O0", - ] - ldflags += [ "--coverage" ] - } } config("xfa_warnings") { @@ -112,6 +124,8 @@ static_library("pdfium") { "fpdfsdk/fpdfdoc.cpp", "fpdfsdk/fpdfeditimg.cpp", "fpdfsdk/fpdfeditpage.cpp", + "fpdfsdk/fpdfeditpath.cpp", + "fpdfsdk/fpdfedittext.cpp", "fpdfsdk/fpdfformfill.cpp", "fpdfsdk/fpdfppo.cpp", "fpdfsdk/fpdfsave.cpp", @@ -685,16 +699,20 @@ static_library("fxcodec") { if (pdf_enable_xfa) { sources += [ + "core/fxcodec/codec/ccodec_bmpmodule.cpp", "core/fxcodec/codec/ccodec_bmpmodule.h", + "core/fxcodec/codec/ccodec_gifmodule.cpp", "core/fxcodec/codec/ccodec_gifmodule.h", + "core/fxcodec/codec/ccodec_pngmodule.cpp", "core/fxcodec/codec/ccodec_pngmodule.h", "core/fxcodec/codec/ccodec_progressivedecoder.h", + "core/fxcodec/codec/ccodec_tiffmodule.cpp", "core/fxcodec/codec/ccodec_tiffmodule.h", - "core/fxcodec/codec/fx_codec_bmp.cpp", - "core/fxcodec/codec/fx_codec_gif.cpp", - "core/fxcodec/codec/fx_codec_png.cpp", "core/fxcodec/codec/fx_codec_progress.cpp", - "core/fxcodec/codec/fx_codec_tiff.cpp", + "core/fxcodec/codec/icodec_bmpmodule.h", + "core/fxcodec/codec/icodec_gifmodule.h", + "core/fxcodec/codec/icodec_pngmodule.h", + "core/fxcodec/codec/icodec_tiffmodule.h", "core/fxcodec/lbmp/fx_bmp.cpp", "core/fxcodec/lbmp/fx_bmp.h", "core/fxcodec/lgif/fx_gif.cpp", @@ -964,6 +982,7 @@ static_library("pdfwindow") { "fpdfsdk/pdfwindow/PWL_Utils.h", "fpdfsdk/pdfwindow/PWL_Wnd.cpp", "fpdfsdk/pdfwindow/PWL_Wnd.h", + "fpdfsdk/pdfwindow/cpwl_color.cpp", "fpdfsdk/pdfwindow/cpwl_color.h", ] configs += [ ":pdfium_core_config" ] @@ -974,7 +993,7 @@ static_library("pdfwindow") { static_library("javascript") { sources = [ - "fpdfsdk/javascript/ijs_context.h", + "fpdfsdk/javascript/ijs_event_context.h", "fpdfsdk/javascript/ijs_runtime.h", ] configs += [ ":pdfium_core_config" ] @@ -1009,8 +1028,8 @@ static_library("javascript") { "fpdfsdk/javascript/PublicMethods.h", "fpdfsdk/javascript/app.cpp", "fpdfsdk/javascript/app.h", - "fpdfsdk/javascript/cjs_context.cpp", - "fpdfsdk/javascript/cjs_context.h", + "fpdfsdk/javascript/cjs_event_context.cpp", + "fpdfsdk/javascript/cjs_event_context.h", "fpdfsdk/javascript/cjs_runtime.cpp", "fpdfsdk/javascript/cjs_runtime.h", "fpdfsdk/javascript/color.cpp", @@ -1144,27 +1163,20 @@ if (pdf_enable_xfa) { "xfa/fde/cfx_chariter.h", "xfa/fde/cfx_wordbreak.cpp", "xfa/fde/cfx_wordbreak.h", - "xfa/fde/css/cfde_cssaccelerator.cpp", - "xfa/fde/css/cfde_cssaccelerator.h", "xfa/fde/css/cfde_csscolorvalue.cpp", "xfa/fde/css/cfde_csscolorvalue.h", "xfa/fde/css/cfde_csscomputedstyle.cpp", "xfa/fde/css/cfde_csscomputedstyle.h", + "xfa/fde/css/cfde_csscustomproperty.cpp", "xfa/fde/css/cfde_csscustomproperty.h", "xfa/fde/css/cfde_cssdeclaration.cpp", "xfa/fde/css/cfde_cssdeclaration.h", "xfa/fde/css/cfde_cssenumvalue.cpp", "xfa/fde/css/cfde_cssenumvalue.h", - "xfa/fde/css/cfde_cssfontfacerule.cpp", - "xfa/fde/css/cfde_cssfontfacerule.h", - "xfa/fde/css/cfde_cssmediarule.cpp", - "xfa/fde/css/cfde_cssmediarule.h", "xfa/fde/css/cfde_cssnumbervalue.cpp", "xfa/fde/css/cfde_cssnumbervalue.h", "xfa/fde/css/cfde_csspropertyholder.cpp", "xfa/fde/css/cfde_csspropertyholder.h", - "xfa/fde/css/cfde_cssrule.cpp", - "xfa/fde/css/cfde_cssrule.h", "xfa/fde/css/cfde_cssrulecollection.cpp", "xfa/fde/css/cfde_cssrulecollection.h", "xfa/fde/css/cfde_cssselector.cpp", @@ -1179,8 +1191,6 @@ if (pdf_enable_xfa) { "xfa/fde/css/cfde_cssstylesheet.h", "xfa/fde/css/cfde_csssyntaxparser.cpp", "xfa/fde/css/cfde_csssyntaxparser.h", - "xfa/fde/css/cfde_csstagcache.cpp", - "xfa/fde/css/cfde_csstagcache.h", "xfa/fde/css/cfde_csstextbuf.cpp", "xfa/fde/css/cfde_csstextbuf.h", "xfa/fde/css/cfde_cssvalue.cpp", @@ -1228,8 +1238,6 @@ if (pdf_enable_xfa) { "xfa/fgas/layout/fgas_rtfbreak.h", "xfa/fgas/layout/fgas_textbreak.cpp", "xfa/fgas/layout/fgas_textbreak.h", - "xfa/fgas/layout/fgas_unicode.cpp", - "xfa/fgas/layout/fgas_unicode.h", "xfa/fgas/localization/fgas_datetime.cpp", "xfa/fgas/localization/fgas_datetime.h", "xfa/fgas/localization/fgas_locale.cpp", @@ -1323,7 +1331,6 @@ if (pdf_enable_xfa) { "xfa/fwl/cfwl_widgetproperties.h", "xfa/fwl/cfx_barcode.cpp", "xfa/fwl/cfx_barcode.h", - "xfa/fwl/fwl_error.h", "xfa/fwl/fwl_widgetdef.h", "xfa/fwl/fwl_widgethit.h", "xfa/fwl/ifwl_adaptertimermgr.h", @@ -1710,16 +1717,12 @@ if (pdf_enable_xfa) { "xfa/fxfa/xfa_ffwidgethandler.h", "xfa/fxfa/xfa_fontmgr.h", "xfa/fxfa/xfa_rendercontext.h", - "xfa/fxgraphics/cagg_graphics.cpp", - "xfa/fxgraphics/cagg_graphics.h", "xfa/fxgraphics/cfx_color.cpp", "xfa/fxgraphics/cfx_color.h", "xfa/fxgraphics/cfx_graphics.cpp", "xfa/fxgraphics/cfx_graphics.h", "xfa/fxgraphics/cfx_path.cpp", "xfa/fxgraphics/cfx_path.h", - "xfa/fxgraphics/cfx_path_generator.cpp", - "xfa/fxgraphics/cfx_path_generator.h", "xfa/fxgraphics/cfx_pattern.cpp", "xfa/fxgraphics/cfx_pattern.h", "xfa/fxgraphics/cfx_shading.cpp", @@ -1740,6 +1743,7 @@ if (pdf_enable_xfa) { test("pdfium_unittests") { sources = [ "core/fdrm/crypto/fx_crypt_unittest.cpp", + "core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp", "core/fpdfapi/font/fpdf_font_cid_unittest.cpp", "core/fpdfapi/font/fpdf_font_unittest.cpp", "core/fpdfapi/page/cpdf_streamcontentparser_unittest.cpp", @@ -1790,6 +1794,7 @@ test("pdfium_unittests") { "xfa/fde/cfde_txtedtbuf_unittest.cpp", "xfa/fde/css/cfde_cssdeclaration_unittest.cpp", "xfa/fde/css/cfde_cssstylesheet_unittest.cpp", + "xfa/fde/css/cfde_cssvaluelistparser_unittest.cpp", "xfa/fde/xml/fde_xml_imp_unittest.cpp", "xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp", "xfa/fxfa/app/cxfa_textparser_unittest.cpp", @@ -5,21 +5,21 @@ vars = { 'pdfium_git': 'https://pdfium.googlesource.com', 'android_ndk_revision': '26d93ec07f3ce2ec2cdfeae1b21ee6f12ff868d8', - 'build_revision': 'acf607f7d345915ea2ecca208bc516677d298463', - 'buildtools_revision': '5fd66957f08bb752dca714a591c84587c9d70762', + 'build_revision': 'dd795a26b9e43ff3a0d761bfd509c2fa67a3a7a1', + 'buildtools_revision': 'cf493f8b1ae59611b19b000d7af922559b6ae92a', 'catapult_revision': '86352b966b0245d6883e5f7df27687856978b6d7', - 'clang_revision': '0a306690ccb471f75990b488b8b61cabbcca3011', + 'clang_revision': '37d701b87a10a2bdee1a5c3523f754ebf64a7e66', 'cygwin_revision': 'c89e446b273697fadf3a10ff1007a97c0b7de6df', 'gen_library_loader_revision': '916d4acd8b2cde67a390737dfba90b3c37de23a1', 'gmock_revision': '29763965ab52f24565299976b936d1265cb6a271', 'gtest_revision': '8245545b6dc9c4703e6496d1efd19e975ad2b038', 'icu_revision': '73e24736676b4b438270fda44e5b2c83b49fdd80', 'instrumented_lib_revision': '45f5814b1543e41ea0be54c771e3840ea52cca4a', - 'pdfium_tests_revision': '9d17ef47f310332ac64e78e636681d493482a409', - 'skia_revision': 'f44703a87f532b3f593d91605d66d52c6bbc45c9', + 'pdfium_tests_revision': 'd25a422ab03d6c3109370bc454c629575e969329', + 'skia_revision': '90e3cd78991ef337dbd0023efb30ece864694308', 'tools_memory_revision': '427f10475e1a8d72424c29d00bf689122b738e5d', 'trace_event_revision': '06294c8a4a6f744ef284cd63cfe54dbf61eea290', - 'v8_revision': '8e0dcfc4ac75c0bef9063bd5dec4dafaa3409b6d', + 'v8_revision': '7a634798302b4ab1f1525a9a881629519c0c2a99', } deps = { @@ -44,7 +44,6 @@ can be found in `depot_tools\win_toolchain\vs_files\<hash>\win_sdk\Debuggers`. If you want the IDE for debugging and editing, you will need to install it separately, but this is optional and not needed for building PDFium. - ## Get the code The name of the top-level directory does not matter. In our examples, we use @@ -105,7 +104,6 @@ If you used Ninja, you can build the sample program by: `ninja -C <directory>/pdfium_test` You can build the entire product (which includes a few unit tests) by: `ninja -C <directory>`. - ## Running the sample program The pdfium\_test program supports reading, parsing, and rasterizing the pages of diff --git a/build_overrides/build.gni b/build_overrides/build.gni index 61d781400..af65788b8 100644 --- a/build_overrides/build.gni +++ b/build_overrides/build.gni @@ -12,12 +12,12 @@ mac_deployment_target_build_override = "10.7" # Variable that can be used to support multiple build scenarios, like having # Chromium specific targets in a client project's GN file etc. -build_with_chromium = true +build_with_chromium = false # Support different NDK locations in non-Chromium builds. default_android_ndk_root = "//third_party/android_ndk" default_android_ndk_version = "r12b" -default_android_ndk_major_version = "12" +default_android_ndk_major_version = 12 # PDFium builds don't support building java targets. enable_java_templates = false @@ -51,8 +51,9 @@ declare_args() { if (use_system_xcode == "") { if (target_os == "mac") { - _result = - exec_script("//build/mac/should_use_hermetic_xcode.py", [], "value") + _result = exec_script("//build/mac/should_use_hermetic_xcode.py", + [ target_os ], + "value") use_system_xcode = _result == 0 } if (target_os == "ios") { diff --git a/build_overrides/v8.gni b/build_overrides/v8.gni deleted file mode 100644 index d9c21d485..000000000 --- a/build_overrides/v8.gni +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2015 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -if (is_android) { - import("//build/config/android/config.gni") -} - -v8_use_external_startup_data = !is_ios - -# Turns on compiler optimizations in V8 in Debug build. -v8_optimized_debug = true - -# V8 extras -# Adding V8 extras files requires API owners review -# Be sure to synchronize with build/common.gypi - -v8_extra_library_files = [] -v8_experimental_extra_library_files = [] - -v8_enable_inspector_override = false diff --git a/codereview.settings b/codereview.settings index 5724235e4..77265c947 100644 --- a/codereview.settings +++ b/codereview.settings @@ -1,7 +1,8 @@ -# This file is used by gcl to get repository specific information. -CODE_REVIEW_SERVER: codereview.chromium.org +# This file is used by git cl to get repository specific information. CC_LIST: pdfium-reviews@googlegroups.com +CODE_REVIEW_SERVER: codereview.chromium.org +GERRIT_HOST: True +PROJECT: pdfium STATUS: http://pdfium-status.appspot.com/status TRY_ON_UPLOAD: False VIEW_VC: https://pdfium.googlesource.com/pdfium/+/ -PROJECT: pdfium diff --git a/core/fpdfapi/cpdf_pagerendercontext.cpp b/core/fpdfapi/cpdf_pagerendercontext.cpp index 91ebc5e7b..39a881c3b 100644 --- a/core/fpdfapi/cpdf_pagerendercontext.cpp +++ b/core/fpdfapi/cpdf_pagerendercontext.cpp @@ -15,7 +15,4 @@ CPDF_PageRenderContext::CPDF_PageRenderContext() {} -CPDF_PageRenderContext::~CPDF_PageRenderContext() { - if (m_pOptions) - delete m_pOptions->m_pOCContext; -} +CPDF_PageRenderContext::~CPDF_PageRenderContext() {} diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp index a65d56414..35595b3e1 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.cpp @@ -6,13 +6,21 @@ #include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h" +#include <tuple> +#include <utility> + +#include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/page/cpdf_docpagedata.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_path.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_textobject.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_document.h" #include "core/fpdfapi/parser/cpdf_name.h" +#include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_reference.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "core/fpdfapi/parser/fpdf_parser_decode.h" @@ -25,6 +33,19 @@ CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& ar, const CFX_Matrix& matrix) { return ar; } +bool GetColor(const CPDF_Color* pColor, FX_FLOAT* rgb) { + int intRGB[3]; + if (!pColor || + pColor->GetColorSpace() != CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB) || + !pColor->GetRGB(intRGB[0], intRGB[1], intRGB[2])) { + return false; + } + rgb[0] = intRGB[0] / 255.0f; + rgb[1] = intRGB[1] / 255.0f; + rgb[2] = intRGB[2] / 255.0f; + return true; +} + } // namespace CPDF_PageContentGenerator::CPDF_PageContentGenerator(CPDF_Page* pPage) @@ -40,9 +61,12 @@ CPDF_PageContentGenerator::~CPDF_PageContentGenerator() {} void CPDF_PageContentGenerator::GenerateContent() { CFX_ByteTextBuf buf; for (CPDF_PageObject* pPageObj : m_pageObjects) { - CPDF_ImageObject* pImageObject = pPageObj->AsImage(); - if (pImageObject) + if (CPDF_ImageObject* pImageObject = pPageObj->AsImage()) ProcessImage(&buf, pImageObject); + else if (CPDF_PathObject* pPathObj = pPageObj->AsPath()) + ProcessPath(&buf, pPathObj); + else if (CPDF_TextObject* pTextObj = pPageObj->AsText()) + ProcessText(&buf, pTextObj); } CPDF_Dictionary* pPageDict = m_pPage->m_pFormDict; CPDF_Object* pContent = @@ -109,3 +133,144 @@ void CPDF_PageContentGenerator::ProcessImage(CFX_ByteTextBuf* buf, *buf << "/" << PDF_NameEncode(name) << " Do Q\n"; } + +// Processing path with operators from Tables 4.9 and 4.10 of PDF spec 1.7: +// "re" appends a rectangle (here, used only if the whole path is a rectangle) +// "m" moves current point to the given coordinates +// "l" creates a line from current point to the new point +// "c" adds a Bezier curve from current to last point, using the two other +// points as the Bezier control points +// Note: "l", "c" change the current point +// "h" closes the subpath (appends a line from current to starting point) +// Path painting operators: "S", "n", "B", "f", "B*", "f*", depending on +// the filling mode and whether we want stroking the path or not. +// "Q" restores the graphics state imposed by the ProcessGraphics method. +void CPDF_PageContentGenerator::ProcessPath(CFX_ByteTextBuf* buf, + CPDF_PathObject* pPathObj) { + ProcessGraphics(buf, pPathObj); + auto& pPoints = pPathObj->m_Path.GetPoints(); + if (pPathObj->m_Path.IsRect()) { + CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point; + *buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x + << " " << diff.y << " re"; + } else { + for (size_t i = 0; i < pPoints.size(); i++) { + if (i > 0) + *buf << " "; + *buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y; + FXPT_TYPE pointType = pPoints[i].m_Type; + if (pointType == FXPT_TYPE::MoveTo) { + *buf << " m"; + } else if (pointType == FXPT_TYPE::LineTo) { + *buf << " l"; + } else if (pointType == FXPT_TYPE::BezierTo) { + if (i + 2 >= pPoints.size() || + !pPoints[i].IsTypeAndOpen(FXPT_TYPE::BezierTo) || + !pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::BezierTo) || + pPoints[i + 2].m_Type != FXPT_TYPE::BezierTo) { + // If format is not supported, close the path and paint + *buf << " h"; + break; + } + *buf << " " << pPoints[i + 1].m_Point.x << " " + << pPoints[i + 1].m_Point.y << " " << pPoints[i + 2].m_Point.x + << " " << pPoints[i + 2].m_Point.y << " c"; + i += 2; + } + if (pPoints[i].m_CloseFigure) + *buf << " h"; + } + } + if (pPathObj->m_FillType == 0) + *buf << (pPathObj->m_bStroke ? " S" : " n"); + else if (pPathObj->m_FillType == FXFILL_WINDING) + *buf << (pPathObj->m_bStroke ? " B" : " f"); + else if (pPathObj->m_FillType == FXFILL_ALTERNATE) + *buf << (pPathObj->m_bStroke ? " B*" : " f*"); + *buf << " Q\n"; +} + +// This method supports color operators rg and RGB from Table 4.24 of PDF spec +// 1.7. A color will not be set if the colorspace is not DefaultRGB or the RGB +// values cannot be obtained. The method also adds an external graphics +// dictionary, as described in Section 4.3.4. +// "rg" sets the fill color, "RG" sets the stroke color (using DefaultRGB) +// "w" sets the stroke line width. +// "ca" sets the fill alpha, "CA" sets the stroke alpha. +// "q" saves the graphics state, so that the settings can later be reversed +void CPDF_PageContentGenerator::ProcessGraphics(CFX_ByteTextBuf* buf, + CPDF_PageObject* pPageObj) { + *buf << "q "; + FX_FLOAT fillColor[3]; + if (GetColor(pPageObj->m_ColorState.GetFillColor(), fillColor)) { + *buf << fillColor[0] << " " << fillColor[1] << " " << fillColor[2] + << " rg "; + } + FX_FLOAT strokeColor[3]; + if (GetColor(pPageObj->m_ColorState.GetStrokeColor(), strokeColor)) { + *buf << strokeColor[0] << " " << strokeColor[1] << " " << strokeColor[2] + << " RG "; + } + FX_FLOAT lineWidth = pPageObj->m_GraphState.GetLineWidth(); + if (lineWidth != 1.0f) + *buf << lineWidth << " w "; + + GraphicsData graphD; + graphD.fillAlpha = pPageObj->m_GeneralState.GetFillAlpha(); + graphD.strokeAlpha = pPageObj->m_GeneralState.GetStrokeAlpha(); + if (graphD.fillAlpha == 1.0f && graphD.strokeAlpha == 1.0f) + return; + + CFX_ByteString name; + auto it = m_pPage->m_GraphicsMap.find(graphD); + if (it != m_pPage->m_GraphicsMap.end()) { + name = it->second; + } else { + auto gsDict = pdfium::MakeUnique<CPDF_Dictionary>(); + gsDict->SetNewFor<CPDF_Number>("ca", graphD.fillAlpha); + gsDict->SetNewFor<CPDF_Number>("CA", graphD.strokeAlpha); + CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(gsDict)); + uint32_t dwObjNum = pDict->GetObjNum(); + name = RealizeResource(dwObjNum, "ExtGState"); + m_pPage->m_GraphicsMap[graphD] = name; + } + *buf << "/" << PDF_NameEncode(name) << " gs "; +} + +// This method adds text to the buffer, BT begins the text object, ET ends it. +// Tm sets the text matrix (allows positioning and transforming text). +// Tf sets the font name (from Font in Resources) and font size. +// Tj sets the actual text, <####...> is used when specifying charcodes. +void CPDF_PageContentGenerator::ProcessText(CFX_ByteTextBuf* buf, + CPDF_TextObject* pTextObj) { + // TODO(npm): Add support for something other than standard type1 fonts. + *buf << "BT " << pTextObj->GetTextMatrix() << " Tm "; + CPDF_Font* pFont = pTextObj->GetFont(); + if (!pFont) + pFont = CPDF_Font::GetStockFont(m_pDocument, "Helvetica"); + FontData fontD; + fontD.baseFont = pFont->GetBaseFont(); + auto it = m_pPage->m_FontsMap.find(fontD); + CFX_ByteString dictName; + if (it != m_pPage->m_FontsMap.end()) { + dictName = it->second; + } else { + auto fontDict = pdfium::MakeUnique<CPDF_Dictionary>(); + fontDict->SetNewFor<CPDF_Name>("Type", "Font"); + fontDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); + fontDict->SetNewFor<CPDF_Name>("BaseFont", fontD.baseFont); + CPDF_Object* pDict = m_pDocument->AddIndirectObject(std::move(fontDict)); + uint32_t dwObjNum = pDict->GetObjNum(); + dictName = RealizeResource(dwObjNum, "Font"); + m_pPage->m_FontsMap[fontD] = dictName; + } + *buf << "/" << PDF_NameEncode(dictName) << " " << pTextObj->GetFontSize() + << " Tf "; + CFX_ByteString text; + for (uint32_t charcode : pTextObj->m_CharCodes) { + if (charcode == CPDF_Font::kInvalidCharCode) + continue; + pFont->AppendChar(text, charcode); + } + *buf << PDF_EncodeString(text, true) << " Tj ET\n"; +} diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h index ac06dcb55..73e75187e 100644 --- a/core/fpdfapi/edit/cpdf_pagecontentgenerator.h +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator.h @@ -16,6 +16,8 @@ class CPDF_Document; class CPDF_ImageObject; class CPDF_Page; class CPDF_PageObject; +class CPDF_PathObject; +class CPDF_TextObject; class CPDF_PageContentGenerator { public: @@ -25,7 +27,12 @@ class CPDF_PageContentGenerator { void GenerateContent(); private: + friend class CPDF_PageContentGeneratorTest; + + void ProcessPath(CFX_ByteTextBuf* buf, CPDF_PathObject* pPathObj); void ProcessImage(CFX_ByteTextBuf* buf, CPDF_ImageObject* pImageObj); + void ProcessGraphics(CFX_ByteTextBuf* buf, CPDF_PageObject* pPageObj); + void ProcessText(CFX_ByteTextBuf* buf, CPDF_TextObject* pTextObj); CFX_ByteString RealizeResource(uint32_t dwResourceObjNum, const CFX_ByteString& bsType); diff --git a/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp new file mode 100644 index 000000000..d8813ba30 --- /dev/null +++ b/core/fpdfapi/edit/cpdf_pagecontentgenerator_unittest.cpp @@ -0,0 +1,178 @@ +// Copyright 2017 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/edit/cpdf_pagecontentgenerator.h" + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_parser.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/base/ptr_util.h" + +class CPDF_PageContentGeneratorTest : public testing::Test { + protected: + void SetUp() override { CPDF_ModuleMgr::Get()->InitPageModule(); } + + void TearDown() override { CPDF_ModuleMgr::Destroy(); } + + void TestProcessPath(CPDF_PageContentGenerator* pGen, + CFX_ByteTextBuf* buf, + CPDF_PathObject* pPathObj) { + pGen->ProcessPath(buf, pPathObj); + } + + CPDF_Dictionary* TestGetResource(CPDF_PageContentGenerator* pGen, + const CFX_ByteString& type, + const CFX_ByteString& name) { + return pGen->m_pPage->m_pResources->GetDictFor(type)->GetDictFor(name); + } + + void TestProcessText(CPDF_PageContentGenerator* pGen, + CFX_ByteTextBuf* buf, + CPDF_TextObject* pTextObj) { + pGen->ProcessText(buf, pTextObj); + } +}; + +TEST_F(CPDF_PageContentGeneratorTest, ProcessRect) { + auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>(); + pPathObj->m_Path.AppendRect(10, 5, 13, 30); + pPathObj->m_FillType = FXFILL_ALTERNATE; + pPathObj->m_bStroke = true; + + auto pTestPage = pdfium::MakeUnique<CPDF_Page>(nullptr, nullptr, false); + CPDF_PageContentGenerator generator(pTestPage.get()); + CFX_ByteTextBuf buf; + TestProcessPath(&generator, &buf, pPathObj.get()); + EXPECT_EQ("q 10 5 3 25 re B* Q\n", buf.MakeString()); + + pPathObj = pdfium::MakeUnique<CPDF_PathObject>(); + pPathObj->m_Path.AppendPoint(CFX_PointF(0, 0), FXPT_TYPE::MoveTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(5.2f, 0), FXPT_TYPE::LineTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(5.2f, 3.78f), FXPT_TYPE::LineTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(0, 3.78f), FXPT_TYPE::LineTo, true); + pPathObj->m_FillType = 0; + pPathObj->m_bStroke = false; + buf.Clear(); + + TestProcessPath(&generator, &buf, pPathObj.get()); + EXPECT_EQ("q 0 0 5.2 3.78 re n Q\n", buf.MakeString()); +} + +TEST_F(CPDF_PageContentGeneratorTest, ProcessPath) { + auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>(); + pPathObj->m_Path.AppendPoint(CFX_PointF(3.102f, 4.67f), FXPT_TYPE::MoveTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(5.45f, 0.29f), FXPT_TYPE::LineTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(4.24f, 3.15f), FXPT_TYPE::BezierTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(4.65f, 2.98f), FXPT_TYPE::BezierTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(3.456f, 0.24f), FXPT_TYPE::BezierTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(10.6f, 11.15f), FXPT_TYPE::LineTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(11, 12.5f), FXPT_TYPE::LineTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(11.46f, 12.67f), FXPT_TYPE::BezierTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(11.84f, 12.96f), FXPT_TYPE::BezierTo, + false); + pPathObj->m_Path.AppendPoint(CFX_PointF(12, 13.64f), FXPT_TYPE::BezierTo, + true); + pPathObj->m_FillType = FXFILL_WINDING; + pPathObj->m_bStroke = false; + + auto pTestPage = pdfium::MakeUnique<CPDF_Page>(nullptr, nullptr, false); + CPDF_PageContentGenerator generator(pTestPage.get()); + CFX_ByteTextBuf buf; + TestProcessPath(&generator, &buf, pPathObj.get()); + EXPECT_EQ( + "q 3.102 4.67 m 5.45 0.29 l 4.24 3.15 4.65 2.98 3.456 0.24 c 10.6 11.15 " + "l 11 12.5 l 11.46 12.67 11.84 12.96 12 13.64 c h f Q\n", + buf.MakeString()); +} + +TEST_F(CPDF_PageContentGeneratorTest, ProcessGraphics) { + auto pPathObj = pdfium::MakeUnique<CPDF_PathObject>(); + pPathObj->m_Path.AppendPoint(CFX_PointF(1, 2), FXPT_TYPE::MoveTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(3, 4), FXPT_TYPE::LineTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(5, 6), FXPT_TYPE::LineTo, true); + pPathObj->m_FillType = FXFILL_WINDING; + pPathObj->m_bStroke = true; + + FX_FLOAT rgb[3] = {0.5f, 0.7f, 0.35f}; + CPDF_ColorSpace* pCS = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB); + pPathObj->m_ColorState.SetFillColor(pCS, rgb, 3); + + FX_FLOAT rgb2[3] = {1, 0.9f, 0}; + pPathObj->m_ColorState.SetStrokeColor(pCS, rgb2, 3); + pPathObj->m_GeneralState.SetFillAlpha(0.5f); + pPathObj->m_GeneralState.SetStrokeAlpha(0.8f); + + auto pDoc = pdfium::MakeUnique<CPDF_Document>(nullptr); + pDoc->CreateNewDoc(); + CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0); + auto pTestPage = pdfium::MakeUnique<CPDF_Page>(pDoc.get(), pPageDict, false); + CPDF_PageContentGenerator generator(pTestPage.get()); + CFX_ByteTextBuf buf; + TestProcessPath(&generator, &buf, pPathObj.get()); + CFX_ByteString pathString = buf.MakeString(); + + // Color RGB values used are integers divided by 255. + EXPECT_EQ("q 0.501961 0.701961 0.34902 rg 1 0.901961 0 RG /", + pathString.Left(48)); + EXPECT_EQ(" gs 1 2 m 3 4 l 5 6 l h B Q\n", pathString.Right(28)); + ASSERT_TRUE(pathString.GetLength() > 76); + CPDF_Dictionary* externalGS = TestGetResource( + &generator, "ExtGState", pathString.Mid(48, pathString.GetLength() - 76)); + ASSERT_TRUE(externalGS); + EXPECT_EQ(0.5f, externalGS->GetNumberFor("ca")); + EXPECT_EQ(0.8f, externalGS->GetNumberFor("CA")); + + // Same path, now with a stroke. + pPathObj->m_GraphState.SetLineWidth(10.5f); + buf.Clear(); + TestProcessPath(&generator, &buf, pPathObj.get()); + CFX_ByteString pathString2 = buf.MakeString(); + EXPECT_EQ("q 0.501961 0.701961 0.34902 rg 1 0.901961 0 RG 10.5 w /", + pathString2.Left(55)); + EXPECT_EQ(" gs 1 2 m 3 4 l 5 6 l h B Q\n", pathString2.Right(28)); + + // Compare with the previous (should use same dictionary for gs) + EXPECT_EQ(pathString.GetLength() + 7, pathString2.GetLength()); + EXPECT_EQ(pathString.Mid(48, pathString.GetLength() - 76), + pathString2.Mid(55, pathString2.GetLength() - 83)); +} + +TEST_F(CPDF_PageContentGeneratorTest, ProcessText) { + auto pDoc = pdfium::MakeUnique<CPDF_Document>(nullptr); + pDoc->CreateNewDoc(); + CPDF_Dictionary* pPageDict = pDoc->CreateNewPage(0); + auto pTestPage = pdfium::MakeUnique<CPDF_Page>(pDoc.get(), pPageDict, false); + CPDF_PageContentGenerator generator(pTestPage.get()); + auto pTextObj = pdfium::MakeUnique<CPDF_TextObject>(); + CPDF_Font* pFont = CPDF_Font::GetStockFont(pDoc.get(), "Times-Roman"); + pTextObj->m_TextState.SetFont(pFont); + pTextObj->m_TextState.SetFontSize(10.0f); + pTextObj->Transform(CFX_Matrix(1, 0, 0, 1, 100, 100)); + pTextObj->SetText("Hello World"); + CFX_ByteTextBuf buf; + TestProcessText(&generator, &buf, pTextObj.get()); + CFX_ByteString textString = buf.MakeString(); + EXPECT_LT(61, textString.GetLength()); + EXPECT_EQ("BT 1 0 0 1 100 100 Tm /", textString.Left(23)); + EXPECT_EQ(" 10 Tf <48656C6C6F20576F726C64> Tj ET\n", textString.Right(38)); + CPDF_Dictionary* fontDict = TestGetResource( + &generator, "Font", textString.Mid(23, textString.GetLength() - 61)); + ASSERT_TRUE(fontDict); + EXPECT_EQ("Font", fontDict->GetStringFor("Type")); + EXPECT_EQ("Type1", fontDict->GetStringFor("Subtype")); + EXPECT_EQ("Times-Roman", fontDict->GetStringFor("BaseFont")); +} diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp index e96f824bd..6d01538f5 100644 --- a/core/fpdfapi/font/cpdf_cidfont.cpp +++ b/core/fpdfapi/font/cpdf_cidfont.cpp @@ -488,7 +488,7 @@ FX_RECT CPDF_CIDFont::GetCharBBox(uint32_t charcode) { CIDTransformToFloat(pTransform[4]) * 1000, CIDTransformToFloat(pTransform[5]) * 1000); CFX_FloatRect rect_f(rect); - rect_f.Transform(&matrix); + matrix.TransformRect(rect_f); rect = rect_f.GetOuterRect(); } } @@ -608,7 +608,7 @@ int CPDF_CIDFont::GlyphFromCharCode(uint32_t charcode, bool* pVertGlyph) { #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ return cid; #else - if (m_Flags & PDFFONT_SYMBOLIC) + if (m_Flags & FXFONT_SYMBOLIC) return cid; CFX_WideString uni_str = UnicodeFromCharCode(charcode); diff --git a/core/fpdfapi/font/cpdf_font.cpp b/core/fpdfapi/font/cpdf_font.cpp index 556320245..36d7d6aee 100644 --- a/core/fpdfapi/font/cpdf_font.cpp +++ b/core/fpdfapi/font/cpdf_font.cpp @@ -161,7 +161,7 @@ uint32_t CPDF_Font::CharCodeFromUnicode(FX_WCHAR unicode) const { } void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { - m_Flags = pFontDesc->GetIntegerFor("Flags", PDFFONT_NONSYMBOLIC); + m_Flags = pFontDesc->GetIntegerFor("Flags", FXFONT_NONSYMBOLIC); int ItalicAngle = 0; bool bExistItalicAngle = false; if (pFontDesc->KeyExist("ItalicAngle")) { @@ -169,7 +169,7 @@ void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { bExistItalicAngle = true; } if (ItalicAngle < 0) { - m_Flags |= PDFFONT_ITALIC; + m_Flags |= FXFONT_ITALIC; m_ItalicAngle = ItalicAngle; } bool bExistStemV = false; @@ -188,16 +188,14 @@ void CPDF_Font::LoadFontDescriptor(CPDF_Dictionary* pFontDesc) { bExistDescent = true; } bool bExistCapHeight = false; - if (pFontDesc->KeyExist("CapHeight")) { + if (pFontDesc->KeyExist("CapHeight")) bExistCapHeight = true; - } if (bExistItalicAngle && bExistAscent && bExistCapHeight && bExistDescent && bExistStemV) { - m_Flags |= PDFFONT_USEEXTERNATTR; + m_Flags |= FXFONT_USEEXTERNATTR; } - if (m_Descent > 10) { + if (m_Descent > 10) m_Descent = -m_Descent; - } CPDF_Array* pBBox = pFontDesc->GetArrayFor("FontBBox"); if (pBBox) { m_FontBBox.left = pBBox->GetIntegerAt(0); @@ -372,10 +370,9 @@ void CPDF_Font::LoadPDFEncoding(CPDF_Object* pEncoding, iBaseEncoding == PDFFONT_ENCODING_ZAPFDINGBATS) { return; } - if ((m_Flags & PDFFONT_SYMBOLIC) && m_BaseFont == "Symbol") { - if (!bTrueType) { + if ((m_Flags & FXFONT_SYMBOLIC) && m_BaseFont == "Symbol") { + if (!bTrueType) iBaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; - } return; } CFX_ByteString bsEncoding = pEncoding->GetString(); diff --git a/core/fpdfapi/font/cpdf_font.h b/core/fpdfapi/font/cpdf_font.h index 0a46f65fe..6025a82d7 100644 --- a/core/fpdfapi/font/cpdf_font.h +++ b/core/fpdfapi/font/cpdf_font.h @@ -14,17 +14,6 @@ #include "core/fxcrt/fx_system.h" #include "core/fxge/fx_font.h" -#define PDFFONT_FIXEDPITCH 1 -#define PDFFONT_SERIF 2 -#define PDFFONT_SYMBOLIC 4 -#define PDFFONT_SCRIPT 8 -#define PDFFONT_NONSYMBOLIC 32 -#define PDFFONT_ITALIC 64 -#define PDFFONT_ALLCAP 0x10000 -#define PDFFONT_SMALLCAP 0x20000 -#define PDFFONT_FORCEBOLD 0x40000 -#define PDFFONT_USEEXTERNATTR 0x80000 - class CFX_SubstFont; class CPDF_CIDFont; class CPDF_Dictionary; diff --git a/core/fpdfapi/font/cpdf_simplefont.cpp b/core/fpdfapi/font/cpdf_simplefont.cpp index ed9860970..c41427006 100644 --- a/core/fpdfapi/font/cpdf_simplefont.cpp +++ b/core/fpdfapi/font/cpdf_simplefont.cpp @@ -127,15 +127,13 @@ bool CPDF_SimpleFont::LoadCommon() { } } if (m_pFontFile) { - if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') { + if (m_BaseFont.GetLength() > 8 && m_BaseFont[7] == '+') m_BaseFont = m_BaseFont.Mid(8); - } } else { LoadSubstFont(); } - if (!(m_Flags & PDFFONT_SYMBOLIC)) { + if (!(m_Flags & FXFONT_SYMBOLIC)) m_BaseEncoding = PDFFONT_ENCODING_STANDARD; - } CPDF_Object* pEncoding = m_pFontDict->GetDirectObjectFor("Encoding"); LoadPDFEncoding(pEncoding, m_BaseEncoding, &m_CharNames, !!m_pFontFile, m_Font.IsTTFont()); @@ -144,7 +142,7 @@ bool CPDF_SimpleFont::LoadCommon() { if (!m_Font.GetFace()) return true; - if (m_Flags & PDFFONT_ALLCAP) { + if (m_Flags & FXFONT_ALLCAP) { unsigned char kLowercases[][2] = {{'a', 'z'}, {0xe0, 0xf6}, {0xf8, 0xfd}}; for (size_t range = 0; range < FX_ArraySize(kLowercases); ++range) { const auto& lower = kLowercases[range]; @@ -166,21 +164,19 @@ bool CPDF_SimpleFont::LoadCommon() { } void CPDF_SimpleFont::LoadSubstFont() { - if (!m_bUseFontWidth && !(m_Flags & PDFFONT_FIXEDPITCH)) { + if (!m_bUseFontWidth && !(m_Flags & FXFONT_FIXED_PITCH)) { int width = 0, i; for (i = 0; i < 256; i++) { - if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) { + if (m_CharWidth[i] == 0 || m_CharWidth[i] == 0xffff) continue; - } - if (width == 0) { + + if (width == 0) width = m_CharWidth[i]; - } else if (width != m_CharWidth[i]) { + else if (width != m_CharWidth[i]) break; - } - } - if (i == 256 && width) { - m_Flags |= PDFFONT_FIXEDPITCH; } + if (i == 256 && width) + m_Flags |= FXFONT_FIXED_PITCH; } pdfium::base::CheckedNumeric<int> safeStemV(m_StemV); if (m_StemV < 140) diff --git a/core/fpdfapi/font/cpdf_truetypefont.cpp b/core/fpdfapi/font/cpdf_truetypefont.cpp index a395e4711..b8bee2968 100644 --- a/core/fpdfapi/font/cpdf_truetypefont.cpp +++ b/core/fpdfapi/font/cpdf_truetypefont.cpp @@ -42,7 +42,7 @@ void CPDF_TrueTypeFont::LoadGlyphMap() { if (m_pFontFile && m_Font.GetFace()->num_charmaps > 0 && (baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI) && - (m_Flags & PDFFONT_SYMBOLIC)) { + (m_Flags & FXFONT_SYMBOLIC)) { bool bSupportWin = false; bool bSupportMac = false; for (int i = 0; i < FXFT_Get_Face_CharmapCount(m_Font.GetFace()); i++) { @@ -65,7 +65,7 @@ void CPDF_TrueTypeFont::LoadGlyphMap() { if (((baseEncoding == PDFFONT_ENCODING_MACROMAN || baseEncoding == PDFFONT_ENCODING_WINANSI) && m_CharNames.empty()) || - (m_Flags & PDFFONT_NONSYMBOLIC)) { + (m_Flags & FXFONT_NONSYMBOLIC)) { if (!FXFT_Has_Glyph_Names(m_Font.GetFace()) && (!m_Font.GetFace()->num_charmaps || !m_Font.GetFace()->charmaps)) { int nStartChar = m_pFontDict->GetIntegerFor("FirstChar"); @@ -86,7 +86,7 @@ void CPDF_TrueTypeFont::LoadGlyphMap() { bool bMacRoman = false; bool bMSSymbol = false; if (!bMSUnicode) { - if (m_Flags & PDFFONT_NONSYMBOLIC) { + if (m_Flags & FXFONT_NONSYMBOLIC) { bMacRoman = FT_UseTTCharmap(m_Font.GetFace(), 1, 0); bMSSymbol = !bMacRoman && FT_UseTTCharmap(m_Font.GetFace(), 3, 0); } else { diff --git a/core/fpdfapi/font/cpdf_type1font.cpp b/core/fpdfapi/font/cpdf_type1font.cpp index 9ef45100d..1a37555a5 100644 --- a/core/fpdfapi/font/cpdf_type1font.cpp +++ b/core/fpdfapi/font/cpdf_type1font.cpp @@ -84,7 +84,7 @@ bool CPDF_Type1Font::Load() { if (pFontDesc && pFontDesc->KeyExist("Flags")) m_Flags = pFontDesc->GetIntegerFor("Flags"); else - m_Flags = m_Base14Font >= 12 ? PDFFONT_SYMBOLIC : PDFFONT_NONSYMBOLIC; + m_Flags = m_Base14Font >= 12 ? FXFONT_SYMBOLIC : FXFONT_NONSYMBOLIC; if (m_Base14Font < 4) { for (int i = 0; i < 256; i++) @@ -94,7 +94,7 @@ bool CPDF_Type1Font::Load() { m_BaseEncoding = PDFFONT_ENCODING_ADOBE_SYMBOL; else if (m_Base14Font == 13) m_BaseEncoding = PDFFONT_ENCODING_ZAPFDINGBATS; - else if (m_Flags & PDFFONT_NONSYMBOLIC) + else if (m_Flags & FXFONT_NONSYMBOLIC) m_BaseEncoding = PDFFONT_ENCODING_STANDARD; } return LoadCommon(); @@ -189,7 +189,7 @@ void CPDF_Type1Font::LoadGlyphMap() { FT_UseType1Charmap(m_Font.GetFace()); #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ if (bCoreText) { - if (m_Flags & PDFFONT_SYMBOLIC) { + if (m_Flags & FXFONT_SYMBOLIC) { for (int charcode = 0; charcode < 256; charcode++) { const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); @@ -257,7 +257,7 @@ void CPDF_Type1Font::LoadGlyphMap() { return; } #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (m_Flags & PDFFONT_SYMBOLIC) { + if (m_Flags & FXFONT_SYMBOLIC) { for (int charcode = 0; charcode < 256; charcode++) { const FX_CHAR* name = GetAdobeCharName(m_BaseEncoding, m_CharNames, charcode); diff --git a/core/fpdfapi/font/cpdf_type3font.cpp b/core/fpdfapi/font/cpdf_type3font.cpp index 954294584..f6cd6ecf2 100644 --- a/core/fpdfapi/font/cpdf_type3font.cpp +++ b/core/fpdfapi/font/cpdf_type3font.cpp @@ -121,7 +121,7 @@ CPDF_Type3Char* CPDF_Type3Font::LoadChar(uint32_t charcode) { if (rcBBox.right <= rcBBox.left || rcBBox.bottom >= rcBBox.top) char_rect = pNewChar->m_pForm->CalcBoundingBox(); - char_rect.Transform(&m_FontMatrix); + m_FontMatrix.TransformRect(char_rect); rcBBox.left = FXSYS_round(char_rect.left * 1000); rcBBox.right = FXSYS_round(char_rect.right * 1000); rcBBox.top = FXSYS_round(char_rect.top * 1000); diff --git a/core/fpdfapi/font/fpdf_font_cid.cpp b/core/fpdfapi/font/fpdf_font_cid.cpp index 386eec334..afb186d07 100644 --- a/core/fpdfapi/font/fpdf_font_cid.cpp +++ b/core/fpdfapi/font/fpdf_font_cid.cpp @@ -18,6 +18,7 @@ #include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fxcrt/fx_ext.h" #include "core/fxge/fx_freetype.h" +#include "third_party/base/logging.h" #include "third_party/base/stl_util.h" namespace { diff --git a/core/fpdfapi/font/ttgsubtable.cpp b/core/fpdfapi/font/ttgsubtable.cpp index c037746c1..51e8e9cc2 100644 --- a/core/fpdfapi/font/ttgsubtable.cpp +++ b/core/fpdfapi/font/ttgsubtable.cpp @@ -7,6 +7,7 @@ #include "core/fpdfapi/font/ttgsubtable.h" #include "core/fxge/fx_freetype.h" +#include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" CFX_GlyphMap::CFX_GlyphMap() {} @@ -93,33 +94,29 @@ bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, (uint8_t)'t', }; if (!m_bFeautureMapLoad) { - for (int i = 0; i < ScriptList.ScriptCount; i++) { - for (int j = 0; j < ScriptList.ScriptRecord[i].Script.LangSysCount; ++j) { - const auto& record = ScriptList.ScriptRecord[i].Script.LangSysRecord[j]; - for (int k = 0; k < record.LangSys.FeatureCount; ++k) { - uint32_t index = record.LangSys.FeatureIndex[k]; - if (FeatureList.FeatureRecord[index].FeatureTag == tag[0] || - FeatureList.FeatureRecord[index].FeatureTag == tag[1]) { - if (!pdfium::ContainsKey(m_featureMap, index)) { - m_featureMap[index] = index; - } + for (const auto& script : ScriptList.ScriptRecords) { + for (const auto& record : script.Script.LangSysRecords) { + for (const auto& index : record.LangSys.FeatureIndices) { + if (FeatureList.FeatureRecords[index].FeatureTag == tag[0] || + FeatureList.FeatureRecords[index].FeatureTag == tag[1]) { + m_featureSet.insert(index); } } } } - if (m_featureMap.empty()) { - for (int i = 0; i < FeatureList.FeatureCount; i++) { - if (FeatureList.FeatureRecord[i].FeatureTag == tag[0] || - FeatureList.FeatureRecord[i].FeatureTag == tag[1]) { - m_featureMap[i] = i; - } + if (m_featureSet.empty()) { + int i = 0; + for (const auto& feature : FeatureList.FeatureRecords) { + if (feature.FeatureTag == tag[0] || feature.FeatureTag == tag[1]) + m_featureSet.insert(i); + ++i; } } m_bFeautureMapLoad = true; } - for (const auto& pair : m_featureMap) { + for (const auto& item : m_featureSet) { if (GetVerticalGlyphSub(glyphnum, vglyphnum, - &FeatureList.FeatureRecord[pair.second].Feature)) { + &FeatureList.FeatureRecords[item].Feature)) { return true; } } @@ -128,17 +125,14 @@ bool CFX_CTTGSUBTable::GetVerticalGlyph(uint32_t glyphnum, bool CFX_CTTGSUBTable::GetVerticalGlyphSub(uint32_t glyphnum, uint32_t* vglyphnum, - TFeature* Feature) const { - for (int i = 0; i < Feature->LookupCount; i++) { - int index = Feature->LookupListIndex[i]; - if (index < 0 || LookupList.LookupCount < index) { + TFeature* Feature) { + for (int index : Feature->LookupListIndices) { + if (index < 0 || index >= pdfium::CollectionSize<int>(LookupList.Lookups)) continue; - } - if (LookupList.Lookup[index].LookupType == 1) { - if (GetVerticalGlyphSub2(glyphnum, vglyphnum, - &LookupList.Lookup[index])) { - return true; - } + + if (LookupList.Lookups[index].LookupType == 1 && + GetVerticalGlyphSub2(glyphnum, vglyphnum, &LookupList.Lookups[index])) { + return true; } } return false; @@ -146,11 +140,11 @@ bool CFX_CTTGSUBTable::GetVerticalGlyphSub(uint32_t glyphnum, bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, uint32_t* vglyphnum, - TLookup* Lookup) const { - for (int i = 0; i < Lookup->SubTableCount; i++) { - switch (Lookup->SubTable[i]->SubstFormat) { + TLookup* Lookup) { + for (const auto& subTable : Lookup->SubTables) { + switch (subTable->SubstFormat) { case 1: { - TSingleSubstFormat1* tbl1 = (TSingleSubstFormat1*)Lookup->SubTable[i]; + auto tbl1 = static_cast<TSingleSubstFormat1*>(subTable.get()); if (GetCoverageIndex(tbl1->Coverage.get(), glyphnum) >= 0) { *vglyphnum = glyphnum + tbl1->DeltaGlyphID; return true; @@ -158,11 +152,11 @@ bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, break; } case 2: { - TSingleSubstFormat2* tbl2 = (TSingleSubstFormat2*)Lookup->SubTable[i]; - int index = -1; - index = GetCoverageIndex(tbl2->Coverage.get(), glyphnum); - if (0 <= index && index < tbl2->GlyphCount) { - *vglyphnum = tbl2->Substitute[index]; + auto tbl2 = static_cast<TSingleSubstFormat2*>(subTable.get()); + int index = GetCoverageIndex(tbl2->Coverage.get(), glyphnum); + if (index >= 0 && + index < pdfium::CollectionSize<int>(tbl2->Substitutes)) { + *vglyphnum = tbl2->Substitutes[index]; return true; } break; @@ -174,29 +168,28 @@ bool CFX_CTTGSUBTable::GetVerticalGlyphSub2(uint32_t glyphnum, int CFX_CTTGSUBTable::GetCoverageIndex(TCoverageFormatBase* Coverage, uint32_t g) const { - int i = 0; - if (!Coverage) { + if (!Coverage) return -1; - } + switch (Coverage->CoverageFormat) { case 1: { + int i = 0; TCoverageFormat1* c1 = (TCoverageFormat1*)Coverage; - for (i = 0; i < c1->GlyphCount; i++) { - if ((uint32_t)c1->GlyphArray[i] == g) { + for (const auto& glyph : c1->GlyphArray) { + if (static_cast<uint32_t>(glyph) == g) return i; - } + ++i; } return -1; } case 2: { TCoverageFormat2* c2 = (TCoverageFormat2*)Coverage; - for (i = 0; i < c2->RangeCount; i++) { - uint32_t s = c2->RangeRecord[i].Start; - uint32_t e = c2->RangeRecord[i].End; - uint32_t si = c2->RangeRecord[i].StartCoverageIndex; - if (s <= g && g <= e) { + for (const auto& rangeRec : c2->RangeRecords) { + uint32_t s = rangeRec.Start; + uint32_t e = rangeRec.End; + uint32_t si = rangeRec.StartCoverageIndex; + if (s <= g && g <= e) return si + g - s; - } } return -1; } @@ -244,33 +237,21 @@ bool CFX_CTTGSUBTable::Parse(FT_Bytes scriptlist, } void CFX_CTTGSUBTable::ParseScriptList(FT_Bytes raw, TScriptList* rec) { - int i; FT_Bytes sp = raw; - rec->ScriptCount = GetUInt16(sp); - if (rec->ScriptCount <= 0) { - return; - } - rec->ScriptRecord.reset(new TScriptRecord[rec->ScriptCount]); - for (i = 0; i < rec->ScriptCount; i++) { - rec->ScriptRecord[i].ScriptTag = GetUInt32(sp); - uint16_t offset = GetUInt16(sp); - ParseScript(&raw[offset], &rec->ScriptRecord[i].Script); + rec->ScriptRecords = std::vector<TScriptRecord>(GetUInt16(sp)); + for (auto& scriptRec : rec->ScriptRecords) { + scriptRec.ScriptTag = GetUInt32(sp); + ParseScript(&raw[GetUInt16(sp)], &scriptRec.Script); } } void CFX_CTTGSUBTable::ParseScript(FT_Bytes raw, TScript* rec) { - int i; FT_Bytes sp = raw; rec->DefaultLangSys = GetUInt16(sp); - rec->LangSysCount = GetUInt16(sp); - if (rec->LangSysCount <= 0) { - return; - } - rec->LangSysRecord.reset(new TLangSysRecord[rec->LangSysCount]); - for (i = 0; i < rec->LangSysCount; i++) { - rec->LangSysRecord[i].LangSysTag = GetUInt32(sp); - uint16_t offset = GetUInt16(sp); - ParseLangSys(&raw[offset], &rec->LangSysRecord[i].LangSys); + rec->LangSysRecords = std::vector<TLangSysRecord>(GetUInt16(sp)); + for (auto& sysRecord : rec->LangSysRecords) { + sysRecord.LangSysTag = GetUInt32(sp); + ParseLangSys(&raw[GetUInt16(sp)], &sysRecord.LangSys); } } @@ -278,81 +259,45 @@ void CFX_CTTGSUBTable::ParseLangSys(FT_Bytes raw, TLangSys* rec) { FT_Bytes sp = raw; rec->LookupOrder = GetUInt16(sp); rec->ReqFeatureIndex = GetUInt16(sp); - rec->FeatureCount = GetUInt16(sp); - if (rec->FeatureCount <= 0) { - return; - } - rec->FeatureIndex.reset(new uint16_t[rec->FeatureCount]); - FXSYS_memset(rec->FeatureIndex.get(), 0, - sizeof(uint16_t) * rec->FeatureCount); - for (int i = 0; i < rec->FeatureCount; ++i) { - rec->FeatureIndex[i] = GetUInt16(sp); - } + rec->FeatureIndices = std::vector<uint16_t>(GetUInt16(sp)); + for (auto& element : rec->FeatureIndices) + element = GetUInt16(sp); } void CFX_CTTGSUBTable::ParseFeatureList(FT_Bytes raw, TFeatureList* rec) { - int i; FT_Bytes sp = raw; - rec->FeatureCount = GetUInt16(sp); - if (rec->FeatureCount <= 0) { - return; - } - rec->FeatureRecord.reset(new TFeatureRecord[rec->FeatureCount]); - for (i = 0; i < rec->FeatureCount; i++) { - rec->FeatureRecord[i].FeatureTag = GetUInt32(sp); - uint16_t offset = GetUInt16(sp); - ParseFeature(&raw[offset], &rec->FeatureRecord[i].Feature); + rec->FeatureRecords = std::vector<TFeatureRecord>(GetUInt16(sp)); + for (auto& featureRec : rec->FeatureRecords) { + featureRec.FeatureTag = GetUInt32(sp); + ParseFeature(&raw[GetUInt16(sp)], &featureRec.Feature); } } void CFX_CTTGSUBTable::ParseFeature(FT_Bytes raw, TFeature* rec) { - int i; FT_Bytes sp = raw; rec->FeatureParams = GetUInt16(sp); - rec->LookupCount = GetUInt16(sp); - if (rec->LookupCount <= 0) { - return; - } - rec->LookupListIndex.reset(new uint16_t[rec->LookupCount]); - for (i = 0; i < rec->LookupCount; i++) { - rec->LookupListIndex[i] = GetUInt16(sp); - } + rec->LookupListIndices = std::vector<uint16_t>(GetUInt16(sp)); + for (auto& listIndex : rec->LookupListIndices) + listIndex = GetUInt16(sp); } void CFX_CTTGSUBTable::ParseLookupList(FT_Bytes raw, TLookupList* rec) { - int i; FT_Bytes sp = raw; - rec->LookupCount = GetUInt16(sp); - if (rec->LookupCount <= 0) { - return; - } - rec->Lookup.reset(new TLookup[rec->LookupCount]); - for (i = 0; i < rec->LookupCount; i++) { - uint16_t offset = GetUInt16(sp); - ParseLookup(&raw[offset], &rec->Lookup[i]); - } + rec->Lookups = std::vector<TLookup>(GetUInt16(sp)); + for (auto& lookup : rec->Lookups) + ParseLookup(&raw[GetUInt16(sp)], &lookup); } void CFX_CTTGSUBTable::ParseLookup(FT_Bytes raw, TLookup* rec) { - int i; FT_Bytes sp = raw; rec->LookupType = GetUInt16(sp); rec->LookupFlag = GetUInt16(sp); - rec->SubTableCount = GetUInt16(sp); - if (rec->SubTableCount <= 0) { - return; - } - rec->SubTable.reset(new TSubTableBase*[rec->SubTableCount]); - for (i = 0; i < rec->SubTableCount; i++) { - rec->SubTable[i] = nullptr; - } - if (rec->LookupType != 1) { + rec->SubTables = std::vector<std::unique_ptr<TSubTableBase>>(GetUInt16(sp)); + if (rec->LookupType != 1) return; - } - for (i = 0; i < rec->SubTableCount; i++) { - uint16_t offset = GetUInt16(sp); - ParseSingleSubst(&raw[offset], &rec->SubTable[i]); - } + + for (auto& subTable : rec->SubTables) + ParseSingleSubst(&raw[GetUInt16(sp)], &subTable); } CFX_CTTGSUBTable::TCoverageFormatBase* CFX_CTTGSUBTable::ParseCoverage( @@ -372,47 +317,39 @@ CFX_CTTGSUBTable::TCoverageFormatBase* CFX_CTTGSUBTable::ParseCoverage( void CFX_CTTGSUBTable::ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1* rec) { - int i; FT_Bytes sp = raw; - GetUInt16(sp); - rec->GlyphCount = GetUInt16(sp); - if (rec->GlyphCount <= 0) { - return; - } - rec->GlyphArray.reset(new uint16_t[rec->GlyphCount]); - for (i = 0; i < rec->GlyphCount; i++) { - rec->GlyphArray[i] = GetUInt16(sp); - } + (void)GetUInt16(sp); + rec->GlyphArray = std::vector<uint16_t>(GetUInt16(sp)); + for (auto& glyph : rec->GlyphArray) + glyph = GetUInt16(sp); } void CFX_CTTGSUBTable::ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2* rec) { - int i; FT_Bytes sp = raw; - GetUInt16(sp); - rec->RangeCount = GetUInt16(sp); - if (rec->RangeCount <= 0) { - return; - } - rec->RangeRecord.reset(new TRangeRecord[rec->RangeCount]); - for (i = 0; i < rec->RangeCount; i++) { - rec->RangeRecord[i].Start = GetUInt16(sp); - rec->RangeRecord[i].End = GetUInt16(sp); - rec->RangeRecord[i].StartCoverageIndex = GetUInt16(sp); + (void)GetUInt16(sp); + rec->RangeRecords = std::vector<TRangeRecord>(GetUInt16(sp)); + for (auto& rangeRec : rec->RangeRecords) { + rangeRec.Start = GetUInt16(sp); + rangeRec.End = GetUInt16(sp); + rangeRec.StartCoverageIndex = GetUInt16(sp); } } -void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec) { +void CFX_CTTGSUBTable::ParseSingleSubst(FT_Bytes raw, + std::unique_ptr<TSubTableBase>* rec) { FT_Bytes sp = raw; uint16_t Format = GetUInt16(sp); switch (Format) { case 1: - *rec = new TSingleSubstFormat1(); - ParseSingleSubstFormat1(raw, (TSingleSubstFormat1*)*rec); + *rec = pdfium::MakeUnique<TSingleSubstFormat1>(); + ParseSingleSubstFormat1(raw, + static_cast<TSingleSubstFormat1*>(rec->get())); break; case 2: - *rec = new TSingleSubstFormat2(); - ParseSingleSubstFormat2(raw, (TSingleSubstFormat2*)*rec); + *rec = pdfium::MakeUnique<TSingleSubstFormat2>(); + ParseSingleSubstFormat2(raw, + static_cast<TSingleSubstFormat2*>(rec->get())); break; } } @@ -428,23 +365,17 @@ void CFX_CTTGSUBTable::ParseSingleSubstFormat1(FT_Bytes raw, void CFX_CTTGSUBTable::ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2* rec) { - int i; FT_Bytes sp = raw; - GetUInt16(sp); + (void)GetUInt16(sp); uint16_t offset = GetUInt16(sp); rec->Coverage.reset(ParseCoverage(&raw[offset])); - rec->GlyphCount = GetUInt16(sp); - if (rec->GlyphCount <= 0) { - return; - } - rec->Substitute.reset(new uint16_t[rec->GlyphCount]); - for (i = 0; i < rec->GlyphCount; i++) { - rec->Substitute[i] = GetUInt16(sp); - } + rec->Substitutes = std::vector<uint16_t>(GetUInt16(sp)); + for (auto& substitute : rec->Substitutes) + substitute = GetUInt16(sp); } CFX_CTTGSUBTable::TCoverageFormat1::TCoverageFormat1() - : TCoverageFormatBase(1), GlyphCount(0) {} + : TCoverageFormatBase(1) {} CFX_CTTGSUBTable::TCoverageFormat1::~TCoverageFormat1() {} @@ -452,7 +383,7 @@ CFX_CTTGSUBTable::TRangeRecord::TRangeRecord() : Start(0), End(0), StartCoverageIndex(0) {} CFX_CTTGSUBTable::TCoverageFormat2::TCoverageFormat2() - : TCoverageFormatBase(2), RangeCount(0) {} + : TCoverageFormatBase(2) {} CFX_CTTGSUBTable::TCoverageFormat2::~TCoverageFormat2() {} @@ -462,41 +393,34 @@ CFX_CTTGSUBTable::TSingleSubstFormat1::TSingleSubstFormat1() CFX_CTTGSUBTable::TSingleSubstFormat1::~TSingleSubstFormat1() {} CFX_CTTGSUBTable::TSingleSubstFormat2::TSingleSubstFormat2() - : TSubTableBase(2), GlyphCount(0) {} + : TSubTableBase(2) {} CFX_CTTGSUBTable::TSingleSubstFormat2::~TSingleSubstFormat2() {} -CFX_CTTGSUBTable::TLookup::TLookup() - : LookupType(0), LookupFlag(0), SubTableCount(0) {} +CFX_CTTGSUBTable::TLookup::TLookup() : LookupType(0), LookupFlag(0) {} -CFX_CTTGSUBTable::TLookup::~TLookup() { - if (SubTable) { - for (int i = 0; i < SubTableCount; ++i) - delete SubTable[i]; - } -} +CFX_CTTGSUBTable::TLookup::~TLookup() {} -CFX_CTTGSUBTable::TScript::TScript() : DefaultLangSys(0), LangSysCount(0) {} +CFX_CTTGSUBTable::TScript::TScript() : DefaultLangSys(0) {} CFX_CTTGSUBTable::TScript::~TScript() {} -CFX_CTTGSUBTable::TScriptList::TScriptList() : ScriptCount(0) {} +CFX_CTTGSUBTable::TScriptList::TScriptList() {} CFX_CTTGSUBTable::TScriptList::~TScriptList() {} -CFX_CTTGSUBTable::TFeature::TFeature() : FeatureParams(0), LookupCount(0) {} +CFX_CTTGSUBTable::TFeature::TFeature() : FeatureParams(0) {} CFX_CTTGSUBTable::TFeature::~TFeature() {} -CFX_CTTGSUBTable::TFeatureList::TFeatureList() : FeatureCount(0) {} +CFX_CTTGSUBTable::TFeatureList::TFeatureList() {} CFX_CTTGSUBTable::TFeatureList::~TFeatureList() {} -CFX_CTTGSUBTable::TLookupList::TLookupList() : LookupCount(0) {} +CFX_CTTGSUBTable::TLookupList::TLookupList() {} CFX_CTTGSUBTable::TLookupList::~TLookupList() {} -CFX_CTTGSUBTable::TLangSys::TLangSys() - : LookupOrder(0), ReqFeatureIndex(0), FeatureCount(0) {} +CFX_CTTGSUBTable::TLangSys::TLangSys() : LookupOrder(0), ReqFeatureIndex(0) {} CFX_CTTGSUBTable::TLangSys::~TLangSys() {} diff --git a/core/fpdfapi/font/ttgsubtable.h b/core/fpdfapi/font/ttgsubtable.h index e0e4bbbd0..f92726954 100644 --- a/core/fpdfapi/font/ttgsubtable.h +++ b/core/fpdfapi/font/ttgsubtable.h @@ -9,8 +9,9 @@ #include <stdint.h> -#include <map> #include <memory> +#include <set> +#include <vector> #include "core/fxcrt/fx_basic.h" #include "core/fxge/fx_font.h" @@ -45,19 +46,20 @@ class CFX_CTTGSUBTable { uint16_t FeatureList; uint16_t LookupList; }; + struct TLangSys { TLangSys(); ~TLangSys(); uint16_t LookupOrder; uint16_t ReqFeatureIndex; - uint16_t FeatureCount; - std::unique_ptr<uint16_t[]> FeatureIndex; + std::vector<uint16_t> FeatureIndices; private: - TLangSys(const TLangSys&); - TLangSys& operator=(const TLangSys&); + TLangSys(const TLangSys&) = delete; + TLangSys& operator=(const TLangSys&) = delete; }; + struct TLangSysRecord { TLangSysRecord() : LangSysTag(0) {} @@ -65,21 +67,22 @@ class CFX_CTTGSUBTable { TLangSys LangSys; private: - TLangSysRecord(const TLangSysRecord&); - TLangSysRecord& operator=(const TLangSysRecord&); + TLangSysRecord(const TLangSysRecord&) = delete; + TLangSysRecord& operator=(const TLangSysRecord&) = delete; }; + struct TScript { TScript(); ~TScript(); uint16_t DefaultLangSys; - uint16_t LangSysCount; - std::unique_ptr<TLangSysRecord[]> LangSysRecord; + std::vector<TLangSysRecord> LangSysRecords; private: - TScript(const TScript&); - TScript& operator=(const TScript&); + TScript(const TScript&) = delete; + TScript& operator=(const TScript&) = delete; }; + struct TScriptRecord { TScriptRecord() : ScriptTag(0) {} @@ -87,32 +90,33 @@ class CFX_CTTGSUBTable { TScript Script; private: - TScriptRecord(const TScriptRecord&); - TScriptRecord& operator=(const TScriptRecord&); + TScriptRecord(const TScriptRecord&) = delete; + TScriptRecord& operator=(const TScriptRecord&) = delete; }; + struct TScriptList { TScriptList(); ~TScriptList(); - uint16_t ScriptCount; - std::unique_ptr<TScriptRecord[]> ScriptRecord; + std::vector<TScriptRecord> ScriptRecords; private: - TScriptList(const TScriptList&); - TScriptList& operator=(const TScriptList&); + TScriptList(const TScriptList&) = delete; + TScriptList& operator=(const TScriptList&) = delete; }; + struct TFeature { TFeature(); ~TFeature(); uint16_t FeatureParams; - int LookupCount; - std::unique_ptr<uint16_t[]> LookupListIndex; + std::vector<uint16_t> LookupListIndices; private: - TFeature(const TFeature&); - TFeature& operator=(const TFeature&); + TFeature(const TFeature&) = delete; + TFeature& operator=(const TFeature&) = delete; }; + struct TFeatureRecord { TFeatureRecord() : FeatureTag(0) {} @@ -120,20 +124,21 @@ class CFX_CTTGSUBTable { TFeature Feature; private: - TFeatureRecord(const TFeatureRecord&); - TFeatureRecord& operator=(const TFeatureRecord&); + TFeatureRecord(const TFeatureRecord&) = delete; + TFeatureRecord& operator=(const TFeatureRecord&) = delete; }; + struct TFeatureList { TFeatureList(); ~TFeatureList(); - int FeatureCount; - std::unique_ptr<TFeatureRecord[]> FeatureRecord; + std::vector<TFeatureRecord> FeatureRecords; private: - TFeatureList(const TFeatureList&); - TFeatureList& operator=(const TFeatureList&); + TFeatureList(const TFeatureList&) = delete; + TFeatureList& operator=(const TFeatureList&) = delete; }; + enum TLookupFlag { LOOKUPFLAG_RightToLeft = 0x0001, LOOKUPFLAG_IgnoreBaseGlyphs = 0x0002, @@ -142,6 +147,7 @@ class CFX_CTTGSUBTable { LOOKUPFLAG_Reserved = 0x00F0, LOOKUPFLAG_MarkAttachmentType = 0xFF00, }; + struct TCoverageFormatBase { TCoverageFormatBase() : CoverageFormat(0) {} explicit TCoverageFormatBase(uint16_t format) : CoverageFormat(format) {} @@ -154,17 +160,18 @@ class CFX_CTTGSUBTable { TCoverageFormatBase(const TCoverageFormatBase&); TCoverageFormatBase& operator=(const TCoverageFormatBase&); }; + struct TCoverageFormat1 : public TCoverageFormatBase { TCoverageFormat1(); ~TCoverageFormat1() override; - uint16_t GlyphCount; - std::unique_ptr<uint16_t[]> GlyphArray; + std::vector<uint16_t> GlyphArray; private: - TCoverageFormat1(const TCoverageFormat1&); - TCoverageFormat1& operator=(const TCoverageFormat1&); + TCoverageFormat1(const TCoverageFormat1&) = delete; + TCoverageFormat1& operator=(const TCoverageFormat1&) = delete; }; + struct TRangeRecord { TRangeRecord(); @@ -177,19 +184,20 @@ class CFX_CTTGSUBTable { uint16_t StartCoverageIndex; private: - TRangeRecord(const TRangeRecord&); + TRangeRecord(const TRangeRecord&) = delete; }; + struct TCoverageFormat2 : public TCoverageFormatBase { TCoverageFormat2(); ~TCoverageFormat2() override; - uint16_t RangeCount; - std::unique_ptr<TRangeRecord[]> RangeRecord; + std::vector<TRangeRecord> RangeRecords; private: - TCoverageFormat2(const TCoverageFormat2&); - TCoverageFormat2& operator=(const TCoverageFormat2&); + TCoverageFormat2(const TCoverageFormat2&) = delete; + TCoverageFormat2& operator=(const TCoverageFormat2&) = delete; }; + struct TDevice { TDevice() : StartSize(0), EndSize(0), DeltaFormat(0) {} @@ -198,9 +206,10 @@ class CFX_CTTGSUBTable { uint16_t DeltaFormat; private: - TDevice(const TDevice&); - TDevice& operator=(const TDevice&); + TDevice(const TDevice&) = delete; + TDevice& operator=(const TDevice&) = delete; }; + struct TSubTableBase { TSubTableBase() : SubstFormat(0) {} explicit TSubTableBase(uint16_t format) : SubstFormat(format) {} @@ -209,9 +218,10 @@ class CFX_CTTGSUBTable { uint16_t SubstFormat; private: - TSubTableBase(const TSubTableBase&); - TSubTableBase& operator=(const TSubTableBase&); + TSubTableBase(const TSubTableBase&) = delete; + TSubTableBase& operator=(const TSubTableBase&) = delete; }; + struct TSingleSubstFormat1 : public TSubTableBase { TSingleSubstFormat1(); ~TSingleSubstFormat1() override; @@ -220,44 +230,44 @@ class CFX_CTTGSUBTable { int16_t DeltaGlyphID; private: - TSingleSubstFormat1(const TSingleSubstFormat1&); - TSingleSubstFormat1& operator=(const TSingleSubstFormat1&); + TSingleSubstFormat1(const TSingleSubstFormat1&) = delete; + TSingleSubstFormat1& operator=(const TSingleSubstFormat1&) = delete; }; + struct TSingleSubstFormat2 : public TSubTableBase { TSingleSubstFormat2(); ~TSingleSubstFormat2() override; std::unique_ptr<TCoverageFormatBase> Coverage; - uint16_t GlyphCount; - std::unique_ptr<uint16_t[]> Substitute; + std::vector<uint16_t> Substitutes; private: - TSingleSubstFormat2(const TSingleSubstFormat2&); - TSingleSubstFormat2& operator=(const TSingleSubstFormat2&); + TSingleSubstFormat2(const TSingleSubstFormat2&) = delete; + TSingleSubstFormat2& operator=(const TSingleSubstFormat2&) = delete; }; + struct TLookup { TLookup(); ~TLookup(); uint16_t LookupType; uint16_t LookupFlag; - uint16_t SubTableCount; - std::unique_ptr<TSubTableBase* []> SubTable; + std::vector<std::unique_ptr<TSubTableBase>> SubTables; private: - TLookup(const TLookup&); - TLookup& operator=(const TLookup&); + TLookup(const TLookup&) = delete; + TLookup& operator=(const TLookup&) = delete; }; + struct TLookupList { TLookupList(); ~TLookupList(); - int LookupCount; - std::unique_ptr<TLookup[]> Lookup; + std::vector<TLookup> Lookups; private: - TLookupList(const TLookupList&); - TLookupList& operator=(const TLookupList&); + TLookupList(const TLookupList&) = delete; + TLookupList& operator=(const TLookupList&) = delete; }; bool Parse(FT_Bytes scriptlist, FT_Bytes featurelist, FT_Bytes lookuplist); @@ -271,16 +281,16 @@ class CFX_CTTGSUBTable { TCoverageFormatBase* ParseCoverage(FT_Bytes raw); void ParseCoverageFormat1(FT_Bytes raw, TCoverageFormat1* rec); void ParseCoverageFormat2(FT_Bytes raw, TCoverageFormat2* rec); - void ParseSingleSubst(FT_Bytes raw, TSubTableBase** rec); + void ParseSingleSubst(FT_Bytes raw, std::unique_ptr<TSubTableBase>* rec); void ParseSingleSubstFormat1(FT_Bytes raw, TSingleSubstFormat1* rec); void ParseSingleSubstFormat2(FT_Bytes raw, TSingleSubstFormat2* rec); bool GetVerticalGlyphSub(uint32_t glyphnum, uint32_t* vglyphnum, - TFeature* Feature) const; + TFeature* Feature); bool GetVerticalGlyphSub2(uint32_t glyphnum, uint32_t* vglyphnum, - TLookup* Lookup) const; + TLookup* Lookup); int GetCoverageIndex(TCoverageFormatBase* Coverage, uint32_t g) const; uint8_t GetUInt8(FT_Bytes& p) const; @@ -289,7 +299,7 @@ class CFX_CTTGSUBTable { int32_t GetInt32(FT_Bytes& p) const; uint32_t GetUInt32(FT_Bytes& p) const; - std::map<uint32_t, uint32_t> m_featureMap; + std::set<uint32_t> m_featureSet; bool m_bFeautureMapLoad; bool loaded; tt_gsub_header header; diff --git a/core/fpdfapi/page/cpdf_allstates.cpp b/core/fpdfapi/page/cpdf_allstates.cpp index 94bc7b466..282a47fe2 100644 --- a/core/fpdfapi/page/cpdf_allstates.cpp +++ b/core/fpdfapi/page/cpdf_allstates.cpp @@ -23,12 +23,8 @@ FX_FLOAT ClipFloat(FX_FLOAT 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() + : m_TextLeading(0), m_TextRise(0), m_TextHorzScale(1.0f) {} CPDF_AllStates::~CPDF_AllStates() {} @@ -37,10 +33,8 @@ void CPDF_AllStates::Copy(const CPDF_AllStates& 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_TextPos = src.m_TextPos; + m_TextLinePos = src.m_TextLinePos; m_TextLeading = src.m_TextLeading; m_TextRise = src.m_TextRise; m_TextHorzScale = src.m_TextHorzScale; diff --git a/core/fpdfapi/page/cpdf_allstates.h b/core/fpdfapi/page/cpdf_allstates.h index 1aa680a2c..dad1b8502 100644 --- a/core/fpdfapi/page/cpdf_allstates.h +++ b/core/fpdfapi/page/cpdf_allstates.h @@ -27,10 +27,8 @@ class CPDF_AllStates : public CPDF_GraphicStates { 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; + CFX_PointF m_TextPos; + CFX_PointF m_TextLinePos; FX_FLOAT m_TextLeading; FX_FLOAT m_TextRise; FX_FLOAT m_TextHorzScale; diff --git a/core/fpdfapi/page/cpdf_clippath.cpp b/core/fpdfapi/page/cpdf_clippath.cpp index cfcd9a1e6..714b56bff 100644 --- a/core/fpdfapi/page/cpdf_clippath.cpp +++ b/core/fpdfapi/page/cpdf_clippath.cpp @@ -84,8 +84,9 @@ void CPDF_ClipPath::AppendPath(CPDF_Path path, uint8_t type, bool bAutoMerge) { 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_PointF point0 = old_path.GetPoint(0); + CFX_PointF point2 = old_path.GetPoint(2); + CFX_FloatRect old_rect(point0.x, point0.y, point2.x, point2.y); CFX_FloatRect new_rect = path.GetBoundingBox(); if (old_rect.Contains(new_rect)) pData->m_PathAndTypeList.pop_back(); diff --git a/core/fpdfapi/page/cpdf_contentparser.cpp b/core/fpdfapi/page/cpdf_contentparser.cpp index 1e0fe62e0..7ceb50934 100644 --- a/core/fpdfapi/page/cpdf_contentparser.cpp +++ b/core/fpdfapi/page/cpdf_contentparser.cpp @@ -90,10 +90,12 @@ void CPDF_ContentParser::Start(CPDF_Form* pForm, ClipPath.Transform(&form_matrix); if (pParentMatrix) ClipPath.Transform(pParentMatrix); - form_bbox.Transform(&form_matrix); + + form_matrix.TransformRect(form_bbox); if (pParentMatrix) - form_bbox.Transform(pParentMatrix); + pParentMatrix->TransformRect(form_bbox); } + CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDictFor("Resources"); m_pParser = pdfium::MakeUnique<CPDF_StreamContentParser>( pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, @@ -201,8 +203,10 @@ void CPDF_ContentParser::Continue(IFX_Pause* pPause) { 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_PointF point0 = ClipPath.GetPoint(0); + CFX_PointF point2 = ClipPath.GetPoint(2); + CFX_FloatRect old_rect(point0.x, point0.y, point2.x, point2.y); CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, pObj->m_Top); if (old_rect.Contains(obj_rect)) diff --git a/core/fpdfapi/page/cpdf_formobject.cpp b/core/fpdfapi/page/cpdf_formobject.cpp index dc596e53c..5642a5dd0 100644 --- a/core/fpdfapi/page/cpdf_formobject.cpp +++ b/core/fpdfapi/page/cpdf_formobject.cpp @@ -35,7 +35,7 @@ CPDF_PageObject::Type CPDF_FormObject::GetType() const { void CPDF_FormObject::CalcBoundingBox() { CFX_FloatRect form_rect = m_pForm->CalcBoundingBox(); - form_rect.Transform(&m_FormMatrix); + m_FormMatrix.TransformRect(form_rect); m_Left = form_rect.left; m_Bottom = form_rect.bottom; m_Right = form_rect.right; diff --git a/core/fpdfapi/page/cpdf_imageobject.cpp b/core/fpdfapi/page/cpdf_imageobject.cpp index bb9182054..01d2df742 100644 --- a/core/fpdfapi/page/cpdf_imageobject.cpp +++ b/core/fpdfapi/page/cpdf_imageobject.cpp @@ -41,8 +41,10 @@ const CPDF_ImageObject* CPDF_ImageObject::AsImage() const { } void CPDF_ImageObject::CalcBoundingBox() { - m_Left = m_Bottom = 0; - m_Right = m_Top = 1.0f; + m_Left = 0; + m_Bottom = 0; + m_Right = 1.0f; + m_Top = 1.0f; m_Matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); } diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp index 8bc2a851c..24ef9b271 100644 --- a/core/fpdfapi/page/cpdf_meshstream.cpp +++ b/core/fpdfapi/page/cpdf_meshstream.cpp @@ -83,6 +83,12 @@ bool IsValidBitsPerFlag(uint32_t x) { } // namespace +CPDF_MeshVertex::CPDF_MeshVertex() = default; + +CPDF_MeshVertex::CPDF_MeshVertex(const CPDF_MeshVertex&) = default; + +CPDF_MeshVertex::~CPDF_MeshVertex() = default; + CPDF_MeshStream::CPDF_MeshStream( ShadingType type, const std::vector<std::unique_ptr<CPDF_Function>>& funcs, @@ -148,37 +154,59 @@ bool CPDF_MeshStream::Load() { return true; } -uint32_t CPDF_MeshStream::GetFlag() { +bool CPDF_MeshStream::CanReadFlag() const { + return m_BitStream.BitsRemaining() >= m_nFlagBits; +} + +bool CPDF_MeshStream::CanReadCoords() const { + return m_BitStream.BitsRemaining() / 2 >= m_nCoordBits; +} + +bool CPDF_MeshStream::CanReadColor() const { + return m_BitStream.BitsRemaining() / m_nComponentBits >= m_nComponents; +} + +uint32_t CPDF_MeshStream::ReadFlag() { ASSERT(ShouldCheckBitsPerFlag(m_type)); return m_BitStream.GetBits(m_nFlagBits) & 0x03; } -void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) { +CFX_PointF CPDF_MeshStream::ReadCoords() { ASSERT(ShouldCheckBPC(m_type)); + + CFX_PointF pos; 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); + pos.x = m_xmin + + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / + static_cast<double>(m_CoordMax); + pos.y = m_ymin + + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / + static_cast<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; + pos.x = m_xmin + + m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax; + pos.y = m_ymin + + m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax; } + return pos; } -void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { +std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT> CPDF_MeshStream::ReadColor() { 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; } + + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; if (m_funcs.empty()) { m_pCS->GetRGB(color_value, r, g, b); - return; + return std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT>(r, g, b); } FX_FLOAT result[kMaxComponents]; @@ -188,29 +216,41 @@ void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) { if (func && func->CountOutputs() <= kMaxComponents) func->Call(color_value, 1, result, nResults); } + m_pCS->GetRGB(result, r, g, b); + return std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT>(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); +bool CPDF_MeshStream::ReadVertex(const CFX_Matrix& pObject2Bitmap, + CPDF_MeshVertex* vertex, + uint32_t* flag) { + if (!CanReadFlag()) + return false; + *flag = ReadFlag(); + + if (!CanReadCoords()) + return false; + vertex->position = pObject2Bitmap.Transform(ReadCoords()); + + if (!CanReadColor()) + return false; + std::tie(vertex->r, vertex->g, vertex->b) = ReadColor(); m_BitStream.ByteAlign(); - return flag; + return true; } -bool CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex, - int count, - CFX_Matrix* pObject2Bitmap) { +bool CPDF_MeshStream::ReadVertexRow(const CFX_Matrix& pObject2Bitmap, + int count, + CPDF_MeshVertex* vertex) { for (int i = 0; i < count; i++) { - if (m_BitStream.IsEOF()) + if (m_BitStream.IsEOF() || !CanReadCoords()) + return false; + + vertex[i].position = pObject2Bitmap.Transform(ReadCoords()); + if (!CanReadColor()) 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); + std::tie(vertex[i].r, vertex[i].g, vertex[i].b) = ReadColor(); m_BitStream.ByteAlign(); } return true; diff --git a/core/fpdfapi/page/cpdf_meshstream.h b/core/fpdfapi/page/cpdf_meshstream.h index 21a6c2fa8..d40de4a01 100644 --- a/core/fpdfapi/page/cpdf_meshstream.h +++ b/core/fpdfapi/page/cpdf_meshstream.h @@ -8,6 +8,7 @@ #define CORE_FPDFAPI_PAGE_CPDF_MESHSTREAM_H_ #include <memory> +#include <tuple> #include <vector> #include "core/fpdfapi/page/cpdf_shadingpattern.h" @@ -15,9 +16,13 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_system.h" -struct CPDF_MeshVertex { - FX_FLOAT x; - FX_FLOAT y; +class CPDF_MeshVertex { + public: + CPDF_MeshVertex(); + CPDF_MeshVertex(const CPDF_MeshVertex&); + ~CPDF_MeshVertex(); + + CFX_PointF position; FX_FLOAT r; FX_FLOAT g; FX_FLOAT b; @@ -37,14 +42,20 @@ class CPDF_MeshStream { bool Load(); - uint32_t GetFlag(); - void GetCoords(FX_FLOAT& x, FX_FLOAT& y); - void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b); + bool CanReadFlag() const; + bool CanReadCoords() const; + bool CanReadColor() const; + + uint32_t ReadFlag(); + CFX_PointF ReadCoords(); + std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT> ReadColor(); - uint32_t GetVertex(CPDF_MeshVertex& vertex, CFX_Matrix* pObject2Bitmap); - bool GetVertexRow(CPDF_MeshVertex* vertex, - int count, - CFX_Matrix* pObject2Bitmap); + bool ReadVertex(const CFX_Matrix& pObject2Bitmap, + CPDF_MeshVertex* vertex, + uint32_t* flag); + bool ReadVertexRow(const CFX_Matrix& pObject2Bitmap, + int count, + CPDF_MeshVertex* vertex); CFX_BitStream* BitStream() { return &m_BitStream; } uint32_t ComponentBits() const { return m_nComponentBits; } diff --git a/core/fpdfapi/page/cpdf_page.cpp b/core/fpdfapi/page/cpdf_page.cpp index f9c02837a..46123ab42 100644 --- a/core/fpdfapi/page/cpdf_page.cpp +++ b/core/fpdfapi/page/cpdf_page.cpp @@ -66,16 +66,17 @@ CPDF_Page::CPDF_Page(CPDF_Document* pDocument, switch (rotate) { case 0: - m_PageMatrix.Set(1.0f, 0, 0, 1.0f, -m_BBox.left, -m_BBox.bottom); + m_PageMatrix = CFX_Matrix(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); + m_PageMatrix = + CFX_Matrix(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); + m_PageMatrix = CFX_Matrix(-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); + m_PageMatrix = CFX_Matrix(0, 1.0f, -1.0f, 0, m_BBox.top, -m_BBox.left); break; } @@ -119,16 +120,14 @@ CPDF_Object* CPDF_Page::GetPageAttr(const CFX_ByteString& name) const { 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; +CFX_Matrix CPDF_Page::GetDisplayMatrix(int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const { + if (m_PageWidth == 0 || m_PageHeight == 0) + return CFX_Matrix(); + float x0 = 0; float y0 = 0; float x1 = 0; @@ -170,9 +169,19 @@ void CPDF_Page::GetDisplayMatrix(CFX_Matrix& matrix, y2 = yPos; break; } - display_matrix.Set((x2 - x0) / m_PageWidth, (y2 - y0) / m_PageWidth, - (x1 - x0) / m_PageHeight, (y1 - y0) / m_PageHeight, x0, - y0); - matrix = m_PageMatrix; - matrix.Concat(display_matrix); + CFX_Matrix matrix = m_PageMatrix; + matrix.Concat(CFX_Matrix((x2 - x0) / m_PageWidth, (y2 - y0) / m_PageWidth, + (x1 - x0) / m_PageHeight, (y1 - y0) / m_PageHeight, + x0, y0)); + return matrix; +} + +bool GraphicsData::operator<(const GraphicsData& other) const { + if (fillAlpha != other.fillAlpha) + return fillAlpha < other.fillAlpha; + return strokeAlpha < other.strokeAlpha; +} + +bool FontData::operator<(const FontData& other) const { + return baseFont < other.baseFont; } diff --git a/core/fpdfapi/page/cpdf_page.h b/core/fpdfapi/page/cpdf_page.h index 3812d2867..9e303562c 100644 --- a/core/fpdfapi/page/cpdf_page.h +++ b/core/fpdfapi/page/cpdf_page.h @@ -7,6 +7,7 @@ #ifndef CORE_FPDFAPI_PAGE_CPDF_PAGE_H_ #define CORE_FPDFAPI_PAGE_CPDF_PAGE_H_ +#include <map> #include <memory> #include "core/fpdfapi/page/cpdf_pageobjectholder.h" @@ -20,6 +21,19 @@ class CPDF_Object; class CPDF_PageRenderCache; class CPDF_PageRenderContext; +// These structs are used to keep track of resources that have already been +// generated in the page. +struct GraphicsData { + FX_FLOAT fillAlpha; + FX_FLOAT strokeAlpha; + bool operator<(const GraphicsData& other) const; +}; + +struct FontData { + CFX_ByteString baseFont; + bool operator<(const FontData& other) const; +}; + class CPDF_Page : public CPDF_PageObjectHolder { public: class View {}; // Caller implements as desired, empty here due to layering. @@ -31,12 +45,11 @@ class CPDF_Page : public CPDF_PageObjectHolder { void ParseContent(); - void GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const; + CFX_Matrix GetDisplayMatrix(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; } @@ -53,6 +66,9 @@ class CPDF_Page : public CPDF_PageObjectHolder { View* GetView() const { return m_pView; } void SetView(View* pView) { m_pView = pView; } + std::map<GraphicsData, CFX_ByteString> m_GraphicsMap; + std::map<FontData, CFX_ByteString> m_FontsMap; + protected: void StartParse(); diff --git a/core/fpdfapi/page/cpdf_pageobject.h b/core/fpdfapi/page/cpdf_pageobject.h index ffc59f4ee..d2b84a5d4 100644 --- a/core/fpdfapi/page/cpdf_pageobject.h +++ b/core/fpdfapi/page/cpdf_pageobject.h @@ -51,6 +51,10 @@ class CPDF_PageObject : public CPDF_GraphicStates { void TransformClipPath(CFX_Matrix& matrix); void TransformGeneralState(CFX_Matrix& matrix); + + CFX_FloatRect GetRect() const { + return CFX_FloatRect(m_Left, m_Bottom, m_Right, m_Top); + } FX_RECT GetBBox(const CFX_Matrix* pMatrix) const; FX_FLOAT m_Left; diff --git a/core/fpdfapi/page/cpdf_path.cpp b/core/fpdfapi/page/cpdf_path.cpp index 2bfda75f5..ddc6bbd1d 100644 --- a/core/fpdfapi/page/cpdf_path.cpp +++ b/core/fpdfapi/page/cpdf_path.cpp @@ -12,32 +12,16 @@ 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 { +const std::vector<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); +void CPDF_Path::ClosePath() { + m_Ref.GetPrivateCopy()->ClosePath(); } -FX_FLOAT CPDF_Path::GetPointY(int index) const { - return m_Ref.GetObject()->GetPointY(index); +CFX_PointF CPDF_Path::GetPoint(int index) const { + return m_Ref.GetObject()->GetPoint(index); } CFX_FloatRect CPDF_Path::GetBoundingBox() const { @@ -71,3 +55,11 @@ void CPDF_Path::AppendRect(FX_FLOAT left, FX_FLOAT top) { m_Ref.GetPrivateCopy()->AppendRect(left, bottom, right, top); } + +void CPDF_Path::AppendPoint(const CFX_PointF& point, + FXPT_TYPE type, + bool close) { + CFX_PathData data; + data.AppendPoint(point, type, close); + Append(&data, nullptr); +} diff --git a/core/fpdfapi/page/cpdf_path.h b/core/fpdfapi/page/cpdf_path.h index 407905e42..b0c5a68a4 100644 --- a/core/fpdfapi/page/cpdf_path.h +++ b/core/fpdfapi/page/cpdf_path.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_PAGE_CPDF_PATH_H_ #define CORE_FPDFAPI_PAGE_CPDF_PATH_H_ +#include <vector> + #include "core/fxcrt/cfx_shared_copy_on_write.h" #include "core/fxcrt/fx_system.h" #include "core/fxge/cfx_fxgedevice.h" @@ -22,14 +24,10 @@ class 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(); + const std::vector<FX_PATHPOINT>& GetPoints() const; + void ClosePath(); - int GetFlag(int index) const; - FX_FLOAT GetPointX(int index) const; - FX_FLOAT GetPointY(int index) const; + CFX_PointF GetPoint(int index) const; CFX_FloatRect GetBoundingBox() const; CFX_FloatRect GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const; @@ -39,6 +37,7 @@ class CPDF_Path { 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); + void AppendPoint(const CFX_PointF& point, FXPT_TYPE type, bool close); // TODO(tsepez): Remove when all access thru this class. const CFX_PathData* GetObject() const { return m_Ref.GetObject(); } diff --git a/core/fpdfapi/page/cpdf_pathobject.cpp b/core/fpdfapi/page/cpdf_pathobject.cpp index 27c4535fa..b5bb89390 100644 --- a/core/fpdfapi/page/cpdf_pathobject.cpp +++ b/core/fpdfapi/page/cpdf_pathobject.cpp @@ -41,7 +41,8 @@ void CPDF_PathObject::CalcBoundingBox() { } else { rect = m_Path.GetBoundingBox(); } - rect.Transform(&m_Matrix); + m_Matrix.TransformRect(rect); + if (width == 0 && m_bStroke) { rect.left += -0.5f; rect.right += 0.5f; diff --git a/core/fpdfapi/page/cpdf_psengine.h b/core/fpdfapi/page/cpdf_psengine.h index 9bdaa6746..659ca82f6 100644 --- a/core/fpdfapi/page/cpdf_psengine.h +++ b/core/fpdfapi/page/cpdf_psengine.h @@ -88,7 +88,6 @@ class CPDF_PSEngine { 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; } diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index 141442bb2..6211b6a4d 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -98,8 +98,11 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, while (!stream.BitStream()->IsEOF()) { uint32_t flag = 0; - if (type != kLatticeFormGouraudTriangleMeshShading) - flag = stream.GetFlag(); + if (type != kLatticeFormGouraudTriangleMeshShading) { + if (!stream.CanReadFlag()) + break; + flag = stream.ReadFlag(); + } if (!bGouraud && flag) { point_count -= 4; @@ -107,13 +110,13 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, } for (int i = 0; i < point_count; i++) { - FX_FLOAT x; - FX_FLOAT y; - stream.GetCoords(x, y); + if (!stream.CanReadCoords()) + break; + CFX_PointF origin = stream.ReadCoords(); if (bStarted) { - rect.UpdateRect(x, y); + rect.UpdateRect(origin.x, origin.y); } else { - rect.InitRect(x, y); + rect.InitRect(origin.x, origin.y); bStarted = true; } } @@ -127,7 +130,7 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, if (bGouraud) stream.BitStream()->ByteAlign(); } - rect.Transform(&matrix); + matrix.TransformRect(rect); return rect; } @@ -265,6 +268,8 @@ CPDF_StreamContentParser::CPDF_StreamContentParser( m_pPathPoints(nullptr), m_PathPointCount(0), m_PathAllocSize(0), + m_PathStartX(0.0f), + m_PathStartY(0.0f), m_PathCurrentX(0.0f), m_PathCurrentY(0.0f), m_PathClipType(0), @@ -316,18 +321,17 @@ int CPDF_StreamContentParser::GetNextParamPos() { return index; } -void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) { - CFX_ByteStringC bsName(name, len); +void CPDF_StreamContentParser::AddNameParam(const CFX_ByteStringC& bsName) { ContentParam& param = m_ParamBuf[GetNextParamPos()]; - if (len > 32) { + if (bsName.GetLength() > 32) { param.m_Type = ContentParam::OBJECT; param.m_pObject = pdfium::MakeUnique<CPDF_Name>( m_pDocument->GetByteStringPool(), 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; + FXSYS_memcpy(param.m_Name.m_Buffer, bsName.raw_str(), bsName.GetLength()); + param.m_Name.m_Len = bsName.GetLength(); } else { CFX_ByteString str = PDF_NameDecode(bsName); FXSYS_memcpy(param.m_Name.m_Buffer, str.c_str(), str.GetLength()); @@ -336,11 +340,10 @@ void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) { } } -void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len) { +void CPDF_StreamContentParser::AddNumberParam(const CFX_ByteStringC& str) { 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); + param.m_Number.m_bInteger = FX_atonum(str, ¶m.m_Number.m_Integer); } void CPDF_StreamContentParser::AddObjectParam( @@ -570,21 +573,10 @@ CPDF_StreamContentParser::InitializeOpCodes() { }); } -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++; - } - +void CPDF_StreamContentParser::OnOperator(const CFX_ByteStringC& op) { static const OpCodes s_OpCodes = InitializeOpCodes(); - auto it = s_OpCodes.find(opid); + auto it = s_OpCodes.find(op.GetID()); if (it != s_OpCodes.end()) (this->*it->second)(); } @@ -599,7 +591,7 @@ void CPDF_StreamContentParser::Handle_FillStrokePath() { } void CPDF_StreamContentParser::Handle_CloseEOFillStrokePath() { - AddPathPoint(m_PathStartX, m_PathStartY, FXPT_LINETO | FXPT_CLOSEFIGURE); + AddPathPoint(m_PathStartX, m_PathStartY, FXPT_TYPE::LineTo, true); AddPathObject(FXFILL_ALTERNATE, true); } @@ -632,9 +624,7 @@ void CPDF_StreamContentParser::Handle_BeginImage() { 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") { + if (m_pSyntax->GetWord() != "ID") { m_pSyntax->SetPos(savePos); return; } @@ -642,9 +632,8 @@ void CPDF_StreamContentParser::Handle_BeginImage() { if (type != CPDF_StreamParser::Name) { break; } - CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, - m_pSyntax->GetWordSize() - 1); - auto pObj = m_pSyntax->ReadNextObject(false, 0); + CFX_ByteString key(m_pSyntax->GetWord().Mid(1)); + auto pObj = m_pSyntax->ReadNextObject(false, false, 0); if (!key.IsEmpty()) { uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; if (dwObjNum) @@ -677,8 +666,7 @@ void CPDF_StreamContentParser::Handle_BeginImage() { if (type != CPDF_StreamParser::Keyword) { continue; } - if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && - m_pSyntax->GetWordBuf()[1] == 'I') { + if (m_pSyntax->GetWord() == "EI") { break; } } @@ -690,18 +678,16 @@ void CPDF_StreamContentParser::Handle_BeginMarkedContent() { } void CPDF_StreamContentParser::Handle_BeginText() { - m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); + m_pCurStates->m_TextMatrix = CFX_Matrix(); OnChangeTextMatrix(); - m_pCurStates->m_TextX = 0; - m_pCurStates->m_TextY = 0; - m_pCurStates->m_TextLineX = 0; - m_pCurStates->m_TextLineY = 0; + m_pCurStates->m_TextPos = CFX_PointF(); + m_pCurStates->m_TextLinePos = CFX_PointF(); } 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); + AddPathPoint(GetNumber(5), GetNumber(4), FXPT_TYPE::BezierTo, false); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_TYPE::BezierTo, false); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_TYPE::BezierTo, false); } void CPDF_StreamContentParser::Handle_ConcatMatrix() { @@ -904,9 +890,9 @@ void CPDF_StreamContentParser::Handle_ClosePath() { 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; + AddPathPoint(m_PathStartX, m_PathStartY, FXPT_TYPE::LineTo, true); + } else if (m_pPathPoints[m_PathPointCount - 1].m_Type != FXPT_TYPE::MoveTo) { + m_pPathPoints[m_PathPointCount - 1].m_CloseFigure = true; } } @@ -954,14 +940,14 @@ void CPDF_StreamContentParser::Handle_LineTo() { if (m_ParamCount != 2) return; - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_LINETO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_TYPE::LineTo, false); } void CPDF_StreamContentParser::Handle_MoveTo() { if (m_ParamCount != 2) return; - AddPathPoint(GetNumber(1), GetNumber(0), FXPT_MOVETO); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_TYPE::MoveTo, false); ParsePathObject(); } @@ -999,11 +985,11 @@ 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); + AddPathPoint(x, y, FXPT_TYPE::MoveTo, false); + AddPathPoint(x + w, y, FXPT_TYPE::LineTo, false); + AddPathPoint(x + w, y + h, FXPT_TYPE::LineTo, false); + AddPathPoint(x, y + h, FXPT_TYPE::LineTo, false); + AddPathPoint(x, y, FXPT_TYPE::LineTo, true); } void CPDF_StreamContentParser::Handle_SetRGBColor_Fill() { @@ -1153,10 +1139,8 @@ void CPDF_StreamContentParser::Handle_SetCharSpace() { } 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; + m_pCurStates->m_TextLinePos += CFX_PointF(GetNumber(1), GetNumber(0)); + m_pCurStates->m_TextPos = m_pCurStates->m_TextLinePos; } void CPDF_StreamContentParser::Handle_MoveTextPoint_SetLeading() { @@ -1246,16 +1230,6 @@ CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, 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, @@ -1266,12 +1240,12 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, } if (fInitKerning != 0) { if (!pFont->IsVertWriting()) { - m_pCurStates->m_TextX -= + m_pCurStates->m_TextPos.x -= (fInitKerning * m_pCurStates->m_TextState.GetFontSize() * m_pCurStates->m_TextHorzScale) / 1000; } else { - m_pCurStates->m_TextY -= + m_pCurStates->m_TextPos.y -= (fInitKerning * m_pCurStates->m_TextState.GetFontSize()) / 1000; } } @@ -1293,15 +1267,13 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, 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; + pText->m_Pos = m_mtContentToUser.Transform( + m_pCurStates->m_CTM.Transform(m_pCurStates->m_TextMatrix.Transform( + CFX_PointF(m_pCurStates->m_TextPos.x, + m_pCurStates->m_TextPos.y + m_pCurStates->m_TextRise)))); + + m_pCurStates->m_TextPos += + pText->CalcPositionData(m_pCurStates->m_TextHorzScale); if (TextRenderingModeIsClipMode(text_mode)) { m_ClipTextList.push_back( std::unique_ptr<CPDF_TextObject>(pText->Clone())); @@ -1310,12 +1282,12 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, } if (pKerning && pKerning[nsegs - 1] != 0) { if (!pFont->IsVertWriting()) { - m_pCurStates->m_TextX -= + m_pCurStates->m_TextPos.x -= (pKerning[nsegs - 1] * m_pCurStates->m_TextState.GetFontSize() * m_pCurStates->m_TextHorzScale) / 1000; } else { - m_pCurStates->m_TextY -= + m_pCurStates->m_TextPos.y -= (pKerning[nsegs - 1] * m_pCurStates->m_TextState.GetFontSize()) / 1000; } @@ -1343,7 +1315,7 @@ void CPDF_StreamContentParser::Handle_ShowText_Positioning() { } if (nsegs == 0) { for (size_t i = 0; i < n; i++) { - m_pCurStates->m_TextX -= + m_pCurStates->m_TextPos.x -= (pArray->GetNumberAt(i) * m_pCurStates->m_TextState.GetFontSize() * m_pCurStates->m_TextHorzScale) / 1000; @@ -1382,13 +1354,12 @@ void CPDF_StreamContentParser::Handle_SetTextLeading() { } void CPDF_StreamContentParser::Handle_SetTextMatrix() { - m_pCurStates->m_TextMatrix.Set(GetNumber(5), GetNumber(4), GetNumber(3), - GetNumber(2), GetNumber(1), GetNumber(0)); + m_pCurStates->m_TextMatrix = + CFX_Matrix(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; + m_pCurStates->m_TextPos = CFX_PointF(); + m_pCurStates->m_TextLinePos = CFX_PointF(); } void CPDF_StreamContentParser::OnChangeTextMatrix() { @@ -1427,15 +1398,14 @@ void CPDF_StreamContentParser::Handle_SetHorzScale() { } 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; + m_pCurStates->m_TextLinePos.y -= m_pCurStates->m_TextLeading; + m_pCurStates->m_TextPos = m_pCurStates->m_TextLinePos; } 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); + AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_TYPE::BezierTo, false); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_TYPE::BezierTo, false); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_TYPE::BezierTo, false); } void CPDF_StreamContentParser::Handle_SetLineWidth() { @@ -1451,9 +1421,9 @@ void CPDF_StreamContentParser::Handle_EOClip() { } 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); + AddPathPoint(GetNumber(3), GetNumber(2), FXPT_TYPE::BezierTo, false); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_TYPE::BezierTo, false); + AddPathPoint(GetNumber(1), GetNumber(0), FXPT_TYPE::BezierTo, false); } void CPDF_StreamContentParser::Handle_NextLineShowText() { @@ -1469,16 +1439,18 @@ void CPDF_StreamContentParser::Handle_NextLineShowText_Space() { void CPDF_StreamContentParser::Handle_Invalid() {} -void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) { +void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, + FX_FLOAT y, + FXPT_TYPE type, + bool close) { m_PathCurrentX = x; m_PathCurrentY = y; - if (flag == FXPT_MOVETO) { + if (type == FXPT_TYPE::MoveTo && !close) { 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; + m_pPathPoints[m_PathPointCount - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) { + m_pPathPoints[m_PathPointCount - 1].m_Point = CFX_PointF(x, y); return; } } else if (m_PathPointCount == 0) { @@ -1496,9 +1468,9 @@ void CPDF_StreamContentParser::AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag) { 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; + m_pPathPoints[m_PathPointCount - 1].m_Type = type; + m_pPathPoints[m_PathPointCount - 1].m_CloseFigure = close; + m_pPathPoints[m_PathPointCount - 1].m_Point = CFX_PointF(x, y); } void CPDF_StreamContentParser::AddPathObject(int FillType, bool bStroke) { @@ -1515,13 +1487,16 @@ void CPDF_StreamContentParser::AddPathObject(int FillType, bool bStroke) { return; } if (PathPointCount && - m_pPathPoints[PathPointCount - 1].m_Flag == FXPT_MOVETO) { + m_pPathPoints[PathPointCount - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) { PathPointCount--; } + CPDF_Path Path; - Path.SetPointCount(PathPointCount); - FXSYS_memcpy(Path.GetMutablePoints(), m_pPathPoints, - sizeof(FX_PATHPOINT) * PathPointCount); + for (int i = 0; i < PathPointCount; i++) { + FX_PATHPOINT& point = m_pPathPoints[i]; + Path.AppendPoint(point.m_Point, point.m_Type, point.m_CloseFigure); + } + CFX_Matrix matrix = m_pCurStates->m_CTM; matrix.Concat(m_mtContentToUser); if (bStroke || FillType) { @@ -1561,15 +1536,14 @@ uint32_t CPDF_StreamContentParser::Parse(const uint8_t* pData, case CPDF_StreamParser::EndOfData: return m_pSyntax->GetPos(); case CPDF_StreamParser::Keyword: - OnOperator((char*)syntax.GetWordBuf()); + OnOperator(syntax.GetWord()); ClearAllParams(); break; case CPDF_StreamParser::Number: - AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize()); + AddNumberParam(syntax.GetWord()); break; case CPDF_StreamParser::Name: - AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, - syntax.GetWordSize() - 1); + AddNameParam(syntax.GetWord().Mid(1)); break; default: AddObjectParam(syntax.GetObject()); @@ -1589,33 +1563,35 @@ void CPDF_StreamContentParser::ParsePathObject() { case CPDF_StreamParser::EndOfData: return; case CPDF_StreamParser::Keyword: { - int len = m_pSyntax->GetWordSize(); + CFX_ByteStringC strc = m_pSyntax->GetWord(); + int len = strc.GetLength(); if (len == 1) { - switch (m_pSyntax->GetWordBuf()[0]) { + switch (strc[0]) { case kPathOperatorSubpath: - AddPathPoint(params[0], params[1], FXPT_MOVETO); + AddPathPoint(params[0], params[1], FXPT_TYPE::MoveTo, false); nParams = 0; break; case kPathOperatorLine: - AddPathPoint(params[0], params[1], FXPT_LINETO); + AddPathPoint(params[0], params[1], FXPT_TYPE::LineTo, false); 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); + AddPathPoint(params[0], params[1], FXPT_TYPE::BezierTo, false); + AddPathPoint(params[2], params[3], FXPT_TYPE::BezierTo, false); + AddPathPoint(params[4], params[5], FXPT_TYPE::BezierTo, false); 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); + AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_TYPE::BezierTo, + false); + AddPathPoint(params[0], params[1], FXPT_TYPE::BezierTo, false); + AddPathPoint(params[2], params[3], FXPT_TYPE::BezierTo, false); 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); + AddPathPoint(params[0], params[1], FXPT_TYPE::BezierTo, false); + AddPathPoint(params[2], params[3], FXPT_TYPE::BezierTo, false); + AddPathPoint(params[2], params[3], FXPT_TYPE::BezierTo, false); nParams = 0; break; case kPathOperatorClosePath: @@ -1627,8 +1603,8 @@ void CPDF_StreamContentParser::ParsePathObject() { break; } } else if (len == 2) { - if (m_pSyntax->GetWordBuf()[0] == kPathOperatorRectangle[0] && - m_pSyntax->GetWordBuf()[1] == kPathOperatorRectangle[1]) { + if (strc[0] == kPathOperatorRectangle[0] && + strc[1] == kPathOperatorRectangle[1]) { AddPathRect(params[0], params[1], params[2], params[3]); nParams = 0; } else { @@ -1647,9 +1623,7 @@ void CPDF_StreamContentParser::ParsePathObject() { break; int value; - bool bInteger = FX_atonum( - CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), - &value); + bool bInteger = FX_atonum(m_pSyntax->GetWord(), &value); params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value; break; } diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h index 6429b02bb..cd41990b0 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.h +++ b/core/fpdfapi/page/cpdf_streamcontentparser.h @@ -77,26 +77,24 @@ class CPDF_StreamContentParser { std::unordered_map<uint32_t, void (CPDF_StreamContentParser::*)()>; static OpCodes InitializeOpCodes(); - void AddNumberParam(const FX_CHAR* str, int len); + void AddNameParam(const CFX_ByteStringC& str); + void AddNumberParam(const CFX_ByteStringC& str); void AddObjectParam(std::unique_ptr<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 OnOperator(const CFX_ByteStringC& op); 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(); void ParsePathObject(); - void AddPathPoint(FX_FLOAT x, FX_FLOAT y, int flag); + void AddPathPoint(FX_FLOAT x, FX_FLOAT y, FXPT_TYPE type, bool close); void AddPathRect(FX_FLOAT x, FX_FLOAT y, FX_FLOAT w, FX_FLOAT h); void AddPathObject(int FillType, bool bStroke); CPDF_ImageObject* AddImage(std::unique_ptr<CPDF_Stream> pStream); diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp index e26de605b..294d72c95 100644 --- a/core/fpdfapi/page/cpdf_streamparser.cpp +++ b/core/fpdfapi/page/cpdf_streamparser.cpp @@ -29,7 +29,7 @@ namespace { -const uint32_t kMaxNestedArrayLevel = 512; +const uint32_t kMaxNestedParsingLevel = 512; const uint32_t kMaxWordBuffer = 256; const FX_STRSIZE kMaxStringLength = 32767; @@ -209,8 +209,7 @@ std::unique_ptr<CPDF_Stream> CPDF_StreamParser::ReadInlineStream( dwStreamSize += m_Pos - dwPrevPos; continue; } - if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && - GetWordBuf()[1] == 'I') { + if (GetWord() == "EI") { m_Pos = dwPrevPos; break; } @@ -256,7 +255,7 @@ CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { if (PDFCharIsDelimiter(ch) && ch != '/') { m_Pos--; - m_pLastObj = ReadNextObject(false, 0); + m_pLastObj = ReadNextObject(false, false, 0); return Others; } @@ -306,10 +305,12 @@ CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { std::unique_ptr<CPDF_Object> CPDF_StreamParser::ReadNextObject( bool bAllowNestedArray, - uint32_t dwInArrayLevel) { + bool bInArray, + uint32_t dwRecursionLevel) { bool bIsNumber; + // Must get the next word before returning to avoid infinite loops. GetNextWord(bIsNumber); - if (!m_WordSize) + if (!m_WordSize || dwRecursionLevel > kMaxNestedParsingLevel) return nullptr; if (bIsNumber) { @@ -345,7 +346,8 @@ std::unique_ptr<CPDF_Object> CPDF_StreamParser::ReadNextObject( CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); - std::unique_ptr<CPDF_Object> pObj = ReadNextObject(true, 0); + std::unique_ptr<CPDF_Object> pObj = + ReadNextObject(true, bInArray, dwRecursionLevel + 1); if (!pObj) return nullptr; @@ -356,15 +358,13 @@ std::unique_ptr<CPDF_Object> CPDF_StreamParser::ReadNextObject( } if (first_char == '[') { - if ((!bAllowNestedArray && dwInArrayLevel) || - dwInArrayLevel > kMaxNestedArrayLevel) { + if ((!bAllowNestedArray && bInArray)) return nullptr; - } auto pArray = pdfium::MakeUnique<CPDF_Array>(); while (1) { std::unique_ptr<CPDF_Object> pObj = - ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1); + ReadNextObject(bAllowNestedArray, true, dwRecursionLevel + 1); if (pObj) { pArray->Add(std::move(pObj)); continue; diff --git a/core/fpdfapi/page/cpdf_streamparser.h b/core/fpdfapi/page/cpdf_streamparser.h index ce01dd04e..fdc418c63 100644 --- a/core/fpdfapi/page/cpdf_streamparser.h +++ b/core/fpdfapi/page/cpdf_streamparser.h @@ -28,13 +28,15 @@ class CPDF_StreamParser { ~CPDF_StreamParser(); SyntaxType ParseNextElement(); - const uint8_t* GetWordBuf() const { return m_WordBuffer; } - uint32_t GetWordSize() const { return m_WordSize; } + CFX_ByteStringC GetWord() const { + return CFX_ByteStringC(m_WordBuffer, m_WordSize); + } uint32_t GetPos() const { return m_Pos; } void SetPos(uint32_t pos) { m_Pos = pos; } std::unique_ptr<CPDF_Object> GetObject() { return std::move(m_pLastObj); } std::unique_ptr<CPDF_Object> ReadNextObject(bool bAllowNestedArray, - uint32_t dwInArrayLevel); + bool bInArray, + uint32_t dwRecursionLevel); std::unique_ptr<CPDF_Stream> ReadInlineStream( CPDF_Document* pDoc, std::unique_ptr<CPDF_Dictionary> pDict, diff --git a/core/fpdfapi/page/cpdf_textobject.cpp b/core/fpdfapi/page/cpdf_textobject.cpp index 0979fcfb3..da69de8ce 100644 --- a/core/fpdfapi/page/cpdf_textobject.cpp +++ b/core/fpdfapi/page/cpdf_textobject.cpp @@ -6,126 +6,97 @@ #include "core/fpdfapi/page/cpdf_textobject.h" +#include <algorithm> + #include "core/fpdfapi/font/cpdf_cidfont.h" #include "core/fpdfapi/font/cpdf_font.h" #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" -CPDF_TextObject::CPDF_TextObject() - : m_PosX(0), - m_PosY(0), - m_nChars(0), - m_pCharCodes(nullptr), - m_pCharPos(nullptr) {} +CPDF_TextObjectItem::CPDF_TextObjectItem() : m_CharCode(0) {} -CPDF_TextObject::~CPDF_TextObject() { - if (m_nChars > 1) { - FX_Free(m_pCharCodes); - } - FX_Free(m_pCharPos); -} +CPDF_TextObjectItem::~CPDF_TextObjectItem() = default; + +CPDF_TextObject::CPDF_TextObject() {} + +CPDF_TextObject::~CPDF_TextObject() {} int CPDF_TextObject::CountItems() const { - return m_nChars; + return pdfium::CollectionSize<int>(m_CharCodes); } 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) { + pInfo->m_CharCode = m_CharCodes[index]; + pInfo->m_Origin = CFX_PointF(index ? m_CharPos[index - 1] : 0, 0); + if (pInfo->m_CharCode == CPDF_Font::kInvalidCharCode) return; - } + CPDF_Font* pFont = m_TextState.GetFont(); - if (!pFont->IsCIDFont()) { + if (!pFont->IsCIDFont()) return; - } - if (!pFont->AsCIDFont()->IsVertWriting()) { + 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; + pInfo->m_Origin = CFX_PointF(0, pInfo->m_Origin.x); + + short vx; + short 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; + pInfo->m_Origin.x -= fontsize * vx / 1000; + pInfo->m_Origin.y -= 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; - } + for (uint32_t charcode : m_CharCodes) { + if (charcode != 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; - } + uint32_t* charcode, + FX_FLOAT* kerning) const { 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; + for (size_t i = 0; i < m_CharCodes.size(); ++i) { + if (m_CharCodes[i] == CPDF_Font::kInvalidCharCode) + continue; + if (count++ != index) + continue; + *charcode = m_CharCodes[i]; + if (i == m_CharCodes.size() - 1 || + m_CharCodes[i + 1] != CPDF_Font::kInvalidCharCode) { + *kerning = 0; + } else { + *kerning = m_CharPos[i]; } + return; } } 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) { + for (int i = 0; i < pdfium::CollectionSize<int>(m_CharCodes); ++i) { + uint32_t charcode = m_CharCodes[i]; + if (charcode == CPDF_Font::kInvalidCharCode) continue; - } - if (count == index) { - GetItemInfo(i, pInfo); - break; - } - ++count; + if (count++ != index) + continue; + GetItemInfo(i, pInfo); + break; } } std::unique_ptr<CPDF_TextObject> CPDF_TextObject::Clone() const { auto obj = pdfium::MakeUnique<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; + obj->m_CharCodes = m_CharCodes; + obj->m_CharPos = m_CharPos; + obj->m_Pos = m_Pos; return obj; } @@ -134,18 +105,16 @@ CPDF_PageObject::Type CPDF_TextObject::GetType() const { } void CPDF_TextObject::Transform(const CFX_Matrix& matrix) { - CFX_Matrix text_matrix; - GetTextMatrix(&text_matrix); + CFX_Matrix text_matrix = GetTextMatrix(); 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); + pTextMatrix[0] = text_matrix.a; + pTextMatrix[1] = text_matrix.c; + pTextMatrix[2] = text_matrix.b; + pTextMatrix[3] = text_matrix.d; + m_Pos = CFX_PointF(text_matrix.e, text_matrix.f); + CalcPositionData(0); } bool CPDF_TextObject::IsText() const { @@ -160,47 +129,35 @@ const CPDF_TextObject* CPDF_TextObject::AsText() const { return this; } -void CPDF_TextObject::GetTextMatrix(CFX_Matrix* pMatrix) const { +CFX_Matrix CPDF_TextObject::GetTextMatrix() const { const FX_FLOAT* pTextMatrix = m_TextState.GetMatrix(); - pMatrix->Set(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], pTextMatrix[3], - m_PosX, m_PosY); + return CFX_Matrix(pTextMatrix[0], pTextMatrix[2], pTextMatrix[1], + pTextMatrix[3], m_Pos.x, m_Pos.y); } void CPDF_TextObject::SetSegments(const CFX_ByteString* pStrs, - FX_FLOAT* pKerning, + const FX_FLOAT* pKerning, int nsegs) { - if (m_nChars > 1) { - FX_Free(m_pCharCodes); - m_pCharCodes = nullptr; - } - FX_Free(m_pCharPos); - m_pCharPos = nullptr; + m_CharCodes.clear(); + m_CharPos.clear(); CPDF_Font* pFont = m_TextState.GetFont(); - m_nChars = 0; + int nChars = 0; + for (int i = 0; i < nsegs; ++i) + nChars += pFont->CountChar(pStrs[i].c_str(), pStrs[i].GetLength()); + nChars += nsegs - 1; + m_CharCodes.resize(nChars); + m_CharPos.resize(nChars - 1); + int index = 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 { + const FX_CHAR* segment = pStrs[i].c_str(); + int len = pStrs[i].GetLength(); int offset = 0; - m_pCharCodes = (uint32_t*)(uintptr_t)pFont->GetNextChar( - pStrs[0].c_str(), pStrs[0].GetLength(), offset); + while (offset < len) + m_CharCodes[index++] = pFont->GetNextChar(segment, len, offset); + if (i != nsegs - 1) { + m_CharPos[index - 1] = pKerning[i]; + m_CharCodes[index++] = CPDF_Font::kInvalidCharCode; + } } } @@ -214,9 +171,8 @@ FX_FLOAT CPDF_TextObject::GetCharWidth(uint32_t charcode) const { CPDF_Font* pFont = m_TextState.GetFont(); bool bVertWriting = false; CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); - if (pCIDFont) { + if (pCIDFont) bVertWriting = pCIDFont->IsVertWriting(); - } if (!bVertWriting) return pFont->GetCharWidthF(charcode) * fontsize; @@ -224,14 +180,6 @@ FX_FLOAT CPDF_TextObject::GetCharWidth(uint32_t charcode) const { 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(); } @@ -240,9 +188,7 @@ FX_FLOAT CPDF_TextObject::GetFontSize() const { return m_TextState.GetFontSize(); } -void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, - FX_FLOAT* pTextAdvanceY, - FX_FLOAT horz_scale) { +CFX_PointF CPDF_TextObject::CalcPositionData(FX_FLOAT horz_scale) { FX_FLOAT curpos = 0; FX_FLOAT min_x = 10000 * 1.0f; FX_FLOAT max_x = -10000 * 1.0f; @@ -251,49 +197,31 @@ void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, CPDF_Font* pFont = m_TextState.GetFont(); bool bVertWriting = false; CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); - if (pCIDFont) { + 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]; + for (int i = 0; i < pdfium::CollectionSize<int>(m_CharCodes); ++i) { + uint32_t charcode = m_CharCodes[i]; if (i > 0) { if (charcode == CPDF_Font::kInvalidCharCode) { - curpos -= (m_pCharPos[i - 1] * fontsize) / 1000; + curpos -= (m_CharPos[i - 1] * fontsize) / 1000; continue; } - m_pCharPos[i - 1] = curpos; + m_CharPos[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; - } + min_y = std::min(min_y, static_cast<FX_FLOAT>( + std::min(char_rect.top, char_rect.bottom))); + max_y = std::max(max_y, static_cast<FX_FLOAT>( + std::max(char_rect.top, 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; - } + min_x = std::min(min_x, std::min(char_left, char_right)); + max_x = std::max(max_x, std::max(char_left, char_right)); charwidth = pFont->GetCharWidthF(charcode) * fontsize / 1000; } else { uint16_t CID = pCIDFont->CIDFromCharCode(charcode); @@ -304,80 +232,57 @@ void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, 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; - } + min_x = std::min(min_x, static_cast<FX_FLOAT>( + std::min(char_rect.left, char_rect.right))); + max_x = std::max(max_x, static_cast<FX_FLOAT>( + std::max(char_rect.left, 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; - } + min_y = std::min(min_y, std::min(char_top, char_bottom)); + max_y = std::max(max_y, std::max(char_top, char_bottom)); charwidth = pCIDFont->GetVertWidth(CID) * fontsize / 1000; } curpos += charwidth; - if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(32) == 1)) { + if (charcode == ' ' && (!pCIDFont || pCIDFont->GetCharSize(' ') == 1)) curpos += m_TextState.GetWordSpace(); - } + curpos += m_TextState.GetCharSpace(); } + + CFX_PointF ret; if (bVertWriting) { - if (pTextAdvanceX) { - *pTextAdvanceX = 0; - } - if (pTextAdvanceY) { - *pTextAdvanceY = curpos; - } + ret.y = curpos; min_x = min_x * fontsize / 1000; max_x = max_x * fontsize / 1000; } else { - if (pTextAdvanceX) { - *pTextAdvanceX = curpos * horz_scale; - } - if (pTextAdvanceY) { - *pTextAdvanceY = 0; - } + ret.x = curpos * horz_scale; 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; - } + GetTextMatrix().TransformRect(m_Left, m_Right, m_Top, m_Bottom); + + if (!TextRenderingModeIsStrokeMode(m_TextState.GetTextMode())) + return ret; + + FX_FLOAT half_width = m_GraphState.GetLineWidth() / 2; + m_Left -= half_width; + m_Right += half_width; + m_Top += half_width; + m_Bottom -= half_width; + + return ret; } 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; + FX_FLOAT dx = x - m_Pos.x; + FX_FLOAT dy = y - m_Pos.y; + m_Pos.x = x; + m_Pos.y = y; m_Left += dx; m_Right += dx; m_Top += dy; @@ -385,5 +290,5 @@ void CPDF_TextObject::SetPosition(FX_FLOAT x, FX_FLOAT y) { } void CPDF_TextObject::RecalcPositionData() { - CalcPositionData(nullptr, nullptr, 1); + CalcPositionData(1); } diff --git a/core/fpdfapi/page/cpdf_textobject.h b/core/fpdfapi/page/cpdf_textobject.h index b520e3ee9..59da718f6 100644 --- a/core/fpdfapi/page/cpdf_textobject.h +++ b/core/fpdfapi/page/cpdf_textobject.h @@ -8,15 +8,19 @@ #define CORE_FPDFAPI_PAGE_CPDF_TEXTOBJECT_H_ #include <memory> +#include <vector> #include "core/fpdfapi/page/cpdf_pageobject.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" -struct CPDF_TextObjectItem { +class CPDF_TextObjectItem { + public: + CPDF_TextObjectItem(); + ~CPDF_TextObjectItem(); + uint32_t m_CharCode; - FX_FLOAT m_OriginX; - FX_FLOAT m_OriginY; + CFX_PointF m_Origin; }; class CPDF_TextObject : public CPDF_PageObject { @@ -35,12 +39,11 @@ class CPDF_TextObject : public CPDF_PageObject { 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, 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; + CFX_PointF GetPos() const { return m_Pos; } + CFX_Matrix GetTextMatrix() const; CPDF_Font* GetFont() const; FX_FLOAT GetFontSize() const; @@ -49,22 +52,21 @@ class CPDF_TextObject : public CPDF_PageObject { void RecalcPositionData(); - protected: + private: friend class CPDF_RenderStatus; friend class CPDF_StreamContentParser; friend class CPDF_TextRenderer; + friend class CPDF_PageContentGenerator; - void SetSegments(const CFX_ByteString* pStrs, FX_FLOAT* pKerning, int nSegs); + void SetSegments(const CFX_ByteString* pStrs, + const FX_FLOAT* pKerning, + int nSegs); - void CalcPositionData(FX_FLOAT* pTextAdvanceX, - FX_FLOAT* pTextAdvanceY, - FX_FLOAT horz_scale); + CFX_PointF CalcPositionData(FX_FLOAT horz_scale); - FX_FLOAT m_PosX; - FX_FLOAT m_PosY; - int m_nChars; - uint32_t* m_pCharCodes; - FX_FLOAT* m_pCharPos; + CFX_PointF m_Pos; + std::vector<uint32_t> m_CharCodes; + std::vector<FX_FLOAT> m_CharPos; }; #endif // CORE_FPDFAPI_PAGE_CPDF_TEXTOBJECT_H_ diff --git a/core/fpdfapi/page/fpdf_page_func.cpp b/core/fpdfapi/page/fpdf_page_func.cpp index 672bfc02b..916641f05 100644 --- a/core/fpdfapi/page/fpdf_page_func.cpp +++ b/core/fpdfapi/page/fpdf_page_func.cpp @@ -410,12 +410,15 @@ bool CPDF_PSEngine::DoOperator(PDF_PSOP op) { break; case PSOP_BITSHIFT: { int shift = (int)Pop(); - int i = (int)Pop(); + result = (int)Pop(); if (shift > 0) { - Push(i << shift); + result <<= shift; } else { - Push(i >> -shift); + // Avoids unsafe negation of INT_MIN. + FX_SAFE_INT32 safe_shift = shift; + result >>= (-safe_shift).ValueOrDefault(0); } + Push(result.ValueOrDefault(0)); break; } case PSOP_TRUE: @@ -574,10 +577,9 @@ bool CPDF_SampledFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const { if (!pSampleData) return false; - for (uint32_t j = 0; j < m_nOutputs; j++) { + for (uint32_t j = 0; j < m_nOutputs; j++, bitpos += m_nBitsPerSample) { uint32_t sample = - GetBits32(pSampleData, bitpos.ValueOrDie() + j * m_nBitsPerSample, - m_nBitsPerSample); + GetBits32(pSampleData, bitpos.ValueOrDie(), 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) { diff --git a/core/fpdfapi/parser/cpdf_array.cpp b/core/fpdfapi/parser/cpdf_array.cpp index 64010e19e..05a93702f 100644 --- a/core/fpdfapi/parser/cpdf_array.cpp +++ b/core/fpdfapi/parser/cpdf_array.cpp @@ -78,11 +78,10 @@ CFX_FloatRect CPDF_Array::GetRect() { CFX_Matrix CPDF_Array::GetMatrix() { CFX_Matrix matrix; if (!IsArray() || m_Objects.size() != 6) - return matrix; + return CFX_Matrix(); - matrix.Set(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), GetNumberAt(3), - GetNumberAt(4), GetNumberAt(5)); - return matrix; + return CFX_Matrix(GetNumberAt(0), GetNumberAt(1), GetNumberAt(2), + GetNumberAt(3), GetNumberAt(4), GetNumberAt(5)); } CPDF_Object* CPDF_Array::GetObjectAt(size_t i) const { diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 4205ed245..64eaf2a43 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -46,6 +46,7 @@ CPDF_DataAvail::CPDF_DataAvail( } m_dwCurrentOffset = 0; m_dwXRefOffset = 0; + m_dwTrailerOffset = 0; m_bufferOffset = 0; m_bufferSize = 0; m_PagesObjNum = 0; @@ -1123,13 +1124,8 @@ bool CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo, return false; } - if (!pPages) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) { - m_docStatus = PDF_DATAAVAIL_ERROR; - return false; - } + if (!pPages) return false; - } CPDF_Array* pArray = pPages->AsArray(); if (!pArray) { @@ -1160,11 +1156,8 @@ bool CPDF_DataAvail::CheckUnknownPageNode(uint32_t dwPageNo, return false; } - if (!pPage) { - if (m_docStatus == PDF_DATAAVAIL_ERROR) - m_docStatus = PDF_DATAAVAIL_ERROR; + if (!pPage) return false; - } if (pPage->IsArray()) { pPageNode->m_dwPageNo = dwPageNo; diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index e425cfc32..21eb61a99 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -279,19 +279,19 @@ int CalculateFlags(bool bold, bool symbolic) { int flags = 0; if (bold) - flags |= PDFFONT_FORCEBOLD; + flags |= FXFONT_BOLD; if (italic) - flags |= PDFFONT_ITALIC; + flags |= FXFONT_ITALIC; if (fixedPitch) - flags |= PDFFONT_FIXEDPITCH; + flags |= FXFONT_FIXED_PITCH; if (serif) - flags |= PDFFONT_SERIF; + flags |= FXFONT_SERIF; if (script) - flags |= PDFFONT_SCRIPT; + flags |= FXFONT_SCRIPT; if (symbolic) - flags |= PDFFONT_SYMBOLIC; + flags |= FXFONT_SYMBOLIC; else - flags |= PDFFONT_NONSYMBOLIC; + flags |= FXFONT_NONSYMBOLIC; return flags; } diff --git a/core/fpdfapi/parser/cpdf_hint_tables.cpp b/core/fpdfapi/parser/cpdf_hint_tables.cpp index 5c0f2a7fb..e000188e7 100644 --- a/core/fpdfapi/parser/cpdf_hint_tables.cpp +++ b/core/fpdfapi/parser/cpdf_hint_tables.cpp @@ -257,7 +257,7 @@ bool CPDF_HintTables::ReadSharedObjHintTable(CFX_BitStream* hStream, bit_offset *= 8; if (!bit_offset.IsValid() || hStream->GetPos() > bit_offset.ValueOrDie()) return false; - hStream->SkipBits(bit_offset.ValueOrDie() - hStream->GetPos()); + hStream->SkipBits((bit_offset - hStream->GetPos()).ValueOrDie()); const uint32_t kHeaderSize = 192; if (hStream->BitsRemaining() < kHeaderSize) diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp index efb9f8405..3037d0b9b 100644 --- a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp +++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp @@ -11,6 +11,7 @@ #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fpdfapi/parser/cpdf_parser.h" +#include "third_party/base/logging.h" CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder() : m_LastObjNum(0), @@ -55,7 +56,9 @@ CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject( CHECK(!pObj->m_ObjNum); CPDF_Object* pUnowned = pObj.get(); pObj->m_ObjNum = ++m_LastObjNum; - m_IndirectObjs[m_LastObjNum].release(); // TODO(tsepez): stop this leak. + if (m_IndirectObjs[m_LastObjNum]) + m_OrphanObjs.push_back(std::move(m_IndirectObjs[m_LastObjNum])); + m_IndirectObjs[m_LastObjNum] = std::move(pObj); return pUnowned; } diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/core/fpdfapi/parser/cpdf_indirect_object_holder.h index 1b174d8b6..b6d33a3cd 100644 --- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h +++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h @@ -11,6 +11,7 @@ #include <memory> #include <type_traits> #include <utility> +#include <vector> #include "core/fpdfapi/parser/cpdf_object.h" #include "core/fxcrt/cfx_string_pool_template.h" @@ -70,6 +71,7 @@ class CPDF_IndirectObjectHolder { private: uint32_t m_LastObjNum; std::map<uint32_t, std::unique_ptr<CPDF_Object>> m_IndirectObjs; + std::vector<std::unique_ptr<CPDF_Object>> m_OrphanObjs; CFX_WeakPtr<CFX_ByteStringPool> m_pByteStringPool; }; diff --git a/core/fpdfapi/parser/cpdf_object_unittest.cpp b/core/fpdfapi/parser/cpdf_object_unittest.cpp index 4977c9931..927b10647 100644 --- a/core/fpdfapi/parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/parser/cpdf_object_unittest.cpp @@ -397,12 +397,12 @@ TEST(PDFArrayTest, GetMatrix) { for (size_t j = 0; j < 6; ++j) arr->AddNew<CPDF_Number>(elems[i][j]); CFX_Matrix arr_matrix = arr->GetMatrix(); - EXPECT_EQ(matrix.GetA(), arr_matrix.GetA()); - EXPECT_EQ(matrix.GetB(), arr_matrix.GetB()); - EXPECT_EQ(matrix.GetC(), arr_matrix.GetC()); - EXPECT_EQ(matrix.GetD(), arr_matrix.GetD()); - EXPECT_EQ(matrix.GetE(), arr_matrix.GetE()); - EXPECT_EQ(matrix.GetF(), arr_matrix.GetF()); + EXPECT_EQ(matrix.a, arr_matrix.a); + EXPECT_EQ(matrix.b, arr_matrix.b); + EXPECT_EQ(matrix.c, arr_matrix.c); + EXPECT_EQ(matrix.d, arr_matrix.d); + EXPECT_EQ(matrix.e, arr_matrix.e); + EXPECT_EQ(matrix.f, arr_matrix.f); } } diff --git a/core/fpdfapi/parser/cpdf_stream.cpp b/core/fpdfapi/parser/cpdf_stream.cpp index e186bc19d..d62b45641 100644 --- a/core/fpdfapi/parser/cpdf_stream.cpp +++ b/core/fpdfapi/parser/cpdf_stream.cpp @@ -113,7 +113,7 @@ void CPDF_Stream::SetData(const uint8_t* pData, uint32_t size) { bool CPDF_Stream::ReadRawData(FX_FILESIZE offset, uint8_t* buf, uint32_t size) const { - if (m_bMemoryBased && m_pFile) + if (!m_bMemoryBased && m_pFile) return m_pFile->ReadBlock(buf, offset, size); if (m_pDataBuf) diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp index 884b5c50d..480e2c111 100644 --- a/core/fpdfapi/parser/fpdf_parser_decode.cpp +++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp @@ -500,7 +500,7 @@ CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len) { dest_buf2[1] = 0xff; dest_buf2 += 2; for (int j = 0; j < len; j++) { - *dest_buf2++ = pString[i] >> 8; + *dest_buf2++ = pString[j] >> 8; *dest_buf2++ = (uint8_t)pString[j]; } result.ReleaseBuffer(encLen); diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp index 83860f914..30d30a433 100644 --- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp +++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp @@ -76,3 +76,36 @@ TEST(fpdf_parser_decode, HexDecode) { FX_Free(result); } } + +TEST(fpdf_parser_decode, EncodeText) { + struct EncodeTestData { + const FX_WCHAR* input; + const FX_CHAR* expected_output; + FX_STRSIZE expected_length; + } test_data[] = { + // Empty src string. + {L"", "", 0}, + // ASCII text. + {L"the quick\tfox", "the quick\tfox", 13}, + // Unicode text. + {L"\x0330\x0331", "\xFE\xFF\x03\x30\x03\x31", 6}, + // More Unicode text. + {L"\x7F51\x9875\x0020\x56FE\x7247\x0020" + L"\x8D44\x8BAF\x66F4\x591A\x0020\x00BB", + "\xFE\xFF\x7F\x51\x98\x75\x00\x20\x56\xFE\x72\x47\x00" + "\x20\x8D\x44\x8B\xAF\x66\xF4\x59\x1A\x00\x20\x00\xBB", + 26}, + }; + + for (size_t i = 0; i < FX_ArraySize(test_data); ++i) { + const auto& test_case = test_data[i]; + CFX_ByteString output = PDF_EncodeText(test_case.input); + ASSERT_EQ(test_case.expected_length, output.GetLength()) << "for case " + << i; + const FX_CHAR* str_ptr = output.c_str(); + for (FX_STRSIZE j = 0; j < test_case.expected_length; ++j) { + EXPECT_EQ(test_case.expected_output[j], str_ptr[j]) << "for case " << i + << " char " << j; + } + } +} diff --git a/core/fpdfapi/render/cpdf_charposlist.cpp b/core/fpdfapi/render/cpdf_charposlist.cpp index 4857b9349..639bdcf17 100644 --- a/core/fpdfapi/render/cpdf_charposlist.cpp +++ b/core/fpdfapi/render/cpdf_charposlist.cpp @@ -8,35 +8,36 @@ #include "core/fpdfapi/font/cpdf_cidfont.h" #include "core/fpdfapi/font/cpdf_font.h" +#include "third_party/base/stl_util.h" CPDF_CharPosList::CPDF_CharPosList() { m_pCharPos = nullptr; + m_nChars = 0; } CPDF_CharPosList::~CPDF_CharPosList() { FX_Free(m_pCharPos); } -void CPDF_CharPosList::Load(int nChars, - uint32_t* pCharCodes, - FX_FLOAT* pCharPos, +void CPDF_CharPosList::Load(const std::vector<uint32_t>& charCodes, + const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT FontSize) { + int nChars = pdfium::CollectionSize<int>(charCodes); m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); m_nChars = 0; CPDF_CIDFont* pCIDFont = pFont->AsCIDFont(); bool bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); for (int iChar = 0; iChar < nChars; iChar++) { - uint32_t CharCode = - nChars == 1 ? (uint32_t)(uintptr_t)pCharCodes : pCharCodes[iChar]; - if (CharCode == (uint32_t)-1) { + uint32_t CharCode = charCodes[iChar]; + if (CharCode == static_cast<uint32_t>(-1)) continue; - } + bool bVert = false; FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; - if (pCIDFont) { + if (pCIDFont) charpos.m_bFontStyle = true; - } + charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); if (charpos.m_GlyphIndex != static_cast<uint32_t>(-1)) { charpos.m_FallbackFontPosition = -1; @@ -46,39 +47,41 @@ void CPDF_CharPosList::Load(int nChars, charpos.m_GlyphIndex = pFont->FallbackGlyphFromCharcode( charpos.m_FallbackFontPosition, CharCode); } + // TODO(npm): Figure out how this affects m_ExtGID #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); #endif - if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) { + if (!pFont->IsEmbedded() && !pFont->IsCIDFont()) charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); - } else { + else charpos.m_FontCharWidth = 0; - } - charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; - charpos.m_OriginY = 0; + + charpos.m_Origin = CFX_PointF(iChar ? charPos[iChar - 1] : 0, 0); charpos.m_bGlyphAdjust = false; - if (!pCIDFont) { + if (!pCIDFont) continue; - } + uint16_t CID = pCIDFont->CIDFromCharCode(CharCode); if (bVertWriting) { - charpos.m_OriginY = charpos.m_OriginX; - charpos.m_OriginX = 0; - short vx, vy; + charpos.m_Origin = CFX_PointF(0, charpos.m_Origin.x); + + short vx; + short vy; pCIDFont->GetVertOrigin(CID, vx, vy); - charpos.m_OriginX -= FontSize * vx / 1000; - charpos.m_OriginY -= FontSize * vy / 1000; + charpos.m_Origin.x -= FontSize * vx / 1000; + charpos.m_Origin.y -= FontSize * vy / 1000; } + const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); if (pTransform && !bVert) { charpos.m_AdjustMatrix[0] = pCIDFont->CIDTransformToFloat(pTransform[0]); charpos.m_AdjustMatrix[2] = pCIDFont->CIDTransformToFloat(pTransform[2]); charpos.m_AdjustMatrix[1] = pCIDFont->CIDTransformToFloat(pTransform[1]); charpos.m_AdjustMatrix[3] = pCIDFont->CIDTransformToFloat(pTransform[3]); - charpos.m_OriginX += + charpos.m_Origin.x += pCIDFont->CIDTransformToFloat(pTransform[4]) * FontSize; - charpos.m_OriginY += + charpos.m_Origin.y += pCIDFont->CIDTransformToFloat(pTransform[5]) * FontSize; charpos.m_bGlyphAdjust = true; } diff --git a/core/fpdfapi/render/cpdf_charposlist.h b/core/fpdfapi/render/cpdf_charposlist.h index 9fa3c2cf5..2f5a44dfa 100644 --- a/core/fpdfapi/render/cpdf_charposlist.h +++ b/core/fpdfapi/render/cpdf_charposlist.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_RENDER_CPDF_CHARPOSLIST_H_ #define CORE_FPDFAPI_RENDER_CPDF_CHARPOSLIST_H_ +#include <vector> + #include "core/fxcrt/fx_system.h" #include "core/fxge/cfx_renderdevice.h" @@ -16,9 +18,8 @@ class CPDF_CharPosList { public: CPDF_CharPosList(); ~CPDF_CharPosList(); - void Load(int nChars, - uint32_t* pCharCodes, - FX_FLOAT* pCharPos, + void Load(const std::vector<uint32_t>& charCodes, + const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT font_size); FXTEXT_CHARPOS* m_pCharPos; diff --git a/core/fpdfapi/render/cpdf_devicebuffer.cpp b/core/fpdfapi/render/cpdf_devicebuffer.cpp index edc91802f..dec13433e 100644 --- a/core/fpdfapi/render/cpdf_devicebuffer.cpp +++ b/core/fpdfapi/render/cpdf_devicebuffer.cpp @@ -28,7 +28,7 @@ bool CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, m_pContext = pContext; m_Rect = *pRect; m_pObject = pObj; - m_Matrix.TranslateI(-pRect->left, -pRect->top); + m_Matrix.Translate(-pRect->left, -pRect->top); #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE); int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE); @@ -44,11 +44,11 @@ bool CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, } #endif CFX_Matrix ctm = m_pDevice->GetCTM(); - FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); - FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); - m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); + m_Matrix.Concat(CFX_Matrix(FXSYS_fabs(ctm.a), 0, 0, FXSYS_fabs(ctm.d), 0, 0)); + CFX_FloatRect rect(*pRect); m_Matrix.TransformRect(rect); + FX_RECT bitmap_rect = rect.GetOuterRect(); m_pBitmap = pdfium::MakeUnique<CFX_DIBitmap>(); m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb); diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp index ad713d0a5..358d13edd 100644 --- a/core/fpdfapi/render/cpdf_imagerenderer.cpp +++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp @@ -239,7 +239,7 @@ FX_RECT CPDF_ImageRenderer::GetDrawRect() const { CFX_Matrix CPDF_ImageRenderer::GetDrawMatrix(const FX_RECT& rect) const { CFX_Matrix new_matrix = m_ImageMatrix; - new_matrix.TranslateI(-rect.left, -rect.top); + new_matrix.Translate(-rect.left, -rect.top); return new_matrix; } diff --git a/core/fpdfapi/render/cpdf_renderoptions.cpp b/core/fpdfapi/render/cpdf_renderoptions.cpp index ea11d7f5e..717e036fe 100644 --- a/core/fpdfapi/render/cpdf_renderoptions.cpp +++ b/core/fpdfapi/render/cpdf_renderoptions.cpp @@ -11,7 +11,6 @@ CPDF_RenderOptions::CPDF_RenderOptions() m_Flags(RENDER_CLEARTYPE), m_Interpolation(0), m_AddFlags(0), - m_pOCContext(nullptr), m_dwLimitCacheSize(1024 * 1024 * 100), m_HalftoneLimit(-1), m_bDrawAnnots(false) {} @@ -23,10 +22,12 @@ CPDF_RenderOptions::CPDF_RenderOptions(const CPDF_RenderOptions& rhs) m_Flags(rhs.m_Flags), m_Interpolation(rhs.m_Interpolation), m_AddFlags(rhs.m_AddFlags), - m_pOCContext(rhs.m_pOCContext), m_dwLimitCacheSize(rhs.m_dwLimitCacheSize), m_HalftoneLimit(rhs.m_HalftoneLimit), - m_bDrawAnnots(rhs.m_bDrawAnnots) {} + m_bDrawAnnots(rhs.m_bDrawAnnots), + m_pOCContext(rhs.m_pOCContext) {} + +CPDF_RenderOptions::~CPDF_RenderOptions() {} FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const { if (m_ColorMode == RENDER_COLOR_NORMAL) diff --git a/core/fpdfapi/render/cpdf_renderoptions.h b/core/fpdfapi/render/cpdf_renderoptions.h index 95651d9d7..b934941d0 100644 --- a/core/fpdfapi/render/cpdf_renderoptions.h +++ b/core/fpdfapi/render/cpdf_renderoptions.h @@ -7,11 +7,11 @@ #ifndef CORE_FPDFAPI_RENDER_CPDF_RENDEROPTIONS_H_ #define CORE_FPDFAPI_RENDER_CPDF_RENDEROPTIONS_H_ +#include "core/fpdfdoc/cpdf_occontext.h" +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_system.h" #include "core/fxge/fx_dib.h" -class CPDF_OCContext; - #define RENDER_COLOR_NORMAL 0 #define RENDER_COLOR_GRAY 1 #define RENDER_COLOR_TWOCOLOR 2 @@ -37,6 +37,8 @@ class CPDF_RenderOptions { public: CPDF_RenderOptions(); CPDF_RenderOptions(const CPDF_RenderOptions& rhs); + ~CPDF_RenderOptions(); + FX_ARGB TranslateColor(FX_ARGB argb) const; int m_ColorMode; @@ -45,10 +47,10 @@ class CPDF_RenderOptions { uint32_t m_Flags; int m_Interpolation; uint32_t m_AddFlags; - CPDF_OCContext* m_pOCContext; uint32_t m_dwLimitCacheSize; int m_HalftoneLimit; bool m_bDrawAnnots; + CFX_RetainPtr<CPDF_OCContext> m_pOCContext; }; #endif // CORE_FPDFAPI_RENDER_CPDF_RENDEROPTIONS_H_ diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index 35d061616..9022212ec 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -159,10 +159,11 @@ void DrawAxialShading(CFX_DIBitmap* pBitmap, for (int row = 0; row < height; row++) { uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch); for (int column = 0; column < width; column++) { - FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; - matrix.Transform(x, y); - FX_FLOAT scale = (((x - start_x) * x_span) + ((y - start_y) * y_span)) / - axis_len_square; + CFX_PointF pos = matrix.Transform(CFX_PointF( + static_cast<FX_FLOAT>(column), static_cast<FX_FLOAT>(row))); + FX_FLOAT scale = + (((pos.x - start_x) * x_span) + ((pos.y - start_y) * y_span)) / + axis_len_square; int index = (int32_t)(scale * (SHADING_STEPS - 1)); if (index < 0) { if (!bStartExtend) @@ -252,13 +253,14 @@ void DrawRadialShading(CFX_DIBitmap* pBitmap, for (int row = 0; row < height; row++) { uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch); for (int column = 0; column < width; column++) { - FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; - matrix.Transform(x, y); - FX_FLOAT b = -2 * (((x - start_x) * (end_x - start_x)) + - ((y - start_y) * (end_y - start_y)) + + CFX_PointF pos = matrix.Transform(CFX_PointF( + static_cast<FX_FLOAT>(column), static_cast<FX_FLOAT>(row))); + FX_FLOAT b = -2 * (((pos.x - start_x) * (end_x - start_x)) + + ((pos.y - start_y) * (end_y - start_y)) + (start_r * (end_r - start_r))); - FX_FLOAT c = ((x - start_x) * (x - start_x)) + - ((y - start_y) * (y - start_y)) - (start_r * start_r); + FX_FLOAT c = ((pos.x - start_x) * (pos.x - start_x)) + + ((pos.y - start_y) * (pos.y - start_y)) - + (start_r * start_r); FX_FLOAT s; if (a == 0) { s = -c / b; @@ -327,8 +329,10 @@ void DrawFuncShading(CFX_DIBitmap* pBitmap, ymax = pDomain->GetNumberAt(3); } CFX_Matrix mtDomain2Target = pDict->GetMatrixFor("Matrix"); - CFX_Matrix matrix, reverse_matrix; + CFX_Matrix matrix; matrix.SetReverse(*pObject2Bitmap); + + CFX_Matrix reverse_matrix; reverse_matrix.SetReverse(mtDomain2Target); matrix.Concat(reverse_matrix); int width = pBitmap->GetWidth(); @@ -342,15 +346,13 @@ void DrawFuncShading(CFX_DIBitmap* pBitmap, for (int row = 0; row < height; row++) { uint32_t* dib_buf = (uint32_t*)(pBitmap->GetBuffer() + row * pitch); for (int column = 0; column < width; column++) { - FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; - matrix.Transform(x, y); - if (x < xmin || x > xmax || y < ymin || y > ymax) { + CFX_PointF pos = matrix.Transform(CFX_PointF( + static_cast<FX_FLOAT>(column), static_cast<FX_FLOAT>(row))); + if (pos.x < xmin || pos.x > xmax || pos.y < ymin || pos.y > ymax) continue; - } - FX_FLOAT input[2]; + + FX_FLOAT input[] = {pos.x, pos.y}; int offset = 0; - input[0] = x; - input[1] = y; for (const auto& func : funcs) { if (func) { int nresults; @@ -358,7 +360,10 @@ void DrawFuncShading(CFX_DIBitmap* pBitmap, offset += nresults; } } - FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + + FX_FLOAT R = 0.0f; + FX_FLOAT G = 0.0f; + FX_FLOAT B = 0.0f; pCS->GetRGB(pResults, R, G, B); dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE( alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); @@ -367,67 +372,65 @@ void DrawFuncShading(CFX_DIBitmap* pBitmap, } bool GetScanlineIntersect(int y, - FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2, + const CFX_PointF& first, + const CFX_PointF& second, FX_FLOAT* x) { - if (y1 == y2) + if (first.y == second.y) return false; - if (y1 < y2) { - if (y < y1 || y > y2) - return false; - } else { - if (y < y2 || y > y1) + if (first.y < second.y) { + if (y < first.y || y > second.y) return false; + } else if (y < second.y || y > first.y) { + return false; } - *x = x1 + ((x2 - x1) * (y - y1) / (y2 - y1)); + *x = first.x + ((second.x - first.x) * (y - first.y) / (second.y - first.y)); return true; } void DrawGouraud(CFX_DIBitmap* pBitmap, int alpha, CPDF_MeshVertex triangle[3]) { - FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; + FX_FLOAT min_y = triangle[0].position.y; + FX_FLOAT max_y = triangle[0].position.y; for (int i = 1; i < 3; i++) { - if (min_y > triangle[i].y) { - min_y = triangle[i].y; - } - if (max_y < triangle[i].y) { - max_y = triangle[i].y; - } + min_y = std::min(min_y, triangle[i].position.y); + max_y = std::max(max_y, triangle[i].position.y); } - if (min_y == max_y) { + if (min_y == max_y) return; - } - int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); - if (min_yi < 0) { - min_yi = 0; - } - if (max_yi >= pBitmap->GetHeight()) { + + int min_yi = std::max(static_cast<int>(FXSYS_floor(min_y)), 0); + int max_yi = static_cast<int>(FXSYS_ceil(max_y)); + + if (max_yi >= pBitmap->GetHeight()) max_yi = pBitmap->GetHeight() - 1; - } + for (int y = min_yi; y <= max_yi; y++) { int nIntersects = 0; - FX_FLOAT inter_x[3], r[3], g[3], b[3]; + FX_FLOAT inter_x[3]; + FX_FLOAT r[3]; + FX_FLOAT g[3]; + FX_FLOAT b[3]; for (int i = 0; i < 3; i++) { CPDF_MeshVertex& vertex1 = triangle[i]; CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; - bool bIntersect = GetScanlineIntersect(y, vertex1.x, vertex1.y, vertex2.x, - vertex2.y, &inter_x[nIntersects]); + CFX_PointF& position1 = vertex1.position; + CFX_PointF& position2 = vertex2.position; + bool bIntersect = + GetScanlineIntersect(y, position1, position2, &inter_x[nIntersects]); if (!bIntersect) continue; - FX_FLOAT y_dist = (y - vertex1.y) / (vertex2.y - vertex1.y); + FX_FLOAT y_dist = (y - position1.y) / (position2.y - position1.y); r[nIntersects] = vertex1.r + ((vertex2.r - vertex1.r) * y_dist); g[nIntersects] = vertex1.g + ((vertex2.g - vertex1.g) * y_dist); b[nIntersects] = vertex1.b + ((vertex2.b - vertex1.b) * y_dist); nIntersects++; } - if (nIntersects != 2) { + if (nIntersects != 2) continue; - } + int min_x, max_x, start_index, end_index; if (inter_x[0] < inter_x[1]) { min_x = (int)FXSYS_floor(inter_x[0]); @@ -440,13 +443,12 @@ void DrawGouraud(CFX_DIBitmap* pBitmap, start_index = 1; end_index = 0; } - int start_x = min_x, end_x = max_x; - if (start_x < 0) { - start_x = 0; - } - if (end_x > pBitmap->GetWidth()) { + + int start_x = std::max(min_x, 0); + int end_x = max_x; + if (end_x > pBitmap->GetWidth()) end_x = pBitmap->GetWidth(); - } + uint8_t* dib_buf = pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4; FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); @@ -486,16 +488,21 @@ void DrawFreeGouraudShading( while (!stream.BitStream()->IsEOF()) { CPDF_MeshVertex vertex; - uint32_t flag = stream.GetVertex(vertex, pObject2Bitmap); + uint32_t flag; + if (!stream.ReadVertex(*pObject2Bitmap, &vertex, &flag)) + return; + if (flag == 0) { triangle[0] = vertex; for (int j = 1; j < 3; j++) { - stream.GetVertex(triangle[j], pObject2Bitmap); + uint32_t tflag; + if (!stream.ReadVertex(*pObject2Bitmap, &triangle[j], &tflag)) + return; } } else { - if (flag == 1) { + if (flag == 1) triangle[0] = triangle[1]; - } + triangle[1] = triangle[2]; triangle[2] = vertex; } @@ -523,14 +530,14 @@ void DrawLatticeGouraudShading( std::unique_ptr<CPDF_MeshVertex, FxFreeDeleter> vertex( FX_Alloc2D(CPDF_MeshVertex, row_verts, 2)); - if (!stream.GetVertexRow(vertex.get(), row_verts, pObject2Bitmap)) + if (!stream.ReadVertexRow(*pObject2Bitmap, row_verts, vertex.get())) return; int last_index = 0; while (1) { CPDF_MeshVertex* last_row = vertex.get() + last_index * row_verts; CPDF_MeshVertex* this_row = vertex.get() + (1 - last_index) * row_verts; - if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) + if (!stream.ReadVertexRow(*pObject2Bitmap, row_verts, this_row)) return; CPDF_MeshVertex triangle[3]; @@ -611,18 +618,21 @@ struct Coon_Bezier { x.FromPoints(x0, x1, x2, x3); y.FromPoints(y0, y1, y2, y3); } + Coon_Bezier first_half() { Coon_Bezier result; result.x = x.first_half(); result.y = y.first_half(); return result; } + Coon_Bezier second_half() { Coon_Bezier result; result.x = x.second_half(); result.y = y.second_half(); return result; } + void BezierInterpol(Coon_Bezier& C1, Coon_Bezier& C2, Coon_Bezier& D1, @@ -630,30 +640,31 @@ struct Coon_Bezier { x.BezierInterpol(C1.x, C2.x, D1.x, D2.x); y.BezierInterpol(C1.y, C2.y, D1.y, D2.y); } - void GetPoints(FX_PATHPOINT* pPoints) { + + void GetPoints(std::vector<FX_PATHPOINT>& pPoints, size_t start_idx) { float p[4]; int i; x.GetPoints(p); - for (i = 0; i < 4; i++) { - pPoints[i].m_PointX = p[i]; - } + for (i = 0; i < 4; i++) + pPoints[start_idx + i].m_Point.x = p[i]; + y.GetPoints(p); - for (i = 0; i < 4; i++) { - pPoints[i].m_PointY = p[i]; - } + for (i = 0; i < 4; i++) + pPoints[start_idx + i].m_Point.y = p[i]; } - void GetPointsReverse(FX_PATHPOINT* pPoints) { + + void GetPointsReverse(std::vector<FX_PATHPOINT>& pPoints, size_t start_idx) { float p[4]; int i; x.GetPointsReverse(p); - for (i = 0; i < 4; i++) { - pPoints[i].m_PointX = p[i]; - } + for (i = 0; i < 4; i++) + pPoints[i + start_idx].m_Point.x = p[i]; + y.GetPointsReverse(p); - for (i = 0; i < 4; i++) { - pPoints[i].m_PointY = p[i]; - } + for (i = 0; i < 4; i++) + pPoints[i + start_idx].m_Point.y = p[i]; } + float Distance() { return x.Distance() + y.Distance(); } }; @@ -693,6 +704,7 @@ struct Coon_Color { } }; +#define COONCOLOR_THRESHOLD 4 struct CPDF_PatchDrawer { Coon_Color patch_colors[4]; int max_delta; @@ -728,15 +740,15 @@ struct CPDF_PatchDrawer { d_top = div_colors[1].Distance(div_colors[2]); d_right = div_colors[2].Distance(div_colors[3]); } -#define COONCOLOR_THRESHOLD 4 + if (bSmall || (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) { - FX_PATHPOINT* pPoints = path.GetPoints(); - C1.GetPoints(pPoints); - D2.GetPoints(pPoints + 3); - C2.GetPointsReverse(pPoints + 6); - D1.GetPointsReverse(pPoints + 9); + std::vector<FX_PATHPOINT>& pPoints = path.GetPoints(); + C1.GetPoints(pPoints, 0); + D2.GetPoints(pPoints, 3); + C2.GetPointsReverse(pPoints, 6); + D1.GetPointsReverse(pPoints, 9); int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER; if (fill_mode & RENDER_NOPATHSMOOTH) { fillFlags |= FXFILL_NOPATHSMOOTH; @@ -814,15 +826,18 @@ void DrawCoonPatchMeshes( patch.alpha = alpha; patch.pDevice = &device; patch.fill_mode = fill_mode; - patch.path.SetPointCount(13); - FX_PATHPOINT* pPoints = patch.path.GetPoints(); - pPoints[0].m_Flag = FXPT_MOVETO; - for (int i = 1; i < 13; i++) - pPoints[i].m_Flag = FXPT_BEZIERTO; + + for (int i = 0; i < 13; i++) { + patch.path.AppendPoint( + CFX_PointF(), i == 0 ? FXPT_TYPE::MoveTo : FXPT_TYPE::BezierTo, false); + } + CFX_PointF coords[16]; int point_count = type == kTensorProductPatchMeshShading ? 16 : 12; while (!stream.BitStream()->IsEOF()) { - uint32_t flag = stream.GetFlag(); + if (!stream.CanReadFlag()) + break; + uint32_t flag = stream.ReadFlag(); int iStartPoint = 0, iStartColor = 0, i = 0; if (flag) { iStartPoint = 4; @@ -838,12 +853,20 @@ void DrawCoonPatchMeshes( FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2); } for (i = iStartPoint; i < point_count; i++) { - stream.GetCoords(coords[i].x, coords[i].y); - pObject2Bitmap->Transform(coords[i].x, coords[i].y); + if (!stream.CanReadCoords()) + break; + coords[i] = pObject2Bitmap->Transform(stream.ReadCoords()); } + for (i = iStartColor; i < 4; i++) { - FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; - stream.GetColor(r, g, b); + if (!stream.CanReadColor()) + break; + + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; + std::tie(r, g, b) = stream.ReadColor(); + patch.patch_colors[i].comp[0] = (int32_t)(r * 255); patch.patch_colors[i].comp[1] = (int32_t)(g * 255); patch.patch_colors[i].comp[2] = (int32_t)(b * 255); @@ -888,6 +911,7 @@ std::unique_ptr<CFX_DIBitmap> DrawPatternBitmap( CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height); CFX_Matrix mtAdjust; mtAdjust.MatchRect(bitmap_rect, cell_bbox); + CFX_Matrix mtPattern2Bitmap = *pObject2Device; mtPattern2Bitmap.Concat(mtAdjust); CPDF_RenderOptions options; @@ -1360,7 +1384,7 @@ void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, if (!pPathData) continue; - if (pPathData->GetPointCount() == 0) { + if (pPathData->GetPoints().empty()) { CFX_PathData EmptyPath; EmptyPath.AppendRect(-1, -1, 0, 0); int fill_mode = FXFILL_WINDING; @@ -1525,7 +1549,7 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, CFX_DIBitmap* bitmap = bitmap_device.GetBitmap(); bitmap->Clear(0); CFX_Matrix new_matrix = *pObj2Device; - new_matrix.TranslateI(-rect.left, -rect.top); + new_matrix.Translate(-rect.left, -rect.top); new_matrix.Scale(scaleX, scaleY); std::unique_ptr<CFX_DIBitmap> pTextMask; if (bTextClip) { @@ -1538,16 +1562,15 @@ bool CPDF_RenderStatus::ProcessTransparency(CPDF_PageObject* pPageObj, text_device.Attach(pTextMask.get(), false, nullptr, false); for (uint32_t i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) { CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i); - if (!textobj) { + if (!textobj) break; - } - CFX_Matrix text_matrix; - textobj->GetTextMatrix(&text_matrix); + + CFX_Matrix text_matrix = textobj->GetTextMatrix(); CPDF_TextRenderer::DrawTextPath( - &text_device, textobj->m_nChars, textobj->m_pCharCodes, - textobj->m_pCharPos, textobj->m_TextState.GetFont(), - textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix, - textobj->m_GraphState.GetObject(), (FX_ARGB)-1, 0, nullptr, 0); + &text_device, textobj->m_CharCodes, textobj->m_CharPos, + textobj->m_TextState.GetFont(), textobj->m_TextState.GetFontSize(), + &text_matrix, &new_matrix, textobj->m_GraphState.GetObject(), + (FX_ARGB)-1, 0, nullptr, 0); } } CPDF_RenderStatus bitmap_render; @@ -1628,7 +1651,7 @@ std::unique_ptr<CFX_DIBitmap> CPDF_RenderStatus::GetBackdrop( } CFX_Matrix FinalMatrix = m_DeviceMatrix; - FinalMatrix.TranslateI(-left, -top); + FinalMatrix.Translate(-left, -top); FinalMatrix.Scale(scaleX, scaleY); pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff); CFX_FxgeDevice device; @@ -1666,7 +1689,7 @@ void CPDF_RenderStatus::DebugVerifyDeviceIsPreMultiplied() const { bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, const CFX_Matrix* pObj2Device, CFX_PathData* pClippingPath) { - if (textobj->m_nChars == 0) + if (textobj->m_CharCodes.empty()) return true; const TextRenderingMode text_render_mode = textobj->m_TextState.GetTextMode(); @@ -1726,8 +1749,7 @@ bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, fill_argb = GetFillArgb(textobj); } } - CFX_Matrix text_matrix; - textobj->GetTextMatrix(&text_matrix); + CFX_Matrix text_matrix = textobj->GetTextMatrix(); if (!IsAvailableMatrix(text_matrix)) return true; @@ -1760,15 +1782,14 @@ bool CPDF_RenderStatus::ProcessText(CPDF_TextObject* textobj, if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) flag |= FXFILL_NOPATHSMOOTH; return CPDF_TextRenderer::DrawTextPath( - m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, - textobj->m_pCharPos, pFont, font_size, &text_matrix, pDeviceMatrix, - textobj->m_GraphState.GetObject(), fill_argb, stroke_argb, - pClippingPath, flag); + m_pDevice, textobj->m_CharCodes, textobj->m_CharPos, pFont, font_size, + &text_matrix, pDeviceMatrix, textobj->m_GraphState.GetObject(), + fill_argb, stroke_argb, pClippingPath, flag); } text_matrix.Concat(*pObj2Device); - return CPDF_TextRenderer::DrawNormalText( - m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, - pFont, font_size, &text_matrix, fill_argb, &m_Options); + return CPDF_TextRenderer::DrawNormalText(m_pDevice, textobj->m_CharCodes, + textobj->m_CharPos, pFont, font_size, + &text_matrix, fill_argb, &m_Options); } CPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont) { @@ -1789,8 +1810,7 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, CFX_Matrix dCTM = m_pDevice->GetCTM(); FX_FLOAT sa = FXSYS_fabs(dCTM.a); FX_FLOAT sd = FXSYS_fabs(dCTM.d); - CFX_Matrix text_matrix; - textobj->GetTextMatrix(&text_matrix); + CFX_Matrix text_matrix = textobj->GetTextMatrix(); CFX_Matrix char_matrix = pType3Font->GetFontMatrix(); FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); char_matrix.Scale(font_size, font_size); @@ -1799,18 +1819,15 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, int device_class = m_pDevice->GetDeviceClass(); std::vector<FXTEXT_GLYPHPOS> glyphs; if (device_class == FXDC_DISPLAY) - glyphs.resize(textobj->m_nChars); + glyphs.resize(textobj->m_CharCodes.size()); else if (fill_alpha < 255) return false; CPDF_RefType3Cache refTypeCache(pType3Font); - uint32_t* pChars = textobj->m_pCharCodes; - if (textobj->m_nChars == 1) - pChars = (uint32_t*)(&textobj->m_pCharCodes); - - for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { - uint32_t charcode = pChars[iChar]; - if (charcode == (uint32_t)-1) + for (int iChar = 0; iChar < pdfium::CollectionSize<int>(textobj->m_CharCodes); + iChar++) { + uint32_t charcode = textobj->m_CharCodes[iChar]; + if (charcode == static_cast<uint32_t>(-1)) continue; CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode); @@ -1818,7 +1835,7 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, continue; CFX_Matrix matrix = char_matrix; - matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0; + matrix.e += iChar ? textobj->m_CharPos[iChar - 1] : 0; matrix.Concat(text_matrix); matrix.Concat(*pObj2Device); if (!pType3Char->LoadBitmap(m_pContext)) { @@ -1829,8 +1846,8 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, continue; m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap, - glyph.m_OriginX + glyph.m_pGlyph->m_Left, - glyph.m_OriginY - glyph.m_pGlyph->m_Top, + glyph.m_Origin.x + glyph.m_pGlyph->m_Left, + glyph.m_Origin.y - glyph.m_pGlyph->m_Top, fill_argb); } glyphs.clear(); @@ -1857,7 +1874,8 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, m_pDevice->RestoreState(false); } else { CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); - rect_f.Transform(&matrix); + matrix.TransformRect(rect_f); + FX_RECT rect = rect_f.GetOuterRect(); CFX_FxgeDevice bitmap_device; if (!bitmap_device.Create((int)(rect.Width() * sa), @@ -1873,7 +1891,7 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, pFormResource, false, pType3Char, fill_argb); status.m_Type3FontCache = m_Type3FontCache; status.m_Type3FontCache.push_back(pType3Font); - matrix.TranslateI(-rect.left, -rect.top); + matrix.Translate(-rect.left, -rect.top); matrix.Scale(sa, sd); status.RenderObjectList(pType3Char->m_pForm.get(), &matrix); m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top); @@ -1887,15 +1905,13 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, if (!pBitmap) continue; - int origin_x = FXSYS_round(matrix.e); - int origin_y = FXSYS_round(matrix.f); + CFX_Point origin(FXSYS_round(matrix.e), FXSYS_round(matrix.f)); if (glyphs.empty()) { - m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, - origin_y - pBitmap->m_Top, fill_argb); + m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin.x + pBitmap->m_Left, + origin.y - pBitmap->m_Top, fill_argb); } else { glyphs[iChar].m_pGlyph = pBitmap; - glyphs[iChar].m_OriginX = origin_x; - glyphs[iChar].m_OriginY = origin_y; + glyphs[iChar].m_Origin = origin; } } else { CFX_Matrix image_matrix = pType3Char->m_ImageMatrix; @@ -1925,14 +1941,14 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, if (!glyph.m_pGlyph) continue; - pdfium::base::CheckedNumeric<int> left = glyph.m_OriginX; + pdfium::base::CheckedNumeric<int> left = glyph.m_Origin.x; left += glyph.m_pGlyph->m_Left; left -= rect.left; left *= sa; if (!left.IsValid()) continue; - pdfium::base::CheckedNumeric<int> top = glyph.m_OriginY; + pdfium::base::CheckedNumeric<int> top = glyph.m_Origin.y; top -= glyph.m_pGlyph->m_Top; top -= rect.top; top *= sd; @@ -1974,8 +1990,7 @@ void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, return; } CPDF_CharPosList CharPosList; - CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, - textobj->m_pCharPos, pFont, font_size); + CharPosList.Load(textobj->m_CharCodes, textobj->m_CharPos, pFont, font_size); for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; auto font = @@ -1984,18 +1999,21 @@ void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, : pFont->m_FontFallbacks[charpos.m_FallbackFontPosition].get(); const CFX_PathData* pPath = font->LoadGlyphPath(charpos.m_GlyphIndex, charpos.m_FontCharWidth); - if (!pPath) { + if (!pPath) continue; - } + CPDF_PathObject path; path.m_GraphState = textobj->m_GraphState; path.m_ColorState = textobj->m_ColorState; + CFX_Matrix matrix; - if (charpos.m_bGlyphAdjust) - matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); - matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, - charpos.m_OriginY); + if (charpos.m_bGlyphAdjust) { + matrix = CFX_Matrix(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], + 0, 0); + } + matrix.Concat(CFX_Matrix(font_size, 0, 0, font_size, charpos.m_Origin.x, + charpos.m_Origin.y)); path.m_Path.Append(pPath, &matrix); path.m_Matrix = *pTextMatrix; path.m_bStroke = bStroke; @@ -2032,7 +2050,7 @@ void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, } if (pDict->KeyExist("BBox")) { CFX_FloatRect rect = pDict->GetRectFor("BBox"); - rect.Transform(pMatrix); + pMatrix->TransformRect(rect); clip_rect.Intersect(rect.GetOuterRect()); } if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SHADING && @@ -2198,8 +2216,9 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, int min_col, max_col, min_row, max_row; CFX_Matrix mtDevice2Pattern; mtDevice2Pattern.SetReverse(mtPattern2Device); + CFX_FloatRect clip_box_p(clip_box); - clip_box_p.Transform(&mtDevice2Pattern); + mtDevice2Pattern.TransformRect(clip_box_p); min_col = (int)FXSYS_ceil((clip_box_p.left - pPattern->bbox().right) / pPattern->x_step()); @@ -2222,13 +2241,11 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, for (int col = min_col; col <= max_col; col++) for (int row = min_row; row <= max_row; row++) { - FX_FLOAT orig_x, orig_y; - orig_x = col * pPattern->x_step(); - orig_y = row * pPattern->y_step(); - mtPattern2Device.Transform(orig_x, orig_y); + CFX_PointF original = mtPattern2Device.Transform( + CFX_PointF(col * pPattern->x_step(), row * pPattern->y_step())); CFX_Matrix matrix = *pObj2Device; - matrix.Translate(orig_x - mtPattern2Device.e, - orig_y - mtPattern2Device.f); + matrix.Translate(original.x - mtPattern2Device.e, + original.y - mtPattern2Device.f); m_pDevice->SaveState(); CPDF_RenderStatus status; status.Initialize(m_pContext, m_pDevice, nullptr, nullptr, this, @@ -2298,14 +2315,13 @@ void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left; start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top; } else { - FX_FLOAT orig_x = col * pPattern->x_step(); - FX_FLOAT orig_y = row * pPattern->y_step(); - mtPattern2Device.Transform(orig_x, orig_y); + CFX_PointF original = mtPattern2Device.Transform( + CFX_PointF(col * pPattern->x_step(), row * pPattern->y_step())); pdfium::base::CheckedNumeric<int> safeStartX = - FXSYS_round(orig_x + left_offset); + FXSYS_round(original.x + left_offset); pdfium::base::CheckedNumeric<int> safeStartY = - FXSYS_round(orig_y + top_offset); + FXSYS_round(original.y + top_offset); safeStartX -= clip_box.left; safeStartY -= clip_box.top; @@ -2516,7 +2532,7 @@ std::unique_ptr<CFX_DIBitmap> CPDF_RenderStatus::LoadSMask( pFunc = CPDF_Function::Load(pFuncObj); CFX_Matrix matrix = *pMatrix; - matrix.TranslateI(-pClipRect->left, -pClipRect->top); + matrix.Translate(-pClipRect->left, -pClipRect->top); CPDF_Form form(m_pContext->GetDocument(), m_pContext->GetPageResources(), pGroup); diff --git a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp index bcc03ba2d..de60e732b 100644 --- a/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp +++ b/core/fpdfapi/render/cpdf_scaledrenderbuffer.cpp @@ -31,7 +31,7 @@ bool CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext, m_pContext = pContext; m_Rect = pRect; m_pObject = pObj; - m_Matrix.TranslateI(-pRect.left, -pRect.top); + m_Matrix.Translate(-pRect.left, -pRect.top); int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE); int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE); if (horz_size && vert_size && max_dpi) { diff --git a/core/fpdfapi/render/cpdf_textrenderer.cpp b/core/fpdfapi/render/cpdf_textrenderer.cpp index 9cb8ce933..95af863f7 100644 --- a/core/fpdfapi/render/cpdf_textrenderer.cpp +++ b/core/fpdfapi/render/cpdf_textrenderer.cpp @@ -6,7 +6,7 @@ #include "core/fpdfapi/render/cpdf_textrenderer.h" -#include <vector> +#include <algorithm> #include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfapi/render/cpdf_charposlist.h" @@ -17,9 +17,8 @@ // static bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, - int nChars, - uint32_t* pCharCodes, - FX_FLOAT* pCharPos, + const std::vector<uint32_t>& charCodes, + const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_Matrix* pText2User, @@ -30,7 +29,7 @@ bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, CFX_PathData* pClippingPath, int nFlag) { CPDF_CharPosList CharPosList; - CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); + CharPosList.Load(charCodes, charPos, pFont, font_size); if (CharPosList.m_nChars == 0) return true; @@ -73,7 +72,6 @@ void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, const CFX_Matrix* pMatrix, const CFX_ByteString& str, FX_ARGB fill_argb, - FX_ARGB stroke_argb, const CFX_GraphStateData* pGraphState, const CPDF_RenderOptions* pOptions) { if (pFont->IsType3Font()) @@ -84,26 +82,16 @@ void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, return; int offset = 0; - uint32_t* pCharCodes; - FX_FLOAT* pCharPos; std::vector<uint32_t> codes; std::vector<FX_FLOAT> positions; - if (nChars == 1) { - pCharCodes = reinterpret_cast<uint32_t*>( - pFont->GetNextChar(str.c_str(), str.GetLength(), offset)); - pCharPos = nullptr; - } else { - codes.resize(nChars); - positions.resize(nChars - 1); - FX_FLOAT cur_pos = 0; - for (int i = 0; i < nChars; i++) { - codes[i] = pFont->GetNextChar(str.c_str(), str.GetLength(), offset); - if (i) - positions[i - 1] = cur_pos; - cur_pos += pFont->GetCharWidthF(codes[i]) * font_size / 1000; - } - pCharCodes = codes.data(); - pCharPos = positions.data(); + codes.resize(nChars); + positions.resize(nChars - 1); + FX_FLOAT cur_pos = 0; + for (int i = 0; i < nChars; i++) { + codes[i] = pFont->GetNextChar(str.c_str(), str.GetLength(), offset); + if (i) + positions[i - 1] = cur_pos; + cur_pos += pFont->GetCharWidthF(codes[i]) * font_size / 1000; } CFX_Matrix matrix; if (pMatrix) @@ -112,28 +100,21 @@ void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, matrix.e = origin_x; matrix.f = origin_y; - if (stroke_argb == 0) { - DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, - &matrix, fill_argb, pOptions); - } else { - DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, - &matrix, nullptr, pGraphState, fill_argb, stroke_argb, nullptr, - 0); - } + DrawNormalText(pDevice, codes, positions, pFont, font_size, &matrix, + fill_argb, pOptions); } // static bool CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, - int nChars, - uint32_t* pCharCodes, - FX_FLOAT* pCharPos, + const std::vector<uint32_t>& charCodes, + const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_Matrix* pText2Device, FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions) { CPDF_CharPosList CharPosList; - CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); + CharPosList.Load(charCodes, charPos, pFont, font_size); if (CharPosList.m_nChars == 0) return true; int FXGE_flags = 0; diff --git a/core/fpdfapi/render/cpdf_textrenderer.h b/core/fpdfapi/render/cpdf_textrenderer.h index 82cc2cf8e..54e9d1bd0 100644 --- a/core/fpdfapi/render/cpdf_textrenderer.h +++ b/core/fpdfapi/render/cpdf_textrenderer.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_RENDER_CPDF_TEXTRENDERER_H_ #define CORE_FPDFAPI_RENDER_CPDF_TEXTRENDERER_H_ +#include <vector> + #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" @@ -28,14 +30,12 @@ class CPDF_TextRenderer { const CFX_Matrix* matrix, const CFX_ByteString& str, FX_ARGB fill_argb, - FX_ARGB stroke_argb, const CFX_GraphStateData* pGraphState, const CPDF_RenderOptions* pOptions); static bool DrawTextPath(CFX_RenderDevice* pDevice, - int nChars, - uint32_t* pCharCodes, - FX_FLOAT* pCharPos, + const std::vector<uint32_t>& charCodes, + const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_Matrix* pText2User, @@ -47,9 +47,8 @@ class CPDF_TextRenderer { int nFlag); static bool DrawNormalText(CFX_RenderDevice* pDevice, - int nChars, - uint32_t* pCharCodes, - FX_FLOAT* pCharPos, + const std::vector<uint32_t>& charCodes, + const std::vector<FX_FLOAT>& charPos, CPDF_Font* pFont, FX_FLOAT font_size, const CFX_Matrix* pText2Device, diff --git a/core/fpdfapi/render/cpdf_type3cache.cpp b/core/fpdfapi/render/cpdf_type3cache.cpp index b27fdf507..63cc780d1 100644 --- a/core/fpdfapi/render/cpdf_type3cache.cpp +++ b/core/fpdfapi/render/cpdf_type3cache.cpp @@ -122,10 +122,10 @@ CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, return nullptr; CFX_DIBitmap* pBitmap = pChar->m_pBitmap.get(); - CFX_Matrix image_matrix, text_matrix; - image_matrix = pChar->m_ImageMatrix; - text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); + CFX_Matrix image_matrix = pChar->m_ImageMatrix; + CFX_Matrix text_matrix(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); image_matrix.Concat(text_matrix); + std::unique_ptr<CFX_DIBitmap> pResBitmap; int left = 0; int top = 0; diff --git a/core/fpdfdoc/cpdf_annot.cpp b/core/fpdfdoc/cpdf_annot.cpp index 38e5b5fc8..89c4785d9 100644 --- a/core/fpdfdoc/cpdf_annot.cpp +++ b/core/fpdfdoc/cpdf_annot.cpp @@ -500,8 +500,8 @@ void CPDF_Annot::DrawBorder(CFX_RenderDevice* pDevice, path.AppendRect(rect.left + width, rect.bottom + width, rect.right - width, rect.top - width); int fill_type = 0; - if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) { + if (pOptions && (pOptions->m_Flags & RENDER_NOPATHSMOOTH)) fill_type |= FXFILL_NOPATHSMOOTH; - } + pDevice->DrawPath(&path, pUser2Device, &graph_state, argb, argb, fill_type); } diff --git a/core/fpdfdoc/cpdf_annotlist.cpp b/core/fpdfdoc/cpdf_annotlist.cpp index 1ad6ab23a..ed1b60c28 100644 --- a/core/fpdfdoc/cpdf_annotlist.cpp +++ b/core/fpdfdoc/cpdf_annotlist.cpp @@ -126,7 +126,7 @@ void CPDF_AnnotList::DisplayPass(CPDF_Page* pPage, continue; if (pOptions) { - CPDF_OCContext* pOCContext = pOptions->m_pOCContext; + CFX_RetainPtr<CPDF_OCContext> pOCContext = pOptions->m_pOCContext; CPDF_Dictionary* pAnnotDict = pAnnot->GetAnnotDict(); if (pOCContext && pAnnotDict && !pOCContext->CheckOCGVisible(pAnnotDict->GetDictFor("OC"))) { @@ -136,12 +136,12 @@ void CPDF_AnnotList::DisplayPass(CPDF_Page* pPage, CFX_FloatRect annot_rect_f = pAnnot->GetRect(); CFX_Matrix matrix = *pMatrix; if (clip_rect) { - annot_rect_f.Transform(&matrix); + matrix.TransformRect(annot_rect_f); + FX_RECT annot_rect = annot_rect_f.GetOuterRect(); annot_rect.Intersect(*clip_rect); - if (annot_rect.IsEmpty()) { + if (annot_rect.IsEmpty()) continue; - } } if (pContext) { pAnnot->DrawInContext(pPage, pContext, &matrix, CPDF_Annot::Normal); diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp index daf93414b..19767650f 100644 --- a/core/fpdfdoc/cpdf_defaultappearance.cpp +++ b/core/fpdfdoc/cpdf_defaultappearance.cpp @@ -209,16 +209,15 @@ CFX_ByteString CPDF_DefaultAppearance::GetTextMatrixString() { } CFX_Matrix CPDF_DefaultAppearance::GetTextMatrix() { - CFX_Matrix tm; if (m_csDA.IsEmpty()) - return tm; + return CFX_Matrix(); CPDF_SimpleParser syntax(m_csDA.AsStringC()); - if (syntax.FindTagParamFromStart("Tm", 6)) { - FX_FLOAT f[6]; - for (int i = 0; i < 6; i++) - f[i] = FX_atof(syntax.GetWord()); - tm.Set(f[0], f[1], f[2], f[3], f[4], f[5]); - } - return tm; + if (!syntax.FindTagParamFromStart("Tm", 6)) + return CFX_Matrix(); + + FX_FLOAT f[6]; + for (int i = 0; i < 6; i++) + f[i] = FX_atof(syntax.GetWord()); + return CFX_Matrix(f); } diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp index d6a66f7b7..ce6f9a247 100644 --- a/core/fpdfdoc/cpdf_filespec.cpp +++ b/core/fpdfdoc/cpdf_filespec.cpp @@ -143,7 +143,7 @@ CFX_WideString CPDF_FileSpec::EncodeFileName(const CFX_WideStringC& filepath) { } return ChangeSlashToPDF(filepath.c_str()); #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (filepath.Left(sizeof("Mac") - 1) == FX_WSTRC(L"Mac")) { + if (filepath.Left(sizeof("Mac") - 1) == L"Mac") { CFX_WideString result; result = '/'; result += ChangeSlashToPDF(filepath.c_str()); diff --git a/core/fpdfdoc/cpdf_formfield.cpp b/core/fpdfdoc/cpdf_formfield.cpp index b344327ad..b4aa90e2b 100644 --- a/core/fpdfdoc/cpdf_formfield.cpp +++ b/core/fpdfdoc/cpdf_formfield.cpp @@ -31,10 +31,6 @@ const int kFormListMultiSelect = 0x100; const int kFormComboEdit = 0x100; -const int kFormFieldReadOnly = 0x01; -const int kFormFieldRequired = 0x02; -const int kFormFieldNoExport = 0x04; - const int kFormRadioNoToggleOff = 0x100; const int kFormRadioUnison = 0x200; @@ -108,12 +104,12 @@ void CPDF_FormField::SyncFieldFlags() { ? FPDF_GetFieldAttr(m_pDict, "Ff")->GetInteger() : 0; m_Flags = 0; - if (flags & 1) - m_Flags |= kFormFieldReadOnly; - if (flags & 2) - m_Flags |= kFormFieldRequired; - if (flags & 4) - m_Flags |= kFormFieldNoExport; + if (flags & FORMFLAG_READONLY) + m_Flags |= FORMFLAG_READONLY; + if (flags & FORMFLAG_REQUIRED) + m_Flags |= FORMFLAG_REQUIRED; + if (flags & FORMFLAG_NOEXPORT) + m_Flags |= FORMFLAG_NOEXPORT; if (type_name == "Btn") { if (flags & 0x8000) { diff --git a/core/fpdfdoc/cpdf_formfield.h b/core/fpdfdoc/cpdf_formfield.h index 9a1ddc459..42608b112 100644 --- a/core/fpdfdoc/cpdf_formfield.h +++ b/core/fpdfdoc/cpdf_formfield.h @@ -25,6 +25,10 @@ #define FIELDTYPE_TEXTFIELD 6 #define FIELDTYPE_SIGNATURE 7 +#define FORMFLAG_READONLY 0x01 +#define FORMFLAG_REQUIRED 0x02 +#define FORMFLAG_NOEXPORT 0x04 + class CPDF_Dictionary; class CPDF_Font; class CPDF_FormControl; diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp index 6cffea622..d9f0db974 100644 --- a/core/fpdfdoc/cpdf_interform.cpp +++ b/core/fpdfdoc/cpdf_interform.cpp @@ -900,8 +900,8 @@ CPDF_FormField* CPDF_InterForm::GetFieldByDict( } CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, - FX_FLOAT pdf_x, - FX_FLOAT pdf_y, + const CFX_PointF& point, + int* z_order) const { CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArrayFor("Annots"); if (!pAnnotList) @@ -918,8 +918,7 @@ CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, continue; CPDF_FormControl* pControl = it->second.get(); - CFX_FloatRect rect = pControl->GetRect(); - if (!rect.Contains(pdf_x, pdf_y)) + if (!pControl->GetRect().Contains(point)) continue; if (z_order) @@ -1157,7 +1156,7 @@ CPDF_FormControl* CPDF_InterForm::AddControl(CPDF_FormField* pField, return pControl; } -CPDF_FormField* CPDF_InterForm::CheckRequiredFields( +bool CPDF_InterForm::CheckRequiredFields( const std::vector<CPDF_FormField*>* fields, bool bIncludeOrExclude) const { size_t nCount = m_pFieldTree->m_Root.CountFields(); @@ -1173,7 +1172,7 @@ CPDF_FormField* CPDF_InterForm::CheckRequiredFields( } uint32_t dwFlags = pField->GetFieldFlags(); // TODO(thestig): Look up these magic numbers and add constants for them. - if (dwFlags & 0x04) + if (dwFlags & FORMFLAG_NOEXPORT) continue; bool bFind = true; @@ -1181,11 +1180,13 @@ CPDF_FormField* CPDF_InterForm::CheckRequiredFields( bFind = pdfium::ContainsValue(*fields, pField); if (bIncludeOrExclude == bFind) { CPDF_Dictionary* pFieldDict = pField->m_pDict; - if ((dwFlags & 0x02) != 0 && pFieldDict->GetStringFor("V").IsEmpty()) - return pField; + if ((dwFlags & FORMFLAG_REQUIRED) != 0 && + pFieldDict->GetStringFor("V").IsEmpty()) { + return false; + } } } - return nullptr; + return true; } std::unique_ptr<CFDF_Document> CPDF_InterForm::ExportToFDF( diff --git a/core/fpdfdoc/cpdf_interform.h b/core/fpdfdoc/cpdf_interform.h index b84697343..cbaaa7bc2 100644 --- a/core/fpdfdoc/cpdf_interform.h +++ b/core/fpdfdoc/cpdf_interform.h @@ -55,8 +55,7 @@ class CPDF_InterForm { CPDF_FormField* GetFieldByDict(CPDF_Dictionary* pFieldDict) const; CPDF_FormControl* GetControlAtPoint(CPDF_Page* pPage, - FX_FLOAT pdf_x, - FX_FLOAT pdf_y, + const CFX_PointF& point, int* z_order) const; CPDF_FormControl* GetControlByDict(const CPDF_Dictionary* pWidgetDict) const; @@ -69,9 +68,8 @@ class CPDF_InterForm { CPDF_DefaultAppearance GetDefaultAppearance() const; int GetFormAlignment() const; - CPDF_FormField* CheckRequiredFields( - const std::vector<CPDF_FormField*>* fields, - bool bIncludeOrExclude) const; + bool CheckRequiredFields(const std::vector<CPDF_FormField*>* fields, + bool bIncludeOrExclude) const; std::unique_ptr<CFDF_Document> ExportToFDF(const CFX_WideStringC& pdf_path, bool bSimpleFileSpec) const; diff --git a/core/fpdfdoc/cpdf_linklist.cpp b/core/fpdfdoc/cpdf_linklist.cpp index 2d8f7e233..0620dbf32 100644 --- a/core/fpdfdoc/cpdf_linklist.cpp +++ b/core/fpdfdoc/cpdf_linklist.cpp @@ -30,8 +30,7 @@ const std::vector<CPDF_Dictionary*>* CPDF_LinkList::GetPageLinks( } CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, - FX_FLOAT pdf_x, - FX_FLOAT pdf_y, + const CFX_PointF& point, int* z_order) { const std::vector<CPDF_Dictionary*>* pPageLinkList = GetPageLinks(pPage); if (!pPageLinkList) @@ -44,8 +43,7 @@ CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, continue; CPDF_Link link(pAnnot); - CFX_FloatRect rect = link.GetRect(); - if (!rect.Contains(pdf_x, pdf_y)) + if (!link.GetRect().Contains(point)) continue; if (z_order) diff --git a/core/fpdfdoc/cpdf_linklist.h b/core/fpdfdoc/cpdf_linklist.h index 21d69fdd1..129790f84 100644 --- a/core/fpdfdoc/cpdf_linklist.h +++ b/core/fpdfdoc/cpdf_linklist.h @@ -22,8 +22,7 @@ class CPDF_LinkList { ~CPDF_LinkList(); CPDF_Link GetLinkAtPoint(CPDF_Page* pPage, - FX_FLOAT pdf_x, - FX_FLOAT pdf_y, + const CFX_PointF& point, int* z_order); private: diff --git a/core/fpdfdoc/cpdf_metadata.cpp b/core/fpdfdoc/cpdf_metadata.cpp index bdb70c016..5e3acbe3a 100644 --- a/core/fpdfdoc/cpdf_metadata.cpp +++ b/core/fpdfdoc/cpdf_metadata.cpp @@ -22,7 +22,7 @@ CPDF_Metadata::CPDF_Metadata(CPDF_Document* pDoc) { CPDF_StreamAcc acc; acc.LoadAllData(pStream, false); - m_pXmlElement.reset(CXML_Element::Parse(acc.GetData(), acc.GetSize())); + m_pXmlElement = CXML_Element::Parse(acc.GetData(), acc.GetSize()); } CPDF_Metadata::~CPDF_Metadata() {} diff --git a/core/fpdfdoc/cpdf_occontext.h b/core/fpdfdoc/cpdf_occontext.h index 49bbd76d0..ecdcfae31 100644 --- a/core/fpdfdoc/cpdf_occontext.h +++ b/core/fpdfdoc/cpdf_occontext.h @@ -9,6 +9,7 @@ #include <unordered_map> +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_string.h" class CPDF_Array; @@ -16,17 +17,20 @@ class CPDF_Dictionary; class CPDF_Document; class CPDF_PageObject; -class CPDF_OCContext { +class CPDF_OCContext : public CFX_Retainable { public: - enum UsageType { View = 0, Design, Print, Export }; + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); - CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType); - ~CPDF_OCContext(); + enum UsageType { View = 0, Design, Print, Export }; bool CheckOCGVisible(const CPDF_Dictionary* pOCGDict); bool CheckObjectVisible(const CPDF_PageObject* pObj); private: + CPDF_OCContext(CPDF_Document* pDoc, UsageType eUsageType); + ~CPDF_OCContext() override; + bool LoadOCGStateFromConfig(const CFX_ByteString& csConfig, const CPDF_Dictionary* pOCGDict) const; bool LoadOCGState(const CPDF_Dictionary* pOCGDict) const; diff --git a/core/fpdfdoc/cpdf_variabletext.cpp b/core/fpdfdoc/cpdf_variabletext.cpp index 1313516f2..94b3425a0 100644 --- a/core/fpdfdoc/cpdf_variabletext.cpp +++ b/core/fpdfdoc/cpdf_variabletext.cpp @@ -172,8 +172,8 @@ bool CPDF_VariableText::Iterator::GetWord(CPVT_Word& word) const { word.nCharset = pWord->nCharset; word.fWidth = m_pVT->GetWordWidth(*pWord); word.ptWord = m_pVT->InToOut( - CFX_FloatPoint(pWord->fWordX + pSection->m_SecInfo.rcSection.left, - pWord->fWordY + pSection->m_SecInfo.rcSection.top)); + CFX_PointF(pWord->fWordX + pSection->m_SecInfo.rcSection.left, + pWord->fWordY + pSection->m_SecInfo.rcSection.top)); word.fAscent = m_pVT->GetWordAscent(*pWord); word.fDescent = m_pVT->GetWordDescent(*pWord); if (pWord->pWordProps) @@ -205,7 +205,7 @@ bool CPDF_VariableText::Iterator::GetLine(CPVT_Line& line) const { line.lineplace = CPVT_WordPlace(m_CurPos.nSecIndex, m_CurPos.nLineIndex, -1); if (CSection* pSection = m_pVT->m_SectionArray.GetAt(m_CurPos.nSecIndex)) { if (CLine* pLine = pSection->m_LineArray.GetAt(m_CurPos.nLineIndex)) { - line.ptLine = m_pVT->InToOut(CFX_FloatPoint( + line.ptLine = m_pVT->InToOut(CFX_PointF( pLine->m_LineInfo.fLineX + pSection->m_SecInfo.rcSection.left, pLine->m_LineInfo.fLineY + pSection->m_SecInfo.rcSection.top)); line.fLineWidth = pLine->m_LineInfo.fLineWidth; @@ -548,8 +548,8 @@ CPVT_WordPlace CPDF_VariableText::GetNextWordPlace( } CPVT_WordPlace CPDF_VariableText::SearchWordPlace( - const CFX_FloatPoint& point) const { - CFX_FloatPoint pt = OutToIn(point); + const CFX_PointF& point) const { + CFX_PointF pt = OutToIn(point); CPVT_WordPlace place = GetBeginWordPlace(); int32_t nLeft = 0; int32_t nRight = m_SectionArray.GetSize() - 1; @@ -574,8 +574,8 @@ CPVT_WordPlace CPDF_VariableText::SearchWordPlace( continue; } else { place = pSection->SearchWordPlace( - CFX_FloatPoint(pt.x - pSection->m_SecInfo.rcSection.left, - pt.y - pSection->m_SecInfo.rcSection.top)); + CFX_PointF(pt.x - pSection->m_SecInfo.rcSection.left, + pt.y - pSection->m_SecInfo.rcSection.top)); place.nSecIndex = nMid; return place; } @@ -592,10 +592,10 @@ CPVT_WordPlace CPDF_VariableText::SearchWordPlace( CPVT_WordPlace CPDF_VariableText::GetUpWordPlace( const CPVT_WordPlace& place, - const CFX_FloatPoint& point) const { + const CFX_PointF& point) const { if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { CPVT_WordPlace temp = place; - CFX_FloatPoint pt = OutToIn(point); + CFX_PointF pt = OutToIn(point); if (temp.nLineIndex-- > 0) { return pSection->SearchWordPlace( pt.x - pSection->m_SecInfo.rcSection.left, temp); @@ -613,10 +613,10 @@ CPVT_WordPlace CPDF_VariableText::GetUpWordPlace( CPVT_WordPlace CPDF_VariableText::GetDownWordPlace( const CPVT_WordPlace& place, - const CFX_FloatPoint& point) const { + const CFX_PointF& point) const { if (CSection* pSection = m_SectionArray.GetAt(place.nSecIndex)) { CPVT_WordPlace temp = place; - CFX_FloatPoint pt = OutToIn(point); + CFX_PointF pt = OutToIn(point); if (temp.nLineIndex++ < pSection->m_LineArray.GetSize() - 1) { return pSection->SearchWordPlace( pt.x - pSection->m_SecInfo.rcSection.left, temp); @@ -1010,10 +1010,10 @@ bool CPDF_VariableText::IsBigger(FX_FLOAT fFontSize) const { for (int32_t s = 0, sz = m_SectionArray.GetSize(); s < sz; s++) { if (CSection* pSection = m_SectionArray.GetAt(s)) { CFX_SizeF size = pSection->GetSectionSize(fFontSize); - szTotal.x = std::max(size.x, szTotal.x); - szTotal.y += size.y; - if (IsFloatBigger(szTotal.x, GetPlateWidth()) || - IsFloatBigger(szTotal.y, GetPlateHeight())) { + szTotal.width = std::max(size.width, szTotal.width); + szTotal.height += size.height; + if (IsFloatBigger(szTotal.width, GetPlateWidth()) || + IsFloatBigger(szTotal.height, GetPlateHeight())) { return true; } } @@ -1109,34 +1109,32 @@ CFX_SizeF CPDF_VariableText::GetPlateSize() const { return CFX_SizeF(GetPlateWidth(), GetPlateHeight()); } -CFX_FloatPoint CPDF_VariableText::GetBTPoint() const { - return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top); +CFX_PointF CPDF_VariableText::GetBTPoint() const { + return CFX_PointF(m_rcPlate.left, m_rcPlate.top); } -CFX_FloatPoint CPDF_VariableText::GetETPoint() const { - return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom); +CFX_PointF CPDF_VariableText::GetETPoint() const { + return CFX_PointF(m_rcPlate.right, m_rcPlate.bottom); } -CFX_FloatPoint CPDF_VariableText::InToOut(const CFX_FloatPoint& point) const { - return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y); +CFX_PointF CPDF_VariableText::InToOut(const CFX_PointF& point) const { + return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y); } -CFX_FloatPoint CPDF_VariableText::OutToIn(const CFX_FloatPoint& point) const { - return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y); +CFX_PointF CPDF_VariableText::OutToIn(const CFX_PointF& point) const { + return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y); } CFX_FloatRect CPDF_VariableText::InToOut(const CPVT_FloatRect& rect) const { - CFX_FloatPoint ptLeftTop = InToOut(CFX_FloatPoint(rect.left, rect.top)); - CFX_FloatPoint ptRightBottom = - InToOut(CFX_FloatPoint(rect.right, rect.bottom)); + CFX_PointF ptLeftTop = InToOut(CFX_PointF(rect.left, rect.top)); + CFX_PointF ptRightBottom = InToOut(CFX_PointF(rect.right, rect.bottom)); return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, ptLeftTop.y); } CPVT_FloatRect CPDF_VariableText::OutToIn(const CFX_FloatRect& rect) const { - CFX_FloatPoint ptLeftTop = OutToIn(CFX_FloatPoint(rect.left, rect.top)); - CFX_FloatPoint ptRightBottom = - OutToIn(CFX_FloatPoint(rect.right, rect.bottom)); + CFX_PointF ptLeftTop = OutToIn(CFX_PointF(rect.left, rect.top)); + CFX_PointF ptRightBottom = OutToIn(CFX_PointF(rect.right, rect.bottom)); return CPVT_FloatRect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x, ptRightBottom.y); } diff --git a/core/fpdfdoc/cpdf_variabletext.h b/core/fpdfdoc/cpdf_variabletext.h index 5983a2978..8e7c0c964 100644 --- a/core/fpdfdoc/cpdf_variabletext.h +++ b/core/fpdfdoc/cpdf_variabletext.h @@ -20,13 +20,13 @@ #include "core/fxcrt/fx_system.h" #include "core/fxge/fx_font.h" +class CPVT_Word; class CSection; class IPVT_FontMap; - struct CPVT_SecProps; struct CPVT_Section; struct CPVT_SectionInfo; -struct CPVT_Word; + struct CPVT_WordInfo; struct CPVT_WordProps; @@ -132,11 +132,11 @@ class CPDF_VariableText { CPVT_WordPlace GetEndWordPlace() const; CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const; CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const; - CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const; + CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; CPVT_WordPlace GetUpWordPlace(const CPVT_WordPlace& place, - const CFX_FloatPoint& point) const; + const CFX_PointF& point) const; CPVT_WordPlace GetDownWordPlace(const CPVT_WordPlace& place, - const CFX_FloatPoint& point) const; + const CFX_PointF& point) const; CPVT_WordPlace GetLineBeginPlace(const CPVT_WordPlace& place) const; CPVT_WordPlace GetLineEndPlace(const CPVT_WordPlace& place) const; CPVT_WordPlace GetSectionBeginPlace(const CPVT_WordPlace& place) const; @@ -152,11 +152,11 @@ class CPDF_VariableText { FX_FLOAT GetPlateWidth() const { return m_rcPlate.right - m_rcPlate.left; } FX_FLOAT GetPlateHeight() const { return m_rcPlate.top - m_rcPlate.bottom; } CFX_SizeF GetPlateSize() const; - CFX_FloatPoint GetBTPoint() const; - CFX_FloatPoint GetETPoint() const; + CFX_PointF GetBTPoint() const; + CFX_PointF GetETPoint() const; - CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const; - CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const; + CFX_PointF InToOut(const CFX_PointF& point) const; + CFX_PointF OutToIn(const CFX_PointF& point) const; CFX_FloatRect InToOut(const CPVT_FloatRect& rect) const; CPVT_FloatRect OutToIn(const CFX_FloatRect& rect) const; diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index 4bb244f29..15515151b 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -246,10 +246,10 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, vt.SetText(swValue); vt.RearrangeAll(); CFX_FloatRect rcContent = vt.GetContentRect(); - CFX_FloatPoint ptOffset; + CFX_PointF ptOffset; if (!bMultiLine) { ptOffset = - CFX_FloatPoint(0.0f, (rcContent.Height() - rcBody.Height()) / 2.0f); + CFX_PointF(0.0f, (rcContent.Height() - rcBody.Height()) / 2.0f); } CFX_ByteString sBody = CPVT_GenerateAP::GenerateEditAP( &map, vt.GetIterator(), ptOffset, !bCharArray, subWord); @@ -296,8 +296,8 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, vt.SetText(swValue); vt.RearrangeAll(); CFX_FloatRect rcContent = vt.GetContentRect(); - CFX_FloatPoint ptOffset = - CFX_FloatPoint(0.0f, (rcContent.Height() - rcEdit.Height()) / 2.0f); + CFX_PointF ptOffset = + CFX_PointF(0.0f, (rcContent.Height() - rcEdit.Height()) / 2.0f); CFX_ByteString sEdit = CPVT_GenerateAP::GenerateEditAP( &map, vt.GetIterator(), ptOffset, true, 0); if (sEdit.GetLength() > 0) { @@ -328,9 +328,8 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, if (sButtonBorder.GetLength() > 0) sAppStream << "q\n" << sButtonBorder << "Q\n"; - CFX_FloatPoint ptCenter = - CFX_FloatPoint((rcButton.left + rcButton.right) / 2, - (rcButton.top + rcButton.bottom) / 2); + CFX_PointF ptCenter = CFX_PointF((rcButton.left + rcButton.right) / 2, + (rcButton.top + rcButton.bottom) / 2); if (IsFloatBigger(rcButton.Width(), 6) && IsFloatBigger(rcButton.Height(), 6)) { sAppStream << "q\n" @@ -402,7 +401,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CPVT_Color(CPVT_Color::kGray, 1), PaintOperation::FILL) << CPVT_GenerateAP::GenerateEditAP(&map, vt.GetIterator(), - CFX_FloatPoint(0.0f, fy), + CFX_PointF(0.0f, fy), true, 0) << "ET\n"; } else { @@ -410,7 +409,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, << CPVT_GenerateAP::GenerateColorAP(crText, PaintOperation::FILL) << CPVT_GenerateAP::GenerateEditAP(&map, vt.GetIterator(), - CFX_FloatPoint(0.0f, fy), + CFX_PointF(0.0f, fy), true, 0) << "ET\n"; } @@ -529,7 +528,7 @@ CFX_ByteString GetPopupContentsString(CPDF_Document* pDoc, vt.Initialize(); vt.SetText(swValue); vt.RearrangeAll(); - CFX_FloatPoint ptOffset(3.0f, -3.0f); + CFX_PointF ptOffset(3.0f, -3.0f); CFX_ByteString sContent = CPVT_GenerateAP::GenerateEditAP( &map, vt.GetIterator(), ptOffset, false, 0); @@ -1102,14 +1101,14 @@ bool CPVT_GenerateAP::GenerateStrikeOutAP(CPDF_Document* pDoc, CFX_ByteString CPVT_GenerateAP::GenerateEditAP( IPVT_FontMap* pFontMap, CPDF_VariableText::Iterator* pIterator, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, bool bContinuous, uint16_t SubWord) { CFX_ByteTextBuf sEditStream; CFX_ByteTextBuf sLineStream; CFX_ByteTextBuf sWords; - CFX_FloatPoint ptOld; - CFX_FloatPoint ptNew; + CFX_PointF ptOld; + CFX_PointF ptNew; int32_t nCurFontIndex = -1; CPVT_WordPlace oldplace; @@ -1126,13 +1125,13 @@ CFX_ByteString CPVT_GenerateAP::GenerateEditAP( } CPVT_Word word; if (pIterator->GetWord(word)) { - ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x, - word.ptWord.y + ptOffset.y); + ptNew = CFX_PointF(word.ptWord.x + ptOffset.x, + word.ptWord.y + ptOffset.y); } else { CPVT_Line line; pIterator->GetLine(line); - ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x, - line.ptLine.y + ptOffset.y); + ptNew = CFX_PointF(line.ptLine.x + ptOffset.x, + line.ptLine.y + ptOffset.y); } if (ptNew != ptOld) { sLineStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y @@ -1157,8 +1156,8 @@ CFX_ByteString CPVT_GenerateAP::GenerateEditAP( } else { CPVT_Word word; if (pIterator->GetWord(word)) { - ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x, - word.ptWord.y + ptOffset.y); + ptNew = + CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y); if (ptNew != ptOld) { sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y << " Td\n"; diff --git a/core/fpdfdoc/cpvt_generateap.h b/core/fpdfdoc/cpvt_generateap.h index 16c939fe9..62a84531e 100644 --- a/core/fpdfdoc/cpvt_generateap.h +++ b/core/fpdfdoc/cpvt_generateap.h @@ -48,7 +48,7 @@ class CPVT_GenerateAP { CPDF_Dictionary* pAnnotDict); static CFX_ByteString GenerateEditAP(IPVT_FontMap* pFontMap, CPDF_VariableText::Iterator* pIterator, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, bool bContinuous, uint16_t SubWord); static CFX_ByteString GenerateBorderAP(const CFX_FloatRect& rect, diff --git a/core/fpdfdoc/cpvt_line.h b/core/fpdfdoc/cpvt_line.h index 25ae34af1..47c3e84d6 100644 --- a/core/fpdfdoc/cpvt_line.h +++ b/core/fpdfdoc/cpvt_line.h @@ -11,15 +11,19 @@ #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" -struct CPVT_Line { - CPVT_Line() : fLineWidth(0.0f), fLineAscent(0.0f), fLineDescent(0.0f) {} +class CPVT_Line { + public: + CPVT_Line(); CPVT_WordPlace lineplace; CPVT_WordPlace lineEnd; - CFX_FloatPoint ptLine; + CFX_PointF ptLine; FX_FLOAT fLineWidth; FX_FLOAT fLineAscent; FX_FLOAT fLineDescent; }; +inline CPVT_Line::CPVT_Line() + : fLineWidth(0.0f), fLineAscent(0.0f), fLineDescent(0.0f) {} + #endif // CORE_FPDFDOC_CPVT_LINE_H_ diff --git a/core/fpdfdoc/cpvt_lineinfo.h b/core/fpdfdoc/cpvt_lineinfo.h index 2ebc51cb8..8fb10de25 100644 --- a/core/fpdfdoc/cpvt_lineinfo.h +++ b/core/fpdfdoc/cpvt_lineinfo.h @@ -9,16 +9,9 @@ #include "core/fxcrt/fx_system.h" -struct CPVT_LineInfo { - CPVT_LineInfo() - : nTotalWord(0), - nBeginWordIndex(-1), - nEndWordIndex(-1), - fLineX(0.0f), - fLineY(0.0f), - fLineWidth(0.0f), - fLineAscent(0.0f), - fLineDescent(0.0f) {} +class CPVT_LineInfo { + public: + CPVT_LineInfo(); int32_t nTotalWord; int32_t nBeginWordIndex; @@ -30,4 +23,14 @@ struct CPVT_LineInfo { FX_FLOAT fLineDescent; }; +inline CPVT_LineInfo::CPVT_LineInfo() + : nTotalWord(0), + nBeginWordIndex(-1), + nEndWordIndex(-1), + fLineX(0.0f), + fLineY(0.0f), + fLineWidth(0.0f), + fLineAscent(0.0f), + fLineDescent(0.0f) {} + #endif // CORE_FPDFDOC_CPVT_LINEINFO_H_ diff --git a/core/fpdfdoc/cpvt_word.h b/core/fpdfdoc/cpvt_word.h index 92a4ce1e9..540f0416a 100644 --- a/core/fpdfdoc/cpvt_word.h +++ b/core/fpdfdoc/cpvt_word.h @@ -11,13 +11,14 @@ #include "core/fpdfdoc/cpvt_wordprops.h" #include "core/fxcrt/fx_system.h" -struct CPVT_Word { +class CPVT_Word { + public: CPVT_Word(); uint16_t Word; int32_t nCharset; CPVT_WordPlace WordPlace; - CFX_FloatPoint ptWord; + CFX_PointF ptWord; FX_FLOAT fAscent; FX_FLOAT fDescent; FX_FLOAT fWidth; diff --git a/core/fpdfdoc/csection.cpp b/core/fpdfdoc/csection.cpp index 496450417..490ef1b23 100644 --- a/core/fpdfdoc/csection.cpp +++ b/core/fpdfdoc/csection.cpp @@ -146,7 +146,7 @@ void CSection::UpdateWordPlace(CPVT_WordPlace& place) const { } } -CPVT_WordPlace CSection::SearchWordPlace(const CFX_FloatPoint& point) const { +CPVT_WordPlace CSection::SearchWordPlace(const CFX_PointF& point) const { ASSERT(m_pVT); CPVT_WordPlace place = GetBeginWordPlace(); bool bUp = true; diff --git a/core/fpdfdoc/csection.h b/core/fpdfdoc/csection.h index 706f5b67b..a2ac43b10 100644 --- a/core/fpdfdoc/csection.h +++ b/core/fpdfdoc/csection.h @@ -14,8 +14,7 @@ #include "core/fxcrt/fx_system.h" class CPDF_VariableText; - -struct CPVT_LineInfo; +class CPVT_LineInfo; struct CPVT_WordLine; struct CPVT_WordPlace; @@ -40,7 +39,7 @@ class CSection final { CPVT_WordPlace GetPrevWordPlace(const CPVT_WordPlace& place) const; CPVT_WordPlace GetNextWordPlace(const CPVT_WordPlace& place) const; void UpdateWordPlace(CPVT_WordPlace& place) const; - CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const; + CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; CPVT_WordPlace SearchWordPlace(FX_FLOAT fx, const CPVT_WordPlace& lineplace) const; CPVT_WordPlace SearchWordPlace(FX_FLOAT fx, diff --git a/core/fpdfdoc/doc_tagged.cpp b/core/fpdfdoc/doc_tagged.cpp index 39feaeef8..af5cf8593 100644 --- a/core/fpdfdoc/doc_tagged.cpp +++ b/core/fpdfdoc/doc_tagged.cpp @@ -32,6 +32,17 @@ bool IsTagged(const CPDF_Document* pDoc) { } // namespace +CPDF_StructKid::CPDF_StructKid() + : m_Type(Invalid), + m_pDict(nullptr), + m_PageObjNum(0), + m_RefObjNum(0), + m_ContentId(0) {} + +CPDF_StructKid::CPDF_StructKid(const CPDF_StructKid& that) = default; + +CPDF_StructKid::~CPDF_StructKid() {} + // static std::unique_ptr<IPDF_StructTree> IPDF_StructTree::LoadPage( const CPDF_Document* pDoc, @@ -39,27 +50,27 @@ std::unique_ptr<IPDF_StructTree> IPDF_StructTree::LoadPage( if (!IsTagged(pDoc)) return nullptr; - auto pTree = pdfium::MakeUnique<CPDF_StructTreeImpl>(pDoc); + auto pTree = pdfium::MakeUnique<CPDF_StructTree>(pDoc); pTree->LoadPageTree(pPageDict); return std::move(pTree); } -CPDF_StructTreeImpl::CPDF_StructTreeImpl(const CPDF_Document* pDoc) +CPDF_StructTree::CPDF_StructTree(const CPDF_Document* pDoc) : m_pTreeRoot(pDoc->GetRoot()->GetDictFor("StructTreeRoot")), m_pRoleMap(m_pTreeRoot ? m_pTreeRoot->GetDictFor("RoleMap") : nullptr), m_pPage(nullptr) {} -CPDF_StructTreeImpl::~CPDF_StructTreeImpl() {} +CPDF_StructTree::~CPDF_StructTree() {} -int CPDF_StructTreeImpl::CountTopElements() const { +int CPDF_StructTree::CountTopElements() const { return pdfium::CollectionSize<int>(m_Kids); } -IPDF_StructElement* CPDF_StructTreeImpl::GetTopElement(int i) const { +IPDF_StructElement* CPDF_StructTree::GetTopElement(int i) const { return m_Kids[i].Get(); } -void CPDF_StructTreeImpl::LoadPageTree(const CPDF_Dictionary* pPageDict) { +void CPDF_StructTree::LoadPageTree(const CPDF_Dictionary* pPageDict) { m_pPage = pPageDict; if (!m_pTreeRoot) return; @@ -91,54 +102,50 @@ void CPDF_StructTreeImpl::LoadPageTree(const CPDF_Dictionary* pPageDict) { if (!pParentArray) return; - std::map<CPDF_Dictionary*, CPDF_StructElementImpl*> element_map; + std::map<CPDF_Dictionary*, CFX_RetainPtr<CPDF_StructElement>> element_map; for (size_t i = 0; i < pParentArray->GetCount(); i++) { if (CPDF_Dictionary* pParent = pParentArray->GetDictAt(i)) - AddPageNode(pParent, element_map); + AddPageNode(pParent, &element_map); } } -CPDF_StructElementImpl* CPDF_StructTreeImpl::AddPageNode( +CFX_RetainPtr<CPDF_StructElement> CPDF_StructTree::AddPageNode( CPDF_Dictionary* pDict, - std::map<CPDF_Dictionary*, CPDF_StructElementImpl*>& map, + std::map<CPDF_Dictionary*, CFX_RetainPtr<CPDF_StructElement>>* map, int nLevel) { if (nLevel > nMaxRecursion) return nullptr; - auto it = map.find(pDict); - if (it != map.end()) + auto it = map->find(pDict); + if (it != map->end()) return it->second; - CPDF_StructElementImpl* pElement = - new CPDF_StructElementImpl(this, nullptr, pDict); - map[pDict] = pElement; + auto pElement = pdfium::MakeRetain<CPDF_StructElement>(this, nullptr, pDict); + (*map)[pDict] = pElement; CPDF_Dictionary* pParent = pDict->GetDictFor("P"); if (!pParent || pParent->GetStringFor("Type") == "StructTreeRoot") { - if (!AddTopLevelNode(pDict, pElement)) { - pElement->Release(); - map.erase(pDict); - } - } else { - CPDF_StructElementImpl* pParentElement = - AddPageNode(pParent, map, nLevel + 1); - bool bSave = false; - for (CPDF_StructKid& kid : pParentElement->m_Kids) { - if (kid.m_Type != CPDF_StructKid::Element) - continue; - if (kid.m_Element.m_pDict != pDict) - continue; - kid.m_Element.m_pElement = pElement->Retain(); + if (!AddTopLevelNode(pDict, pElement)) + map->erase(pDict); + return pElement; + } + + CFX_RetainPtr<CPDF_StructElement> pParentElement = + AddPageNode(pParent, map, nLevel + 1); + bool bSave = false; + for (CPDF_StructKid& kid : *pParentElement->GetKids()) { + if (kid.m_Type == CPDF_StructKid::Element && kid.m_pDict == pDict) { + kid.m_pElement = pElement; bSave = true; } - if (!bSave) { - pElement->Release(); - map.erase(pDict); - } } + if (!bSave) + map->erase(pDict); return pElement; } -bool CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, - CPDF_StructElementImpl* pElement) { + +bool CPDF_StructTree::AddTopLevelNode( + CPDF_Dictionary* pDict, + const CFX_RetainPtr<CPDF_StructElement>& pElement) { CPDF_Object* pObj = m_pTreeRoot->GetDirectObjectFor("K"); if (!pObj) return false; @@ -146,14 +153,14 @@ bool CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, if (pObj->IsDictionary()) { if (pObj->GetObjNum() != pDict->GetObjNum()) return false; - m_Kids[0].Reset(pElement); + m_Kids[0] = pElement; } if (CPDF_Array* pTopKids = pObj->AsArray()) { bool bSave = false; for (size_t i = 0; i < pTopKids->GetCount(); i++) { CPDF_Reference* pKidRef = ToReference(pTopKids->GetObjectAt(i)); if (pKidRef && pKidRef->GetRefObjNum() == pDict->GetObjNum()) { - m_Kids[i].Reset(pElement); + m_Kids[i] = pElement; bSave = true; } } @@ -163,11 +170,10 @@ bool CPDF_StructTreeImpl::AddTopLevelNode(CPDF_Dictionary* pDict, return true; } -CPDF_StructElementImpl::CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, - CPDF_StructElementImpl* pParent, - CPDF_Dictionary* pDict) - : m_RefCount(0), - m_pTree(pTree), +CPDF_StructElement::CPDF_StructElement(CPDF_StructTree* pTree, + CPDF_StructElement* pParent, + CPDF_Dictionary* pDict) + : m_pTree(pTree), m_pParent(pParent), m_pDict(pDict), m_Type(pDict->GetStringFor("S")) { @@ -179,47 +185,36 @@ CPDF_StructElementImpl::CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, LoadKids(pDict); } -IPDF_StructTree* CPDF_StructElementImpl::GetTree() const { +IPDF_StructTree* CPDF_StructElement::GetTree() const { return m_pTree; } -const CFX_ByteString& CPDF_StructElementImpl::GetType() const { +const CFX_ByteString& CPDF_StructElement::GetType() const { return m_Type; } -IPDF_StructElement* CPDF_StructElementImpl::GetParent() const { +IPDF_StructElement* CPDF_StructElement::GetParent() const { return m_pParent; } -CPDF_Dictionary* CPDF_StructElementImpl::GetDict() const { +CPDF_Dictionary* CPDF_StructElement::GetDict() const { return m_pDict; } -int CPDF_StructElementImpl::CountKids() const { +int CPDF_StructElement::CountKids() const { return pdfium::CollectionSize<int>(m_Kids); } -const CPDF_StructKid& CPDF_StructElementImpl::GetKid(int index) const { - return m_Kids[index]; -} +IPDF_StructElement* CPDF_StructElement::GetKidIfElement(int index) const { + if (m_Kids[index].m_Type != CPDF_StructKid::Element) + return nullptr; -CPDF_StructElementImpl::~CPDF_StructElementImpl() { - for (CPDF_StructKid& kid : m_Kids) { - if (kid.m_Type == CPDF_StructKid::Element && kid.m_Element.m_pElement) - static_cast<CPDF_StructElementImpl*>(kid.m_Element.m_pElement)->Release(); - } + return m_Kids[index].m_pElement.Get(); } -CPDF_StructElementImpl* CPDF_StructElementImpl::Retain() { - m_RefCount++; - return this; -} -void CPDF_StructElementImpl::Release() { - if (--m_RefCount < 1) { - delete this; - } -} -void CPDF_StructElementImpl::LoadKids(CPDF_Dictionary* pDict) { +CPDF_StructElement::~CPDF_StructElement() {} + +void CPDF_StructElement::LoadKids(CPDF_Dictionary* pDict) { CPDF_Object* pObj = pDict->GetObjectFor("Pg"); uint32_t PageObjNum = 0; if (CPDF_Reference* pRef = ToReference(pObj)) @@ -241,9 +236,9 @@ void CPDF_StructElementImpl::LoadKids(CPDF_Dictionary* pDict) { LoadKid(PageObjNum, pKids, &m_Kids[0]); } } -void CPDF_StructElementImpl::LoadKid(uint32_t PageObjNum, - CPDF_Object* pKidObj, - CPDF_StructKid* pKid) { +void CPDF_StructElement::LoadKid(uint32_t PageObjNum, + CPDF_Object* pKidObj, + CPDF_StructKid* pKid) { pKid->m_Type = CPDF_StructKid::Invalid; if (!pKidObj) return; @@ -253,8 +248,8 @@ void CPDF_StructElementImpl::LoadKid(uint32_t PageObjNum, return; } pKid->m_Type = CPDF_StructKid::PageContent; - pKid->m_PageContent.m_ContentId = pKidObj->GetInteger(); - pKid->m_PageContent.m_PageObjNum = PageObjNum; + pKid->m_ContentId = pKidObj->GetInteger(); + pKid->m_PageObjNum = PageObjNum; return; } @@ -271,32 +266,26 @@ void CPDF_StructElementImpl::LoadKid(uint32_t PageObjNum, return; } pKid->m_Type = CPDF_StructKid::StreamContent; - if (CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Stm"))) { - pKid->m_StreamContent.m_RefObjNum = pRef->GetRefObjNum(); - } else { - pKid->m_StreamContent.m_RefObjNum = 0; - } - pKid->m_StreamContent.m_PageObjNum = PageObjNum; - pKid->m_StreamContent.m_ContentId = pKidDict->GetIntegerFor("MCID"); + CPDF_Reference* pRef = ToReference(pKidDict->GetObjectFor("Stm")); + pKid->m_RefObjNum = pRef ? pRef->GetRefObjNum() : 0; + pKid->m_PageObjNum = PageObjNum; + pKid->m_ContentId = pKidDict->GetIntegerFor("MCID"); } else if (type == "OBJR") { if (m_pTree->m_pPage && m_pTree->m_pPage->GetObjNum() != PageObjNum) { return; } pKid->m_Type = CPDF_StructKid::Object; - if (CPDF_Reference* pObj = ToReference(pKidDict->GetObjectFor("Obj"))) { - pKid->m_Object.m_RefObjNum = pObj->GetRefObjNum(); - } else { - pKid->m_Object.m_RefObjNum = 0; - } - pKid->m_Object.m_PageObjNum = PageObjNum; + CPDF_Reference* pObj = ToReference(pKidDict->GetObjectFor("Obj")); + pKid->m_RefObjNum = pObj ? pObj->GetRefObjNum() : 0; + pKid->m_PageObjNum = PageObjNum; } else { pKid->m_Type = CPDF_StructKid::Element; - pKid->m_Element.m_pDict = pKidDict; + pKid->m_pDict = pKidDict; if (!m_pTree->m_pPage) { - pKid->m_Element.m_pElement = - new CPDF_StructElementImpl(m_pTree, this, pKidDict); + pKid->m_pElement = + pdfium::MakeRetain<CPDF_StructElement>(m_pTree, this, pKidDict); } else { - pKid->m_Element.m_pElement = nullptr; + pKid->m_pElement = nullptr; } } } @@ -325,10 +314,10 @@ static CPDF_Dictionary* FindAttrDict(CPDF_Object* pAttrs, return pDict; return nullptr; } -CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, - const CFX_ByteStringC& name, - bool bInheritable, - FX_FLOAT fLevel) { +CPDF_Object* CPDF_StructElement::GetAttr(const CFX_ByteStringC& owner, + const CFX_ByteStringC& name, + bool bInheritable, + FX_FLOAT fLevel) { if (fLevel > nMaxRecursion) { return nullptr; } @@ -375,10 +364,10 @@ CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, return pClassDict->GetDirectObjectFor(CFX_ByteString(name)); return nullptr; } -CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, - const CFX_ByteStringC& name, - bool bInheritable, - int subindex) { +CPDF_Object* CPDF_StructElement::GetAttr(const CFX_ByteStringC& owner, + const CFX_ByteStringC& name, + bool bInheritable, + int subindex) { CPDF_Object* pAttr = GetAttr(owner, name, bInheritable); CPDF_Array* pArray = ToArray(pAttr); if (!pArray || subindex == -1) @@ -388,23 +377,22 @@ CPDF_Object* CPDF_StructElementImpl::GetAttr(const CFX_ByteStringC& owner, return pAttr; return pArray->GetDirectObjectAt(subindex); } -CFX_ByteString CPDF_StructElementImpl::GetName( - const CFX_ByteStringC& owner, - const CFX_ByteStringC& name, - const CFX_ByteStringC& default_value, - bool bInheritable, - int subindex) { +CFX_ByteString CPDF_StructElement::GetName(const CFX_ByteStringC& owner, + const CFX_ByteStringC& name, + const CFX_ByteStringC& default_value, + bool bInheritable, + int subindex) { CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); if (ToName(pAttr)) return pAttr->GetString(); return CFX_ByteString(default_value); } -FX_ARGB CPDF_StructElementImpl::GetColor(const CFX_ByteStringC& owner, - const CFX_ByteStringC& name, - FX_ARGB default_value, - bool bInheritable, - int subindex) { +FX_ARGB CPDF_StructElement::GetColor(const CFX_ByteStringC& owner, + const CFX_ByteStringC& name, + FX_ARGB default_value, + bool bInheritable, + int subindex) { CPDF_Array* pArray = ToArray(GetAttr(owner, name, bInheritable, subindex)); if (!pArray) return default_value; @@ -412,19 +400,19 @@ FX_ARGB CPDF_StructElementImpl::GetColor(const CFX_ByteStringC& owner, ((int)(pArray->GetNumberAt(1) * 255) << 8) | (int)(pArray->GetNumberAt(2) * 255); } -FX_FLOAT CPDF_StructElementImpl::GetNumber(const CFX_ByteStringC& owner, - const CFX_ByteStringC& name, - FX_FLOAT default_value, - bool bInheritable, - int subindex) { - CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); - return ToNumber(pAttr) ? pAttr->GetNumber() : default_value; -} -int CPDF_StructElementImpl::GetInteger(const CFX_ByteStringC& owner, +FX_FLOAT CPDF_StructElement::GetNumber(const CFX_ByteStringC& owner, const CFX_ByteStringC& name, - int default_value, + FX_FLOAT default_value, bool bInheritable, int subindex) { CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); + return ToNumber(pAttr) ? pAttr->GetNumber() : default_value; +} +int CPDF_StructElement::GetInteger(const CFX_ByteStringC& owner, + const CFX_ByteStringC& name, + int default_value, + bool bInheritable, + int subindex) { + CPDF_Object* pAttr = GetAttr(owner, name, bInheritable, subindex); return ToNumber(pAttr) ? pAttr->GetInteger() : default_value; } diff --git a/core/fpdfdoc/fpdf_tagged.h b/core/fpdfdoc/fpdf_tagged.h index aa697ca24..fbbb49f85 100644 --- a/core/fpdfdoc/fpdf_tagged.h +++ b/core/fpdfdoc/fpdf_tagged.h @@ -21,46 +21,23 @@ class IPDF_StructTree { const CPDF_Document* pDoc, const CPDF_Dictionary* pPageDict); - virtual ~IPDF_StructTree() {} virtual int CountTopElements() const = 0; virtual IPDF_StructElement* GetTopElement(int i) const = 0; -}; -struct CPDF_StructKid { - enum { Invalid, Element, PageContent, StreamContent, Object } m_Type; - - union { - struct { - IPDF_StructElement* m_pElement; - CPDF_Dictionary* m_pDict; - } m_Element; - struct { - uint32_t m_PageObjNum; - uint32_t m_ContentId; - } m_PageContent; - struct { - uint32_t m_PageObjNum; - uint32_t m_ContentId; - uint32_t m_RefObjNum; - } m_StreamContent; - struct { - uint32_t m_PageObjNum; - uint32_t m_RefObjNum; - } m_Object; - }; + protected: + friend std::default_delete<IPDF_StructTree>; + virtual ~IPDF_StructTree() {} }; class IPDF_StructElement { public: - virtual ~IPDF_StructElement() {} - virtual IPDF_StructTree* GetTree() const = 0; virtual const CFX_ByteString& GetType() const = 0; virtual IPDF_StructElement* GetParent() const = 0; virtual CPDF_Dictionary* GetDict() const = 0; virtual int CountKids() const = 0; - virtual const CPDF_StructKid& GetKid(int index) const = 0; + virtual IPDF_StructElement* GetKidIfElement(int index) const = 0; virtual CPDF_Object* GetAttr(const CFX_ByteStringC& owner, const CFX_ByteStringC& name, @@ -90,6 +67,9 @@ class IPDF_StructElement { int default_value, bool bInheritable = false, int subindex = -1) = 0; + + protected: + virtual ~IPDF_StructElement() {} }; #endif // CORE_FPDFDOC_FPDF_TAGGED_H_ diff --git a/core/fpdfdoc/tagged_int.h b/core/fpdfdoc/tagged_int.h index 03f1c40ad..ce246023d 100644 --- a/core/fpdfdoc/tagged_int.h +++ b/core/fpdfdoc/tagged_int.h @@ -15,39 +15,53 @@ #include "core/fxcrt/cfx_retain_ptr.h" #include "third_party/base/stl_util.h" -class CPDF_StructElementImpl; +class CPDF_StructElement; -class CPDF_StructTreeImpl final : public IPDF_StructTree { +struct CPDF_StructKid { + CPDF_StructKid(); + CPDF_StructKid(const CPDF_StructKid& that); + ~CPDF_StructKid(); + + enum { Invalid, Element, PageContent, StreamContent, Object } m_Type; + + CFX_RetainPtr<CPDF_StructElement> m_pElement; // For Element. + CPDF_Dictionary* m_pDict; // For Element. + uint32_t m_PageObjNum; // For PageContent, StreamContent, Object. + uint32_t m_RefObjNum; // For StreamContent, Object. + uint32_t m_ContentId; // For PageContent, StreamContent. +}; + +class CPDF_StructTree final : public IPDF_StructTree { public: - explicit CPDF_StructTreeImpl(const CPDF_Document* pDoc); - ~CPDF_StructTreeImpl() override; + explicit CPDF_StructTree(const CPDF_Document* pDoc); + ~CPDF_StructTree() override; // IPDF_StructTree: int CountTopElements() const override; IPDF_StructElement* GetTopElement(int i) const override; void LoadPageTree(const CPDF_Dictionary* pPageDict); - CPDF_StructElementImpl* AddPageNode( + CFX_RetainPtr<CPDF_StructElement> AddPageNode( CPDF_Dictionary* pElement, - std::map<CPDF_Dictionary*, CPDF_StructElementImpl*>& map, + std::map<CPDF_Dictionary*, CFX_RetainPtr<CPDF_StructElement>>* map, int nLevel = 0); bool AddTopLevelNode(CPDF_Dictionary* pDict, - CPDF_StructElementImpl* pElement); + const CFX_RetainPtr<CPDF_StructElement>& pElement); protected: const CPDF_Dictionary* const m_pTreeRoot; const CPDF_Dictionary* const m_pRoleMap; const CPDF_Dictionary* m_pPage; - std::vector<CFX_RetainPtr<CPDF_StructElementImpl>> m_Kids; + std::vector<CFX_RetainPtr<CPDF_StructElement>> m_Kids; - friend class CPDF_StructElementImpl; + friend class CPDF_StructElement; }; -class CPDF_StructElementImpl final : public IPDF_StructElement { +class CPDF_StructElement final : public CFX_Retainable, + public IPDF_StructElement { public: - CPDF_StructElementImpl(CPDF_StructTreeImpl* pTree, - CPDF_StructElementImpl* pParent, - CPDF_Dictionary* pDict); + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); // IPDF_StructElement IPDF_StructTree* GetTree() const override; @@ -55,7 +69,7 @@ class CPDF_StructElementImpl final : public IPDF_StructElement { IPDF_StructElement* GetParent() const override; CPDF_Dictionary* GetDict() const override; int CountKids() const override; - const CPDF_StructKid& GetKid(int index) const override; + IPDF_StructElement* GetKidIfElement(int index) const override; CPDF_Object* GetAttr(const CFX_ByteStringC& owner, const CFX_ByteStringC& name, bool bInheritable = false, @@ -81,26 +95,25 @@ class CPDF_StructElementImpl final : public IPDF_StructElement { bool bInheritable = false, int subindex = -1) override; + std::vector<CPDF_StructKid>* GetKids() { return &m_Kids; } void LoadKids(CPDF_Dictionary* pDict); void LoadKid(uint32_t PageObjNum, CPDF_Object* pObj, CPDF_StructKid* pKid); CPDF_Object* GetAttr(const CFX_ByteStringC& owner, const CFX_ByteStringC& name, bool bInheritable, int subindex); - CPDF_StructElementImpl* Retain(); - void Release(); - protected: - ~CPDF_StructElementImpl() override; + private: + CPDF_StructElement(CPDF_StructTree* pTree, + CPDF_StructElement* pParent, + CPDF_Dictionary* pDict); + ~CPDF_StructElement() override; - int m_RefCount; - CPDF_StructTreeImpl* const m_pTree; - CPDF_StructElementImpl* const m_pParent; + CPDF_StructTree* const m_pTree; + CPDF_StructElement* const m_pParent; CPDF_Dictionary* const m_pDict; CFX_ByteString m_Type; std::vector<CPDF_StructKid> m_Kids; - - friend class CPDF_StructTreeImpl; }; #endif // CORE_FPDFDOC_TAGGED_INT_H_ diff --git a/core/fpdftext/cpdf_textpage.cpp b/core/fpdftext/cpdf_textpage.cpp index 9cde4f502..73a1a7e88 100644 --- a/core/fpdftext/cpdf_textpage.cpp +++ b/core/fpdftext/cpdf_textpage.cpp @@ -55,7 +55,7 @@ FX_FLOAT CalculateBaseSpace(const CPDF_TextObject* pTextObj, pTextObj->GetItemInfo(i, &item); if (item.m_CharCode == static_cast<uint32_t>(-1)) { FX_FLOAT fontsize_h = pTextObj->m_TextState.GetFontSizeH(); - FX_FLOAT kerning = -fontsize_h * item.m_OriginX / 1000; + FX_FLOAT kerning = -fontsize_h * item.m_Origin.x / 1000; baseSpace = std::min(baseSpace, kerning + spacing); bAllChar = false; } @@ -108,6 +108,22 @@ float MaskPercentFilled(const std::vector<bool>& mask, } // namespace +FPDF_CHAR_INFO::FPDF_CHAR_INFO() + : m_Unicode(0), + m_Charcode(0), + m_Flag(0), + m_FontSize(0), + m_pTextObj(nullptr) {} + +FPDF_CHAR_INFO::~FPDF_CHAR_INFO() {} + +PAGECHAR_INFO::PAGECHAR_INFO() + : m_Index(0), m_CharCode(0), m_Unicode(0), m_Flag(0), m_pTextObj(nullptr) {} + +PAGECHAR_INFO::PAGECHAR_INFO(const PAGECHAR_INFO&) = default; + +PAGECHAR_INFO::~PAGECHAR_INFO() {} + CPDF_TextPage::CPDF_TextPage(const CPDF_Page* pPage, FPDFText_Direction flags) : m_pPage(pPage), m_parserflag(flags), @@ -115,8 +131,9 @@ CPDF_TextPage::CPDF_TextPage(const CPDF_Page* pPage, FPDFText_Direction flags) m_bIsParsed(false), m_TextlineDir(TextOrientation::Unknown) { m_TextBuf.EstimateSize(0, 10240); - pPage->GetDisplayMatrix(m_DisplayMatrix, 0, 0, (int)pPage->GetPageWidth(), - (int)pPage->GetPageHeight(), 0); + m_DisplayMatrix = + pPage->GetDisplayMatrix(0, 0, static_cast<int>(pPage->GetPageWidth()), + static_cast<int>(pPage->GetPageHeight()), 0); } CPDF_TextPage::~CPDF_TextPage() {} @@ -238,32 +255,33 @@ std::vector<CFX_FloatRect> CPDF_TextPage::GetRectArray(int start, bFlagNewRect = true; } if (bFlagNewRect) { - FX_FLOAT orgX = info_curchar.m_OriginX, orgY = info_curchar.m_OriginY; - CFX_Matrix matrix, matrix_reverse; - info_curchar.m_pTextObj->GetTextMatrix(&matrix); + CFX_Matrix matrix = info_curchar.m_pTextObj->GetTextMatrix(); matrix.Concat(info_curchar.m_Matrix); + + CFX_Matrix matrix_reverse; matrix_reverse.SetReverse(matrix); - matrix_reverse.Transform(orgX, orgY); + + CFX_PointF origin = matrix_reverse.Transform(info_curchar.m_Origin); rect.left = info_curchar.m_CharBox.left; rect.right = info_curchar.m_CharBox.right; if (pCurObj->GetFont()->GetTypeDescent()) { - rect.bottom = orgY + + rect.bottom = origin.y + pCurObj->GetFont()->GetTypeDescent() * pCurObj->GetFontSize() / 1000; - FX_FLOAT xPosTemp = orgX; - matrix.Transform(xPosTemp, rect.bottom); + + rect.bottom = matrix.Transform(CFX_PointF(origin.x, rect.bottom)).y; } else { rect.bottom = info_curchar.m_CharBox.bottom; } if (pCurObj->GetFont()->GetTypeAscent()) { rect.top = - orgY + + origin.y + pCurObj->GetFont()->GetTypeAscent() * pCurObj->GetFontSize() / 1000; FX_FLOAT xPosTemp = - orgX + + origin.x + GetCharWidth(info_curchar.m_CharCode, pCurObj->GetFont()) * pCurObj->GetFontSize() / 1000; - matrix.Transform(xPosTemp, rect.top); + rect.top = matrix.Transform(CFX_PointF(xPosTemp, rect.top)).y; } else { rect.top = info_curchar.m_CharBox.top; } @@ -282,9 +300,8 @@ std::vector<CFX_FloatRect> CPDF_TextPage::GetRectArray(int start, return rectArray; } -int CPDF_TextPage::GetIndexAtPos(CFX_FloatPoint point, - FX_FLOAT xTolerance, - FX_FLOAT yTolerance) const { +int CPDF_TextPage::GetIndexAtPos(const CFX_PointF& point, + const CFX_SizeF& tolerance) const { if (!m_bIsParsed) return -3; @@ -295,16 +312,16 @@ int CPDF_TextPage::GetIndexAtPos(CFX_FloatPoint point, while (pos < pdfium::CollectionSize<int>(m_CharList)) { PAGECHAR_INFO charinfo = m_CharList[pos]; CFX_FloatRect charrect = charinfo.m_CharBox; - if (charrect.Contains(point.x, point.y)) + if (charrect.Contains(point)) break; - if (xTolerance > 0 || yTolerance > 0) { + if (tolerance.width > 0 || tolerance.height > 0) { CFX_FloatRect charRectExt; charrect.Normalize(); - charRectExt.left = charrect.left - xTolerance / 2; - charRectExt.right = charrect.right + xTolerance / 2; - charRectExt.top = charrect.top + yTolerance / 2; - charRectExt.bottom = charrect.bottom - yTolerance / 2; - if (charRectExt.Contains(point.x, point.y)) { + charRectExt.left = charrect.left - tolerance.width / 2; + charRectExt.right = charrect.right + tolerance.width / 2; + charRectExt.top = charrect.top + tolerance.height / 2; + charRectExt.bottom = charrect.bottom - tolerance.height / 2; + if (charRectExt.Contains(point)) { double curXdif, curYdif; curXdif = FXSYS_fabs(point.x - charrect.left) < FXSYS_fabs(point.x - charrect.right) @@ -336,9 +353,9 @@ CFX_WideString CPDF_TextPage::GetTextByRect(const CFX_FloatRect& rect) const { CFX_WideString strText; for (const auto& charinfo : m_CharList) { if (IsRectIntersect(rect, charinfo.m_CharBox)) { - if (FXSYS_fabs(posy - charinfo.m_OriginY) > 0 && !IsContainPreChar && + if (FXSYS_fabs(posy - charinfo.m_Origin.y) > 0 && !IsContainPreChar && IsAddLineFeed) { - posy = charinfo.m_OriginY; + posy = charinfo.m_Origin.y; if (!strText.IsEmpty()) strText += L"\r\n"; } @@ -360,14 +377,6 @@ CFX_WideString CPDF_TextPage::GetTextByRect(const CFX_FloatRect& rect) const { return strText; } -int CPDF_TextPage::GetIndexAtPos(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT xTolerance, - FX_FLOAT yTolerance) const { - CFX_FloatPoint point(x, y); - return GetIndexAtPos(point, xTolerance, yTolerance); -} - void CPDF_TextPage::GetCharInfo(int index, FPDF_CHAR_INFO* info) const { if (!m_bIsParsed) return; @@ -377,8 +386,7 @@ void CPDF_TextPage::GetCharInfo(int index, FPDF_CHAR_INFO* info) const { const PAGECHAR_INFO& charinfo = m_CharList[index]; info->m_Charcode = charinfo.m_CharCode; - info->m_OriginX = charinfo.m_OriginX; - info->m_OriginY = charinfo.m_OriginY; + info->m_Origin = charinfo.m_Origin; info->m_Unicode = charinfo.m_Unicode; info->m_Flag = charinfo.m_Flag; info->m_CharBox = charinfo.m_CharBox; @@ -736,10 +744,9 @@ void CPDF_TextPage::ProcessTextObject( const CFX_Matrix& formMatrix, const CPDF_PageObjectList* pObjList, CPDF_PageObjectList::const_iterator ObjPos) { - CFX_FloatRect re(pTextObj->m_Left, pTextObj->m_Bottom, pTextObj->m_Right, - pTextObj->m_Top); if (FXSYS_fabs(pTextObj->m_Right - pTextObj->m_Left) < 0.01f) return; + size_t count = m_LineObj.size(); PDFTEXT_Obj Obj; Obj.m_pTextObj = pTextObj; @@ -750,6 +757,7 @@ void CPDF_TextPage::ProcessTextObject( } if (IsSameAsPreTextObject(pTextObj, pObjList, ObjPos)) return; + PDFTEXT_Obj prev_Obj = m_LineObj[count - 1]; CPDF_TextObjectItem item; int nItem = prev_Obj.m_pTextObj->CountItems(); @@ -757,8 +765,8 @@ void CPDF_TextPage::ProcessTextObject( FX_FLOAT prev_width = GetCharWidth(item.m_CharCode, prev_Obj.m_pTextObj->GetFont()) * prev_Obj.m_pTextObj->GetFontSize() / 1000; - CFX_Matrix prev_matrix; - prev_Obj.m_pTextObj->GetTextMatrix(&prev_matrix); + + CFX_Matrix prev_matrix = prev_Obj.m_pTextObj->GetTextMatrix(); prev_width = FXSYS_fabs(prev_width); prev_matrix.Concat(prev_Obj.m_formMatrix); prev_width = prev_matrix.TransformDistance(prev_width); @@ -766,41 +774,37 @@ void CPDF_TextPage::ProcessTextObject( FX_FLOAT this_width = GetCharWidth(item.m_CharCode, pTextObj->GetFont()) * pTextObj->GetFontSize() / 1000; this_width = FXSYS_fabs(this_width); - CFX_Matrix this_matrix; - pTextObj->GetTextMatrix(&this_matrix); + + CFX_Matrix this_matrix = pTextObj->GetTextMatrix(); this_width = FXSYS_fabs(this_width); this_matrix.Concat(formMatrix); this_width = this_matrix.TransformDistance(this_width); + FX_FLOAT threshold = prev_width > this_width ? prev_width / 4 : this_width / 4; - FX_FLOAT prev_x = prev_Obj.m_pTextObj->GetPosX(), - prev_y = prev_Obj.m_pTextObj->GetPosY(); - prev_Obj.m_formMatrix.Transform(prev_x, prev_y); - m_DisplayMatrix.Transform(prev_x, prev_y); - FX_FLOAT this_x = pTextObj->GetPosX(), this_y = pTextObj->GetPosY(); - formMatrix.Transform(this_x, this_y); - m_DisplayMatrix.Transform(this_x, this_y); - if (FXSYS_fabs(this_y - prev_y) > threshold * 2) { + CFX_PointF prev_pos = m_DisplayMatrix.Transform( + prev_Obj.m_formMatrix.Transform(prev_Obj.m_pTextObj->GetPos())); + CFX_PointF this_pos = + m_DisplayMatrix.Transform(formMatrix.Transform(pTextObj->GetPos())); + if (FXSYS_fabs(this_pos.y - prev_pos.y) > threshold * 2) { for (size_t i = 0; i < count; i++) ProcessTextObject(m_LineObj[i]); m_LineObj.clear(); m_LineObj.push_back(Obj); return; } - size_t i; - for (i = count; i > 0; --i) { + + for (size_t i = count; i > 0; --i) { PDFTEXT_Obj prev_text_obj = m_LineObj[i - 1]; - FX_FLOAT Prev_x = prev_text_obj.m_pTextObj->GetPosX(), - Prev_y = prev_text_obj.m_pTextObj->GetPosY(); - prev_text_obj.m_formMatrix.Transform(Prev_x, Prev_y); - m_DisplayMatrix.Transform(Prev_x, Prev_y); - if (this_x >= Prev_x) { + CFX_PointF new_prev_pos = + m_DisplayMatrix.Transform(prev_text_obj.m_formMatrix.Transform( + prev_text_obj.m_pTextObj->GetPos())); + if (this_pos.x >= new_prev_pos.x) { m_LineObj.insert(m_LineObj.begin() + i, Obj); - break; + return; } } - if (i == 0) - m_LineObj.insert(m_LineObj.begin(), Obj); + m_LineObj.insert(m_LineObj.begin(), Obj); } FPDFText_MarkedContent CPDF_TextPage::PreMarkedContent(PDFTEXT_Obj Obj) { @@ -887,36 +891,24 @@ void CPDF_TextPage::ProcessMarkedContent(PDFTEXT_Obj Obj) { return; CPDF_Font* pFont = pTextObj->GetFont(); - CFX_Matrix formMatrix = Obj.m_formMatrix; - CFX_Matrix matrix; - pTextObj->GetTextMatrix(&matrix); - matrix.Concat(formMatrix); - FX_FLOAT fPosX = pTextObj->GetPosX(); - FX_FLOAT fPosY = pTextObj->GetPosY(); - int nCharInfoIndex = m_TextBuf.GetLength(); - CFX_FloatRect charBox; - charBox.top = pTextObj->m_Top; - charBox.left = pTextObj->m_Left; - charBox.right = pTextObj->m_Right; - charBox.bottom = pTextObj->m_Bottom; + CFX_Matrix matrix = pTextObj->GetTextMatrix(); + matrix.Concat(Obj.m_formMatrix); + for (FX_STRSIZE k = 0; k < nItems; k++) { FX_WCHAR wChar = actText.GetAt(k); if (wChar <= 0x80 && !isprint(wChar)) wChar = 0x20; if (wChar >= 0xFFFD) continue; + PAGECHAR_INFO charinfo; - charinfo.m_OriginX = fPosX; - charinfo.m_OriginY = fPosY; - charinfo.m_Index = nCharInfoIndex; + charinfo.m_Origin = pTextObj->GetPos(); + charinfo.m_Index = m_TextBuf.GetLength(); charinfo.m_Unicode = wChar; charinfo.m_CharCode = pFont->CharCodeFromUnicode(wChar); charinfo.m_Flag = FPDFTEXT_CHAR_PIECE; charinfo.m_pTextObj = pTextObj; - charinfo.m_CharBox.top = charBox.top; - charinfo.m_CharBox.left = charBox.left; - charinfo.m_CharBox.right = charBox.right; - charinfo.m_CharBox.bottom = charBox.bottom; + charinfo.m_CharBox = pTextObj->GetRect(); charinfo.m_Matrix = matrix; m_TempTextBuf.AppendChar(wChar); m_TempCharList.push_back(charinfo); @@ -974,9 +966,9 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { return; CFX_Matrix formMatrix = Obj.m_formMatrix; CPDF_Font* pFont = pTextObj->GetFont(); - CFX_Matrix matrix; - pTextObj->GetTextMatrix(&matrix); + CFX_Matrix matrix = pTextObj->GetTextMatrix(); matrix.Concat(formMatrix); + FPDFText_MarkedContent ePreMKC = PreMarkedContent(Obj); if (ePreMKC == FPDFText_MarkedContent::Done) { m_pPreTextObj = pTextObj; @@ -986,15 +978,11 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { GenerateCharacter result = GenerateCharacter::None; if (m_pPreTextObj) { result = ProcessInsertObject(pTextObj, formMatrix); - if (result == GenerateCharacter::LineBreak) { - m_CurlineRect = - CFX_FloatRect(Obj.m_pTextObj->m_Left, Obj.m_pTextObj->m_Bottom, - Obj.m_pTextObj->m_Right, Obj.m_pTextObj->m_Top); - } else { - m_CurlineRect.Union( - CFX_FloatRect(Obj.m_pTextObj->m_Left, Obj.m_pTextObj->m_Bottom, - Obj.m_pTextObj->m_Right, Obj.m_pTextObj->m_Top)); - } + if (result == GenerateCharacter::LineBreak) + m_CurlineRect = Obj.m_pTextObj->GetRect(); + else + m_CurlineRect.Union(Obj.m_pTextObj->GetRect()); + switch (result) { case GenerateCharacter::None: break; @@ -1041,10 +1029,9 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { break; } } else { - m_CurlineRect = - CFX_FloatRect(Obj.m_pTextObj->m_Left, Obj.m_pTextObj->m_Bottom, - Obj.m_pTextObj->m_Right, Obj.m_pTextObj->m_Top); + m_CurlineRect = Obj.m_pTextObj->GetRect(); } + if (ePreMKC == FPDFText_MarkedContent::Delay) { ProcessMarkedContent(Obj); m_pPreTextObj = pTextObj; @@ -1067,8 +1054,6 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { for (int i = 0; i < nItems; i++) { CPDF_TextObjectItem item; PAGECHAR_INFO charinfo; - charinfo.m_OriginX = 0; - charinfo.m_OriginY = 0; pTextObj->GetItemInfo(i, &item); if (item.m_CharCode == static_cast<uint32_t>(-1)) { CFX_WideString str = m_TempTextBuf.MakeString(); @@ -1078,7 +1063,7 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { continue; FX_FLOAT fontsize_h = pTextObj->m_TextState.GetFontSizeH(); - spacing = -fontsize_h * item.m_OriginX / 1000; + spacing = -fontsize_h * item.m_Origin.x / 1000; continue; } FX_FLOAT charSpace = pTextObj->m_TextState.GetCharSpace(); @@ -1114,11 +1099,10 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { m_TempTextBuf.AppendChar(TEXT_SPACE_CHAR); charinfo.m_CharCode = CPDF_Font::kInvalidCharCode; charinfo.m_Matrix = formMatrix; - matrix.Transform(item.m_OriginX, item.m_OriginY, charinfo.m_OriginX, - charinfo.m_OriginY); + charinfo.m_Origin = matrix.Transform(item.m_Origin); charinfo.m_CharBox = - CFX_FloatRect(charinfo.m_OriginX, charinfo.m_OriginY, - charinfo.m_OriginX, charinfo.m_OriginY); + CFX_FloatRect(charinfo.m_Origin.x, charinfo.m_Origin.y, + charinfo.m_Origin.x, charinfo.m_Origin.y); m_TempCharList.push_back(charinfo); } if (item.m_CharCode == CPDF_Font::kInvalidCharCode) @@ -1137,20 +1121,20 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { charinfo.m_Flag = FPDFTEXT_CHAR_UNUNICODE; else charinfo.m_Flag = FPDFTEXT_CHAR_NORMAL; + charinfo.m_pTextObj = pTextObj; - charinfo.m_OriginX = 0, charinfo.m_OriginY = 0; - matrix.Transform(item.m_OriginX, item.m_OriginY, charinfo.m_OriginX, - charinfo.m_OriginY); + charinfo.m_Origin = matrix.Transform(item.m_Origin); + FX_RECT rect = charinfo.m_pTextObj->GetFont()->GetCharBBox(charinfo.m_CharCode); charinfo.m_CharBox.top = - rect.top * pTextObj->GetFontSize() / 1000 + item.m_OriginY; + rect.top * pTextObj->GetFontSize() / 1000 + item.m_Origin.y; charinfo.m_CharBox.left = - rect.left * pTextObj->GetFontSize() / 1000 + item.m_OriginX; + rect.left * pTextObj->GetFontSize() / 1000 + item.m_Origin.x; charinfo.m_CharBox.right = - rect.right * pTextObj->GetFontSize() / 1000 + item.m_OriginX; + rect.right * pTextObj->GetFontSize() / 1000 + item.m_Origin.x; charinfo.m_CharBox.bottom = - rect.bottom * pTextObj->GetFontSize() / 1000 + item.m_OriginY; + rect.bottom * pTextObj->GetFontSize() / 1000 + item.m_Origin.y; if (fabsf(charinfo.m_CharBox.top - charinfo.m_CharBox.bottom) < 0.01f) { charinfo.m_CharBox.top = charinfo.m_CharBox.bottom + pTextObj->GetFontSize(); @@ -1176,10 +1160,10 @@ void CPDF_TextPage::ProcessTextObject(PDFTEXT_Obj Obj) { for (int n = pdfium::CollectionSize<int>(m_TempCharList); n > pdfium::CollectionSize<int>(m_TempCharList) - count; n--) { const PAGECHAR_INFO& charinfo1 = m_TempCharList[n - 1]; + CFX_PointF diff = charinfo1.m_Origin - charinfo.m_Origin; if (charinfo1.m_CharCode == charinfo.m_CharCode && charinfo1.m_pTextObj->GetFont() == charinfo.m_pTextObj->GetFont() && - FXSYS_fabs(charinfo1.m_OriginX - charinfo.m_OriginX) < threshold && - FXSYS_fabs(charinfo1.m_OriginY - charinfo.m_OriginY) < threshold) { + FXSYS_fabs(diff.x) < threshold && FXSYS_fabs(diff.y) < threshold) { bDel = true; break; } @@ -1218,12 +1202,13 @@ CPDF_TextPage::TextOrientation CPDF_TextPage::GetTextObjectWritingMode( CPDF_TextObjectItem first, last; pTextObj->GetCharInfo(0, &first); pTextObj->GetCharInfo(nChars - 1, &last); - CFX_Matrix textMatrix; - pTextObj->GetTextMatrix(&textMatrix); - textMatrix.TransformPoint(first.m_OriginX, first.m_OriginY); - textMatrix.TransformPoint(last.m_OriginX, last.m_OriginY); - FX_FLOAT dX = FXSYS_fabs(last.m_OriginX - first.m_OriginX); - FX_FLOAT dY = FXSYS_fabs(last.m_OriginY - first.m_OriginY); + + CFX_Matrix textMatrix = pTextObj->GetTextMatrix(); + first.m_Origin = textMatrix.Transform(first.m_Origin); + last.m_Origin = textMatrix.Transform(last.m_Origin); + + FX_FLOAT dX = FXSYS_fabs(last.m_Origin.x - first.m_Origin.x); + FX_FLOAT dY = FXSYS_fabs(last.m_Origin.y - first.m_Origin.y); if (dX <= 0.0001f && dY <= 0.0001f) return TextOrientation::Unknown; @@ -1280,11 +1265,10 @@ CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject( if (WritingMode == TextOrientation::Unknown) WritingMode = GetTextObjectWritingMode(m_pPreTextObj); - CFX_FloatRect this_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, - pObj->m_Top); - CFX_FloatRect prev_rect(m_pPreTextObj->m_Left, m_pPreTextObj->m_Bottom, - m_pPreTextObj->m_Right, m_pPreTextObj->m_Top); - CPDF_TextObjectItem PrevItem, item; + CFX_FloatRect this_rect = pObj->GetRect(); + CFX_FloatRect prev_rect = m_pPreTextObj->GetRect(); + CPDF_TextObjectItem PrevItem; + CPDF_TextObjectItem item; int nItem = m_pPreTextObj->CountItems(); m_pPreTextObj->GetItemInfo(nItem - 1, &PrevItem); pObj->GetItemInfo(0, &item); @@ -1318,7 +1302,8 @@ CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject( } } } - FX_FLOAT last_pos = PrevItem.m_OriginX; + + FX_FLOAT last_pos = PrevItem.m_Origin.x; int nLastWidth = GetCharWidth(PrevItem.m_CharCode, m_pPreTextObj->GetFont()); FX_FLOAT last_width = nLastWidth * m_pPreTextObj->GetFontSize() / 1000; last_width = FXSYS_fabs(last_width); @@ -1327,47 +1312,45 @@ CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject( this_width = FXSYS_fabs(this_width); FX_FLOAT threshold = last_width > this_width ? last_width / 4 : this_width / 4; - CFX_Matrix prev_matrix, prev_reverse; - m_pPreTextObj->GetTextMatrix(&prev_matrix); + + CFX_Matrix prev_matrix = m_pPreTextObj->GetTextMatrix(); prev_matrix.Concat(m_perMatrix); + + CFX_Matrix prev_reverse; prev_reverse.SetReverse(prev_matrix); - FX_FLOAT x = pObj->GetPosX(); - FX_FLOAT y = pObj->GetPosY(); - formMatrix.Transform(x, y); - prev_reverse.Transform(x, y); + + CFX_PointF pos = prev_reverse.Transform(formMatrix.Transform(pObj->GetPos())); if (last_width < this_width) threshold = prev_reverse.TransformDistance(threshold); + bool bNewline = false; if (WritingMode == TextOrientation::Horizontal) { CFX_FloatRect rect1(m_pPreTextObj->m_Left, pObj->m_Bottom, m_pPreTextObj->m_Right, pObj->m_Top); - CFX_FloatRect rect2(m_pPreTextObj->m_Left, m_pPreTextObj->m_Bottom, - m_pPreTextObj->m_Right, m_pPreTextObj->m_Top); + CFX_FloatRect rect2 = m_pPreTextObj->GetRect(); CFX_FloatRect rect3 = rect1; rect1.Intersect(rect2); if ((rect1.IsEmpty() && rect2.Height() > 5 && rect3.Height() > 5) || - ((y > threshold * 2 || y < threshold * -3) && - (FXSYS_fabs(y) < 1 ? FXSYS_fabs(x) < FXSYS_fabs(y) : true))) { + ((pos.y > threshold * 2 || pos.y < threshold * -3) && + (FXSYS_fabs(pos.y) < 1 ? FXSYS_fabs(pos.x) < FXSYS_fabs(pos.y) + : true))) { bNewline = true; if (nItem > 1) { CPDF_TextObjectItem tempItem; m_pPreTextObj->GetItemInfo(0, &tempItem); - CFX_Matrix m; - m_pPreTextObj->GetTextMatrix(&m); - if (PrevItem.m_OriginX > tempItem.m_OriginX && + CFX_Matrix m = m_pPreTextObj->GetTextMatrix(); + if (PrevItem.m_Origin.x > tempItem.m_Origin.x && m_DisplayMatrix.a > 0.9 && m_DisplayMatrix.b < 0.1 && m_DisplayMatrix.c < 0.1 && m_DisplayMatrix.d < -0.9 && m.b < 0.1 && m.c < 0.1) { CFX_FloatRect re(0, m_pPreTextObj->m_Bottom, 1000, m_pPreTextObj->m_Top); - if (re.Contains(pObj->GetPosX(), pObj->GetPosY())) { + if (re.Contains(pObj->GetPos())) { bNewline = false; } else { CFX_FloatRect rect(0, pObj->m_Bottom, 1000, pObj->m_Top); - if (rect.Contains(m_pPreTextObj->GetPosX(), - m_pPreTextObj->GetPosY())) { + if (rect.Contains(m_pPreTextObj->GetPos())) bNewline = false; - } } } } @@ -1386,9 +1369,9 @@ CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject( CFX_WideString PrevStr = m_pPreTextObj->GetFont()->UnicodeFromCharCode(PrevItem.m_CharCode); FX_WCHAR preChar = PrevStr.GetAt(PrevStr.GetLength() - 1); - CFX_Matrix matrix; - pObj->GetTextMatrix(&matrix); + CFX_Matrix matrix = pObj->GetTextMatrix(); matrix.Concat(formMatrix); + threshold = (FX_FLOAT)(nLastWidth > nThisWidth ? nLastWidth : nThisWidth); threshold = threshold > 400 ? (threshold < 700 @@ -1407,17 +1390,17 @@ CPDF_TextPage::GenerateCharacter CPDF_TextPage::ProcessInsertObject( (threshold < 1.39001 && threshold > 1.38999)) { threshold *= 1.5; } - if (FXSYS_fabs(last_pos + last_width - x) > threshold && curChar != L' ' && - preChar != L' ') { + if (FXSYS_fabs(last_pos + last_width - pos.x) > threshold && + curChar != L' ' && preChar != L' ') { if (curChar != L' ' && preChar != L' ') { - if ((x - last_pos - last_width) > threshold || - (last_pos - x - last_width) > threshold) { + if ((pos.x - last_pos - last_width) > threshold || + (last_pos - pos.x - last_width) > threshold) { return GenerateCharacter::Space; } - if (x < 0 && (last_pos - x - last_width) > threshold) + if (pos.x < 0 && (last_pos - pos.x - last_width) > threshold) return GenerateCharacter::Space; - if ((x - last_pos - last_width) > this_width || - (x - last_pos - this_width) > last_width) { + if ((pos.x - last_pos - last_width) > this_width || + (pos.x - last_pos - this_width) > last_width) { return GenerateCharacter::Space; } } @@ -1429,10 +1412,9 @@ bool CPDF_TextPage::IsSameTextObject(CPDF_TextObject* pTextObj1, CPDF_TextObject* pTextObj2) { if (!pTextObj1 || !pTextObj2) return false; - CFX_FloatRect rcPreObj(pTextObj2->m_Left, pTextObj2->m_Bottom, - pTextObj2->m_Right, pTextObj2->m_Top); - CFX_FloatRect rcCurObj(pTextObj1->m_Left, pTextObj1->m_Bottom, - pTextObj1->m_Right, pTextObj1->m_Top); + + CFX_FloatRect rcPreObj = pTextObj2->GetRect(); + CFX_FloatRect rcCurObj = pTextObj1->GetRect(); if (rcPreObj.IsEmpty() && rcCurObj.IsEmpty()) { FX_FLOAT dbXdif = FXSYS_fabs(rcPreObj.left - rcCurObj.left); size_t nCount = m_CharList.size(); @@ -1462,21 +1444,22 @@ bool CPDF_TextPage::IsSameTextObject(CPDF_TextObject* pTextObj1, if (!nPreCount) return true; - CPDF_TextObjectItem itemPer = {0, 0.0f, 0.0f}; - CPDF_TextObjectItem itemCur = {0, 0.0f, 0.0f}; + CPDF_TextObjectItem itemPer; + CPDF_TextObjectItem itemCur; for (int i = 0; i < nPreCount; i++) { pTextObj2->GetItemInfo(i, &itemPer); pTextObj1->GetItemInfo(i, &itemCur); if (itemCur.m_CharCode != itemPer.m_CharCode) return false; } - if (FXSYS_fabs(pTextObj1->GetPosX() - pTextObj2->GetPosX()) > - GetCharWidth(itemPer.m_CharCode, pTextObj2->GetFont()) * - pTextObj2->GetFontSize() / 1000 * 0.9 || - FXSYS_fabs(pTextObj1->GetPosY() - pTextObj2->GetPosY()) > - std::max(std::max(rcPreObj.Height(), rcPreObj.Width()), - pTextObj2->GetFontSize()) / - 8) { + + CFX_PointF diff = pTextObj1->GetPos() - pTextObj2->GetPos(); + FX_FLOAT font_size = pTextObj2->GetFontSize(); + FX_FLOAT char_size = GetCharWidth(itemPer.m_CharCode, pTextObj2->GetFont()); + FX_FLOAT max_pre_size = + std::max(std::max(rcPreObj.Height(), rcPreObj.Width()), font_size); + if (FXSYS_fabs(diff.x) > char_size * font_size / 1000 * 0.9 || + FXSYS_fabs(diff.y) > max_pre_size / 8) { return false; } return true; @@ -1507,11 +1490,13 @@ bool CPDF_TextPage::GenerateCharInfo(FX_WCHAR unicode, PAGECHAR_INFO& info) { preChar = &m_CharList.back(); else return false; + info.m_Index = m_TextBuf.GetLength(); info.m_Unicode = unicode; info.m_pTextObj = nullptr; info.m_CharCode = CPDF_Font::kInvalidCharCode; info.m_Flag = FPDFTEXT_CHAR_GENERATED; + int preWidth = 0; if (preChar->m_pTextObj && preChar->m_CharCode != -1) { preWidth = @@ -1523,10 +1508,10 @@ bool CPDF_TextPage::GenerateCharInfo(FX_WCHAR unicode, PAGECHAR_INFO& info) { if (!fFontSize) fFontSize = kDefaultFontSize; - info.m_OriginX = preChar->m_OriginX + preWidth * (fFontSize) / 1000; - info.m_OriginY = preChar->m_OriginY; - info.m_CharBox = CFX_FloatRect(info.m_OriginX, info.m_OriginY, info.m_OriginX, - info.m_OriginY); + info.m_Origin = CFX_PointF( + preChar->m_Origin.x + preWidth * (fFontSize) / 1000, preChar->m_Origin.y); + info.m_CharBox = CFX_FloatRect(info.m_Origin.x, info.m_Origin.y, + info.m_Origin.x, info.m_Origin.y); return true; } diff --git a/core/fpdftext/cpdf_textpage.h b/core/fpdftext/cpdf_textpage.h index 85ee7058b..91942d1be 100644 --- a/core/fpdftext/cpdf_textpage.h +++ b/core/fpdftext/cpdf_textpage.h @@ -44,13 +44,16 @@ enum class FPDFText_MarkedContent { Pass = 0, Done, Delay }; enum class FPDFText_Direction { Left = -1, Right = 1 }; -struct FPDF_CHAR_INFO { +class FPDF_CHAR_INFO { + public: + FPDF_CHAR_INFO(); + ~FPDF_CHAR_INFO(); + FX_WCHAR m_Unicode; FX_WCHAR m_Charcode; int32_t m_Flag; FX_FLOAT m_FontSize; - FX_FLOAT m_OriginX; - FX_FLOAT m_OriginY; + CFX_PointF m_Origin; CFX_FloatRect m_CharBox; CPDF_TextObject* m_pTextObj; CFX_Matrix m_Matrix; @@ -61,16 +64,20 @@ struct FPDF_SEGMENT { int m_nCount; }; -struct PAGECHAR_INFO { +class PAGECHAR_INFO { + public: + PAGECHAR_INFO(); + PAGECHAR_INFO(const PAGECHAR_INFO&); + ~PAGECHAR_INFO(); + + int m_Index; int m_CharCode; FX_WCHAR m_Unicode; - FX_FLOAT m_OriginX; - FX_FLOAT m_OriginY; int32_t m_Flag; + CFX_PointF m_Origin; CFX_FloatRect m_CharBox; CPDF_TextObject* m_pTextObj; CFX_Matrix m_Matrix; - int m_Index; }; struct PDFTEXT_Obj { @@ -91,13 +98,7 @@ class CPDF_TextPage { int CountChars() const; void GetCharInfo(int index, FPDF_CHAR_INFO* info) const; std::vector<CFX_FloatRect> GetRectArray(int start, int nCount) const; - int GetIndexAtPos(CFX_FloatPoint point, - FX_FLOAT xTolerance, - FX_FLOAT yTolerance) const; - int GetIndexAtPos(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT xTolerance, - FX_FLOAT yTolerance) const; + int GetIndexAtPos(const CFX_PointF& point, const CFX_SizeF& tolerance) const; CFX_WideString GetTextByRect(const CFX_FloatRect& rect) const; CFX_WideString GetPageText(int start = 0, int nCount = -1) const; int CountRects(int start, int nCount); diff --git a/core/fxcodec/codec/fx_codec_bmp.cpp b/core/fxcodec/codec/ccodec_bmpmodule.cpp index ae83d3f1e..9d6419950 100644 --- a/core/fxcodec/codec/fx_codec_bmp.cpp +++ b/core/fxcodec/codec/ccodec_bmpmodule.cpp @@ -4,14 +4,16 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +#include "core/fxcodec/codec/ccodec_bmpmodule.h" + #include "core/fxcodec/codec/codec_int.h" #include "core/fxcodec/fx_codec.h" #include "core/fxcodec/lbmp/fx_bmp.h" #include "core/fxge/fx_dib.h" + struct FXBMP_Context { bmp_decompress_struct_p bmp_ptr; void* parent_ptr; - void* child_ptr; void* (*m_AllocFunc)(unsigned int); void (*m_FreeFunc)(void*); @@ -34,16 +36,22 @@ static void bmp_read_scanline(bmp_decompress_struct_p bmp_ptr, uint8_t* row_buf) { FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; - pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf); + pModule->GetDelegate()->BmpReadScanline(row_num, row_buf); } static bool bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, uint32_t rcd_pos) { FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr; CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr; - return pModule->InputImagePositionBufCallback(p->child_ptr, rcd_pos); + return pModule->GetDelegate()->BmpInputImagePositionBuf(rcd_pos); } -FXBMP_Context* CCodec_BmpModule::Start(void* pModule) { +CCodec_BmpModule::CCodec_BmpModule() { + memset(m_szLastError, 0, sizeof(m_szLastError)); +} + +CCodec_BmpModule::~CCodec_BmpModule() {} + +FXBMP_Context* CCodec_BmpModule::Start() { FXBMP_Context* p = FX_Alloc(FXBMP_Context, 1); if (!p) return nullptr; @@ -56,7 +64,6 @@ FXBMP_Context* CCodec_BmpModule::Start(void* pModule) { p->m_FreeFunc = bmp_free_func; p->bmp_ptr = nullptr; p->parent_ptr = (void*)this; - p->child_ptr = pModule; p->bmp_ptr = bmp_create_decompress(); if (!p->bmp_ptr) { FX_Free(p); diff --git a/core/fxcodec/codec/ccodec_bmpmodule.h b/core/fxcodec/codec/ccodec_bmpmodule.h index 605bd620c..11d5931ca 100644 --- a/core/fxcodec/codec/ccodec_bmpmodule.h +++ b/core/fxcodec/codec/ccodec_bmpmodule.h @@ -7,23 +7,21 @@ #ifndef CORE_FXCODEC_CODEC_CCODEC_BMPMODULE_H_ #define CORE_FXCODEC_CODEC_CCODEC_BMPMODULE_H_ +#include "core/fxcodec/codec/icodec_bmpmodule.h" #include "core/fxcrt/fx_system.h" -struct FXBMP_Context; -class CFX_DIBAttribute; - -class CCodec_BmpModule { +class CCodec_BmpModule : public ICodec_BmpModule { public: - CCodec_BmpModule() { FXSYS_memset(m_szLastError, 0, sizeof(m_szLastError)); } - - FXBMP_Context* Start(void* pModule); - void Finish(FXBMP_Context* pContext); + CCodec_BmpModule(); + ~CCodec_BmpModule() override; - uint32_t GetAvailInput(FXBMP_Context* pContext, uint8_t** avail_buf_ptr); + FXBMP_Context* Start() override; + void Finish(FXBMP_Context* pContext) override; + uint32_t GetAvailInput(FXBMP_Context* pContext, + uint8_t** avail_buf_ptr) override; void Input(FXBMP_Context* pContext, const uint8_t* src_buf, - uint32_t src_size); - + uint32_t src_size) override; int32_t ReadHeader(FXBMP_Context* pContext, int32_t* width, int32_t* height, @@ -31,13 +29,8 @@ class CCodec_BmpModule { int32_t* components, int32_t* pal_num, uint32_t** pal_pp, - CFX_DIBAttribute* pAttribute); - int32_t LoadImage(FXBMP_Context* pContext); - - bool (*InputImagePositionBufCallback)(void* pModule, uint32_t rcd_pos); - void (*ReadScanlineCallback)(void* pModule, - int32_t row_num, - uint8_t* row_buf); + CFX_DIBAttribute* pAttribute) override; + int32_t LoadImage(FXBMP_Context* pContext) override; protected: FX_CHAR m_szLastError[256]; diff --git a/core/fxcodec/codec/fx_codec_gif.cpp b/core/fxcodec/codec/ccodec_gifmodule.cpp index fadf18f25..a85bc5edd 100644 --- a/core/fxcodec/codec/fx_codec_gif.cpp +++ b/core/fxcodec/codec/ccodec_gifmodule.cpp @@ -4,18 +4,21 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +#include "core/fxcodec/codec/ccodec_gifmodule.h" + #include "core/fxcodec/codec/codec_int.h" #include "core/fxcodec/fx_codec.h" #include "core/fxcodec/lgif/fx_gif.h" #include "core/fxge/fx_dib.h" + struct FXGIF_Context { gif_decompress_struct_p gif_ptr; void* parent_ptr; - void* child_ptr; void* (*m_AllocFunc)(unsigned int); void (*m_FreeFunc)(void*); }; + extern "C" { static void* gif_alloc_func(unsigned int size) { return FX_Alloc(char, size); @@ -24,31 +27,36 @@ static void gif_free_func(void* p) { FX_Free(p); } }; + static void gif_error_data(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) { FXSYS_strncpy((char*)gif_ptr->err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1); longjmp(gif_ptr->jmpbuf, 1); } + static uint8_t* gif_ask_buf_for_pal(gif_decompress_struct_p gif_ptr, int32_t pal_size) { FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - return pModule->AskLocalPaletteBufCallback( - p->child_ptr, gif_get_frame_num(gif_ptr), pal_size); + return pModule->GetDelegate()->GifAskLocalPaletteBuf( + gif_get_frame_num(gif_ptr), pal_size); } + static void gif_record_current_position(gif_decompress_struct_p gif_ptr, uint32_t* cur_pos_ptr) { FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - pModule->RecordCurrentPositionCallback(p->child_ptr, *cur_pos_ptr); + pModule->GetDelegate()->GifRecordCurrentPosition(*cur_pos_ptr); } + static void gif_read_scanline(gif_decompress_struct_p gif_ptr, int32_t row_num, uint8_t* row_buf) { FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf); + pModule->GetDelegate()->GifReadScanline(row_num, row_buf); } + static bool gif_get_record_position(gif_decompress_struct_p gif_ptr, uint32_t cur_pos, int32_t left, @@ -64,13 +72,18 @@ static bool gif_get_record_position(gif_decompress_struct_p gif_ptr, bool interlace) { FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr; CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr; - return pModule->InputRecordPositionBufCallback( - p->child_ptr, cur_pos, FX_RECT(left, top, left + width, top + height), - pal_num, pal_ptr, delay_time, user_input, trans_index, disposal_method, - interlace); + return pModule->GetDelegate()->GifInputRecordPositionBuf( + cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal_ptr, + delay_time, user_input, trans_index, disposal_method, interlace); } -FXGIF_Context* CCodec_GifModule::Start(void* pModule) { +CCodec_GifModule::CCodec_GifModule() { + memset(m_szLastError, 0, sizeof(m_szLastError)); +} + +CCodec_GifModule::~CCodec_GifModule() {} + +FXGIF_Context* CCodec_GifModule::Start() { FXGIF_Context* p = FX_Alloc(FXGIF_Context, 1); if (!p) return nullptr; @@ -80,7 +93,6 @@ FXGIF_Context* CCodec_GifModule::Start(void* pModule) { p->m_FreeFunc = gif_free_func; p->gif_ptr = nullptr; p->parent_ptr = (void*)this; - p->child_ptr = pModule; p->gif_ptr = gif_create_decompress(); if (!p->gif_ptr) { FX_Free(p); diff --git a/core/fxcodec/codec/ccodec_gifmodule.h b/core/fxcodec/codec/ccodec_gifmodule.h index fac621d25..7721d7a76 100644 --- a/core/fxcodec/codec/ccodec_gifmodule.h +++ b/core/fxcodec/codec/ccodec_gifmodule.h @@ -7,22 +7,23 @@ #ifndef CORE_FXCODEC_CODEC_CCODEC_GIFMODULE_H_ #define CORE_FXCODEC_CODEC_CCODEC_GIFMODULE_H_ +#include "core/fxcodec/codec/icodec_gifmodule.h" +#include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" -struct FXGIF_Context; - -class CCodec_GifModule { +class CCodec_GifModule : public ICodec_GifModule { public: - CCodec_GifModule() { FXSYS_memset(m_szLastError, 0, sizeof(m_szLastError)); } - - FXGIF_Context* Start(void* pModule); - void Finish(FXGIF_Context* pContext); + CCodec_GifModule(); + ~CCodec_GifModule() override; + FXGIF_Context* Start() override; + void Finish(FXGIF_Context* pContext) override; uint32_t GetAvailInput(FXGIF_Context* pContext, - uint8_t** avail_buf_ptr = nullptr); + uint8_t** avail_buf_ptr = nullptr) override; + void Input(FXGIF_Context* pContext, const uint8_t* src_buf, - uint32_t src_size); + uint32_t src_size) override; int32_t ReadHeader(FXGIF_Context* pContext, int* width, @@ -30,31 +31,12 @@ class CCodec_GifModule { int* pal_num, void** pal_pp, int* bg_index, - CFX_DIBAttribute* pAttribute); - - int32_t LoadFrameInfo(FXGIF_Context* pContext, int* frame_num); + CFX_DIBAttribute* pAttribute) override; + int32_t LoadFrameInfo(FXGIF_Context* pContext, int* frame_num) override; int32_t LoadFrame(FXGIF_Context* pContext, int frame_num, - CFX_DIBAttribute* pAttribute); - - void (*RecordCurrentPositionCallback)(void* pModule, uint32_t& cur_pos); - uint8_t* (*AskLocalPaletteBufCallback)(void* pModule, - int32_t frame_num, - int32_t pal_size); - bool (*InputRecordPositionBufCallback)(void* pModule, - uint32_t rcd_pos, - const FX_RECT& img_rc, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - bool user_input, - int32_t trans_index, - int32_t disposal_method, - bool interlace); - void (*ReadScanlineCallback)(void* pModule, - int32_t row_num, - uint8_t* row_buf); + CFX_DIBAttribute* pAttribute) override; protected: FX_CHAR m_szLastError[256]; diff --git a/core/fxcodec/codec/fx_codec_png.cpp b/core/fxcodec/codec/ccodec_pngmodule.cpp index 579c85bf0..028513b72 100644 --- a/core/fxcodec/codec/fx_codec_png.cpp +++ b/core/fxcodec/codec/ccodec_pngmodule.cpp @@ -4,6 +4,8 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +#include "core/fxcodec/codec/ccodec_pngmodule.h" + #include <algorithm> #include "core/fxcodec/codec/codec_int.h" @@ -95,7 +97,6 @@ struct FXPNG_Context { png_structp png_ptr; png_infop info_ptr; void* parent_ptr; - void* child_ptr; void* (*m_AllocFunc)(unsigned int); void (*m_FreeFunc)(void*); @@ -133,8 +134,8 @@ static void _png_get_header_func(png_structp png_ptr, png_infop info_ptr) { png_set_palette_to_rgb(png_ptr); } pass = png_set_interlace_handling(png_ptr); - if (!pModule->ReadHeaderCallback(p->child_ptr, width, height, bpc, pass, - &color_type, &gamma)) { + if (!pModule->GetDelegate()->PngReadHeader(width, height, bpc, pass, + &color_type, &gamma)) { png_error(p->png_ptr, "Read Header Callback Error"); } int intent; @@ -187,16 +188,22 @@ static void _png_get_row_func(png_structp png_ptr, CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr; uint8_t* src_buf = nullptr; - if (!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) { + if (!pModule->GetDelegate()->PngAskScanlineBuf(row_num, src_buf)) { png_error(png_ptr, "Ask Scanline buffer Callback Error"); } if (src_buf) { png_progressive_combine_row(png_ptr, src_buf, new_row); } - pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num); + pModule->GetDelegate()->PngFillScanlineBufCompleted(pass, row_num); +} + +CCodec_PngModule::CCodec_PngModule() { + memset(m_szLastError, 0, sizeof(m_szLastError)); } -FXPNG_Context* CCodec_PngModule::Start(void* pModule) { +CCodec_PngModule::~CCodec_PngModule() {} + +FXPNG_Context* CCodec_PngModule::Start() { FXPNG_Context* p = FX_Alloc(FXPNG_Context, 1); if (!p) return nullptr; @@ -206,7 +213,6 @@ FXPNG_Context* CCodec_PngModule::Start(void* pModule) { p->png_ptr = nullptr; p->info_ptr = nullptr; p->parent_ptr = (void*)this; - p->child_ptr = pModule; p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!p->png_ptr) { diff --git a/core/fxcodec/codec/ccodec_pngmodule.h b/core/fxcodec/codec/ccodec_pngmodule.h index 77c4af394..1f3a3d96c 100644 --- a/core/fxcodec/codec/ccodec_pngmodule.h +++ b/core/fxcodec/codec/ccodec_pngmodule.h @@ -7,33 +7,22 @@ #ifndef CORE_FXCODEC_CODEC_CCODEC_PNGMODULE_H_ #define CORE_FXCODEC_CODEC_CCODEC_PNGMODULE_H_ +#include "core/fxcodec/codec/icodec_pngmodule.h" #include "core/fxcrt/fx_system.h" -class CFX_DIBAttribute; -struct FXPNG_Context; - #define PNG_ERROR_SIZE 256 -class CCodec_PngModule { +class CCodec_PngModule : public ICodec_PngModule { public: - CCodec_PngModule() { FXSYS_memset(m_szLastError, 0, sizeof(m_szLastError)); } + CCodec_PngModule(); + ~CCodec_PngModule() override; - FXPNG_Context* Start(void* pModule); - void Finish(FXPNG_Context* pContext); + FXPNG_Context* Start() override; + void Finish(FXPNG_Context* pContext) override; bool Input(FXPNG_Context* pContext, const uint8_t* src_buf, uint32_t src_size, - CFX_DIBAttribute* pAttribute); - - bool (*ReadHeaderCallback)(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma); - bool (*AskScanlineBufCallback)(void* pModule, int line, uint8_t*& src_buf); - void (*FillScanlineBufCompletedCallback)(void* pModule, int pass, int line); + CFX_DIBAttribute* pAttribute) override; protected: FX_CHAR m_szLastError[PNG_ERROR_SIZE]; diff --git a/core/fxcodec/codec/ccodec_progressivedecoder.h b/core/fxcodec/codec/ccodec_progressivedecoder.h index 614146f79..61703dde2 100644 --- a/core/fxcodec/codec/ccodec_progressivedecoder.h +++ b/core/fxcodec/codec/ccodec_progressivedecoder.h @@ -9,27 +9,25 @@ #include <vector> +#include "core/fxcodec/codec/icodec_bmpmodule.h" +#include "core/fxcodec/codec/icodec_gifmodule.h" +#include "core/fxcodec/codec/icodec_pngmodule.h" +#include "core/fxcodec/codec/icodec_tiffmodule.h" #include "core/fxcodec/fx_codec_def.h" #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_system.h" #include "core/fxge/fx_dib.h" -class CCodec_BmpModule; -class CCodec_GifContext; -class CCodec_GifModule; class CCodec_JpegModule; class CCodec_ModuleMgr; -class CCodec_PngContext; -class CCodec_TiffContext; class CFX_DIBAttribute; class IFX_SeekableReadStream; class IFX_Pause; -struct FXBMP_Context; -struct FXGIF_Context; struct FXJPEG_Context; -struct FXPNG_Context; -class CCodec_ProgressiveDecoder { +class CCodec_ProgressiveDecoder : public ICodec_BmpModule::Delegate, + public ICodec_GifModule::Delegate, + public ICodec_PngModule::Delegate { public: enum FXCodec_Format { FXCodec_Invalid = 0, @@ -44,7 +42,7 @@ class CCodec_ProgressiveDecoder { }; explicit CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr); - ~CCodec_ProgressiveDecoder(); + virtual ~CCodec_ProgressiveDecoder(); FXCODEC_STATUS LoadImageInfo( const CFX_RetainPtr<IFX_SeekableReadStream>& pFile, @@ -170,41 +168,46 @@ class CCodec_ProgressiveDecoder { bool m_BmpIsTopBottom; FXCODEC_STATUS m_status; - protected: - static bool PngReadHeaderFunc(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma); - static bool PngAskScanlineBufFunc(void* pModule, int line, uint8_t*& src_buf); - static void PngFillScanlineBufCompletedFunc(void* pModule, - int pass, - int line); - static void GifRecordCurrentPositionCallback(void* pModule, - uint32_t& cur_pos); - static uint8_t* GifAskLocalPaletteBufCallback(void* pModule, - int32_t frame_num, - int32_t pal_size); - static bool GifInputRecordPositionBufCallback(void* pModule, - uint32_t rcd_pos, - const FX_RECT& img_rc, - int32_t pal_num, - void* pal_ptr, - int32_t delay_time, - bool user_input, - int32_t trans_index, - int32_t disposal_method, - bool interlace); - static void GifReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf); - static bool BmpInputImagePositionBufCallback(void* pModule, uint32_t rcd_pos); - static void BmpReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf); + // ICodec_PngModule::Delegate + bool PngReadHeader(int width, + int height, + int bpc, + int pass, + int* color_type, + double* gamma) override; + bool PngAskScanlineBuf(int line, uint8_t*& src_buf) override; + void PngFillScanlineBufCompleted(int pass, int line) override; + + // ICodec_GifModule::Delegate + void GifRecordCurrentPosition(uint32_t& cur_pos) override; + uint8_t* GifAskLocalPaletteBuf(int32_t frame_num, int32_t pal_size) override; + bool GifInputRecordPositionBuf(uint32_t rcd_pos, + const FX_RECT& img_rc, + int32_t pal_num, + void* pal_ptr, + int32_t delay_time, + bool user_input, + int32_t trans_index, + int32_t disposal_method, + bool interlace) override; + void GifReadScanline(int32_t row_num, uint8_t* row_buf) override; + + // ICodec_BmpModule::Delegate + bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; + void BmpReadScanline(int32_t row_num, uint8_t* row_buf) override; + protected: + bool BmpReadMoreData(ICodec_BmpModule* pBmpModule, + FXCODEC_STATUS& err_status); + bool GifReadMoreData(ICodec_GifModule* pGifModule, + FXCODEC_STATUS& err_status); + void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, + double scale_y, + int des_row); + void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, + int32_t des_line, + uint8_t* src_scan, + FXCodec_Format src_format); bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute); void GetDownScale(int& down_scale); @@ -220,17 +223,6 @@ class CCodec_ProgressiveDecoder { void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); bool JpegReadMoreData(CCodec_JpegModule* pJpegModule, FXCODEC_STATUS& err_status); - void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, - int32_t des_line, - uint8_t* src_scan, - FXCodec_Format src_format); - bool GifReadMoreData(CCodec_GifModule* pGifModule, - FXCODEC_STATUS& err_status); - void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, - double scale_y, - int des_row); - bool BmpReadMoreData(CCodec_BmpModule* pBmpModule, - FXCODEC_STATUS& err_status); void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); }; diff --git a/core/fxcodec/codec/fx_codec_tiff.cpp b/core/fxcodec/codec/ccodec_tiffmodule.cpp index 7818a34ec..736772892 100644 --- a/core/fxcodec/codec/fx_codec_tiff.cpp +++ b/core/fxcodec/codec/ccodec_tiffmodule.cpp @@ -4,6 +4,8 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com +#include "core/fxcodec/codec/ccodec_tiffmodule.h" + #include <limits> #include "core/fxcodec/codec/codec_int.h" diff --git a/core/fxcodec/codec/ccodec_tiffmodule.h b/core/fxcodec/codec/ccodec_tiffmodule.h index dd2cbd768..a8820f4aa 100644 --- a/core/fxcodec/codec/ccodec_tiffmodule.h +++ b/core/fxcodec/codec/ccodec_tiffmodule.h @@ -7,30 +7,25 @@ #ifndef CORE_FXCODEC_CODEC_CCODEC_TIFFMODULE_H_ #define CORE_FXCODEC_CODEC_CCODEC_TIFFMODULE_H_ +#include "core/fxcodec/codec/icodec_tiffmodule.h" #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_system.h" -class CCodec_TiffContext; -class CFX_DIBAttribute; -class CFX_DIBitmap; -class IFX_SeekableReadStream; - -class CCodec_TiffModule { +class CCodec_TiffModule : public ICodec_TiffModule { public: - ~CCodec_TiffModule() {} + ~CCodec_TiffModule() override {} CCodec_TiffContext* CreateDecoder( - const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr); - + const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr) override; bool LoadFrameInfo(CCodec_TiffContext* ctx, int32_t frame, int32_t* width, int32_t* height, int32_t* comps, int32_t* bpc, - CFX_DIBAttribute* pAttribute); - bool Decode(CCodec_TiffContext* ctx, class CFX_DIBitmap* pDIBitmap); - void DestroyDecoder(CCodec_TiffContext* ctx); + CFX_DIBAttribute* pAttribute) override; + bool Decode(CCodec_TiffContext* ctx, class CFX_DIBitmap* pDIBitmap) override; + void DestroyDecoder(CCodec_TiffContext* ctx) override; }; #endif // CORE_FXCODEC_CODEC_CCODEC_TIFFMODULE_H_ diff --git a/core/fxcodec/codec/fx_codec.cpp b/core/fxcodec/codec/fx_codec.cpp index 23171cf3e..0d886b43c 100644 --- a/core/fxcodec/codec/fx_codec.cpp +++ b/core/fxcodec/codec/fx_codec.cpp @@ -24,12 +24,6 @@ CCodec_ModuleMgr::CCodec_ModuleMgr() m_pJpxModule(new CCodec_JpxModule), m_pJbig2Module(new CCodec_Jbig2Module), m_pIccModule(new CCodec_IccModule), -#ifdef PDF_ENABLE_XFA - m_pPngModule(new CCodec_PngModule), - m_pGifModule(new CCodec_GifModule), - m_pBmpModule(new CCodec_BmpModule), - m_pTiffModule(new CCodec_TiffModule), -#endif // PDF_ENABLE_XFA m_pFlateModule(new CCodec_FlateModule) { } @@ -229,7 +223,7 @@ bool CCodec_BasicModule::A85Encode(const uint8_t* src_buf, uint32_t val = 0; int count = 0; while (pos < src_size) { - val += (uint32_t)(src_buf[pos] << (8 * (3 - pos))); + val += (uint32_t)(src_buf[pos]) << (8 * (3 - count)); count++; pos++; } diff --git a/core/fxcodec/codec/fx_codec_a85_unittest.cpp b/core/fxcodec/codec/fx_codec_a85_unittest.cpp index 791088177..78f9bd8fc 100644 --- a/core/fxcodec/codec/fx_codec_a85_unittest.cpp +++ b/core/fxcodec/codec/fx_codec_a85_unittest.cpp @@ -12,7 +12,7 @@ #include "testing/gtest/include/gtest/gtest.h" TEST(fxcodec, A85TestBadInputs) { - uint8_t src_buf[4] = {1, 2, 3, 4}; + const uint8_t src_buf[] = {1, 2, 3, 4}; uint8_t* dest_buf = nullptr; uint32_t src_size = 4; uint32_t dest_size = 0; @@ -30,7 +30,7 @@ TEST(fxcodec, A85TestBadInputs) { // No leftover bytes, just translate 2 sets of symbols. TEST(fxcodec, A85TestBasic) { // Make sure really big values don't break. - uint8_t src_buf[8] = {1, 2, 3, 4, 255, 255, 255, 255}; + const uint8_t src_buf[] = {1, 2, 3, 4, 255, 255, 255, 255}; uint8_t* dest_buf = nullptr; uint32_t src_size = 8; uint32_t dest_size = 0; @@ -42,19 +42,20 @@ TEST(fxcodec, A85TestBasic) { EXPECT_TRUE(pEncoders->A85Encode(src_buf, src_size, &dest_buf, &dest_size)); // Should have 5 chars for each set of 4 and 2 terminators. - EXPECT_EQ(12u, dest_size); - uint8_t expected_out[12] = {33, 60, 78, 63, 43, 115, 56, 87, 45, 33, 126, 62}; + ASSERT_EQ(12u, dest_size); + const uint8_t expected_out[] = {33, 60, 78, 63, 43, 115, + 56, 87, 45, 33, 126, 62}; // Check the output for (uint32_t i = 0; i < 12; i++) - EXPECT_EQ(dest_buf[i], expected_out[i]) << " at " << i; + EXPECT_EQ(expected_out[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); } // Leftover bytes. TEST(fxcodec, A85TestLeftoverBytes) { // 1 Leftover Byte: - uint8_t src_buf_1leftover[5] = {1, 2, 3, 4, 255}; + const uint8_t src_buf_1leftover[] = {1, 2, 3, 4, 255}; uint8_t* dest_buf = nullptr; uint32_t src_size = 5; uint32_t dest_size = 0; @@ -65,53 +66,53 @@ TEST(fxcodec, A85TestLeftoverBytes) { // Should succeed EXPECT_TRUE( pEncoders->A85Encode(src_buf_1leftover, src_size, &dest_buf, &dest_size)); - EXPECT_EQ(9u, dest_size); // 5 chars for first symbol + 2 + 2 terminators. - uint8_t expected_out_1leftover[9] = {33, 60, 78, 63, 43, 114, 114, 126, 62}; + ASSERT_EQ(9u, dest_size); // 5 chars for first symbol + 2 + 2 terminators. + uint8_t expected_out_1leftover[] = {33, 60, 78, 63, 43, 114, 114, 126, 62}; // Check the output for (uint32_t i = 0; i < 9; i++) - EXPECT_EQ(dest_buf[i], expected_out_1leftover[i]) << " at " << i; + EXPECT_EQ(expected_out_1leftover[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); // 2 Leftover bytes: src_size++; dest_buf = nullptr; dest_size = 0; - uint8_t src_buf_2leftover[6] = {1, 2, 3, 4, 255, 254}; + const uint8_t src_buf_2leftover[] = {1, 2, 3, 4, 255, 254}; // Should succeed EXPECT_TRUE( pEncoders->A85Encode(src_buf_2leftover, src_size, &dest_buf, &dest_size)); - EXPECT_EQ(10u, dest_size); // 5 chars for first symbol + 3 + 2 terminators. - uint8_t expected_out_2leftover[10] = {33, 60, 78, 63, 43, - 115, 56, 68, 126, 62}; + ASSERT_EQ(10u, dest_size); // 5 chars for first symbol + 3 + 2 terminators. + const uint8_t expected_out_2leftover[] = {33, 60, 78, 63, 43, + 115, 56, 68, 126, 62}; // Check the output for (uint32_t i = 0; i < 10; i++) - EXPECT_EQ(dest_buf[i], expected_out_2leftover[i]) << " at " << i; + EXPECT_EQ(expected_out_2leftover[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); // 3 Leftover bytes: src_size++; dest_buf = nullptr; dest_size = 0; - uint8_t src_buf_3leftover[7] = {1, 2, 3, 4, 255, 254, 253}; + const uint8_t src_buf_3leftover[] = {1, 2, 3, 4, 255, 254, 253}; // Should succeed EXPECT_TRUE( pEncoders->A85Encode(src_buf_3leftover, src_size, &dest_buf, &dest_size)); - EXPECT_EQ(11u, dest_size); // 5 chars for first symbol + 4 + 2 terminators. - uint8_t expected_out_3leftover[11] = {33, 60, 78, 63, 43, 115, - 56, 77, 114, 126, 62}; + ASSERT_EQ(11u, dest_size); // 5 chars for first symbol + 4 + 2 terminators. + const uint8_t expected_out_3leftover[] = {33, 60, 78, 63, 43, 115, + 56, 77, 114, 126, 62}; // Check the output for (uint32_t i = 0; i < 11; i++) - EXPECT_EQ(dest_buf[i], expected_out_3leftover[i]) << " at " << i; + EXPECT_EQ(expected_out_3leftover[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); } // Test all zeros comes through as "z". TEST(fxcodec, A85TestZeros) { // Make sure really big values don't break. - uint8_t src_buf[8] = {1, 2, 3, 4, 0, 0, 0, 0}; + const uint8_t src_buf[] = {1, 2, 3, 4, 0, 0, 0, 0}; uint8_t* dest_buf = nullptr; uint32_t src_size = 8; uint32_t dest_size = 0; @@ -123,29 +124,29 @@ TEST(fxcodec, A85TestZeros) { EXPECT_TRUE(pEncoders->A85Encode(src_buf, src_size, &dest_buf, &dest_size)); // Should have 5 chars for first set of 4 + 1 for z + 2 terminators. - EXPECT_EQ(8u, dest_size); - uint8_t expected_out[8] = {33, 60, 78, 63, 43, 122, 126, 62}; + ASSERT_EQ(8u, dest_size); + const uint8_t expected_out[] = {33, 60, 78, 63, 43, 122, 126, 62}; // Check the output for (uint32_t i = 0; i < 8; i++) - EXPECT_EQ(dest_buf[i], expected_out[i]) << " at " << i; + EXPECT_EQ(expected_out[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); // Should also work if it is at the start: dest_buf = nullptr; dest_size = 0; - uint8_t src_buf_2[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t src_buf_2[] = {0, 0, 0, 0, 1, 2, 3, 4}; // Should succeed. EXPECT_TRUE(pEncoders->A85Encode(src_buf_2, src_size, &dest_buf, &dest_size)); // Should have 5 chars for set of 4 + 1 for z + 2 terminators. - EXPECT_EQ(8u, dest_size); - uint8_t expected_out_2[8] = {122, 33, 60, 78, 63, 43, 126, 62}; + ASSERT_EQ(8u, dest_size); + const uint8_t expected_out_2[] = {122, 33, 60, 78, 63, 43, 126, 62}; // Check the output for (uint32_t i = 0; i < 8; i++) - EXPECT_EQ(dest_buf[i], expected_out_2[i]) << " at " << i; + EXPECT_EQ(expected_out_2[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); // Try with 2 leftover zero bytes. Make sure we don't get a "z". @@ -157,12 +158,13 @@ TEST(fxcodec, A85TestZeros) { EXPECT_TRUE(pEncoders->A85Encode(src_buf, src_size, &dest_buf, &dest_size)); // Should have 5 chars for set of 4 + 3 for last 2 + 2 terminators. - EXPECT_EQ(10u, dest_size); - uint8_t expected_out_leftover[10] = {33, 60, 78, 63, 43, 33, 33, 33, 126, 62}; + ASSERT_EQ(10u, dest_size); + const uint8_t expected_out_leftover[] = {33, 60, 78, 63, 43, + 33, 33, 33, 126, 62}; // Check the output for (uint32_t i = 0; i < 10; i++) - EXPECT_EQ(dest_buf[i], expected_out_leftover[i]) << " at " << i; + EXPECT_EQ(expected_out_leftover[i], dest_buf[i]) << " at " << i; FX_Free(dest_buf); } @@ -197,13 +199,13 @@ TEST(fxcodec, A85TestLineBreaks) { // Should have 75 chars in the first row plus 2 char return, // 76 chars in the second row plus 2 char return, // and 9 chars in the last row with 2 terminators. - EXPECT_EQ(166u, dest_size); + ASSERT_EQ(166u, dest_size); // Check for the returns. - EXPECT_EQ(dest_buf[75], 13); - EXPECT_EQ(dest_buf[76], 10); - EXPECT_EQ(dest_buf[153], 13); - EXPECT_EQ(dest_buf[154], 10); + EXPECT_EQ(13, dest_buf[75]); + EXPECT_EQ(10, dest_buf[76]); + EXPECT_EQ(13, dest_buf[153]); + EXPECT_EQ(10, dest_buf[154]); FX_Free(dest_buf); } diff --git a/core/fxcodec/codec/fx_codec_progress.cpp b/core/fxcodec/codec/fx_codec_progress.cpp index 386b66a7e..1f2f50c29 100644 --- a/core/fxcodec/codec/fx_codec_progress.cpp +++ b/core/fxcodec/codec/fx_codec_progress.cpp @@ -12,6 +12,7 @@ #include "core/fxcodec/fx_codec.h" #include "core/fxge/fx_dib.h" #include "third_party/base/numerics/safe_math.h" +#include "third_party/base/ptr_util.h" #define FXCODEC_BLOCK_SIZE 4096 @@ -19,9 +20,9 @@ namespace { #if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ const double kPngGamma = 1.7; -#else +#else // _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ const double kPngGamma = 2.2; -#endif +#endif // _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_ void RGB2BGR(uint8_t* buffer, int width = 1) { if (buffer && width > 0) { @@ -299,12 +300,12 @@ CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder() { m_pFile = nullptr; if (m_pJpegContext) m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext); - if (m_pPngContext) - m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); - if (m_pGifContext) - m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); if (m_pBmpContext) m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext); + if (m_pGifContext) + m_pCodecMgr->GetGifModule()->Finish(m_pGifContext); + if (m_pPngContext) + m_pCodecMgr->GetPngModule()->Finish(m_pPngContext); if (m_pTiffContext) m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext); FX_Free(m_pSrcBuf); @@ -349,41 +350,39 @@ bool CCodec_ProgressiveDecoder::JpegReadMoreData(CCodec_JpegModule* pJpegModule, return true; } -bool CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, - int width, - int height, - int bpc, - int pass, - int* color_type, - double* gamma) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - if (!pCodec->m_pDeviceBitmap) { - pCodec->m_SrcWidth = width; - pCodec->m_SrcHeight = height; - pCodec->m_SrcBPC = bpc; - pCodec->m_SrcPassNumber = pass; +bool CCodec_ProgressiveDecoder::PngReadHeader(int width, + int height, + int bpc, + int pass, + int* color_type, + double* gamma) { + if (!m_pDeviceBitmap) { + m_SrcWidth = width; + m_SrcHeight = height; + m_SrcBPC = bpc; + m_SrcPassNumber = pass; switch (*color_type) { case 0: - pCodec->m_SrcComponents = 1; + m_SrcComponents = 1; break; case 4: - pCodec->m_SrcComponents = 2; + m_SrcComponents = 2; break; case 2: - pCodec->m_SrcComponents = 3; + m_SrcComponents = 3; break; case 3: case 6: - pCodec->m_SrcComponents = 4; + m_SrcComponents = 4; break; default: - pCodec->m_SrcComponents = 0; + m_SrcComponents = 0; break; } - pCodec->m_clipBox = FX_RECT(0, 0, width, height); + m_clipBox = FX_RECT(0, 0, width, height); return false; } - FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat(); + FXDIB_Format format = m_pDeviceBitmap->GetFormat(); switch (format) { case FXDIB_1bppMask: case FXDIB_1bppRgb: @@ -408,32 +407,26 @@ bool CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, return true; } -bool CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, - int line, - uint8_t*& src_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; +bool CCodec_ProgressiveDecoder::PngAskScanlineBuf(int line, uint8_t*& src_buf) { + CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap; if (!pDIBitmap) { ASSERT(false); return false; } - if (line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) { - double scale_y = - (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height(); - int32_t row = - (int32_t)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY; + if (line >= m_clipBox.top && line < m_clipBox.bottom) { + double scale_y = (double)m_sizeY / (double)m_clipBox.Height(); + int32_t row = (int32_t)((line - m_clipBox.top) * scale_y) + m_startY; uint8_t* src_scan = (uint8_t*)pDIBitmap->GetScanline(row); - uint8_t* des_scan = pCodec->m_pDecodeBuf; - src_buf = pCodec->m_pDecodeBuf; + uint8_t* des_scan = m_pDecodeBuf; + src_buf = m_pDecodeBuf; int32_t src_Bpp = pDIBitmap->GetBPP() >> 3; - int32_t des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3; - int32_t src_left = pCodec->m_startX; - int32_t des_left = pCodec->m_clipBox.left; + int32_t des_Bpp = (m_SrcFormat & 0xff) >> 3; + int32_t src_left = m_startX; + int32_t des_left = m_clipBox.left; src_scan += src_left * src_Bpp; des_scan += des_left * des_Bpp; - for (int32_t src_col = 0; src_col < pCodec->m_sizeX; src_col++) { - PixelWeight* pPixelWeights = - pCodec->m_WeightHorzOO.GetPixelWeight(src_col); + for (int32_t src_col = 0; src_col < m_sizeX; src_col++) { + PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col); if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) { continue; } @@ -555,17 +548,15 @@ void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz( } } -void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, - int pass, - int line) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; +void CCodec_ProgressiveDecoder::PngFillScanlineBufCompleted(int pass, + int line) { + CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap; ASSERT(pDIBitmap); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; + int src_top = m_clipBox.top; + int src_bottom = m_clipBox.bottom; + int des_top = m_startY; + int src_hei = m_clipBox.Height(); + int des_hei = m_sizeY; if (line >= src_top && line < src_bottom) { double scale_y = (double)des_hei / (double)src_hei; int src_row = line - src_top; @@ -573,19 +564,18 @@ void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, if (des_row >= des_top + des_hei) { return; } - pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + PngOneOneMapResampleHorz(pDIBitmap, des_row, m_pDecodeBuf, m_SrcFormat); + if (m_SrcPassNumber == 1 && scale_y > 1.0) { + ResampleVert(pDIBitmap, scale_y, des_row); return; } if (pass == 6 && scale_y > 1.0) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + ResampleVert(pDIBitmap, scale_y, des_row); } } } -bool CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule, +bool CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, FXCODEC_STATUS& err_status) { uint32_t dwSize = (uint32_t)m_pFile->GetSize(); if (dwSize <= m_offSet) { @@ -622,24 +612,18 @@ bool CCodec_ProgressiveDecoder::GifReadMoreData(CCodec_GifModule* pGifModule, return true; } -void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback( - void* pModule, - uint32_t& cur_pos) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; +void CCodec_ProgressiveDecoder::GifRecordCurrentPosition(uint32_t& cur_pos) { uint32_t remain_size = - pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext); - cur_pos = pCodec->m_offSet - remain_size; + m_pCodecMgr->GetGifModule()->GetAvailInput(m_pGifContext); + cur_pos = m_offSet - remain_size; } -uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback( - void* pModule, - int32_t frame_num, - int32_t pal_size) { +uint8_t* CCodec_ProgressiveDecoder::GifAskLocalPaletteBuf(int32_t frame_num, + int32_t pal_size) { return FX_Alloc(uint8_t, pal_size); } -bool CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( - void* pModule, +bool CCodec_ProgressiveDecoder::GifInputRecordPositionBuf( uint32_t rcd_pos, const FX_RECT& img_rc, int32_t pal_num, @@ -649,58 +633,56 @@ bool CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( int32_t trans_index, int32_t disposal_method, bool interlace) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - pCodec->m_offSet = rcd_pos; + m_offSet = rcd_pos; FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - if (!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), - error_status)) { + if (!GifReadMoreData(m_pCodecMgr->GetGifModule(), error_status)) { return false; } uint8_t* pPalette = nullptr; if (pal_num != 0 && pal_ptr) { pPalette = (uint8_t*)pal_ptr; } else { - pal_num = pCodec->m_GifPltNumber; - pPalette = pCodec->m_pGifPalette; - } - if (!pCodec->m_pSrcPalette) { - pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); - } else if (pal_num > pCodec->m_SrcPaletteNumber) { - pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num); + pal_num = m_GifPltNumber; + pPalette = m_pGifPalette; } - if (!pCodec->m_pSrcPalette) + if (!m_pSrcPalette) + m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num); + else if (pal_num > m_SrcPaletteNumber) + m_pSrcPalette = FX_Realloc(FX_ARGB, m_pSrcPalette, pal_num); + if (!m_pSrcPalette) return false; - pCodec->m_SrcPaletteNumber = pal_num; + m_SrcPaletteNumber = pal_num; for (int i = 0; i < pal_num; i++) { uint32_t j = i * 3; - pCodec->m_pSrcPalette[i] = + m_pSrcPalette[i] = ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]); } - pCodec->m_GifTransIndex = trans_index; - pCodec->m_GifFrameRect = img_rc; - pCodec->m_SrcPassNumber = interlace ? 4 : 1; - int32_t pal_index = pCodec->m_GifBgIndex; - CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap; - if (trans_index >= pal_num) { + m_GifTransIndex = trans_index; + m_GifFrameRect = img_rc; + m_SrcPassNumber = interlace ? 4 : 1; + int32_t pal_index = m_GifBgIndex; + CFX_DIBitmap* pDevice = m_pDeviceBitmap; + if (trans_index >= pal_num) trans_index = -1; - } if (trans_index != -1) { - pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff; - if (pDevice->HasAlpha()) { + m_pSrcPalette[trans_index] &= 0x00ffffff; + if (pDevice->HasAlpha()) pal_index = trans_index; - } } - int startX = pCodec->m_startX; - int startY = pCodec->m_startY; - int sizeX = pCodec->m_sizeX; - int sizeY = pCodec->m_sizeY; + if (pal_index >= pal_num) + return false; + + int startX = m_startX; + int startY = m_startY; + int sizeX = m_sizeX; + int sizeY = m_sizeY; int Bpp = pDevice->GetBPP() / 8; - FX_ARGB argb = pCodec->m_pSrcPalette[pal_index]; + FX_ARGB argb = m_pSrcPalette[pal_index]; for (int row = 0; row < sizeY; row++) { uint8_t* pScanline = (uint8_t*)pDevice->GetScanline(row + startY) + startX * Bpp; - switch (pCodec->m_TransMethod) { + switch (m_TransMethod) { case 3: { uint8_t gray = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb)); @@ -728,36 +710,34 @@ bool CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback( return true; } -void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; +void CCodec_ProgressiveDecoder::GifReadScanline(int32_t row_num, + uint8_t* row_buf) { + CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap; ASSERT(pDIBitmap); - int32_t img_width = pCodec->m_GifFrameRect.Width(); + int32_t img_width = m_GifFrameRect.Width(); if (!pDIBitmap->HasAlpha()) { uint8_t* byte_ptr = row_buf; for (int i = 0; i < img_width; i++) { - if (*byte_ptr == pCodec->m_GifTransIndex) { - *byte_ptr = pCodec->m_GifBgIndex; + if (*byte_ptr == m_GifTransIndex) { + *byte_ptr = m_GifBgIndex; } byte_ptr++; } } - int32_t pal_index = pCodec->m_GifBgIndex; - if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) { - pal_index = pCodec->m_GifTransIndex; + int32_t pal_index = m_GifBgIndex; + if (m_GifTransIndex != -1 && m_pDeviceBitmap->HasAlpha()) { + pal_index = m_GifTransIndex; } - FXSYS_memset(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth); + FXSYS_memset(m_pDecodeBuf, pal_index, m_SrcWidth); bool bLastPass = (row_num % 2) == 1; - int32_t line = row_num + pCodec->m_GifFrameRect.top; - int32_t left = pCodec->m_GifFrameRect.left; - FXSYS_memcpy(pCodec->m_pDecodeBuf + left, row_buf, img_width); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; + int32_t line = row_num + m_GifFrameRect.top; + int32_t left = m_GifFrameRect.left; + FXSYS_memcpy(m_pDecodeBuf + left, row_buf, img_width); + int src_top = m_clipBox.top; + int src_bottom = m_clipBox.bottom; + int des_top = m_startY; + int src_hei = m_clipBox.Height(); + int des_hei = m_sizeY; if (line < src_top || line >= src_bottom) return; @@ -767,18 +747,17 @@ void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, if (des_row >= des_top + des_hei) return; - pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); - if (scale_y > 1.0 && (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + ReSampleScanline(pDIBitmap, des_row, m_pDecodeBuf, m_SrcFormat); + if (scale_y > 1.0 && (!m_bInterpol || m_SrcPassNumber == 1)) { + ResampleVert(pDIBitmap, scale_y, des_row); return; } if (scale_y <= 1.0) return; - int des_bottom = des_top + pCodec->m_sizeY; + int des_bottom = des_top + m_sizeY; int des_Bpp = pDIBitmap->GetBPP() >> 3; - uint32_t des_ScanOffet = pCodec->m_startX * des_Bpp; + uint32_t des_ScanOffet = m_startX * des_Bpp; if (des_row + (int)scale_y >= des_bottom - 1) { uint8_t* scan_src = (uint8_t*)pDIBitmap->GetScanline(des_row) + des_ScanOffet; @@ -786,12 +765,12 @@ void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, while (++cur_row < des_bottom) { uint8_t* scan_des = (uint8_t*)pDIBitmap->GetScanline(cur_row) + des_ScanOffet; - uint32_t size = pCodec->m_sizeX * des_Bpp; + uint32_t size = m_sizeX * des_Bpp; FXSYS_memmove(scan_des, scan_src, size); } } if (bLastPass) - pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row); + GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row); } void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( @@ -875,7 +854,7 @@ void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert( } } -bool CCodec_ProgressiveDecoder::BmpReadMoreData(CCodec_BmpModule* pBmpModule, +bool CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, FXCODEC_STATUS& err_status) { uint32_t dwSize = (uint32_t)m_pFile->GetSize(); if (dwSize <= m_offSet) @@ -912,28 +891,22 @@ bool CCodec_ProgressiveDecoder::BmpReadMoreData(CCodec_BmpModule* pBmpModule, return true; } -bool CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback( - void* pModule, - uint32_t rcd_pos) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - pCodec->m_offSet = rcd_pos; +bool CCodec_ProgressiveDecoder::BmpInputImagePositionBuf(uint32_t rcd_pos) { + m_offSet = rcd_pos; FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR; - return pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), - error_status); + return BmpReadMoreData(m_pCodecMgr->GetBmpModule(), error_status); } -void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, - int32_t row_num, - uint8_t* row_buf) { - CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule; - CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap; +void CCodec_ProgressiveDecoder::BmpReadScanline(int32_t row_num, + uint8_t* row_buf) { + CFX_DIBitmap* pDIBitmap = m_pDeviceBitmap; ASSERT(pDIBitmap); - FXSYS_memcpy(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize); - int src_top = pCodec->m_clipBox.top; - int src_bottom = pCodec->m_clipBox.bottom; - int des_top = pCodec->m_startY; - int src_hei = pCodec->m_clipBox.Height(); - int des_hei = pCodec->m_sizeY; + FXSYS_memcpy(m_pDecodeBuf, row_buf, m_ScanlineSize); + int src_top = m_clipBox.top; + int src_bottom = m_clipBox.bottom; + int des_top = m_startY; + int src_hei = m_clipBox.Height(); + int des_hei = m_sizeY; if (row_num < src_top || row_num >= src_bottom) return; @@ -943,16 +916,15 @@ void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, if (des_row >= des_top + des_hei) return; - pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, - pCodec->m_SrcFormat); + ReSampleScanline(pDIBitmap, des_row, m_pDecodeBuf, m_SrcFormat); if (scale_y <= 1.0) return; - if (pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) { - pCodec->ResampleVert(pDIBitmap, scale_y, des_row); + if (m_BmpIsTopBottom || !m_bInterpol) { + ResampleVert(pDIBitmap, scale_y, des_row); return; } - pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row); + ResampleVertBT(pDIBitmap, scale_y, des_row); } void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, @@ -1052,15 +1024,13 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, m_SrcSize = size; switch (imageType) { case FXCODEC_IMAGE_BMP: { - CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); if (!pBmpModule) { m_status = FXCODEC_STATUS_ERR_MEMORY; return false; } - pBmpModule->InputImagePositionBufCallback = - BmpInputImagePositionBufCallback; - pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback; - m_pBmpContext = pBmpModule->Start((void*)this); + pBmpModule->SetDelegate(this); + m_pBmpContext = pBmpModule->Start(); if (!m_pBmpContext) { m_status = FXCODEC_STATUS_ERR_MEMORY; return false; @@ -1150,18 +1120,13 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, return false; } case FXCODEC_IMAGE_PNG: { - CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); if (!pPngModule) { m_status = FXCODEC_STATUS_ERR_MEMORY; return false; } - pPngModule->ReadHeaderCallback = - CCodec_ProgressiveDecoder::PngReadHeaderFunc; - pPngModule->AskScanlineBufCallback = - CCodec_ProgressiveDecoder::PngAskScanlineBufFunc; - pPngModule->FillScanlineBufCompletedCallback = - CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc; - m_pPngContext = pPngModule->Start((void*)this); + pPngModule->SetDelegate(this); + m_pPngContext = pPngModule->Start(); if (!m_pPngContext) { m_status = FXCODEC_STATUS_ERR_MEMORY; return false; @@ -1212,20 +1177,13 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, return true; } case FXCODEC_IMAGE_GIF: { - CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); if (!pGifModule) { m_status = FXCODEC_STATUS_ERR_MEMORY; return false; } - pGifModule->RecordCurrentPositionCallback = - CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback; - pGifModule->AskLocalPaletteBufCallback = - CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback; - pGifModule->InputRecordPositionBufCallback = - CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback; - pGifModule->ReadScanlineCallback = - CCodec_ProgressiveDecoder::GifReadScanlineCallback; - m_pGifContext = pGifModule->Start((void*)this); + pGifModule->SetDelegate(this); + m_pGifContext = pGifModule->Start(); if (!m_pGifContext) { m_status = FXCODEC_STATUS_ERR_MEMORY; return false; @@ -1264,7 +1222,7 @@ bool CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, return false; } case FXCODEC_IMAGE_TIF: { - CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); + ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); if (!pTiffModule) { m_status = FXCODEC_STATUS_ERR_FORMAT; return false; @@ -1832,15 +1790,19 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(int32_t& frames, return FXCODEC_STATUS_ERROR; } switch (m_imagType) { - case FXCODEC_IMAGE_BMP: case FXCODEC_IMAGE_JPG: + case FXCODEC_IMAGE_BMP: case FXCODEC_IMAGE_PNG: case FXCODEC_IMAGE_TIF: frames = m_FrameNumber = 1; m_status = FXCODEC_STATUS_DECODE_READY; return m_status; case FXCODEC_IMAGE_GIF: { - CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + if (!pGifModule) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return m_status; + } while (true) { int32_t readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber); @@ -1969,7 +1931,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, return m_status; } case FXCODEC_IMAGE_PNG: { - CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); if (!pPngModule) { m_pDeviceBitmap = nullptr; m_pFile = nullptr; @@ -1980,7 +1942,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, pPngModule->Finish(m_pPngContext); m_pPngContext = nullptr; } - m_pPngContext = pPngModule->Start((void*)this); + m_pPngContext = pPngModule->Start(); if (!m_pPngContext) { m_pDeviceBitmap = nullptr; m_pFile = nullptr; @@ -2021,7 +1983,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, return m_status; } case FXCODEC_IMAGE_GIF: { - CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); if (!pGifModule) { m_pDeviceBitmap = nullptr; m_pFile = nullptr; @@ -2042,7 +2004,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap, return m_status; } case FXCODEC_IMAGE_BMP: { - CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); if (!pBmpModule) { m_pDeviceBitmap = nullptr; m_pFile = nullptr; @@ -2117,7 +2079,11 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { } } case FXCODEC_IMAGE_PNG: { - CCodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule(); + if (!pPngModule) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return m_status; + } while (true) { uint32_t remain_size = (uint32_t)m_pFile->GetSize() - m_offSet; uint32_t input_size = @@ -2161,7 +2127,11 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { } } case FXCODEC_IMAGE_GIF: { - CCodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule(); + if (!pGifModule) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return m_status; + } while (true) { int32_t readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur, nullptr); @@ -2192,7 +2162,11 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { } } case FXCODEC_IMAGE_BMP: { - CCodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule(); + if (!pBmpModule) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return m_status; + } while (true) { int32_t readRes = pBmpModule->LoadImage(m_pBmpContext); while (readRes == 2) { @@ -2220,9 +2194,13 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { m_status = FXCODEC_STATUS_ERROR; return m_status; } - }; + } case FXCODEC_IMAGE_TIF: { - CCodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); + ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule(); + if (!pTiffModule) { + m_status = FXCODEC_STATUS_ERR_MEMORY; + return m_status; + } bool ret = false; if (m_pDeviceBitmap->GetBPP() == 32 && m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX && @@ -2369,6 +2347,7 @@ FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause) { } } -CCodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder() { - return new CCodec_ProgressiveDecoder(this); +std::unique_ptr<CCodec_ProgressiveDecoder> +CCodec_ModuleMgr::CreateProgressiveDecoder() { + return pdfium::MakeUnique<CCodec_ProgressiveDecoder>(this); } diff --git a/core/fxcodec/codec/fx_codec_rle_unittest.cpp b/core/fxcodec/codec/fx_codec_rle_unittest.cpp index 94d87cde9..d90a515d4 100644 --- a/core/fxcodec/codec/fx_codec_rle_unittest.cpp +++ b/core/fxcodec/codec/fx_codec_rle_unittest.cpp @@ -13,7 +13,7 @@ #include "testing/gtest/include/gtest/gtest.h" TEST(fxcodec, RLETestBadInputs) { - uint8_t src_buf[1] = {1}; + const uint8_t src_buf[] = {1}; uint8_t* dest_buf = nullptr; uint32_t src_size = 4; uint32_t dest_size = 0; @@ -33,7 +33,7 @@ TEST(fxcodec, RLETestBadInputs) { // Check length 1 input works. Check terminating character is applied. TEST(fxcodec, RLETestShortInput) { - uint8_t src_buf[1] = {1}; + const uint8_t src_buf[] = {1}; uint8_t* dest_buf = nullptr; uint32_t src_size = 1; uint32_t dest_size = 0; @@ -43,25 +43,25 @@ TEST(fxcodec, RLETestShortInput) { EXPECT_TRUE( pEncoders->RunLengthEncode(src_buf, src_size, &dest_buf, &dest_size)); - EXPECT_EQ(3u, dest_size); - EXPECT_EQ(dest_buf[0], 0); - EXPECT_EQ(dest_buf[1], 1); - EXPECT_EQ(dest_buf[2], 128); + ASSERT_EQ(3u, dest_size); + EXPECT_EQ(0, dest_buf[0]); + EXPECT_EQ(1, dest_buf[1]); + EXPECT_EQ(128, dest_buf[2]); FX_Free(dest_buf); } // Check a few basic cases (2 matching runs in a row, matching run followed -// by a nonmatching run, and nonmatching run followed by a matching run). +// by a non-matching run, and non-matching run followed by a matching run). TEST(fxcodec, RLETestNormalInputs) { // Match, match - uint8_t src_buf_1[10] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4}; + const uint8_t src_buf_1[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4}; - // Match, nonmatch - uint8_t src_buf_2[10] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6}; + // Match, non-match + const uint8_t src_buf_2[] = {2, 2, 2, 2, 1, 2, 3, 4, 5, 6}; - // Nonmatch, match - uint8_t src_buf_3[10] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3}; + // Non-match, match + const uint8_t src_buf_3[] = {1, 2, 3, 4, 5, 3, 3, 3, 3, 3}; uint32_t src_size = 10; uint32_t dest_size = 0; @@ -76,9 +76,9 @@ TEST(fxcodec, RLETestNormalInputs) { uint8_t* decoded_buf = nullptr; uint32_t decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_1[i]) << " at " << i; + EXPECT_EQ(src_buf_1[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); @@ -90,9 +90,9 @@ TEST(fxcodec, RLETestNormalInputs) { decoded_buf = nullptr; decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_2[i]) << " at " << i; + EXPECT_EQ(src_buf_2[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); @@ -104,30 +104,30 @@ TEST(fxcodec, RLETestNormalInputs) { decoded_buf = nullptr; decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_3[i]) << " at " << i; + EXPECT_EQ(src_buf_3[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); } // Check that runs longer than 128 are broken up properly, both matched and -// nonmatched. +// non-matched. TEST(fxcodec, RLETestFullLengthInputs) { // Match, match - uint8_t src_buf_1[260] = {1}; + const uint8_t src_buf_1[260] = {1}; - // Match, nonmatch + // Match, non-match uint8_t src_buf_2[260] = {2}; for (uint16_t i = 128; i < 260; i++) src_buf_2[i] = (uint8_t)(i - 125); - // Nonmatch, match + // Non-match, match uint8_t src_buf_3[260] = {3}; for (uint8_t i = 0; i < 128; i++) src_buf_3[i] = i; - // Nonmatch, nonmatch + // Non-match, non-match uint8_t src_buf_4[260]; for (uint16_t i = 0; i < 260; i++) src_buf_4[i] = (uint8_t)(i); @@ -145,9 +145,9 @@ TEST(fxcodec, RLETestFullLengthInputs) { uint8_t* decoded_buf = nullptr; uint32_t decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_1[i]) << " at " << i; + EXPECT_EQ(src_buf_1[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); @@ -159,9 +159,9 @@ TEST(fxcodec, RLETestFullLengthInputs) { decoded_buf = nullptr; decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_2[i]) << " at " << i; + EXPECT_EQ(src_buf_2[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); @@ -173,9 +173,9 @@ TEST(fxcodec, RLETestFullLengthInputs) { decoded_buf = nullptr; decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_3[i]) << " at " << i; + EXPECT_EQ(src_buf_3[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); @@ -187,9 +187,9 @@ TEST(fxcodec, RLETestFullLengthInputs) { decoded_buf = nullptr; decoded_size = 0; RunLengthDecode(dest_buf, dest_size, decoded_buf, decoded_size); - EXPECT_EQ(decoded_size, src_size); + ASSERT_EQ(src_size, decoded_size); for (uint32_t i = 0; i < src_size; i++) - EXPECT_EQ(decoded_buf[i], src_buf_4[i]) << " at " << i; + EXPECT_EQ(src_buf_4[i], decoded_buf[i]) << " at " << i; FX_Free(dest_buf); FX_Free(decoded_buf); } diff --git a/core/fxcodec/codec/icodec_bmpmodule.h b/core/fxcodec/codec/icodec_bmpmodule.h new file mode 100644 index 000000000..a67e20cf0 --- /dev/null +++ b/core/fxcodec/codec/icodec_bmpmodule.h @@ -0,0 +1,51 @@ +// Copyright 2017 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_FXCODEC_CODEC_ICODEC_BMPMODULE_H_ +#define CORE_FXCODEC_CODEC_ICODEC_BMPMODULE_H_ + +#include "core/fxcrt/fx_system.h" + +struct FXBMP_Context; +class CFX_DIBAttribute; + +// Virtual interface to avoid linking in a concrete implementation +// if we do not enable this codec. +class ICodec_BmpModule { + public: + class Delegate { + public: + virtual bool BmpInputImagePositionBuf(uint32_t rcd_pos) = 0; + virtual void BmpReadScanline(int32_t row_num, uint8_t* row_buf) = 0; + }; + + virtual ~ICodec_BmpModule() {} + + virtual FXBMP_Context* Start() = 0; + virtual void Finish(FXBMP_Context* pContext) = 0; + virtual uint32_t GetAvailInput(FXBMP_Context* pContext, + uint8_t** avail_buf_ptr) = 0; + virtual void Input(FXBMP_Context* pContext, + const uint8_t* src_buf, + uint32_t src_size) = 0; + virtual int32_t ReadHeader(FXBMP_Context* pContext, + int32_t* width, + int32_t* height, + bool* tb_flag, + int32_t* components, + int32_t* pal_num, + uint32_t** pal_pp, + CFX_DIBAttribute* pAttribute) = 0; + virtual int32_t LoadImage(FXBMP_Context* pContext) = 0; + + Delegate* GetDelegate() const { return m_pDelegate; } + void SetDelegate(Delegate* pDelegate) { m_pDelegate = pDelegate; } + + protected: + Delegate* m_pDelegate; +}; + +#endif // CORE_FXCODEC_CODEC_ICODEC_BMPMODULE_H_ diff --git a/core/fxcodec/codec/icodec_gifmodule.h b/core/fxcodec/codec/icodec_gifmodule.h new file mode 100644 index 000000000..9dc0708eb --- /dev/null +++ b/core/fxcodec/codec/icodec_gifmodule.h @@ -0,0 +1,68 @@ +// Copyright 2017 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_FXCODEC_CODEC_ICODEC_GIFMODULE_H_ +#define CORE_FXCODEC_CODEC_ICODEC_GIFMODULE_H_ + +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_system.h" + +class CFX_DIBAttribute; +struct FXGIF_Context; + +// Virtual interface to avoid linking in a concrete implementation +// if we do not enable this codec. +class ICodec_GifModule { + public: + class Delegate { + public: + virtual void GifRecordCurrentPosition(uint32_t& cur_pos) = 0; + virtual uint8_t* GifAskLocalPaletteBuf(int32_t frame_num, + int32_t pal_size) = 0; + virtual bool GifInputRecordPositionBuf(uint32_t rcd_pos, + const FX_RECT& img_rc, + int32_t pal_num, + void* pal_ptr, + int32_t delay_time, + bool user_input, + int32_t trans_index, + int32_t disposal_method, + bool interlace) = 0; + virtual void GifReadScanline(int32_t row_num, uint8_t* row_buf) = 0; + }; + + virtual ~ICodec_GifModule() {} + + virtual FXGIF_Context* Start() = 0; + virtual void Finish(FXGIF_Context* pContext) = 0; + virtual uint32_t GetAvailInput(FXGIF_Context* pContext, + uint8_t** avail_buf_ptr = nullptr) = 0; + + virtual void Input(FXGIF_Context* pContext, + const uint8_t* src_buf, + uint32_t src_size) = 0; + + virtual int32_t ReadHeader(FXGIF_Context* pContext, + int* width, + int* height, + int* pal_num, + void** pal_pp, + int* bg_index, + CFX_DIBAttribute* pAttribute) = 0; + + virtual int32_t LoadFrameInfo(FXGIF_Context* pContext, int* frame_num) = 0; + virtual int32_t LoadFrame(FXGIF_Context* pContext, + int frame_num, + CFX_DIBAttribute* pAttribute) = 0; + + Delegate* GetDelegate() const { return m_pDelegate; } + void SetDelegate(Delegate* pDelegate) { m_pDelegate = pDelegate; } + + protected: + Delegate* m_pDelegate; +}; + +#endif // CORE_FXCODEC_CODEC_ICODEC_GIFMODULE_H_ diff --git a/core/fxcodec/codec/icodec_pngmodule.h b/core/fxcodec/codec/icodec_pngmodule.h new file mode 100644 index 000000000..63e61fe5b --- /dev/null +++ b/core/fxcodec/codec/icodec_pngmodule.h @@ -0,0 +1,47 @@ +// Copyright 2017 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_FXCODEC_CODEC_ICODEC_PNGMODULE_H_ +#define CORE_FXCODEC_CODEC_ICODEC_PNGMODULE_H_ + +#include "core/fxcrt/fx_system.h" + +class CFX_DIBAttribute; +struct FXPNG_Context; + +// Virtual interface to avoid linking in a concrete implementation +// if we do not enable this codec. +class ICodec_PngModule { + public: + class Delegate { + public: + virtual bool PngReadHeader(int width, + int height, + int bpc, + int pass, + int* color_type, + double* gamma) = 0; + virtual bool PngAskScanlineBuf(int line, uint8_t*& src_buf) = 0; + virtual void PngFillScanlineBufCompleted(int pass, int line) = 0; + }; + + virtual ~ICodec_PngModule() {} + + virtual FXPNG_Context* Start() = 0; + virtual void Finish(FXPNG_Context* pContext) = 0; + virtual bool Input(FXPNG_Context* pContext, + const uint8_t* src_buf, + uint32_t src_size, + CFX_DIBAttribute* pAttribute) = 0; + + Delegate* GetDelegate() const { return m_pDelegate; } + void SetDelegate(Delegate* delegate) { m_pDelegate = delegate; } + + protected: + Delegate* m_pDelegate; +}; + +#endif // CORE_FXCODEC_CODEC_ICODEC_PNGMODULE_H_ diff --git a/core/fxcodec/codec/icodec_tiffmodule.h b/core/fxcodec/codec/icodec_tiffmodule.h new file mode 100644 index 000000000..540d82ff6 --- /dev/null +++ b/core/fxcodec/codec/icodec_tiffmodule.h @@ -0,0 +1,36 @@ +// Copyright 2017 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_FXCODEC_CODEC_ICODEC_TIFFMODULE_H_ +#define CORE_FXCODEC_CODEC_ICODEC_TIFFMODULE_H_ + +#include "core/fxcrt/cfx_retain_ptr.h" +#include "core/fxcrt/fx_system.h" + +class CCodec_TiffContext; +class CFX_DIBAttribute; +class CFX_DIBitmap; +class IFX_SeekableReadStream; + +class ICodec_TiffModule { + public: + virtual ~ICodec_TiffModule() {} + + virtual CCodec_TiffContext* CreateDecoder( + const CFX_RetainPtr<IFX_SeekableReadStream>& file_ptr) = 0; + virtual bool LoadFrameInfo(CCodec_TiffContext* ctx, + int32_t frame, + int32_t* width, + int32_t* height, + int32_t* comps, + int32_t* bpc, + CFX_DIBAttribute* pAttribute) = 0; + virtual bool Decode(CCodec_TiffContext* ctx, + class CFX_DIBitmap* pDIBitmap) = 0; + virtual void DestroyDecoder(CCodec_TiffContext* ctx) = 0; +}; + +#endif // CORE_FXCODEC_CODEC_ICODEC_TIFFMODULE_H_ diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h index bb4766567..b0b9fa182 100644 --- a/core/fxcodec/fx_codec.h +++ b/core/fxcodec/fx_codec.h @@ -9,6 +9,7 @@ #include <map> #include <memory> +#include <utility> #include <vector> #include "core/fxcodec/codec/ccodec_basicmodule.h" @@ -23,17 +24,19 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_coordinates.h" +#ifdef PDF_ENABLE_XFA +#include "core/fxcodec/codec/icodec_bmpmodule.h" +#include "core/fxcodec/codec/icodec_gifmodule.h" +#include "core/fxcodec/codec/icodec_pngmodule.h" +#include "core/fxcodec/codec/icodec_tiffmodule.h" +#endif // PDF_ENABLE_XFA + class CFX_DIBSource; class CJPX_Decoder; class CPDF_ColorSpace; class CPDF_StreamAcc; #ifdef PDF_ENABLE_XFA -#include "core/fxcodec/codec/ccodec_bmpmodule.h" -#include "core/fxcodec/codec/ccodec_gifmodule.h" -#include "core/fxcodec/codec/ccodec_pngmodule.h" -#include "core/fxcodec/codec/ccodec_tiffmodule.h" - class CCodec_ProgressiveDecoder; class CFX_DIBAttribute { @@ -70,11 +73,23 @@ class CCodec_ModuleMgr { CCodec_FlateModule* GetFlateModule() const { return m_pFlateModule.get(); } #ifdef PDF_ENABLE_XFA - CCodec_ProgressiveDecoder* CreateProgressiveDecoder(); - CCodec_PngModule* GetPngModule() const { return m_pPngModule.get(); } - CCodec_GifModule* GetGifModule() const { return m_pGifModule.get(); } - CCodec_BmpModule* GetBmpModule() const { return m_pBmpModule.get(); } - CCodec_TiffModule* GetTiffModule() const { return m_pTiffModule.get(); } + std::unique_ptr<CCodec_ProgressiveDecoder> CreateProgressiveDecoder(); + void SetBmpModule(std::unique_ptr<ICodec_BmpModule> module) { + m_pBmpModule = std::move(module); + } + void SetGifModule(std::unique_ptr<ICodec_GifModule> module) { + m_pGifModule = std::move(module); + } + void SetPngModule(std::unique_ptr<ICodec_PngModule> module) { + m_pPngModule = std::move(module); + } + void SetTiffModule(std::unique_ptr<ICodec_TiffModule> module) { + m_pTiffModule = std::move(module); + } + ICodec_BmpModule* GetBmpModule() const { return m_pBmpModule.get(); } + ICodec_GifModule* GetGifModule() const { return m_pGifModule.get(); } + ICodec_PngModule* GetPngModule() const { return m_pPngModule.get(); } + ICodec_TiffModule* GetTiffModule() const { return m_pTiffModule.get(); } #endif // PDF_ENABLE_XFA protected: @@ -86,10 +101,10 @@ class CCodec_ModuleMgr { std::unique_ptr<CCodec_IccModule> m_pIccModule; #ifdef PDF_ENABLE_XFA - std::unique_ptr<CCodec_PngModule> m_pPngModule; - std::unique_ptr<CCodec_GifModule> m_pGifModule; - std::unique_ptr<CCodec_BmpModule> m_pBmpModule; - std::unique_ptr<CCodec_TiffModule> m_pTiffModule; + std::unique_ptr<ICodec_BmpModule> m_pBmpModule; + std::unique_ptr<ICodec_GifModule> m_pGifModule; + std::unique_ptr<ICodec_PngModule> m_pPngModule; + std::unique_ptr<ICodec_TiffModule> m_pTiffModule; #endif // PDF_ENABLE_XFA std::unique_ptr<CCodec_FlateModule> m_pFlateModule; diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp index 93db181a9..d62dacb36 100644 --- a/core/fxcodec/lgif/fx_gif.cpp +++ b/core/fxcodec/lgif/fx_gif.cpp @@ -114,7 +114,17 @@ int32_t CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t& des_size) { FXSYS_strncpy(err_msg_ptr, "Decode Error", GIF_MAX_ERROR_SIZE - 1); return 0; } - code_store |= (*next_in++) << bits_left; + pdfium::base::CheckedNumeric<uint32_t> safe_code = *next_in++; + safe_code <<= bits_left; + safe_code |= code_store; + if (!safe_code.IsValid()) { + if (err_msg_ptr) { + FXSYS_strncpy(err_msg_ptr, "Code Store Out Of Range", + GIF_MAX_ERROR_SIZE - 1); + } + return 0; + } + code_store = safe_code.ValueOrDie(); avail_in--; bits_left += 8; } diff --git a/core/fxcrt/cfx_retain_ptr.h b/core/fxcrt/cfx_retain_ptr.h index 62b26942b..0267ae04c 100644 --- a/core/fxcrt/cfx_retain_ptr.h +++ b/core/fxcrt/cfx_retain_ptr.h @@ -30,6 +30,11 @@ class CFX_RetainPtr { template <class U> CFX_RetainPtr(const CFX_RetainPtr<U>& that) : CFX_RetainPtr(that.Get()) {} + template <class U> + CFX_RetainPtr<U> As() const { + return CFX_RetainPtr<U>(static_cast<U*>(Get())); + } + void Reset(T* obj = nullptr) { if (obj) obj->Retain(); diff --git a/core/fxcrt/cfx_string_data_template.h b/core/fxcrt/cfx_string_data_template.h index affd61001..c3e090fef 100644 --- a/core/fxcrt/cfx_string_data_template.h +++ b/core/fxcrt/cfx_string_data_template.h @@ -30,7 +30,8 @@ class CFX_StringDataTemplate { // where we can save a re-alloc when adding a few characters to a string // by using this otherwise wasted space. nSize += 7; - int totalSize = nSize.ValueOrDie() & ~7; + nSize &= ~7; + int totalSize = nSize.ValueOrDie(); int usableLen = (totalSize - overhead) / sizeof(CharType); ASSERT(usableLen >= nLen); diff --git a/core/fxcrt/fx_arabic.cpp b/core/fxcrt/fx_arabic.cpp index d6b3c6522..108c6c19a 100644 --- a/core/fxcrt/fx_arabic.cpp +++ b/core/fxcrt/fx_arabic.cpp @@ -5,7 +5,12 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/fxcrt/fx_arabic.h" + +#include <algorithm> +#include <vector> + #include "core/fxcrt/fx_ucd.h" +#include "third_party/base/stl_util.h" namespace { @@ -374,7 +379,7 @@ int32_t FX_BidiGetResolvedNeutrals(int32_t iAction) { int32_t FX_BidiReorderLevel(int32_t iBaseLevel, CFX_WideString& wsText, - const CFX_Int32Array& levels, + const CFX_ArrayTemplate<int32_t>& levels, int32_t iStart, bool bReverse) { ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); @@ -403,7 +408,7 @@ int32_t FX_BidiReorderLevel(int32_t iBaseLevel, } void FX_BidiReorder(int32_t iBaseLevel, CFX_WideString& wsText, - const CFX_Int32Array& levels) { + const CFX_ArrayTemplate<int32_t>& levels) { ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); ASSERT(wsText.GetLength() == levels.GetSize()); int32_t iSize = wsText.GetLength(); @@ -419,81 +424,62 @@ void FX_BidiReorder(int32_t iBaseLevel, template <class baseType> class CFX_BidiLineTemplate { public: - void FX_BidiReverseString(CFX_ArrayTemplate<baseType>& chars, + void FX_BidiReverseString(std::vector<baseType>& chars, int32_t iStart, int32_t iCount) { - ASSERT(iStart > -1 && iStart < chars.GetSize()); - ASSERT(iCount >= 0 && iStart + iCount <= chars.GetSize()); - baseType *pStart, *pEnd; - int32_t iEnd = iStart + iCount - 1, iTemp; - while (iStart < iEnd) { - pStart = chars.GetDataPtr(iStart++); - pEnd = chars.GetDataPtr(iEnd--); - iTemp = pStart->m_iBidiPos; - pStart->m_iBidiPos = pEnd->m_iBidiPos; - pEnd->m_iBidiPos = iTemp; - } + ASSERT(iStart >= 0 && iStart < pdfium::CollectionSize<int32_t>(chars)); + ASSERT(iCount >= 0 && + iStart + iCount <= pdfium::CollectionSize<int32_t>(chars)); + std::reverse(chars.begin() + iStart, chars.begin() + iStart + iCount); } - void FX_BidiSetDeferredRun(CFX_ArrayTemplate<baseType>& chars, + + void FX_BidiSetDeferredRun(std::vector<baseType>& chars, bool bClass, int32_t iStart, int32_t iCount, int32_t iValue) { - ASSERT(iStart > -1 && iStart <= chars.GetSize()); + ASSERT(iStart >= 0 && iStart <= pdfium::CollectionSize<int32_t>(chars)); ASSERT(iStart - iCount > -1); - baseType* pTC; int32_t iLast = iStart - iCount; if (bClass) { - for (int32_t i = iStart - 1; i >= iLast; i--) { - pTC = chars.GetDataPtr(i); - pTC->m_iBidiClass = (int16_t)iValue; - } + for (int32_t i = iStart - 1; i >= iLast; i--) + chars[i].m_iBidiClass = (int16_t)iValue; } else { - for (int32_t i = iStart - 1; i >= iLast; i--) { - pTC = chars.GetDataPtr(i); - pTC->m_iBidiLevel = (int16_t)iValue; - } + for (int32_t i = iStart - 1; i >= iLast; i--) + chars[i].m_iBidiLevel = (int16_t)iValue; } } - void FX_BidiClassify(CFX_ArrayTemplate<baseType>& chars, - int32_t iCount, - bool bWS) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); - baseType* pTC; + + void FX_BidiClassify(std::vector<baseType>& chars, int32_t iCount, bool bWS) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); if (bWS) { for (int32_t i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); - pTC->m_iBidiClass = - (int16_t)(pTC->m_dwCharProps & FX_BIDICLASSBITSMASK) >> + chars[i].m_iBidiClass = + (int16_t)(chars[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS; } } else { for (int32_t i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); - pTC->m_iBidiClass = (int16_t) - gc_FX_BidiNTypes[(pTC->m_dwCharProps & FX_BIDICLASSBITSMASK) >> + chars[i].m_iBidiClass = (int16_t) + gc_FX_BidiNTypes[(chars[i].m_dwCharProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS]; } } } - void FX_BidiResolveExplicit(CFX_ArrayTemplate<baseType>& chars, + + void FX_BidiResolveExplicit(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); - if (iCount < 1) { - return; - } - baseType* pTC; - for (int32_t i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); - pTC->m_iBidiLevel = (int16_t)iBaseLevel; - } + for (int32_t i = 0; i < iCount; i++) + chars[i].m_iBidiLevel = static_cast<int16_t>(iBaseLevel); } - void FX_BidiResolveWeak(CFX_ArrayTemplate<baseType>& chars, + + void FX_BidiResolveWeak(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); iCount--; if (iCount < 1) { return; @@ -503,7 +489,7 @@ class CFX_BidiLineTemplate { int32_t iState = FX_IsOdd(iBaseLevel) ? FX_BWSxr : FX_BWSxl; int32_t i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction; for (; i <= iCount; i++) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; iClsCur = pTC->m_iBidiClass; if (iClsCur == FX_BIDICLASS_BN) { pTC->m_iBidiLevel = (int16_t)iLevelCur; @@ -511,7 +497,7 @@ class CFX_BidiLineTemplate { iClsCur = FX_BidiDirection(iLevelCur); pTC->m_iBidiClass = (int16_t)iClsCur; } else if (i < iCount) { - pTCNext = chars.GetDataPtr(i + 1); + pTCNext = &chars[i + 1]; int32_t iLevelNext, iLevelNew; iClsNew = pTCNext->m_iBidiClass; iLevelNext = pTCNext->m_iBidiLevel; @@ -561,10 +547,11 @@ class CFX_BidiLineTemplate { } } } - void FX_BidiResolveNeutrals(CFX_ArrayTemplate<baseType>& chars, + + void FX_BidiResolveNeutrals(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); iCount--; if (iCount < 1) { @@ -575,7 +562,7 @@ class CFX_BidiLineTemplate { int32_t iState = FX_IsOdd(iBaseLevel) ? FX_BNSr : FX_BNSl; int32_t i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction; for (; i <= iCount; i++) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; iClsCur = pTC->m_iBidiClass; if (iClsCur == FX_BIDICLASS_BN) { if (iNum) { @@ -609,27 +596,25 @@ class CFX_BidiLineTemplate { } } } - void FX_BidiResolveImplicit(CFX_ArrayTemplate<baseType>& chars, - int32_t iCount) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); - baseType* pTC; - int32_t iCls, iLevel; + + void FX_BidiResolveImplicit(std::vector<baseType>& chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); for (int32_t i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); - iCls = pTC->m_iBidiClass; + int32_t iCls = chars[i].m_iBidiClass; if (iCls == FX_BIDICLASS_BN) { continue; } ASSERT(iCls > FX_BIDICLASS_ON && iCls < FX_BIDICLASS_AL); - iLevel = pTC->m_iBidiLevel; + int32_t iLevel = chars[i].m_iBidiLevel; iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1]; - pTC->m_iBidiLevel = (int16_t)iLevel; + chars[i].m_iBidiLevel = (int16_t)iLevel; } } - void FX_BidiResolveWhitespace(CFX_ArrayTemplate<baseType>& chars, + + void FX_BidiResolveWhitespace(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); if (iCount < 1) { return; @@ -637,10 +622,8 @@ class CFX_BidiLineTemplate { iCount--; int32_t iLevel = iBaseLevel; int32_t i = 0, iNum = 0; - baseType* pTC; for (; i <= iCount; i++) { - pTC = chars.GetDataPtr(i); - switch (pTC->m_iBidiClass) { + switch (chars[i].m_iBidiClass) { case FX_BIDICLASS_WS: iNum++; break; @@ -650,7 +633,7 @@ class CFX_BidiLineTemplate { case FX_BIDICLASS_RLO: case FX_BIDICLASS_PDF: case FX_BIDICLASS_BN: - pTC->m_iBidiLevel = (int16_t)iLevel; + chars[i].m_iBidiLevel = (int16_t)iLevel; iNum++; break; case FX_BIDICLASS_S: @@ -658,41 +641,39 @@ class CFX_BidiLineTemplate { if (iNum > 0) { FX_BidiSetDeferredRun(chars, false, i, iNum, iBaseLevel); } - pTC->m_iBidiLevel = (int16_t)iBaseLevel; + chars[i].m_iBidiLevel = (int16_t)iBaseLevel; iNum = 0; break; default: iNum = 0; break; } - iLevel = pTC->m_iBidiLevel; + iLevel = chars[i].m_iBidiLevel; } if (iNum > 0) { FX_BidiSetDeferredRun(chars, false, i, iNum, iBaseLevel); } } - int32_t FX_BidiReorderLevel(CFX_ArrayTemplate<baseType>& chars, + + int32_t FX_BidiReorderLevel(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel, int32_t iStart, bool bReverse) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); ASSERT(iStart >= 0 && iStart < iCount); if (iCount < 1) { return 0; } - baseType* pTC; bReverse = bReverse || FX_IsOdd(iBaseLevel); - int32_t i = iStart, iLevel; + int32_t i = iStart; for (; i < iCount; i++) { - pTC = chars.GetDataPtr(i); - if ((iLevel = pTC->m_iBidiLevel) == iBaseLevel) { + int32_t iLevel = chars[i].m_iBidiLevel; + if (iLevel == iBaseLevel) continue; - } - if (iLevel < iBaseLevel) { + if (iLevel < iBaseLevel) break; - } i += FX_BidiReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1; } int32_t iNum = i - iStart; @@ -701,31 +682,28 @@ class CFX_BidiLineTemplate { } return iNum; } - void FX_BidiReorder(CFX_ArrayTemplate<baseType>& chars, + + void FX_BidiReorder(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); ASSERT(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL); int32_t i = 0; while (i < iCount) { i += FX_BidiReorderLevel(chars, iCount, iBaseLevel, i, false); } } - void FX_BidiPosition(CFX_ArrayTemplate<baseType>& chars, int32_t iCount) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); - baseType* pTC; - int32_t i = 0; - while (i < iCount) { - pTC = chars.GetDataPtr(i); - pTC = chars.GetDataPtr(pTC->m_iBidiPos); - pTC->m_iBidiOrder = i++; - } + + void FX_BidiPosition(std::vector<baseType>& chars, int32_t iCount) { + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); + for (int32_t i = 0; i < iCount; ++i) + chars[chars[i].m_iBidiPos].m_iBidiOrder = i; } - void FX_BidiLine(CFX_ArrayTemplate<baseType>& chars, + void FX_BidiLine(std::vector<baseType>& chars, int32_t iCount, int32_t iBaseLevel) { - ASSERT(iCount > -1 && iCount <= chars.GetSize()); + ASSERT(iCount >= 0 && iCount <= pdfium::CollectionSize<int32_t>(chars)); if (iCount < 2) { return; } @@ -740,11 +718,16 @@ class CFX_BidiLineTemplate { FX_BidiPosition(chars, iCount); } }; -void FX_BidiLine(CFX_TxtCharArray& chars, int32_t iCount, int32_t iBaseLevel) { + +void FX_BidiLine(std::vector<CFX_TxtChar>& chars, + int32_t iCount, + int32_t iBaseLevel) { CFX_BidiLineTemplate<CFX_TxtChar> blt; blt.FX_BidiLine(chars, iCount, iBaseLevel); } -void FX_BidiLine(CFX_RTFCharArray& chars, int32_t iCount, int32_t iBaseLevel) { +void FX_BidiLine(std::vector<CFX_RTFChar>& chars, + int32_t iCount, + int32_t iBaseLevel) { CFX_BidiLineTemplate<CFX_RTFChar> blt; blt.FX_BidiLine(chars, iCount, iBaseLevel); } diff --git a/core/fxcrt/fx_arabic.h b/core/fxcrt/fx_arabic.h index 1f4d38b88..e7ba079f4 100644 --- a/core/fxcrt/fx_arabic.h +++ b/core/fxcrt/fx_arabic.h @@ -30,17 +30,17 @@ FX_WCHAR GetFormChar(const CFX_Char* cur, void FX_BidiReverseString(CFX_WideString& wsText, int32_t iStart, int32_t iCount); -void FX_BidiSetDeferredRun(CFX_Int32Array& values, +void FX_BidiSetDeferredRun(CFX_ArrayTemplate<int32_t>& values, int32_t iStart, int32_t iCount, int32_t iValue); void FX_BidiClassify(const CFX_WideString& wsText, - CFX_Int32Array& classes, + CFX_ArrayTemplate<int32_t>& classes, bool bWS = false); int32_t FX_BidiResolveExplicit(int32_t iBaseLevel, int32_t iDirection, - CFX_Int32Array& classes, - CFX_Int32Array& levels, + CFX_ArrayTemplate<int32_t>& classes, + CFX_ArrayTemplate<int32_t>& levels, int32_t iStart, int32_t iCount, int32_t iNest = 0); @@ -136,8 +136,8 @@ enum FX_BIDIWEAKACTION { #define FX_BWALxx FX_BIDIWEAKACTION_Lxx void FX_BidiResolveWeak(int32_t iBaseLevel, - CFX_Int32Array& classes, - CFX_Int32Array& levels); + CFX_ArrayTemplate<int32_t>& classes, + CFX_ArrayTemplate<int32_t>& levels); enum FX_BIDINEUTRALSTATE { FX_BIDINEUTRALSTATE_r = 0, FX_BIDINEUTRALSTATE_l, @@ -169,20 +169,20 @@ enum FX_BIDINEUTRALACTION { int32_t FX_BidiGetDeferredNeutrals(int32_t iAction, int32_t iLevel); int32_t FX_BidiGetResolvedNeutrals(int32_t iAction); void FX_BidiResolveNeutrals(int32_t iBaseLevel, - CFX_Int32Array& classes, - const CFX_Int32Array& levels); -void FX_BidiResolveImplicit(const CFX_Int32Array& classes, - CFX_Int32Array& levels); + CFX_ArrayTemplate<int32_t>& classes, + const CFX_ArrayTemplate<int32_t>& levels); +void FX_BidiResolveImplicit(const CFX_ArrayTemplate<int32_t>& classes, + CFX_ArrayTemplate<int32_t>& levels); void FX_BidiResolveWhitespace(int32_t iBaseLevel, - const CFX_Int32Array& classes, - CFX_Int32Array& levels); + const CFX_ArrayTemplate<int32_t>& classes, + CFX_ArrayTemplate<int32_t>& levels); int32_t FX_BidiReorderLevel(int32_t iBaseLevel, CFX_WideString& wsText, - const CFX_Int32Array& levels, + const CFX_ArrayTemplate<int32_t>& levels, int32_t iStart, bool bReverse = false); void FX_BidiReorder(int32_t iBaseLevel, CFX_WideString& wsText, - const CFX_Int32Array& levels); + const CFX_ArrayTemplate<int32_t>& levels); #endif // CORE_FXCRT_FX_ARABIC_H_ diff --git a/core/fxcrt/fx_arb.h b/core/fxcrt/fx_arb.h index 6d556fe9f..d24197c7e 100644 --- a/core/fxcrt/fx_arb.h +++ b/core/fxcrt/fx_arb.h @@ -7,6 +7,8 @@ #ifndef CORE_FXCRT_FX_ARB_H_ #define CORE_FXCRT_FX_ARB_H_ +#include <vector> + #include "core/fxcrt/fx_system.h" #include "core/fxcrt/fx_ucd.h" @@ -39,10 +41,10 @@ enum FX_ARBPOSITION { }; void FX_BidiLine(CFX_WideString& wsText, int32_t iBaseLevel = 0); -void FX_BidiLine(CFX_TxtCharArray& chars, +void FX_BidiLine(std::vector<CFX_TxtChar>& chars, int32_t iCount, int32_t iBaseLevel = 0); -void FX_BidiLine(CFX_RTFCharArray& chars, +void FX_BidiLine(std::vector<CFX_RTFChar>& chars, int32_t iCount, int32_t iBaseLevel = 0); diff --git a/core/fxcrt/fx_basic.h b/core/fxcrt/fx_basic.h index 5adcf701c..18413b2e7 100644 --- a/core/fxcrt/fx_basic.h +++ b/core/fxcrt/fx_basic.h @@ -16,6 +16,10 @@ #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" +#ifdef PDF_ENABLE_XFA +#define FX_IsOdd(a) ((a)&1) +#endif // PDF_ENABLE_XFA + class CFX_BinaryBuf { public: CFX_BinaryBuf(); @@ -313,11 +317,6 @@ class CFX_ArrayTemplate : public CFX_BasicArray { } }; -#ifdef PDF_ENABLE_XFA -typedef CFX_ArrayTemplate<uint8_t> CFX_ByteArray; -typedef CFX_ArrayTemplate<int32_t> CFX_Int32Array; -#endif // PDF_ENABLE_XFA - template <class DataType, int FixedSize> class CFX_FixedBufGrow { public: @@ -357,9 +356,7 @@ class CFX_BitStream { protected: uint32_t m_BitPos; - uint32_t m_BitSize; - const uint8_t* m_pData; }; @@ -505,18 +502,6 @@ typedef CFX_ListArrayTemplate<CFX_SortListArray<sizeof(FX_FILESIZE)>, FX_FILESIZE> CFX_FileSizeListArray; -#ifdef PDF_ENABLE_XFA -class IFX_Retainable { - public: - virtual uint32_t Retain() = 0; - virtual uint32_t Release() = 0; - - protected: - virtual ~IFX_Retainable() {} -}; -#define FX_IsOdd(a) ((a)&1) -#endif // PDF_ENABLE_XFA - class CFX_Vector_3by1 { public: CFX_Vector_3by1() : a(0.0f), b(0.0f), c(0.0f) {} diff --git a/core/fxcrt/fx_basic_array.cpp b/core/fxcrt/fx_basic_array.cpp index 92df0e00f..83c981e9e 100644 --- a/core/fxcrt/fx_basic_array.cpp +++ b/core/fxcrt/fx_basic_array.cpp @@ -33,7 +33,8 @@ bool CFX_BasicArray::SetSize(int nNewSize) { m_nSize = m_nMaxSize = 0; return false; } - m_pData = FX_Alloc(uint8_t, totalSize.ValueOrDie()); + m_pData = + FX_Alloc(uint8_t, pdfium::base::ValueOrDieForType<size_t>(totalSize)); m_nSize = m_nMaxSize = nNewSize; } else if (nNewSize <= m_nMaxSize) { if (nNewSize > m_nSize) { @@ -48,7 +49,8 @@ bool CFX_BasicArray::SetSize(int nNewSize) { if (!totalSize.IsValid() || nNewMax < m_nSize) { return false; } - uint8_t* pNewData = FX_Realloc(uint8_t, m_pData, totalSize.ValueOrDie()); + uint8_t* pNewData = FX_Realloc( + uint8_t, m_pData, pdfium::base::ValueOrDieForType<size_t>(totalSize)); if (!pNewData) { return false; } diff --git a/core/fxcrt/fx_basic_coords.cpp b/core/fxcrt/fx_basic_coords.cpp index d2bcc2b3e..cb5a01042 100644 --- a/core/fxcrt/fx_basic_coords.cpp +++ b/core/fxcrt/fx_basic_coords.cpp @@ -6,9 +6,26 @@ #include <limits.h> +#include <algorithm> + #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_ext.h" +namespace { + +void MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int* i1, int* i2) { + int length = static_cast<int>(FXSYS_ceil(f2 - f1)); + int i1_1 = static_cast<int>(FXSYS_floor(f1)); + int i1_2 = static_cast<int>(FXSYS_ceil(f1)); + FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); + FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); + + *i1 = (error1 > error2) ? i1_2 : i1_1; + *i2 = *i1 + length; +} + +} // namespace + void FX_RECT::Normalize() { if (left > right) { int temp = left; @@ -33,15 +50,7 @@ void FX_RECT::Intersect(const FX_RECT& src) { left = top = right = bottom = 0; } } -void FX_RECT::Union(const FX_RECT& other_rect) { - Normalize(); - FX_RECT other = other_rect; - other.Normalize(); - left = left < other.left ? left : other.left; - right = right > other.right ? right : other.right; - bottom = bottom > other.bottom ? bottom : other.bottom; - top = top < other.top ? top : other.top; -} + bool GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, @@ -105,9 +114,7 @@ void CFX_FloatRect::Union(const CFX_FloatRect& other_rect) { bottom = bottom < other.bottom ? bottom : other.bottom; top = top > other.top ? top : other.top; } -void CFX_FloatRect::Transform(const CFX_Matrix* pMatrix) { - pMatrix->TransformRect(left, right, top, bottom); -} + int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects) { Normalize(); s.Normalize(); @@ -150,6 +157,7 @@ int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects) { } return nRects; } + FX_RECT CFX_FloatRect::GetOuterRect() const { CFX_FloatRect rect1 = *this; FX_RECT rect; @@ -160,6 +168,7 @@ FX_RECT CFX_FloatRect::GetOuterRect() const { rect.Normalize(); return rect; } + FX_RECT CFX_FloatRect::GetInnerRect() const { CFX_FloatRect rect1 = *this; FX_RECT rect; @@ -170,24 +179,23 @@ FX_RECT CFX_FloatRect::GetInnerRect() const { rect.Normalize(); return rect; } -static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2) { - int length = (int)FXSYS_ceil(f2 - f1); - int i1_1 = (int)FXSYS_floor(f1); - int i1_2 = (int)FXSYS_ceil(f1); - FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); - FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); - i1 = (error1 > error2) ? i1_2 : i1_1; - i2 = i1 + length; -} + FX_RECT CFX_FloatRect::GetClosestRect() const { CFX_FloatRect rect1 = *this; FX_RECT rect; - _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right); - _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom); + MatchFloatRange(rect1.left, rect1.right, &rect.left, &rect.right); + MatchFloatRange(rect1.bottom, rect1.top, &rect.top, &rect.bottom); rect.Normalize(); return rect; } +bool CFX_FloatRect::Contains(const CFX_PointF& point) const { + CFX_FloatRect n1(*this); + n1.Normalize(); + return point.x <= n1.right && point.x >= n1.left && point.y <= n1.top && + point.y >= n1.bottom; +} + bool CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const { CFX_FloatRect n1(*this); CFX_FloatRect n2(other_rect); @@ -197,74 +205,35 @@ bool CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const { n2.top <= n1.top; } -bool CFX_FloatRect::Contains(FX_FLOAT x, FX_FLOAT y) const { - CFX_FloatRect n1(*this); - n1.Normalize(); - return x <= n1.right && x >= n1.left && y <= n1.top && y >= n1.bottom; -} - void CFX_FloatRect::UpdateRect(FX_FLOAT x, FX_FLOAT y) { - if (left > x) { - left = x; - } - if (right < x) { - right = x; - } - if (bottom > y) { - bottom = y; - } - if (top < y) { - top = y; - } + left = std::min(left, x); + right = std::max(right, x); + bottom = std::min(bottom, y); + top = std::max(top, y); } + CFX_FloatRect CFX_FloatRect::GetBBox(const CFX_PointF* pPoints, int nPoints) { - if (nPoints == 0) { + if (nPoints == 0) return CFX_FloatRect(); - } - FX_FLOAT min_x = pPoints->x, max_x = pPoints->x, min_y = pPoints->y, - max_y = pPoints->y; + + FX_FLOAT min_x = pPoints->x; + FX_FLOAT max_x = pPoints->x; + FX_FLOAT min_y = pPoints->y; + FX_FLOAT max_y = pPoints->y; for (int i = 1; i < nPoints; i++) { - if (min_x > pPoints[i].x) { - min_x = pPoints[i].x; - } - if (max_x < pPoints[i].x) { - max_x = pPoints[i].x; - } - if (min_y > pPoints[i].y) { - min_y = pPoints[i].y; - } - if (max_y < pPoints[i].y) { - max_y = pPoints[i].y; - } + min_x = std::min(min_x, pPoints[i].x); + max_x = std::max(max_x, pPoints[i].x); + min_y = std::min(min_y, pPoints[i].y); + max_y = std::max(max_y, pPoints[i].y); } return CFX_FloatRect(min_x, min_y, max_x, max_y); } -void CFX_Matrix::Set(FX_FLOAT other_a, - FX_FLOAT other_b, - FX_FLOAT other_c, - FX_FLOAT other_d, - FX_FLOAT other_e, - FX_FLOAT other_f) { - a = other_a; - b = other_b; - c = other_c; - d = other_d; - e = other_e; - f = other_f; -} -void CFX_Matrix::Set(const FX_FLOAT n[6]) { - a = n[0]; - b = n[1]; - c = n[2]; - d = n[3]; - e = n[4]; - f = n[5]; -} + void CFX_Matrix::SetReverse(const CFX_Matrix& m) { FX_FLOAT i = m.a * m.d - m.b * m.c; - if (FXSYS_fabs(i) == 0) { + if (FXSYS_fabs(i) == 0) return; - } + FX_FLOAT j = -i; a = m.d / i; b = m.b / j; @@ -273,82 +242,59 @@ void CFX_Matrix::SetReverse(const CFX_Matrix& m) { e = (m.c * m.f - m.d * m.e) / i; f = (m.a * m.f - m.b * m.e) / j; } -static void FXCRT_Matrix_Concat(CFX_Matrix& m, - const CFX_Matrix& m1, - const CFX_Matrix& m2) { - FX_FLOAT aa = m1.a * m2.a + m1.b * m2.c; - FX_FLOAT bb = m1.a * m2.b + m1.b * m2.d; - FX_FLOAT cc = m1.c * m2.a + m1.d * m2.c; - FX_FLOAT dd = m1.c * m2.b + m1.d * m2.d; - FX_FLOAT ee = m1.e * m2.a + m1.f * m2.c + m2.e; - FX_FLOAT ff = m1.e * m2.b + m1.f * m2.d + m2.f; - m.a = aa, m.b = bb, m.c = cc, m.d = dd, m.e = ee, m.f = ff; -} -void CFX_Matrix::Concat(FX_FLOAT a_in, - FX_FLOAT b_in, - FX_FLOAT c_in, - FX_FLOAT d_in, - FX_FLOAT e_in, - FX_FLOAT f_in, - bool bPrepended) { - CFX_Matrix m; - m.Set(a_in, b_in, c_in, d_in, e_in, f_in); - Concat(m, bPrepended); -} + void CFX_Matrix::Concat(const CFX_Matrix& m, bool bPrepended) { - if (bPrepended) { - FXCRT_Matrix_Concat(*this, m, *this); - } else { - FXCRT_Matrix_Concat(*this, *this, m); - } + ConcatInternal(m, bPrepended); } + void CFX_Matrix::ConcatInverse(const CFX_Matrix& src, bool bPrepended) { CFX_Matrix m; m.SetReverse(src); Concat(m, bPrepended); } -bool CFX_Matrix::IsInvertible() const { - return FXSYS_fabs(a * d - b * c) >= 0.0001f; -} + bool CFX_Matrix::Is90Rotated() const { return FXSYS_fabs(a * 1000) < FXSYS_fabs(b) && FXSYS_fabs(d * 1000) < FXSYS_fabs(c); } + bool CFX_Matrix::IsScaled() const { return FXSYS_fabs(b * 1000) < FXSYS_fabs(a) && FXSYS_fabs(c * 1000) < FXSYS_fabs(d); } + void CFX_Matrix::Translate(FX_FLOAT x, FX_FLOAT y, bool bPrepended) { if (bPrepended) { e += x * a + y * c; f += y * d + x * b; - } else { - e += x, f += y; + return; } + e += x; + f += y; } + void CFX_Matrix::Scale(FX_FLOAT sx, FX_FLOAT sy, bool bPrepended) { - a *= sx, d *= sy; + a *= sx; + d *= sy; if (bPrepended) { b *= sx; c *= sy; - } else { - b *= sy; - c *= sx; - e *= sx; - f *= sy; + return; } + + b *= sy; + c *= sx; + e *= sx; + f *= sy; } + void CFX_Matrix::Rotate(FX_FLOAT fRadian, bool bPrepended) { FX_FLOAT cosValue = FXSYS_cos(fRadian); FX_FLOAT sinValue = FXSYS_sin(fRadian); - CFX_Matrix m; - m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0); - if (bPrepended) { - FXCRT_Matrix_Concat(*this, m, *this); - } else { - FXCRT_Matrix_Concat(*this, *this, m); - } + ConcatInternal(CFX_Matrix(cosValue, sinValue, -sinValue, cosValue, 0, 0), + bPrepended); } + void CFX_Matrix::RotateAt(FX_FLOAT fRadian, FX_FLOAT dx, FX_FLOAT dy, @@ -357,21 +303,20 @@ void CFX_Matrix::RotateAt(FX_FLOAT fRadian, Rotate(fRadian, bPrepended); Translate(-dx, -dy, bPrepended); } + void CFX_Matrix::Shear(FX_FLOAT fAlphaRadian, FX_FLOAT fBetaRadian, bool bPrepended) { - CFX_Matrix m; - m.Set(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0); - if (bPrepended) { - FXCRT_Matrix_Concat(*this, m, *this); - } else { - FXCRT_Matrix_Concat(*this, *this, m); - } + ConcatInternal( + CFX_Matrix(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0), + bPrepended); } + void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src) { FX_FLOAT fDiff = src.left - src.right; a = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.left - dest.right) / fDiff; + fDiff = src.bottom - src.top; d = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.bottom - dest.top) / fDiff; e = dest.left - src.left * a; @@ -379,139 +324,93 @@ void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, b = 0; c = 0; } + FX_FLOAT CFX_Matrix::GetXUnit() const { - if (b == 0) { + if (b == 0) return (a > 0 ? a : -a); - } - if (a == 0) { + if (a == 0) return (b > 0 ? b : -b); - } return FXSYS_sqrt(a * a + b * b); } + FX_FLOAT CFX_Matrix::GetYUnit() const { - if (c == 0) { + if (c == 0) return (d > 0 ? d : -d); - } - if (d == 0) { + if (d == 0) return (c > 0 ? c : -c); - } return FXSYS_sqrt(c * c + d * d); } -void CFX_Matrix::GetUnitRect(CFX_RectF& rect) const { - rect.left = rect.top = 0; - rect.width = rect.height = 1; - TransformRect(rect); -} + CFX_FloatRect CFX_Matrix::GetUnitRect() const { CFX_FloatRect rect(0, 0, 1, 1); - rect.Transform((const CFX_Matrix*)this); + TransformRect(rect); return rect; } -FX_FLOAT CFX_Matrix::GetUnitArea() const { - FX_FLOAT A = FXSYS_sqrt(a * a + b * b); - FX_FLOAT B = FXSYS_sqrt(c * c + d * d); - FX_FLOAT ac = a + c, bd = b + d; - FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd); - FX_FLOAT P = (A + B + C) / 2; - return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2; -} + FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const { - FX_FLOAT fx = a * dx, fy = b * dx; + FX_FLOAT fx = a * dx; + FX_FLOAT fy = b * dx; return FXSYS_sqrt(fx * fx + fy * fy); } -int32_t CFX_Matrix::TransformXDistance(int32_t dx) const { - FX_FLOAT fx = a * dx, fy = b * dx; - return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); -} -FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const { - FX_FLOAT fx = c * dy, fy = d * dy; - return FXSYS_sqrt(fx * fx + fy * fy); -} -int32_t CFX_Matrix::TransformYDistance(int32_t dy) const { - FX_FLOAT fx = c * dy, fy = d * dy; - return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); -} + FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const { - FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; + FX_FLOAT fx = a * dx + c * dy; + FX_FLOAT fy = b * dx + d * dy; return FXSYS_sqrt(fx * fx + fy * fy); } -int32_t CFX_Matrix::TransformDistance(int32_t dx, int32_t dy) const { - FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; - return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); -} + FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT distance) const { return distance * (GetXUnit() + GetYUnit()) / 2; } -void CFX_Matrix::TransformVector(CFX_VectorF& v) const { - FX_FLOAT fx = a * v.x + c * v.y; - FX_FLOAT fy = b * v.x + d * v.y; - v.x = fx, v.y = fy; -} -void CFX_Matrix::TransformVector(CFX_Vector& v) const { - FX_FLOAT fx = a * v.x + c * v.y; - FX_FLOAT fy = b * v.x + d * v.y; - v.x = FXSYS_round(fx); - v.y = FXSYS_round(fy); -} -void CFX_Matrix::TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const { - FX_FLOAT fx = a * x + c * y + e; - FX_FLOAT fy = b * x + d * y + f; - x = fx, y = fy; -} -void CFX_Matrix::TransformPoint(int32_t& x, int32_t& y) const { - FX_FLOAT fx = a * x + c * y + e; - FX_FLOAT fy = b * x + d * y + f; - x = FXSYS_round(fx); - y = FXSYS_round(fy); + +CFX_PointF CFX_Matrix::Transform(const CFX_PointF& point) const { + return CFX_PointF(a * point.x + c * point.y + e, + b * point.x + d * point.y + f); } + void CFX_Matrix::TransformRect(CFX_RectF& rect) const { FX_FLOAT right = rect.right(), bottom = rect.bottom(); TransformRect(rect.left, right, bottom, rect.top); rect.width = right - rect.left; rect.height = bottom - rect.top; } -void CFX_Matrix::TransformRect(CFX_Rect& rect) const { - FX_FLOAT left = (FX_FLOAT)rect.left; - FX_FLOAT top = (FX_FLOAT)rect.bottom(); - FX_FLOAT right = (FX_FLOAT)rect.right(); - FX_FLOAT bottom = (FX_FLOAT)rect.top; - TransformRect(left, right, top, bottom); - rect.left = FXSYS_round(left); - rect.top = FXSYS_round(bottom); - rect.width = FXSYS_round(right - left); - rect.height = FXSYS_round(top - bottom); -} + void CFX_Matrix::TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, FX_FLOAT& bottom) const { - FX_FLOAT x[4], y[4]; - x[0] = left; - y[0] = top; - x[1] = left; - y[1] = bottom; - x[2] = right; - y[2] = top; - x[3] = right; - y[3] = bottom; - int i; - for (i = 0; i < 4; i++) { - Transform(x[i], y[i], x[i], y[i]); + CFX_PointF points[] = { + {left, top}, {left, bottom}, {right, top}, {right, bottom}}; + for (int i = 0; i < 4; i++) + points[i] = Transform(points[i]); + + right = points[0].x; + left = points[0].x; + top = points[0].y; + bottom = points[0].y; + for (int i = 1; i < 4; i++) { + right = std::max(right, points[i].x); + left = std::min(left, points[i].x); + top = std::max(top, points[i].y); + bottom = std::min(bottom, points[i].y); } - right = left = x[0]; - top = bottom = y[0]; - for (i = 1; i < 4; i++) { - if (right < x[i]) { - right = x[i]; - } - if (left > x[i]) { - left = x[i]; - } - if (top < y[i]) { - top = y[i]; - } - if (bottom > y[i]) { - bottom = y[i]; - } +} + +void CFX_Matrix::ConcatInternal(const CFX_Matrix& other, bool prepend) { + CFX_Matrix left; + CFX_Matrix right; + if (prepend) { + left = other; + right = *this; + } else { + left = *this; + right = other; } + + a = left.a * right.a + left.b * right.c; + b = left.a * right.b + left.b * right.d; + c = left.c * right.a + left.d * right.c; + d = left.c * right.b + left.d * right.d; + e = left.e * right.a + left.f * right.c + right.e; + f = left.e * right.b + left.f * right.d + right.f; } diff --git a/core/fxcrt/fx_basic_utf.cpp b/core/fxcrt/fx_basic_utf.cpp index 8dbbb2887..c0f14c817 100644 --- a/core/fxcrt/fx_basic_utf.cpp +++ b/core/fxcrt/fx_basic_utf.cpp @@ -73,13 +73,13 @@ void CFX_UTF8Encoder::Input(FX_WCHAR unicode) { } } } -CFX_ByteString FX_UTF8Encode(const FX_WCHAR* pwsStr, FX_STRSIZE len) { - if (len < 0) - len = FXSYS_wcslen(pwsStr); +CFX_ByteString FX_UTF8Encode(const CFX_WideStringC& wsStr) { + FX_STRSIZE len = wsStr.GetLength(); + const FX_WCHAR* pStr = wsStr.c_str(); CFX_UTF8Encoder encoder; while (len-- > 0) - encoder.Input(*pwsStr++); + encoder.Input(*pStr++); return CFX_ByteString(encoder.GetResult()); } diff --git a/core/fxcrt/fx_basic_util.cpp b/core/fxcrt/fx_basic_util.cpp index e52ff2ece..f608e290a 100644 --- a/core/fxcrt/fx_basic_util.cpp +++ b/core/fxcrt/fx_basic_util.cpp @@ -12,12 +12,6 @@ #include <limits> #include <memory> -namespace { - -const int kDefaultIntValue = 0; - -} // namespace - bool FX_atonum(const CFX_ByteStringC& strc, void* pData) { if (strc.Find('.') != -1) { FX_FLOAT* pFloat = static_cast<FX_FLOAT*>(pData); @@ -54,18 +48,19 @@ bool FX_atonum(const CFX_ByteStringC& strc, void* pData) { // we've overflowed, reset to the default value. if (bSigned) { if (bNegative) { - if (integer.ValueOrDefault(kDefaultIntValue) > + if (integer.ValueOrDefault(0) > static_cast<uint32_t>(std::numeric_limits<int>::max()) + 1) { - integer = kDefaultIntValue; + integer = 0; } - } else if (integer.ValueOrDefault(kDefaultIntValue) > + } else if (integer.ValueOrDefault(0) > static_cast<uint32_t>(std::numeric_limits<int>::max())) { - integer = kDefaultIntValue; + integer = 0; } } // Switch back to the int space so we can flip to a negative if we need. - int value = static_cast<int>(integer.ValueOrDefault(kDefaultIntValue)); + uint32_t uValue = integer.ValueOrDefault(0); + int32_t value = static_cast<int>(uValue); if (bNegative) value = -value; diff --git a/core/fxcrt/fx_basic_wstring.cpp b/core/fxcrt/fx_basic_wstring.cpp index e779621e6..93b9ba7c2 100644 --- a/core/fxcrt/fx_basic_wstring.cpp +++ b/core/fxcrt/fx_basic_wstring.cpp @@ -343,12 +343,10 @@ void CFX_WideString::Concat(const FX_WCHAR* pSrcData, FX_STRSIZE nSrcLen) { m_pData.Swap(pNewData); } -// static CFX_ByteString CFX_WideString::UTF8Encode() const { - return FX_UTF8Encode(*this); + return FX_UTF8Encode(AsStringC()); } -// static CFX_ByteString CFX_WideString::UTF16LE_Encode() const { if (!m_pData) { return CFX_ByteString("\0\0", 2); diff --git a/core/fxcrt/fx_coordinates.h b/core/fxcrt/fx_coordinates.h index d8ad4efe4..2c84d0776 100644 --- a/core/fxcrt/fx_coordinates.h +++ b/core/fxcrt/fx_coordinates.h @@ -12,89 +12,155 @@ class CFX_Matrix; template <class BaseType> -class CFX_PSTemplate { +class CFX_PTemplate { public: - CFX_PSTemplate() : x(0), y(0) {} - CFX_PSTemplate(BaseType new_x, BaseType new_y) : x(new_x), y(new_y) {} - CFX_PSTemplate(const CFX_PSTemplate& other) : x(other.x), y(other.y) {} + CFX_PTemplate() : x(0), y(0) {} + CFX_PTemplate(BaseType new_x, BaseType new_y) : x(new_x), y(new_y) {} + CFX_PTemplate(const CFX_PTemplate& other) : x(other.x), y(other.y) {} void clear() { x = 0; y = 0; } - CFX_PSTemplate operator=(const CFX_PSTemplate& other) { + CFX_PTemplate operator=(const CFX_PTemplate& other) { if (this != &other) { x = other.x; y = other.y; } return *this; } - bool operator==(const CFX_PSTemplate& other) const { + bool operator==(const CFX_PTemplate& other) const { return x == other.x && y == other.y; } - bool operator!=(const CFX_PSTemplate& other) const { + bool operator!=(const CFX_PTemplate& other) const { return !(*this == other); } - CFX_PSTemplate& operator+=(const CFX_PSTemplate<BaseType>& obj) { + CFX_PTemplate& operator+=(const CFX_PTemplate<BaseType>& obj) { x += obj.x; y += obj.y; return *this; } - CFX_PSTemplate& operator-=(const CFX_PSTemplate<BaseType>& obj) { + CFX_PTemplate& operator-=(const CFX_PTemplate<BaseType>& obj) { x -= obj.x; y -= obj.y; return *this; } - CFX_PSTemplate& operator*=(BaseType factor) { + CFX_PTemplate& operator*=(BaseType factor) { x *= factor; y *= factor; return *this; } - CFX_PSTemplate& operator/=(BaseType divisor) { + CFX_PTemplate& operator/=(BaseType divisor) { x /= divisor; y /= divisor; return *this; } - CFX_PSTemplate operator+(const CFX_PSTemplate& other) { - return CFX_PSTemplate(x + other.x, y + other.y); + CFX_PTemplate operator+(const CFX_PTemplate& other) const { + return CFX_PTemplate(x + other.x, y + other.y); } - CFX_PSTemplate operator-(const CFX_PSTemplate& other) { - return CFX_PSTemplate(x - other.x, y - other.y); + CFX_PTemplate operator-(const CFX_PTemplate& other) const { + return CFX_PTemplate(x - other.x, y - other.y); } - CFX_PSTemplate operator*(BaseType factor) { - return CFX_PSTemplate(x * factor, y * factor); + CFX_PTemplate operator*(BaseType factor) const { + return CFX_PTemplate(x * factor, y * factor); } - CFX_PSTemplate operator/(BaseType divisor) { - return CFX_PSTemplate(x / divisor, y / divisor); + CFX_PTemplate operator/(BaseType divisor) const { + return CFX_PTemplate(x / divisor, y / divisor); } BaseType x; BaseType y; }; -typedef CFX_PSTemplate<int32_t> CFX_Point; -typedef CFX_PSTemplate<FX_FLOAT> CFX_PointF; -typedef CFX_PSTemplate<int32_t> CFX_Size; -typedef CFX_PSTemplate<FX_FLOAT> CFX_SizeF; +using CFX_Point = CFX_PTemplate<int32_t>; +using CFX_PointF = CFX_PTemplate<FX_FLOAT>; -#ifdef PDF_ENABLE_XFA -typedef CFX_ArrayTemplate<CFX_Point> CFX_Points; -typedef CFX_ArrayTemplate<CFX_PointF> CFX_PointsF; -#endif // PDF_ENABLE_XFA +template <class BaseType> +class CFX_STemplate { + public: + CFX_STemplate() : width(0), height(0) {} + + CFX_STemplate(BaseType new_width, BaseType new_height) + : width(new_width), height(new_height) {} + + CFX_STemplate(const CFX_STemplate& other) + : width(other.width), height(other.height) {} + + template <typename OtherType> + CFX_STemplate<OtherType> As() const { + return CFX_STemplate<OtherType>(static_cast<OtherType>(width), + static_cast<OtherType>(height)); + } + + void clear() { + width = 0; + height = 0; + } + CFX_STemplate operator=(const CFX_STemplate& other) { + if (this != &other) { + width = other.width; + height = other.height; + } + return *this; + } + bool operator==(const CFX_STemplate& other) const { + return width == other.width && height == other.height; + } + bool operator!=(const CFX_STemplate& other) const { + return !(*this == other); + } + CFX_STemplate& operator+=(const CFX_STemplate<BaseType>& obj) { + width += obj.width; + height += obj.height; + return *this; + } + CFX_STemplate& operator-=(const CFX_STemplate<BaseType>& obj) { + width -= obj.width; + height -= obj.height; + return *this; + } + CFX_STemplate& operator*=(BaseType factor) { + width *= factor; + height *= factor; + return *this; + } + CFX_STemplate& operator/=(BaseType divisor) { + width /= divisor; + height /= divisor; + return *this; + } + CFX_STemplate operator+(const CFX_STemplate& other) const { + return CFX_STemplate(width + other.width, height + other.height); + } + CFX_STemplate operator-(const CFX_STemplate& other) const { + return CFX_STemplate(width - other.width, height - other.height); + } + CFX_STemplate operator*(BaseType factor) const { + return CFX_STemplate(width * factor, height * factor); + } + CFX_STemplate operator/(BaseType divisor) const { + return CFX_STemplate(width / divisor, height / divisor); + } + + BaseType width; + BaseType height; +}; +using CFX_Size = CFX_STemplate<int32_t>; +using CFX_SizeF = CFX_STemplate<FX_FLOAT>; template <class BaseType> -class CFX_VTemplate : public CFX_PSTemplate<BaseType> { +class CFX_VTemplate : public CFX_PTemplate<BaseType> { public: - using CFX_PSTemplate<BaseType>::x; - using CFX_PSTemplate<BaseType>::y; + using CFX_PTemplate<BaseType>::x; + using CFX_PTemplate<BaseType>::y; - CFX_VTemplate() : CFX_PSTemplate<BaseType>() {} + CFX_VTemplate() : CFX_PTemplate<BaseType>() {} CFX_VTemplate(BaseType new_x, BaseType new_y) - : CFX_PSTemplate<BaseType>(new_x, new_y) {} + : CFX_PTemplate<BaseType>(new_x, new_y) {} - CFX_VTemplate(const CFX_VTemplate& other) : CFX_PSTemplate<BaseType>(other) {} + CFX_VTemplate(const CFX_VTemplate& other) : CFX_PTemplate<BaseType>(other) {} - CFX_VTemplate(const CFX_PSTemplate<BaseType>& point1, - const CFX_PSTemplate<BaseType>& point2) - : CFX_PSTemplate<BaseType>(point2.x - point1.x, point2.y - point1.y) {} + CFX_VTemplate(const CFX_PTemplate<BaseType>& point1, + const CFX_PTemplate<BaseType>& point2) + : CFX_PTemplate<BaseType>(point2.x - point1.x, point2.y - point1.y) {} FX_FLOAT Length() const { return FXSYS_sqrt(x * x + y * y); } void Normalize() { @@ -120,137 +186,80 @@ class CFX_VTemplate : public CFX_PSTemplate<BaseType> { y = x * sinValue + y * cosValue; } }; -typedef CFX_VTemplate<int32_t> CFX_Vector; -typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF; +using CFX_Vector = CFX_VTemplate<int32_t>; +using CFX_VectorF = CFX_VTemplate<FX_FLOAT>; // Rectangles. // TODO(tsepez): Consolidate all these different rectangle classes. -// LTRB rectangles (y-axis runs downwards). -struct FX_RECT { - FX_RECT() : left(0), top(0), right(0), bottom(0) {} - - FX_RECT(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {} - - int Width() const { return right - left; } - int Height() const { return bottom - top; } - bool IsEmpty() const { return right <= left || bottom <= top; } - - bool Valid() const { - pdfium::base::CheckedNumeric<int> w = right; - pdfium::base::CheckedNumeric<int> h = bottom; - w -= left; - h -= top; - return w.IsValid() && h.IsValid(); - } - - void Normalize(); - - void Intersect(const FX_RECT& src); - void Intersect(int l, int t, int r, int b) { Intersect(FX_RECT(l, t, r, b)); } - - void Union(const FX_RECT& other_rect); - void Union(int l, int t, int r, int b) { Union(FX_RECT(l, t, r, b)); } - - void Offset(int dx, int dy) { - left += dx; - right += dx; - top += dy; - bottom += dy; - } - - bool operator==(const FX_RECT& src) const { - return left == src.left && right == src.right && top == src.top && - bottom == src.bottom; - } - - bool Contains(const FX_RECT& other_rect) const { - return other_rect.left >= left && other_rect.right <= right && - other_rect.top >= top && other_rect.bottom <= bottom; - } - - bool Contains(int x, int y) const { - return x >= left && x < right && y >= top && y < bottom; - } - - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; -}; - -// LBRT rectangles (y-axis runs upwards). -class CFX_FloatPoint { - public: - CFX_FloatPoint() : x(0.0f), y(0.0f) {} - CFX_FloatPoint(FX_FLOAT xx, FX_FLOAT yy) : x(xx), y(yy) {} - - bool operator==(const CFX_FloatPoint& that) const { - return x == that.x && y == that.y; - } - bool operator!=(const CFX_FloatPoint& that) const { return !(*this == that); } - - FX_FLOAT x; - FX_FLOAT y; -}; - // LTWH rectangles (y-axis runs downwards). -template <class baseType> +template <class BaseType> class CFX_RTemplate { public: - typedef CFX_PSTemplate<baseType> FXT_POINT; - typedef CFX_PSTemplate<baseType> FXT_SIZE; - typedef CFX_VTemplate<baseType> FXT_VECTOR; - typedef CFX_RTemplate<baseType> FXT_RECT; - void Set(baseType dst_left, - baseType dst_top, - baseType dst_width, - baseType dst_height) { - left = dst_left; - top = dst_top; - width = dst_width; - height = dst_height; - } - void Set(baseType dst_left, baseType dst_top, const FXT_SIZE& dst_size) { - left = dst_left; - top = dst_top; - Size(dst_size); - } - void Set(const FXT_POINT& p, baseType dst_width, baseType dst_height) { - TopLeft(p); - width = dst_width; - height = dst_height; - } - void Set(const FXT_POINT& p1, const FXT_POINT& p2) { - TopLeft(p1); - width = p2.x - p1.x; - height = p2.y - p1.y; + using PointType = CFX_PTemplate<BaseType>; + using SizeType = CFX_STemplate<BaseType>; + using VectorType = CFX_VTemplate<BaseType>; + using RectType = CFX_RTemplate<BaseType>; + + CFX_RTemplate() : left(0), top(0), width(0), height(0) {} + CFX_RTemplate(BaseType dst_left, + BaseType dst_top, + BaseType dst_width, + BaseType dst_height) + : left(dst_left), top(dst_top), width(dst_width), height(dst_height) {} + CFX_RTemplate(BaseType dst_left, BaseType dst_top, const SizeType& dst_size) + : left(dst_left), + top(dst_top), + width(dst_size.width), + height(dst_size.height) {} + CFX_RTemplate(const PointType& p, BaseType dst_width, BaseType dst_height) + : left(p.x), top(p.y), width(dst_width), height(dst_height) {} + CFX_RTemplate(const PointType& p1, const SizeType& s2) + : left(p1.x), top(p1.y), width(s2.width), height(s2.height) {} + CFX_RTemplate(const PointType& p1, const PointType& p2) + : left(p1.x), + top(p1.y), + width(p2.width - p1.width), + height(p2.height - p1.height) { Normalize(); } - void Set(const FXT_POINT& p, const FXT_VECTOR& v) { - TopLeft(p); - width = v.x; - height = v.y; + CFX_RTemplate(const PointType& p, const VectorType& v) + : left(p.x), top(p.y), width(v.x), height(v.y) { Normalize(); } + + // NOLINTNEXTLINE(runtime/explicit) + CFX_RTemplate(const RectType& other) + : left(other.left), + top(other.top), + width(other.width), + height(other.height) {} + + template <typename OtherType> + CFX_RTemplate<OtherType> As() const { + return CFX_RTemplate<OtherType>( + static_cast<OtherType>(left), static_cast<OtherType>(top), + static_cast<OtherType>(width), static_cast<OtherType>(height)); + } + void Reset() { left = 0; top = 0; width = 0; height = 0; } - FXT_RECT& operator+=(const FXT_POINT& p) { + RectType& operator+=(const PointType& p) { left += p.x; top += p.y; return *this; } - FXT_RECT& operator-=(const FXT_POINT& p) { + RectType& operator-=(const PointType& p) { left -= p.x; top -= p.y; return *this; } - baseType right() const { return left + width; } - baseType bottom() const { return top + height; } + BaseType right() const { return left + width; } + BaseType bottom() const { return top + height; } void Normalize() { if (width < 0) { left += width; @@ -261,46 +270,46 @@ class CFX_RTemplate { height = -height; } } - void Offset(baseType dx, baseType dy) { + void Offset(BaseType dx, BaseType dy) { left += dx; top += dy; } - void Inflate(baseType x, baseType y) { + void Inflate(BaseType x, BaseType y) { left -= x; width += x * 2; top -= y; height += y * 2; } - void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); } - void Inflate(baseType off_left, - baseType off_top, - baseType off_right, - baseType off_bottom) { + void Inflate(const PointType& p) { Inflate(p.x, p.y); } + void Inflate(BaseType off_left, + BaseType off_top, + BaseType off_right, + BaseType off_bottom) { left -= off_left; top -= off_top; width += off_left + off_right; height += off_top + off_bottom; } - void Inflate(const FXT_RECT& rt) { + void Inflate(const RectType& rt) { Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height); } - void Deflate(baseType x, baseType y) { + void Deflate(BaseType x, BaseType y) { left += x; width -= x * 2; top += y; height -= y * 2; } - void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); } - void Deflate(baseType off_left, - baseType off_top, - baseType off_right, - baseType off_bottom) { + void Deflate(const PointType& p) { Deflate(p.x, p.y); } + void Deflate(BaseType off_left, + BaseType off_top, + BaseType off_right, + BaseType off_bottom) { left += off_left; top += off_top; width -= off_left + off_right; height -= off_top + off_bottom; } - void Deflate(const FXT_RECT& rt) { + void Deflate(const RectType& rt) { Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height); } bool IsEmpty() const { return width <= 0 || height <= 0; } @@ -308,71 +317,29 @@ class CFX_RTemplate { return width <= fEpsilon || height <= fEpsilon; } void Empty() { width = height = 0; } - bool Contains(baseType x, baseType y) const { - return x >= left && x < left + width && y >= top && y < top + height; + bool Contains(const PointType& p) const { + return p.x >= left && p.x < left + width && p.y >= top && + p.y < top + height; } - bool Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); } - bool Contains(const FXT_RECT& rt) const { + bool Contains(const RectType& rt) const { return rt.left >= left && rt.right() <= right() && rt.top >= top && rt.bottom() <= bottom(); } - baseType Width() const { return width; } - baseType Height() const { return height; } - FXT_SIZE Size() const { - FXT_SIZE size; - size.Set(width, height); - return size; - } - void Size(FXT_SIZE s) { width = s.x, height = s.y; } - FXT_POINT TopLeft() const { - FXT_POINT p; - p.x = left; - p.y = top; - return p; - } - FXT_POINT TopRight() const { - FXT_POINT p; - p.x = left + width; - p.y = top; - return p; - } - FXT_POINT BottomLeft() const { - FXT_POINT p; - p.x = left; - p.y = top + height; - return p; - } - FXT_POINT BottomRight() const { - FXT_POINT p; - p.x = left + width; - p.y = top + height; - return p; - } - void TopLeft(FXT_POINT tl) { - left = tl.x; - top = tl.y; - } - void TopRight(FXT_POINT tr) { - width = tr.x - left; - top = tr.y; - } - void BottomLeft(FXT_POINT bl) { - left = bl.x; - height = bl.y - top; - } - void BottomRight(FXT_POINT br) { - width = br.x - left; - height = br.y - top; - } - FXT_POINT Center() const { - FXT_POINT p; - p.x = left + width / 2; - p.y = top + height / 2; - return p; - } - void Union(baseType x, baseType y) { - baseType r = right(); - baseType b = bottom(); + BaseType Width() const { return width; } + BaseType Height() const { return height; } + SizeType Size() const { return SizeType(width, height); } + PointType TopLeft() const { return PointType(left, top); } + PointType TopRight() const { return PointType(left + width, top); } + PointType BottomLeft() const { return PointType(left, top + height); } + PointType BottomRight() const { + return PointType(left + width, top + height); + } + PointType Center() const { + return PointType(left + width / 2, top + height / 2); + } + void Union(BaseType x, BaseType y) { + BaseType r = right(); + BaseType b = bottom(); if (left > x) left = x; if (r < x) @@ -384,10 +351,10 @@ class CFX_RTemplate { width = r - left; height = b - top; } - void Union(const FXT_POINT& p) { Union(p.x, p.y); } - void Union(const FXT_RECT& rt) { - baseType r = right(); - baseType b = bottom(); + void Union(const PointType& p) { Union(p.x, p.y); } + void Union(const RectType& rt) { + BaseType r = right(); + BaseType b = bottom(); if (left > rt.left) left = rt.left; if (r < rt.right()) @@ -399,9 +366,9 @@ class CFX_RTemplate { width = r - left; height = b - top; } - void Intersect(const FXT_RECT& rt) { - baseType r = right(); - baseType b = bottom(); + void Intersect(const RectType& rt) { + BaseType r = right(); + BaseType b = bottom(); if (left < rt.left) left = rt.left; if (r > rt.right()) @@ -413,33 +380,77 @@ class CFX_RTemplate { width = r - left; height = b - top; } - bool IntersectWith(const FXT_RECT& rt) const { - FXT_RECT rect = rt; + bool IntersectWith(const RectType& rt) const { + RectType rect = rt; rect.Intersect(*this); return !rect.IsEmpty(); } - bool IntersectWith(const FXT_RECT& rt, FX_FLOAT fEpsilon) const { - FXT_RECT rect = rt; + bool IntersectWith(const RectType& rt, FX_FLOAT fEpsilon) const { + RectType rect = rt; rect.Intersect(*this); return !rect.IsEmpty(fEpsilon); } - friend bool operator==(const FXT_RECT& rc1, const FXT_RECT& rc2) { + friend bool operator==(const RectType& rc1, const RectType& rc2) { return rc1.left == rc2.left && rc1.top == rc2.top && rc1.width == rc2.width && rc1.height == rc2.height; } - friend bool operator!=(const FXT_RECT& rc1, const FXT_RECT& rc2) { + friend bool operator!=(const RectType& rc1, const RectType& rc2) { return !(rc1 == rc2); } - baseType left, top; - baseType width, height; + + BaseType left; + BaseType top; + BaseType width; + BaseType height; }; -typedef CFX_RTemplate<int32_t> CFX_Rect; -typedef CFX_RTemplate<FX_FLOAT> CFX_RectF; +using CFX_Rect = CFX_RTemplate<int32_t>; +using CFX_RectF = CFX_RTemplate<FX_FLOAT>; -#ifdef PDF_ENABLE_XFA -typedef CFX_ArrayTemplate<CFX_RectF> CFX_RectFArray; -#endif // PDF_ENABLE_XFA +// LTRB rectangles (y-axis runs downwards). +struct FX_RECT { + FX_RECT() : left(0), top(0), right(0), bottom(0) {} + FX_RECT(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {} + + int Width() const { return right - left; } + int Height() const { return bottom - top; } + bool IsEmpty() const { return right <= left || bottom <= top; } + + bool Valid() const { + pdfium::base::CheckedNumeric<int> w = right; + pdfium::base::CheckedNumeric<int> h = bottom; + w -= left; + h -= top; + return w.IsValid() && h.IsValid(); + } + + void Normalize(); + void Intersect(const FX_RECT& src); + void Intersect(int l, int t, int r, int b) { Intersect(FX_RECT(l, t, r, b)); } + + void Offset(int dx, int dy) { + left += dx; + right += dx; + top += dy; + bottom += dy; + } + + bool operator==(const FX_RECT& src) const { + return left == src.left && right == src.right && top == src.top && + bottom == src.bottom; + } + + bool Contains(int x, int y) const { + return x >= left && x < right && y >= top && y < bottom; + } + + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + +// LTRB rectangles (y-axis runs upwards). class CFX_FloatRect { public: CFX_FloatRect() : CFX_FloatRect(0.0f, 0.0f, 0.0f, 0.0f) {} @@ -461,10 +472,10 @@ class CFX_FloatRect { } bool IsEmpty() const { return left >= right || bottom >= top; } + + bool Contains(const CFX_PointF& point) const; bool Contains(const CFX_FloatRect& other_rect) const; - bool Contains(FX_FLOAT x, FX_FLOAT y) const; - void Transform(const CFX_Matrix* pMatrix); void Intersect(const CFX_FloatRect& other_rect); void Union(const CFX_FloatRect& other_rect); @@ -559,42 +570,45 @@ class CFX_Matrix { public: CFX_Matrix() { SetIdentity(); } + explicit CFX_Matrix(const FX_FLOAT n[6]) + : a(n[0]), b(n[1]), c(n[2]), d(n[3]), e(n[4]), f(n[5]) {} + + CFX_Matrix(const CFX_Matrix& other) + : a(other.a), + b(other.b), + c(other.c), + d(other.d), + e(other.e), + f(other.f) {} + CFX_Matrix(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1, FX_FLOAT d1, FX_FLOAT e1, - FX_FLOAT f1) { - a = a1; - b = b1; - c = c1; - d = d1; - e = e1; - f = f1; - } - - void Set(FX_FLOAT a, - FX_FLOAT b, - FX_FLOAT c, - FX_FLOAT d, - FX_FLOAT e, - FX_FLOAT f); - void Set(const FX_FLOAT n[6]); + FX_FLOAT f1) + : a(a1), b(b1), c(c1), d(d1), e(e1), f(f1) {} + + void operator=(const CFX_Matrix& other) { + a = other.a; + b = other.b; + c = other.c; + d = other.d; + e = other.e; + f = other.f; + } void SetIdentity() { - a = d = 1; - b = c = e = f = 0; + a = 1; + b = 0; + c = 0; + d = 1; + e = 0; + f = 0; } void SetReverse(const CFX_Matrix& m); - void Concat(FX_FLOAT a, - FX_FLOAT b, - FX_FLOAT c, - FX_FLOAT d, - FX_FLOAT e, - FX_FLOAT f, - bool bPrepended = false); void Concat(const CFX_Matrix& m, bool bPrepended = false); void ConcatInverse(const CFX_Matrix& m, bool bPrepended = false); @@ -602,13 +616,13 @@ class CFX_Matrix { return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0; } - bool IsInvertible() const; bool Is90Rotated() const; bool IsScaled() const; + bool WillScale() const { return a != 1.0f || b != 0 || c != 0 || d != 1.0f; } void Translate(FX_FLOAT x, FX_FLOAT y, bool bPrepended = false); - void TranslateI(int32_t x, int32_t y, bool bPrepended = false) { - Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended); + void Translate(int32_t x, int32_t y, bool bPrepended = false) { + Translate(static_cast<FX_FLOAT>(x), static_cast<FX_FLOAT>(y), bPrepended); } void Scale(FX_FLOAT sx, FX_FLOAT sy, bool bPrepended = false); @@ -623,33 +637,18 @@ class CFX_Matrix { bool bPrepended = false); void MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src); + FX_FLOAT GetXUnit() const; FX_FLOAT GetYUnit() const; - void GetUnitRect(CFX_RectF& rect) const; CFX_FloatRect GetUnitRect() const; - FX_FLOAT GetUnitArea() const; FX_FLOAT TransformXDistance(FX_FLOAT dx) const; - int32_t TransformXDistance(int32_t dx) const; - FX_FLOAT TransformYDistance(FX_FLOAT dy) const; - int32_t TransformYDistance(int32_t dy) const; FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const; - int32_t TransformDistance(int32_t dx, int32_t dy) const; FX_FLOAT TransformDistance(FX_FLOAT distance) const; - void TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const; - void TransformPoint(int32_t& x, int32_t& y) const; + CFX_PointF Transform(const CFX_PointF& point) const; - void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); } - void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const { - x1 = x, y1 = y; - TransformPoint(x1, y1); - } - - void TransformVector(CFX_VectorF& v) const; - void TransformVector(CFX_Vector& v) const; void TransformRect(CFX_RectF& rect) const; - void TransformRect(CFX_Rect& rect) const; void TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, @@ -658,20 +657,15 @@ class CFX_Matrix { TransformRect(rect.left, rect.right, rect.top, rect.bottom); } - FX_FLOAT GetA() const { return a; } - FX_FLOAT GetB() const { return b; } - FX_FLOAT GetC() const { return c; } - FX_FLOAT GetD() const { return d; } - FX_FLOAT GetE() const { return e; } - FX_FLOAT GetF() const { return f; } - - public: FX_FLOAT a; FX_FLOAT b; FX_FLOAT c; FX_FLOAT d; FX_FLOAT e; FX_FLOAT f; + + private: + void ConcatInternal(const CFX_Matrix& other, bool prepend); }; #endif // CORE_FXCRT_FX_COORDINATES_H_ diff --git a/core/fxcrt/fx_extension.cpp b/core/fxcrt/fx_extension.cpp index f1e2583b4..5b577f745 100644 --- a/core/fxcrt/fx_extension.cpp +++ b/core/fxcrt/fx_extension.cpp @@ -204,7 +204,7 @@ FX_FILESIZE CFX_MemoryStream::GetPosition() { bool CFX_MemoryStream::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) { - if (!buffer || !size) + if (!buffer || !size || offset < 0) return false; FX_SAFE_SIZE_T newPos = size; diff --git a/core/fxcrt/fx_string.h b/core/fxcrt/fx_string.h index 540c0c433..cd93f2727 100644 --- a/core/fxcrt/fx_string.h +++ b/core/fxcrt/fx_string.h @@ -28,8 +28,6 @@ using CFX_WideStringC = CFX_StringCTemplate<FX_WCHAR>; (((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | \ ((uint32_t)c4)) -#define FX_WSTRC(wstr) CFX_WideStringC(wstr, FX_ArraySize(wstr) - 1) - // A mutable string with shared buffers using copy-on-write semantics that // avoids the cost of std::string's iterator stability guarantees. class CFX_ByteString { @@ -426,17 +424,10 @@ inline bool operator!=(const CFX_WideStringC& lhs, const CFX_WideString& rhs) { return rhs != lhs; } -CFX_ByteString FX_UTF8Encode(const FX_WCHAR* pwsStr, FX_STRSIZE len); -inline CFX_ByteString FX_UTF8Encode(const CFX_WideStringC& wsStr) { - return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength()); -} -inline CFX_ByteString FX_UTF8Encode(const CFX_WideString& wsStr) { - return FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength()); -} - +CFX_ByteString FX_UTF8Encode(const CFX_WideStringC& wsStr); FX_FLOAT FX_atof(const CFX_ByteStringC& str); inline FX_FLOAT FX_atof(const CFX_WideStringC& wsStr) { - return FX_atof(FX_UTF8Encode(wsStr.c_str(), wsStr.GetLength()).c_str()); + return FX_atof(FX_UTF8Encode(wsStr).c_str()); } bool FX_atonum(const CFX_ByteStringC& str, void* pData); FX_STRSIZE FX_ftoa(FX_FLOAT f, FX_CHAR* buf); diff --git a/core/fxcrt/fx_ucd.h b/core/fxcrt/fx_ucd.h index d79693b9f..eb4bad097 100644 --- a/core/fxcrt/fx_ucd.h +++ b/core/fxcrt/fx_ucd.h @@ -7,6 +7,7 @@ #ifndef CORE_FXCRT_FX_UCD_H_ #define CORE_FXCRT_FX_UCD_H_ +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_basic.h" #define FX_BIDICLASSBITS 6 @@ -121,43 +122,43 @@ class CFX_Char { CFX_Char() : m_wCharCode(0), m_nBreakType(0), - m_nRotation(0), m_dwCharProps(0), - m_dwCharStyles(0), m_iCharWidth(0), m_iHorizontalScale(100), - m_iVertialScale(100) {} + m_iVerticalScale(100) {} + CFX_Char(uint16_t wCharCode, uint32_t dwCharProps) : m_wCharCode(wCharCode), m_nBreakType(0), - m_nRotation(0), m_dwCharProps(dwCharProps), - m_dwCharStyles(0), m_iCharWidth(0), m_iHorizontalScale(100), - m_iVertialScale(100) {} + m_iVerticalScale(100) {} FX_CHARTYPE GetCharType() const { return GetCharTypeFromProp(m_dwCharProps); } uint16_t m_wCharCode; uint8_t m_nBreakType; - int8_t m_nRotation; uint32_t m_dwCharProps; - uint32_t m_dwCharStyles; int32_t m_iCharWidth; int32_t m_iHorizontalScale; - int32_t m_iVertialScale; + int32_t m_iVerticalScale; }; -typedef CFX_ArrayTemplate<CFX_Char> CFX_CharArray; + class CFX_TxtChar : public CFX_Char { public: CFX_TxtChar() - : m_dwStatus(0), + : m_nRotation(0), + m_dwCharStyles(0), + m_dwStatus(0), m_iBidiClass(0), m_iBidiLevel(0), m_iBidiPos(0), m_iBidiOrder(0), m_pUserData(nullptr) {} + + int8_t m_nRotation; + uint32_t m_dwCharStyles; uint32_t m_dwStatus; int16_t m_iBidiClass; int16_t m_iBidiLevel; @@ -165,38 +166,39 @@ class CFX_TxtChar : public CFX_Char { int16_t m_iBidiOrder; void* m_pUserData; }; -typedef CFX_ArrayTemplate<CFX_TxtChar> CFX_TxtCharArray; + +enum class CFX_RTFBreakType { None = 0, Piece, Line, Paragraph, Page }; + class CFX_RTFChar : public CFX_Char { public: CFX_RTFChar(); CFX_RTFChar(const CFX_RTFChar& other); + ~CFX_RTFChar(); - uint32_t m_dwStatus; + CFX_RTFBreakType m_dwStatus; int32_t m_iFontSize; int32_t m_iFontHeight; int16_t m_iBidiClass; int16_t m_iBidiLevel; int16_t m_iBidiPos; int16_t m_iBidiOrder; - uint32_t m_dwLayoutStyles; uint32_t m_dwIdentity; - IFX_Retainable* m_pUserData; + CFX_RetainPtr<CFX_Retainable> m_pUserData; }; inline CFX_RTFChar::CFX_RTFChar() - : m_dwStatus(0), + : m_dwStatus(CFX_RTFBreakType::None), m_iFontSize(0), m_iFontHeight(0), m_iBidiClass(0), m_iBidiLevel(0), m_iBidiPos(0), - m_dwLayoutStyles(0), m_dwIdentity(0), m_pUserData(nullptr) {} inline CFX_RTFChar::CFX_RTFChar(const CFX_RTFChar& other) = default; +inline CFX_RTFChar::~CFX_RTFChar() = default; -typedef CFX_ArrayTemplate<CFX_RTFChar> CFX_RTFCharArray; #endif // PDF_ENABLE_XFA #endif // CORE_FXCRT_FX_UCD_H_ diff --git a/core/fxcrt/fx_xml.h b/core/fxcrt/fx_xml.h index 7f42a7fa9..87f1915cb 100644 --- a/core/fxcrt/fx_xml.h +++ b/core/fxcrt/fx_xml.h @@ -54,28 +54,18 @@ class CXML_Element { public: enum ChildType { Invalid, Element, Content }; - static CXML_Element* Parse(const void* pBuffer, - size_t size, - bool bSaveSpaceChars = false, - FX_FILESIZE* pParsedSize = nullptr); - static CXML_Element* Parse(const CFX_RetainPtr<IFX_SeekableReadStream>& pFile, - bool bSaveSpaceChars = false, - FX_FILESIZE* pParsedSize = nullptr); - static CXML_Element* Parse( - const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer, - bool bSaveSpaceChars = false, - FX_FILESIZE* pParsedSize = nullptr); - - CXML_Element(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagName); - explicit CXML_Element(const CFX_ByteStringC& qTagName); - CXML_Element(); + static std::unique_ptr<CXML_Element> Parse(const void* pBuffer, size_t size); + + CXML_Element(const CXML_Element* pParent, + const CFX_ByteStringC& qSpace, + const CFX_ByteStringC& tagname); ~CXML_Element(); void Empty(); CFX_ByteString GetTagName(bool bQualified = false) const; CFX_ByteString GetNamespace(bool bQualified = false) const; CFX_ByteString GetNamespaceURI(const CFX_ByteString& qName) const; - CXML_Element* GetParent() const { return m_pParent; } + const CXML_Element* GetParent() const { return m_pParent; } uint32_t CountAttrs() const { return m_AttrMap.GetSize(); } void GetAttrByIndex(int index, CFX_ByteString& space, @@ -150,7 +140,6 @@ class CXML_Element { int index) const; uint32_t FindElement(CXML_Element* pChild) const; - void SetTag(const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagname); void SetTag(const CFX_ByteStringC& qTagName); void RemoveChildren(); void RemoveChild(uint32_t index); @@ -161,7 +150,7 @@ class CXML_Element { void* child; // CXML_Element and CXML_Content lack a common ancestor. }; - CXML_Element* m_pParent; + const CXML_Element* const m_pParent; CFX_ByteString m_QSpaceName; CFX_ByteString m_TagName; CXML_AttrMap m_AttrMap; diff --git a/core/fxcrt/fx_xml_composer.cpp b/core/fxcrt/fx_xml_composer.cpp index 91118a0a6..637d64cd8 100644 --- a/core/fxcrt/fx_xml_composer.cpp +++ b/core/fxcrt/fx_xml_composer.cpp @@ -23,14 +23,10 @@ void FX_XML_SplitQualifiedName(const CFX_ByteStringC& bsFullName, } } -void CXML_Element::SetTag(const CFX_ByteStringC& qSpace, - const CFX_ByteStringC& tagname) { - m_QSpaceName = qSpace; - m_TagName = tagname; -} void CXML_Element::SetTag(const CFX_ByteStringC& qTagName) { ASSERT(!qTagName.IsEmpty()); - CFX_ByteStringC bsSpace, bsName; + CFX_ByteStringC bsSpace; + CFX_ByteStringC bsName; FX_XML_SplitQualifiedName(qTagName, bsSpace, bsName); m_QSpaceName = bsSpace; m_TagName = bsName; diff --git a/core/fxcrt/fx_xml_parser.cpp b/core/fxcrt/fx_xml_parser.cpp index 1b562c208..761aae777 100644 --- a/core/fxcrt/fx_xml_parser.cpp +++ b/core/fxcrt/fx_xml_parser.cpp @@ -4,13 +4,13 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#include "core/fxcrt/xml_int.h" - #include <algorithm> +#include <memory> #include <vector> #include "core/fxcrt/fx_ext.h" #include "core/fxcrt/fx_xml.h" +#include "core/fxcrt/xml_int.h" #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" @@ -101,7 +101,7 @@ bool CXML_DataBufAcc::IsEOF() { } FX_FILESIZE CXML_DataBufAcc::GetPosition() { - return (FX_FILESIZE)m_dwCurPos; + return static_cast<FX_FILESIZE>(m_dwCurPos); } size_t CXML_DataBufAcc::ReadBlock(void* buffer, size_t size) { @@ -167,11 +167,12 @@ CXML_DataStmAcc::~CXML_DataStmAcc() { } bool CXML_DataStmAcc::IsEOF() { - return m_nStart + (FX_FILESIZE)m_dwSize >= m_pFileRead->GetSize(); + return m_nStart + static_cast<FX_FILESIZE>(m_dwSize) >= + m_pFileRead->GetSize(); } FX_FILESIZE CXML_DataStmAcc::GetPosition() { - return m_nStart + (FX_FILESIZE)m_dwSize; + return m_nStart + static_cast<FX_FILESIZE>(m_dwSize); } size_t CXML_DataStmAcc::ReadBlock(void* buffer, size_t size) { @@ -183,7 +184,7 @@ bool CXML_DataStmAcc::ReadNextBlock(bool bRestart) { m_nStart = 0; FX_FILESIZE nLength = m_pFileRead->GetSize(); - m_nStart += (FX_FILESIZE)m_dwSize; + m_nStart += static_cast<FX_FILESIZE>(m_dwSize); if (m_nStart >= nLength) return false; @@ -212,7 +213,6 @@ FX_FILESIZE CXML_DataStmAcc::GetBlockOffset() { CXML_Parser::CXML_Parser() : m_nOffset(0), - m_bSaveSpaceChars(false), m_pBuffer(nullptr), m_dwBufferSize(0), m_nBufferOffset(0), @@ -220,25 +220,8 @@ CXML_Parser::CXML_Parser() CXML_Parser::~CXML_Parser() {} -bool CXML_Parser::Init(uint8_t* pBuffer, size_t size) { +bool CXML_Parser::Init(const uint8_t* pBuffer, size_t size) { m_pDataAcc = pdfium::MakeRetain<CXML_DataBufAcc>(pBuffer, size); - return Init(); -} - -bool CXML_Parser::Init(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead) { - m_pDataAcc = pdfium::MakeRetain<CXML_DataStmAcc>(pFileRead); - return Init(); -} - -bool CXML_Parser::Init(const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer) { - if (!pBuffer) - return false; - - m_pDataAcc = pBuffer; - return Init(); -} - -bool CXML_Parser::Init() { m_nOffset = 0; return ReadNextBlock(); } @@ -259,33 +242,33 @@ bool CXML_Parser::IsEOF() { } void CXML_Parser::SkipWhiteSpaces() { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (IsEOF()) return; - } + do { while (m_dwIndex < m_dwBufferSize && g_FXCRT_XML_IsWhiteSpace(m_pBuffer[m_dwIndex])) { m_dwIndex++; } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (m_dwIndex < m_dwBufferSize || IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); } -void CXML_Parser::GetName(CFX_ByteString& space, CFX_ByteString& name) { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (IsEOF()) { + +void CXML_Parser::GetName(CFX_ByteString* space, CFX_ByteString* name) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (IsEOF()) return; - } + CFX_ByteTextBuf buf; uint8_t ch; do { while (m_dwIndex < m_dwBufferSize) { ch = m_pBuffer[m_dwIndex]; if (ch == ':') { - space = buf.AsStringC(); + *space = buf.AsStringC(); buf.Clear(); } else if (g_FXCRT_XML_IsNameChar(ch)) { buf.AppendChar(ch); @@ -294,15 +277,15 @@ void CXML_Parser::GetName(CFX_ByteString& space, CFX_ByteString& name) { } m_dwIndex++; } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (m_dwIndex < m_dwBufferSize || IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); - name = buf.AsStringC(); + *name = buf.AsStringC(); } + void CXML_Parser::SkipLiterals(const CFX_ByteStringC& str) { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); if (IsEOF()) { return; } @@ -311,32 +294,31 @@ void CXML_Parser::SkipLiterals(const CFX_ByteStringC& str) { while (m_dwIndex < m_dwBufferSize) { if (str.GetAt(i) != m_pBuffer[m_dwIndex++]) { i = 0; - } else { - i++; - if (i == iLen) { - break; - } + continue; } + i++; + if (i == iLen) + break; } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (i == iLen) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (i == iLen) return; - } - if (m_dwIndex < m_dwBufferSize || IsEOF()) { + + if (m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); while (!m_pDataAcc->IsEOF()) { ReadNextBlock(); - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwBufferSize; + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwBufferSize); } m_dwIndex = m_dwBufferSize; } + uint32_t CXML_Parser::GetCharRef() { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (IsEOF()) return 0; - } + uint8_t ch; int32_t iState = 0; CFX_ByteTextBuf buf; @@ -356,17 +338,16 @@ uint32_t CXML_Parser::GetCharRef() { m_dwIndex++; if (ch == ';') { CFX_ByteStringC ref = buf.AsStringC(); - if (ref == "gt") { + if (ref == "gt") code = '>'; - } else if (ref == "lt") { + else if (ref == "lt") code = '<'; - } else if (ref == "amp") { + else if (ref == "amp") code = '&'; - } else if (ref == "apos") { + else if (ref == "apos") code = '\''; - } else if (ref == "quot") { + else if (ref == "quot") code = '"'; - } iState = 10; break; } @@ -408,40 +389,40 @@ uint32_t CXML_Parser::GetCharRef() { } break; } - if (iState == 10) { + if (iState == 10) break; - } } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { break; } } while (ReadNextBlock()); return code; } + void CXML_Parser::GetAttrValue(CFX_WideString& value) { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (IsEOF()) return; - } + CFX_UTF8Decoder decoder; uint8_t mark = 0, ch = 0; do { while (m_dwIndex < m_dwBufferSize) { ch = m_pBuffer[m_dwIndex]; if (mark == 0) { - if (ch != '\'' && ch != '"') { + if (ch != '\'' && ch != '"') return; - } + mark = ch; m_dwIndex++; ch = 0; continue; } m_dwIndex++; - if (ch == mark) { + if (ch == mark) break; - } + if (ch == '&') { decoder.AppendChar(GetCharRef()); if (IsEOF()) { @@ -452,22 +433,22 @@ void CXML_Parser::GetAttrValue(CFX_WideString& value) { decoder.Input(ch); } } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (ch == mark || m_dwIndex < m_dwBufferSize || IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (ch == mark || m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); value = decoder.GetResult(); } -void CXML_Parser::GetTagName(CFX_ByteString& space, - CFX_ByteString& name, - bool& bEndTag, - bool bStartTag) { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (IsEOF()) { + +void CXML_Parser::GetTagName(bool bStartTag, + bool* bEndTag, + CFX_ByteString* space, + CFX_ByteString* name) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (IsEOF()) return; - } - bEndTag = false; + + *bEndTag = false; uint8_t ch; int32_t iState = bStartTag ? 1 : 0; do { @@ -476,9 +457,9 @@ void CXML_Parser::GetTagName(CFX_ByteString& space, switch (iState) { case 0: m_dwIndex++; - if (ch != '<') { + if (ch != '<') break; - } + iState = 1; break; case 1: @@ -487,7 +468,8 @@ void CXML_Parser::GetTagName(CFX_ByteString& space, SkipLiterals("?>"); iState = 0; break; - } else if (ch == '!') { + } + if (ch == '!') { m_dwIndex++; SkipLiterals("-->"); iState = 0; @@ -496,85 +478,85 @@ void CXML_Parser::GetTagName(CFX_ByteString& space, if (ch == '/') { m_dwIndex++; GetName(space, name); - bEndTag = true; + *bEndTag = true; } else { GetName(space, name); - bEndTag = false; + *bEndTag = false; } return; } } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (m_dwIndex < m_dwBufferSize || IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); } -CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, bool bStartTag) { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (IsEOF()) { + +std::unique_ptr<CXML_Element> CXML_Parser::ParseElement(CXML_Element* pParent, + bool bStartTag) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (IsEOF()) return nullptr; - } - CFX_ByteString tag_name, tag_space; + + CFX_ByteString tag_name; + CFX_ByteString tag_space; bool bEndTag; - GetTagName(tag_space, tag_name, bEndTag, bStartTag); - if (tag_name.IsEmpty() || bEndTag) { + GetTagName(bStartTag, &bEndTag, &tag_space, &tag_name); + if (tag_name.IsEmpty() || bEndTag) return nullptr; - } - CXML_Element* pElement = new CXML_Element; - pElement->m_pParent = pParent; - pElement->SetTag(tag_space.AsStringC(), tag_name.AsStringC()); + + auto pElement = pdfium::MakeUnique<CXML_Element>( + pParent, tag_space.AsStringC(), tag_name.AsStringC()); do { - CFX_ByteString attr_space, attr_name; + CFX_ByteString attr_space; + CFX_ByteString attr_name; while (m_dwIndex < m_dwBufferSize) { SkipWhiteSpaces(); - if (IsEOF()) { + if (IsEOF()) break; - } - if (!g_FXCRT_XML_IsNameIntro(m_pBuffer[m_dwIndex])) { + + if (!g_FXCRT_XML_IsNameIntro(m_pBuffer[m_dwIndex])) break; - } - GetName(attr_space, attr_name); + + GetName(&attr_space, &attr_name); SkipWhiteSpaces(); - if (IsEOF()) { + if (IsEOF()) break; - } - if (m_pBuffer[m_dwIndex] != '=') { + + if (m_pBuffer[m_dwIndex] != '=') break; - } + m_dwIndex++; SkipWhiteSpaces(); - if (IsEOF()) { + if (IsEOF()) break; - } + CFX_WideString attr_value; GetAttrValue(attr_value); pElement->m_AttrMap.SetAt(attr_space, attr_name, attr_value); } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (m_dwIndex < m_dwBufferSize || IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); SkipWhiteSpaces(); - if (IsEOF()) { + if (IsEOF()) return pElement; - } + uint8_t ch = m_pBuffer[m_dwIndex++]; if (ch == '/') { m_dwIndex++; - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); return pElement; } if (ch != '>') { - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - delete pElement; + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); return nullptr; } SkipWhiteSpaces(); - if (IsEOF()) { + if (IsEOF()) return pElement; - } + CFX_UTF8Decoder decoder; CFX_WideTextBuf content; bool bCDATA = false; @@ -601,30 +583,31 @@ CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, bool bStartTag) { SkipWhiteSpaces(); iState = 0; } else if (ch == '/') { - CFX_ByteString space, name; - GetName(space, name); + CFX_ByteString space; + CFX_ByteString name; + GetName(&space, &name); SkipWhiteSpaces(); m_dwIndex++; iState = 10; } else { content << decoder.GetResult(); CFX_WideString dataStr = content.MakeString(); - if (!bCDATA && !m_bSaveSpaceChars) { + if (!bCDATA) dataStr.TrimRight(L" \t\r\n"); - } - InsertContentSegment(bCDATA, dataStr.AsStringC(), pElement); + + InsertContentSegment(bCDATA, dataStr.AsStringC(), pElement.get()); content.Clear(); decoder.Clear(); bCDATA = false; iState = 0; m_dwIndex--; - CXML_Element* pSubElement = ParseElement(pElement, true); - if (!pSubElement) { + std::unique_ptr<CXML_Element> pSubElement( + ParseElement(pElement.get(), true)); + if (!pSubElement) break; - } - pSubElement->m_pParent = pElement; + pElement->m_Children.push_back( - {CXML_Element::Element, pSubElement}); + {CXML_Element::Element, pSubElement.release()}); SkipWhiteSpaces(); } break; @@ -646,89 +629,49 @@ CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, bool bStartTag) { break; } } - m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; - if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { + m_nOffset = m_nBufferOffset + static_cast<FX_FILESIZE>(m_dwIndex); + if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) break; - } } while (ReadNextBlock()); content << decoder.GetResult(); CFX_WideString dataStr = content.MakeString(); - if (!m_bSaveSpaceChars) { - dataStr.TrimRight(L" \t\r\n"); - } - InsertContentSegment(bCDATA, dataStr.AsStringC(), pElement); + dataStr.TrimRight(L" \t\r\n"); + + InsertContentSegment(bCDATA, dataStr.AsStringC(), pElement.get()); content.Clear(); decoder.Clear(); bCDATA = false; return pElement; } + void CXML_Parser::InsertContentSegment(bool bCDATA, const CFX_WideStringC& content, CXML_Element* pElement) { - if (content.IsEmpty()) { + if (content.IsEmpty()) return; - } + CXML_Content* pContent = new CXML_Content; pContent->Set(bCDATA, content); pElement->m_Children.push_back({CXML_Element::Content, pContent}); } -static CXML_Element* XML_ContinueParse(CXML_Parser& parser, - bool bSaveSpaceChars, - FX_FILESIZE* pParsedSize) { - parser.m_bSaveSpaceChars = bSaveSpaceChars; - CXML_Element* pElement = parser.ParseElement(nullptr, false); - if (pParsedSize) { - *pParsedSize = parser.m_nOffset; - } - return pElement; -} -CXML_Element* CXML_Element::Parse(const void* pBuffer, - size_t size, - bool bSaveSpaceChars, - FX_FILESIZE* pParsedSize) { - CXML_Parser parser; - if (!parser.Init((uint8_t*)pBuffer, size)) { - return nullptr; - } - return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); -} -CXML_Element* CXML_Element::Parse( - const CFX_RetainPtr<IFX_SeekableReadStream>& pFile, - bool bSaveSpaceChars, - FX_FILESIZE* pParsedSize) { +std::unique_ptr<CXML_Element> CXML_Element::Parse(const void* pBuffer, + size_t size) { CXML_Parser parser; - if (!parser.Init(pFile)) + if (!parser.Init(static_cast<const uint8_t*>(pBuffer), size)) return nullptr; - - return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); + return parser.ParseElement(nullptr, false); } -CXML_Element* CXML_Element::Parse( - const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer, - bool bSaveSpaceChars, - FX_FILESIZE* pParsedSize) { - CXML_Parser parser; - if (!parser.Init(pBuffer)) - return nullptr; - - return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); -} +CXML_Element::CXML_Element(const CXML_Element* pParent, + const CFX_ByteStringC& qSpace, + const CFX_ByteStringC& tagname) + : m_pParent(pParent), m_QSpaceName(qSpace), m_TagName(tagname) {} -CXML_Element::CXML_Element() : m_QSpaceName(), m_TagName(), m_AttrMap() {} -CXML_Element::CXML_Element(const CFX_ByteStringC& qSpace, - const CFX_ByteStringC& tagName) - : m_QSpaceName(), m_TagName(), m_AttrMap() { - m_QSpaceName = qSpace; - m_TagName = tagName; -} -CXML_Element::CXML_Element(const CFX_ByteStringC& qTagName) - : m_pParent(nullptr), m_QSpaceName(), m_TagName(), m_AttrMap() { - SetTag(qTagName); -} CXML_Element::~CXML_Element() { Empty(); } + void CXML_Element::Empty() { RemoveChildren(); } @@ -763,36 +706,38 @@ CFX_ByteString CXML_Element::GetNamespaceURI( const CFX_WideString* pwsSpace; const CXML_Element* pElement = this; do { - if (qName.IsEmpty()) { + if (qName.IsEmpty()) pwsSpace = pElement->m_AttrMap.Lookup("", "xmlns"); - } else { + else pwsSpace = pElement->m_AttrMap.Lookup("xmlns", qName); - } - if (pwsSpace) { + if (pwsSpace) break; - } + pElement = pElement->GetParent(); } while (pElement); - return pwsSpace ? FX_UTF8Encode(*pwsSpace) : CFX_ByteString(); + return pwsSpace ? pwsSpace->UTF8Encode() : CFX_ByteString(); } + void CXML_Element::GetAttrByIndex(int index, CFX_ByteString& space, CFX_ByteString& name, CFX_WideString& value) const { - if (index < 0 || index >= m_AttrMap.GetSize()) { + if (index < 0 || index >= m_AttrMap.GetSize()) return; - } + CXML_AttrItem& item = m_AttrMap.GetAt(index); space = item.m_QSpaceName; name = item.m_AttrName; value = item.m_Value; } + bool CXML_Element::HasAttr(const CFX_ByteStringC& name) const { CFX_ByteStringC bsSpace; CFX_ByteStringC bsName; FX_XML_SplitQualifiedName(name, bsSpace, bsName); return !!m_AttrMap.Lookup(CFX_ByteString(bsSpace), CFX_ByteString(bsName)); } + bool CXML_Element::GetAttrValue(const CFX_ByteStringC& name, CFX_WideString& attribute) const { CFX_ByteStringC bsSpace; @@ -800,17 +745,19 @@ bool CXML_Element::GetAttrValue(const CFX_ByteStringC& name, FX_XML_SplitQualifiedName(name, bsSpace, bsName); return GetAttrValue(bsSpace, bsName, attribute); } + bool CXML_Element::GetAttrValue(const CFX_ByteStringC& space, const CFX_ByteStringC& name, CFX_WideString& attribute) const { const CFX_WideString* pValue = m_AttrMap.Lookup(CFX_ByteString(space), CFX_ByteString(name)); - if (pValue) { - attribute = *pValue; - return true; - } - return false; + if (!pValue) + return false; + + attribute = *pValue; + return true; } + bool CXML_Element::GetAttrInteger(const CFX_ByteStringC& name, int& attribute) const { CFX_ByteStringC bsSpace; @@ -818,43 +765,49 @@ bool CXML_Element::GetAttrInteger(const CFX_ByteStringC& name, FX_XML_SplitQualifiedName(name, bsSpace, bsName); const CFX_WideString* pwsValue = m_AttrMap.Lookup(CFX_ByteString(bsSpace), CFX_ByteString(bsName)); - if (pwsValue) { - attribute = pwsValue->GetInteger(); - return true; - } - return false; + if (!pwsValue) + return false; + + attribute = pwsValue->GetInteger(); + return true; } + bool CXML_Element::GetAttrInteger(const CFX_ByteStringC& space, const CFX_ByteStringC& name, int& attribute) const { const CFX_WideString* pwsValue = m_AttrMap.Lookup(CFX_ByteString(space), CFX_ByteString(name)); - if (pwsValue) { - attribute = pwsValue->GetInteger(); - return true; - } - return false; + if (!pwsValue) + return false; + + attribute = pwsValue->GetInteger(); + return true; } + bool CXML_Element::GetAttrFloat(const CFX_ByteStringC& name, FX_FLOAT& attribute) const { - CFX_ByteStringC bsSpace, bsName; + CFX_ByteStringC bsSpace; + CFX_ByteStringC bsName; FX_XML_SplitQualifiedName(name, bsSpace, bsName); return GetAttrFloat(bsSpace, bsName, attribute); } + bool CXML_Element::GetAttrFloat(const CFX_ByteStringC& space, const CFX_ByteStringC& name, FX_FLOAT& attribute) const { const CFX_WideString* pValue = m_AttrMap.Lookup(CFX_ByteString(space), CFX_ByteString(name)); - if (pValue) { - attribute = pValue->GetFloat(); - return true; - } - return false; + if (!pValue) + return false; + + attribute = pValue->GetFloat(); + return true; } + CXML_Element::ChildType CXML_Element::GetChildType(uint32_t index) const { return index < m_Children.size() ? m_Children[index].type : Invalid; } + CFX_WideString CXML_Element::GetContent(uint32_t index) const { if (index < m_Children.size() && m_Children[index].type == Content) { CXML_Content* pContent = @@ -864,12 +817,13 @@ CFX_WideString CXML_Element::GetContent(uint32_t index) const { } return CFX_WideString(); } + CXML_Element* CXML_Element::GetElement(uint32_t index) const { - if (index < m_Children.size() && m_Children[index].type == Element) { + if (index < m_Children.size() && m_Children[index].type == Element) return static_cast<CXML_Element*>(m_Children[index].child); - } return nullptr; } + uint32_t CXML_Element::CountElements(const CFX_ByteStringC& space, const CFX_ByteStringC& tag) const { int count = 0; @@ -885,6 +839,7 @@ uint32_t CXML_Element::CountElements(const CFX_ByteStringC& space, } return count; } + CXML_Element* CXML_Element::GetElement(const CFX_ByteStringC& space, const CFX_ByteStringC& tag, int index) const { @@ -904,6 +859,7 @@ CXML_Element* CXML_Element::GetElement(const CFX_ByteStringC& space, } return nullptr; } + uint32_t CXML_Element::FindElement(CXML_Element* pChild) const { int index = 0; for (const ChildRecord& record : m_Children) { diff --git a/core/fxcrt/xml_int.h b/core/fxcrt/xml_int.h index e617a777f..96a7da9c5 100644 --- a/core/fxcrt/xml_int.h +++ b/core/fxcrt/xml_int.h @@ -8,6 +8,7 @@ #define CORE_FXCRT_XML_INT_H_ #include <algorithm> +#include <memory> #include "core/fxcrt/fx_stream.h" @@ -19,23 +20,21 @@ class CXML_Parser { CXML_Parser(); ~CXML_Parser(); - bool Init(uint8_t* pBuffer, size_t size); - bool Init(const CFX_RetainPtr<IFX_SeekableReadStream>& pFileRead); - bool Init(const CFX_RetainPtr<IFX_BufferedReadStream>& pBuffer); - bool Init(); + bool Init(const uint8_t* pBuffer, size_t size); bool ReadNextBlock(); bool IsEOF(); bool HaveAvailData(); void SkipWhiteSpaces(); - void GetName(CFX_ByteString& space, CFX_ByteString& name); + void GetName(CFX_ByteString* space, CFX_ByteString* name); void GetAttrValue(CFX_WideString& value); uint32_t GetCharRef(); - void GetTagName(CFX_ByteString& space, - CFX_ByteString& name, - bool& bEndTag, - bool bStartTag = false); + void GetTagName(bool bStartTag, + bool* bEndTag, + CFX_ByteString* space, + CFX_ByteString* name); void SkipLiterals(const CFX_ByteStringC& str); - CXML_Element* ParseElement(CXML_Element* pParent, bool bStartTag = false); + std::unique_ptr<CXML_Element> ParseElement(CXML_Element* pParent, + bool bStartTag); void InsertContentSegment(bool bCDATA, const CFX_WideStringC& content, CXML_Element* pElement); @@ -43,7 +42,6 @@ class CXML_Parser { CFX_RetainPtr<IFX_BufferedReadStream> m_pDataAcc; FX_FILESIZE m_nOffset; - bool m_bSaveSpaceChars; const uint8_t* m_pBuffer; size_t m_dwBufferSize; FX_FILESIZE m_nBufferOffset; diff --git a/core/fxge/agg/fx_agg_driver.cpp b/core/fxge/agg/fx_agg_driver.cpp index 94fe72d30..8c7277752 100644 --- a/core/fxge/agg/fx_agg_driver.cpp +++ b/core/fxge/agg/fx_agg_driver.cpp @@ -32,9 +32,9 @@ namespace { -void HardClip(FX_FLOAT& x, FX_FLOAT& y) { - x = std::max(std::min(x, 50000.0f), -50000.0f); - y = std::max(std::min(y, 50000.0f), -50000.0f); +CFX_PointF HardClip(const CFX_PointF& pos) { + return CFX_PointF(std::max(std::min(pos.x, 50000.0f), -50000.0f), + std::max(std::min(pos.y, 50000.0f), -50000.0f)); } void RgbByteOrderSetPixel(CFX_DIBitmap* pBitmap, int x, int y, uint32_t argb) { @@ -273,46 +273,46 @@ bool DibSetPixel(CFX_DIBitmap* pDevice, void CAgg_PathData::BuildPath(const CFX_PathData* pPathData, const CFX_Matrix* pObject2Device) { - int nPoints = pPathData->GetPointCount(); - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - for (int i = 0; i < nPoints; i++) { - FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY; - if (pObject2Device) { - pObject2Device->Transform(x, y); - } - HardClip(x, y); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - m_PathData.move_to(x, y); - } else if (point_type == FXPT_LINETO) { - if (pPoints[i - 1].m_Flag == FXPT_MOVETO && - (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && - pPoints[i].m_PointX == pPoints[i - 1].m_PointX && - pPoints[i].m_PointY == pPoints[i - 1].m_PointY) { - x += 1; + const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints(); + for (size_t i = 0; i < pPoints.size(); i++) { + CFX_PointF pos = pPoints[i].m_Point; + if (pObject2Device) + pos = pObject2Device->Transform(pos); + + pos = HardClip(pos); + FXPT_TYPE point_type = pPoints[i].m_Type; + if (point_type == FXPT_TYPE::MoveTo) { + m_PathData.move_to(pos.x, pos.y); + } else if (point_type == FXPT_TYPE::LineTo) { + if (pPoints[i - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo) && + (i == pPoints.size() - 1 || + pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) && + pPoints[i].m_Point == pPoints[i - 1].m_Point) { + pos.x += 1; } - m_PathData.line_to(x, y); - } else if (point_type == FXPT_BEZIERTO) { - FX_FLOAT x0 = pPoints[i - 1].m_PointX, y0 = pPoints[i - 1].m_PointY; - FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; - FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; + m_PathData.line_to(pos.x, pos.y); + } else if (point_type == FXPT_TYPE::BezierTo) { + CFX_PointF pos0 = pPoints[i - 1].m_Point; + CFX_PointF pos2 = pPoints[i + 1].m_Point; + CFX_PointF pos3 = pPoints[i + 2].m_Point; if (pObject2Device) { - pObject2Device->Transform(x0, y0); - pObject2Device->Transform(x2, y2); - pObject2Device->Transform(x3, y3); + pos0 = pObject2Device->Transform(pos0); + pos2 = pObject2Device->Transform(pos2); + pos3 = pObject2Device->Transform(pos3); } - HardClip(x0, y0); - HardClip(x2, y2); - HardClip(x3, y3); - agg::curve4 curve(x0, y0, x, y, x2, y2, x3, y3); + pos0 = HardClip(pos0); + pos2 = HardClip(pos2); + pos3 = HardClip(pos3); + agg::curve4 curve(pos0.x, pos0.y, pos.x, pos.y, pos2.x, pos2.y, pos3.x, + pos3.y); i += 2; m_PathData.add_path_curve(curve); } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { + if (pPoints[i].m_CloseFigure) m_PathData.end_poly(); - } } } + namespace agg { template <class BaseRenderer> @@ -552,7 +552,8 @@ bool CFX_AggDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, m_pClipRgn = pdfium::MakeUnique<CFX_ClipRgn>( GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); } - if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { + size_t size = pPathData->GetPoints().size(); + if (size == 5 || size == 4) { CFX_FloatRect rectf; if (pPathData->IsRect(pObject2Device, &rectf)) { rectf.Intersect( @@ -1500,14 +1501,16 @@ bool CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData, matrix1.a = std::max(FXSYS_fabs(pObject2Device->a), FXSYS_fabs(pObject2Device->b)); matrix1.d = matrix1.a; - matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, - pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, 0, - 0); + matrix2 = CFX_Matrix( + pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a, + pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d, 0, 0); + CFX_Matrix mtRervese; mtRervese.SetReverse(matrix2); matrix1 = *pObject2Device; matrix1.Concat(mtRervese); } + CAgg_PathData path_data; path_data.BuildPath(pPathData, &matrix1); agg::rasterizer_scanline_aa rasterizer; diff --git a/core/fxge/apple/fx_apple_platform.cpp b/core/fxge/apple/fx_apple_platform.cpp index 7fc12fd36..f576eb0ba 100644 --- a/core/fxge/apple/fx_apple_platform.cpp +++ b/core/fxge/apple/fx_apple_platform.cpp @@ -35,13 +35,11 @@ bool CGDrawGlyphRun(CGContextRef pContext, if (nChars == 0) return true; - CFX_Matrix new_matrix; bool bNegSize = font_size < 0; if (bNegSize) font_size = -font_size; - FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY; - new_matrix.Transform(ori_x, ori_y); + CFX_Matrix new_matrix; if (pObject2Device) new_matrix.Concat(*pObject2Device); @@ -63,10 +61,10 @@ bool CGDrawGlyphRun(CGContextRef pContext, glyph_indices[i] = pCharPos[i].m_ExtGID ? pCharPos[i].m_ExtGID : pCharPos[i].m_GlyphIndex; if (bNegSize) - glyph_positions[i].x = -pCharPos[i].m_OriginX; + glyph_positions[i].x = -pCharPos[i].m_Origin.x; else - glyph_positions[i].x = pCharPos[i].m_OriginX; - glyph_positions[i].y = pCharPos[i].m_OriginY; + glyph_positions[i].x = pCharPos[i].m_Origin.x; + glyph_positions[i].y = pCharPos[i].m_Origin.y; } if (bNegSize) { new_matrix.a = -new_matrix.a; diff --git a/core/fxge/cfx_pathdata.h b/core/fxge/cfx_pathdata.h index 3e0e11c4e..b0e30e32a 100644 --- a/core/fxge/cfx_pathdata.h +++ b/core/fxge/cfx_pathdata.h @@ -7,14 +7,26 @@ #ifndef CORE_FXGE_CFX_PATHDATA_H_ #define CORE_FXGE_CFX_PATHDATA_H_ +#include <vector> + #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" #include "core/fxge/cfx_renderdevice.h" -struct FX_PATHPOINT { - FX_FLOAT m_PointX; - FX_FLOAT m_PointY; - int m_Flag; +class FX_PATHPOINT { + public: + FX_PATHPOINT(); + FX_PATHPOINT(const CFX_PointF& point, FXPT_TYPE type, bool close); + FX_PATHPOINT(const FX_PATHPOINT& other); + ~FX_PATHPOINT(); + + bool IsTypeAndOpen(FXPT_TYPE type) const { + return m_Type == type && !m_CloseFigure; + } + + CFX_PointF m_Point; + FXPT_TYPE m_Type; + bool m_CloseFigure; }; class CFX_PathData { @@ -23,34 +35,36 @@ class CFX_PathData { CFX_PathData(const CFX_PathData& src); ~CFX_PathData(); - int GetPointCount() const { return m_PointCount; } - int GetFlag(int index) const { return m_pPoints[index].m_Flag; } - FX_FLOAT GetPointX(int index) const { return m_pPoints[index].m_PointX; } - FX_FLOAT GetPointY(int index) const { return m_pPoints[index].m_PointY; } - FX_PATHPOINT* GetPoints() const { return m_pPoints; } + void Clear(); + + FXPT_TYPE GetType(int index) const { return m_Points[index].m_Type; } + bool IsClosingFigure(int index) const { + return m_Points[index].m_CloseFigure; + } + + CFX_PointF GetPoint(int index) const { return m_Points[index].m_Point; } + const std::vector<FX_PATHPOINT>& GetPoints() const { return m_Points; } + std::vector<FX_PATHPOINT>& GetPoints() { return m_Points; } - void SetPointCount(int nPoints); - void AllocPointCount(int nPoints); - void AddPointCount(int addPoints); CFX_FloatRect GetBoundingBox() const; CFX_FloatRect GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const; + void Transform(const CFX_Matrix* pMatrix); bool IsRect() const; - bool GetZeroAreaPath(CFX_PathData& NewPath, - CFX_Matrix* pMatrix, - bool& bThin, - bool bAdjust) const; + bool GetZeroAreaPath(const CFX_Matrix* pMatrix, + bool bAdjust, + CFX_PathData* NewPath, + bool* bThin, + bool* setIdentity) const; bool IsRect(const CFX_Matrix* pMatrix, CFX_FloatRect* rect) const; + void Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix); void AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top); - void SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag); - void TrimPoints(int nPoints); - void Copy(const CFX_PathData& src); + void AppendPoint(const CFX_PointF& pos, FXPT_TYPE type, bool closeFigure); + void ClosePath(); private: - int m_PointCount; - int m_AllocCount; - FX_PATHPOINT* m_pPoints; + std::vector<FX_PATHPOINT> m_Points; }; #endif // CORE_FXGE_CFX_PATHDATA_H_ diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h index 800d0c7c5..2e9abf996 100644 --- a/core/fxge/cfx_renderdevice.h +++ b/core/fxge/cfx_renderdevice.h @@ -27,12 +27,6 @@ class IFX_RenderDeviceDriver; #define FXDC_DISPLAY 1 #define FXDC_PRINTER 2 -#define FXPT_CLOSEFIGURE 0x01 -#define FXPT_LINETO 0x02 -#define FXPT_BEZIERTO 0x04 -#define FXPT_MOVETO 0x06 -#define FXPT_TYPE 0x06 - #define FXRC_GET_BITS 0x01 #define FXRC_BIT_MASK 0x02 #define FXRC_ALPHA_MASK 0x04 @@ -66,10 +60,16 @@ class IFX_RenderDeviceDriver; #define FXTEXT_PRINTIMAGETEXT 0x10 #define FXTEXT_NOSMOOTH 0x20 -struct FXTEXT_CHARPOS { +enum class FXPT_TYPE : uint8_t { LineTo, BezierTo, MoveTo }; + +class FXTEXT_CHARPOS { + public: + FXTEXT_CHARPOS(); + FXTEXT_CHARPOS(const FXTEXT_CHARPOS&); + ~FXTEXT_CHARPOS(); + FX_FLOAT m_AdjustMatrix[4]; - FX_FLOAT m_OriginX; - FX_FLOAT m_OriginY; + CFX_PointF m_Origin; uint32_t m_GlyphIndex; int32_t m_FontCharWidth; #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ diff --git a/core/fxge/dib/fx_dib_composite.cpp b/core/fxge/dib/fx_dib_composite.cpp index e3dc7404f..072ebbddd 100644 --- a/core/fxge/dib/fx_dib_composite.cpp +++ b/core/fxge/dib/fx_dib_composite.cpp @@ -4014,6 +4014,7 @@ CFX_ScanlineCompositor::CFX_ScanlineCompositor() { m_CacheSize = 0; m_bRgbByteOrder = false; m_BlendType = FXDIB_BLEND_NORMAL; + m_pIccTransform = nullptr; } CFX_ScanlineCompositor::~CFX_ScanlineCompositor() { diff --git a/core/fxge/dib/fx_dib_main.cpp b/core/fxge/dib/fx_dib_main.cpp index 8e6366d5c..96cae9d4e 100644 --- a/core/fxge/dib/fx_dib_main.cpp +++ b/core/fxge/dib/fx_dib_main.cpp @@ -1471,6 +1471,7 @@ void CFX_FilteredDIB::DownSampleScanline(int line, CFX_ImageRenderer::CFX_ImageRenderer() { m_Status = 0; + m_pIccTransform = nullptr; m_bRgbByteOrder = false; m_BlendType = FXDIB_BLEND_NORMAL; } diff --git a/core/fxge/dib/fx_dib_transform.cpp b/core/fxge/dib/fx_dib_transform.cpp index 1c29ada68..bd8827294 100644 --- a/core/fxge/dib/fx_dib_transform.cpp +++ b/core/fxge/dib/fx_dib_transform.cpp @@ -396,12 +396,13 @@ bool CFX_ImageTransformer::Start() { CFX_Matrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height)); stretch2dest.Concat( - m_pMatrix->a / stretch_width, m_pMatrix->b / stretch_width, - m_pMatrix->c / stretch_height, m_pMatrix->d / stretch_height, - m_pMatrix->e, m_pMatrix->f); + CFX_Matrix(m_pMatrix->a / stretch_width, m_pMatrix->b / stretch_width, + m_pMatrix->c / stretch_height, m_pMatrix->d / stretch_height, + m_pMatrix->e, m_pMatrix->f)); m_dest2stretch.SetReverse(stretch2dest); + CFX_FloatRect clip_rect_f(result_clip); - clip_rect_f.Transform(&m_dest2stretch); + m_dest2stretch.TransformRect(clip_rect_f); m_StretchClip = clip_rect_f.GetOuterRect(); m_StretchClip.Intersect(0, 0, stretch_width, stretch_height); m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>( @@ -455,7 +456,7 @@ bool CFX_ImageTransformer::Continue(IFX_Pause* pPause) { CFX_Matrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_result.left), (FX_FLOAT)(m_result.top)); result2stretch.Concat(m_dest2stretch); - result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top); + result2stretch.Translate(-m_StretchClip.left, -m_StretchClip.top); if (!stretch_buf_mask && pTransformed->m_pAlphaMask) { pTransformed->m_pAlphaMask->Clear(0xff000000); } else if (pTransformed->m_pAlphaMask) { diff --git a/core/fxge/fx_font.h b/core/fxge/fx_font.h index 224720fbc..07392fa07 100644 --- a/core/fxge/fx_font.h +++ b/core/fxge/fx_font.h @@ -58,13 +58,18 @@ using CFX_TypeFace = SkTypeface; #define FXFONT_FW_NORMAL 400 #define FXFONT_FW_BOLD 700 -/* Font styles */ -#define FXFONT_FIXED_PITCH 0x01 -#define FXFONT_SERIF 0x02 -#define FXFONT_SYMBOLIC 0x04 -#define FXFONT_SCRIPT 0x08 -#define FXFONT_ITALIC 0x40 -#define FXFONT_BOLD 0x40000 +/* Font styles as defined in PDF 1.7 Table 5.20 */ +#define FXFONT_FIXED_PITCH (1 << 0) +#define FXFONT_SERIF (1 << 1) +#define FXFONT_SYMBOLIC (1 << 2) +#define FXFONT_SCRIPT (1 << 3) +#define FXFONT_NONSYMBOLIC (1 << 5) +#define FXFONT_ITALIC (1 << 6) +#define FXFONT_ALLCAP (1 << 16) +#define FXFONT_SMALLCAP (1 << 17) +#define FXFONT_BOLD (1 << 18) + +/* Other font flags */ #define FXFONT_USEEXTERNATTR 0x80000 #define FXFONT_CIDFONT 0x100000 #ifdef PDF_ENABLE_XFA @@ -222,12 +227,15 @@ class CFX_GlyphBitmap { CFX_DIBitmap m_Bitmap; }; -struct FXTEXT_GLYPHPOS { +class FXTEXT_GLYPHPOS { + public: + FXTEXT_GLYPHPOS(); + FXTEXT_GLYPHPOS(const FXTEXT_GLYPHPOS&); + ~FXTEXT_GLYPHPOS(); + const CFX_GlyphBitmap* m_pGlyph; - int m_OriginX; - int m_OriginY; - FX_FLOAT m_fOriginX; - FX_FLOAT m_fOriginY; + CFX_Point m_Origin; + CFX_PointF m_fOrigin; }; FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, diff --git a/core/fxge/ge/cfx_facecache.cpp b/core/fxge/ge/cfx_facecache.cpp index cbaa07e44..314c95b8b 100644 --- a/core/fxge/ge/cfx_facecache.cpp +++ b/core/fxge/ge/cfx_facecache.cpp @@ -101,10 +101,10 @@ CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(const CFX_Font* pFont, return nullptr; FXFT_Matrix ft_matrix; - ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536); - ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536); - ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536); - ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536); + ft_matrix.xx = (signed long)(pMatrix->a / 64 * 65536); + ft_matrix.xy = (signed long)(pMatrix->c / 64 * 65536); + ft_matrix.yx = (signed long)(pMatrix->b / 64 * 65536); + ft_matrix.yy = (signed long)(pMatrix->d / 64 * 65536); bool bUseCJKSubFont = false; const CFX_SubstFont* pSubstFont = pFont->GetSubstFont(); if (pSubstFont) { diff --git a/core/fxge/ge/cfx_font.cpp b/core/fxge/ge/cfx_font.cpp index 24dcb8738..87157b010 100644 --- a/core/fxge/ge/cfx_font.cpp +++ b/core/fxge/ge/cfx_font.cpp @@ -28,9 +28,7 @@ namespace { typedef struct { - bool m_bCount; - int m_PointCount; - FX_PATHPOINT* m_pPoints; + CFX_PathData* m_pPath; int m_CurX; int m_CurY; FX_FLOAT m_CoordUnit; @@ -86,59 +84,47 @@ FXFT_Face FT_LoadFont(const uint8_t* pData, int size) { } void Outline_CheckEmptyContour(OUTLINE_PARAMS* param) { - if (param->m_PointCount >= 2 && - param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO && - param->m_pPoints[param->m_PointCount - 2].m_PointX == - param->m_pPoints[param->m_PointCount - 1].m_PointX && - param->m_pPoints[param->m_PointCount - 2].m_PointY == - param->m_pPoints[param->m_PointCount - 1].m_PointY) { - param->m_PointCount -= 2; + std::vector<FX_PATHPOINT>& points = param->m_pPath->GetPoints(); + size_t size = points.size(); + + if (size >= 2 && points[size - 2].IsTypeAndOpen(FXPT_TYPE::MoveTo) && + points[size - 2].m_Point == points[size - 1].m_Point) { + size -= 2; } - if (param->m_PointCount >= 4 && - param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO && - param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO && - param->m_pPoints[param->m_PointCount - 3].m_PointX == - param->m_pPoints[param->m_PointCount - 4].m_PointX && - param->m_pPoints[param->m_PointCount - 3].m_PointY == - param->m_pPoints[param->m_PointCount - 4].m_PointY && - param->m_pPoints[param->m_PointCount - 2].m_PointX == - param->m_pPoints[param->m_PointCount - 4].m_PointX && - param->m_pPoints[param->m_PointCount - 2].m_PointY == - param->m_pPoints[param->m_PointCount - 4].m_PointY && - param->m_pPoints[param->m_PointCount - 1].m_PointX == - param->m_pPoints[param->m_PointCount - 4].m_PointX && - param->m_pPoints[param->m_PointCount - 1].m_PointY == - param->m_pPoints[param->m_PointCount - 4].m_PointY) { - param->m_PointCount -= 4; + if (size >= 4 && points[size - 4].IsTypeAndOpen(FXPT_TYPE::MoveTo) && + points[size - 3].IsTypeAndOpen(FXPT_TYPE::BezierTo) && + points[size - 3].m_Point == points[size - 4].m_Point && + points[size - 2].m_Point == points[size - 4].m_Point && + points[size - 1].m_Point == points[size - 4].m_Point) { + size -= 4; } + points.resize(size); } int Outline_MoveTo(const FXFT_Vector* to, void* user) { OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - Outline_CheckEmptyContour(param); - param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO; - param->m_CurX = to->x; - param->m_CurY = to->y; - if (param->m_PointCount) - param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; - } - param->m_PointCount++; + + Outline_CheckEmptyContour(param); + + param->m_pPath->ClosePath(); + param->m_pPath->AppendPoint( + CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit), + FXPT_TYPE::MoveTo, false); + + param->m_CurX = to->x; + param->m_CurY = to->y; return 0; } int Outline_LineTo(const FXFT_Vector* to, void* user) { OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO; - param->m_CurX = to->x; - param->m_CurY = to->y; - } - param->m_PointCount++; + + param->m_pPath->AppendPoint( + CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit), + FXPT_TYPE::LineTo, false); + + param->m_CurX = to->x; + param->m_CurY = to->y; return 0; } @@ -146,28 +132,25 @@ int Outline_ConicTo(const FXFT_Vector* control, const FXFT_Vector* to, void* user) { OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - param->m_pPoints[param->m_PointCount].m_PointX = - (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / - param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = - (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / - param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 1].m_PointX = - (control->x + (to->x - control->x) / 3) / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_PointY = - (control->y + (to->y - control->y) / 3) / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 2].m_PointX = - to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_PointY = - to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; - param->m_CurX = to->x; - param->m_CurY = to->y; - } - param->m_PointCount += 3; + + param->m_pPath->AppendPoint( + CFX_PointF((param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / + param->m_CoordUnit, + (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / + param->m_CoordUnit), + FXPT_TYPE::BezierTo, false); + + param->m_pPath->AppendPoint( + CFX_PointF((control->x + (to->x - control->x) / 3) / param->m_CoordUnit, + (control->y + (to->y - control->y) / 3) / param->m_CoordUnit), + FXPT_TYPE::BezierTo, false); + + param->m_pPath->AppendPoint( + CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit), + FXPT_TYPE::BezierTo, false); + + param->m_CurX = to->x; + param->m_CurY = to->y; return 0; } @@ -176,26 +159,21 @@ int Outline_CubicTo(const FXFT_Vector* control1, const FXFT_Vector* to, void* user) { OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user; - if (!param->m_bCount) { - param->m_pPoints[param->m_PointCount].m_PointX = - control1->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_PointY = - control1->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 1].m_PointX = - control2->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_PointY = - control2->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO; - param->m_pPoints[param->m_PointCount + 2].m_PointX = - to->x / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_PointY = - to->y / param->m_CoordUnit; - param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO; - param->m_CurX = to->x; - param->m_CurY = to->y; - } - param->m_PointCount += 3; + + param->m_pPath->AppendPoint(CFX_PointF(control1->x / param->m_CoordUnit, + control1->y / param->m_CoordUnit), + FXPT_TYPE::BezierTo, false); + + param->m_pPath->AppendPoint(CFX_PointF(control2->x / param->m_CoordUnit, + control2->y / param->m_CoordUnit), + FXPT_TYPE::BezierTo, false); + + param->m_pPath->AppendPoint( + CFX_PointF(to->x / param->m_CoordUnit, to->y / param->m_CoordUnit), + FXPT_TYPE::BezierTo, false); + + param->m_CurX = to->x; + param->m_CurY = to->y; return 0; } @@ -672,6 +650,7 @@ CFX_PathData* CFX_Font::LoadGlyphPathImpl(uint32_t glyph_index, level = s_WeightPow[index] * 2; FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level); } + FXFT_Outline_Funcs funcs; funcs.move_to = Outline_MoveTo; funcs.line_to = Outline_LineTo; @@ -679,25 +658,21 @@ CFX_PathData* CFX_Font::LoadGlyphPathImpl(uint32_t glyph_index, funcs.cubic_to = Outline_CubicTo; funcs.shift = 0; funcs.delta = 0; + OUTLINE_PARAMS params; - params.m_bCount = true; - params.m_PointCount = 0; - FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); - if (params.m_PointCount == 0) - return nullptr; - CFX_PathData* pPath = new CFX_PathData; - pPath->SetPointCount(params.m_PointCount); - params.m_bCount = false; - params.m_PointCount = 0; - params.m_pPoints = pPath->GetPoints(); + auto pPath = pdfium::MakeUnique<CFX_PathData>(); + params.m_pPath = pPath.get(); params.m_CurX = params.m_CurY = 0; params.m_CoordUnit = 64 * 64.0; + FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, ¶ms); + if (pPath->GetPoints().empty()) + return nullptr; + Outline_CheckEmptyContour(¶ms); - pPath->TrimPoints(params.m_PointCount); - if (params.m_PointCount) - pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE; - return pPath; + pPath->ClosePath(); + + return pPath.release(); } const CFX_GlyphBitmap* CFX_Font::LoadGlyphBitmap(uint32_t glyph_index, diff --git a/core/fxge/ge/cfx_fontmapper.cpp b/core/fxge/ge/cfx_fontmapper.cpp index 02143ecc5..064fc9610 100644 --- a/core/fxge/ge/cfx_fontmapper.cpp +++ b/core/fxge/ge/cfx_fontmapper.cpp @@ -582,15 +582,16 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, bItalic = italic_angle != 0; weight = old_weight; } - if (family.Find("Narrow") > 0 || family.Find("Condensed") > 0) { #if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ + if (SubstName.Find("Narrow") > 0 || SubstName.Find("Condensed") > 0) family = "LiberationSansNarrow"; #elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_ + if (family.Find("Narrow") > 0 || family.Find("Condensed") > 0) family = "RobotoCondensed"; #else + if (family.Find("Narrow") > 0 || family.Find("Condensed") > 0) family = "ArialNarrow"; -#endif - } +#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ } else { pSubstFont->m_bSubstCJK = true; if (nStyle) diff --git a/core/fxge/ge/cfx_graphstate.cpp b/core/fxge/ge/cfx_graphstate.cpp index 7eb6d3d85..6357aa51a 100644 --- a/core/fxge/ge/cfx_graphstate.cpp +++ b/core/fxge/ge/cfx_graphstate.cpp @@ -30,7 +30,7 @@ void CFX_GraphState::SetLineDash(CPDF_Array* pArray, } FX_FLOAT CFX_GraphState::GetLineWidth() const { - return m_Ref.GetObject()->m_LineWidth; + return m_Ref.GetObject() ? m_Ref.GetObject()->m_LineWidth : 1.f; } void CFX_GraphState::SetLineWidth(FX_FLOAT width) { @@ -53,7 +53,7 @@ void CFX_GraphState::SetLineJoin(CFX_GraphStateData::LineJoin join) { } FX_FLOAT CFX_GraphState::GetMiterLimit() const { - return m_Ref.GetObject()->m_MiterLimit; + return m_Ref.GetObject() ? m_Ref.GetObject()->m_MiterLimit : 10.f; } void CFX_GraphState::SetMiterLimit(FX_FLOAT limit) { diff --git a/core/fxge/ge/cfx_pathdata.cpp b/core/fxge/ge/cfx_pathdata.cpp index 19e8bdb01..9fa2cd2aa 100644 --- a/core/fxge/ge/cfx_pathdata.cpp +++ b/core/fxge/ge/cfx_pathdata.cpp @@ -9,263 +9,250 @@ #include "core/fxcrt/fx_system.h" #include "third_party/base/numerics/safe_math.h" -CFX_PathData::CFX_PathData() - : m_PointCount(0), m_AllocCount(0), m_pPoints(nullptr) {} +namespace { -CFX_PathData::~CFX_PathData() { - FX_Free(m_pPoints); -} - -void CFX_PathData::SetPointCount(int nPoints) { - m_PointCount = nPoints; - if (m_AllocCount < nPoints) { - FX_Free(m_pPoints); - m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints); - m_AllocCount = nPoints; - } -} - -void CFX_PathData::AllocPointCount(int nPoints) { - if (m_AllocCount < nPoints) { - FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints); - if (m_PointCount) { - FXSYS_memcpy(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT)); +void UpdateLineEndPoints(CFX_FloatRect* rect, + const CFX_PointF& start_pos, + const CFX_PointF& end_pos, + FX_FLOAT hw) { + if (start_pos.x == end_pos.x) { + if (start_pos.y == end_pos.y) { + rect->UpdateRect(end_pos.x + hw, end_pos.y + hw); + rect->UpdateRect(end_pos.x - hw, end_pos.y - hw); + return; } - FX_Free(m_pPoints); - m_pPoints = pNewBuf; - m_AllocCount = nPoints; - } -} -CFX_PathData::CFX_PathData(const CFX_PathData& src) { - m_PointCount = m_AllocCount = src.m_PointCount; - m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount); - FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount); -} + FX_FLOAT point_y; + if (end_pos.y < start_pos.y) + point_y = end_pos.y - hw; + else + point_y = end_pos.y + hw; -void CFX_PathData::TrimPoints(int nPoints) { - if (m_PointCount <= nPoints) { + rect->UpdateRect(end_pos.x + hw, point_y); + rect->UpdateRect(end_pos.x - hw, point_y); return; } - SetPointCount(nPoints); -} -void CFX_PathData::AddPointCount(int addPoints) { - pdfium::base::CheckedNumeric<int> safe_new_count = m_PointCount; - safe_new_count += addPoints; - int new_count = safe_new_count.ValueOrDie(); - AllocPointCount(new_count); - m_PointCount = new_count; -} + if (start_pos.y == end_pos.y) { + FX_FLOAT point_x; + if (end_pos.x < start_pos.x) + point_x = end_pos.x - hw; + else + point_x = end_pos.x + hw; -void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) { - int old_count = m_PointCount; - AddPointCount(pSrc->m_PointCount); - FXSYS_memcpy(m_pPoints + old_count, pSrc->m_pPoints, - pSrc->m_PointCount * sizeof(FX_PATHPOINT)); - if (pMatrix) { - for (int i = 0; i < pSrc->m_PointCount; i++) { - pMatrix->Transform(m_pPoints[old_count + i].m_PointX, - m_pPoints[old_count + i].m_PointY); - } + rect->UpdateRect(point_x, end_pos.y + hw); + rect->UpdateRect(point_x, end_pos.y - hw); + return; } -} -void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag) { - ASSERT(index < m_PointCount); - m_pPoints[index].m_PointX = x; - m_pPoints[index].m_PointY = y; - m_pPoints[index].m_Flag = flag; + CFX_PointF diff = end_pos - start_pos; + FX_FLOAT ll = FXSYS_sqrt2(diff.x, diff.y); + FX_FLOAT mx = end_pos.x + hw * diff.x / ll; + FX_FLOAT my = end_pos.y + hw * diff.y / ll; + FX_FLOAT dx1 = hw * diff.y / ll; + FX_FLOAT dy1 = hw * diff.x / ll; + rect->UpdateRect(mx - dx1, my + dy1); + rect->UpdateRect(mx + dx1, my - dy1); } -void CFX_PathData::AppendRect(FX_FLOAT left, - FX_FLOAT bottom, - FX_FLOAT right, - FX_FLOAT top) { - int old_count = m_PointCount; - AddPointCount(5); - FX_PATHPOINT* pPoints = m_pPoints + old_count; - pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left; - pPoints[2].m_PointX = pPoints[3].m_PointX = right; - pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom; - pPoints[1].m_PointY = pPoints[2].m_PointY = top; - pPoints[0].m_Flag = FXPT_MOVETO; - pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO; - pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE; -} - -CFX_FloatRect CFX_PathData::GetBoundingBox() const { - CFX_FloatRect rect; - if (m_PointCount) { - rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY); - for (int i = 1; i < m_PointCount; i++) { - rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); - } - } - return rect; -} - -static void _UpdateLineEndPoints(CFX_FloatRect& rect, - FX_FLOAT start_x, - FX_FLOAT start_y, - FX_FLOAT end_x, - FX_FLOAT end_y, - FX_FLOAT hw) { - if (start_x == end_x) { - if (start_y == end_y) { - rect.UpdateRect(end_x + hw, end_y + hw); - rect.UpdateRect(end_x - hw, end_y - hw); - return; - } - FX_FLOAT point_y; - if (end_y < start_y) { - point_y = end_y - hw; - } else { - point_y = end_y + hw; - } - rect.UpdateRect(end_x + hw, point_y); - rect.UpdateRect(end_x - hw, point_y); - return; - } - if (start_y == end_y) { - FX_FLOAT point_x; - if (end_x < start_x) { - point_x = end_x - hw; - } else { - point_x = end_x + hw; - } - rect.UpdateRect(point_x, end_y + hw); - rect.UpdateRect(point_x, end_y - hw); - return; - } - FX_FLOAT dx = end_x - start_x; - FX_FLOAT dy = end_y - start_y; - FX_FLOAT ll = FXSYS_sqrt2(dx, dy); - FX_FLOAT mx = end_x + hw * dx / ll; - FX_FLOAT my = end_y + hw * dy / ll; - FX_FLOAT dx1 = hw * dy / ll; - FX_FLOAT dy1 = hw * dx / ll; - rect.UpdateRect(mx - dx1, my + dy1); - rect.UpdateRect(mx + dx1, my - dy1); -} +void UpdateLineJoinPoints(CFX_FloatRect* rect, + const CFX_PointF& start_pos, + const CFX_PointF& mid_pos, + const CFX_PointF& end_pos, + FX_FLOAT half_width, + FX_FLOAT miter_limit) { + FX_FLOAT start_k = 0; + FX_FLOAT start_c = 0; + FX_FLOAT end_k = 0; + FX_FLOAT end_c = 0; + FX_FLOAT start_len = 0; + FX_FLOAT start_dc = 0; + FX_FLOAT end_len = 0; + FX_FLOAT end_dc = 0; + FX_FLOAT one_twentieth = 1.0f / 20; -static void _UpdateLineJoinPoints(CFX_FloatRect& rect, - FX_FLOAT start_x, - FX_FLOAT start_y, - FX_FLOAT middle_x, - FX_FLOAT middle_y, - FX_FLOAT end_x, - FX_FLOAT end_y, - FX_FLOAT half_width, - FX_FLOAT miter_limit) { - FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, - start_dc = 0, end_len = 0, end_dc = 0; - bool bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20; - bool bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20; + bool bStartVert = FXSYS_fabs(start_pos.x - mid_pos.x) < one_twentieth; + bool bEndVert = FXSYS_fabs(mid_pos.x - end_pos.x) < one_twentieth; if (bStartVert && bEndVert) { - int start_dir = middle_y > start_y ? 1 : -1; - FX_FLOAT point_y = middle_y + half_width * start_dir; - rect.UpdateRect(middle_x + half_width, point_y); - rect.UpdateRect(middle_x - half_width, point_y); + int start_dir = mid_pos.y > start_pos.y ? 1 : -1; + FX_FLOAT point_y = mid_pos.y + half_width * start_dir; + rect->UpdateRect(mid_pos.x + half_width, point_y); + rect->UpdateRect(mid_pos.x - half_width, point_y); return; } + if (!bStartVert) { - start_k = (middle_y - start_y) / (middle_x - start_x); - start_c = middle_y - (start_k * middle_x); - start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y); - start_dc = - (FX_FLOAT)FXSYS_fabs(half_width * start_len / (start_x - middle_x)); + CFX_PointF start_to_mid = start_pos - mid_pos; + start_k = (mid_pos.y - start_pos.y) / (mid_pos.x - start_pos.x); + start_c = mid_pos.y - (start_k * mid_pos.x); + start_len = FXSYS_sqrt2(start_to_mid.x, start_to_mid.y); + start_dc = static_cast<FX_FLOAT>( + FXSYS_fabs(half_width * start_len / start_to_mid.x)); } if (!bEndVert) { - end_k = (end_y - middle_y) / (end_x - middle_x); - end_c = middle_y - (end_k * middle_x); - end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y); - end_dc = (FX_FLOAT)FXSYS_fabs(half_width * end_len / (end_x - middle_x)); + CFX_PointF end_to_mid = end_pos - mid_pos; + end_k = end_to_mid.y / end_to_mid.x; + end_c = mid_pos.y - (end_k * mid_pos.x); + end_len = FXSYS_sqrt2(end_to_mid.x, end_to_mid.y); + end_dc = + static_cast<FX_FLOAT>(FXSYS_fabs(half_width * end_len / end_to_mid.x)); } if (bStartVert) { - FX_FLOAT outside_x = start_x; - if (end_x < start_x) { - outside_x += half_width; - } else { - outside_x -= half_width; - } - FX_FLOAT outside_y; - if (start_y < (end_k * start_x) + end_c) { - outside_y = (end_k * outside_x) + end_c + end_dc; - } else { - outside_y = (end_k * outside_x) + end_c - end_dc; - } - rect.UpdateRect(outside_x, outside_y); + CFX_PointF outside(start_pos.x, 0); + if (end_pos.x < start_pos.x) + outside.x += half_width; + else + outside.x -= half_width; + + if (start_pos.y < (end_k * start_pos.x) + end_c) + outside.y = (end_k * outside.x) + end_c + end_dc; + else + outside.y = (end_k * outside.x) + end_c - end_dc; + + rect->UpdateRect(outside.x, outside.y); return; } + if (bEndVert) { - FX_FLOAT outside_x = end_x; - if (start_x < end_x) { - outside_x += half_width; - } else { - outside_x -= half_width; - } - FX_FLOAT outside_y; - if (end_y < (start_k * end_x) + start_c) { - outside_y = (start_k * outside_x) + start_c + start_dc; - } else { - outside_y = (start_k * outside_x) + start_c - start_dc; - } - rect.UpdateRect(outside_x, outside_y); + CFX_PointF outside(end_pos.x, 0); + if (start_pos.x < end_pos.x) + outside.x += half_width; + else + outside.x -= half_width; + + if (end_pos.y < (start_k * end_pos.x) + start_c) + outside.y = (start_k * outside.x) + start_c + start_dc; + else + outside.y = (start_k * outside.x) + start_c - start_dc; + + rect->UpdateRect(outside.x, outside.y); return; } - if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) { - int start_dir = middle_x > start_x ? 1 : -1; - int end_dir = end_x > middle_x ? 1 : -1; - if (start_dir == end_dir) { - _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width); - } else { - _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, - half_width); - } + + if (FXSYS_fabs(start_k - end_k) < one_twentieth) { + int start_dir = mid_pos.x > start_pos.x ? 1 : -1; + int end_dir = end_pos.x > mid_pos.x ? 1 : -1; + if (start_dir == end_dir) + UpdateLineEndPoints(rect, mid_pos, end_pos, half_width); + else + UpdateLineEndPoints(rect, start_pos, mid_pos, half_width); return; } + FX_FLOAT start_outside_c = start_c; - if (end_y < (start_k * end_x) + start_c) { + if (end_pos.y < (start_k * end_pos.x) + start_c) start_outside_c += start_dc; - } else { + else start_outside_c -= start_dc; - } + FX_FLOAT end_outside_c = end_c; - if (start_y < (end_k * start_x) + end_c) { + if (start_pos.y < (end_k * start_pos.x) + end_c) end_outside_c += end_dc; - } else { + else end_outside_c -= end_dc; - } + FX_FLOAT join_x = (end_outside_c - start_outside_c) / (start_k - end_k); - FX_FLOAT join_y = (start_k * join_x) + start_outside_c; - rect.UpdateRect(join_x, join_y); + FX_FLOAT join_y = start_k * join_x + start_outside_c; + rect->UpdateRect(join_x, join_y); +} + +} // namespace + +FX_PATHPOINT::FX_PATHPOINT() = default; + +FX_PATHPOINT::FX_PATHPOINT(const CFX_PointF& point, FXPT_TYPE type, bool close) + : m_Point(point), m_Type(type), m_CloseFigure(close) {} + +FX_PATHPOINT::FX_PATHPOINT(const FX_PATHPOINT& other) = default; + +FX_PATHPOINT::~FX_PATHPOINT() = default; + +CFX_PathData::CFX_PathData() {} + +CFX_PathData::~CFX_PathData() {} + +CFX_PathData::CFX_PathData(const CFX_PathData& src) : m_Points(src.m_Points) {} + +void CFX_PathData::Clear() { + m_Points.clear(); +} + +void CFX_PathData::ClosePath() { + if (m_Points.empty()) + return; + m_Points.back().m_CloseFigure = true; +} + +void CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_Matrix* pMatrix) { + if (pSrc->m_Points.empty()) + return; + + size_t cur_size = m_Points.size(); + m_Points.insert(m_Points.end(), pSrc->m_Points.begin(), pSrc->m_Points.end()); + + if (!pMatrix) + return; + + for (size_t i = cur_size; i < m_Points.size(); i++) + m_Points[i].m_Point = pMatrix->Transform(m_Points[i].m_Point); +} + +void CFX_PathData::AppendPoint(const CFX_PointF& point, + FXPT_TYPE type, + bool closeFigure) { + m_Points.push_back(FX_PATHPOINT(point, type, closeFigure)); +} + +void CFX_PathData::AppendRect(FX_FLOAT left, + FX_FLOAT bottom, + FX_FLOAT right, + FX_FLOAT top) { + m_Points.push_back( + FX_PATHPOINT(CFX_PointF(left, bottom), FXPT_TYPE::MoveTo, false)); + m_Points.push_back( + FX_PATHPOINT(CFX_PointF(left, top), FXPT_TYPE::LineTo, false)); + m_Points.push_back( + FX_PATHPOINT(CFX_PointF(right, top), FXPT_TYPE::LineTo, false)); + m_Points.push_back( + FX_PATHPOINT(CFX_PointF(right, bottom), FXPT_TYPE::LineTo, false)); + m_Points.push_back( + FX_PATHPOINT(CFX_PointF(left, bottom), FXPT_TYPE::LineTo, true)); +} + +CFX_FloatRect CFX_PathData::GetBoundingBox() const { + if (m_Points.empty()) + return CFX_FloatRect(); + + CFX_FloatRect rect; + rect.InitRect(m_Points[0].m_Point.x, m_Points[0].m_Point.y); + for (size_t i = 1; i < m_Points.size(); i++) + rect.UpdateRect(m_Points[i].m_Point.x, m_Points[i].m_Point.y); + return rect; } CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const { - CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, - -100000 * 1.0f); - int iPoint = 0; + CFX_FloatRect rect(100000.0f, 100000.0f, -100000.0f, -100000.0f); + size_t iPoint = 0; FX_FLOAT half_width = line_width; int iStartPoint = 0; int iEndPoint = 0; int iMiddlePoint = 0; bool bJoin; - while (iPoint < m_PointCount) { - if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) { + while (iPoint < m_Points.size()) { + if (m_Points[iPoint].IsTypeAndOpen(FXPT_TYPE::MoveTo)) { iStartPoint = iPoint + 1; iEndPoint = iPoint; bJoin = false; } else { - if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) { - rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY); - rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, - m_pPoints[iPoint + 1].m_PointY); + if (m_Points[iPoint].IsTypeAndOpen(FXPT_TYPE::BezierTo)) { + rect.UpdateRect(m_Points[iPoint].m_Point.x, m_Points[iPoint].m_Point.y); + rect.UpdateRect(m_Points[iPoint + 1].m_Point.x, + m_Points[iPoint + 1].m_Point.y); iPoint += 2; } - if (iPoint == m_PointCount - 1 || - m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) { + if (iPoint == m_Points.size() - 1 || + m_Points[iPoint + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) { iStartPoint = iPoint - 1; iEndPoint = iPoint; bJoin = false; @@ -276,17 +263,15 @@ CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, bJoin = true; } } - FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX; - FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY; - FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX; - FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY; + + CFX_PointF start_pos = m_Points[iStartPoint].m_Point; + CFX_PointF end_pos = m_Points[iEndPoint].m_Point; if (bJoin) { - FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX; - FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY; - _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x, - end_y, half_width, miter_limit); + CFX_PointF mid_pos = m_Points[iMiddlePoint].m_Point; + UpdateLineJoinPoints(&rect, start_pos, mid_pos, end_pos, half_width, + miter_limit); } else { - _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width); + UpdateLineEndPoints(&rect, start_pos, end_pos, half_width); } iPoint++; } @@ -294,239 +279,207 @@ CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, } void CFX_PathData::Transform(const CFX_Matrix* pMatrix) { - if (!pMatrix) { + if (!pMatrix) return; - } - for (int i = 0; i < m_PointCount; i++) { - pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY); - } + for (auto& point : m_Points) + point.m_Point = pMatrix->Transform(point.m_Point); } -bool CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, - CFX_Matrix* pMatrix, - bool& bThin, - bool bAdjust) const { - if (m_PointCount < 3) { +bool CFX_PathData::GetZeroAreaPath(const CFX_Matrix* pMatrix, + bool bAdjust, + CFX_PathData* NewPath, + bool* bThin, + bool* setIdentity) const { + *setIdentity = false; + if (m_Points.size() < 3) return false; - } - if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO && - (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && - (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO && - m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && - m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) { - NewPath.AddPointCount(2); - if (bAdjust) { - if (pMatrix) { - FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY; - pMatrix->TransformPoint(x, y); - x = (int)x + 0.5f; - y = (int)y + 0.5f; - NewPath.SetPoint(0, x, y, FXPT_MOVETO); - x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY; - pMatrix->TransformPoint(x, y); - x = (int)x + 0.5f; - y = (int)y + 0.5f; - NewPath.SetPoint(1, x, y, FXPT_LINETO); - pMatrix->SetIdentity(); - } else { - FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, - y = (int)m_pPoints[0].m_PointY + 0.5f; - NewPath.SetPoint(0, x, y, FXPT_MOVETO); - x = (int)m_pPoints[1].m_PointX + 0.5f, - y = (int)m_pPoints[1].m_PointY + 0.5f; - NewPath.SetPoint(1, x, y, FXPT_LINETO); + + if (m_Points.size() == 3 && m_Points[0].m_Type == FXPT_TYPE::MoveTo && + m_Points[1].m_Type == FXPT_TYPE::LineTo && + m_Points[2].m_Type == FXPT_TYPE::LineTo && + m_Points[0].m_Point == m_Points[2].m_Point) { + for (size_t i = 0; i < 2; i++) { + CFX_PointF point = m_Points[i].m_Point; + if (bAdjust) { + if (pMatrix) + point = pMatrix->Transform(point); + + point = CFX_PointF(static_cast<int>(point.x) + 0.5f, + static_cast<int>(point.y) + 0.5f); } - } else { - NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, - FXPT_MOVETO); - NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, - FXPT_LINETO); + NewPath->AppendPoint( + point, i == 0 ? FXPT_TYPE::MoveTo : FXPT_TYPE::LineTo, false); } - if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && - m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) { - bThin = true; + if (bAdjust && pMatrix) + *setIdentity = true; + + // Note, they both have to be not equal. + if (m_Points[0].m_Point.x != m_Points[1].m_Point.x && + m_Points[0].m_Point.y != m_Points[1].m_Point.y) { + *bThin = true; } return true; } - if (((m_PointCount > 3) && (m_PointCount % 2))) { - int mid = m_PointCount / 2; + + if (((m_Points.size() > 3) && (m_Points.size() % 2))) { + int mid = m_Points.size() / 2; bool bZeroArea = false; CFX_PathData t_path; for (int i = 0; i < mid; i++) { - if (!(m_pPoints[mid - i - 1].m_PointX == - m_pPoints[mid + i + 1].m_PointX && - m_pPoints[mid - i - 1].m_PointY == - m_pPoints[mid + i + 1].m_PointY && - ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && - (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) { + if (!(m_Points[mid - i - 1].m_Point == m_Points[mid + i + 1].m_Point && + m_Points[mid - i - 1].m_Type != FXPT_TYPE::BezierTo && + m_Points[mid + i + 1].m_Type != FXPT_TYPE::BezierTo)) { bZeroArea = true; break; } - int new_count = t_path.GetPointCount(); - t_path.AddPointCount(2); - t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, - m_pPoints[mid - i].m_PointY, FXPT_MOVETO); - t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, - m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO); + + t_path.AppendPoint(m_Points[mid - i].m_Point, FXPT_TYPE::MoveTo, false); + t_path.AppendPoint(m_Points[mid - i - 1].m_Point, FXPT_TYPE::LineTo, + false); } if (!bZeroArea) { - NewPath.Append(&t_path, nullptr); - bThin = true; + NewPath->Append(&t_path, nullptr); + *bThin = true; return true; } } + int stratPoint = 0; - int next = 0, i; - for (i = 0; i < m_PointCount; i++) { - int point_type = m_pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { + int next = 0; + for (size_t i = 0; i < m_Points.size(); i++) { + FXPT_TYPE point_type = m_Points[i].m_Type; + if (point_type == FXPT_TYPE::MoveTo) { stratPoint = i; - } else if (point_type == FXPT_LINETO) { - next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint; - if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && - (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) { - if ((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && - m_pPoints[i].m_PointX == m_pPoints[next].m_PointX) && - ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * - (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > + } else if (point_type == FXPT_TYPE::LineTo) { + next = (i + 1 - stratPoint) % (m_Points.size() - stratPoint) + stratPoint; + if (m_Points[next].m_Type != FXPT_TYPE::BezierTo && + m_Points[next].m_Type != FXPT_TYPE::MoveTo) { + if ((m_Points[i - 1].m_Point.x == m_Points[i].m_Point.x && + m_Points[i].m_Point.x == m_Points[next].m_Point.x) && + ((m_Points[i].m_Point.y - m_Points[i - 1].m_Point.y) * + (m_Points[i].m_Point.y - m_Points[next].m_Point.y) > 0)) { int pre = i; - if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) < - FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) { + if (FXSYS_fabs(m_Points[i].m_Point.y - m_Points[i - 1].m_Point.y) < + FXSYS_fabs(m_Points[i].m_Point.y - m_Points[next].m_Point.y)) { pre--; next--; } - int new_count = NewPath.GetPointCount(); - NewPath.AddPointCount(2); - NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, - m_pPoints[pre].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, - m_pPoints[next].m_PointY, FXPT_LINETO); - } else if ((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && - m_pPoints[i].m_PointY == m_pPoints[next].m_PointY) && - ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) * - (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > + + NewPath->AppendPoint(m_Points[pre].m_Point, FXPT_TYPE::MoveTo, false); + NewPath->AppendPoint(m_Points[next].m_Point, FXPT_TYPE::LineTo, + false); + } else if ((m_Points[i - 1].m_Point.y == m_Points[i].m_Point.y && + m_Points[i].m_Point.y == m_Points[next].m_Point.y) && + ((m_Points[i].m_Point.x - m_Points[i - 1].m_Point.x) * + (m_Points[i].m_Point.x - m_Points[next].m_Point.x) > 0)) { int pre = i; - if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) < - FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) { + if (FXSYS_fabs(m_Points[i].m_Point.x - m_Points[i - 1].m_Point.x) < + FXSYS_fabs(m_Points[i].m_Point.x - m_Points[next].m_Point.x)) { pre--; next--; } - int new_count = NewPath.GetPointCount(); - NewPath.AddPointCount(2); - NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, - m_pPoints[pre].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, - m_pPoints[next].m_PointY, FXPT_LINETO); - } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && - (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO && - m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && - m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY && - m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) { - int new_count = NewPath.GetPointCount(); - NewPath.AddPointCount(2); - NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, - m_pPoints[i - 1].m_PointY, FXPT_MOVETO); - NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, - m_pPoints[i].m_PointY, FXPT_LINETO); - bThin = true; + + NewPath->AppendPoint(m_Points[pre].m_Point, FXPT_TYPE::MoveTo, false); + NewPath->AppendPoint(m_Points[next].m_Point, FXPT_TYPE::LineTo, + false); + } else if (m_Points[i - 1].m_Type == FXPT_TYPE::MoveTo && + m_Points[next].m_Type == FXPT_TYPE::LineTo && + m_Points[i - 1].m_Point == m_Points[next].m_Point && + m_Points[next].m_CloseFigure) { + NewPath->AppendPoint(m_Points[i - 1].m_Point, FXPT_TYPE::MoveTo, + false); + NewPath->AppendPoint(m_Points[i].m_Point, FXPT_TYPE::LineTo, false); + *bThin = true; } } - } else if (point_type == FXPT_BEZIERTO) { + } else if (point_type == FXPT_TYPE::BezierTo) { i += 2; continue; } } - if (m_PointCount > 3 && NewPath.GetPointCount()) { - bThin = true; - } - if (NewPath.GetPointCount() == 0) { - return false; - } - return true; + + size_t new_path_size = NewPath->GetPoints().size(); + if (m_Points.size() > 3 && new_path_size > 0) + *bThin = true; + return new_path_size != 0; } bool CFX_PathData::IsRect() const { - if (m_PointCount != 5 && m_PointCount != 4) { + if (m_Points.size() != 5 && m_Points.size() != 4) return false; - } - if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || - m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || - (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && - m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) || - (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && - m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) { + + if ((m_Points.size() == 5 && m_Points[0].m_Point != m_Points[4].m_Point) || + m_Points[0].m_Point == m_Points[2].m_Point || + m_Points[1].m_Point == m_Points[3].m_Point) { return false; } - if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && - m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { + // Note, both x,y have to not equal. + if (m_Points[0].m_Point.x != m_Points[3].m_Point.x && + m_Points[0].m_Point.y != m_Points[3].m_Point.y) { return false; } + for (int i = 1; i < 4; i++) { - if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { + if (m_Points[i].m_Type != FXPT_TYPE::LineTo) return false; - } - if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && - m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) { + // Note, both x,y have to not equal. + if (m_Points[i].m_Point.x != m_Points[i - 1].m_Point.x && + m_Points[i].m_Point.y != m_Points[i - 1].m_Point.y) { return false; } } - return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE); + return m_Points.size() == 5 || m_Points[3].m_CloseFigure; } bool CFX_PathData::IsRect(const CFX_Matrix* pMatrix, CFX_FloatRect* pRect) const { if (!pMatrix) { - if (!IsRect()) { + if (!IsRect()) return false; - } + if (pRect) { - pRect->left = m_pPoints[0].m_PointX; - pRect->right = m_pPoints[2].m_PointX; - pRect->bottom = m_pPoints[0].m_PointY; - pRect->top = m_pPoints[2].m_PointY; + pRect->left = m_Points[0].m_Point.x; + pRect->right = m_Points[2].m_Point.x; + pRect->bottom = m_Points[0].m_Point.y; + pRect->top = m_Points[2].m_Point.y; pRect->Normalize(); } return true; } - if (m_PointCount != 5 && m_PointCount != 4) { + + if (m_Points.size() != 5 && m_Points.size() != 4) return false; - } - if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || - m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) || - (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && - m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) { + + if ((m_Points.size() == 5 && m_Points[0].m_Point != m_Points[4].m_Point) || + m_Points[1].m_Point == m_Points[3].m_Point) { return false; } - if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && - m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) { + // Note, both x,y not equal. + if (m_Points.size() == 4 && m_Points[0].m_Point.x != m_Points[3].m_Point.x && + m_Points[0].m_Point.y != m_Points[3].m_Point.y) { return false; } - FX_FLOAT x[5], y[5]; - for (int i = 0; i < m_PointCount; i++) { - pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], - y[i]); - if (i) { - if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) { - return false; - } - if (x[i] != x[i - 1] && y[i] != y[i - 1]) { - return false; - } - } + + CFX_PointF points[5]; + for (size_t i = 0; i < m_Points.size(); i++) { + points[i] = pMatrix->Transform(m_Points[i].m_Point); + + if (i == 0) + continue; + if (m_Points[i].m_Type != FXPT_TYPE::LineTo) + return false; + if (points[i].x != points[i - 1].x && points[i].y != points[i - 1].y) + return false; } + if (pRect) { - pRect->left = x[0]; - pRect->right = x[2]; - pRect->bottom = y[0]; - pRect->top = y[2]; + pRect->left = points[0].x; + pRect->right = points[2].x; + pRect->bottom = points[0].y; + pRect->top = points[2].y; pRect->Normalize(); } return true; } - -void CFX_PathData::Copy(const CFX_PathData& src) { - SetPointCount(src.m_PointCount); - FXSYS_memcpy(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount); -} diff --git a/core/fxge/ge/cfx_renderdevice.cpp b/core/fxge/ge/cfx_renderdevice.cpp index 9c67a7d1e..daa67ccc9 100644 --- a/core/fxge/ge/cfx_renderdevice.cpp +++ b/core/fxge/ge/cfx_renderdevice.cpp @@ -27,19 +27,19 @@ namespace { void AdjustGlyphSpace(std::vector<FXTEXT_GLYPHPOS>* pGlyphAndPos) { ASSERT(pGlyphAndPos->size() > 1); std::vector<FXTEXT_GLYPHPOS>& glyphs = *pGlyphAndPos; - bool bVertical = glyphs.back().m_OriginX == glyphs.front().m_OriginX; - if (!bVertical && (glyphs.back().m_OriginY != glyphs.front().m_OriginY)) + bool bVertical = glyphs.back().m_Origin.x == glyphs.front().m_Origin.x; + if (!bVertical && (glyphs.back().m_Origin.y != glyphs.front().m_Origin.y)) return; for (size_t i = glyphs.size() - 1; i > 1; --i) { FXTEXT_GLYPHPOS& next = glyphs[i]; - int next_origin = bVertical ? next.m_OriginY : next.m_OriginX; - FX_FLOAT next_origin_f = bVertical ? next.m_fOriginY : next.m_fOriginX; + int next_origin = bVertical ? next.m_Origin.y : next.m_Origin.x; + FX_FLOAT next_origin_f = bVertical ? next.m_fOrigin.y : next.m_fOrigin.x; FXTEXT_GLYPHPOS& current = glyphs[i - 1]; - int& current_origin = bVertical ? current.m_OriginY : current.m_OriginX; + int& current_origin = bVertical ? current.m_Origin.y : current.m_Origin.x; FX_FLOAT current_origin_f = - bVertical ? current.m_fOriginY : current.m_fOriginX; + bVertical ? current.m_fOrigin.y : current.m_fOrigin.x; int space = next_origin - current_origin; FX_FLOAT space_f = next_origin_f - current_origin_f; @@ -346,6 +346,21 @@ bool ShouldDrawDeviceText(const CFX_Font* pFont, uint32_t text_flags) { } // namespace +FXTEXT_CHARPOS::FXTEXT_CHARPOS() + : m_GlyphIndex(0), + m_FontCharWidth(0), +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + m_ExtGID(0), +#endif + m_FallbackFontPosition(0), + m_bGlyphAdjust(false), + m_bFontStyle(false) { +} + +FXTEXT_CHARPOS::FXTEXT_CHARPOS(const FXTEXT_CHARPOS&) = default; + +FXTEXT_CHARPOS::~FXTEXT_CHARPOS(){}; + CFX_RenderDevice::CFX_RenderDevice() : m_pBitmap(nullptr), m_Width(0), @@ -473,25 +488,20 @@ bool CFX_RenderDevice::DrawPathWithBlend(const CFX_PathData* pPathData, int blend_type) { uint8_t stroke_alpha = pGraphState ? FXARGB_A(stroke_color) : 0; uint8_t fill_alpha = (fill_mode & 3) ? FXARGB_A(fill_color) : 0; - if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) { - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - FX_FLOAT x1, x2, y1, y2; + const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints(); + if (stroke_alpha == 0 && pPoints.size() == 2) { + CFX_PointF pos1 = pPoints[0].m_Point; + CFX_PointF pos2 = pPoints[1].m_Point; if (pObject2Device) { - pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1, - y1); - pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2, - y2); - } else { - x1 = pPoints[0].m_PointX; - y1 = pPoints[0].m_PointY; - x2 = pPoints[1].m_PointX; - y2 = pPoints[1].m_PointY; + pos1 = pObject2Device->Transform(pos1); + pos2 = pObject2Device->Transform(pos2); } - DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, blend_type); + DrawCosmeticLine(pos1.x, pos1.y, pos2.x, pos2.y, fill_color, fill_mode, + blend_type); return true; } - if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && - stroke_alpha == 0) { + + if ((pPoints.size() == 5 || pPoints.size() == 4) && stroke_alpha == 0) { CFX_FloatRect rect_f; if (!(fill_mode & FXFILL_RECT_AA) && pPathData->IsRect(pObject2Device, &rect_f)) { @@ -539,19 +549,25 @@ bool CFX_RenderDevice::DrawPathWithBlend(const CFX_PathData* pPathData, !(fill_mode & FX_FILL_TEXT_MODE)) { CFX_PathData newPath; bool bThin = false; - if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin, - !!m_pDeviceDriver->GetDriverType())) { + bool setIdentity = false; + if (pPathData->GetZeroAreaPath(pObject2Device, + !!m_pDeviceDriver->GetDriverType(), &newPath, + &bThin, &setIdentity)) { CFX_GraphStateData graphState; graphState.m_LineWidth = 0.0f; + uint32_t strokecolor = fill_color; if (bThin) strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff)); - CFX_Matrix* pMatrix = nullptr; - if (pObject2Device && !pObject2Device->IsIdentity()) - pMatrix = (CFX_Matrix*)pObject2Device; + + const CFX_Matrix* pMatrix = nullptr; + if (pObject2Device && !pObject2Device->IsIdentity() && !setIdentity) + pMatrix = pObject2Device; + int smooth_path = FX_ZEROAREA_FILL; if (fill_mode & FXFILL_NOPATHSMOOTH) smooth_path |= FXFILL_NOPATHSMOOTH; + m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor, smooth_path, blend_type); } @@ -589,7 +605,8 @@ bool CFX_RenderDevice::DrawFillStrokePath(const CFX_PathData* pPathData, bbox = pPathData->GetBoundingBox(); } if (pObject2Device) - bbox.Transform(pObject2Device); + pObject2Device->TransformRect(bbox); + CFX_Matrix ctm = GetCTM(); FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); @@ -612,8 +629,8 @@ bool CFX_RenderDevice::DrawFillStrokePath(const CFX_PathData* pPathData, CFX_Matrix matrix; if (pObject2Device) matrix = *pObject2Device; - matrix.TranslateI(-rect.left, -rect.top); - matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); + matrix.Translate(-rect.left, -rect.top); + matrix.Concat(CFX_Matrix(fScaleX, 0, 0, fScaleY, 0, 0)); if (!bitmap_device.GetDeviceDriver()->DrawPath( pPathData, &matrix, pGraphState, fill_color, stroke_color, fill_mode, blend_type)) { @@ -675,9 +692,8 @@ bool CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, } CFX_GraphStateData graph_state; CFX_PathData path; - path.SetPointCount(2); - path.SetPoint(0, x1, y1, FXPT_MOVETO); - path.SetPoint(1, x2, y2, FXPT_LINETO); + path.AppendPoint(CFX_PointF(x1, y1), FXPT_TYPE::MoveTo, false); + path.AppendPoint(CFX_PointF(x2, y2), FXPT_TYPE::LineTo, false); return m_pDeviceDriver->DrawPath(&path, nullptr, &graph_state, 0, color, fill_mode, blend_type); } @@ -860,6 +876,7 @@ bool CFX_RenderDevice::DrawNormalText(int nChars, char2device = *pText2Device; text2Device = *pText2Device; } + char2device.Scale(font_size, -font_size); if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f || ((m_DeviceClass == FXDC_PRINTER) && @@ -902,19 +919,21 @@ bool CFX_RenderDevice::DrawNormalText(int nChars, FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a); FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d); CFX_Matrix deviceCtm = char2device; - deviceCtm.Concat(scale_x, 0, 0, scale_y, 0, 0); - text2Device.Concat(scale_x, 0, 0, scale_y, 0, 0); + CFX_Matrix m(scale_x, 0, 0, scale_y, 0, 0); + deviceCtm.Concat(m); + text2Device.Concat(m); + for (size_t i = 0; i < glyphs.size(); ++i) { FXTEXT_GLYPHPOS& glyph = glyphs[i]; const FXTEXT_CHARPOS& charpos = pCharPos[i]; - glyph.m_fOriginX = charpos.m_OriginX; - glyph.m_fOriginY = charpos.m_OriginY; - text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY); + + glyph.m_fOrigin = text2Device.Transform(charpos.m_Origin); if (anti_alias < FXFT_RENDER_MODE_LCD) - glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX); + glyph.m_Origin.x = FXSYS_round(glyph.m_fOrigin.x); else - glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX); - glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY); + glyph.m_Origin.x = static_cast<int>(FXSYS_floor(glyph.m_fOrigin.x)); + glyph.m_Origin.y = FXSYS_round(glyph.m_fOrigin.y); + if (charpos.m_bGlyphAdjust) { CFX_Matrix new_matrix( charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], @@ -960,8 +979,8 @@ bool CFX_RenderDevice::DrawNormalText(int nChars, continue; const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap; bitmap.TransferBitmap( - glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left, - glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top, + glyph.m_Origin.x + glyph.m_pGlyph->m_Left - pixel_left, + glyph.m_Origin.y - glyph.m_pGlyph->m_Top - pixel_top, pGlyph->GetWidth(), pGlyph->GetHeight(), pGlyph, 0, 0); } return SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color); @@ -995,13 +1014,13 @@ bool CFX_RenderDevice::DrawNormalText(int nChars, if (!glyph.m_pGlyph) continue; - pdfium::base::CheckedNumeric<int> left = glyph.m_OriginX; + pdfium::base::CheckedNumeric<int> left = glyph.m_Origin.x; left += glyph.m_pGlyph->m_Left; left -= pixel_left; if (!left.IsValid()) return false; - pdfium::base::CheckedNumeric<int> top = glyph.m_OriginY; + pdfium::base::CheckedNumeric<int> top = glyph.m_Origin.y; top -= glyph.m_pGlyph->m_Top; top -= pixel_top; if (!top.IsValid()) @@ -1021,14 +1040,16 @@ bool CFX_RenderDevice::DrawNormalText(int nChars, } bool bBGRStripe = !!(text_flags & FXTEXT_BGR_STRIPE); ncols /= 3; - int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3; - int start_col = std::max(left.ValueOrDie(), 0); + int x_subpixel = static_cast<int>(glyph.m_fOrigin.x * 3) % 3; + int start_col = + pdfium::base::ValueOrDieForType<int>(pdfium::base::CheckMax(left, 0)); pdfium::base::CheckedNumeric<int> end_col_safe = left; end_col_safe += ncols; if (!end_col_safe.IsValid()) return false; - int end_col = std::min(end_col_safe.ValueOrDie(), dest_width); + int end_col = + std::min(static_cast<int>(end_col_safe.ValueOrDie<int>()), dest_width); if (start_col >= end_col) continue; @@ -1058,16 +1079,19 @@ bool CFX_RenderDevice::DrawTextPath(int nChars, const FXTEXT_CHARPOS& charpos = pCharPos[iChar]; CFX_Matrix matrix; if (charpos.m_bGlyphAdjust) { - matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); + matrix = CFX_Matrix(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], + 0, 0); } - matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, - charpos.m_OriginY); + matrix.Concat(CFX_Matrix(font_size, 0, 0, font_size, charpos.m_Origin.x, + charpos.m_Origin.y)); const CFX_PathData* pPath = pFont->LoadGlyphPath(charpos.m_GlyphIndex, charpos.m_FontCharWidth); if (!pPath) continue; + matrix.Concat(*pText2User); + CFX_PathData TransformedPath(*pPath); TransformedPath.Transform(&matrix); if (fill_color || stroke_color) { diff --git a/core/fxge/ge/fx_ge_text.cpp b/core/fxge/ge/fx_ge_text.cpp index ca88879d1..669969db0 100644 --- a/core/fxge/ge/fx_ge_text.cpp +++ b/core/fxge/ge/fx_ge_text.cpp @@ -28,6 +28,12 @@ void ResetTransform(FT_Face face) { } // namespace +FXTEXT_GLYPHPOS::FXTEXT_GLYPHPOS() : m_pGlyph(nullptr) {} + +FXTEXT_GLYPHPOS::FXTEXT_GLYPHPOS(const FXTEXT_GLYPHPOS&) = default; + +FXTEXT_GLYPHPOS::~FXTEXT_GLYPHPOS(){}; + ScopedFontTransform::ScopedFontTransform(FT_Face face, FXFT_Matrix* matrix) : m_Face(face) { FXFT_Set_Transform(m_Face, matrix, 0); @@ -48,7 +54,7 @@ FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, if (!pGlyph) continue; - FX_SAFE_INT32 char_left = glyph.m_OriginX; + FX_SAFE_INT32 char_left = glyph.m_Origin.x; char_left += pGlyph->m_Left; if (!char_left.IsValid()) continue; @@ -64,7 +70,7 @@ FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, if (!char_right.IsValid()) continue; - FX_SAFE_INT32 char_top = glyph.m_OriginY; + FX_SAFE_INT32 char_top = glyph.m_Origin.y; char_top -= pGlyph->m_Top; if (!char_top.IsValid()) continue; @@ -79,10 +85,14 @@ FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs, continue; if (bStarted) { - rect.left = std::min(rect.left, char_left.ValueOrDie()); - rect.right = std::max(rect.right, char_right.ValueOrDie()); - rect.top = std::min(rect.top, char_top.ValueOrDie()); - rect.bottom = std::max(rect.bottom, char_bottom.ValueOrDie()); + rect.left = pdfium::base::ValueOrDieForType<int32_t>( + pdfium::base::CheckMin(rect.left, char_left)); + rect.right = pdfium::base::ValueOrDieForType<int32_t>( + pdfium::base::CheckMax(rect.right, char_right)); + rect.top = pdfium::base::ValueOrDieForType<int32_t>( + pdfium::base::CheckMin(rect.top, char_top)); + rect.bottom = pdfium::base::ValueOrDieForType<int32_t>( + pdfium::base::CheckMax(rect.bottom, char_bottom)); continue; } diff --git a/core/fxge/ifx_renderdevicedriver.h b/core/fxge/ifx_renderdevicedriver.h index 6a5b63ba3..fd35149e4 100644 --- a/core/fxge/ifx_renderdevicedriver.h +++ b/core/fxge/ifx_renderdevicedriver.h @@ -16,8 +16,8 @@ class CFX_GraphStateData; class CFX_Matrix; class CFX_PathData; class CPDF_ShadingPattern; +class FXTEXT_CHARPOS; class IFX_Pause; -struct FXTEXT_CHARPOS; struct FX_RECT; class IFX_RenderDeviceDriver { diff --git a/core/fxge/skia/fx_skia_device.cpp b/core/fxge/skia/fx_skia_device.cpp index 2a004836a..7e23f9728 100644 --- a/core/fxge/skia/fx_skia_device.cpp +++ b/core/fxge/skia/fx_skia_device.cpp @@ -45,10 +45,6 @@ #include "third_party/skia/include/core/SkPictureRecorder.h" #endif // _SKIA_SUPPORT_ -#ifdef SK_DEBUG -#include "third_party/skia/include/core/SkClipStack.h" -#endif // SK_DEBUG - namespace { #ifdef _SKIA_SUPPORT_PATHS_ @@ -195,8 +191,6 @@ void DebugShowCanvasClip(const SkCanvas* canvas) { canvas->getClipDeviceBounds(&device); printf("device bounds %d %d %d %d\n", device.fLeft, device.fTop, device.fRight, device.fBottom); - const SkClipStack* clipStack = canvas->getClipStack(); - clipStack->dump(); #endif // SHOW_SKIA_PATH } @@ -284,23 +278,21 @@ static void DebugValidate(const CFX_DIBitmap* bitmap, SkPath BuildPath(const CFX_PathData* pPathData) { SkPath skPath; const CFX_PathData* pFPath = pPathData; - int nPoints = pFPath->GetPointCount(); - FX_PATHPOINT* pPoints = pFPath->GetPoints(); - for (int i = 0; i < nPoints; i++) { - FX_FLOAT x = pPoints[i].m_PointX; - FX_FLOAT y = pPoints[i].m_PointY; - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { - skPath.moveTo(x, y); - } else if (point_type == FXPT_LINETO) { - skPath.lineTo(x, y); - } else if (point_type == FXPT_BEZIERTO) { - FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY; - FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY; - skPath.cubicTo(x, y, x2, y2, x3, y3); + const std::vector<FX_PATHPOINT>& pPoints = pFPath->GetPoints(); + for (size_t i = 0; i < pPoints.size(); i++) { + CFX_PointF point = pPoints[i].m_Point; + FXPT_TYPE point_type = pPoints[i].m_Type; + if (point_type == FXPT_TYPE::MoveTo) { + skPath.moveTo(point.x, point.y); + } else if (point_type == FXPT_TYPE::LineTo) { + skPath.lineTo(point.x, point.y); + } else if (point_type == FXPT_TYPE::BezierTo) { + CFX_PointF point2 = pPoints[i + 1].m_Point; + CFX_PointF point3 = pPoints[i + 2].m_Point; + skPath.cubicTo(point.x, point.y, point2.x, point2.y, point3.x, point3.y); i += 2; } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) + if (pPoints[i].m_CloseFigure) skPath.close(); } return skPath; @@ -312,7 +304,7 @@ SkMatrix ToSkMatrix(const CFX_Matrix& m) { return skMatrix; } -// use when pdf's y-axis points up insead of down +// use when pdf's y-axis points up instead of down SkMatrix ToFlippedSkMatrix(const CFX_Matrix& m, SkScalar flip) { SkMatrix skMatrix; skMatrix.setAll(m.a * flip, -m.c * flip, m.e, m.b * flip, -m.d * flip, m.f, 0, @@ -809,8 +801,9 @@ class SkiaState { vFlip *= -1; for (int index = 0; index < nChars; ++index) { const FXTEXT_CHARPOS& cp = pCharPos[index]; - m_positions[index + count] = {cp.m_OriginX * flip, cp.m_OriginY * vFlip}; - m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex; + m_positions[index + count] = {cp.m_Origin.x * flip, + cp.m_Origin.y * vFlip}; + m_glyphs[index + count] = static_cast<uint16_t>(cp.m_GlyphIndex); } SkPoint delta; if (MatrixOffset(pMatrix, &delta)) { @@ -1086,7 +1079,6 @@ class SkiaState { #if SHOW_SKIA_PATH printf("\n%s\nSkia Save Count %d:\n", where, m_pDriver->m_pCanvas->getSaveCount()); - m_pDriver->m_pCanvas->getClipStack()->dump(); printf("Cache:\n"); for (int index = 0; index < m_commands.count(); ++index) { DumpPrefix(index); @@ -1297,8 +1289,8 @@ bool CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, glyphs.setCount(nChars); for (int index = 0; index < nChars; ++index) { const FXTEXT_CHARPOS& cp = pCharPos[index]; - positions[index] = {cp.m_OriginX * flip, cp.m_OriginY * vFlip}; - glyphs[index] = (uint16_t)cp.m_GlyphIndex; + positions[index] = {cp.m_Origin.x * flip, cp.m_Origin.y * vFlip}; + glyphs[index] = static_cast<uint16_t>(cp.m_GlyphIndex); } #ifdef _SKIA_SUPPORT_PATHS_ m_pBitmap->PreMultiply(); @@ -1439,7 +1431,8 @@ bool CFX_SkiaDeviceDriver::SetClip_PathFill( GetDeviceCaps(FXDC_PIXEL_WIDTH), GetDeviceCaps(FXDC_PIXEL_HEIGHT)); } #endif // _SKIA_SUPPORT_PATHS_ - if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { + if (pPathData->GetPoints().size() == 5 || + pPathData->GetPoints().size() == 4) { CFX_FloatRect rectf; if (pPathData->IsRect(deviceMatrix, &rectf)) { rectf.Intersect( @@ -1749,7 +1742,7 @@ bool CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern, m_pCanvas->clipPath(skClip, SkClipOp::kIntersect, true); m_pCanvas->concat(skMatrix); while (!stream.BitStream()->IsEOF()) { - uint32_t flag = stream.GetFlag(); + uint32_t flag = stream.ReadFlag(); int iStartPoint = flag ? 4 : 0; int iStartColor = flag ? 2 : 0; if (flag) { @@ -1762,11 +1755,16 @@ bool CFX_SkiaDeviceDriver::DrawShading(const CPDF_ShadingPattern* pPattern, tempColors[1] = colors[(flag + 1) % 4]; FXSYS_memcpy(colors, tempColors, sizeof(tempColors)); } - for (int i = iStartPoint; i < (int)SK_ARRAY_COUNT(cubics); i++) - stream.GetCoords(cubics[i].fX, cubics[i].fY); + for (int i = iStartPoint; i < (int)SK_ARRAY_COUNT(cubics); i++) { + CFX_PointF point = stream.ReadCoords(); + cubics[i].fX = point.x; + cubics[i].fY = point.y; + } for (int i = iStartColor; i < (int)SK_ARRAY_COUNT(colors); i++) { - FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; - stream.GetColor(r, g, b); + FX_FLOAT r; + FX_FLOAT g; + FX_FLOAT b; + std::tie(r, g, b) = stream.ReadColor(); colors[i] = SkColorSetARGBInline(0xFF, (U8CPU)(r * 255), (U8CPU)(g * 255), (U8CPU)(b * 255)); } diff --git a/core/fxge/skia/fx_skia_device.h b/core/fxge/skia/fx_skia_device.h index ff81daef4..ecb110451 100644 --- a/core/fxge/skia/fx_skia_device.h +++ b/core/fxge/skia/fx_skia_device.h @@ -13,13 +13,13 @@ #include "core/fxge/cfx_pathdata.h" #include "core/fxge/ifx_renderdevicedriver.h" +class FXTEXT_CHARPOS; class SkCanvas; class SkMatrix; class SkPaint; class SkPath; class SkPictureRecorder; class SkiaState; -struct FXTEXT_CHARPOS; struct SkIRect; class CFX_SkiaDeviceDriver : public IFX_RenderDeviceDriver { diff --git a/core/fxge/skia/fx_skia_device_unittest.cpp b/core/fxge/skia/fx_skia_device_unittest.cpp index c77c8f88e..afd47780d 100644 --- a/core/fxge/skia/fx_skia_device_unittest.cpp +++ b/core/fxge/skia/fx_skia_device_unittest.cpp @@ -35,7 +35,11 @@ void EmptyTest(CFX_SkiaDeviceDriver* driver, const State&) { } void CommonTest(CFX_SkiaDeviceDriver* driver, const State& state) { - FXTEXT_CHARPOS charPos[] = {{{0, 0, 0, 0}, 0, 1, 1, 4, false, false}}; + FXTEXT_CHARPOS charPos[1]; + charPos[0].m_Origin = CFX_PointF(0, 1); + charPos[0].m_GlyphIndex = 1; + charPos[0].m_FontCharWidth = 4; + CFX_Font font; FX_FLOAT fontSize = 1; CFX_PathData clipPath, clipPath2; @@ -46,7 +50,9 @@ void CommonTest(CFX_SkiaDeviceDriver* driver, const State& state) { driver->SaveState(); CFX_PathData path1; path1.AppendRect(0, 0, 1, 2); - CFX_Matrix matrix, matrix2; + + CFX_Matrix matrix; + CFX_Matrix matrix2; matrix2.Translate(1, 0); CFX_GraphStateData graphState; if (state.m_save == State::Save::kYes) diff --git a/core/fxge/win32/cfx_psrenderer.cpp b/core/fxge/win32/cfx_psrenderer.cpp index b62d0cb8f..74fae088d 100644 --- a/core/fxge/win32/cfx_psrenderer.cpp +++ b/core/fxge/win32/cfx_psrenderer.cpp @@ -109,37 +109,37 @@ void CFX_PSRenderer::RestoreState(bool bKeepSaved) { void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData, const CFX_Matrix* pObject2Device) { - int nPoints = pPathData->GetPointCount(); CFX_ByteTextBuf buf; - buf.EstimateSize(nPoints * 10); - for (int i = 0; i < nPoints; i++) { - uint8_t flag = pPathData->GetFlag(i); - FX_FLOAT x = pPathData->GetPointX(i); - FX_FLOAT y = pPathData->GetPointY(i); - if (pObject2Device) { - pObject2Device->Transform(x, y); - } - buf << x << " " << y; - switch (flag & FXPT_TYPE) { - case FXPT_MOVETO: + size_t size = pPathData->GetPoints().size(); + buf.EstimateSize(size * 10); + + for (size_t i = 0; i < size; i++) { + FXPT_TYPE type = pPathData->GetType(i); + bool closing = pPathData->IsClosingFigure(i); + CFX_PointF pos = pPathData->GetPoint(i); + if (pObject2Device) + pos = pObject2Device->Transform(pos); + + buf << pos.x << " " << pos.y; + switch (type) { + case FXPT_TYPE::MoveTo: buf << " m "; break; - case FXPT_LINETO: + case FXPT_TYPE::LineTo: buf << " l "; - if (flag & FXPT_CLOSEFIGURE) + if (closing) buf << "h "; break; - case FXPT_BEZIERTO: { - FX_FLOAT x1 = pPathData->GetPointX(i + 1); - FX_FLOAT x2 = pPathData->GetPointX(i + 2); - FX_FLOAT y1 = pPathData->GetPointY(i + 1); - FX_FLOAT y2 = pPathData->GetPointY(i + 2); + case FXPT_TYPE::BezierTo: { + CFX_PointF pos1 = pPathData->GetPoint(i + 1); + CFX_PointF pos2 = pPathData->GetPoint(i + 2); if (pObject2Device) { - pObject2Device->Transform(x1, y1); - pObject2Device->Transform(x2, y2); + pos1 = pObject2Device->Transform(pos1); + pos2 = pObject2Device->Transform(pos2); } - buf << " " << x1 << " " << y1 << " " << x2 << " " << y2 << " c"; - if (flag & FXPT_CLOSEFIGURE) + buf << " " << pos1.x << " " << pos1.y << " " << pos2.x << " " << pos2.y + << " c"; + if (closing) buf << " h"; buf << "\n"; i += 2; @@ -157,7 +157,8 @@ void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData, OutputPath(pPathData, pObject2Device); CFX_FloatRect rect = pPathData->GetBoundingBox(); if (pObject2Device) - rect.Transform(pObject2Device); + pObject2Device->TransformRect(rect); + m_ClipBox.left = static_cast<int>(rect.left); m_ClipBox.right = static_cast<int>(rect.left + rect.right); m_ClipBox.top = static_cast<int>(rect.top + rect.bottom); @@ -184,7 +185,7 @@ void CFX_PSRenderer::SetClip_PathStroke(const CFX_PathData* pPathData, OutputPath(pPathData, nullptr); CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit); - rect.Transform(pObject2Device); + pObject2Device->TransformRect(rect); m_ClipBox.Intersect(rect.GetOuterRect()); if (pObject2Device) { OUTPUT_PS("strokepath W n sm\n"); @@ -580,39 +581,42 @@ void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, pPSFont->m_Glyphs[glyphindex].m_AdjustMatrix[3] = charpos.m_AdjustMatrix[3]; } pPSFont->m_nGlyphs++; + CFX_Matrix matrix; - if (charpos.m_bGlyphAdjust) - matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); - matrix.Concat(1.0f, 0, 0, 1.0f, 0, 0); + if (charpos.m_bGlyphAdjust) { + matrix = + CFX_Matrix(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); + } + matrix.Concat(CFX_Matrix(1.0f, 0, 0, 1.0f, 0, 0)); const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath( pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth); - if (!pPathData) { + if (!pPathData) return; - } + CFX_PathData TransformedPath(*pPathData); - if (charpos.m_bGlyphAdjust) { + if (charpos.m_bGlyphAdjust) TransformedPath.Transform(&matrix); - } + CFX_ByteTextBuf buf; buf << "/X" << *ps_fontnum << " Ff/CharProcs get begin/" << glyphindex << "{n "; - for (int p = 0; p < TransformedPath.GetPointCount(); p++) { - FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p); - switch (TransformedPath.GetFlag(p) & FXPT_TYPE) { - case FXPT_MOVETO: { - buf << x << " " << y << " m\n"; + for (size_t p = 0; p < TransformedPath.GetPoints().size(); p++) { + CFX_PointF point = TransformedPath.GetPoint(p); + switch (TransformedPath.GetType(p)) { + case FXPT_TYPE::MoveTo: { + buf << point.x << " " << point.y << " m\n"; break; } - case FXPT_LINETO: { - buf << x << " " << y << " l\n"; + case FXPT_TYPE::LineTo: { + buf << point.x << " " << point.y << " l\n"; break; } - case FXPT_BEZIERTO: { - buf << x << " " << y << " " << TransformedPath.GetPointX(p + 1) << " " - << TransformedPath.GetPointY(p + 1) << " " - << TransformedPath.GetPointX(p + 2) << " " - << TransformedPath.GetPointY(p + 2) << " c\n"; + case FXPT_TYPE::BezierTo: { + CFX_PointF point1 = TransformedPath.GetPoint(p + 1); + CFX_PointF point2 = TransformedPath.GetPoint(p + 2); + buf << point.x << " " << point.y << " " << point1.x << " " << point1.y + << " " << point2.x << " " << point2.y << " c\n"; p += 2; break; } @@ -656,7 +660,7 @@ bool CFX_PSRenderer::DrawText(int nChars, buf << "/X" << ps_fontnum << " Ff " << font_size << " Fs Sf "; last_fontnum = ps_fontnum; } - buf << pCharPos[i].m_OriginX << " " << pCharPos[i].m_OriginY << " m"; + buf << pCharPos[i].m_Origin.x << " " << pCharPos[i].m_Origin.y << " m"; CFX_ByteString hex; hex.Format("<%02X>", ps_glyphindex); buf << hex.AsStringC() << "Tj\n"; diff --git a/core/fxge/win32/cfx_psrenderer.h b/core/fxge/win32/cfx_psrenderer.h index e941739f4..163c6180a 100644 --- a/core/fxge/win32/cfx_psrenderer.h +++ b/core/fxge/win32/cfx_psrenderer.h @@ -22,7 +22,7 @@ class CFX_FontCache; class CFX_Matrix; class CFX_PathData; class CPSFont; -struct FXTEXT_CHARPOS; +class FXTEXT_CHARPOS; class CFX_PSRenderer { public: diff --git a/core/fxge/win32/fx_win32_device.cpp b/core/fxge/win32/fx_win32_device.cpp index c673a18d2..92e9b41e0 100644 --- a/core/fxge/win32/fx_win32_device.cpp +++ b/core/fxge/win32/fx_win32_device.cpp @@ -166,47 +166,45 @@ void SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_Matrix* pMatrix) { BeginPath(hDC); - int nPoints = pPathData->GetPointCount(); - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - for (int i = 0; i < nPoints; i++) { - FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY; - if (pMatrix) { - pMatrix->Transform(posx, posy); - } - int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == PT_MOVETO) { - MoveToEx(hDC, screen_x, screen_y, nullptr); - } else if (point_type == PT_LINETO) { - if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && - pPoints[i].m_PointX == pPoints[i - 1].m_PointX) { - screen_x++; - } - LineTo(hDC, screen_x, screen_y); - } else if (point_type == PT_BEZIERTO) { + + const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints(); + for (size_t i = 0; i < pPoints.size(); i++) { + CFX_PointF pos = pPoints[i].m_Point; + if (pMatrix) + pos = pMatrix->Transform(pos); + + CFX_Point screen(FXSYS_round(pos.x), FXSYS_round(pos.y)); + FXPT_TYPE point_type = pPoints[i].m_Type; + if (point_type == FXPT_TYPE::MoveTo) { + MoveToEx(hDC, screen.x, screen.y, nullptr); + } else if (point_type == FXPT_TYPE::LineTo) { + if (pPoints[i].m_Point == pPoints[i - 1].m_Point) + screen.x++; + + LineTo(hDC, screen.x, screen.y); + } else if (point_type == FXPT_TYPE::BezierTo) { POINT lppt[3]; - lppt[0].x = screen_x; - lppt[0].y = screen_y; - posx = pPoints[i + 1].m_PointX; - posy = pPoints[i + 1].m_PointY; - if (pMatrix) { - pMatrix->Transform(posx, posy); - } - lppt[1].x = FXSYS_round(posx); - lppt[1].y = FXSYS_round(posy); - posx = pPoints[i + 2].m_PointX; - posy = pPoints[i + 2].m_PointY; - if (pMatrix) { - pMatrix->Transform(posx, posy); - } - lppt[2].x = FXSYS_round(posx); - lppt[2].y = FXSYS_round(posy); + lppt[0].x = screen.x; + lppt[0].y = screen.y; + + pos = pPoints[i + 1].m_Point; + if (pMatrix) + pos = pMatrix->Transform(pos); + + lppt[1].x = FXSYS_round(pos.x); + lppt[1].y = FXSYS_round(pos.y); + + pos = pPoints[i + 2].m_Point; + if (pMatrix) + pos = pMatrix->Transform(pos); + + lppt[2].x = FXSYS_round(pos.x); + lppt[2].y = FXSYS_round(pos.y); PolyBezierTo(hDC, lppt, 3); i += 2; } - if (pPoints[i].m_Flag & PT_CLOSEFIGURE) { + if (pPoints[i].m_CloseFigure) CloseFigure(hDC); - } } EndPath(hDC); } @@ -316,11 +314,6 @@ unsigned clip_liang_barsky(FX_FLOAT x1, } #endif // _SKIA_SUPPORT_ -bool MatrixNoScaled(const CFX_Matrix* pMatrix) { - return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && - pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f; -} - class CFX_Win32FallbackFontInfo final : public CFX_FolderFontInfo { public: CFX_Win32FallbackFontInfo() {} @@ -996,9 +989,9 @@ bool CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData, if (!(pGraphState || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) { CFX_FloatRect bbox_f = pPathData->GetBoundingBox(); - if (pMatrix) { - bbox_f.Transform(pMatrix); - } + if (pMatrix) + pMatrix->TransformRect(bbox_f); + FX_RECT bbox = bbox_f.GetInnerRect(); if (bbox.Width() <= 0) { return DrawCosmeticLine( @@ -1022,10 +1015,10 @@ bool CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData, if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || (pGraphState && pGraphState->m_DashCount))) { - if (!((!pMatrix || MatrixNoScaled(pMatrix)) && pGraphState && + if (!((!pMatrix || !pMatrix->WillScale()) && pGraphState && pGraphState->m_LineWidth == 1.f && - (pPathData->GetPointCount() == 5 || - pPathData->GetPointCount() == 4) && + (pPathData->GetPoints().size() == 5 || + pPathData->GetPoints().size() == 4) && pPathData->IsRect())) { if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, @@ -1049,17 +1042,15 @@ bool CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData, hBrush = CreateBrush(fill_color); hBrush = (HBRUSH)SelectObject(m_hDC, hBrush); } - if (pPathData->GetPointCount() == 2 && pGraphState && + if (pPathData->GetPoints().size() == 2 && pGraphState && pGraphState->m_DashCount) { - FX_FLOAT x1 = pPathData->GetPointX(0); - FX_FLOAT y1 = pPathData->GetPointY(0); - FX_FLOAT x2 = pPathData->GetPointX(1); - FX_FLOAT y2 = pPathData->GetPointY(1); + CFX_PointF pos1 = pPathData->GetPoint(0); + CFX_PointF pos2 = pPathData->GetPoint(1); if (pMatrix) { - pMatrix->Transform(x1, y1); - pMatrix->Transform(x2, y2); + pos1 = pMatrix->Transform(pos1); + pos2 = pMatrix->Transform(pos2); } - DrawLine(x1, y1, x2, y2); + DrawLine(pos1.x, pos1.y, pos2.x, pos2.y); } else { SetPathToDC(m_hDC, pPathData, pMatrix); if (pGraphState && stroke_alpha) { @@ -1113,7 +1104,7 @@ bool CGdiDeviceDriver::FillRectWithBlend(const FX_RECT* pRect, bool CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_Matrix* pMatrix, int fill_mode) { - if (pPathData->GetPointCount() == 5) { + if (pPathData->GetPoints().size() == 5) { CFX_FloatRect rectf; if (pPathData->IsRect(pMatrix, &rectf)) { FX_RECT rect = rectf.GetOuterRect(); diff --git a/core/fxge/win32/fx_win32_gdipext.cpp b/core/fxge/win32/fx_win32_gdipext.cpp index cd18525b0..1be2a54b1 100644 --- a/core/fxge/win32/fx_win32_gdipext.cpp +++ b/core/fxge/win32/fx_win32_gdipext.cpp @@ -1080,15 +1080,16 @@ static bool IsSmallTriangle(PointF* points, for (int i = 0; i < 3; i++) { int pair1 = pairs[i * 2]; int pair2 = pairs[i * 2 + 1]; - FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X; - FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y; + + CFX_PointF p1(points[pair1].X, points[pair1].Y); + CFX_PointF p2(points[pair2].X, points[pair2].Y); if (pMatrix) { - pMatrix->Transform(x1, y1); - pMatrix->Transform(x2, y2); + p1 = pMatrix->Transform(p1); + p2 = pMatrix->Transform(p2); } - FX_FLOAT dx = x1 - x2; - FX_FLOAT dy = y1 - y2; - FX_FLOAT distance_square = (dx * dx) + (dy * dy); + + CFX_PointF diff = p1 - p2; + FX_FLOAT distance_square = (diff.x * diff.x) + (diff.y * diff.y); if (distance_square < (1.0f * 2 + 1.0f / 4)) { v1 = i; v2 = pair1; @@ -1104,11 +1105,10 @@ bool CGdiplusExt::DrawPath(HDC hDC, uint32_t fill_argb, uint32_t stroke_argb, int fill_mode) { - int nPoints = pPathData->GetPointCount(); - if (nPoints == 0) { + auto& pPoints = pPathData->GetPoints(); + if (pPoints.empty()) return true; - } - FX_PATHPOINT* pPoints = pPathData->GetPoints(); + GpGraphics* pGraphics = nullptr; CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt; @@ -1122,45 +1122,41 @@ bool CGdiplusExt::DrawPath(HDC hDC, pObject2Device->e, pObject2Device->f, &pMatrix); CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix); } - PointF* points = FX_Alloc(PointF, nPoints); - BYTE* types = FX_Alloc(BYTE, nPoints); + PointF* points = FX_Alloc(PointF, pPoints.size()); + BYTE* types = FX_Alloc(BYTE, pPoints.size()); int nSubPathes = 0; bool bSubClose = false; int pos_subclose = 0; bool bSmooth = false; int startpoint = 0; - for (int i = 0; i < nPoints; i++) { - points[i].X = pPoints[i].m_PointX; - points[i].Y = pPoints[i].m_PointY; - FX_FLOAT x, y; - if (pObject2Device) { - pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y); - } else { - x = pPoints[i].m_PointX; - y = pPoints[i].m_PointY; - } - if (x > 50000 * 1.0f) { + for (size_t i = 0; i < pPoints.size(); i++) { + points[i].X = pPoints[i].m_Point.x; + points[i].Y = pPoints[i].m_Point.y; + + CFX_PointF pos = pPoints[i].m_Point; + if (pObject2Device) + pos = pObject2Device->Transform(pos); + + if (pos.x > 50000 * 1.0f) points[i].X = 50000 * 1.0f; - } - if (x < -50000 * 1.0f) { + if (pos.x < -50000 * 1.0f) points[i].X = -50000 * 1.0f; - } - if (y > 50000 * 1.0f) { + if (pos.y > 50000 * 1.0f) points[i].Y = 50000 * 1.0f; - } - if (y < -50000 * 1.0f) { + if (pos.y < -50000 * 1.0f) points[i].Y = -50000 * 1.0f; - } - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { + + FXPT_TYPE point_type = pPoints[i].m_Type; + if (point_type == FXPT_TYPE::MoveTo) { types[i] = PathPointTypeStart; nSubPathes++; bSubClose = false; startpoint = i; - } else if (point_type == FXPT_LINETO) { + } else if (point_type == FXPT_TYPE::LineTo) { types[i] = PathPointTypeLine; - if (pPoints[i - 1].m_Flag == FXPT_MOVETO && - (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) && + if (pPoints[i - 1].IsTypeAndOpen(FXPT_TYPE::MoveTo) && + (i == pPoints.size() - 1 || + pPoints[i + 1].IsTypeAndOpen(FXPT_TYPE::MoveTo)) && points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) { points[i].X += 0.01f; continue; @@ -1169,11 +1165,11 @@ bool CGdiplusExt::DrawPath(HDC hDC, points[i].Y != points[i - 1].Y) { bSmooth = true; } - } else if (point_type == FXPT_BEZIERTO) { + } else if (point_type == FXPT_TYPE::BezierTo) { types[i] = PathPointTypeBezier; bSmooth = true; } - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) { + if (pPoints[i].m_CloseFigure) { if (bSubClose) { types[pos_subclose] &= ~PathPointTypeCloseSubpath; } else { @@ -1199,7 +1195,7 @@ bool CGdiplusExt::DrawPath(HDC hDC, } } int new_fill_mode = fill_mode & 3; - if (nPoints == 4 && !pGraphState) { + if (pPoints.size() == 4 && !pGraphState) { int v1, v2; if (IsSmallTriangle(points, pObject2Device, v1, v2)) { GpPen* pPen = nullptr; @@ -1212,12 +1208,12 @@ bool CGdiplusExt::DrawPath(HDC hDC, } } GpPath* pGpPath = nullptr; - CallFunc(GdipCreatePath2)(points, types, nPoints, + CallFunc(GdipCreatePath2)(points, types, pPoints.size(), GdiFillType2Gdip(new_fill_mode), &pGpPath); if (!pGpPath) { - if (pMatrix) { + if (pMatrix) CallFunc(GdipDeleteMatrix)(pMatrix); - } + FX_Free(points); FX_Free(types); CallFunc(GdipDeleteGraphics)(pGraphics); @@ -1236,8 +1232,8 @@ bool CGdiplusExt::DrawPath(HDC hDC, CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath); } else { int iStart = 0; - for (int i = 0; i < nPoints; i++) { - if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) { + for (size_t i = 0; i < pPoints.size(); i++) { + if (i == pPoints.size() - 1 || types[i + 1] == PathPointTypeStart) { GpPath* pSubPath; CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, diff --git a/core/fxge/win32/fx_win32_print.cpp b/core/fxge/win32/fx_win32_print.cpp index 94c415b72..cda83ebc9 100644 --- a/core/fxge/win32/fx_win32_print.cpp +++ b/core/fxge/win32/fx_win32_print.cpp @@ -269,12 +269,12 @@ bool CGdiPrinterDriver::DrawDeviceText(int nChars, // Transforms SetGraphicsMode(m_hDC, GM_ADVANCED); XFORM xform; - xform.eM11 = pObject2Device->GetA() / kScaleFactor; - xform.eM12 = pObject2Device->GetB() / kScaleFactor; - xform.eM21 = -pObject2Device->GetC() / kScaleFactor; - xform.eM22 = -pObject2Device->GetD() / kScaleFactor; - xform.eDx = pObject2Device->GetE(); - xform.eDy = pObject2Device->GetF(); + xform.eM11 = pObject2Device->a / kScaleFactor; + xform.eM12 = pObject2Device->b / kScaleFactor; + xform.eM21 = -pObject2Device->c / kScaleFactor; + xform.eM22 = -pObject2Device->d / kScaleFactor; + xform.eDx = pObject2Device->e; + xform.eDy = pObject2Device->f; ModifyWorldTransform(m_hDC, &xform, MWT_LEFTMULTIPLY); // Color @@ -296,11 +296,11 @@ bool CGdiPrinterDriver::DrawDeviceText(int nChars, ASSERT(charpos.m_AdjustMatrix[1] == 0); ASSERT(charpos.m_AdjustMatrix[2] == 0); ASSERT(charpos.m_AdjustMatrix[3] == 0); - ASSERT(charpos.m_OriginY == 0); + ASSERT(charpos.m_Origin.y == 0); // Round the spacing to the nearest integer, but keep track of the rounding // error for calculating the next spacing value. - FX_FLOAT fOriginX = charpos.m_OriginX * kScaleFactor; + FX_FLOAT fOriginX = charpos.m_Origin.x * kScaleFactor; FX_FLOAT fPixelSpacing = fOriginX - fPreviousOriginX; spacing[i] = FXSYS_round(fPixelSpacing); fPreviousOriginX = fOriginX - (fPixelSpacing - spacing[i]); @@ -346,12 +346,13 @@ CPSPrinterDriver::CPSPrinterDriver(HDC hDC, int pslevel, bool bCmykOutput) ret = ::GetRegionData(hRgn, ret, pData); if (ret) { CFX_PathData path; - path.AllocPointCount(pData->rdh.nCount * 5); for (uint32_t i = 0; i < pData->rdh.nCount; i++) { RECT* pRect = reinterpret_cast<RECT*>(pData->Buffer + pData->rdh.nRgnSize * i); - path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, - (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top); + path.AppendRect(static_cast<FX_FLOAT>(pRect->left), + static_cast<FX_FLOAT>(pRect->bottom), + static_cast<FX_FLOAT>(pRect->right), + static_cast<FX_FLOAT>(pRect->top)); } m_PSRenderer.SetClip_PathFill(&path, nullptr, FXFILL_WINDING); } diff --git a/core/fxge/win32/win32_int.h b/core/fxge/win32/win32_int.h index 974a1200e..f8eae8730 100644 --- a/core/fxge/win32/win32_int.h +++ b/core/fxge/win32/win32_int.h @@ -17,7 +17,7 @@ #include "core/fxge/win32/cpsoutput.h" #include "core/fxge/win32/dwrite_int.h" -struct FXTEXT_CHARPOS; +class FXTEXT_CHARPOS; struct WINDIB_Open_Args_; typedef HANDLE(__stdcall* FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, diff --git a/fpdfsdk/cfx_systemhandler.cpp b/fpdfsdk/cfx_systemhandler.cpp index f38be4c3e..b6dc19d48 100644 --- a/fpdfsdk/cfx_systemhandler.cpp +++ b/fpdfsdk/cfx_systemhandler.cpp @@ -46,19 +46,14 @@ void CFX_SystemHandler::InvalidateRect(CPDFSDK_Widget* widget, FX_RECT rect) { CFX_Matrix device2page; device2page.SetReverse(page2device); - FX_FLOAT left; - FX_FLOAT top; - FX_FLOAT right; - FX_FLOAT bottom; - device2page.Transform(static_cast<FX_FLOAT>(rect.left), - static_cast<FX_FLOAT>(rect.top), left, top); - device2page.Transform(static_cast<FX_FLOAT>(rect.right), - static_cast<FX_FLOAT>(rect.bottom), right, bottom); - CFX_FloatRect rcPDF(left, bottom, right, top); - rcPDF.Normalize(); + CFX_PointF left_top = device2page.Transform(CFX_PointF( + static_cast<FX_FLOAT>(rect.left), static_cast<FX_FLOAT>(rect.top))); + CFX_PointF right_bottom = device2page.Transform(CFX_PointF( + static_cast<FX_FLOAT>(rect.right), static_cast<FX_FLOAT>(rect.bottom))); - m_pFormFillEnv->Invalidate(pPage, rcPDF.left, rcPDF.top, rcPDF.right, - rcPDF.bottom); + CFX_FloatRect rcPDF(left_top.x, right_bottom.y, right_bottom.x, left_top.y); + rcPDF.Normalize(); + m_pFormFillEnv->Invalidate(pPage, rcPDF.ToFxRect()); } void CFX_SystemHandler::OutputSelectedRect(CFFL_FormFiller* pFormFiller, @@ -66,16 +61,15 @@ void CFX_SystemHandler::OutputSelectedRect(CFFL_FormFiller* pFormFiller, if (!pFormFiller) return; - CFX_FloatPoint leftbottom = CFX_FloatPoint(rect.left, rect.bottom); - CFX_FloatPoint righttop = CFX_FloatPoint(rect.right, rect.top); - CFX_FloatPoint ptA = pFormFiller->PWLtoFFL(leftbottom); - CFX_FloatPoint ptB = pFormFiller->PWLtoFFL(righttop); + CFX_PointF ptA = pFormFiller->PWLtoFFL(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptB = pFormFiller->PWLtoFFL(CFX_PointF(rect.right, rect.top)); CPDFSDK_Annot* pAnnot = pFormFiller->GetSDKAnnot(); UnderlyingPageType* pPage = pAnnot->GetUnderlyingPage(); ASSERT(pPage); - m_pFormFillEnv->OutputSelectedRect(pPage, ptA.x, ptB.y, ptB.x, ptA.y); + m_pFormFillEnv->OutputSelectedRect(pPage, + CFX_FloatRect(ptA.x, ptA.y, ptB.x, ptB.y)); } bool CFX_SystemHandler::IsSelectionImplemented() const { diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp index 898b9ccc0..c4990674d 100644 --- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp +++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp @@ -106,7 +106,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDown( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnLButtonDown(pPageView, pAnnot, nFlags, point); @@ -116,7 +116,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonUp( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnLButtonUp(pPageView, pAnnot, nFlags, point); @@ -126,7 +126,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnLButtonDblClk( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnLButtonDblClk(pPageView, pAnnot, nFlags, point); @@ -136,7 +136,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseMove( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnMouseMove(pPageView, pAnnot, nFlags, point); @@ -147,7 +147,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnMouseWheel( CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point); @@ -157,7 +157,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonDown( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnRButtonDown(pPageView, pAnnot, nFlags, point); @@ -167,7 +167,7 @@ bool CPDFSDK_AnnotHandlerMgr::Annot_OnRButtonUp( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(*pAnnot); return GetAnnotHandler(pAnnot->Get()) ->OnRButtonUp(pPageView, pAnnot, nFlags, point); @@ -263,7 +263,7 @@ CFX_FloatRect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox( bool CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(pAnnot); IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(pAnnot); if (pAnnotHandler->CanAnswer(pAnnot)) diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.h b/fpdfsdk/cpdfsdk_annothandlermgr.h index 7742fd6ed..cbda02cbe 100644 --- a/fpdfsdk/cpdfsdk_annothandlermgr.h +++ b/fpdfsdk/cpdfsdk_annothandlermgr.h @@ -58,32 +58,32 @@ class CPDFSDK_AnnotHandlerMgr { bool Annot_OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool Annot_OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags); bool Annot_OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag); bool Annot_OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag); @@ -100,7 +100,7 @@ class CPDFSDK_AnnotHandlerMgr { CPDFSDK_Annot* pAnnot); bool Annot_OnHitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point); + const CFX_PointF& point); private: IPDFSDK_AnnotHandler* GetAnnotHandler(CPDF_Annot::Subtype nSubtype) const; diff --git a/fpdfsdk/cpdfsdk_baannothandler.cpp b/fpdfsdk/cpdfsdk_baannothandler.cpp index 617d88fd4..fa83932a8 100644 --- a/fpdfsdk/cpdfsdk_baannothandler.cpp +++ b/fpdfsdk/cpdfsdk_baannothandler.cpp @@ -96,28 +96,28 @@ void CPDFSDK_BAAnnotHandler::OnMouseExit(CPDFSDK_PageView* pPageView, bool CPDFSDK_BAAnnotHandler::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } bool CPDFSDK_BAAnnotHandler::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } bool CPDFSDK_BAAnnotHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } bool CPDFSDK_BAAnnotHandler::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } @@ -125,28 +125,28 @@ bool CPDFSDK_BAAnnotHandler::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } bool CPDFSDK_BAAnnotHandler::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } bool CPDFSDK_BAAnnotHandler::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } bool CPDFSDK_BAAnnotHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } @@ -195,10 +195,8 @@ CFX_FloatRect CPDFSDK_BAAnnotHandler::GetViewBBox(CPDFSDK_PageView* pPageView, bool CPDFSDK_BAAnnotHandler::HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(pPageView); ASSERT(pAnnot); - - CFX_FloatRect rect = GetViewBBox(pPageView, pAnnot); - return rect.Contains(point.x, point.y); + return GetViewBBox(pPageView, pAnnot).Contains(point); } diff --git a/fpdfsdk/cpdfsdk_baannothandler.h b/fpdfsdk/cpdfsdk_baannothandler.h index 2efed0e26..d5f170f45 100644 --- a/fpdfsdk/cpdfsdk_baannothandler.h +++ b/fpdfsdk/cpdfsdk_baannothandler.h @@ -39,7 +39,7 @@ class CPDFSDK_BAAnnotHandler : public IPDFSDK_AnnotHandler { CPDFSDK_Annot* pAnnot) override; bool HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; void OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, @@ -56,36 +56,36 @@ class CPDFSDK_BAAnnotHandler : public IPDFSDK_AnnotHandler { bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override; bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override; bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override; diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.cpp b/fpdfsdk/cpdfsdk_formfillenvironment.cpp index b91c97842..4ef766d9f 100644 --- a/fpdfsdk/cpdfsdk_formfillenvironment.cpp +++ b/fpdfsdk/cpdfsdk_formfillenvironment.cpp @@ -233,21 +233,20 @@ CPDFSDK_FormFillEnvironment::GetInteractiveFormFiller() { } void CPDFSDK_FormFillEnvironment::Invalidate(FPDF_PAGE page, - double left, - double top, - double right, - double bottom) { - if (m_pInfo && m_pInfo->FFI_Invalidate) - m_pInfo->FFI_Invalidate(m_pInfo, page, left, top, right, bottom); -} - -void CPDFSDK_FormFillEnvironment::OutputSelectedRect(FPDF_PAGE page, - double left, - double top, - double right, - double bottom) { - if (m_pInfo && m_pInfo->FFI_OutputSelectedRect) - m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, left, top, right, bottom); + const FX_RECT& rect) { + if (m_pInfo && m_pInfo->FFI_Invalidate) { + m_pInfo->FFI_Invalidate(m_pInfo, page, rect.left, rect.top, rect.right, + rect.bottom); + } +} + +void CPDFSDK_FormFillEnvironment::OutputSelectedRect( + FPDF_PAGE page, + const CFX_FloatRect& rect) { + if (m_pInfo && m_pInfo->FFI_OutputSelectedRect) { + m_pInfo->FFI_OutputSelectedRect(m_pInfo, page, rect.left, rect.top, + rect.right, rect.bottom); + } } void CPDFSDK_FormFillEnvironment::SetCursor(int nCursorType) { diff --git a/fpdfsdk/cpdfsdk_formfillenvironment.h b/fpdfsdk/cpdfsdk_formfillenvironment.h index 8c2a8a33c..eead8734f 100644 --- a/fpdfsdk/cpdfsdk_formfillenvironment.h +++ b/fpdfsdk/cpdfsdk_formfillenvironment.h @@ -68,16 +68,8 @@ class CPDFSDK_FormFillEnvironment void ProcJavascriptFun(); bool ProcOpenAction(); - void Invalidate(FPDF_PAGE page, - double left, - double top, - double right, - double bottom); - void OutputSelectedRect(FPDF_PAGE page, - double left, - double top, - double right, - double bottom); + void Invalidate(FPDF_PAGE page, const FX_RECT& rect); + void OutputSelectedRect(FPDF_PAGE page, const CFX_FloatRect& rect); void SetCursor(int nCursorType); int SetTimer(int uElapse, TimerCallback lpTimerFunc); diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp index 7b7718030..4ebcf8a2f 100644 --- a/fpdfsdk/cpdfsdk_interform.cpp +++ b/fpdfsdk/cpdfsdk_interform.cpp @@ -30,7 +30,7 @@ #include "fpdfsdk/fsdk_define.h" #include "fpdfsdk/fxedit/fxet_edit.h" #include "fpdfsdk/ipdfsdk_annothandler.h" -#include "fpdfsdk/javascript/ijs_context.h" +#include "fpdfsdk/javascript/ijs_event_context.h" #include "fpdfsdk/javascript/ijs_runtime.h" #include "fpdfsdk/pdfwindow/PWL_Utils.h" #include "third_party/base/stl_util.h" @@ -253,7 +253,7 @@ void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) { if (csJS.IsEmpty()) continue; - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); CFX_WideString sOldValue = pField->GetValue(); CFX_WideString sValue = sOldValue; bool bRC = true; @@ -261,12 +261,10 @@ void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField) { CFX_WideString sInfo; bool bRet = pContext->RunScript(csJS, &sInfo); - pRuntime->ReleaseContext(pContext); - + pRuntime->ReleaseEventContext(pContext); if (bRet && bRC && sValue.Compare(sOldValue) != 0) pField->SetValue(sValue, true); } - m_bBusy = false; } @@ -296,12 +294,11 @@ CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, if (!script.IsEmpty()) { CFX_WideString Value = sValue; - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); pContext->OnField_Format(pFormField, Value, true); CFX_WideString sInfo; bool bRet = pContext->RunScript(script, &sInfo); - pRuntime->ReleaseContext(pContext); - + pRuntime->ReleaseEventContext(pContext); if (bRet) { sValue = Value; bFormatted = true; @@ -309,7 +306,6 @@ CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, } } } - return sValue; } @@ -325,18 +321,16 @@ void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, } void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField) { + auto formfiller = m_pFormFillEnv->GetInteractiveFormFiller(); for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { CPDF_FormControl* pFormCtrl = pFormField->GetControl(i); ASSERT(pFormCtrl); if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl)) { UnderlyingPageType* pPage = pWidget->GetUnderlyingPage(); - CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(pPage, false); - FX_RECT rcBBox = m_pFormFillEnv->GetInteractiveFormFiller()->GetViewBBox( - pPageView, pWidget); - - m_pFormFillEnv->Invalidate(pPage, rcBBox.left, rcBBox.top, rcBBox.right, - rcBBox.bottom); + m_pFormFillEnv->Invalidate( + pPage, formfiller->GetViewBBox( + m_pFormFillEnv->GetPageView(pPage, false), pWidget)); } } } @@ -427,13 +421,13 @@ bool CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action) { std::vector<CPDF_FormField*> fields = GetFieldFromObjects(fieldObjects); if (!fields.empty()) { bool bIncludeOrExclude = !(dwFlags & 0x01); - if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude)) + if (!m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude)) return false; return SubmitFields(sDestination, fields, bIncludeOrExclude, false); } } - if (m_pInterForm->CheckRequiredFields(nullptr, true)) + if (!m_pInterForm->CheckRequiredFields(nullptr, true)) return false; return SubmitForm(sDestination, false); diff --git a/fpdfsdk/cpdfsdk_pageview.cpp b/fpdfsdk/cpdfsdk_pageview.cpp index 416adffbe..c67948da9 100644 --- a/fpdfsdk/cpdfsdk_pageview.cpp +++ b/fpdfsdk/cpdfsdk_pageview.cpp @@ -95,13 +95,11 @@ void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, return; if (pPage->GetContext()->GetDocType() == DOCTYPE_DYNAMIC_XFA) { - CFX_Graphics gs; - gs.Create(pDevice); - CFX_RectF rectClip; - rectClip.Set(static_cast<FX_FLOAT>(pClip.left), - static_cast<FX_FLOAT>(pClip.top), - static_cast<FX_FLOAT>(pClip.Width()), - static_cast<FX_FLOAT>(pClip.Height())); + CFX_Graphics gs(pDevice); + CFX_RectF rectClip(static_cast<FX_FLOAT>(pClip.left), + static_cast<FX_FLOAT>(pClip.top), + static_cast<FX_FLOAT>(pClip.Width()), + static_cast<FX_FLOAT>(pClip.Height())); gs.SetClipRect(rectClip); std::unique_ptr<CXFA_RenderContext> pRenderContext(new CXFA_RenderContext); CXFA_RenderOptions renderOptions; @@ -131,22 +129,20 @@ void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, } } -CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX, - FX_FLOAT pageY) { +CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(const CFX_PointF& point) { CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr(); CPDFSDK_AnnotIteration annotIteration(this, false); for (const auto& pSDKAnnot : annotIteration) { CFX_FloatRect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get()); if (pSDKAnnot->GetAnnotSubtype() == CPDF_Annot::Subtype::POPUP) continue; - if (rc.Contains(pageX, pageY)) + if (rc.Contains(point)) return pSDKAnnot.Get(); } return nullptr; } -CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, - FX_FLOAT pageY) { +CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(const CFX_PointF& point) { CPDFSDK_AnnotHandlerMgr* pAnnotMgr = m_pFormFillEnv->GetAnnotHandlerMgr(); CPDFSDK_AnnotIteration annotIteration(this, false); for (const auto& pSDKAnnot : annotIteration) { @@ -157,7 +153,6 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, #endif // PDF_ENABLE_XFA if (bHitTest) { pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot.Get()); - CFX_FloatPoint point(pageX, pageY); if (pAnnotMgr->Annot_OnHitTest(this, pSDKAnnot.Get(), point)) return pSDKAnnot.Get(); } @@ -247,9 +242,8 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(CXFA_FFWidget* hWidget) { } #endif // PDF_ENABLE_XFA -bool CPDFSDK_PageView::OnLButtonDown(const CFX_FloatPoint& point, - uint32_t nFlag) { - CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point.x, point.y)); +bool CPDFSDK_PageView::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { + CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point)); if (!pAnnot) { m_pFormFillEnv->KillFocusAnnot(nFlag); return false; @@ -268,9 +262,8 @@ bool CPDFSDK_PageView::OnLButtonDown(const CFX_FloatPoint& point, } #ifdef PDF_ENABLE_XFA -bool CPDFSDK_PageView::OnRButtonDown(const CFX_FloatPoint& point, - uint32_t nFlag) { - CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point.x, point.y)); +bool CPDFSDK_PageView::OnRButtonDown(const CFX_PointF& point, uint32_t nFlag) { + CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point)); if (!pAnnot) return false; @@ -286,11 +279,10 @@ bool CPDFSDK_PageView::OnRButtonDown(const CFX_FloatPoint& point, return true; } -bool CPDFSDK_PageView::OnRButtonUp(const CFX_FloatPoint& point, - uint32_t nFlag) { +bool CPDFSDK_PageView::OnRButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = m_pFormFillEnv->GetAnnotHandlerMgr(); - CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point.x, point.y)); + CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point)); if (!pFXAnnot) return false; @@ -301,11 +293,10 @@ bool CPDFSDK_PageView::OnRButtonUp(const CFX_FloatPoint& point, } #endif // PDF_ENABLE_XFA -bool CPDFSDK_PageView::OnLButtonUp(const CFX_FloatPoint& point, - uint32_t nFlag) { +bool CPDFSDK_PageView::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = m_pFormFillEnv->GetAnnotHandlerMgr(); - CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point.x, point.y)); + CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXWidgetAtPoint(point)); CPDFSDK_Annot::ObservedPtr pFocusAnnot(GetFocusAnnot()); if (pFocusAnnot && pFocusAnnot != pFXAnnot) { // Last focus Annot gets a chance to handle the event. @@ -316,10 +307,10 @@ bool CPDFSDK_PageView::OnLButtonUp(const CFX_FloatPoint& point, pAnnotHandlerMgr->Annot_OnLButtonUp(this, &pFXAnnot, nFlag, point); } -bool CPDFSDK_PageView::OnMouseMove(const CFX_FloatPoint& point, int nFlag) { +bool CPDFSDK_PageView::OnMouseMove(const CFX_PointF& point, int nFlag) { CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = m_pFormFillEnv->GetAnnotHandlerMgr(); - CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXAnnotAtPoint(point.x, point.y)); + CPDFSDK_Annot::ObservedPtr pFXAnnot(GetFXAnnotAtPoint(point)); if (pFXAnnot) { if (m_pCaptureWidget && m_pCaptureWidget != pFXAnnot) { m_bExitWidget = true; @@ -350,9 +341,9 @@ bool CPDFSDK_PageView::OnMouseMove(const CFX_FloatPoint& point, int nFlag) { bool CPDFSDK_PageView::OnMouseWheel(double deltaX, double deltaY, - const CFX_FloatPoint& point, + const CFX_PointF& point, int nFlag) { - CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point.x, point.y)); + CPDFSDK_Annot::ObservedPtr pAnnot(GetFXWidgetAtPoint(point)); if (!pAnnot) return false; @@ -441,13 +432,12 @@ void CPDFSDK_PageView::LoadFXAnnots() { void CPDFSDK_PageView::UpdateRects(const std::vector<CFX_FloatRect>& rects) { for (const auto& rc : rects) - m_pFormFillEnv->Invalidate(m_page, rc.left, rc.top, rc.right, rc.bottom); + m_pFormFillEnv->Invalidate(m_page, rc.ToFxRect()); } void CPDFSDK_PageView::UpdateView(CPDFSDK_Annot* pAnnot) { CFX_FloatRect rcWindow = pAnnot->GetRect(); - m_pFormFillEnv->Invalidate(m_page, rcWindow.left, rcWindow.top, - rcWindow.right, rcWindow.bottom); + m_pFormFillEnv->Invalidate(m_page, rcWindow.ToFxRect()); } int CPDFSDK_PageView::GetPageIndex() const { diff --git a/fpdfsdk/cpdfsdk_pageview.h b/fpdfsdk/cpdfsdk_pageview.h index 9a3443b4b..bcd5177c1 100644 --- a/fpdfsdk/cpdfsdk_pageview.h +++ b/fpdfsdk/cpdfsdk_pageview.h @@ -35,9 +35,6 @@ class CPDFSDK_PageView final : public CPDF_Page::View { CPDF_RenderOptions* pOptions); #endif // PDF_ENABLE_XFA - CPDFSDK_Annot* GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY); - CPDFSDK_Annot* GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY); - void LoadFXAnnots(); CPDFSDK_Annot* GetFocusAnnot(); bool IsValidAnnot(const CPDF_Annot* p) const; @@ -59,20 +56,20 @@ class CPDFSDK_PageView final : public CPDF_Page::View { CPDF_Page* GetPDFPage() const; CPDF_Document* GetPDFDocument(); CPDFSDK_FormFillEnvironment* GetFormFillEnv() const { return m_pFormFillEnv; } - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag); - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag); + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag); + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag); #ifdef PDF_ENABLE_XFA - bool OnRButtonDown(const CFX_FloatPoint& point, uint32_t nFlag); - bool OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag); + bool OnRButtonDown(const CFX_PointF& point, uint32_t nFlag); + bool OnRButtonUp(const CFX_PointF& point, uint32_t nFlag); #endif // PDF_ENABLE_XFA bool OnChar(int nChar, uint32_t nFlag); bool OnKeyDown(int nKeyCode, int nFlag); bool OnKeyUp(int nKeyCode, int nFlag); - bool OnMouseMove(const CFX_FloatPoint& point, int nFlag); + bool OnMouseMove(const CFX_PointF& point, int nFlag); bool OnMouseWheel(double deltaX, double deltaY, - const CFX_FloatPoint& point, + const CFX_PointF& point, int nFlag); void GetCurrentMatrix(CFX_Matrix& matrix) { matrix = m_curMatrix; } @@ -96,6 +93,9 @@ class CPDFSDK_PageView final : public CPDF_Page::View { #endif // PDF_ENABLE_XFA private: + CPDFSDK_Annot* GetFXAnnotAtPoint(const CFX_PointF& point); + CPDFSDK_Annot* GetFXWidgetAtPoint(const CFX_PointF& point); + int GetPageIndexForStaticPDF() const; CFX_Matrix m_curMatrix; diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index 108690665..cd86f7a0b 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp @@ -841,24 +841,24 @@ void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, if (!m_pInterForm->IsNeedHighLight(nFieldType)) return; - CFX_FloatRect rc = GetRect(); - FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType); - uint8_t alpha = m_pInterForm->GetHighlightAlpha(); - - CFX_FloatRect rcDevice; CFX_Matrix page2device; pPageView->GetCurrentMatrix(page2device); - page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), - rcDevice.left, rcDevice.bottom); - page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), - rcDevice.right, rcDevice.top); + CFX_FloatRect rcDevice = GetRect(); + CFX_PointF tmp = + page2device.Transform(CFX_PointF(rcDevice.left, rcDevice.bottom)); + rcDevice.left = tmp.x; + rcDevice.bottom = tmp.y; + + tmp = page2device.Transform(CFX_PointF(rcDevice.right, rcDevice.top)); + rcDevice.right = tmp.x; + rcDevice.top = tmp.y; rcDevice.Normalize(); - FX_ARGB argb = ArgbEncode((int)alpha, color); - FX_RECT rcDev((int)rcDevice.left, (int)rcDevice.top, (int)rcDevice.right, - (int)rcDevice.bottom); - pDevice->FillRect(&rcDev, argb); + FX_RECT rcDev = rcDevice.ToFxRect(); + pDevice->FillRect( + &rcDev, ArgbEncode(static_cast<int>(m_pInterForm->GetHighlightAlpha()), + m_pInterForm->GetHighlightColor(nFieldType))); } void CPDFSDK_Widget::ResetAppearance_PushButton() { @@ -889,11 +889,10 @@ void CPDFSDK_Widget::ResetAppearance_PushButton() { break; } - CPWL_Color crBackground, crBorder; - + CPWL_Color crBackground; + CPWL_Color crBorder; int iColorType; FX_FLOAT fc[4]; - pControl->GetOriginalBackgroundColor(iColorType, fc); if (iColorType > 0) crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]); @@ -904,7 +903,8 @@ void CPDFSDK_Widget::ResetAppearance_PushButton() { FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); CPWL_Dash dsBorder(3, 0, 0); - CPWL_Color crLeftTop, crRightBottom; + CPWL_Color crLeftTop; + CPWL_Color crRightBottom; BorderStyle nBorderStyle = GetBorderStyle(); switch (nBorderStyle) { @@ -914,7 +914,7 @@ void CPDFSDK_Widget::ResetAppearance_PushButton() { case BorderStyle::BEVELED: fBorderWidth *= 2; crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); - crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); + crRightBottom = crBackground / 2.0f; break; case BorderStyle::INSET: fBorderWidth *= 2; @@ -1050,8 +1050,7 @@ void CPDFSDK_Widget::ResetAppearance_PushButton() { font_map.SetAPType("D"); - csAP = CPWL_Utils::GetRectFillAppStream( - rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) + + csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) + CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) + @@ -1094,7 +1093,7 @@ void CPDFSDK_Widget::ResetAppearance_CheckBox() { case BorderStyle::BEVELED: fBorderWidth *= 2; crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); - crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); + crRightBottom = crBackground / 2.0f; break; case BorderStyle::INSET: fBorderWidth *= 2; @@ -1107,7 +1106,6 @@ void CPDFSDK_Widget::ResetAppearance_CheckBox() { CFX_FloatRect rcWindow = GetRotatedRect(); CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth); - CPDF_DefaultAppearance da = pControl->GetDefaultAppearance(); if (da.HasColor()) { da.GetColor(iColorType, fc); @@ -1115,7 +1113,6 @@ void CPDFSDK_Widget::ResetAppearance_CheckBox() { } int32_t nStyle = 0; - CFX_WideString csWCaption = pControl->GetNormalCaption(); if (csWCaption.GetLength() > 0) { switch (csWCaption[0]) { @@ -1167,8 +1164,7 @@ void CPDFSDK_Widget::ResetAppearance_CheckBox() { } CFX_ByteString csAP_D_ON = - CPWL_Utils::GetRectFillAppStream( - rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) + + CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) + CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder); @@ -1207,8 +1203,8 @@ void CPDFSDK_Widget::ResetAppearance_RadioButton() { FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); CPWL_Dash dsBorder(3, 0, 0); - CPWL_Color crLeftTop, crRightBottom; - + CPWL_Color crLeftTop; + CPWL_Color crRightBottom; BorderStyle nBorderStyle = GetBorderStyle(); switch (nBorderStyle) { case BorderStyle::DASH: @@ -1217,7 +1213,7 @@ void CPDFSDK_Widget::ResetAppearance_RadioButton() { case BorderStyle::BEVELED: fBorderWidth *= 2; crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); - crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); + crRightBottom = crBackground / 2.0f; break; case BorderStyle::INSET: fBorderWidth *= 2; @@ -1238,7 +1234,6 @@ void CPDFSDK_Widget::ResetAppearance_RadioButton() { } int32_t nStyle = 0; - CFX_WideString csWCaption = pControl->GetNormalCaption(); if (csWCaption.GetLength() > 0) { switch (csWCaption[0]) { @@ -1273,7 +1268,7 @@ void CPDFSDK_Widget::ResetAppearance_RadioButton() { if (nStyle == PCS_CIRCLE) { if (nBorderStyle == BorderStyle::BEVELED) { crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); - crRightBottom = CPWL_Utils::SubstractColor(crBackground, 0.25f); + crRightBottom = crBackground - 0.25f; } else if (nBorderStyle == BorderStyle::INSET) { crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f); crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f); @@ -1311,9 +1306,9 @@ void CPDFSDK_Widget::ResetAppearance_RadioButton() { CFX_ByteString csAP_D_ON; if (nStyle == PCS_CIRCLE) { - CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground, 0.25f); + CPWL_Color crBK = crBackground - 0.25f; if (nBorderStyle == BorderStyle::BEVELED) { - crLeftTop = CPWL_Utils::SubstractColor(crBackground, 0.25f); + crLeftTop = crBackground - 0.25f; crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1); crBK = crBackground; } else if (nBorderStyle == BorderStyle::INSET) { @@ -1326,11 +1321,11 @@ void CPDFSDK_Widget::ResetAppearance_RadioButton() { rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder); } else { - csAP_D_ON = CPWL_Utils::GetRectFillAppStream( - rcWindow, CPWL_Utils::SubstractColor(crBackground, 0.25f)) + - CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, - crLeftTop, crRightBottom, - nBorderStyle, dsBorder); + csAP_D_ON = + CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) + + CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, + crLeftTop, crRightBottom, nBorderStyle, + dsBorder); } CFX_ByteString csAP_D_OFF = csAP_D_ON; @@ -1395,7 +1390,7 @@ void CPDFSDK_Widget::ResetAppearance_ComboBox(const CFX_WideString* sValue) { CFX_FloatRect rcContent = pEdit->GetContentRect(); CFX_ByteString sEdit = - CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint()); + CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF()); if (sEdit.GetLength() > 0) { sBody << "/Tx BMC\n" << "q\n"; @@ -1475,15 +1470,13 @@ void CPDFSDK_Widget::ResetAppearance_ListBox() { sList << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1), true) - << CPWL_Utils::GetEditAppStream(pEdit.get(), - CFX_FloatPoint(0.0f, fy)) + << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy)) << "ET\n"; } else { CPWL_Color crText = GetTextPWLColor(); sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText, true) - << CPWL_Utils::GetEditAppStream(pEdit.get(), - CFX_FloatPoint(0.0f, fy)) + << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy)) << "ET\n"; } @@ -1572,7 +1565,7 @@ void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) { CFX_FloatRect rcContent = pEdit->GetContentRect(); CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream( - pEdit.get(), CFX_FloatPoint(), nullptr, !bCharArray, subWord); + pEdit.get(), CFX_PointF(), nullptr, !bCharArray, subWord); if (sEdit.GetLength() > 0) { sBody << "/Tx BMC\n" @@ -1709,7 +1702,7 @@ CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const { case BorderStyle::BEVELED: fBorderWidth *= 2; crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1); - crRightBottom = CPWL_Utils::DevideColor(crBackground, 2); + crRightBottom = crBackground / 2.0f; break; case BorderStyle::INSET: fBorderWidth *= 2; @@ -1915,18 +1908,3 @@ int32_t CPDFSDK_Widget::GetAppearanceAge() const { int32_t CPDFSDK_Widget::GetValueAge() const { return m_nValueAge; } - -bool CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY) { - CPDF_Annot* pAnnot = GetPDFAnnot(); - CFX_FloatRect annotRect = pAnnot->GetRect(); - if (!annotRect.Contains(pageX, pageY)) - return false; - - if (!IsVisible()) - return false; - - if ((GetFieldFlags() & FIELDFLAG_READONLY) == FIELDFLAG_READONLY) - return false; - - return true; -} diff --git a/fpdfsdk/cpdfsdk_widget.h b/fpdfsdk/cpdfsdk_widget.h index 69114d129..21e516970 100644 --- a/fpdfsdk/cpdfsdk_widget.h +++ b/fpdfsdk/cpdfsdk_widget.h @@ -138,8 +138,6 @@ class CPDFSDK_Widget : public CPDFSDK_BAAnnot { CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions) override; - bool HitTest(FX_FLOAT pageX, FX_FLOAT pageY); - private: void ResetAppearance_PushButton(); void ResetAppearance_CheckBox(); diff --git a/fpdfsdk/cpdfsdk_widgethandler.cpp b/fpdfsdk/cpdfsdk_widgethandler.cpp index 4105ae4f3..e85d24c4e 100644 --- a/fpdfsdk/cpdfsdk_widgethandler.cpp +++ b/fpdfsdk/cpdfsdk_widgethandler.cpp @@ -119,7 +119,7 @@ void CPDFSDK_WidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point); @@ -129,7 +129,7 @@ bool CPDFSDK_WidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point); @@ -139,7 +139,7 @@ bool CPDFSDK_WidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point); @@ -149,7 +149,7 @@ bool CPDFSDK_WidgetHandler::OnLButtonDblClk(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point); @@ -160,7 +160,7 @@ bool CPDFSDK_WidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point); @@ -171,7 +171,7 @@ bool CPDFSDK_WidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point); @@ -181,7 +181,7 @@ bool CPDFSDK_WidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!(*pAnnot)->IsSignatureWidget() && m_pFormFiller) return m_pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point); @@ -191,7 +191,7 @@ bool CPDFSDK_WidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { return false; } @@ -279,10 +279,8 @@ CFX_FloatRect CPDFSDK_WidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, bool CPDFSDK_WidgetHandler::HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(pPageView); ASSERT(pAnnot); - - CFX_FloatRect rect = GetViewBBox(pPageView, pAnnot); - return rect.Contains(point.x, point.y); + return GetViewBBox(pPageView, pAnnot).Contains(point); } diff --git a/fpdfsdk/cpdfsdk_widgethandler.h b/fpdfsdk/cpdfsdk_widgethandler.h index 7154bda6f..6e4d50b27 100644 --- a/fpdfsdk/cpdfsdk_widgethandler.h +++ b/fpdfsdk/cpdfsdk_widgethandler.h @@ -39,7 +39,7 @@ class CPDFSDK_WidgetHandler : public IPDFSDK_AnnotHandler { CPDFSDK_Annot* pAnnot) override; bool HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; void OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, @@ -56,36 +56,36 @@ class CPDFSDK_WidgetHandler : public IPDFSDK_AnnotHandler { bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override; bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override; bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override; diff --git a/fpdfsdk/cpdfsdk_xfawidget.cpp b/fpdfsdk/cpdfsdk_xfawidget.cpp index 67a8a17df..b30e5f3ac 100644 --- a/fpdfsdk/cpdfsdk_xfawidget.cpp +++ b/fpdfsdk/cpdfsdk_xfawidget.cpp @@ -29,8 +29,7 @@ CPDF_Annot::Subtype CPDFSDK_XFAWidget::GetAnnotSubtype() const { } CFX_FloatRect CPDFSDK_XFAWidget::GetRect() const { - CFX_RectF rcBBox; - GetXFAWidget()->GetRect(rcBBox); + CFX_RectF rcBBox = GetXFAWidget()->GetRect(false); return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, rcBBox.top + rcBBox.height); } diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp index eff351b55..653eb8ae4 100644 --- a/fpdfsdk/cpdfsdk_xfawidgethandler.cpp +++ b/fpdfsdk/cpdfsdk_xfawidgethandler.cpp @@ -53,12 +53,9 @@ void CPDFSDK_XFAWidgetHandler::OnDraw(CPDFSDK_PageView* pPageView, ASSERT(pPageView); ASSERT(pAnnot); - CFX_Graphics gs; - gs.Create(pDevice); - - CFX_Matrix mt; - mt = *pUser2Device; + CFX_Graphics gs(pDevice); + CFX_Matrix mt = *pUser2Device; bool bIsHighlight = false; if (pPageView->GetFormFillEnv()->GetFocusAnnot() != pAnnot) bIsHighlight = true; @@ -86,9 +83,9 @@ CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, CFX_RectF rcBBox; XFA_Element eType = pAnnot->GetXFAWidget()->GetDataAcc()->GetUIType(); if (eType == XFA_Element::Signature) - pAnnot->GetXFAWidget()->GetBBox(rcBBox, XFA_WidgetStatus_Visible, true); + rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_Visible, true); else - pAnnot->GetXFAWidget()->GetBBox(rcBBox, XFA_WidgetStatus_None); + rcBBox = pAnnot->GetXFAWidget()->GetBBox(XFA_WidgetStatus_None); CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, rcBBox.top + rcBBox.height); @@ -102,7 +99,7 @@ CFX_FloatRect CPDFSDK_XFAWidgetHandler::GetViewBBox(CPDFSDK_PageView* pPageView, bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !pAnnot) return false; @@ -123,7 +120,7 @@ bool CPDFSDK_XFAWidgetHandler::HitTest(CPDFSDK_PageView* pPageView, return false; FWL_WidgetHit dwHitTest = - pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point.x, point.y); + pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point); return dwHitTest != FWL_WidgetHit::Unknown; } @@ -149,100 +146,100 @@ void CPDFSDK_XFAWidgetHandler::OnMouseExit(CPDFSDK_PageView* pPageView, bool CPDFSDK_XFAWidgetHandler::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnLButtonDown((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnLButtonUp((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnLButtonDblClk( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnLButtonDblClk((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnMouseMove((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); - return pWidgetHandler->OnMouseWheel( - (*pAnnot)->GetXFAWidget(), GetFWLFlags(nFlags), zDelta, point.x, point.y); + return pWidgetHandler->OnMouseWheel((*pAnnot)->GetXFAWidget(), + GetFWLFlags(nFlags), zDelta, point); } bool CPDFSDK_XFAWidgetHandler::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnRButtonDown((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnRButtonUp((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnRButtonDblClk( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!pPageView || !(*pAnnot)) return false; CXFA_FFWidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot->Get()); return pWidgetHandler->OnRButtonDblClk((*pAnnot)->GetXFAWidget(), - GetFWLFlags(nFlags), point.x, point.y); + GetFWLFlags(nFlags), point); } bool CPDFSDK_XFAWidgetHandler::OnChar(CPDFSDK_Annot* pAnnot, diff --git a/fpdfsdk/cpdfsdk_xfawidgethandler.h b/fpdfsdk/cpdfsdk_xfawidgethandler.h index 1a1a48081..3903103ee 100644 --- a/fpdfsdk/cpdfsdk_xfawidgethandler.h +++ b/fpdfsdk/cpdfsdk_xfawidgethandler.h @@ -34,7 +34,7 @@ class CPDFSDK_XFAWidgetHandler : public IPDFSDK_AnnotHandler { CPDFSDK_Annot* pAnnot) override; bool HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; void OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, @@ -50,36 +50,36 @@ class CPDFSDK_XFAWidgetHandler : public IPDFSDK_AnnotHandler { bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) override; bool OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override; bool OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag) override; diff --git a/fpdfsdk/formfiller/cffl_checkbox.cpp b/fpdfsdk/formfiller/cffl_checkbox.cpp index ffa3a032c..c233c136c 100644 --- a/fpdfsdk/formfiller/cffl_checkbox.cpp +++ b/fpdfsdk/formfiller/cffl_checkbox.cpp @@ -73,7 +73,7 @@ bool CFFL_CheckBox::OnChar(CPDFSDK_Annot* pAnnot, bool CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point); if (IsValid()) { diff --git a/fpdfsdk/formfiller/cffl_checkbox.h b/fpdfsdk/formfiller/cffl_checkbox.h index 65dba29f2..79ddc847c 100644 --- a/fpdfsdk/formfiller/cffl_checkbox.h +++ b/fpdfsdk/formfiller/cffl_checkbox.h @@ -24,7 +24,7 @@ class CFFL_CheckBox : public CFFL_Button { bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool IsDataChanged(CPDFSDK_PageView* pPageView) override; void SaveData(CPDFSDK_PageView* pPageView) override; }; diff --git a/fpdfsdk/formfiller/cffl_formfiller.cpp b/fpdfsdk/formfiller/cffl_formfiller.cpp index 281057a6a..da6f9208e 100644 --- a/fpdfsdk/formfiller/cffl_formfiller.cpp +++ b/fpdfsdk/formfiller/cffl_formfiller.cpp @@ -119,13 +119,12 @@ void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView* pPageView, bool CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true)) { m_bValid = true; FX_RECT rect = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rect.left, rect.top, rect.right, rect.bottom); - - if (!rect.Contains((int)point.x, (int)point.y)) + InvalidateRect(rect); + if (!rect.Contains(static_cast<int>(point.x), static_cast<int>(point.y))) return false; return pWnd->OnLButtonDown(WndtoPWL(pPageView, point), nFlags); @@ -137,13 +136,12 @@ bool CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView, bool CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false); if (!pWnd) return false; - FX_RECT rcFFL = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom); + InvalidateRect(GetViewBBox(pPageView, pAnnot)); pWnd->OnLButtonUp(WndtoPWL(pPageView, point), nFlags); return true; } @@ -151,7 +149,7 @@ bool CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, bool CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false); if (!pWnd) return false; @@ -163,7 +161,7 @@ bool CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView, bool CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (m_ptOldPos != point) m_ptOldPos = point; @@ -179,7 +177,7 @@ bool CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { if (!IsValid()) return false; @@ -190,7 +188,7 @@ bool CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView, bool CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true); if (!pWnd) return false; @@ -202,7 +200,7 @@ bool CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView, bool CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { CPWL_Wnd* pWnd = GetPDFWindow(pPageView, false); if (!pWnd) return false; @@ -249,8 +247,7 @@ void CFFL_FormFiller::SetFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) { pWnd->SetFocus(); m_bValid = true; - FX_RECT rcRect = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom); + InvalidateRect(GetViewBBox(pPageView, pAnnot)); } void CFFL_FormFiller::KillFocusForAnnot(CPDFSDK_Annot* pAnnot, uint32_t nFlag) { @@ -395,6 +392,7 @@ CFX_Matrix CFFL_FormFiller::GetWindowMatrix(void* pAttachedData) { if (pPrivateData->pPageView) { CFX_Matrix mtPageView; pPrivateData->pPageView->GetCurrentMatrix(mtPageView); + CFX_Matrix mt = GetCurMatrix(); mt.Concat(mtPageView); @@ -482,27 +480,18 @@ CFX_FloatRect CFFL_FormFiller::PWLtoFFL(const CFX_FloatRect& rect) { return temp; } -CFX_FloatPoint CFFL_FormFiller::FFLtoPWL(const CFX_FloatPoint& point) { +CFX_PointF CFFL_FormFiller::FFLtoPWL(const CFX_PointF& point) { CFX_Matrix mt; mt.SetReverse(GetCurMatrix()); - - CFX_FloatPoint pt = point; - mt.Transform(pt.x, pt.y); - - return pt; + return mt.Transform(point); } -CFX_FloatPoint CFFL_FormFiller::PWLtoFFL(const CFX_FloatPoint& point) { - CFX_Matrix mt = GetCurMatrix(); - - CFX_FloatPoint pt = point; - mt.Transform(pt.x, pt.y); - - return pt; +CFX_PointF CFFL_FormFiller::PWLtoFFL(const CFX_PointF& point) { + return GetCurMatrix().Transform(point); } -CFX_FloatPoint CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView, - const CFX_FloatPoint& pt) { +CFX_PointF CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView, + const CFX_PointF& pt) { return FFLtoPWL(pt); } @@ -593,19 +582,13 @@ void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView, bool bDestroyPDFWindow) { m_bValid = false; - FX_RECT rcRect = GetViewBBox(pPageView, m_pWidget); - InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom); - + InvalidateRect(GetViewBBox(pPageView, m_pWidget)); if (bDestroyPDFWindow) DestroyPDFWindow(pPageView); } -void CFFL_FormFiller::InvalidateRect(double left, - double top, - double right, - double bottom) { - UnderlyingPageType* pPage = m_pWidget->GetUnderlyingPage(); - m_pFormFillEnv->Invalidate(pPage, left, top, right, bottom); +void CFFL_FormFiller::InvalidateRect(const FX_RECT& rect) { + m_pFormFillEnv->Invalidate(m_pWidget->GetUnderlyingPage(), rect); } CFFL_Button::CFFL_Button(CPDFSDK_FormFillEnvironment* pApp, @@ -617,16 +600,14 @@ CFFL_Button::~CFFL_Button() {} void CFFL_Button::OnMouseEnter(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) { m_bMouseIn = true; - FX_RECT rect = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rect.left, rect.top, rect.right, rect.bottom); + InvalidateRect(GetViewBBox(pPageView, pAnnot)); } void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot) { m_bMouseIn = false; - FX_RECT rect = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rect.left, rect.top, rect.right, rect.bottom); + InvalidateRect(GetViewBBox(pPageView, pAnnot)); EndTimer(); ASSERT(m_pWidget); } @@ -634,40 +615,35 @@ void CFFL_Button::OnMouseExit(CPDFSDK_PageView* pPageView, bool CFFL_Button::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { - CFX_FloatRect rcAnnot = pAnnot->GetRect(); - if (!rcAnnot.Contains(point.x, point.y)) + const CFX_PointF& point) { + if (!pAnnot->GetRect().Contains(point)) return false; m_bMouseDown = true; m_bValid = true; - FX_RECT rect = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rect.left, rect.top, rect.right, rect.bottom); + InvalidateRect(GetViewBBox(pPageView, pAnnot)); return true; } bool CFFL_Button::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { - CFX_FloatRect rcAnnot = pAnnot->GetRect(); - if (!rcAnnot.Contains(point.x, point.y)) + const CFX_PointF& point) { + if (!pAnnot->GetRect().Contains(point)) return false; m_bMouseDown = false; m_pWidget->GetPDFPage(); - FX_RECT rect = GetViewBBox(pPageView, pAnnot); - InvalidateRect(rect.left, rect.top, rect.right, rect.bottom); + InvalidateRect(GetViewBBox(pPageView, pAnnot)); return true; } bool CFFL_Button::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT(m_pFormFillEnv); - return true; } diff --git a/fpdfsdk/formfiller/cffl_formfiller.h b/fpdfsdk/formfiller/cffl_formfiller.h index cf1aaf720..c6b1e5978 100644 --- a/fpdfsdk/formfiller/cffl_formfiller.h +++ b/fpdfsdk/formfiller/cffl_formfiller.h @@ -41,32 +41,32 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler { virtual bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); virtual bool OnKeyDown(CPDFSDK_Annot* pAnnot, uint32_t nKeyCode, @@ -104,11 +104,10 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler { CFX_FloatRect FFLtoPWL(const CFX_FloatRect& rect); CFX_FloatRect PWLtoFFL(const CFX_FloatRect& rect); - CFX_FloatPoint FFLtoPWL(const CFX_FloatPoint& point); - CFX_FloatPoint PWLtoFFL(const CFX_FloatPoint& point); + CFX_PointF FFLtoPWL(const CFX_PointF& point); + CFX_PointF PWLtoFFL(const CFX_PointF& point); - CFX_FloatPoint WndtoPWL(CPDFSDK_PageView* pPageView, - const CFX_FloatPoint& pt); + CFX_PointF WndtoPWL(CPDFSDK_PageView* pPageView, const CFX_PointF& pt); CFX_FloatRect FFLtoWnd(CPDFSDK_PageView* pPageView, const CFX_FloatRect& rect); @@ -139,10 +138,7 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler { CPDFSDK_PageView* GetCurPageView(bool renew); void SetChangeMark(); - virtual void InvalidateRect(double left, - double top, - double right, - double bottom); + virtual void InvalidateRect(const FX_RECT& rect); CPDFSDK_Annot* GetSDKAnnot() { return m_pAnnot; } protected: @@ -159,10 +155,9 @@ class CFFL_FormFiller : public IPWL_Provider, public CPWL_TimerHandler { CPDFSDK_FormFillEnvironment* m_pFormFillEnv; CPDFSDK_Widget* m_pWidget; CPDFSDK_Annot* m_pAnnot; - bool m_bValid; CFFL_PageView2PDFWindow m_Maps; - CFX_FloatPoint m_ptOldPos; + CFX_PointF m_ptOldPos; }; class CFFL_Button : public CFFL_FormFiller { @@ -178,15 +173,15 @@ class CFFL_Button : public CFFL_FormFiller { bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; void OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp index 01009d25f..a830d529c 100644 --- a/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp +++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.cpp @@ -34,9 +34,8 @@ CFFL_InteractiveFormFiller::~CFFL_InteractiveFormFiller() {} bool CFFL_InteractiveFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - CFX_FloatPoint point) { - CFX_FloatRect rc = pAnnot->GetRect(); - return rc.Contains(point.x, point.y); + const CFX_PointF& point) { + return pAnnot->GetRect().Contains(point); } FX_RECT CFFL_InteractiveFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView, @@ -70,12 +69,16 @@ void CFFL_InteractiveFormFiller::OnDraw(CPDFSDK_PageView* pPageView, CFX_FloatRect rcFocus = pFormFiller->GetFocusBox(pPageView); if (!rcFocus.IsEmpty()) { CFX_PathData path; - path.SetPointCount(5); - path.SetPoint(0, rcFocus.left, rcFocus.top, FXPT_MOVETO); - path.SetPoint(1, rcFocus.left, rcFocus.bottom, FXPT_LINETO); - path.SetPoint(2, rcFocus.right, rcFocus.bottom, FXPT_LINETO); - path.SetPoint(3, rcFocus.right, rcFocus.top, FXPT_LINETO); - path.SetPoint(4, rcFocus.left, rcFocus.top, FXPT_LINETO); + path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.top), + FXPT_TYPE::MoveTo, false); + path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.bottom), + FXPT_TYPE::LineTo, false); + path.AppendPoint(CFX_PointF(rcFocus.right, rcFocus.bottom), + FXPT_TYPE::LineTo, false); + path.AppendPoint(CFX_PointF(rcFocus.right, rcFocus.top), + FXPT_TYPE::LineTo, false); + path.AppendPoint(CFX_PointF(rcFocus.left, rcFocus.top), + FXPT_TYPE::LineTo, false); CFX_GraphStateData gsd; gsd.SetDashCount(1); @@ -176,7 +179,7 @@ bool CFFL_InteractiveFormFiller::OnLButtonDown( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); if (!m_bNotifying) { CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get()); @@ -217,7 +220,7 @@ bool CFFL_InteractiveFormFiller::OnLButtonDown( bool CFFL_InteractiveFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CPDFSDK_Widget* pWidget = static_cast<CPDFSDK_Widget*>(pAnnot->Get()); @@ -291,7 +294,7 @@ bool CFFL_InteractiveFormFiller::OnLButtonDblClk( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false); return pFormFiller && @@ -301,7 +304,7 @@ bool CFFL_InteractiveFormFiller::OnLButtonDblClk( bool CFFL_InteractiveFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), true); return pFormFiller && @@ -313,7 +316,7 @@ bool CFFL_InteractiveFormFiller::OnMouseWheel( CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false); return pFormFiller && @@ -325,7 +328,7 @@ bool CFFL_InteractiveFormFiller::OnRButtonDown( CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false); return pFormFiller && @@ -335,7 +338,7 @@ bool CFFL_InteractiveFormFiller::OnRButtonDown( bool CFFL_InteractiveFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { ASSERT((*pAnnot)->GetPDFAnnot()->GetSubtype() == CPDF_Annot::Subtype::WIDGET); CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot->Get(), false); return pFormFiller && diff --git a/fpdfsdk/formfiller/cffl_interactiveformfiller.h b/fpdfsdk/formfiller/cffl_interactiveformfiller.h index e81d3c88d..90fd98c0e 100644 --- a/fpdfsdk/formfiller/cffl_interactiveformfiller.h +++ b/fpdfsdk/formfiller/cffl_interactiveformfiller.h @@ -27,7 +27,7 @@ class CFFL_InteractiveFormFiller : public IPWL_Filler_Notify { bool Annot_HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - CFX_FloatPoint point); + const CFX_PointF& point); FX_RECT GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot); void OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, @@ -45,32 +45,32 @@ class CFFL_InteractiveFormFiller : public IPWL_Filler_Notify { bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point); + const CFX_PointF& point); bool OnKeyDown(CPDFSDK_Annot* pAnnot, uint32_t nKeyCode, uint32_t nFlags); bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags); diff --git a/fpdfsdk/formfiller/cffl_listbox.cpp b/fpdfsdk/formfiller/cffl_listbox.cpp index bc3bb6c4a..556e0e17d 100644 --- a/fpdfsdk/formfiller/cffl_listbox.cpp +++ b/fpdfsdk/formfiller/cffl_listbox.cpp @@ -167,20 +167,25 @@ void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView) { ASSERT(pPageView); - if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, false)) { - for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) { - if (pListBox->IsItemSelected(i)) { - m_State.Add(i); - } - } + CPWL_ListBox* pListBox = + static_cast<CPWL_ListBox*>(GetPDFWindow(pPageView, false)); + if (!pListBox) + return; + + for (int32_t i = 0, sz = pListBox->GetCount(); i < sz; i++) { + if (pListBox->IsItemSelected(i)) + m_State.push_back(i); } } void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView) { - if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, false)) { - for (int i = 0, sz = m_State.GetSize(); i < sz; i++) - pListBox->Select(m_State[i]); - } + CPWL_ListBox* pListBox = + static_cast<CPWL_ListBox*>(GetPDFWindow(pPageView, false)); + if (!pListBox) + return; + + for (const auto& item : m_State) + pListBox->Select(item); } CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, diff --git a/fpdfsdk/formfiller/cffl_listbox.h b/fpdfsdk/formfiller/cffl_listbox.h index e97ede0de..609f2c480 100644 --- a/fpdfsdk/formfiller/cffl_listbox.h +++ b/fpdfsdk/formfiller/cffl_listbox.h @@ -9,6 +9,7 @@ #include <memory> #include <set> +#include <vector> #include "fpdfsdk/formfiller/cffl_formfiller.h" @@ -37,7 +38,7 @@ class CFFL_ListBox : public CFFL_FormFiller { private: std::unique_ptr<CBA_FontMap> m_pFontMap; std::set<int> m_OriginSelections; - CFX_ArrayTemplate<int> m_State; + std::vector<int> m_State; }; #endif // FPDFSDK_FORMFILLER_CFFL_LISTBOX_H_ diff --git a/fpdfsdk/formfiller/cffl_radiobutton.cpp b/fpdfsdk/formfiller/cffl_radiobutton.cpp index 70d4c0dee..e78160e5d 100644 --- a/fpdfsdk/formfiller/cffl_radiobutton.cpp +++ b/fpdfsdk/formfiller/cffl_radiobutton.cpp @@ -72,7 +72,7 @@ bool CFFL_RadioButton::OnChar(CPDFSDK_Annot* pAnnot, bool CFFL_RadioButton::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) { + const CFX_PointF& point) { CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point); if (IsValid()) { diff --git a/fpdfsdk/formfiller/cffl_radiobutton.h b/fpdfsdk/formfiller/cffl_radiobutton.h index 49a658f84..10ac37dcb 100644 --- a/fpdfsdk/formfiller/cffl_radiobutton.h +++ b/fpdfsdk/formfiller/cffl_radiobutton.h @@ -24,7 +24,7 @@ class CFFL_RadioButton : public CFFL_Button { bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) override; + const CFX_PointF& point) override; bool IsDataChanged(CPDFSDK_PageView* pPageView) override; void SaveData(CPDFSDK_PageView* pPageView) override; }; diff --git a/fpdfsdk/formfiller/cffl_textfield.cpp b/fpdfsdk/formfiller/cffl_textfield.cpp index c1cd7868c..91db0959d 100644 --- a/fpdfsdk/formfiller/cffl_textfield.cpp +++ b/fpdfsdk/formfiller/cffl_textfield.cpp @@ -114,9 +114,8 @@ bool CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, CPDFSDK_PageView* pPageView = GetCurPageView(true); ASSERT(pPageView); m_bValid = !m_bValid; - CFX_FloatRect rcAnnot = pAnnot->GetRect(); - m_pFormFillEnv->Invalidate(pAnnot->GetUnderlyingPage(), rcAnnot.left, - rcAnnot.top, rcAnnot.right, rcAnnot.bottom); + m_pFormFillEnv->Invalidate(pAnnot->GetUnderlyingPage(), + pAnnot->GetRect().ToFxRect()); if (m_bValid) { if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, true)) diff --git a/fpdfsdk/fpdf_structtree.cpp b/fpdfsdk/fpdf_structtree.cpp index 9bc1df66f..5a922a1c3 100644 --- a/fpdfsdk/fpdf_structtree.cpp +++ b/fpdfsdk/fpdf_structtree.cpp @@ -4,6 +4,8 @@ #include "public/fpdf_structtree.h" +#include <memory> + #include "core/fpdfapi/page/cpdf_page.h" #include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfdoc/fpdf_tagged.h" @@ -30,7 +32,7 @@ DLLEXPORT FPDF_STRUCTTREE STDCALL FPDF_StructTree_GetForPage(FPDF_PAGE page) { } DLLEXPORT void STDCALL FPDF_StructTree_Close(FPDF_STRUCTTREE struct_tree) { - delete ToStructTree(struct_tree); + std::unique_ptr<IPDF_StructTree>(ToStructTree(struct_tree)); } DLLEXPORT int STDCALL @@ -83,7 +85,5 @@ FPDF_StructElement_GetChildAtIndex(FPDF_STRUCTELEMENT struct_element, if (!elem || index < 0 || index >= elem->CountKids()) return nullptr; - CPDF_StructKid kid = elem->GetKid(index); - return kid.m_Type == CPDF_StructKid::Element ? kid.m_Element.m_pElement - : nullptr; + return elem->GetKidIfElement(index); } diff --git a/fpdfsdk/fpdf_transformpage.cpp b/fpdfsdk/fpdf_transformpage.cpp index 13d9756bd..3427f4ea5 100644 --- a/fpdfsdk/fpdf_transformpage.cpp +++ b/fpdfsdk/fpdf_transformpage.cpp @@ -6,6 +6,8 @@ #include "public/fpdf_transformpage.h" +#include <vector> + #include "core/fpdfapi/page/cpdf_clippath.h" #include "core/fpdfapi/page/cpdf_page.h" #include "core/fpdfapi/page/cpdf_pageobject.h" @@ -235,35 +237,34 @@ void OutputPath(CFX_ByteTextBuf& buf, CPDF_Path path) { if (!pPathData) return; - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - + const std::vector<FX_PATHPOINT>& pPoints = pPathData->GetPoints(); if (path.IsRect()) { - buf << (pPoints[0].m_PointX) << " " << (pPoints[0].m_PointY) << " " - << (pPoints[2].m_PointX - pPoints[0].m_PointX) << " " - << (pPoints[2].m_PointY - pPoints[0].m_PointY) << " re\n"; + CFX_PointF diff = pPoints[2].m_Point - pPoints[0].m_Point; + buf << pPoints[0].m_Point.x << " " << pPoints[0].m_Point.y << " " << diff.x + << " " << diff.y << " re\n"; return; } CFX_ByteString temp; - for (int i = 0; i < pPathData->GetPointCount(); i++) { - buf << (pPoints[i].m_PointX) << " " << (pPoints[i].m_PointY); - int point_type = pPoints[i].m_Flag & FXPT_TYPE; - if (point_type == FXPT_MOVETO) { + for (size_t i = 0; i < pPoints.size(); i++) { + buf << pPoints[i].m_Point.x << " " << pPoints[i].m_Point.y; + FXPT_TYPE point_type = pPoints[i].m_Type; + if (point_type == FXPT_TYPE::MoveTo) { buf << " m\n"; - } else if (point_type == FXPT_BEZIERTO) { - buf << " " << (pPoints[i + 1].m_PointX) << " " - << (pPoints[i + 1].m_PointY) << " " << (pPoints[i + 2].m_PointX) - << " " << (pPoints[i + 2].m_PointY); - if (pPoints[i + 2].m_Flag & FXPT_CLOSEFIGURE) - buf << " c h\n"; - else - buf << " c\n"; + } else if (point_type == FXPT_TYPE::BezierTo) { + buf << " " << pPoints[i + 1].m_Point.x << " " << pPoints[i + 1].m_Point.y + << " " << pPoints[i + 2].m_Point.x << " " << pPoints[i + 2].m_Point.y; + buf << " c"; + if (pPoints[i + 2].m_CloseFigure) + buf << " h"; + buf << "\n"; + i += 2; - } else if (point_type == FXPT_LINETO) { - if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) - buf << " l h\n"; - else - buf << " l\n"; + } else if (point_type == FXPT_TYPE::LineTo) { + buf << " l"; + if (pPoints[i].m_CloseFigure) + buf << " h"; + buf << "\n"; } } } @@ -288,7 +289,7 @@ DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page, for (i = 0; i < pClipPath->GetPathCount(); i++) { CPDF_Path path = pClipPath->GetPath(i); int iClipType = pClipPath->GetClipType(i); - if (path.GetPointCount() == 0) { + if (path.GetPoints().empty()) { // Empty clipping (totally clipped out) strClip << "0 0 m W n "; } else { diff --git a/fpdfsdk/fpdfdoc.cpp b/fpdfsdk/fpdfdoc.cpp index 82b898aa8..f7d94c2f9 100644 --- a/fpdfsdk/fpdfdoc.cpp +++ b/fpdfsdk/fpdfdoc.cpp @@ -257,7 +257,10 @@ DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page, if (!pLinkList) return nullptr; - return pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, nullptr) + return pLinkList + ->GetLinkAtPoint( + pPage, CFX_PointF(static_cast<FX_FLOAT>(x), static_cast<FX_FLOAT>(y)), + nullptr) .GetDict(); } @@ -273,7 +276,9 @@ DLLEXPORT int STDCALL FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page, return -1; int z_order = -1; - pLinkList->GetLinkAtPoint(pPage, (FX_FLOAT)x, (FX_FLOAT)y, &z_order); + pLinkList->GetLinkAtPoint( + pPage, CFX_PointF(static_cast<FX_FLOAT>(x), static_cast<FX_FLOAT>(y)), + &z_order); return z_order; } diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp index 40bed3a56..53554a182 100644 --- a/fpdfsdk/fpdfedit_embeddertest.cpp +++ b/fpdfsdk/fpdfedit_embeddertest.cpp @@ -5,6 +5,13 @@ #include <memory> #include <string> +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_dictionary.h" +#include "core/fpdfapi/parser/cpdf_stream.h" +#include "core/fxcrt/fx_system.h" +#include "fpdfsdk/fsdk_define.h" #include "public/fpdf_edit.h" #include "public/fpdfview.h" #include "testing/embedder_test.h" @@ -140,16 +147,359 @@ TEST_F(FPDFEditEmbeddertest, RasterizePDF) { EXPECT_EQ(1, FPDF_GetPageCount(document_)); FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0); EXPECT_NE(nullptr, new_page); - int width = static_cast<int>(FPDF_GetPageWidth(new_page)); - int height = static_cast<int>(FPDF_GetPageHeight(new_page)); - int alpha = FPDFPage_HasTransparency(new_page) ? 1 : 0; - FPDF_BITMAP new_bitmap = FPDFBitmap_Create(width, height, alpha); - FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF; - FPDFBitmap_FillRect(new_bitmap, 0, 0, width, height, fill_color); - FPDF_RenderPageBitmap(new_bitmap, new_page, 0, 0, width, height, 0, 0); + FPDF_BITMAP new_bitmap = RenderPage(new_page); CompareBitmap(new_bitmap, 612, 792, kAllBlackMd5sum); FPDF_ClosePage(new_page); FPDF_CloseDocument(new_doc); FPDFBitmap_Destroy(new_bitmap); } } + +TEST_F(FPDFEditEmbeddertest, AddPaths) { + // Start with a blank page + FPDF_DOCUMENT doc = FPDF_CreateNewDocument(); + FPDF_PAGE page = FPDFPage_New(doc, 0, 612, 792); + + // We will first add a red rectangle + FPDF_PAGEOBJECT red_rect = FPDFPageObj_CreateNewRect(10, 10, 20, 20); + ASSERT_NE(nullptr, red_rect); + // Expect false when trying to set colors out of range + EXPECT_FALSE(FPDFPath_SetStrokeColor(red_rect, 100, 100, 100, 300)); + EXPECT_FALSE(FPDFPath_SetFillColor(red_rect, 200, 256, 200, 0)); + + // Fill rectangle with red and insert to the page + EXPECT_TRUE(FPDFPath_SetFillColor(red_rect, 255, 0, 0, 255)); + EXPECT_TRUE(FPDFPath_SetDrawMode(red_rect, FPDF_FILLMODE_ALTERNATE, 0)); + FPDFPage_InsertObject(page, red_rect); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + FPDF_BITMAP page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "66d02eaa6181e2c069ce2ea99beda497"); + FPDFBitmap_Destroy(page_bitmap); + + // Now add to that a green rectangle with some medium alpha + FPDF_PAGEOBJECT green_rect = FPDFPageObj_CreateNewRect(100, 100, 40, 40); + EXPECT_TRUE(FPDFPath_SetFillColor(green_rect, 0, 255, 0, 128)); + EXPECT_TRUE(FPDFPath_SetDrawMode(green_rect, FPDF_FILLMODE_WINDING, 0)); + FPDFPage_InsertObject(page, green_rect); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "7b0b87604594e773add528fae567a558"); + FPDFBitmap_Destroy(page_bitmap); + + // Add a black triangle. + FPDF_PAGEOBJECT black_path = FPDFPageObj_CreateNewPath(400, 100); + EXPECT_TRUE(FPDFPath_SetFillColor(black_path, 0, 0, 0, 200)); + EXPECT_TRUE(FPDFPath_SetDrawMode(black_path, FPDF_FILLMODE_ALTERNATE, 0)); + EXPECT_TRUE(FPDFPath_LineTo(black_path, 400, 200)); + EXPECT_TRUE(FPDFPath_LineTo(black_path, 300, 100)); + EXPECT_TRUE(FPDFPath_Close(black_path)); + FPDFPage_InsertObject(page, black_path); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "eadc8020a14dfcf091da2688733d8806"); + FPDFBitmap_Destroy(page_bitmap); + + // Now add a more complex blue path. + FPDF_PAGEOBJECT blue_path = FPDFPageObj_CreateNewPath(200, 200); + EXPECT_TRUE(FPDFPath_SetFillColor(blue_path, 0, 0, 255, 255)); + EXPECT_TRUE(FPDFPath_SetDrawMode(blue_path, FPDF_FILLMODE_WINDING, 0)); + EXPECT_TRUE(FPDFPath_LineTo(blue_path, 230, 230)); + EXPECT_TRUE(FPDFPath_BezierTo(blue_path, 250, 250, 280, 280, 300, 300)); + EXPECT_TRUE(FPDFPath_LineTo(blue_path, 325, 325)); + EXPECT_TRUE(FPDFPath_LineTo(blue_path, 350, 325)); + EXPECT_TRUE(FPDFPath_BezierTo(blue_path, 375, 330, 390, 360, 400, 400)); + EXPECT_TRUE(FPDFPath_Close(blue_path)); + FPDFPage_InsertObject(page, blue_path); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "9823e1a21bd9b72b6a442ba4f12af946"); + FPDFBitmap_Destroy(page_bitmap); + + // Now save the result, closing the page and document + EXPECT_TRUE(FPDF_SaveAsCopy(doc, this, 0)); + FPDF_ClosePage(page); + FPDF_CloseDocument(doc); + std::string new_file = GetString(); + + // Render the saved result + FPDF_FILEACCESS file_access; + memset(&file_access, 0, sizeof(file_access)); + file_access.m_FileLen = new_file.size(); + file_access.m_GetBlock = GetBlockFromString; + file_access.m_Param = &new_file; + FPDF_DOCUMENT new_doc = FPDF_LoadCustomDocument(&file_access, nullptr); + ASSERT_NE(nullptr, new_doc); + EXPECT_EQ(1, FPDF_GetPageCount(new_doc)); + FPDF_PAGE new_page = FPDF_LoadPage(new_doc, 0); + ASSERT_NE(nullptr, new_page); + FPDF_BITMAP new_bitmap = RenderPage(new_page); + CompareBitmap(new_bitmap, 612, 792, "9823e1a21bd9b72b6a442ba4f12af946"); + FPDFBitmap_Destroy(new_bitmap); + FPDF_ClosePage(new_page); + FPDF_CloseDocument(new_doc); +} + +TEST_F(FPDFEditEmbeddertest, PathOnTopOfText) { + // Load document with some text + EXPECT_TRUE(OpenDocument("hello_world.pdf")); + FPDF_PAGE page = LoadPage(0); + EXPECT_NE(nullptr, page); + + // Add an opaque rectangle on top of some of the text. + FPDF_PAGEOBJECT red_rect = FPDFPageObj_CreateNewRect(20, 100, 50, 50); + EXPECT_TRUE(FPDFPath_SetFillColor(red_rect, 255, 0, 0, 255)); + EXPECT_TRUE(FPDFPath_SetDrawMode(red_rect, FPDF_FILLMODE_ALTERNATE, 0)); + FPDFPage_InsertObject(page, red_rect); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + + // Add a transparent triangle on top of other part of the text. + FPDF_PAGEOBJECT black_path = FPDFPageObj_CreateNewPath(20, 50); + EXPECT_TRUE(FPDFPath_SetFillColor(black_path, 0, 0, 0, 100)); + EXPECT_TRUE(FPDFPath_SetDrawMode(black_path, FPDF_FILLMODE_ALTERNATE, 0)); + EXPECT_TRUE(FPDFPath_LineTo(black_path, 30, 80)); + EXPECT_TRUE(FPDFPath_LineTo(black_path, 40, 10)); + EXPECT_TRUE(FPDFPath_Close(black_path)); + FPDFPage_InsertObject(page, black_path); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + + // Render and check the result. Text is slightly different on Mac. + FPDF_BITMAP bitmap = RenderPage(page); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5[] = "2f7c0deee10a9490538e195af64beb67"; +#else + const char md5[] = "17c942c76ff229200f2c98073bb60d85"; +#endif + CompareBitmap(bitmap, 200, 200, md5); + FPDFBitmap_Destroy(bitmap); + UnloadPage(page); +} + +TEST_F(FPDFEditEmbeddertest, AddStrokedPaths) { + // Start with a blank page + FPDF_DOCUMENT doc = FPDF_CreateNewDocument(); + FPDF_PAGE page = FPDFPage_New(doc, 0, 612, 792); + + // Add a large stroked rectangle (fill color should not affect it). + FPDF_PAGEOBJECT rect = FPDFPageObj_CreateNewRect(20, 20, 200, 400); + EXPECT_TRUE(FPDFPath_SetFillColor(rect, 255, 0, 0, 255)); + EXPECT_TRUE(FPDFPath_SetStrokeColor(rect, 0, 255, 0, 255)); + EXPECT_TRUE(FPDFPath_SetStrokeWidth(rect, 15.0f)); + EXPECT_TRUE(FPDFPath_SetDrawMode(rect, 0, 1)); + FPDFPage_InsertObject(page, rect); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + FPDF_BITMAP page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "64bd31f862a89e0a9e505a5af6efd506"); + FPDFBitmap_Destroy(page_bitmap); + + // Add crossed-checkmark + FPDF_PAGEOBJECT check = FPDFPageObj_CreateNewPath(300, 500); + EXPECT_TRUE(FPDFPath_LineTo(check, 400, 400)); + EXPECT_TRUE(FPDFPath_LineTo(check, 600, 600)); + EXPECT_TRUE(FPDFPath_MoveTo(check, 400, 600)); + EXPECT_TRUE(FPDFPath_LineTo(check, 600, 400)); + EXPECT_TRUE(FPDFPath_SetStrokeColor(check, 128, 128, 128, 180)); + EXPECT_TRUE(FPDFPath_SetStrokeWidth(check, 8.35f)); + EXPECT_TRUE(FPDFPath_SetDrawMode(check, 0, 1)); + FPDFPage_InsertObject(page, check); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "4b6f3b9d25c4e194821217d5016c3724"); + FPDFBitmap_Destroy(page_bitmap); + + // Add stroked and filled oval-ish path. + FPDF_PAGEOBJECT path = FPDFPageObj_CreateNewPath(250, 100); + EXPECT_TRUE(FPDFPath_BezierTo(path, 180, 166, 180, 233, 250, 300)); + EXPECT_TRUE(FPDFPath_LineTo(path, 255, 305)); + EXPECT_TRUE(FPDFPath_BezierTo(path, 325, 233, 325, 166, 255, 105)); + EXPECT_TRUE(FPDFPath_Close(path)); + EXPECT_TRUE(FPDFPath_SetFillColor(path, 200, 128, 128, 100)); + EXPECT_TRUE(FPDFPath_SetStrokeColor(path, 128, 200, 128, 150)); + EXPECT_TRUE(FPDFPath_SetStrokeWidth(path, 10.5f)); + EXPECT_TRUE(FPDFPath_SetDrawMode(path, FPDF_FILLMODE_ALTERNATE, 1)); + FPDFPage_InsertObject(page, path); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "ff3e6a22326754944cc6e56609acd73b"); + FPDFBitmap_Destroy(page_bitmap); + FPDF_ClosePage(page); + FPDF_CloseDocument(doc); +} + +TEST_F(FPDFEditEmbeddertest, AddStandardFontText) { + // Start with a blank page + FPDF_DOCUMENT doc = FPDF_CreateNewDocument(); + FPDF_PAGE page = FPDFPage_New(doc, 0, 612, 792); + + // Add some text to the page + FPDF_PAGEOBJECT text1 = FPDFPageObj_NewTextObj(doc, "Arial", 12.0f); + EXPECT_TRUE(text1); + EXPECT_TRUE(FPDFText_SetText(text1, "I'm at the bottom of the page")); + FPDFPageObj_Transform(text1, 1, 0, 0, 1, 20, 20); + FPDFPage_InsertObject(page, text1); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + FPDF_BITMAP page_bitmap = RenderPage(page); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5[] = "e19c90395d73cb9f37a6c3b0e8b18a9e"; +#else + const char md5[] = "7c3a36ba7cec01688a16a14bfed9ecfc"; +#endif + CompareBitmap(page_bitmap, 612, 792, md5); + FPDFBitmap_Destroy(page_bitmap); + + // Try another font + FPDF_PAGEOBJECT text2 = + FPDFPageObj_NewTextObj(doc, "TimesNewRomanBold", 15.0f); + EXPECT_TRUE(text2); + EXPECT_TRUE(FPDFText_SetText(text2, "Hi, I'm Bold. Times New Roman Bold.")); + FPDFPageObj_Transform(text2, 1, 0, 0, 1, 100, 600); + FPDFPage_InsertObject(page, text2); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5_2[] = "8e1c43dca6be68d364dbc283f5521041"; +#else + const char md5_2[] = "e0e0873e3a2634a6394a431a51ce90ff"; +#endif + CompareBitmap(page_bitmap, 612, 792, md5_2); + FPDFBitmap_Destroy(page_bitmap); + + // And some randomly transformed text + FPDF_PAGEOBJECT text3 = FPDFPageObj_NewTextObj(doc, "Courier-Bold", 20.0f); + EXPECT_TRUE(text3); + EXPECT_TRUE(FPDFText_SetText(text3, "Can you read me? <:)>")); + FPDFPageObj_Transform(text3, 1, 1.5, 2, 0.5, 200, 200); + FPDFPage_InsertObject(page, text3); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + page_bitmap = RenderPage(page); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5_3[] = "c6e5df448428793c7e4b0c820bd8c85e"; +#else + const char md5_3[] = "903ee10b6a9f0be51ecad0a1a0eeb171"; +#endif + CompareBitmap(page_bitmap, 612, 792, md5_3); + FPDFBitmap_Destroy(page_bitmap); + + // TODO(npm): Why are there issues with text rotated by 90 degrees? + // TODO(npm): FPDF_SaveAsCopy not giving the desired result after this. + FPDF_ClosePage(page); + FPDF_CloseDocument(doc); +} + +TEST_F(FPDFEditEmbeddertest, DoubleGenerating) { + // Start with a blank page + FPDF_DOCUMENT doc = FPDF_CreateNewDocument(); + FPDF_PAGE page = FPDFPage_New(doc, 0, 612, 792); + + // Add a red rectangle with some non-default alpha + FPDF_PAGEOBJECT rect = FPDFPageObj_CreateNewRect(10, 10, 100, 100); + EXPECT_TRUE(FPDFPath_SetFillColor(rect, 255, 0, 0, 128)); + EXPECT_TRUE(FPDFPath_SetDrawMode(rect, FPDF_FILLMODE_WINDING, 0)); + FPDFPage_InsertObject(page, rect); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + + // Check the ExtGState + CPDF_Page* the_page = CPDFPageFromFPDFPage(page); + CPDF_Dictionary* graphics_dict = + the_page->m_pResources->GetDictFor("ExtGState"); + ASSERT_TRUE(graphics_dict); + EXPECT_EQ(1, static_cast<int>(graphics_dict->GetCount())); + + // Check the bitmap + FPDF_BITMAP page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "5384da3406d62360ffb5cac4476fff1c"); + FPDFBitmap_Destroy(page_bitmap); + + // Never mind, my new favorite color is blue, increase alpha + EXPECT_TRUE(FPDFPath_SetFillColor(rect, 0, 0, 255, 180)); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount())); + + // Check that bitmap displays changed content + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "2e51656f5073b0bee611d9cd086aa09c"); + FPDFBitmap_Destroy(page_bitmap); + + // And now generate, without changes + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount())); + page_bitmap = RenderPage(page); + CompareBitmap(page_bitmap, 612, 792, "2e51656f5073b0bee611d9cd086aa09c"); + FPDFBitmap_Destroy(page_bitmap); + + // Add some text to the page + FPDF_PAGEOBJECT text = FPDFPageObj_NewTextObj(doc, "Arial", 12.0f); + EXPECT_TRUE(FPDFText_SetText(text, "Something something #text# something")); + FPDFPageObj_Transform(text, 1, 0, 0, 1, 300, 300); + FPDFPage_InsertObject(page, text); + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + CPDF_Dictionary* font_dict = the_page->m_pResources->GetDictFor("Font"); + ASSERT_TRUE(font_dict); + EXPECT_EQ(1, static_cast<int>(font_dict->GetCount())); + + // Generate yet again, check dicts are reasonably sized + EXPECT_TRUE(FPDFPage_GenerateContent(page)); + EXPECT_EQ(2, static_cast<int>(graphics_dict->GetCount())); + EXPECT_EQ(1, static_cast<int>(font_dict->GetCount())); + FPDF_ClosePage(page); + FPDF_CloseDocument(doc); +} + +TEST_F(FPDFEditEmbeddertest, Type1Font) { + // Create a new document + FPDF_DOCUMENT doc = FPDF_CreateNewDocument(); + CPDF_Document* document = reinterpret_cast<CPDF_Document*>(doc); + + // Get Times New Roman Bold as a Type 1 font + CPDF_Font* times_bold = CPDF_Font::GetStockFont(document, "Times-Bold"); + uint8_t* data = times_bold->m_Font.GetFontData(); + uint32_t size = times_bold->m_Font.GetSize(); + FPDF_FONT font = FPDFText_LoadType1Font(doc, data, size); + ASSERT_TRUE(font); + CPDF_Font* type1_font = reinterpret_cast<CPDF_Font*>(font); + EXPECT_TRUE(type1_font->IsType1Font()); + + // Check that the font dictionary has the required keys according to the spec + CPDF_Dictionary* font_dict = type1_font->GetFontDict(); + EXPECT_EQ("Font", font_dict->GetStringFor("Type")); + EXPECT_EQ("Type1", font_dict->GetStringFor("Subtype")); + EXPECT_EQ("Times New Roman Bold", font_dict->GetStringFor("BaseFont")); + ASSERT_TRUE(font_dict->KeyExist("FirstChar")); + ASSERT_TRUE(font_dict->KeyExist("LastChar")); + EXPECT_EQ(32, font_dict->GetIntegerFor("FirstChar")); + EXPECT_EQ(65532, font_dict->GetIntegerFor("LastChar")); + ASSERT_TRUE(font_dict->KeyExist("Widths")); + CPDF_Array* widths_array = font_dict->GetArrayFor("Widths"); + EXPECT_EQ(65501U, widths_array->GetCount()); + EXPECT_EQ(250, widths_array->GetNumberAt(0)); + EXPECT_EQ(0, widths_array->GetNumberAt(8172)); + EXPECT_EQ(1000, widths_array->GetNumberAt(65500)); + ASSERT_TRUE(font_dict->KeyExist("FontDescriptor")); + CPDF_Dictionary* font_desc = font_dict->GetDictFor("FontDescriptor"); + EXPECT_EQ("FontDescriptor", font_desc->GetStringFor("Type")); + EXPECT_EQ(font_dict->GetStringFor("BaseFont"), + font_desc->GetStringFor("FontName")); + + // Check that the font descriptor has the required keys according to the spec + ASSERT_TRUE(font_desc->KeyExist("Flags")); + int font_flags = font_desc->GetIntegerFor("Flags"); + EXPECT_TRUE(font_flags & FXFONT_BOLD); + EXPECT_TRUE(font_flags & FXFONT_NONSYMBOLIC); + ASSERT_TRUE(font_desc->KeyExist("FontBBox")); + EXPECT_EQ(4U, font_desc->GetArrayFor("FontBBox")->GetCount()); + EXPECT_TRUE(font_desc->KeyExist("ItalicAngle")); + EXPECT_TRUE(font_desc->KeyExist("Ascent")); + EXPECT_TRUE(font_desc->KeyExist("Descent")); + EXPECT_TRUE(font_desc->KeyExist("CapHeight")); + EXPECT_TRUE(font_desc->KeyExist("StemV")); + ASSERT_TRUE(font_desc->KeyExist("FontFile")); + + // Check that the font stream is the one that was provided + CPDF_Stream* font_stream = font_desc->GetStreamFor("FontFile"); + ASSERT_EQ(size, font_stream->GetRawSize()); + uint8_t* stream_data = font_stream->GetRawData(); + for (size_t i = 0; i < size; i++) + EXPECT_EQ(data[i], stream_data[i]); + + // Close document + FPDF_CloseDocument(doc); +} diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp index 18a1d6179..63740ba08 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -289,7 +289,7 @@ DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page, CFX_FloatRect rect = pAnnot->GetRect(); // transformAnnots Rectangle CFX_Matrix matrix((FX_FLOAT)a, (FX_FLOAT)b, (FX_FLOAT)c, (FX_FLOAT)d, (FX_FLOAT)e, (FX_FLOAT)f); - rect.Transform(&matrix); + matrix.TransformRect(rect); CPDF_Array* pRectArray = pAnnot->GetAnnotDict()->GetArrayFor("Rect"); if (!pRectArray) diff --git a/fpdfsdk/fpdfeditpath.cpp b/fpdfsdk/fpdfeditpath.cpp new file mode 100644 index 000000000..074f083bb --- /dev/null +++ b/fpdfsdk/fpdfeditpath.cpp @@ -0,0 +1,132 @@ +// Copyright 2017 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 "public/fpdf_edit.h" + +#include "core/fpdfapi/page/cpdf_path.h" +#include "core/fpdfapi/page/cpdf_pathobject.h" +#include "core/fxcrt/fx_system.h" + +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewPath(float x, float y) { + CPDF_PathObject* pPathObj = new CPDF_PathObject; + pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::MoveTo, false); + pPathObj->DefaultStates(); + return pPathObj; +} + +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewRect(float x, + float y, + float w, + float h) { + CPDF_PathObject* pPathObj = new CPDF_PathObject; + pPathObj->m_Path.AppendRect(x, y, x + w, y + h); + pPathObj->DefaultStates(); + return pPathObj; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A) { + if (!path || R > 255 || G > 255 || B > 255 || A > 255) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + pPathObj->m_GeneralState.SetStrokeAlpha(A / 255.f); + FX_FLOAT rgb[3] = {R / 255.f, G / 255.f, B / 255.f}; + pPathObj->m_ColorState.SetStrokeColor( + CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width) { + if (!path || width < 0.0f) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + pPathObj->m_GraphState.SetLineWidth(width); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetFillColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A) { + if (!path || R > 255 || G > 255 || B > 255 || A > 255) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + pPathObj->m_GeneralState.SetFillAlpha(A / 255.f); + FX_FLOAT rgb[3] = {R / 255.f, G / 255.f, B / 255.f}; + pPathObj->m_ColorState.SetFillColor( + CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_MoveTo(FPDF_PAGEOBJECT path, float x, float y) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::MoveTo, false); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_LineTo(FPDF_PAGEOBJECT path, float x, float y) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + pPathObj->m_Path.AppendPoint(CFX_PointF(x, y), FXPT_TYPE::LineTo, false); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_BezierTo(FPDF_PAGEOBJECT path, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + pPathObj->m_Path.AppendPoint(CFX_PointF(x1, y1), FXPT_TYPE::BezierTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(x2, y2), FXPT_TYPE::BezierTo, false); + pPathObj->m_Path.AppendPoint(CFX_PointF(x3, y3), FXPT_TYPE::BezierTo, false); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_Close(FPDF_PAGEOBJECT path) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + if (pPathObj->m_Path.GetPoints().empty()) + return false; + + pPathObj->m_Path.ClosePath(); + return true; +} + +DLLEXPORT FPDF_BOOL FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path, + int fillmode, + FPDF_BOOL stroke) { + if (!path) + return false; + + auto pPathObj = reinterpret_cast<CPDF_PathObject*>(path); + + if (fillmode == FPDF_FILLMODE_ALTERNATE) + pPathObj->m_FillType = FXFILL_ALTERNATE; + else if (fillmode == FPDF_FILLMODE_WINDING) + pPathObj->m_FillType = FXFILL_WINDING; + else + pPathObj->m_FillType = 0; + pPathObj->m_bStroke = stroke != 0; + return true; +} diff --git a/fpdfsdk/fpdfedittext.cpp b/fpdfsdk/fpdfedittext.cpp new file mode 100644 index 000000000..8bf0a0ac4 --- /dev/null +++ b/fpdfsdk/fpdfedittext.cpp @@ -0,0 +1,132 @@ +// Copyright 2017 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 <utility> + +#include "core/fpdfapi/cpdf_modulemgr.h" +#include "core/fpdfapi/font/cpdf_font.h" +#include "core/fpdfapi/font/cpdf_type1font.h" +#include "core/fpdfapi/page/cpdf_textobject.h" +#include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_dictionary.h" +#include "core/fpdfapi/parser/cpdf_document.h" +#include "core/fpdfapi/parser/cpdf_name.h" +#include "core/fpdfapi/parser/cpdf_number.h" +#include "core/fpdfapi/parser/cpdf_reference.h" +#include "core/fpdfapi/parser/cpdf_stream.h" +#include "core/fxge/cfx_fontmgr.h" +#include "core/fxge/fx_font.h" +#include "fpdfsdk/fsdk_define.h" +#include "public/fpdf_edit.h" + +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewTextObj(FPDF_DOCUMENT document, + FPDF_BYTESTRING font, + float font_size) { + CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); + if (!pDoc) + return nullptr; + + CPDF_Font* pFont = CPDF_Font::GetStockFont(pDoc, CFX_ByteStringC(font)); + if (!pFont) + return nullptr; + + CPDF_TextObject* pTextObj = new CPDF_TextObject; + pTextObj->m_TextState.SetFont(pFont); + pTextObj->m_TextState.SetFontSize(font_size); + pTextObj->DefaultStates(); + return pTextObj; +} + +DLLEXPORT FPDF_BOOL STDCALL FPDFText_SetText(FPDF_PAGEOBJECT text_object, + FPDF_BYTESTRING text) { + if (!text_object) + return false; + + auto pTextObj = reinterpret_cast<CPDF_TextObject*>(text_object); + pTextObj->SetText(CFX_ByteString(text)); + return true; +} + +DLLEXPORT FPDF_FONT STDCALL FPDFText_LoadType1Font(FPDF_DOCUMENT document, + const uint8_t* data, + uint32_t size) { + CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document); + if (!pDoc || !data || size == 0) + return nullptr; + + auto pFont = pdfium::MakeUnique<CFX_Font>(); + + // TODO(npm): Maybe use FT_Get_X11_Font_Format to check format? + if (!pFont->LoadEmbedded(data, size)) + return nullptr; + + CPDF_Dictionary* fontDict = pDoc->NewIndirect<CPDF_Dictionary>(); + fontDict->SetNewFor<CPDF_Name>("Type", "Font"); + fontDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); + CFX_ByteString name = pFont->GetFaceName(); + if (name.IsEmpty()) + name = "Unnamed"; + fontDict->SetNewFor<CPDF_Name>("BaseFont", name); + + uint32_t glyphIndex; + int currentChar = FXFT_Get_First_Char(pFont->GetFace(), &glyphIndex); + fontDict->SetNewFor<CPDF_Number>("FirstChar", currentChar); + int nextChar; + CPDF_Array* widthsArray = pDoc->NewIndirect<CPDF_Array>(); + while (true) { + int width = pFont->GetGlyphWidth(glyphIndex); + widthsArray->AddNew<CPDF_Number>(width); + nextChar = FXFT_Get_Next_Char(pFont->GetFace(), currentChar, &glyphIndex); + if (glyphIndex == 0) + break; + for (int i = currentChar + 1; i < nextChar; i++) + widthsArray->AddNew<CPDF_Number>(0); + currentChar = nextChar; + } + fontDict->SetNewFor<CPDF_Number>("LastChar", currentChar); + fontDict->SetNewFor<CPDF_Reference>("Widths", pDoc, widthsArray->GetObjNum()); + CPDF_Dictionary* fontDesc = pDoc->NewIndirect<CPDF_Dictionary>(); + fontDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor"); + fontDesc->SetNewFor<CPDF_Name>("FontName", name); + int flags = 0; + if (FXFT_Is_Face_fixedwidth(pFont->GetFace())) + flags |= FXFONT_FIXED_PITCH; + if (name.Find("Serif") > -1) + flags |= FXFONT_SERIF; + if (FXFT_Is_Face_Italic(pFont->GetFace())) + flags |= FXFONT_ITALIC; + if (FXFT_Is_Face_Bold(pFont->GetFace())) + flags |= FXFONT_BOLD; + + // TODO(npm): How do I know if a Type1 font is symbolic, script, allcap, + // smallcap + flags |= FXFONT_NONSYMBOLIC; + + fontDesc->SetNewFor<CPDF_Number>("Flags", flags); + FX_RECT bbox; + pFont->GetBBox(bbox); + auto pBBox = pdfium::MakeUnique<CPDF_Array>(); + pBBox->AddNew<CPDF_Number>(bbox.left); + pBBox->AddNew<CPDF_Number>(bbox.bottom); + pBBox->AddNew<CPDF_Number>(bbox.right); + pBBox->AddNew<CPDF_Number>(bbox.top); + fontDesc->SetFor("FontBBox", std::move(pBBox)); + + // TODO(npm): calculate italic angle correctly + fontDesc->SetNewFor<CPDF_Number>("ItalicAngle", pFont->IsItalic() ? -12 : 0); + + fontDesc->SetNewFor<CPDF_Number>("Ascent", pFont->GetAscent()); + fontDesc->SetNewFor<CPDF_Number>("Descent", pFont->GetDescent()); + + // TODO(npm): calculate the capheight, stemV correctly + fontDesc->SetNewFor<CPDF_Number>("CapHeight", pFont->GetAscent()); + fontDesc->SetNewFor<CPDF_Number>("StemV", pFont->IsBold() ? 120 : 70); + + CPDF_Stream* pStream = pDoc->NewIndirect<CPDF_Stream>(); + pStream->SetData(data, size); + fontDesc->SetNewFor<CPDF_Reference>("FontFile", pDoc, pStream->GetObjNum()); + fontDict->SetNewFor<CPDF_Reference>("FontDescriptor", pDoc, + fontDesc->GetObjNum()); + return pDoc->LoadFont(fontDict); +} diff --git a/fpdfsdk/fpdfformfill.cpp b/fpdfsdk/fpdfformfill.cpp index 6b8cbaa59..57ff6b669 100644 --- a/fpdfsdk/fpdfformfill.cpp +++ b/fpdfsdk/fpdfformfill.cpp @@ -98,9 +98,8 @@ void FFLCommon(FPDF_FORMHANDLE hHandle, return; #endif // PDF_ENABLE_XFA - CFX_Matrix matrix; - pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate); - + CFX_Matrix matrix = + pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); FX_RECT clip(start_x, start_y, start_x + size_x, start_y + size_y); std::unique_ptr<CFX_FxgeDevice> pDevice(new CFX_FxgeDevice); @@ -127,12 +126,13 @@ void FFLCommon(FPDF_FORMHANDLE hHandle, options.m_bDrawAnnots = flags & FPDF_ANNOT; #ifdef PDF_ENABLE_XFA - options.m_pOCContext = new CPDF_OCContext(pPDFDoc, CPDF_OCContext::View); + options.m_pOCContext = + pdfium::MakeRetain<CPDF_OCContext>(pPDFDoc, CPDF_OCContext::View); if (CPDFSDK_PageView* pPageView = pFormFillEnv->GetPageView(pPage, true)) pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options, clip); #else // PDF_ENABLE_XFA - options.m_pOCContext = - new CPDF_OCContext(pPage->m_pDocument, CPDF_OCContext::View); + options.m_pOCContext = pdfium::MakeRetain<CPDF_OCContext>( + pPage->m_pDocument, CPDF_OCContext::View); if (CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, pPage)) pPageView->PageView_OnDraw(pDevice.get(), &matrix, &options); #endif // PDF_ENABLE_XFA @@ -142,8 +142,6 @@ void FFLCommon(FPDF_FORMHANDLE hHandle, pDevice->Flush(); CFXBitmapFromFPDFBitmap(bitmap)->UnPreMultiply(); #endif - delete options.m_pOCContext; - options.m_pOCContext = nullptr; } } // namespace @@ -157,9 +155,10 @@ DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, CPDF_Page* pPage = CPDFPageFromFPDFPage(page); if (pPage) { CPDF_InterForm interform(pPage->m_pDocument); - CPDF_FormControl* pFormCtrl = - interform.GetControlAtPoint(pPage, static_cast<FX_FLOAT>(page_x), - static_cast<FX_FLOAT>(page_y), nullptr); + CPDF_FormControl* pFormCtrl = interform.GetControlAtPoint( + pPage, CFX_PointF(static_cast<FX_FLOAT>(page_x), + static_cast<FX_FLOAT>(page_y)), + nullptr); if (!pFormCtrl) return -1; CPDF_FormField* pFormField = pFormCtrl->GetField(); @@ -191,8 +190,7 @@ DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, CXFA_FFWidget* pXFAAnnot = pWidgetIterator->MoveToNext(); while (pXFAAnnot) { - CFX_RectF rcBBox; - pXFAAnnot->GetBBox(rcBBox, 0); + CFX_RectF rcBBox = pXFAAnnot->GetBBox(0); CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, rcBBox.top + rcBBox.height); rcWidget.left -= 1.0f; @@ -200,8 +198,8 @@ DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, rcWidget.bottom -= 1.0f; rcWidget.top += 1.0f; - if (rcWidget.Contains(static_cast<FX_FLOAT>(page_x), - static_cast<FX_FLOAT>(page_y))) { + if (rcWidget.Contains(CFX_PointF(static_cast<FX_FLOAT>(page_x), + static_cast<FX_FLOAT>(page_y)))) { return FPDF_FORMFIELD_XFA; } pXFAAnnot = pWidgetIterator->MoveToNext(); @@ -228,8 +226,10 @@ DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle, return -1; CPDF_InterForm interform(pPage->m_pDocument); int z_order = -1; - (void)interform.GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y, - &z_order); + (void)interform.GetControlAtPoint( + pPage, + CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y)), + &z_order); return z_order; } @@ -295,9 +295,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); if (!pPageView) return false; - - CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); - return pPageView->OnMouseMove(pt, modifier); + return pPageView->OnMouseMove(CFX_PointF(page_x, page_y), modifier); } DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, @@ -308,9 +306,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); if (!pPageView) return false; - - CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); - return pPageView->OnLButtonDown(pt, modifier); + return pPageView->OnLButtonDown(CFX_PointF(page_x, page_y), modifier); } DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, @@ -322,7 +318,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, if (!pPageView) return false; - CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); + CFX_PointF pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); return pPageView->OnLButtonUp(pt, modifier); } @@ -335,9 +331,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle, CPDFSDK_PageView* pPageView = FormHandleToPageView(hHandle, page); if (!pPageView) return false; - - CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); - return pPageView->OnRButtonDown(pt, modifier); + return pPageView->OnRButtonDown(CFX_PointF(page_x, page_y), modifier); } DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, @@ -349,7 +343,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, if (!pPageView) return false; - CFX_FloatPoint pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); + CFX_PointF pt((FX_FLOAT)page_x, (FX_FLOAT)page_y); return pPageView->OnRButtonUp(pt, modifier); } #endif // PDF_ENABLE_XFA diff --git a/fpdfsdk/fpdftext.cpp b/fpdfsdk/fpdftext.cpp index 629e596c8..0432afd70 100644 --- a/fpdfsdk/fpdftext.cpp +++ b/fpdfsdk/fpdftext.cpp @@ -133,8 +133,10 @@ DLLEXPORT int STDCALL FPDFText_GetCharIndexAtPos(FPDF_TEXTPAGE text_page, return -3; CPDF_TextPage* textpage = CPDFTextPageFromFPDFTextPage(text_page); - return textpage->GetIndexAtPos((FX_FLOAT)x, (FX_FLOAT)y, (FX_FLOAT)xTolerance, - (FX_FLOAT)yTolerance); + return textpage->GetIndexAtPos( + CFX_PointF(static_cast<FX_FLOAT>(x), static_cast<FX_FLOAT>(y)), + CFX_SizeF(static_cast<FX_FLOAT>(xTolerance), + static_cast<FX_FLOAT>(yTolerance))); } DLLEXPORT int STDCALL FPDFText_GetText(FPDF_TEXTPAGE text_page, diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp index ff4d46e35..1e7a651aa 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp @@ -44,6 +44,22 @@ #include "xfa/fxbarcode/BC_Library.h" #endif // PDF_ENABLE_XFA +#ifdef PDF_ENABLE_XFA_BMP +#include "core/fxcodec/codec/ccodec_bmpmodule.h" +#endif + +#ifdef PDF_ENABLE_XFA_GIF +#include "core/fxcodec/codec/ccodec_gifmodule.h" +#endif + +#ifdef PDF_ENABLE_XFA_PNG +#include "core/fxcodec/codec/ccodec_pngmodule.h" +#endif + +#ifdef PDF_ENABLE_XFA_TIFF +#include "core/fxcodec/codec/ccodec_tiffmodule.h" +#endif + #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ #include "core/fxge/cfx_windowsdevice.h" #endif @@ -94,7 +110,7 @@ void RenderPageImpl(CPDF_PageRenderContext* pContext, (flags & FPDF_PRINTING) ? CPDF_OCContext::Print : CPDF_OCContext::View; pContext->m_pOptions->m_AddFlags = flags >> 8; pContext->m_pOptions->m_pOCContext = - new CPDF_OCContext(pPage->m_pDocument, usage); + pdfium::MakeRetain<CPDF_OCContext>(pPage->m_pDocument, usage); pContext->m_pDevice->SaveState(); pContext->m_pDevice->SetClip_Rect(clipping_rect); @@ -364,6 +380,26 @@ FPDF_InitLibraryWithConfig(const FPDF_LIBRARY_CONFIG* cfg) { pModuleMgr->LoadEmbeddedCNS1CMaps(); pModuleMgr->LoadEmbeddedKorea1CMaps(); +#ifdef PDF_ENABLE_XFA_BMP + pModuleMgr->GetCodecModule()->SetBmpModule( + pdfium::MakeUnique<CCodec_BmpModule>()); +#endif + +#ifdef PDF_ENABLE_XFA_GIF + pModuleMgr->GetCodecModule()->SetGifModule( + pdfium::MakeUnique<CCodec_GifModule>()); +#endif + +#ifdef PDF_ENABLE_XFA_PNG + pModuleMgr->GetCodecModule()->SetPngModule( + pdfium::MakeUnique<CCodec_PngModule>()); +#endif + +#ifdef PDF_ENABLE_XFA_TIFF + pModuleMgr->GetCodecModule()->SetTiffModule( + pdfium::MakeUnique<CCodec_TiffModule>()); +#endif + #ifdef PDF_ENABLE_XFA FXJSE_Initialize(); BC_Library_Init(); @@ -756,14 +792,8 @@ DLLEXPORT void STDCALL FPDF_RenderPageBitmapWithMatrix(FPDF_BITMAP bitmap, CFX_Matrix transform_matrix = pPage->GetPageMatrix(); if (matrix) { - CFX_Matrix cmatrix; - cmatrix.a = matrix->a; - cmatrix.b = matrix->b; - cmatrix.c = matrix->c; - cmatrix.d = matrix->d; - cmatrix.e = matrix->e; - cmatrix.f = matrix->f; - transform_matrix.Concat(cmatrix); + transform_matrix.Concat(CFX_Matrix(matrix->a, matrix->b, matrix->c, + matrix->d, matrix->e, matrix->f)); } CFX_FloatRect clipping_rect; @@ -856,16 +886,16 @@ DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page, pPage->DeviceToPage(start_x, start_y, size_x, size_y, rotate, device_x, device_y, page_x, page_y); #else // PDF_ENABLE_XFA - CFX_Matrix page2device; - pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, - rotate); + CFX_Matrix page2device = + pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); CFX_Matrix device2page; device2page.SetReverse(page2device); - FX_FLOAT page_x_f, page_y_f; - device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, - page_y_f); - *page_x = (page_x_f); - *page_y = (page_y_f); + + CFX_PointF pos = device2page.Transform(CFX_PointF( + static_cast<FX_FLOAT>(device_x), static_cast<FX_FLOAT>(device_y))); + + *page_x = pos.x; + *page_y = pos.y; #endif // PDF_ENABLE_XFA } @@ -888,14 +918,13 @@ DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, pPage->PageToDevice(start_x, start_y, size_x, size_y, rotate, page_x, page_y, device_x, device_y); #else // PDF_ENABLE_XFA - CFX_Matrix page2device; - pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, - rotate); - FX_FLOAT device_x_f, device_y_f; - page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, - device_y_f); - *device_x = FXSYS_round(device_x_f); - *device_y = FXSYS_round(device_y_f); + CFX_Matrix page2device = + pPage->GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); + CFX_PointF pos = page2device.Transform( + CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y))); + + *device_x = FXSYS_round(pos.x); + *device_y = FXSYS_round(pos.y); #endif // PDF_ENABLE_XFA } @@ -988,10 +1017,10 @@ void FPDF_RenderPage_Retail(CPDF_PageRenderContext* pContext, if (!pPage) return; - CFX_Matrix matrix; - pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate); - FX_RECT rect(start_x, start_y, start_x + size_x, start_y + size_y); - RenderPageImpl(pContext, pPage, matrix, rect, flags, bNeedToRestore, pause); + RenderPageImpl(pContext, pPage, pPage->GetDisplayMatrix( + start_x, start_y, size_x, size_y, rotate), + FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y), + flags, bNeedToRestore, pause); } DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 98478f041..54a33252b 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -83,8 +83,22 @@ int CheckPDFiumCApi() { CHK(FPDFPage_TransformAnnots); CHK(FPDFPageObj_NewImgeObj); CHK(FPDFImageObj_LoadJpegFile); + CHK(FPDFImageObj_LoadJpegFileInline); CHK(FPDFImageObj_SetMatrix); CHK(FPDFImageObj_SetBitmap); + CHK(FPDFPageObj_CreateNewPath); + CHK(FPDFPageObj_CreateNewRect); + CHK(FPDFPath_SetStrokeColor); + CHK(FPDFPath_SetStrokeWidth); + CHK(FPDFPath_SetFillColor); + CHK(FPDFPath_MoveTo); + CHK(FPDFPath_LineTo); + CHK(FPDFPath_BezierTo); + CHK(FPDFPath_Close); + CHK(FPDFPath_SetDrawMode); + CHK(FPDFPageObj_NewTextObj); + CHK(FPDFText_SetText); + CHK(FPDFText_LoadType1Font); // fpdf_ext.h CHK(FSDK_SetUnSpObjProcessHandler); diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp index 113a74e22..88c88a174 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp +++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.cpp @@ -19,6 +19,7 @@ #include "fpdfsdk/javascript/ijs_runtime.h" #include "public/fpdf_formfill.h" #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fxfa/cxfa_eventparam.h" #include "xfa/fxfa/xfa_ffapp.h" #include "xfa/fxfa/xfa_ffdoc.h" @@ -82,11 +83,10 @@ void CPDFXFA_Context::SetFormFillEnv( bool CPDFXFA_Context::LoadXFADoc() { m_nLoadStatus = FXFA_LOADSTATUS_LOADING; - if (!m_pPDFDoc) return false; - m_XFAPageList.RemoveAll(); + m_XFAPageList.clear(); CXFA_FFApp* pApp = GetXFAApp(); if (!pApp) @@ -155,24 +155,27 @@ CPDFXFA_Page* CPDFXFA_Context::GetXFAPage(int page_index) { return nullptr; CPDFXFA_Page* pPage = nullptr; - int nCount = m_XFAPageList.GetSize(); + int nCount = pdfium::CollectionSize<int>(m_XFAPageList); if (nCount > 0 && page_index < nCount) { - pPage = m_XFAPageList.GetAt(page_index); - if (pPage) + pPage = m_XFAPageList[page_index]; + if (pPage) { pPage->Retain(); + return pPage; + } } else { m_nPageCount = GetPageCount(); - m_XFAPageList.SetSize(m_nPageCount); + m_XFAPageList.resize(m_nPageCount); } - if (pPage) - return pPage; pPage = new CPDFXFA_Page(this, page_index); if (!pPage->LoadPage()) { pPage->Release(); return nullptr; } - m_XFAPageList.SetAt(page_index, pPage); + if (page_index >= 0 && + page_index < pdfium::CollectionSize<int>(m_XFAPageList)) { + m_XFAPageList[page_index] = pPage; + } return pPage; } @@ -186,15 +189,10 @@ CPDFXFA_Page* CPDFXFA_Context::GetXFAPage(CXFA_FFPageView* pPage) const { if (m_iDocType != DOCTYPE_DYNAMIC_XFA) return nullptr; - int nSize = m_XFAPageList.GetSize(); - for (int i = 0; i < nSize; i++) { - CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i); - if (!pTempPage) - continue; - if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage) + for (CPDFXFA_Page* pTempPage : m_XFAPageList) { + if (pTempPage && pTempPage->GetXFAPageView() == pPage) return pTempPage; } - return nullptr; } @@ -205,15 +203,20 @@ void CPDFXFA_Context::DeletePage(int page_index) { if (m_pPDFDoc) m_pPDFDoc->DeletePage(page_index); - if (page_index < 0 || page_index >= m_XFAPageList.GetSize()) + if (page_index < 0 || + page_index >= pdfium::CollectionSize<int>(m_XFAPageList)) { return; - - if (CPDFXFA_Page* pPage = m_XFAPageList.GetAt(page_index)) + } + if (CPDFXFA_Page* pPage = m_XFAPageList[page_index]) pPage->Release(); } void CPDFXFA_Context::RemovePage(CPDFXFA_Page* page) { - m_XFAPageList.SetAt(page->GetPageIndex(), nullptr); + int page_index = page->GetPageIndex(); + if (page_index >= 0 && + page_index < pdfium::CollectionSize<int>(m_XFAPageList)) { + m_XFAPageList[page_index] = nullptr; + } } void CPDFXFA_Context::ClearChangeMark() { diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_context.h b/fpdfsdk/fpdfxfa/cpdfxfa_context.h index de3f39cb2..9a2a517fb 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_context.h +++ b/fpdfsdk/fpdfxfa/cpdfxfa_context.h @@ -8,6 +8,7 @@ #define FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_ #include <memory> +#include <vector> #include "fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h" #include "xfa/fxfa/xfa_ffdoc.h" @@ -16,8 +17,8 @@ class CJS_Runtime; class CPDFSDK_FormFillEnvironment; class CPDFXFA_Page; class CXFA_FFDocHandler; +class IJS_EventContext; class IJS_Runtime; -class IJS_Context; enum LoadStatus { FXFA_LOADSTATUS_PRELOAD = 0, @@ -88,12 +89,11 @@ class CPDFXFA_Context : public IXFA_AppProvider { int GetOriginalPageCount() const { return m_nPageCount; } void SetOriginalPageCount(int count) { m_nPageCount = count; - m_XFAPageList.SetSize(count); + m_XFAPageList.resize(count); } LoadStatus GetLoadStatus() const { return m_nLoadStatus; } - - CFX_ArrayTemplate<CPDFXFA_Page*>* GetXFAPageList() { return &m_XFAPageList; } + std::vector<CPDFXFA_Page*>* GetXFAPageList() { return &m_XFAPageList; } private: void CloseXFADoc(); @@ -106,7 +106,7 @@ class CPDFXFA_Context : public IXFA_AppProvider { CXFA_FFDocView* m_pXFADocView; // not owned. std::unique_ptr<CXFA_FFApp> m_pXFAApp; std::unique_ptr<CJS_Runtime> m_pRuntime; - CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList; + std::vector<CPDFXFA_Page*> m_XFAPageList; LoadStatus m_nLoadStatus; int m_nPageCount; diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp index 2b3368bc6..731b0cc29 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp +++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.cpp @@ -38,13 +38,15 @@ #define FXFA_XFA_ALL 0x01111111 CPDFXFA_DocEnvironment::CPDFXFA_DocEnvironment(CPDFXFA_Context* pContext) - : m_pContext(pContext), m_pJSContext(nullptr) { + : m_pContext(pContext), m_pJSEventContext(nullptr) { ASSERT(m_pContext); } CPDFXFA_DocEnvironment::~CPDFXFA_DocEnvironment() { - if (m_pJSContext && m_pContext->GetFormFillEnv()) - m_pContext->GetFormFillEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext); + if (m_pJSEventContext && m_pContext->GetFormFillEnv()) { + m_pContext->GetFormFillEnv()->GetJSRuntime()->ReleaseEventContext( + m_pJSEventContext); + } } void CPDFXFA_DocEnvironment::SetChangeMark(CXFA_FFDoc* hDoc) { @@ -69,9 +71,8 @@ void CPDFXFA_DocEnvironment::InvalidateRect(CXFA_FFPageView* pPageView, if (!pFormFillEnv) return; - CFX_FloatRect rcPage = CFX_FloatRect::FromCFXRectF(rt); - pFormFillEnv->Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom, - rcPage.right, rcPage.top); + pFormFillEnv->Invalidate(static_cast<FPDF_PAGE>(pPage), + CFX_FloatRect::FromCFXRectF(rt).ToFxRect()); } void CPDFXFA_DocEnvironment::DisplayCaret(CXFA_FFWidget* hWidget, @@ -277,7 +278,7 @@ void CPDFXFA_DocEnvironment::PageViewEvent(CXFA_FFPageView* pPageView, for (int iPageIter = 0; iPageIter < m_pContext->GetOriginalPageCount(); iPageIter++) { - CPDFXFA_Page* pPage = m_pContext->GetXFAPageList()->GetAt(iPageIter); + CPDFXFA_Page* pPage = (*m_pContext->GetXFAPageList())[iPageIter]; if (!pPage) continue; @@ -1023,8 +1024,8 @@ bool CPDFXFA_DocEnvironment::GetGlobalProperty( } CPDFSDK_FormFillEnvironment* pFormFillEnv = m_pContext->GetFormFillEnv(); - if (!m_pJSContext) - m_pJSContext = pFormFillEnv->GetJSRuntime()->NewContext(); + if (!m_pJSEventContext) + m_pJSEventContext = pFormFillEnv->GetJSRuntime()->NewEventContext(); return pFormFillEnv->GetJSRuntime()->GetValueByName(szPropName, pValue); } diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h index d7cb16961..dc18d9a0c 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h +++ b/fpdfsdk/fpdfxfa/cpdfxfa_docenvironment.h @@ -12,7 +12,7 @@ #include "xfa/fxfa/fxfa.h" class CPDFXFA_Context; -class IJS_Context; +class IJS_EventContext; class CPDFXFA_DocEnvironment : public IXFA_DocEnvironment { public: @@ -107,8 +107,8 @@ class CPDFXFA_DocEnvironment : public IXFA_DocEnvironment { FPDF_DWORD flag); void ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag); - CPDFXFA_Context* const m_pContext; // Not owned; - IJS_Context* m_pJSContext; + CPDFXFA_Context* const m_pContext; // Not owned. + IJS_EventContext* m_pJSEventContext; // Not owned. }; #endif // FPDFSDK_FPDFXFA_CPDFXFA_DOCENVIRONMENT_H_ diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp index 8cc325009..8b5bb3d27 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp +++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.cpp @@ -101,17 +101,16 @@ FX_FLOAT CPDFXFA_Page::GetPageWidth() const { int nDocType = m_pContext->GetDocType(); switch (nDocType) { case DOCTYPE_DYNAMIC_XFA: { - if (m_pXFAPageView) { - CFX_RectF rect; - m_pXFAPageView->GetPageViewRect(rect); - return rect.width; - } - } break; + if (m_pXFAPageView) + return m_pXFAPageView->GetPageViewRect().width; + break; + } case DOCTYPE_STATIC_XFA: case DOCTYPE_PDF: { if (m_pPDFPage) return m_pPDFPage->GetPageWidth(); - } break; + break; + } default: return 0.0f; } @@ -129,14 +128,13 @@ FX_FLOAT CPDFXFA_Page::GetPageHeight() const { case DOCTYPE_STATIC_XFA: { if (m_pPDFPage) return m_pPDFPage->GetPageHeight(); - } break; + break; + } case DOCTYPE_DYNAMIC_XFA: { - if (m_pXFAPageView) { - CFX_RectF rect; - m_pXFAPageView->GetPageViewRect(rect); - return rect.height; - } - } break; + if (m_pXFAPageView) + return m_pXFAPageView->GetPageViewRect().height; + break; + } default: return 0.0f; } @@ -156,18 +154,15 @@ void CPDFXFA_Page::DeviceToPage(int start_x, if (!m_pPDFPage && !m_pXFAPageView) return; - CFX_Matrix page2device; CFX_Matrix device2page; - FX_FLOAT page_x_f, page_y_f; + device2page.SetReverse( + GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate)); - GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); + CFX_PointF pos = device2page.Transform(CFX_PointF( + static_cast<FX_FLOAT>(device_x), static_cast<FX_FLOAT>(device_y))); - device2page.SetReverse(page2device); - device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, - page_y_f); - - *page_x = (page_x_f); - *page_y = (page_y_f); + *page_x = pos.x; + *page_y = pos.y; } void CPDFXFA_Page::PageToDevice(int start_x, @@ -182,43 +177,41 @@ void CPDFXFA_Page::PageToDevice(int start_x, if (!m_pPDFPage && !m_pXFAPageView) return; - CFX_Matrix page2device; - FX_FLOAT device_x_f, device_y_f; - - GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate); + CFX_Matrix page2device = + GetDisplayMatrix(start_x, start_y, size_x, size_y, rotate); - page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, - device_y_f); + CFX_PointF pos = page2device.Transform( + CFX_PointF(static_cast<FX_FLOAT>(page_x), static_cast<FX_FLOAT>(page_y))); - *device_x = FXSYS_round(device_x_f); - *device_y = FXSYS_round(device_y_f); + *device_x = FXSYS_round(pos.x); + *device_y = FXSYS_round(pos.y); } -void CPDFXFA_Page::GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const { +CFX_Matrix CPDFXFA_Page::GetDisplayMatrix(int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const { if (!m_pPDFPage && !m_pXFAPageView) - return; + return CFX_Matrix(); int nDocType = m_pContext->GetDocType(); switch (nDocType) { case DOCTYPE_DYNAMIC_XFA: { if (m_pXFAPageView) { - CFX_Rect rect; - rect.Set(xPos, yPos, xSize, ySize); - m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate); + return m_pXFAPageView->GetDisplayMatrix( + CFX_Rect(xPos, yPos, xSize, ySize), iRotate); } - } break; + break; + } case DOCTYPE_PDF: case DOCTYPE_STATIC_XFA: { - if (m_pPDFPage) { - m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate); - } - } break; + if (m_pPDFPage) + return m_pPDFPage->GetDisplayMatrix(xPos, yPos, xSize, ySize, iRotate); + break; + } default: - return; + return CFX_Matrix(); } + return CFX_Matrix(); } diff --git a/fpdfsdk/fpdfxfa/cpdfxfa_page.h b/fpdfsdk/fpdfxfa/cpdfxfa_page.h index 79158f4ea..993885d59 100644 --- a/fpdfsdk/fpdfxfa/cpdfxfa_page.h +++ b/fpdfsdk/fpdfxfa/cpdfxfa_page.h @@ -60,12 +60,11 @@ class CPDFXFA_Page { int* device_x, int* device_y); - void GetDisplayMatrix(CFX_Matrix& matrix, - int xPos, - int yPos, - int xSize, - int ySize, - int iRotate) const; + CFX_Matrix GetDisplayMatrix(int xPos, + int yPos, + int xSize, + int ySize, + int iRotate) const; protected: // Refcounted class. diff --git a/fpdfsdk/fsdk_actionhandler.cpp b/fpdfsdk/fsdk_actionhandler.cpp index 61d2a5285..dc99f32f3 100644 --- a/fpdfsdk/fsdk_actionhandler.cpp +++ b/fpdfsdk/fsdk_actionhandler.cpp @@ -14,7 +14,7 @@ #include "fpdfsdk/cpdfsdk_formfillenvironment.h" #include "fpdfsdk/cpdfsdk_interform.h" #include "fpdfsdk/fsdk_define.h" -#include "fpdfsdk/javascript/ijs_context.h" +#include "fpdfsdk/javascript/ijs_event_context.h" #include "fpdfsdk/javascript/ijs_runtime.h" #include "third_party/base/stl_util.h" @@ -157,16 +157,15 @@ bool CPDFSDK_ActionHandler::ExecuteLinkAction( CFX_WideString swJS = action.GetJavaScript(); if (!swJS.IsEmpty()) { IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime(); - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); pContext->OnLink_MouseUp(pFormFillEnv); CFX_WideString csInfo; bool bRet = pContext->RunScript(swJS, &csInfo); + pRuntime->ReleaseEventContext(pContext); if (!bRet) { // FIXME: return error. } - - pRuntime->ReleaseContext(pContext); } } } else { @@ -282,14 +281,13 @@ bool CPDFSDK_ActionHandler::ExecuteScreenAction( CFX_WideString swJS = action.GetJavaScript(); if (!swJS.IsEmpty()) { IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime(); - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); CFX_WideString csInfo; bool bRet = pContext->RunScript(swJS, &csInfo); + pRuntime->ReleaseEventContext(pContext); if (!bRet) { // FIXME: return error. } - - pRuntime->ReleaseContext(pContext); } } } else { @@ -322,16 +320,15 @@ bool CPDFSDK_ActionHandler::ExecuteBookMark( CFX_WideString swJS = action.GetJavaScript(); if (!swJS.IsEmpty()) { IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime(); - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); pContext->OnBookmark_MouseUp(pBookmark); CFX_WideString csInfo; bool bRet = pContext->RunScript(swJS, &csInfo); + pRuntime->ReleaseEventContext(pContext); if (!bRet) { // FIXME: return error. } - - pRuntime->ReleaseContext(pContext); } } } else { @@ -478,7 +475,7 @@ void CPDFSDK_ActionHandler::RunFieldJavaScript( ASSERT(type != CPDF_AAction::Format); IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime(); - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); switch (type) { case CPDF_AAction::CursorEnter: pContext->OnField_MouseEnter(data.bModifier, data.bShift, pFormField); @@ -518,11 +515,10 @@ void CPDFSDK_ActionHandler::RunFieldJavaScript( CFX_WideString csInfo; bool bRet = pContext->RunScript(script, &csInfo); + pRuntime->ReleaseEventContext(pContext); if (!bRet) { // FIXME: return error. } - - pRuntime->ReleaseContext(pContext); } void CPDFSDK_ActionHandler::RunDocumentOpenJavaScript( @@ -530,16 +526,15 @@ void CPDFSDK_ActionHandler::RunDocumentOpenJavaScript( const CFX_WideString& sScriptName, const CFX_WideString& script) { IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime(); - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); pContext->OnDoc_Open(pFormFillEnv, sScriptName); CFX_WideString csInfo; bool bRet = pContext->RunScript(script, &csInfo); + pRuntime->ReleaseEventContext(pContext); if (!bRet) { // FIXME: return error. } - - pRuntime->ReleaseContext(pContext); } void CPDFSDK_ActionHandler::RunDocumentPageJavaScript( @@ -547,7 +542,7 @@ void CPDFSDK_ActionHandler::RunDocumentPageJavaScript( CPDF_AAction::AActionType type, const CFX_WideString& script) { IJS_Runtime* pRuntime = pFormFillEnv->GetJSRuntime(); - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); switch (type) { case CPDF_AAction::OpenPage: pContext->OnPage_Open(pFormFillEnv); @@ -583,11 +578,10 @@ void CPDFSDK_ActionHandler::RunDocumentPageJavaScript( CFX_WideString csInfo; bool bRet = pContext->RunScript(script, &csInfo); + pRuntime->ReleaseEventContext(pContext); if (!bRet) { // FIXME: return error. } - - pRuntime->ReleaseContext(pContext); } bool CPDFSDK_ActionHandler::DoAction_Hide( diff --git a/fpdfsdk/fxedit/fxet_edit.cpp b/fpdfsdk/fxedit/fxet_edit.cpp index aa77e9fa5..1acc57795 100644 --- a/fpdfsdk/fxedit/fxet_edit.cpp +++ b/fpdfsdk/fxedit/fxet_edit.cpp @@ -29,6 +29,7 @@ #include "fpdfsdk/pdfwindow/PWL_Edit.h" #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h" #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" namespace { @@ -56,16 +57,14 @@ CFX_ByteString GetFontSetString(IPVT_FontMap* pFontMap, } void DrawTextString(CFX_RenderDevice* pDevice, - const CFX_FloatPoint& pt, + const CFX_PointF& pt, CPDF_Font* pFont, FX_FLOAT fFontSize, CFX_Matrix* pUser2Device, const CFX_ByteString& str, FX_ARGB crTextFill, - FX_ARGB crTextStroke, int32_t nHorzScale) { - FX_FLOAT x = pt.x, y = pt.y; - pUser2Device->Transform(x, y); + CFX_PointF pos = pUser2Device->Transform(pt); if (pFont) { if (nHorzScale != 100) { @@ -76,86 +75,20 @@ void DrawTextString(CFX_RenderDevice* pDevice, ro.m_Flags = RENDER_CLEARTYPE; ro.m_ColorMode = RENDER_COLOR_NORMAL; - if (crTextStroke != 0) { - CFX_FloatPoint pt1; - CFX_FloatPoint pt2; - pUser2Device->Transform(pt1.x, pt1.y); - pUser2Device->Transform(pt2.x, pt2.y); - CFX_GraphStateData gsd; - gsd.m_LineWidth = - (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y)); - - CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt, - str, crTextFill, crTextStroke, &gsd, - &ro); - } else { - CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, &mt, - str, crTextFill, 0, nullptr, &ro); - } + CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize, + &mt, str, crTextFill, nullptr, &ro); } else { CPDF_RenderOptions ro; ro.m_Flags = RENDER_CLEARTYPE; ro.m_ColorMode = RENDER_COLOR_NORMAL; - if (crTextStroke != 0) { - CFX_FloatPoint pt1; - CFX_FloatPoint pt2; - pUser2Device->Transform(pt1.x, pt1.y); - pUser2Device->Transform(pt2.x, pt2.y); - CFX_GraphStateData gsd; - gsd.m_LineWidth = - (FX_FLOAT)FXSYS_fabs((pt2.x + pt2.y) - (pt1.x + pt1.y)); - - CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, - pUser2Device, str, crTextFill, - crTextStroke, &gsd, &ro); - } else { - CPDF_TextRenderer::DrawTextString(pDevice, x, y, pFont, fFontSize, - pUser2Device, str, crTextFill, 0, - nullptr, &ro); - } + CPDF_TextRenderer::DrawTextString(pDevice, pos.x, pos.y, pFont, fFontSize, + pUser2Device, str, crTextFill, nullptr, + &ro); } } } -CPDF_TextObject* AddTextObjToPageObjects(CPDF_PageObjectHolder* pObjectHolder, - FX_COLORREF crText, - CPDF_Font* pFont, - FX_FLOAT fFontSize, - FX_FLOAT fCharSpace, - int32_t nHorzScale, - const CFX_FloatPoint& point, - const CFX_ByteString& text) { - std::unique_ptr<CPDF_TextObject> pTxtObj(new CPDF_TextObject); - pTxtObj->m_TextState.SetFont(pFont); - pTxtObj->m_TextState.SetFontSize(fFontSize); - pTxtObj->m_TextState.SetCharSpace(fCharSpace); - pTxtObj->m_TextState.SetWordSpace(0); - pTxtObj->m_TextState.SetTextMode(TextRenderingMode::MODE_FILL); - - FX_FLOAT* matrix = pTxtObj->m_TextState.GetMutableMatrix(); - matrix[0] = nHorzScale / 100.0f; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 1; - - FX_FLOAT rgb[3]; - rgb[0] = FXARGB_R(crText) / 255.0f; - rgb[1] = FXARGB_G(crText) / 255.0f; - rgb[2] = FXARGB_B(crText) / 255.0f; - pTxtObj->m_ColorState.SetFillColor( - CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); - pTxtObj->m_ColorState.SetStrokeColor( - CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB), rgb, 3); - - pTxtObj->SetPosition(point.x, point.y); - pTxtObj->SetText(text); - - CPDF_TextObject* pRet = pTxtObj.get(); - pObjectHolder->GetPageObjectList()->push_back(std::move(pTxtObj)); - return pRet; -} - } // namespace CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit* pEdit, @@ -274,8 +207,8 @@ CFX_Edit_Refresh::CFX_Edit_Refresh() {} CFX_Edit_Refresh::~CFX_Edit_Refresh() {} void CFX_Edit_Refresh::BeginRefresh() { - m_RefreshRects.Empty(); - m_OldLineRects = m_NewLineRects; + m_RefreshRects.Clear(); + m_OldLineRects = std::move(m_NewLineRects); } void CFX_Edit_Refresh::Push(const CPVT_WordRange& linerange, @@ -306,7 +239,7 @@ const CFX_Edit_RectArray* CFX_Edit_Refresh::GetRefreshRects() const { } void CFX_Edit_Refresh::EndRefresh() { - m_RefreshRects.Empty(); + m_RefreshRects.Clear(); } CFX_Edit_Undo::CFX_Edit_Undo(int32_t nBufsize) @@ -326,55 +259,43 @@ bool CFX_Edit_Undo::CanUndo() const { void CFX_Edit_Undo::Undo() { m_bWorking = true; - if (m_nCurUndoPos > 0) { - IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos - 1); - pItem->Undo(); - + m_UndoItemStack[m_nCurUndoPos - 1]->Undo(); m_nCurUndoPos--; m_bModified = (m_nCurUndoPos != 0); } - m_bWorking = false; } bool CFX_Edit_Undo::CanRedo() const { - return m_nCurUndoPos < m_UndoItemStack.GetSize(); + return m_nCurUndoPos < m_UndoItemStack.size(); } void CFX_Edit_Undo::Redo() { m_bWorking = true; - - int32_t nStackSize = m_UndoItemStack.GetSize(); - - if (m_nCurUndoPos < nStackSize) { - IFX_Edit_UndoItem* pItem = m_UndoItemStack.GetAt(m_nCurUndoPos); - pItem->Redo(); - + if (m_nCurUndoPos < m_UndoItemStack.size()) { + m_UndoItemStack[m_nCurUndoPos]->Redo(); m_nCurUndoPos++; - m_bModified = (m_nCurUndoPos != 0); + m_bModified = true; } - m_bWorking = false; } -void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem) { +void CFX_Edit_Undo::AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem) { ASSERT(!m_bWorking); ASSERT(pItem); ASSERT(m_nBufSize > 1); - - if (m_nCurUndoPos < m_UndoItemStack.GetSize()) + if (m_nCurUndoPos < m_UndoItemStack.size()) RemoveTails(); - if (m_UndoItemStack.GetSize() >= m_nBufSize) { + if (m_UndoItemStack.size() >= m_nBufSize) { RemoveHeads(); m_bVirgin = false; } - m_UndoItemStack.Add(pItem); - m_nCurUndoPos = m_UndoItemStack.GetSize(); - - m_bModified = (m_nCurUndoPos != 0); + m_UndoItemStack.push_back(std::move(pItem)); + m_nCurUndoPos = m_UndoItemStack.size(); + m_bModified = true; } bool CFX_Edit_Undo::IsModified() const { @@ -382,33 +303,26 @@ bool CFX_Edit_Undo::IsModified() const { } void CFX_Edit_Undo::RemoveHeads() { - ASSERT(m_UndoItemStack.GetSize() > 1); - - delete m_UndoItemStack.GetAt(0); - m_UndoItemStack.RemoveAt(0); + ASSERT(m_UndoItemStack.size() > 1); + m_UndoItemStack.pop_front(); } void CFX_Edit_Undo::RemoveTails() { - for (int32_t i = m_UndoItemStack.GetSize() - 1; i >= m_nCurUndoPos; i--) { - delete m_UndoItemStack.GetAt(i); - m_UndoItemStack.RemoveAt(i); - } + while (m_UndoItemStack.size() > m_nCurUndoPos) + m_UndoItemStack.pop_back(); } void CFX_Edit_Undo::Reset() { - for (int32_t i = 0, sz = m_UndoItemStack.GetSize(); i < sz; i++) { - delete m_UndoItemStack.GetAt(i); - } + m_UndoItemStack.clear(); m_nCurUndoPos = 0; - m_UndoItemStack.RemoveAll(); } CFX_Edit_UndoItem::CFX_Edit_UndoItem() : m_bFirst(true), m_bLast(true) {} CFX_Edit_UndoItem::~CFX_Edit_UndoItem() {} -CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() { - return L""; +CFX_WideString CFX_Edit_UndoItem::GetUndoTitle() const { + return CFX_WideString(); } void CFX_Edit_UndoItem::SetFirst(bool bFirst) { @@ -426,49 +340,36 @@ bool CFX_Edit_UndoItem::IsLast() { CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle) : m_sTitle(sTitle) {} -CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem() { - for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) { - delete m_Items[i]; - } +CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem() {} - m_Items.RemoveAll(); -} - -void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem) { +void CFX_Edit_GroupUndoItem::AddUndoItem( + std::unique_ptr<CFX_Edit_UndoItem> pUndoItem) { pUndoItem->SetFirst(false); pUndoItem->SetLast(false); - - m_Items.Add(pUndoItem); - if (m_sTitle.IsEmpty()) m_sTitle = pUndoItem->GetUndoTitle(); + + m_Items.push_back(std::move(pUndoItem)); } void CFX_Edit_GroupUndoItem::UpdateItems() { - if (m_Items.GetSize() > 0) { - CFX_Edit_UndoItem* pFirstItem = m_Items[0]; - pFirstItem->SetFirst(true); - - CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1]; - pLastItem->SetLast(true); + if (!m_Items.empty()) { + m_Items.front()->SetFirst(true); + m_Items.back()->SetLast(true); } } void CFX_Edit_GroupUndoItem::Undo() { - for (int i = m_Items.GetSize() - 1; i >= 0; i--) { - CFX_Edit_UndoItem* pUndoItem = m_Items[i]; - pUndoItem->Undo(); - } + for (auto iter = m_Items.rbegin(); iter != m_Items.rend(); ++iter) + (*iter)->Undo(); } void CFX_Edit_GroupUndoItem::Redo() { - for (int i = 0, sz = m_Items.GetSize(); i < sz; i++) { - CFX_Edit_UndoItem* pUndoItem = m_Items[i]; - pUndoItem->Redo(); - } + for (auto iter = m_Items.begin(); iter != m_Items.end(); ++iter) + (*iter)->Redo(); } -CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle() { +CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle() const { return m_sTitle; } @@ -671,7 +572,7 @@ void CFXEU_InsertText::Undo() { // static CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange, bool bContinuous, uint16_t SubWord) { @@ -684,8 +585,8 @@ CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit, CFX_ByteTextBuf sEditStream; CFX_ByteTextBuf sWords; int32_t nCurFontIndex = -1; - CFX_FloatPoint ptOld; - CFX_FloatPoint ptNew; + CFX_PointF ptOld; + CFX_PointF ptNew; CPVT_WordPlace oldplace; while (pIterator->NextWord()) { @@ -702,13 +603,13 @@ CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit, CPVT_Word word; if (pIterator->GetWord(word)) { - ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x, - word.ptWord.y + ptOffset.y); + ptNew = CFX_PointF(word.ptWord.x + ptOffset.x, + word.ptWord.y + ptOffset.y); } else { CPVT_Line line; pIterator->GetLine(line); - ptNew = CFX_FloatPoint(line.ptLine.x + ptOffset.x, - line.ptLine.y + ptOffset.y); + ptNew = CFX_PointF(line.ptLine.x + ptOffset.x, + line.ptLine.y + ptOffset.y); } if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) { @@ -739,8 +640,8 @@ CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit, } else { CPVT_Word word; if (pIterator->GetWord(word)) { - ptNew = CFX_FloatPoint(word.ptWord.x + ptOffset.x, - word.ptWord.y + ptOffset.y); + ptNew = + CFX_PointF(word.ptWord.x + ptOffset.x, word.ptWord.y + ptOffset.y); if (ptNew.x != ptOld.x || ptNew.y != ptOld.y) { sEditStream << ptNew.x - ptOld.x << " " << ptNew.y - ptOld.y @@ -786,7 +687,7 @@ CFX_ByteString CFX_Edit::GetEditAppearanceStream(CFX_Edit* pEdit, // static CFX_ByteString CFX_Edit::GetSelectAppearanceStream( CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange) { if (!pRange || !pRange->IsExist()) return CFX_ByteString(); @@ -817,9 +718,8 @@ void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, CFX_Edit* pEdit, FX_COLORREF crTextFill, - FX_COLORREF crTextStroke, const CFX_FloatRect& rcClip, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange, CFX_SystemHandler* pSystemHandler, CFFL_FormFiller* pFFLData) { @@ -839,7 +739,7 @@ void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, CFX_ByteTextBuf sTextBuf; int32_t nFontIndex = -1; - CFX_FloatPoint ptBT; + CFX_PointF ptBT; pDevice->SaveState(); if (!rcClip.IsEmpty()) { CFX_FloatRect rcTemp = rcClip; @@ -897,10 +797,9 @@ void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, crOldFill != crCurFill) { if (sTextBuf.GetLength() > 0) { DrawTextString( - pDevice, - CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), + pDevice, CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, - sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale); + sTextBuf.MakeString(), crOldFill, nHorzScale); sTextBuf.Clear(); } @@ -914,85 +813,27 @@ void CFX_Edit::DrawEdit(CFX_RenderDevice* pDevice, .AsStringC(); } else { DrawTextString( - pDevice, CFX_FloatPoint(word.ptWord.x + ptOffset.x, - word.ptWord.y + ptOffset.y), + pDevice, CFX_PointF(word.ptWord.x + ptOffset.x, + word.ptWord.y + ptOffset.y), pFontMap->GetPDFFont(word.nFontIndex), fFontSize, pUser2Device, GetPDFWordString(pFontMap, word.nFontIndex, word.Word, SubWord), - crCurFill, crTextStroke, nHorzScale); + crCurFill, nHorzScale); } oldplace = place; } } if (sTextBuf.GetLength() > 0) { - DrawTextString( - pDevice, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), - pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, - sTextBuf.MakeString(), crOldFill, crTextStroke, nHorzScale); + DrawTextString(pDevice, + CFX_PointF(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), + pFontMap->GetPDFFont(nFontIndex), fFontSize, pUser2Device, + sTextBuf.MakeString(), crOldFill, nHorzScale); } } pDevice->RestoreState(false); } -// static -void CFX_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder, - CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, - const CPVT_WordRange* pRange, - FX_COLORREF crText, - std::vector<CPDF_TextObject*>* ObjArray) { - ObjArray->clear(); - - IPVT_FontMap* pFontMap = pEdit->GetFontMap(); - if (!pFontMap) - return; - - FX_FLOAT fFontSize = pEdit->GetFontSize(); - int32_t nOldFontIndex = -1; - CFX_ByteTextBuf sTextBuf; - CPVT_WordPlace oldplace; - CFX_FloatPoint ptBT(0.0f, 0.0f); - CFX_Edit_Iterator* pIterator = pEdit->GetIterator(); - if (pRange) - pIterator->SetAt(pRange->BeginPos); - else - pIterator->SetAt(0); - - while (pIterator->NextWord()) { - CPVT_WordPlace place = pIterator->GetAt(); - if (pRange && place.WordCmp(pRange->EndPos) > 0) - break; - - CPVT_Word word; - if (!pIterator->GetWord(word)) - continue; - - if (place.LineCmp(oldplace) != 0 || nOldFontIndex != word.nFontIndex) { - if (sTextBuf.GetLength() > 0) { - ObjArray->push_back(AddTextObjToPageObjects( - pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), - fFontSize, 0.0f, 100, - CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), - sTextBuf.MakeString())); - - sTextBuf.Clear(); - } - ptBT = word.ptWord; - nOldFontIndex = word.nFontIndex; - } - sTextBuf << GetPDFWordString(pFontMap, word.nFontIndex, word.Word, 0) - .AsStringC(); - oldplace = place; - } - if (sTextBuf.GetLength() > 0) { - ObjArray->push_back(AddTextObjToPageObjects( - pObjectHolder, crText, pFontMap->GetPDFFont(nOldFontIndex), fFontSize, - 0.0f, 100, CFX_FloatPoint(ptBT.x + ptOffset.x, ptBT.y + ptOffset.y), - sTextBuf.MakeString())); - } -} - CFX_Edit::CFX_Edit() : m_pVT(new CPDF_VariableText), m_pNotify(nullptr), @@ -1048,7 +889,7 @@ IPVT_FontMap* CFX_Edit::GetFontMap() { void CFX_Edit::SetPlateRect(const CFX_FloatRect& rect) { m_pVT->SetPlateRect(rect); - m_ptScrollPos = CFX_FloatPoint(rect.left, rect.top); + m_ptScrollPos = CFX_PointF(rect.left, rect.top); Paint(); } @@ -1336,10 +1177,10 @@ CPVT_WordRange CFX_Edit::GetVisibleWordRange() const { if (m_pVT->IsValid()) { CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); - CPVT_WordPlace place1 = m_pVT->SearchWordPlace( - EditToVT(CFX_FloatPoint(rcPlate.left, rcPlate.top))); + CPVT_WordPlace place1 = + m_pVT->SearchWordPlace(EditToVT(CFX_PointF(rcPlate.left, rcPlate.top))); CPVT_WordPlace place2 = m_pVT->SearchWordPlace( - EditToVT(CFX_FloatPoint(rcPlate.right, rcPlate.bottom))); + EditToVT(CFX_PointF(rcPlate.right, rcPlate.bottom))); return CPVT_WordRange(place1, place2); } @@ -1347,7 +1188,7 @@ CPVT_WordRange CFX_Edit::GetVisibleWordRange() const { return CPVT_WordRange(); } -CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_FloatPoint& point) const { +CPVT_WordPlace CFX_Edit::SearchWordPlace(const CFX_PointF& point) const { if (m_pVT->IsValid()) { return m_pVT->SearchWordPlace(EditToVT(point)); } @@ -1424,7 +1265,7 @@ bool CFX_Edit::IsSelected() const { return m_SelState.IsExist(); } -CFX_FloatPoint CFX_Edit::VTToEdit(const CFX_FloatPoint& point) const { +CFX_PointF CFX_Edit::VTToEdit(const CFX_PointF& point) const { CFX_FloatRect rcContent = m_pVT->GetContentRect(); CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); @@ -1442,11 +1283,11 @@ CFX_FloatPoint CFX_Edit::VTToEdit(const CFX_FloatPoint& point) const { break; } - return CFX_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left), - point.y - (m_ptScrollPos.y + fPadding - rcPlate.top)); + return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left), + point.y - (m_ptScrollPos.y + fPadding - rcPlate.top)); } -CFX_FloatPoint CFX_Edit::EditToVT(const CFX_FloatPoint& point) const { +CFX_PointF CFX_Edit::EditToVT(const CFX_PointF& point) const { CFX_FloatRect rcContent = m_pVT->GetContentRect(); CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); @@ -1464,14 +1305,13 @@ CFX_FloatPoint CFX_Edit::EditToVT(const CFX_FloatPoint& point) const { break; } - return CFX_FloatPoint(point.x + (m_ptScrollPos.x - rcPlate.left), - point.y + (m_ptScrollPos.y + fPadding - rcPlate.top)); + return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left), + point.y + (m_ptScrollPos.y + fPadding - rcPlate.top)); } CFX_FloatRect CFX_Edit::VTToEdit(const CFX_FloatRect& rect) const { - CFX_FloatPoint ptLeftBottom = - VTToEdit(CFX_FloatPoint(rect.left, rect.bottom)); - CFX_FloatPoint ptRightTop = VTToEdit(CFX_FloatPoint(rect.right, rect.top)); + CFX_PointF ptLeftBottom = VTToEdit(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptRightTop = VTToEdit(CFX_PointF(rect.right, rect.top)); return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y); @@ -1524,14 +1364,14 @@ void CFX_Edit::SetScrollPosY(FX_FLOAT fy) { } } -void CFX_Edit::SetScrollPos(const CFX_FloatPoint& point) { +void CFX_Edit::SetScrollPos(const CFX_PointF& point) { SetScrollPosX(point.x); SetScrollPosY(point.y); SetScrollLimit(); SetCaretInfo(); } -CFX_FloatPoint CFX_Edit::GetScrollPos() const { +CFX_PointF CFX_Edit::GetScrollPos() const { return m_ptScrollPos; } @@ -1573,8 +1413,8 @@ void CFX_Edit::ScrollToCaret() { CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); pIterator->SetAt(m_wpCaret); - CFX_FloatPoint ptHead; - CFX_FloatPoint ptFoot; + CFX_PointF ptHead; + CFX_PointF ptFoot; CPVT_Word word; CPVT_Line line; if (pIterator->GetWord(word)) { @@ -1589,8 +1429,8 @@ void CFX_Edit::ScrollToCaret() { ptFoot.y = line.ptLine.y + line.fLineDescent; } - CFX_FloatPoint ptHeadEdit = VTToEdit(ptHead); - CFX_FloatPoint ptFootEdit = VTToEdit(ptFoot); + CFX_PointF ptHeadEdit = VTToEdit(ptHead); + CFX_PointF ptFootEdit = VTToEdit(ptFoot); CFX_FloatRect rcPlate = m_pVT->GetPlateRect(); if (!IsFloatEqual(rcPlate.left, rcPlate.right)) { if (IsFloatSmaller(ptHeadEdit.x, rcPlate.left) || @@ -1732,8 +1572,8 @@ void CFX_Edit::SetCaretInfo() { CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); pIterator->SetAt(m_wpCaret); - CFX_FloatPoint ptHead; - CFX_FloatPoint ptFoot; + CFX_PointF ptHead; + CFX_PointF ptFoot; CPVT_Word word; CPVT_Line line; if (pIterator->GetWord(word)) { @@ -1768,9 +1608,7 @@ void CFX_Edit::SetCaret(int32_t nPos) { } } -void CFX_Edit::OnMouseDown(const CFX_FloatPoint& point, - bool bShift, - bool bCtrl) { +void CFX_Edit::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) { if (m_pVT->IsValid()) { SelectNone(); SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); @@ -1782,9 +1620,7 @@ void CFX_Edit::OnMouseDown(const CFX_FloatPoint& point, } } -void CFX_Edit::OnMouseMove(const CFX_FloatPoint& point, - bool bShift, - bool bCtrl) { +void CFX_Edit::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) { if (m_pVT->IsValid()) { SetCaret(m_pVT->SearchWordPlace(EditToVT(point))); @@ -2020,167 +1856,139 @@ bool CFX_Edit::InsertWord(uint16_t word, const CPVT_WordProps* pWordProps, bool bAddUndo, bool bPaint) { - if (IsTextOverflow()) + if (IsTextOverflow() || !m_pVT->IsValid()) return false; - if (m_pVT->IsValid()) { - m_pVT->UpdateWordPlace(m_wpCaret); - - SetCaret(m_pVT->InsertWord( - m_wpCaret, word, GetCharSetFromUnicode(word, charset), pWordProps)); - m_SelState.Set(m_wpCaret, m_wpCaret); - - if (m_wpCaret != m_wpOldCaret) { - if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem(new CFXEU_InsertWord(this, m_wpOldCaret, m_wpCaret, - word, charset, pWordProps)); - } - - if (bPaint) - PaintInsertText(m_wpOldCaret, m_wpCaret); - - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret); + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(m_pVT->InsertWord(m_wpCaret, word, + GetCharSetFromUnicode(word, charset), pWordProps)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; - return true; - } + if (bAddUndo && m_bEnableUndo) { + AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertWord>( + this, m_wpOldCaret, m_wpCaret, word, charset, pWordProps)); } + if (bPaint) + PaintInsertText(m_wpOldCaret, m_wpCaret); - return false; + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret); + + return true; } bool CFX_Edit::InsertReturn(const CPVT_SecProps* pSecProps, const CPVT_WordProps* pWordProps, bool bAddUndo, bool bPaint) { - if (IsTextOverflow()) + if (IsTextOverflow() || !m_pVT->IsValid()) return false; - if (m_pVT->IsValid()) { - m_pVT->UpdateWordPlace(m_wpCaret); - SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps)); - m_SelState.Set(m_wpCaret, m_wpCaret); - - if (m_wpCaret != m_wpOldCaret) { - if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem(new CFXEU_InsertReturn(this, m_wpOldCaret, m_wpCaret, - pSecProps, pWordProps)); - } - - if (bPaint) { - RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } - - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret); + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(m_pVT->InsertSection(m_wpCaret, pSecProps, pWordProps)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; - return true; - } + if (bAddUndo && m_bEnableUndo) { + AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertReturn>( + this, m_wpOldCaret, m_wpCaret, pSecProps, pWordProps)); + } + if (bPaint) { + RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret); - return false; + return true; } bool CFX_Edit::Backspace(bool bAddUndo, bool bPaint) { - if (m_pVT->IsValid()) { - if (m_wpCaret == m_pVT->GetBeginWordPlace()) - return false; - - CPVT_Section section; - CPVT_Word word; - - if (bAddUndo) { - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_wpCaret); - pIterator->GetSection(section); - pIterator->GetWord(word); - } - - m_pVT->UpdateWordPlace(m_wpCaret); - SetCaret(m_pVT->BackSpaceWord(m_wpCaret)); - m_SelState.Set(m_wpCaret, m_wpCaret); - - if (m_wpCaret != m_wpOldCaret) { - if (bAddUndo && m_bEnableUndo) { - if (m_wpCaret.SecCmp(m_wpOldCaret) != 0) - AddEditUndoItem(new CFXEU_Backspace( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, section.WordProps)); - else - AddEditUndoItem(new CFXEU_Backspace( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, word.WordProps)); - } - - if (bPaint) { - RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); - } + if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetBeginWordPlace()) + return false; - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret); + CPVT_Section section; + CPVT_Word word; + if (bAddUndo) { + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_wpCaret); + pIterator->GetSection(section); + pIterator->GetWord(word); + } + m_pVT->UpdateWordPlace(m_wpCaret); + SetCaret(m_pVT->BackSpaceWord(m_wpCaret)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (m_wpCaret == m_wpOldCaret) + return false; - return true; + if (bAddUndo && m_bEnableUndo) { + if (m_wpCaret.SecCmp(m_wpOldCaret) != 0) { + AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, section.WordProps)); + } else { + AddEditUndoItem(pdfium::MakeUnique<CFXEU_Backspace>( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, word.WordProps)); } } + if (bPaint) { + RearrangePart(CPVT_WordRange(m_wpCaret, m_wpOldCaret)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret); - return false; + return true; } bool CFX_Edit::Delete(bool bAddUndo, bool bPaint) { - if (m_pVT->IsValid()) { - if (m_wpCaret == m_pVT->GetEndWordPlace()) - return false; - - CPVT_Section section; - CPVT_Word word; - - if (bAddUndo) { - CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); - pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret)); - pIterator->GetSection(section); - pIterator->GetWord(word); - } - - m_pVT->UpdateWordPlace(m_wpCaret); - bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret)); - - SetCaret(m_pVT->DeleteWord(m_wpCaret)); - m_SelState.Set(m_wpCaret, m_wpCaret); - - if (bAddUndo && m_bEnableUndo) { - if (bSecEnd) - AddEditUndoItem(new CFXEU_Delete( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, section.WordProps, bSecEnd)); - else - AddEditUndoItem(new CFXEU_Delete( - this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, - section.SecProps, word.WordProps, bSecEnd)); - } + if (!m_pVT->IsValid() || m_wpCaret == m_pVT->GetEndWordPlace()) + return false; - if (bPaint) { - RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); - ScrollToCaret(); - Refresh(); - SetCaretOrigin(); - SetCaretInfo(); + CPVT_Section section; + CPVT_Word word; + if (bAddUndo) { + CPDF_VariableText::Iterator* pIterator = m_pVT->GetIterator(); + pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret)); + pIterator->GetSection(section); + pIterator->GetWord(word); + } + m_pVT->UpdateWordPlace(m_wpCaret); + bool bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret)); + SetCaret(m_pVT->DeleteWord(m_wpCaret)); + m_SelState.Set(m_wpCaret, m_wpCaret); + if (bAddUndo && m_bEnableUndo) { + if (bSecEnd) { + AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, section.WordProps, bSecEnd)); + } else { + AddEditUndoItem(pdfium::MakeUnique<CFXEU_Delete>( + this, m_wpOldCaret, m_wpCaret, word.Word, word.nCharset, + section.SecProps, word.WordProps, bSecEnd)); } - - if (m_bOprNotify && m_pOprNotify) - m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret); - - return true; } + if (bPaint) { + RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret)); + ScrollToCaret(); + Refresh(); + SetCaretOrigin(); + SetCaretInfo(); + } + if (m_bOprNotify && m_pOprNotify) + m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret); - return false; + return true; } bool CFX_Edit::Empty() { @@ -2195,21 +2003,16 @@ bool CFX_Edit::Empty() { } bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) { - if (!m_pVT->IsValid()) - return false; - - if (!m_SelState.IsExist()) + if (!m_pVT->IsValid() || !m_SelState.IsExist()) return false; CPVT_WordRange range = m_SelState.ConvertToWordRange(); - if (bAddUndo && m_bEnableUndo) - AddEditUndoItem(new CFXEU_Clear(this, range, GetSelText())); + AddEditUndoItem(pdfium::MakeUnique<CFXEU_Clear>(this, range, GetSelText())); SelectNone(); SetCaret(m_pVT->DeleteWords(range)); m_SelState.Set(m_wpCaret, m_wpCaret); - if (bPaint) { RearrangePart(range); ScrollToCaret(); @@ -2217,7 +2020,6 @@ bool CFX_Edit::Clear(bool bAddUndo, bool bPaint) { SetCaretOrigin(); SetCaretInfo(); } - if (m_bOprNotify && m_pOprNotify) m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret); @@ -2238,10 +2040,9 @@ bool CFX_Edit::InsertText(const CFX_WideString& sText, return false; if (bAddUndo && m_bEnableUndo) { - AddEditUndoItem( - new CFXEU_InsertText(this, m_wpOldCaret, m_wpCaret, sText, charset)); + AddEditUndoItem(pdfium::MakeUnique<CFXEU_InsertText>( + this, m_wpOldCaret, m_wpCaret, sText, charset)); } - if (bPaint) PaintInsertText(m_wpOldCaret, m_wpCaret); @@ -2407,53 +2208,36 @@ int32_t CFX_Edit::GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset) { return nOldCharset; } -void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem) { - if (m_pGroupUndoItem) { - m_pGroupUndoItem->AddUndoItem(pEditUndoItem); - } else { - m_Undo.AddItem(pEditUndoItem); - } +void CFX_Edit::AddEditUndoItem( + std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem) { + if (m_pGroupUndoItem) + m_pGroupUndoItem->AddUndoItem(std::move(pEditUndoItem)); + else + m_Undo.AddItem(std::move(pEditUndoItem)); } CFX_Edit_LineRectArray::CFX_Edit_LineRectArray() {} -CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() { - Empty(); -} - -void CFX_Edit_LineRectArray::Empty() { - for (int32_t i = 0, sz = m_LineRects.GetSize(); i < sz; i++) - delete m_LineRects.GetAt(i); - - m_LineRects.RemoveAll(); -} - -void CFX_Edit_LineRectArray::RemoveAll() { - m_LineRects.RemoveAll(); -} +CFX_Edit_LineRectArray::~CFX_Edit_LineRectArray() {} -void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray& rects) { - Empty(); - for (int32_t i = 0, sz = rects.GetSize(); i < sz; i++) - m_LineRects.Add(rects.GetAt(i)); - - rects.RemoveAll(); +void CFX_Edit_LineRectArray::operator=(CFX_Edit_LineRectArray&& that) { + m_LineRects = std::move(that.m_LineRects); } void CFX_Edit_LineRectArray::Add(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine) { - m_LineRects.Add(new CFX_Edit_LineRect(wrLine, rcLine)); + m_LineRects.push_back(pdfium::MakeUnique<CFX_Edit_LineRect>(wrLine, rcLine)); } int32_t CFX_Edit_LineRectArray::GetSize() const { - return m_LineRects.GetSize(); + return pdfium::CollectionSize<int32_t>(m_LineRects); } CFX_Edit_LineRect* CFX_Edit_LineRectArray::GetAt(int32_t nIndex) const { - if (nIndex < 0 || nIndex >= m_LineRects.GetSize()) + if (nIndex < 0 || nIndex >= GetSize()) return nullptr; - return m_LineRects.GetAt(nIndex); + return m_LineRects[nIndex].get(); } CFX_Edit_Select::CFX_Edit_Select() {} @@ -2496,35 +2280,28 @@ bool CFX_Edit_Select::IsExist() const { CFX_Edit_RectArray::CFX_Edit_RectArray() {} -CFX_Edit_RectArray::~CFX_Edit_RectArray() { - Empty(); -} - -void CFX_Edit_RectArray::Empty() { - for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++) - delete m_Rects.GetAt(i); +CFX_Edit_RectArray::~CFX_Edit_RectArray() {} - m_Rects.RemoveAll(); +void CFX_Edit_RectArray::Clear() { + m_Rects.clear(); } void CFX_Edit_RectArray::Add(const CFX_FloatRect& rect) { // check for overlapped area - for (int32_t i = 0, sz = m_Rects.GetSize(); i < sz; i++) { - CFX_FloatRect* pRect = m_Rects.GetAt(i); + for (const auto& pRect : m_Rects) { if (pRect && pRect->Contains(rect)) return; } - - m_Rects.Add(new CFX_FloatRect(rect)); + m_Rects.push_back(pdfium::MakeUnique<CFX_FloatRect>(rect)); } int32_t CFX_Edit_RectArray::GetSize() const { - return m_Rects.GetSize(); + return pdfium::CollectionSize<int32_t>(m_Rects); } CFX_FloatRect* CFX_Edit_RectArray::GetAt(int32_t nIndex) const { - if (nIndex < 0 || nIndex >= m_Rects.GetSize()) + if (nIndex < 0 || nIndex >= GetSize()) return nullptr; - return m_Rects.GetAt(nIndex); + return m_Rects[nIndex].get(); } diff --git a/fpdfsdk/fxedit/fxet_edit.h b/fpdfsdk/fxedit/fxet_edit.h index 2ab27d3a8..ab83af2e3 100644 --- a/fpdfsdk/fxedit/fxet_edit.h +++ b/fpdfsdk/fxedit/fxet_edit.h @@ -7,6 +7,7 @@ #ifndef FPDFSDK_FXEDIT_FXET_EDIT_H_ #define FPDFSDK_FXEDIT_FXET_EDIT_H_ +#include <deque> #include <memory> #include <vector> @@ -40,16 +41,14 @@ class CFX_Edit_LineRectArray { CFX_Edit_LineRectArray(); virtual ~CFX_Edit_LineRectArray(); - void Empty(); - void RemoveAll(); - void operator=(CFX_Edit_LineRectArray& rects); + void operator=(CFX_Edit_LineRectArray&& rects); void Add(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine); int32_t GetSize() const; CFX_Edit_LineRect* GetAt(int32_t nIndex) const; private: - CFX_ArrayTemplate<CFX_Edit_LineRect*> m_LineRects; + std::vector<std::unique_ptr<CFX_Edit_LineRect>> m_LineRects; }; class CFX_Edit_RectArray { @@ -57,14 +56,14 @@ class CFX_Edit_RectArray { CFX_Edit_RectArray(); virtual ~CFX_Edit_RectArray(); - void Empty(); + void Clear(); void Add(const CFX_FloatRect& rect); int32_t GetSize() const; CFX_FloatRect* GetAt(int32_t nIndex) const; private: - CFX_ArrayTemplate<CFX_FloatRect*> m_Rects; + std::vector<std::unique_ptr<CFX_FloatRect>> m_Rects; }; class CFX_Edit_Refresh { @@ -99,7 +98,8 @@ class CFX_Edit_Select { CPVT_WordRange ConvertToWordRange() const; bool IsExist() const; - CPVT_WordPlace BeginPos, EndPos; + CPVT_WordPlace BeginPos; + CPVT_WordPlace EndPos; }; class CFX_Edit_Undo { @@ -107,26 +107,21 @@ class CFX_Edit_Undo { explicit CFX_Edit_Undo(int32_t nBufsize); virtual ~CFX_Edit_Undo(); + void AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem); void Undo(); void Redo(); - - void AddItem(IFX_Edit_UndoItem* pItem); - bool CanUndo() const; bool CanRedo() const; bool IsModified() const; - void Reset(); private: void RemoveHeads(); void RemoveTails(); - private: - CFX_ArrayTemplate<IFX_Edit_UndoItem*> m_UndoItemStack; - - int32_t m_nCurUndoPos; - int32_t m_nBufSize; + std::deque<std::unique_ptr<IFX_Edit_UndoItem>> m_UndoItemStack; + size_t m_nCurUndoPos; + size_t m_nBufSize; bool m_bModified; bool m_bVirgin; bool m_bWorking; @@ -138,7 +133,7 @@ class IFX_Edit_UndoItem { virtual void Undo() = 0; virtual void Redo() = 0; - virtual CFX_WideString GetUndoTitle() = 0; + virtual CFX_WideString GetUndoTitle() const = 0; }; class CFX_Edit_UndoItem : public IFX_Edit_UndoItem { @@ -146,7 +141,7 @@ class CFX_Edit_UndoItem : public IFX_Edit_UndoItem { CFX_Edit_UndoItem(); ~CFX_Edit_UndoItem() override; - CFX_WideString GetUndoTitle() override; + CFX_WideString GetUndoTitle() const override; void SetFirst(bool bFirst); void SetLast(bool bLast); @@ -165,14 +160,14 @@ class CFX_Edit_GroupUndoItem : public IFX_Edit_UndoItem { // IFX_Edit_UndoItem void Undo() override; void Redo() override; - CFX_WideString GetUndoTitle() override; + CFX_WideString GetUndoTitle() const override; - void AddUndoItem(CFX_Edit_UndoItem* pUndoItem); + void AddUndoItem(std::unique_ptr<CFX_Edit_UndoItem> pUndoItem); void UpdateItems(); private: CFX_WideString m_sTitle; - CFX_ArrayTemplate<CFX_Edit_UndoItem*> m_Items; + std::vector<std::unique_ptr<CFX_Edit_UndoItem>> m_Items; }; class CFXEU_InsertWord : public CFX_Edit_UndoItem { @@ -318,30 +313,22 @@ class CFXEU_InsertText : public CFX_Edit_UndoItem { class CFX_Edit { public: static CFX_ByteString GetEditAppearanceStream(CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange, bool bContinuous, uint16_t SubWord); - static CFX_ByteString GetSelectAppearanceStream( - CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, - const CPVT_WordRange* pRange); + static CFX_ByteString GetSelectAppearanceStream(CFX_Edit* pEdit, + const CFX_PointF& ptOffset, + const CPVT_WordRange* pRange); static void DrawEdit(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, CFX_Edit* pEdit, FX_COLORREF crTextFill, - FX_COLORREF crTextStroke, const CFX_FloatRect& rcClip, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange, CFX_SystemHandler* pSystemHandler, CFFL_FormFiller* pFFLData); - static void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder, - CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, - const CPVT_WordRange* pRange, - FX_COLORREF crText, - std::vector<CPDF_TextObject*>* ObjArray); CFX_Edit(); ~CFX_Edit(); @@ -357,7 +344,7 @@ class CFX_Edit { // Set the bounding box of the text area. void SetPlateRect(const CFX_FloatRect& rect); - void SetScrollPos(const CFX_FloatPoint& point); + void SetScrollPos(const CFX_PointF& point); // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right]) void SetAlignmentH(int32_t nFormat, bool bPaint); @@ -377,8 +364,8 @@ class CFX_Edit { void SetAutoScroll(bool bAuto, bool bPaint); void SetFontSize(FX_FLOAT fFontSize); void SetTextOverflow(bool bAllowed, bool bPaint); - void OnMouseDown(const CFX_FloatPoint& point, bool bShift, bool bCtrl); - void OnMouseMove(const CFX_FloatPoint& point, bool bShift, bool bCtrl); + void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); + void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); void OnVK_UP(bool bShift, bool bCtrl); void OnVK_DOWN(bool bShift, bool bCtrl); void OnVK_LEFT(bool bShift, bool bCtrl); @@ -396,14 +383,14 @@ class CFX_Edit { bool Undo(); int32_t WordPlaceToWordIndex(const CPVT_WordPlace& place) const; CPVT_WordPlace WordIndexToWordPlace(int32_t index) const; - CPVT_WordPlace SearchWordPlace(const CFX_FloatPoint& point) const; + CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const; int32_t GetCaret() const; CPVT_WordPlace GetCaretWordPlace() const; CFX_WideString GetSelText() const; CFX_WideString GetText() const; FX_FLOAT GetFontSize() const; uint16_t GetPasswordChar() const; - CFX_FloatPoint GetScrollPos() const; + CFX_PointF GetScrollPos() const; int32_t GetCharArray() const; CFX_FloatRect GetContentRect() const; CFX_WideString GetRangeText(const CPVT_WordRange& range) const; @@ -477,8 +464,8 @@ class CFX_Edit { void PaintInsertText(const CPVT_WordPlace& wpOld, const CPVT_WordPlace& wpNew); - inline CFX_FloatPoint VTToEdit(const CFX_FloatPoint& point) const; - inline CFX_FloatPoint EditToVT(const CFX_FloatPoint& point) const; + inline CFX_PointF VTToEdit(const CFX_PointF& point) const; + inline CFX_PointF EditToVT(const CFX_PointF& point) const; inline CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const; void Refresh(); @@ -488,24 +475,22 @@ class CFX_Edit { void SetCaretInfo(); void SetCaretOrigin(); - void AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem); + void AddEditUndoItem(std::unique_ptr<CFX_Edit_UndoItem> pEditUndoItem); private: std::unique_ptr<CPDF_VariableText> m_pVT; CPWL_EditCtrl* m_pNotify; CPWL_Edit* m_pOprNotify; std::unique_ptr<CFX_Edit_Provider> m_pVTProvider; - CPVT_WordPlace m_wpCaret; CPVT_WordPlace m_wpOldCaret; CFX_Edit_Select m_SelState; - - CFX_FloatPoint m_ptScrollPos; - CFX_FloatPoint m_ptRefreshScrollPos; + CFX_PointF m_ptScrollPos; + CFX_PointF m_ptRefreshScrollPos; bool m_bEnableScroll; std::unique_ptr<CFX_Edit_Iterator> m_pIterator; CFX_Edit_Refresh m_Refresh; - CFX_FloatPoint m_ptCaret; + CFX_PointF m_ptCaret; CFX_Edit_Undo m_Undo; int32_t m_nAlignment; bool m_bNotifyFlag; diff --git a/fpdfsdk/fxedit/fxet_list.cpp b/fpdfsdk/fxedit/fxet_list.cpp index cf718b9ac..39877c955 100644 --- a/fpdfsdk/fxedit/fxet_list.cpp +++ b/fpdfsdk/fxedit/fxet_list.cpp @@ -207,37 +207,33 @@ void CFX_ListCtrl::SetNotify(CPWL_List_Notify* pNotify) { m_pNotify = pNotify; } -CFX_FloatPoint CFX_ListCtrl::InToOut(const CFX_FloatPoint& point) const { +CFX_PointF CFX_ListCtrl::InToOut(const CFX_PointF& point) const { CFX_FloatRect rcPlate = GetPlateRect(); - - return CFX_FloatPoint(point.x - (m_ptScrollPos.x - rcPlate.left), - point.y - (m_ptScrollPos.y - rcPlate.top)); + return CFX_PointF(point.x - (m_ptScrollPos.x - rcPlate.left), + point.y - (m_ptScrollPos.y - rcPlate.top)); } -CFX_FloatPoint CFX_ListCtrl::OutToIn(const CFX_FloatPoint& point) const { +CFX_PointF CFX_ListCtrl::OutToIn(const CFX_PointF& point) const { CFX_FloatRect rcPlate = GetPlateRect(); - - return CFX_FloatPoint(point.x + (m_ptScrollPos.x - rcPlate.left), - point.y + (m_ptScrollPos.y - rcPlate.top)); + return CFX_PointF(point.x + (m_ptScrollPos.x - rcPlate.left), + point.y + (m_ptScrollPos.y - rcPlate.top)); } CFX_FloatRect CFX_ListCtrl::InToOut(const CFX_FloatRect& rect) const { - CFX_FloatPoint ptLeftBottom = InToOut(CFX_FloatPoint(rect.left, rect.bottom)); - CFX_FloatPoint ptRightTop = InToOut(CFX_FloatPoint(rect.right, rect.top)); - + CFX_PointF ptLeftBottom = InToOut(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptRightTop = InToOut(CFX_PointF(rect.right, rect.top)); return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y); } CFX_FloatRect CFX_ListCtrl::OutToIn(const CFX_FloatRect& rect) const { - CFX_FloatPoint ptLeftBottom = OutToIn(CFX_FloatPoint(rect.left, rect.bottom)); - CFX_FloatPoint ptRightTop = OutToIn(CFX_FloatPoint(rect.right, rect.top)); - + CFX_PointF ptLeftBottom = OutToIn(CFX_PointF(rect.left, rect.bottom)); + CFX_PointF ptRightTop = OutToIn(CFX_PointF(rect.right, rect.top)); return CFX_FloatRect(ptLeftBottom.x, ptLeftBottom.y, ptRightTop.x, ptRightTop.y); } -void CFX_ListCtrl::OnMouseDown(const CFX_FloatPoint& point, +void CFX_ListCtrl::OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl) { int32_t nHitIndex = GetItemIndex(point); @@ -276,7 +272,7 @@ void CFX_ListCtrl::OnMouseDown(const CFX_FloatPoint& point, ScrollToListItem(nHitIndex); } -void CFX_ListCtrl::OnMouseMove(const CFX_FloatPoint& point, +void CFX_ListCtrl::OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl) { int32_t nHitIndex = GetItemIndex(point); @@ -367,7 +363,7 @@ bool CFX_ListCtrl::OnChar(uint16_t nChar, bool bShift, bool bCtrl) { void CFX_ListCtrl::SetPlateRect(const CFX_FloatRect& rect) { CFX_ListContainer::SetPlateRect(rect); m_ptScrollPos.x = rect.left; - SetScrollPos(CFX_FloatPoint(rect.left, rect.top)); + SetScrollPos(CFX_PointF(rect.left, rect.top)); ReArrange(0); InvalidateItem(-1); } @@ -542,7 +538,7 @@ void CFX_ListCtrl::SetScrollInfo() { } } -void CFX_ListCtrl::SetScrollPos(const CFX_FloatPoint& point) { +void CFX_ListCtrl::SetScrollPos(const CFX_PointF& point) { SetScrollPosY(point.y); } @@ -630,8 +626,8 @@ void CFX_ListCtrl::Cancel() { m_aSelItems.DeselectAll(); } -int32_t CFX_ListCtrl::GetItemIndex(const CFX_FloatPoint& point) const { - CFX_FloatPoint pt = OuterToInner(OutToIn(point)); +int32_t CFX_ListCtrl::GetItemIndex(const CFX_PointF& point) const { + CFX_PointF pt = OuterToInner(OutToIn(point)); bool bFirst = true; bool bLast = true; diff --git a/fpdfsdk/fxedit/fxet_list.h b/fpdfsdk/fxedit/fxet_list.h index 38d1957e0..01e18bc00 100644 --- a/fpdfsdk/fxedit/fxet_list.h +++ b/fpdfsdk/fxedit/fxet_list.h @@ -64,11 +64,11 @@ class CLST_Rect : public CFX_FloatRect { return bottom - top; } - CFX_FloatPoint LeftTop() const { return CFX_FloatPoint(left, top); } + CFX_PointF LeftTop() const { return CFX_PointF(left, top); } - CFX_FloatPoint RightBottom() const { return CFX_FloatPoint(right, bottom); } + CFX_PointF RightBottom() const { return CFX_PointF(right, bottom); } - const CLST_Rect operator+=(const CFX_FloatPoint& point) { + const CLST_Rect operator+=(const CFX_PointF& point) { left += point.x; right += point.x; top += point.y; @@ -77,7 +77,7 @@ class CLST_Rect : public CFX_FloatRect { return *this; } - const CLST_Rect operator-=(const CFX_FloatPoint& point) { + const CLST_Rect operator-=(const CFX_PointF& point) { left -= point.x; right -= point.x; top -= point.y; @@ -86,12 +86,12 @@ class CLST_Rect : public CFX_FloatRect { return *this; } - CLST_Rect operator+(const CFX_FloatPoint& point) const { + CLST_Rect operator+(const CFX_PointF& point) const { return CLST_Rect(left + point.x, top + point.y, right + point.x, bottom + point.y); } - CLST_Rect operator-(const CFX_FloatPoint& point) const { + CLST_Rect operator-(const CFX_PointF& point) const { return CLST_Rect(left - point.x, top - point.y, right - point.x, bottom - point.y); } @@ -134,33 +134,31 @@ class CFX_ListContainer { CFX_FloatRect GetPlateRect() const { return m_rcPlate; } void SetContentRect(const CLST_Rect& rect) { m_rcContent = rect; } CLST_Rect GetContentRect() const { return m_rcContent; } - CFX_FloatPoint GetBTPoint() const { - return CFX_FloatPoint(m_rcPlate.left, m_rcPlate.top); + CFX_PointF GetBTPoint() const { + return CFX_PointF(m_rcPlate.left, m_rcPlate.top); } - CFX_FloatPoint GetETPoint() const { - return CFX_FloatPoint(m_rcPlate.right, m_rcPlate.bottom); + CFX_PointF GetETPoint() const { + return CFX_PointF(m_rcPlate.right, m_rcPlate.bottom); } public: - CFX_FloatPoint InnerToOuter(const CFX_FloatPoint& point) const { - return CFX_FloatPoint(point.x + GetBTPoint().x, GetBTPoint().y - point.y); + CFX_PointF InnerToOuter(const CFX_PointF& point) const { + return CFX_PointF(point.x + GetBTPoint().x, GetBTPoint().y - point.y); } - CFX_FloatPoint OuterToInner(const CFX_FloatPoint& point) const { - return CFX_FloatPoint(point.x - GetBTPoint().x, GetBTPoint().y - point.y); + CFX_PointF OuterToInner(const CFX_PointF& point) const { + return CFX_PointF(point.x - GetBTPoint().x, GetBTPoint().y - point.y); } CFX_FloatRect InnerToOuter(const CLST_Rect& rect) const { - CFX_FloatPoint ptLeftTop = - InnerToOuter(CFX_FloatPoint(rect.left, rect.top)); - CFX_FloatPoint ptRightBottom = - InnerToOuter(CFX_FloatPoint(rect.right, rect.bottom)); + CFX_PointF ptLeftTop = InnerToOuter(CFX_PointF(rect.left, rect.top)); + CFX_PointF ptRightBottom = + InnerToOuter(CFX_PointF(rect.right, rect.bottom)); return CFX_FloatRect(ptLeftTop.x, ptRightBottom.y, ptRightBottom.x, ptLeftTop.y); } CLST_Rect OuterToInner(const CFX_FloatRect& rect) const { - CFX_FloatPoint ptLeftTop = - OuterToInner(CFX_FloatPoint(rect.left, rect.top)); - CFX_FloatPoint ptRightBottom = - OuterToInner(CFX_FloatPoint(rect.right, rect.bottom)); + CFX_PointF ptLeftTop = OuterToInner(CFX_PointF(rect.left, rect.top)); + CFX_PointF ptRightBottom = + OuterToInner(CFX_PointF(rect.right, rect.bottom)); return CLST_Rect(ptLeftTop.x, ptLeftTop.y, ptRightBottom.x, ptRightBottom.y); } @@ -226,8 +224,8 @@ class CFX_ListCtrl : protected CFX_ListContainer { void SetPlateRect(const CFX_FloatRect& rect) override; void SetNotify(CPWL_List_Notify* pNotify); - void OnMouseDown(const CFX_FloatPoint& point, bool bShift, bool bCtrl); - void OnMouseMove(const CFX_FloatPoint& point, bool bShift, bool bCtrl); + void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl); + void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl); void OnVK_UP(bool bShift, bool bCtrl); void OnVK_DOWN(bool bShift, bool bCtrl); void OnVK_LEFT(bool bShift, bool bCtrl); @@ -237,14 +235,14 @@ class CFX_ListCtrl : protected CFX_ListContainer { void OnVK(int32_t nItemIndex, bool bShift, bool bCtrl); bool OnChar(uint16_t nChar, bool bShift, bool bCtrl); - void SetScrollPos(const CFX_FloatPoint& point); + void SetScrollPos(const CFX_PointF& point); void ScrollToListItem(int32_t nItemIndex); CFX_FloatRect GetItemRect(int32_t nIndex) const; int32_t GetCaret() const; int32_t GetSelect() const; int32_t GetTopItem() const; CFX_FloatRect GetContentRect() const; - int32_t GetItemIndex(const CFX_FloatPoint& point) const; + int32_t GetItemIndex(const CFX_PointF& point) const; void AddString(const CFX_WideString& str); void SetTopItem(int32_t nIndex); void Select(int32_t nItemIndex); @@ -267,8 +265,8 @@ class CFX_ListCtrl : protected CFX_ListContainer { int32_t FindNext(int32_t nIndex, FX_WCHAR nChar) const; int32_t GetFirstSelected() const; - CFX_FloatPoint InToOut(const CFX_FloatPoint& point) const; - CFX_FloatPoint OutToIn(const CFX_FloatPoint& point) const; + CFX_PointF InToOut(const CFX_PointF& point) const; + CFX_PointF OutToIn(const CFX_PointF& point) const; CFX_FloatRect InToOut(const CFX_FloatRect& rect) const; CFX_FloatRect OutToIn(const CFX_FloatRect& rect) const; @@ -291,7 +289,7 @@ class CFX_ListCtrl : protected CFX_ListContainer { CPWL_List_Notify* m_pNotify; bool m_bNotifyFlag; - CFX_FloatPoint m_ptScrollPos; + CFX_PointF m_ptScrollPos; CPLST_Select m_aSelItems; // for multiple int32_t m_nSelItem; // for single int32_t m_nFootIndex; // for multiple diff --git a/fpdfsdk/ipdfsdk_annothandler.h b/fpdfsdk/ipdfsdk_annothandler.h index 408dcceae..636d161fe 100644 --- a/fpdfsdk/ipdfsdk_annothandler.h +++ b/fpdfsdk/ipdfsdk_annothandler.h @@ -38,7 +38,7 @@ class IPDFSDK_AnnotHandler { CPDFSDK_Annot* pAnnot) = 0; virtual bool HitTest(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual void OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, @@ -55,36 +55,36 @@ class IPDFSDK_AnnotHandler { virtual bool OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, short zDelta, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot::ObservedPtr* pAnnot, uint32_t nFlags, - const CFX_FloatPoint& point) = 0; + const CFX_PointF& point) = 0; virtual bool OnChar(CPDFSDK_Annot* pAnnot, uint32_t nChar, uint32_t nFlags) = 0; diff --git a/fpdfsdk/javascript/Annot.cpp b/fpdfsdk/javascript/Annot.cpp index 1aef4634f..41c71ec41 100644 --- a/fpdfsdk/javascript/Annot.cpp +++ b/fpdfsdk/javascript/Annot.cpp @@ -9,7 +9,7 @@ #include "fpdfsdk/javascript/JS_Define.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" namespace { @@ -19,17 +19,15 @@ CPDFSDK_BAAnnot* ToBAAnnot(CPDFSDK_Annot* annot) { } // namespace -BEGIN_JS_STATIC_CONST(CJS_Annot) -END_JS_STATIC_CONST() +JSConstSpec CJS_Annot::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_Annot) -JS_STATIC_PROP_ENTRY(hidden) -JS_STATIC_PROP_ENTRY(name) -JS_STATIC_PROP_ENTRY(type) -END_JS_STATIC_PROP() +JSPropertySpec CJS_Annot::PropertySpecs[] = { + {"hidden", get_hidden_static, set_hidden_static}, + {"name", get_name_static, set_name_static}, + {"type", get_type_static, set_type_static}, + {0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_Annot) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_Annot::MethodSpecs[] = {{0, 0}}; IMPLEMENT_JS_CLASS(CJS_Annot, Annot) @@ -37,7 +35,9 @@ Annot::Annot(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {} Annot::~Annot() {} -bool Annot::hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Annot::hidden(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsGetting()) { if (!m_pAnnot) { sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); @@ -71,7 +71,9 @@ bool Annot::hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Annot::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Annot::name(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsGetting()) { if (!m_pAnnot) { sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); @@ -92,7 +94,9 @@ bool Annot::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Annot::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Annot::type(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsSetting()) { sError = JSGetStringFromID(IDS_STRING_JSREADONLY); return false; diff --git a/fpdfsdk/javascript/Annot.h b/fpdfsdk/javascript/Annot.h index 39073e671..d9757fa51 100644 --- a/fpdfsdk/javascript/Annot.h +++ b/fpdfsdk/javascript/Annot.h @@ -17,9 +17,9 @@ class Annot : public CJS_EmbedObj { explicit Annot(CJS_Object* pJSObject); ~Annot() override; - bool hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); + bool hidden(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool name(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool type(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); void SetSDKAnnot(CPDFSDK_BAAnnot* annot); diff --git a/fpdfsdk/javascript/Consts.cpp b/fpdfsdk/javascript/Consts.cpp index c224ad0de..82f9b4c94 100644 --- a/fpdfsdk/javascript/Consts.cpp +++ b/fpdfsdk/javascript/Consts.cpp @@ -10,93 +10,92 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -BEGIN_JS_STATIC_CONST(CJS_Border) -JS_STATIC_CONST_ENTRY_STRING(L"s", L"solid") -JS_STATIC_CONST_ENTRY_STRING(L"b", L"beveled") -JS_STATIC_CONST_ENTRY_STRING(L"d", L"dashed") -JS_STATIC_CONST_ENTRY_STRING(L"i", L"inset") -JS_STATIC_CONST_ENTRY_STRING(L"u", L"underline") -END_JS_STATIC_CONST() +JSConstSpec CJS_Border::ConstSpecs[] = { + {"s", JSConstSpec::String, 0, "solid"}, + {"b", JSConstSpec::String, 0, "beveled"}, + {"d", JSConstSpec::String, 0, "dashed"}, + {"i", JSConstSpec::String, 0, "inset"}, + {"u", JSConstSpec::String, 0, "underline"}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Border, border) -BEGIN_JS_STATIC_CONST(CJS_Display) -JS_STATIC_CONST_ENTRY_NUMBER(L"visible", 0) -JS_STATIC_CONST_ENTRY_NUMBER(L"hidden", 1) -JS_STATIC_CONST_ENTRY_NUMBER(L"noPrint", 2) -JS_STATIC_CONST_ENTRY_NUMBER(L"noView", 3) -END_JS_STATIC_CONST() +JSConstSpec CJS_Display::ConstSpecs[] = {{"visible", JSConstSpec::Number, 0, 0}, + {"hidden", JSConstSpec::Number, 1, 0}, + {"noPrint", JSConstSpec::Number, 2, 0}, + {"noView", JSConstSpec::Number, 3, 0}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Display, display) -BEGIN_JS_STATIC_CONST(CJS_Font) -JS_STATIC_CONST_ENTRY_STRING(L"Times", L"Times-Roman") -JS_STATIC_CONST_ENTRY_STRING(L"TimesB", L"Times-Bold") -JS_STATIC_CONST_ENTRY_STRING(L"TimesI", L"Times-Italic") -JS_STATIC_CONST_ENTRY_STRING(L"TimesBI", L"Times-BoldItalic") -JS_STATIC_CONST_ENTRY_STRING(L"Helv", L"Helvetica") -JS_STATIC_CONST_ENTRY_STRING(L"HelvB", L"Helvetica-Bold") -JS_STATIC_CONST_ENTRY_STRING(L"HelvI", L"Helvetica-Oblique") -JS_STATIC_CONST_ENTRY_STRING(L"HelvBI", L"Helvetica-BoldOblique") -JS_STATIC_CONST_ENTRY_STRING(L"Cour", L"Courier") -JS_STATIC_CONST_ENTRY_STRING(L"CourB", L"Courier-Bold") -JS_STATIC_CONST_ENTRY_STRING(L"CourI", L"Courier-Oblique") -JS_STATIC_CONST_ENTRY_STRING(L"CourBI", L"Courier-BoldOblique") -JS_STATIC_CONST_ENTRY_STRING(L"Symbol", L"Symbol") -JS_STATIC_CONST_ENTRY_STRING(L"ZapfD", L"ZapfDingbats") -END_JS_STATIC_CONST() +JSConstSpec CJS_Font::ConstSpecs[] = { + {"Times", JSConstSpec::String, 0, "Times-Roman"}, + {"TimesB", JSConstSpec::String, 0, "Times-Bold"}, + {"TimesI", JSConstSpec::String, 0, "Times-Italic"}, + {"TimesBI", JSConstSpec::String, 0, "Times-BoldItalic"}, + {"Helv", JSConstSpec::String, 0, "Helvetica"}, + {"HelvB", JSConstSpec::String, 0, "Helvetica-Bold"}, + {"HelvI", JSConstSpec::String, 0, "Helvetica-Oblique"}, + {"HelvBI", JSConstSpec::String, 0, "Helvetica-BoldOblique"}, + {"Cour", JSConstSpec::String, 0, "Courier"}, + {"CourB", JSConstSpec::String, 0, "Courier-Bold"}, + {"CourI", JSConstSpec::String, 0, "Courier-Oblique"}, + {"CourBI", JSConstSpec::String, 0, "Courier-BoldOblique"}, + {"Symbol", JSConstSpec::String, 0, "Symbol"}, + {"ZapfD", JSConstSpec::String, 0, "ZapfDingbats"}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Font, font) -BEGIN_JS_STATIC_CONST(CJS_Highlight) -JS_STATIC_CONST_ENTRY_STRING(L"n", L"none") -JS_STATIC_CONST_ENTRY_STRING(L"i", L"invert") -JS_STATIC_CONST_ENTRY_STRING(L"p", L"push") -JS_STATIC_CONST_ENTRY_STRING(L"o", L"outline") -END_JS_STATIC_CONST() +JSConstSpec CJS_Highlight::ConstSpecs[] = { + {"n", JSConstSpec::String, 0, "none"}, + {"i", JSConstSpec::String, 0, "invert"}, + {"p", JSConstSpec::String, 0, "push"}, + {"o", JSConstSpec::String, 0, "outline"}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Highlight, highlight) -BEGIN_JS_STATIC_CONST(CJS_Position) -JS_STATIC_CONST_ENTRY_NUMBER(L"textOnly", 0) -JS_STATIC_CONST_ENTRY_NUMBER(L"iconOnly", 1) -JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextV", 2) -JS_STATIC_CONST_ENTRY_NUMBER(L"textIconV", 3) -JS_STATIC_CONST_ENTRY_NUMBER(L"iconTextH", 4) -JS_STATIC_CONST_ENTRY_NUMBER(L"textIconH", 5) -JS_STATIC_CONST_ENTRY_NUMBER(L"overlay", 6) -END_JS_STATIC_CONST() +JSConstSpec CJS_Position::ConstSpecs[] = { + {"textOnly", JSConstSpec::Number, 0, 0}, + {"iconOnly", JSConstSpec::Number, 1, 0}, + {"iconTextV", JSConstSpec::Number, 2, 0}, + {"textIconV", JSConstSpec::Number, 3, 0}, + {"iconTextH", JSConstSpec::Number, 4, 0}, + {"textIconH", JSConstSpec::Number, 5, 0}, + {"overlay", JSConstSpec::Number, 6, 0}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Position, position) -BEGIN_JS_STATIC_CONST(CJS_ScaleHow) -JS_STATIC_CONST_ENTRY_NUMBER(L"proportional", 0) -JS_STATIC_CONST_ENTRY_NUMBER(L"anamorphic", 1) -END_JS_STATIC_CONST() +JSConstSpec CJS_ScaleHow::ConstSpecs[] = { + {"proportional", JSConstSpec::Number, 0, 0}, + {"anamorphic", JSConstSpec::Number, 1, 0}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_ScaleHow, scaleHow) -BEGIN_JS_STATIC_CONST(CJS_ScaleWhen) -JS_STATIC_CONST_ENTRY_NUMBER(L"always", 0) -JS_STATIC_CONST_ENTRY_NUMBER(L"never", 1) -JS_STATIC_CONST_ENTRY_NUMBER(L"tooBig", 2) -JS_STATIC_CONST_ENTRY_NUMBER(L"tooSmall", 3) -END_JS_STATIC_CONST() +JSConstSpec CJS_ScaleWhen::ConstSpecs[] = { + {"always", JSConstSpec::Number, 0, 0}, + {"never", JSConstSpec::Number, 1, 0}, + {"tooBig", JSConstSpec::Number, 2, 0}, + {"tooSmall", JSConstSpec::Number, 3, 0}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_ScaleWhen, scaleWhen) -BEGIN_JS_STATIC_CONST(CJS_Style) -JS_STATIC_CONST_ENTRY_STRING(L"ch", L"check") -JS_STATIC_CONST_ENTRY_STRING(L"cr", L"cross") -JS_STATIC_CONST_ENTRY_STRING(L"di", L"diamond") -JS_STATIC_CONST_ENTRY_STRING(L"ci", L"circle") -JS_STATIC_CONST_ENTRY_STRING(L"st", L"star") -JS_STATIC_CONST_ENTRY_STRING(L"sq", L"square") -END_JS_STATIC_CONST() +JSConstSpec CJS_Style::ConstSpecs[] = { + {"ch", JSConstSpec::String, 0, "check"}, + {"cr", JSConstSpec::String, 0, "cross"}, + {"di", JSConstSpec::String, 0, "diamond"}, + {"ci", JSConstSpec::String, 0, "circle"}, + {"st", JSConstSpec::String, 0, "star"}, + {"sq", JSConstSpec::String, 0, "square"}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Style, style) -BEGIN_JS_STATIC_CONST(CJS_Zoomtype) -JS_STATIC_CONST_ENTRY_STRING(L"none", L"NoVary") -JS_STATIC_CONST_ENTRY_STRING(L"fitP", L"FitPage") -JS_STATIC_CONST_ENTRY_STRING(L"fitW", L"FitWidth") -JS_STATIC_CONST_ENTRY_STRING(L"fitH", L"FitHeight") -JS_STATIC_CONST_ENTRY_STRING(L"fitV", L"FitVisibleWidth") -JS_STATIC_CONST_ENTRY_STRING(L"pref", L"Preferred") -JS_STATIC_CONST_ENTRY_STRING(L"refW", L"ReflowWidth") -END_JS_STATIC_CONST() +JSConstSpec CJS_Zoomtype::ConstSpecs[] = { + {"none", JSConstSpec::String, 0, "NoVary"}, + {"fitP", JSConstSpec::String, 0, "FitPage"}, + {"fitW", JSConstSpec::String, 0, "FitWidth"}, + {"fitH", JSConstSpec::String, 0, "FitHeight"}, + {"fitV", JSConstSpec::String, 0, "FitVisibleWidth"}, + {"pref", JSConstSpec::String, 0, "Preferred"}, + {"refW", JSConstSpec::String, 0, "ReflowWidth"}, + {0, JSConstSpec::Number, 0, 0}}; IMPLEMENT_JS_CLASS_CONST(CJS_Zoomtype, zoomtype) #define GLOBAL_STRING(rt, name, value) \ diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp index 4bf1afd5a..a45b8b9ea 100644 --- a/fpdfsdk/javascript/Document.cpp +++ b/fpdfsdk/javascript/Document.cpp @@ -6,6 +6,7 @@ #include "fpdfsdk/javascript/Document.h" +#include <algorithm> #include <utility> #include <vector> @@ -30,20 +31,17 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" #include "fpdfsdk/javascript/app.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" #include "fpdfsdk/javascript/resource.h" #include "third_party/base/numerics/safe_math.h" #include "third_party/base/ptr_util.h" -BEGIN_JS_STATIC_CONST(CJS_PrintParamsObj) -END_JS_STATIC_CONST() +JSConstSpec CJS_PrintParamsObj::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_PrintParamsObj) -END_JS_STATIC_PROP() +JSPropertySpec CJS_PrintParamsObj::PropertySpecs[] = {{0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_PrintParamsObj) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_PrintParamsObj::MethodSpecs[] = {{0, 0}}; IMPLEMENT_JS_CLASS(CJS_PrintParamsObj, PrintParamsObj) @@ -62,88 +60,88 @@ PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject) #define MINWIDTH 5.0f #define MINHEIGHT 5.0f -BEGIN_JS_STATIC_CONST(CJS_Document) -END_JS_STATIC_CONST() - -BEGIN_JS_STATIC_PROP(CJS_Document) -JS_STATIC_PROP_ENTRY(ADBE) -JS_STATIC_PROP_ENTRY(author) -JS_STATIC_PROP_ENTRY(baseURL) -JS_STATIC_PROP_ENTRY(bookmarkRoot) -JS_STATIC_PROP_ENTRY(calculate) -JS_STATIC_PROP_ENTRY(Collab) -JS_STATIC_PROP_ENTRY(creationDate) -JS_STATIC_PROP_ENTRY(creator) -JS_STATIC_PROP_ENTRY(delay) -JS_STATIC_PROP_ENTRY(dirty) -JS_STATIC_PROP_ENTRY(documentFileName) -JS_STATIC_PROP_ENTRY(external) -JS_STATIC_PROP_ENTRY(filesize) -JS_STATIC_PROP_ENTRY(icons) -JS_STATIC_PROP_ENTRY(info) -JS_STATIC_PROP_ENTRY(keywords) -JS_STATIC_PROP_ENTRY(layout) -JS_STATIC_PROP_ENTRY(media) -JS_STATIC_PROP_ENTRY(modDate) -JS_STATIC_PROP_ENTRY(mouseX) -JS_STATIC_PROP_ENTRY(mouseY) -JS_STATIC_PROP_ENTRY(numFields) -JS_STATIC_PROP_ENTRY(numPages) -JS_STATIC_PROP_ENTRY(pageNum) -JS_STATIC_PROP_ENTRY(pageWindowRect) -JS_STATIC_PROP_ENTRY(path) -JS_STATIC_PROP_ENTRY(producer) -JS_STATIC_PROP_ENTRY(subject) -JS_STATIC_PROP_ENTRY(title) -JS_STATIC_PROP_ENTRY(URL) -JS_STATIC_PROP_ENTRY(zoom) -JS_STATIC_PROP_ENTRY(zoomType) -END_JS_STATIC_PROP() - -BEGIN_JS_STATIC_METHOD(CJS_Document) -JS_STATIC_METHOD_ENTRY(addAnnot) -JS_STATIC_METHOD_ENTRY(addField) -JS_STATIC_METHOD_ENTRY(addLink) -JS_STATIC_METHOD_ENTRY(addIcon) -JS_STATIC_METHOD_ENTRY(calculateNow) -JS_STATIC_METHOD_ENTRY(closeDoc) -JS_STATIC_METHOD_ENTRY(createDataObject) -JS_STATIC_METHOD_ENTRY(deletePages) -JS_STATIC_METHOD_ENTRY(exportAsText) -JS_STATIC_METHOD_ENTRY(exportAsFDF) -JS_STATIC_METHOD_ENTRY(exportAsXFDF) -JS_STATIC_METHOD_ENTRY(extractPages) -JS_STATIC_METHOD_ENTRY(getAnnot) -JS_STATIC_METHOD_ENTRY(getAnnots) -JS_STATIC_METHOD_ENTRY(getAnnot3D) -JS_STATIC_METHOD_ENTRY(getAnnots3D) -JS_STATIC_METHOD_ENTRY(getField) -JS_STATIC_METHOD_ENTRY(getIcon) -JS_STATIC_METHOD_ENTRY(getLinks) -JS_STATIC_METHOD_ENTRY(getNthFieldName) -JS_STATIC_METHOD_ENTRY(getOCGs) -JS_STATIC_METHOD_ENTRY(getPageBox) -JS_STATIC_METHOD_ENTRY(getPageNthWord) -JS_STATIC_METHOD_ENTRY(getPageNthWordQuads) -JS_STATIC_METHOD_ENTRY(getPageNumWords) -JS_STATIC_METHOD_ENTRY(getPrintParams) -JS_STATIC_METHOD_ENTRY(getURL) -JS_STATIC_METHOD_ENTRY(gotoNamedDest) -JS_STATIC_METHOD_ENTRY(importAnFDF) -JS_STATIC_METHOD_ENTRY(importAnXFDF) -JS_STATIC_METHOD_ENTRY(importTextData) -JS_STATIC_METHOD_ENTRY(insertPages) -JS_STATIC_METHOD_ENTRY(mailForm) -JS_STATIC_METHOD_ENTRY(print) -JS_STATIC_METHOD_ENTRY(removeField) -JS_STATIC_METHOD_ENTRY(replacePages) -JS_STATIC_METHOD_ENTRY(resetForm) -JS_STATIC_METHOD_ENTRY(removeIcon) -JS_STATIC_METHOD_ENTRY(saveAs) -JS_STATIC_METHOD_ENTRY(submitForm) -JS_STATIC_METHOD_ENTRY(syncAnnotScan) -JS_STATIC_METHOD_ENTRY(mailDoc) -END_JS_STATIC_METHOD() +JSConstSpec CJS_Document::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; + +JSPropertySpec CJS_Document::PropertySpecs[] = { + {"ADBE", get_ADBE_static, set_ADBE_static}, + {"author", get_author_static, set_author_static}, + {"baseURL", get_baseURL_static, set_baseURL_static}, + {"bookmarkRoot", get_bookmarkRoot_static, set_bookmarkRoot_static}, + {"calculate", get_calculate_static, set_calculate_static}, + {"Collab", get_Collab_static, set_Collab_static}, + {"creationDate", get_creationDate_static, set_creationDate_static}, + {"creator", get_creator_static, set_creator_static}, + {"delay", get_delay_static, set_delay_static}, + {"dirty", get_dirty_static, set_dirty_static}, + {"documentFileName", get_documentFileName_static, + set_documentFileName_static}, + {"external", get_external_static, set_external_static}, + {"filesize", get_filesize_static, set_filesize_static}, + {"icons", get_icons_static, set_icons_static}, + {"info", get_info_static, set_info_static}, + {"keywords", get_keywords_static, set_keywords_static}, + {"layout", get_layout_static, set_layout_static}, + {"media", get_media_static, set_media_static}, + {"modDate", get_modDate_static, set_modDate_static}, + {"mouseX", get_mouseX_static, set_mouseX_static}, + {"mouseY", get_mouseY_static, set_mouseY_static}, + {"numFields", get_numFields_static, set_numFields_static}, + {"numPages", get_numPages_static, set_numPages_static}, + {"pageNum", get_pageNum_static, set_pageNum_static}, + {"pageWindowRect", get_pageWindowRect_static, set_pageWindowRect_static}, + {"path", get_path_static, set_path_static}, + {"producer", get_producer_static, set_producer_static}, + {"subject", get_subject_static, set_subject_static}, + {"title", get_title_static, set_title_static}, + {"URL", get_URL_static, set_URL_static}, + {"zoom", get_zoom_static, set_zoom_static}, + {"zoomType", get_zoomType_static, set_zoomType_static}, + {0, 0, 0}}; + +JSMethodSpec CJS_Document::MethodSpecs[] = { + {"addAnnot", addAnnot_static}, + {"addField", addField_static}, + {"addLink", addLink_static}, + {"addIcon", addIcon_static}, + {"calculateNow", calculateNow_static}, + {"closeDoc", closeDoc_static}, + {"createDataObject", createDataObject_static}, + {"deletePages", deletePages_static}, + {"exportAsText", exportAsText_static}, + {"exportAsFDF", exportAsFDF_static}, + {"exportAsXFDF", exportAsXFDF_static}, + {"extractPages", extractPages_static}, + {"getAnnot", getAnnot_static}, + {"getAnnots", getAnnots_static}, + {"getAnnot3D", getAnnot3D_static}, + {"getAnnots3D", getAnnots3D_static}, + {"getField", getField_static}, + {"getIcon", getIcon_static}, + {"getLinks", getLinks_static}, + {"getNthFieldName", getNthFieldName_static}, + {"getOCGs", getOCGs_static}, + {"getPageBox", getPageBox_static}, + {"getPageNthWord", getPageNthWord_static}, + {"getPageNthWordQuads", getPageNthWordQuads_static}, + {"getPageNumWords", getPageNumWords_static}, + {"getPrintParams", getPrintParams_static}, + {"getURL", getURL_static}, + {"gotoNamedDest", gotoNamedDest_static}, + {"importAnFDF", importAnFDF_static}, + {"importAnXFDF", importAnXFDF_static}, + {"importTextData", importTextData_static}, + {"insertPages", insertPages_static}, + {"mailForm", mailForm_static}, + {"print", print_static}, + {"removeField", removeField_static}, + {"replacePages", replacePages_static}, + {"resetForm", resetForm_static}, + {"removeIcon", removeIcon_static}, + {"saveAs", saveAs_static}, + {"submitForm", submitForm_static}, + {"syncAnnotScan", syncAnnotScan_static}, + {"mailDoc", mailDoc_static}, + {0, 0}}; IMPLEMENT_JS_CLASS(CJS_Document, Document) @@ -163,7 +161,7 @@ Document::~Document() { } // the total number of fileds in document. -bool Document::numFields(IJS_Context* cc, +bool Document::numFields(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -180,7 +178,7 @@ bool Document::numFields(IJS_Context* cc, return true; } -bool Document::dirty(IJS_Context* cc, +bool Document::dirty(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!m_pFormFillEnv) { @@ -189,28 +187,28 @@ bool Document::dirty(IJS_Context* cc, } if (vp.IsGetting()) { vp << !!m_pFormFillEnv->GetChangeMark(); - } else { - bool bChanged = false; - vp >> bChanged; - - if (bChanged) - m_pFormFillEnv->SetChangeMark(); - else - m_pFormFillEnv->ClearChangeMark(); + return true; } + bool bChanged = false; + vp >> bChanged; + if (bChanged) + m_pFormFillEnv->SetChangeMark(); + else + m_pFormFillEnv->ClearChangeMark(); + return true; } -bool Document::ADBE(IJS_Context* cc, +bool Document::ADBE(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsGetting()) - vp.GetJSValue()->SetNull(CJS_Runtime::FromContext(cc)); + vp.GetJSValue()->SetNull(pRuntime); return true; } -bool Document::pageNum(IJS_Context* cc, +bool Document::pageNum(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!m_pFormFillEnv) { @@ -218,27 +216,24 @@ bool Document::pageNum(IJS_Context* cc, return false; } if (vp.IsGetting()) { - if (CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetCurrentView()) { + if (CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetCurrentView()) vp << pPageView->GetPageIndex(); - } - } else { - int iPageCount = m_pFormFillEnv->GetPageCount(); - int iPageNum = 0; - vp >> iPageNum; - - if (iPageNum >= 0 && iPageNum < iPageCount) { - m_pFormFillEnv->JS_docgotoPage(iPageNum); - } else if (iPageNum >= iPageCount) { - m_pFormFillEnv->JS_docgotoPage(iPageCount - 1); - } else if (iPageNum < 0) { - m_pFormFillEnv->JS_docgotoPage(0); - } + return true; } + int iPageCount = m_pFormFillEnv->GetPageCount(); + int iPageNum = 0; + vp >> iPageNum; + if (iPageNum >= 0 && iPageNum < iPageCount) + m_pFormFillEnv->JS_docgotoPage(iPageNum); + else if (iPageNum >= iPageCount) + m_pFormFillEnv->JS_docgotoPage(iPageCount - 1); + else if (iPageNum < 0) + m_pFormFillEnv->JS_docgotoPage(0); return true; } -bool Document::addAnnot(IJS_Context* cc, +bool Document::addAnnot(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -246,7 +241,7 @@ bool Document::addAnnot(IJS_Context* cc, return true; } -bool Document::addField(IJS_Context* cc, +bool Document::addField(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -254,7 +249,7 @@ bool Document::addField(IJS_Context* cc, return true; } -bool Document::exportAsText(IJS_Context* cc, +bool Document::exportAsText(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -262,7 +257,7 @@ bool Document::exportAsText(IJS_Context* cc, return true; } -bool Document::exportAsFDF(IJS_Context* cc, +bool Document::exportAsFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -270,7 +265,7 @@ bool Document::exportAsFDF(IJS_Context* cc, return true; } -bool Document::exportAsXFDF(IJS_Context* cc, +bool Document::exportAsXFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -283,7 +278,7 @@ bool Document::exportAsXFDF(IJS_Context* cc, // note: the paremter cName, this is clue how to treat if the cName is not a // valiable filed name in this document -bool Document::getField(IJS_Context* cc, +bool Document::getField(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -295,8 +290,6 @@ bool Document::getField(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); CFX_WideString wideName = params[0].ToCFXWideString(pRuntime); CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); CPDF_InterForm* pPDFForm = pInterForm->GetInterForm(); @@ -307,17 +300,19 @@ bool Document::getField(IJS_Context* cc, v8::Local<v8::Object> pFieldObj = pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID); + if (pFieldObj.IsEmpty()) + return false; + CJS_Field* pJSField = static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pFieldObj)); Field* pField = static_cast<Field*>(pJSField->GetEmbedObject()); pField->AttachField(this, wideName); - vRet = CJS_Value(pRuntime, pJSField); return true; } // Gets the name of the nth field in the document -bool Document::getNthFieldName(IJS_Context* cc, +bool Document::getNthFieldName(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -329,8 +324,6 @@ bool Document::getNthFieldName(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); int nIndex = params[0].ToInt(pRuntime); if (nIndex < 0) { sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR); @@ -346,7 +339,7 @@ bool Document::getNthFieldName(IJS_Context* cc, return true; } -bool Document::importAnFDF(IJS_Context* cc, +bool Document::importAnFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -354,7 +347,7 @@ bool Document::importAnFDF(IJS_Context* cc, return true; } -bool Document::importAnXFDF(IJS_Context* cc, +bool Document::importAnXFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -362,7 +355,7 @@ bool Document::importAnXFDF(IJS_Context* cc, return true; } -bool Document::importTextData(IJS_Context* cc, +bool Document::importTextData(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -373,7 +366,7 @@ bool Document::importTextData(IJS_Context* cc, // exports the form data and mails the resulting fdf file as an attachment to // all recipients. // comment: need reader supports -bool Document::mailForm(IJS_Context* cc, +bool Document::mailForm(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -385,10 +378,6 @@ bool Document::mailForm(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION); return false; } - - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - int iLength = params.size(); bool bUI = iLength > 0 ? params[0].ToBool(pRuntime) : true; CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString(pRuntime) : L""; @@ -397,14 +386,13 @@ bool Document::mailForm(IJS_Context* cc, CFX_WideString cSubject = iLength > 4 ? params[4].ToCFXWideString(pRuntime) : L""; CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString(pRuntime) : L""; - CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); CFX_ByteTextBuf textBuf; if (!pInterForm->ExportFormToFDFTextBuf(textBuf)) return false; pRuntime->BeginBlock(); - CPDFSDK_FormFillEnvironment* pFormFillEnv = pContext->GetFormFillEnv(); + CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); pFormFillEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str()); @@ -412,7 +400,7 @@ bool Document::mailForm(IJS_Context* cc, return true; } -bool Document::print(IJS_Context* cc, +bool Document::print(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -420,10 +408,6 @@ bool Document::print(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - bool bUI = true; int nStart = 0; int nEnd = 0; @@ -432,7 +416,6 @@ bool Document::print(IJS_Context* cc, bool bPrintAsImage = false; bool bReverse = false; bool bAnnotations = false; - int nlength = params.size(); if (nlength == 9) { if (params[8].GetType() == CJS_Value::VT_object) { @@ -485,7 +468,7 @@ bool Document::print(IJS_Context* cc, // comment: // note: if the filed name is not rational, adobe is dumb for it. -bool Document::removeField(IJS_Context* cc, +bool Document::removeField(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -502,8 +485,6 @@ bool Document::removeField(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); CFX_WideString sFieldName = params[0].ToCFXWideString(pRuntime); CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); std::vector<CPDFSDK_Annot::ObservedPtr> widgets; @@ -546,7 +527,7 @@ bool Document::removeField(IJS_Context* cc, // comment: // note: if the fields names r not rational, aodbe is dumb for it. -bool Document::resetForm(IJS_Context* cc, +bool Document::resetForm(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -571,9 +552,6 @@ bool Document::resetForm(IJS_Context* cc, return true; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - switch (params[0].GetType()) { default: aName.Attach(params[0].ToV8Array(pRuntime)); @@ -600,7 +578,7 @@ bool Document::resetForm(IJS_Context* cc, return true; } -bool Document::saveAs(IJS_Context* cc, +bool Document::saveAs(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -608,14 +586,14 @@ bool Document::saveAs(IJS_Context* cc, return true; } -bool Document::syncAnnotScan(IJS_Context* cc, +bool Document::syncAnnotScan(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Document::submitForm(IJS_Context* cc, +bool Document::submitForm(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -628,8 +606,7 @@ bool Document::submitForm(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); + CJS_Array aFields; CFX_WideString strURL; bool bFDF = true; @@ -698,20 +675,17 @@ void Document::SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv) { m_pFormFillEnv.Reset(pFormFillEnv); } -bool Document::bookmarkRoot(IJS_Context* cc, +bool Document::bookmarkRoot(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::mailDoc(IJS_Context* cc, +bool Document::mailDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - // TODO(tsepez): Check maximum number of allowed params. - bool bUI = true; CFX_WideString cTo = L""; CFX_WideString cCc = L""; @@ -719,8 +693,6 @@ bool Document::mailDoc(IJS_Context* cc, CFX_WideString cSubject = L""; CFX_WideString cMsg = L""; - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - if (params.size() >= 1) bUI = params[0].ToBool(pRuntime); if (params.size() >= 2) @@ -761,17 +733,16 @@ bool Document::mailDoc(IJS_Context* cc, pFormFillEnv->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str()); pRuntime->EndBlock(); - return true; } -bool Document::author(IJS_Context* cc, +bool Document::author(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "Author", sError); + return getPropertyInternal(pRuntime, vp, "Author", sError); } -bool Document::info(IJS_Context* cc, +bool Document::info(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -797,22 +768,25 @@ bool Document::info(IJS_Context* cc, CFX_WideString cwModDate = pDictionary->GetUnicodeTextFor("ModDate"); CFX_WideString cwTrapped = pDictionary->GetUnicodeTextFor("Trapped"); - CJS_Context* pContext = (CJS_Context*)cc; - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(-1); - pRuntime->PutObjectProperty(pObj, L"Author", pRuntime->NewString(cwAuthor)); - pRuntime->PutObjectProperty(pObj, L"Title", pRuntime->NewString(cwTitle)); - pRuntime->PutObjectProperty(pObj, L"Subject", pRuntime->NewString(cwSubject)); + pRuntime->PutObjectProperty(pObj, L"Author", + pRuntime->NewString(cwAuthor.AsStringC())); + pRuntime->PutObjectProperty(pObj, L"Title", + pRuntime->NewString(cwTitle.AsStringC())); + pRuntime->PutObjectProperty(pObj, L"Subject", + pRuntime->NewString(cwSubject.AsStringC())); pRuntime->PutObjectProperty(pObj, L"Keywords", - pRuntime->NewString(cwKeywords)); - pRuntime->PutObjectProperty(pObj, L"Creator", pRuntime->NewString(cwCreator)); + pRuntime->NewString(cwKeywords.AsStringC())); + pRuntime->PutObjectProperty(pObj, L"Creator", + pRuntime->NewString(cwCreator.AsStringC())); pRuntime->PutObjectProperty(pObj, L"Producer", - pRuntime->NewString(cwProducer)); + pRuntime->NewString(cwProducer.AsStringC())); pRuntime->PutObjectProperty(pObj, L"CreationDate", - pRuntime->NewString(cwCreationDate)); - pRuntime->PutObjectProperty(pObj, L"ModDate", pRuntime->NewString(cwModDate)); - pRuntime->PutObjectProperty(pObj, L"Trapped", pRuntime->NewString(cwTrapped)); + pRuntime->NewString(cwCreationDate.AsStringC())); + pRuntime->PutObjectProperty(pObj, L"ModDate", + pRuntime->NewString(cwModDate.AsStringC())); + pRuntime->PutObjectProperty(pObj, L"Trapped", + pRuntime->NewString(cwTrapped.AsStringC())); // It's to be compatible to non-standard info dictionary. for (const auto& it : *pDictionary) { @@ -821,7 +795,8 @@ bool Document::info(IJS_Context* cc, CFX_WideString wsKey = CFX_WideString::FromUTF8(bsKey.AsStringC()); if (pValueObj->IsString() || pValueObj->IsName()) { pRuntime->PutObjectProperty( - pObj, wsKey, pRuntime->NewString(pValueObj->GetUnicodeText())); + pObj, wsKey, + pRuntime->NewString(pValueObj->GetUnicodeText().AsStringC())); } else if (pValueObj->IsNumber()) { pRuntime->PutObjectProperty(pObj, wsKey, pRuntime->NewNumber(pValueObj->GetNumber())); @@ -834,7 +809,7 @@ bool Document::info(IJS_Context* cc, return true; } -bool Document::getPropertyInternal(IJS_Context* cc, +bool Document::getPropertyInternal(CJS_Runtime* pRuntime, CJS_PropValue& vp, const CFX_ByteString& propName, CFX_WideString& sError) { @@ -862,19 +837,19 @@ bool Document::getPropertyInternal(IJS_Context* cc, return true; } -bool Document::creationDate(IJS_Context* cc, +bool Document::creationDate(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "CreationDate", sError); + return getPropertyInternal(pRuntime, vp, "CreationDate", sError); } -bool Document::creator(IJS_Context* cc, +bool Document::creator(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "Creator", sError); + return getPropertyInternal(pRuntime, vp, "Creator", sError); } -bool Document::delay(IJS_Context* cc, +bool Document::delay(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!m_pFormFillEnv) { @@ -883,59 +858,60 @@ bool Document::delay(IJS_Context* cc, } if (vp.IsGetting()) { vp << m_bDelay; - } else { - if (!m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY)) { - sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION); - return false; - } - vp >> m_bDelay; - if (m_bDelay) { - m_DelayData.clear(); - } else { - std::list<std::unique_ptr<CJS_DelayData>> DelayDataToProcess; - DelayDataToProcess.swap(m_DelayData); - for (const auto& pData : DelayDataToProcess) - Field::DoDelay(m_pFormFillEnv.Get(), pData.get()); - } + return true; + } + if (!m_pFormFillEnv->GetPermissions(FPDFPERM_MODIFY)) { + sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION); + return false; } + vp >> m_bDelay; + if (m_bDelay) { + m_DelayData.clear(); + return true; + } + std::list<std::unique_ptr<CJS_DelayData>> DelayDataToProcess; + DelayDataToProcess.swap(m_DelayData); + for (const auto& pData : DelayDataToProcess) + Field::DoDelay(m_pFormFillEnv.Get(), pData.get()); + return true; } -bool Document::keywords(IJS_Context* cc, +bool Document::keywords(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "Keywords", sError); + return getPropertyInternal(pRuntime, vp, "Keywords", sError); } -bool Document::modDate(IJS_Context* cc, +bool Document::modDate(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "ModDate", sError); + return getPropertyInternal(pRuntime, vp, "ModDate", sError); } -bool Document::producer(IJS_Context* cc, +bool Document::producer(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "Producer", sError); + return getPropertyInternal(pRuntime, vp, "Producer", sError); } -bool Document::subject(IJS_Context* cc, +bool Document::subject(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - return getPropertyInternal(cc, vp, "Subject", sError); + return getPropertyInternal(pRuntime, vp, "Subject", sError); } -bool Document::title(IJS_Context* cc, +bool Document::title(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!m_pFormFillEnv || !m_pFormFillEnv->GetUnderlyingDocument()) { sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - return getPropertyInternal(cc, vp, "Title", sError); + return getPropertyInternal(pRuntime, vp, "Title", sError); } -bool Document::numPages(IJS_Context* cc, +bool Document::numPages(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -950,7 +926,7 @@ bool Document::numPages(IJS_Context* cc, return true; } -bool Document::external(IJS_Context* cc, +bool Document::external(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { // In Chrome case, should always return true. @@ -960,7 +936,7 @@ bool Document::external(IJS_Context* cc, return true; } -bool Document::filesize(IJS_Context* cc, +bool Document::filesize(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -971,19 +947,21 @@ bool Document::filesize(IJS_Context* cc, return true; } -bool Document::mouseX(IJS_Context* cc, +bool Document::mouseX(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::mouseY(IJS_Context* cc, +bool Document::mouseY(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::URL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Document::URL(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsSetting()) { sError = JSGetStringFromID(IDS_STRING_JSREADONLY); return false; @@ -996,7 +974,7 @@ bool Document::URL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::baseURL(IJS_Context* cc, +bool Document::baseURL(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsGetting()) { @@ -1007,7 +985,7 @@ bool Document::baseURL(IJS_Context* cc, return true; } -bool Document::calculate(IJS_Context* cc, +bool Document::calculate(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!m_pFormFillEnv) { @@ -1017,15 +995,15 @@ bool Document::calculate(IJS_Context* cc, CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); if (vp.IsGetting()) { vp << !!pInterForm->IsCalculateEnabled(); - } else { - bool bCalculate; - vp >> bCalculate; - pInterForm->EnableCalculate(bCalculate); + return true; } + bool bCalculate; + vp >> bCalculate; + pInterForm->EnableCalculate(bCalculate); return true; } -bool Document::documentFileName(IJS_Context* cc, +bool Document::documentFileName(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -1050,7 +1028,7 @@ bool Document::documentFileName(IJS_Context* cc, return true; } -bool Document::path(IJS_Context* cc, +bool Document::path(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -1065,40 +1043,40 @@ bool Document::path(IJS_Context* cc, return true; } -bool Document::pageWindowRect(IJS_Context* cc, +bool Document::pageWindowRect(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::layout(IJS_Context* cc, +bool Document::layout(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::addLink(IJS_Context* cc, +bool Document::addLink(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Document::closeDoc(IJS_Context* cc, +bool Document::closeDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Document::getPageBox(IJS_Context* cc, +bool Document::getPageBox(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Document::getAnnot(IJS_Context* cc, +bool Document::getAnnot(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1110,8 +1088,6 @@ bool Document::getAnnot(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); int nPageNo = params[0].ToInt(pRuntime); CFX_WideString swAnnotName = params[1].ToCFXWideString(pRuntime); CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(nPageNo); @@ -1138,19 +1114,13 @@ bool Document::getAnnot(IJS_Context* cc, CJS_Annot* pJS_Annot = static_cast<CJS_Annot*>(pRuntime->GetObjectPrivate(pObj)); - if (!pJS_Annot) - return false; - Annot* pAnnot = static_cast<Annot*>(pJS_Annot->GetEmbedObject()); - if (!pAnnot) - return false; - pAnnot->SetSDKAnnot(pSDKBAAnnot); vRet = CJS_Value(pRuntime, pJS_Annot); return true; } -bool Document::getAnnots(IJS_Context* cc, +bool Document::getAnnots(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1158,9 +1128,6 @@ bool Document::getAnnots(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - // TODO(tonikitoo): Add support supported parameters as per // the PDF spec. @@ -1185,13 +1152,7 @@ bool Document::getAnnots(IJS_Context* cc, CJS_Annot* pJS_Annot = static_cast<CJS_Annot*>(pRuntime->GetObjectPrivate(pObj)); - if (!pJS_Annot) - return false; - Annot* pAnnot = static_cast<Annot*>(pJS_Annot->GetEmbedObject()); - if (!pAnnot) - return false; - pAnnot->SetSDKAnnot(static_cast<CPDFSDK_BAAnnot*>(pSDKAnnotCur.Get())); annots.SetElement(pRuntime, i, CJS_Value(pRuntime, pJS_Annot)); } @@ -1200,29 +1161,29 @@ bool Document::getAnnots(IJS_Context* cc, return true; } -bool Document::getAnnot3D(IJS_Context* cc, +bool Document::getAnnot3D(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - vRet.SetNull(CJS_Runtime::FromContext(cc)); + vRet.SetNull(pRuntime); return true; } -bool Document::getAnnots3D(IJS_Context* cc, +bool Document::getAnnots3D(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Document::getOCGs(IJS_Context* cc, +bool Document::getOCGs(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Document::getLinks(IJS_Context* cc, +bool Document::getLinks(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1234,7 +1195,7 @@ bool Document::IsEnclosedInRect(CFX_FloatRect rect, CFX_FloatRect LinkRect) { rect.right >= LinkRect.right && rect.bottom >= LinkRect.bottom); } -bool Document::addIcon(IJS_Context* cc, +bool Document::addIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1243,10 +1204,7 @@ bool Document::addIcon(IJS_Context* cc, return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); CFX_WideString swIconName = params[0].ToCFXWideString(pRuntime); - if (params[1].GetType() != CJS_Value::VT_object) { sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR); return false; @@ -1258,35 +1216,30 @@ bool Document::addIcon(IJS_Context* cc, return false; } - CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject(pRuntime)->GetEmbedObject(); - if (!pEmbedObj) { + if (!params[1].ToCJSObject(pRuntime)->GetEmbedObject()) { sError = JSGetStringFromID(IDS_STRING_JSTYPEERROR); return false; } - m_Icons.push_back(pdfium::MakeUnique<IconElement>( - swIconName, static_cast<Icon*>(pEmbedObj))); + m_IconNames.push_back(swIconName); return true; } -bool Document::icons(IJS_Context* cc, +bool Document::icons(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { sError = JSGetStringFromID(IDS_STRING_JSREADONLY); return false; } - - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - if (m_Icons.empty()) { + if (m_IconNames.empty()) { vp.GetJSValue()->SetNull(pRuntime); return true; } CJS_Array Icons; - int i = 0; - for (const auto& pIconElement : m_Icons) { + for (const auto& name : m_IconNames) { v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID); if (pObj.IsEmpty()) @@ -1294,15 +1247,8 @@ bool Document::icons(IJS_Context* cc, CJS_Icon* pJS_Icon = static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj)); - if (!pJS_Icon) - return false; - Icon* pIcon = static_cast<Icon*>(pJS_Icon->GetEmbedObject()); - if (!pIcon) - return false; - - pIcon->SetStream(pIconElement->IconStream->GetStream()); - pIcon->SetIconName(pIconElement->IconName); + pIcon->SetIconName(name); Icons.SetElement(pRuntime, i++, CJS_Value(pRuntime, pJS_Icon)); } @@ -1310,7 +1256,7 @@ bool Document::icons(IJS_Context* cc, return true; } -bool Document::getIcon(IJS_Context* cc, +bool Document::getIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1319,41 +1265,24 @@ bool Document::getIcon(IJS_Context* cc, return false; } - if (m_Icons.empty()) - return false; - - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString swIconName = params[0].ToCFXWideString(pRuntime); + auto it = std::find(m_IconNames.begin(), m_IconNames.end(), swIconName); + if (it == m_IconNames.end()) + return false; - for (const auto& pIconElement : m_Icons) { - if (pIconElement->IconName != swIconName) - continue; - - v8::Local<v8::Object> pObj = - pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID); - if (pObj.IsEmpty()) - return false; - - CJS_Icon* pJS_Icon = - static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj)); - if (!pJS_Icon) - return false; - - Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject(); - if (!pIcon) - return false; - - pIcon->SetIconName(swIconName); - pIcon->SetStream(pIconElement->IconStream->GetStream()); - - vRet = CJS_Value(pRuntime, pJS_Icon); - return true; - } + v8::Local<v8::Object> pObj = + pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID); + if (pObj.IsEmpty()) + return false; - return false; + CJS_Icon* pJS_Icon = static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj)); + Icon* pIcon = static_cast<Icon*>(pJS_Icon->GetEmbedObject()); + pIcon->SetIconName(*it); + vRet = CJS_Value(pRuntime, pJS_Icon); + return true; } -bool Document::removeIcon(IJS_Context* cc, +bool Document::removeIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1361,7 +1290,7 @@ bool Document::removeIcon(IJS_Context* cc, return true; } -bool Document::createDataObject(IJS_Context* cc, +bool Document::createDataObject(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1369,13 +1298,13 @@ bool Document::createDataObject(IJS_Context* cc, return true; } -bool Document::media(IJS_Context* cc, +bool Document::media(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::calculateNow(IJS_Context* cc, +bool Document::calculateNow(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1393,13 +1322,13 @@ bool Document::calculateNow(IJS_Context* cc, return true; } -bool Document::Collab(IJS_Context* cc, +bool Document::Collab(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::getPageNthWord(IJS_Context* cc, +bool Document::getPageNthWord(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1411,7 +1340,6 @@ bool Document::getPageNthWord(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION); return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); // TODO(tsepez): check maximum allowable params. @@ -1458,7 +1386,7 @@ bool Document::getPageNthWord(IJS_Context* cc, return true; } -bool Document::getPageNthWordQuads(IJS_Context* cc, +bool Document::getPageNthWordQuads(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1473,7 +1401,7 @@ bool Document::getPageNthWordQuads(IJS_Context* cc, return false; } -bool Document::getPageNumWords(IJS_Context* cc, +bool Document::getPageNumWords(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1485,7 +1413,6 @@ bool Document::getPageNumWords(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSNOPERMISSION); return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int nPageNo = params.size() > 0 ? params[0].ToInt(pRuntime) : 0; CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument(); if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) { @@ -1510,14 +1437,14 @@ bool Document::getPageNumWords(IJS_Context* cc, return true; } -bool Document::getPrintParams(IJS_Context* cc, +bool Document::getPrintParams(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); v8::Local<v8::Object> pRetObj = pRuntime->NewFxDynamicObj(CJS_PrintParamsObj::g_nObjDefnID); + if (pRetObj.IsEmpty()) + return false; // Not implemented yet. @@ -1543,7 +1470,7 @@ int Document::CountWords(CPDF_TextObject* pTextObj) { uint32_t charcode = CPDF_Font::kInvalidCharCode; FX_FLOAT kerning; - pTextObj->GetCharInfo(i, charcode, kerning); + pTextObj->GetCharInfo(i, &charcode, &kerning); CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode); uint16_t unicode = 0; @@ -1576,7 +1503,7 @@ CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, uint32_t charcode = CPDF_Font::kInvalidCharCode; FX_FLOAT kerning; - pTextObj->GetCharInfo(i, charcode, kerning); + pTextObj->GetCharInfo(i, &charcode, &kerning); CFX_WideString swUnicode = pFont->UnicodeFromCharCode(charcode); uint16_t unicode = 0; @@ -1597,7 +1524,7 @@ CFX_WideString Document::GetObjWordStr(CPDF_TextObject* pTextObj, return swRet; } -bool Document::zoom(IJS_Context* cc, +bool Document::zoom(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; @@ -1613,13 +1540,13 @@ bool Document::zoom(IJS_Context* cc, (refW, ReflowWidth) */ -bool Document::zoomType(IJS_Context* cc, +bool Document::zoomType(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Document::deletePages(IJS_Context* cc, +bool Document::deletePages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1627,7 +1554,7 @@ bool Document::deletePages(IJS_Context* cc, return true; } -bool Document::extractPages(IJS_Context* cc, +bool Document::extractPages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1635,7 +1562,7 @@ bool Document::extractPages(IJS_Context* cc, return true; } -bool Document::insertPages(IJS_Context* cc, +bool Document::insertPages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1643,7 +1570,7 @@ bool Document::insertPages(IJS_Context* cc, return true; } -bool Document::replacePages(IJS_Context* cc, +bool Document::replacePages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1651,7 +1578,7 @@ bool Document::replacePages(IJS_Context* cc, return true; } -bool Document::getURL(IJS_Context* cc, +bool Document::getURL(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1659,7 +1586,7 @@ bool Document::getURL(IJS_Context* cc, return true; } -bool Document::gotoNamedDest(IJS_Context* cc, +bool Document::gotoNamedDest(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1671,7 +1598,6 @@ bool Document::gotoNamedDest(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSBADOBJECT); return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString wideName = params[0].ToCFXWideString(pRuntime); CFX_ByteString utf8Name = wideName.UTF8Encode(); CPDF_Document* pDocument = m_pFormFillEnv->GetPDFDocument(); diff --git a/fpdfsdk/javascript/Document.h b/fpdfsdk/javascript/Document.h index 227c4284b..91ca778c7 100644 --- a/fpdfsdk/javascript/Document.h +++ b/fpdfsdk/javascript/Document.h @@ -41,231 +41,250 @@ class CJS_PrintParamsObj : public CJS_Object { DECLARE_JS_CLASS(); }; -class Icon; -class Field; - -struct IconElement { - IconElement(const CFX_WideString& name, Icon* stream) - : IconName(name), IconStream(stream) {} - - const CFX_WideString IconName; - Icon* const IconStream; -}; - -struct CJS_DelayData; -struct CJS_DelayAnnot; struct CJS_AnnotObj; +struct CJS_DelayAnnot; +struct CJS_DelayData; class Document : public CJS_EmbedObj { public: explicit Document(CJS_Object* pJSObject); ~Document() override; - bool ADBE(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool author(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool baseURL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool bookmarkRoot(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool calculate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool Collab(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool creationDate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool creator(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool dirty(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool documentFileName(IJS_Context* cc, + bool ADBE(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool author(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool baseURL(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool bookmarkRoot(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool calculate(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool Collab(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool creationDate(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool creator(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool delay(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool dirty(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool documentFileName(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool external(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool filesize(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool icons(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool info(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool keywords(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool layout(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool modDate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool mouseX(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool mouseY(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool numFields(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool numPages(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool pageNum(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool pageWindowRect(IJS_Context* cc, + bool external(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool filesize(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool icons(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool info(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool keywords(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool layout(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool media(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool modDate(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool mouseX(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool mouseY(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool numFields(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool numPages(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool pageNum(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool pageWindowRect(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool path(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool producer(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool subject(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool title(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool zoom(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool zoomType(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); + bool path(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool producer(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool subject(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool title(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool zoom(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool zoomType(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); - bool addAnnot(IJS_Context* cc, + bool addAnnot(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool addField(IJS_Context* cc, + bool addField(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool addLink(IJS_Context* cc, + bool addLink(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool addIcon(IJS_Context* cc, + bool addIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool calculateNow(IJS_Context* cc, + bool calculateNow(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool closeDoc(IJS_Context* cc, + bool closeDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool createDataObject(IJS_Context* cc, + bool createDataObject(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool deletePages(IJS_Context* cc, + bool deletePages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool exportAsText(IJS_Context* cc, + bool exportAsText(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool exportAsFDF(IJS_Context* cc, + bool exportAsFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool exportAsXFDF(IJS_Context* cc, + bool exportAsXFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool extractPages(IJS_Context* cc, + bool extractPages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getAnnot(IJS_Context* cc, + bool getAnnot(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getAnnots(IJS_Context* cc, + bool getAnnots(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getAnnot3D(IJS_Context* cc, + bool getAnnot3D(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getAnnots3D(IJS_Context* cc, + bool getAnnots3D(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getField(IJS_Context* cc, + bool getField(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getIcon(IJS_Context* cc, + bool getIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getLinks(IJS_Context* cc, + bool getLinks(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getNthFieldName(IJS_Context* cc, + bool getNthFieldName(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getOCGs(IJS_Context* cc, + bool getOCGs(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getPageBox(IJS_Context* cc, + bool getPageBox(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getPageNthWord(IJS_Context* cc, + bool getPageNthWord(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getPageNthWordQuads(IJS_Context* cc, + bool getPageNthWordQuads(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getPageNumWords(IJS_Context* cc, + bool getPageNumWords(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getPrintParams(IJS_Context* cc, + bool getPrintParams(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getURL(IJS_Context* cc, + bool getURL(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool gotoNamedDest(IJS_Context* cc, + bool gotoNamedDest(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool importAnFDF(IJS_Context* cc, + bool importAnFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool importAnXFDF(IJS_Context* cc, + bool importAnXFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool importTextData(IJS_Context* cc, + bool importTextData(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool insertPages(IJS_Context* cc, + bool insertPages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool mailForm(IJS_Context* cc, + bool mailForm(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool print(IJS_Context* cc, + bool print(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool removeField(IJS_Context* cc, + bool removeField(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool replacePages(IJS_Context* cc, + bool replacePages(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool resetForm(IJS_Context* cc, + bool resetForm(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool saveAs(IJS_Context* cc, + bool saveAs(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool submitForm(IJS_Context* cc, + bool submitForm(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool syncAnnotScan(IJS_Context* cc, + bool syncAnnotScan(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool mailDoc(IJS_Context* cc, + bool mailDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool removeIcon(IJS_Context* cc, + bool removeIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool URL(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); + bool URL(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); void SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv); CPDFSDK_FormFillEnvironment* GetFormFillEnv() const { @@ -280,7 +299,7 @@ class Document : public CJS_EmbedObj { int CountWords(CPDF_TextObject* pTextObj); CFX_WideString GetObjWordStr(CPDF_TextObject* pTextObj, int nWordIndex); - bool getPropertyInternal(IJS_Context* cc, + bool getPropertyInternal(CJS_Runtime* pRuntime, CJS_PropValue& vp, const CFX_ByteString& propName, CFX_WideString& sError); @@ -288,7 +307,8 @@ class Document : public CJS_EmbedObj { CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; CFX_WideString m_cwBaseURL; std::list<std::unique_ptr<CJS_DelayData>> m_DelayData; - std::vector<std::unique_ptr<IconElement>> m_Icons; + // Needs to be a std::list for iterator stability. + std::list<CFX_WideString> m_IconNames; bool m_bDelay; }; diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp index e04cbd696..f37b3d486 100644 --- a/fpdfsdk/javascript/Field.cpp +++ b/fpdfsdk/javascript/Field.cpp @@ -26,7 +26,7 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" #include "fpdfsdk/javascript/PublicMethods.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" #include "fpdfsdk/javascript/color.h" @@ -72,92 +72,94 @@ bool SetWidgetDisplayStatus(CPDFSDK_Widget* pWidget, int value) { } // namespace -BEGIN_JS_STATIC_CONST(CJS_Field) -END_JS_STATIC_CONST() - -BEGIN_JS_STATIC_PROP(CJS_Field) -JS_STATIC_PROP_ENTRY(alignment) -JS_STATIC_PROP_ENTRY(borderStyle) -JS_STATIC_PROP_ENTRY(buttonAlignX) -JS_STATIC_PROP_ENTRY(buttonAlignY) -JS_STATIC_PROP_ENTRY(buttonFitBounds) -JS_STATIC_PROP_ENTRY(buttonPosition) -JS_STATIC_PROP_ENTRY(buttonScaleHow) -JS_STATIC_PROP_ENTRY(buttonScaleWhen) -JS_STATIC_PROP_ENTRY(calcOrderIndex) -JS_STATIC_PROP_ENTRY(charLimit) -JS_STATIC_PROP_ENTRY(comb) -JS_STATIC_PROP_ENTRY(commitOnSelChange) -JS_STATIC_PROP_ENTRY(currentValueIndices) -JS_STATIC_PROP_ENTRY(defaultStyle) -JS_STATIC_PROP_ENTRY(defaultValue) -JS_STATIC_PROP_ENTRY(doNotScroll) -JS_STATIC_PROP_ENTRY(doNotSpellCheck) -JS_STATIC_PROP_ENTRY(delay) -JS_STATIC_PROP_ENTRY(display) -JS_STATIC_PROP_ENTRY(doc) -JS_STATIC_PROP_ENTRY(editable) -JS_STATIC_PROP_ENTRY(exportValues) -JS_STATIC_PROP_ENTRY(hidden) -JS_STATIC_PROP_ENTRY(fileSelect) -JS_STATIC_PROP_ENTRY(fillColor) -JS_STATIC_PROP_ENTRY(lineWidth) -JS_STATIC_PROP_ENTRY(highlight) -JS_STATIC_PROP_ENTRY(multiline) -JS_STATIC_PROP_ENTRY(multipleSelection) -JS_STATIC_PROP_ENTRY(name) -JS_STATIC_PROP_ENTRY(numItems) -JS_STATIC_PROP_ENTRY(page) -JS_STATIC_PROP_ENTRY(password) -JS_STATIC_PROP_ENTRY(print) -JS_STATIC_PROP_ENTRY(radiosInUnison) -JS_STATIC_PROP_ENTRY(readonly) -JS_STATIC_PROP_ENTRY(rect) -JS_STATIC_PROP_ENTRY(required) -JS_STATIC_PROP_ENTRY(richText) -JS_STATIC_PROP_ENTRY(richValue) -JS_STATIC_PROP_ENTRY(rotation) -JS_STATIC_PROP_ENTRY(strokeColor) -JS_STATIC_PROP_ENTRY(style) -JS_STATIC_PROP_ENTRY(submitName) -JS_STATIC_PROP_ENTRY(textColor) -JS_STATIC_PROP_ENTRY(textFont) -JS_STATIC_PROP_ENTRY(textSize) -JS_STATIC_PROP_ENTRY(type) -JS_STATIC_PROP_ENTRY(userName) -JS_STATIC_PROP_ENTRY(value) -JS_STATIC_PROP_ENTRY(valueAsString) -JS_STATIC_PROP_ENTRY(source) -END_JS_STATIC_PROP() - -BEGIN_JS_STATIC_METHOD(CJS_Field) -JS_STATIC_METHOD_ENTRY(browseForFileToSubmit) -JS_STATIC_METHOD_ENTRY(buttonGetCaption) -JS_STATIC_METHOD_ENTRY(buttonGetIcon) -JS_STATIC_METHOD_ENTRY(buttonImportIcon) -JS_STATIC_METHOD_ENTRY(buttonSetCaption) -JS_STATIC_METHOD_ENTRY(buttonSetIcon) -JS_STATIC_METHOD_ENTRY(checkThisBox) -JS_STATIC_METHOD_ENTRY(clearItems) -JS_STATIC_METHOD_ENTRY(defaultIsChecked) -JS_STATIC_METHOD_ENTRY(deleteItemAt) -JS_STATIC_METHOD_ENTRY(getArray) -JS_STATIC_METHOD_ENTRY(getItemAt) -JS_STATIC_METHOD_ENTRY(getLock) -JS_STATIC_METHOD_ENTRY(insertItemAt) -JS_STATIC_METHOD_ENTRY(isBoxChecked) -JS_STATIC_METHOD_ENTRY(isDefaultChecked) -JS_STATIC_METHOD_ENTRY(setAction) -JS_STATIC_METHOD_ENTRY(setFocus) -JS_STATIC_METHOD_ENTRY(setItems) -JS_STATIC_METHOD_ENTRY(setLock) -JS_STATIC_METHOD_ENTRY(signatureGetModifications) -JS_STATIC_METHOD_ENTRY(signatureGetSeedValue) -JS_STATIC_METHOD_ENTRY(signatureInfo) -JS_STATIC_METHOD_ENTRY(signatureSetSeedValue) -JS_STATIC_METHOD_ENTRY(signatureSign) -JS_STATIC_METHOD_ENTRY(signatureValidate) -END_JS_STATIC_METHOD() +JSConstSpec CJS_Field::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; + +JSPropertySpec CJS_Field::PropertySpecs[] = { + {"alignment", get_alignment_static, set_alignment_static}, + {"borderStyle", get_borderStyle_static, set_borderStyle_static}, + {"buttonAlignX", get_buttonAlignX_static, set_buttonAlignX_static}, + {"buttonAlignY", get_buttonAlignY_static, set_buttonAlignY_static}, + {"buttonFitBounds", get_buttonFitBounds_static, set_buttonFitBounds_static}, + {"buttonPosition", get_buttonPosition_static, set_buttonPosition_static}, + {"buttonScaleHow", get_buttonScaleHow_static, set_buttonScaleHow_static}, + {"buttonScaleWhen", get_buttonScaleWhen_static, set_buttonScaleWhen_static}, + {"calcOrderIndex", get_calcOrderIndex_static, set_calcOrderIndex_static}, + {"charLimit", get_charLimit_static, set_charLimit_static}, + {"comb", get_comb_static, set_comb_static}, + {"commitOnSelChange", get_commitOnSelChange_static, + set_commitOnSelChange_static}, + {"currentValueIndices", get_currentValueIndices_static, + set_currentValueIndices_static}, + {"defaultStyle", get_defaultStyle_static, set_defaultStyle_static}, + {"defaultValue", get_defaultValue_static, set_defaultValue_static}, + {"doNotScroll", get_doNotScroll_static, set_doNotScroll_static}, + {"doNotSpellCheck", get_doNotSpellCheck_static, set_doNotSpellCheck_static}, + {"delay", get_delay_static, set_delay_static}, + {"display", get_display_static, set_display_static}, + {"doc", get_doc_static, set_doc_static}, + {"editable", get_editable_static, set_editable_static}, + {"exportValues", get_exportValues_static, set_exportValues_static}, + {"hidden", get_hidden_static, set_hidden_static}, + {"fileSelect", get_fileSelect_static, set_fileSelect_static}, + {"fillColor", get_fillColor_static, set_fillColor_static}, + {"lineWidth", get_lineWidth_static, set_lineWidth_static}, + {"highlight", get_highlight_static, set_highlight_static}, + {"multiline", get_multiline_static, set_multiline_static}, + {"multipleSelection", get_multipleSelection_static, + set_multipleSelection_static}, + {"name", get_name_static, set_name_static}, + {"numItems", get_numItems_static, set_numItems_static}, + {"page", get_page_static, set_page_static}, + {"password", get_password_static, set_password_static}, + {"print", get_print_static, set_print_static}, + {"radiosInUnison", get_radiosInUnison_static, set_radiosInUnison_static}, + {"readonly", get_readonly_static, set_readonly_static}, + {"rect", get_rect_static, set_rect_static}, + {"required", get_required_static, set_required_static}, + {"richText", get_richText_static, set_richText_static}, + {"richValue", get_richValue_static, set_richValue_static}, + {"rotation", get_rotation_static, set_rotation_static}, + {"strokeColor", get_strokeColor_static, set_strokeColor_static}, + {"style", get_style_static, set_style_static}, + {"submitName", get_submitName_static, set_submitName_static}, + {"textColor", get_textColor_static, set_textColor_static}, + {"textFont", get_textFont_static, set_textFont_static}, + {"textSize", get_textSize_static, set_textSize_static}, + {"type", get_type_static, set_type_static}, + {"userName", get_userName_static, set_userName_static}, + {"value", get_value_static, set_value_static}, + {"valueAsString", get_valueAsString_static, set_valueAsString_static}, + {"source", get_source_static, set_source_static}, + {0, 0, 0}}; + +JSMethodSpec CJS_Field::MethodSpecs[] = { + {"browseForFileToSubmit", browseForFileToSubmit_static}, + {"buttonGetCaption", buttonGetCaption_static}, + {"buttonGetIcon", buttonGetIcon_static}, + {"buttonImportIcon", buttonImportIcon_static}, + {"buttonSetCaption", buttonSetCaption_static}, + {"buttonSetIcon", buttonSetIcon_static}, + {"checkThisBox", checkThisBox_static}, + {"clearItems", clearItems_static}, + {"defaultIsChecked", defaultIsChecked_static}, + {"deleteItemAt", deleteItemAt_static}, + {"getArray", getArray_static}, + {"getItemAt", getItemAt_static}, + {"getLock", getLock_static}, + {"insertItemAt", insertItemAt_static}, + {"isBoxChecked", isBoxChecked_static}, + {"isDefaultChecked", isDefaultChecked_static}, + {"setAction", setAction_static}, + {"setFocus", setFocus_static}, + {"setItems", setItems_static}, + {"setLock", setLock_static}, + {"signatureGetModifications", signatureGetModifications_static}, + {"signatureGetSeedValue", signatureGetSeedValue_static}, + {"signatureInfo", signatureInfo_static}, + {"signatureSetSeedValue", signatureSetSeedValue_static}, + {"signatureSign", signatureSign_static}, + {"signatureValidate", signatureValidate_static}, + {0, 0}}; IMPLEMENT_JS_CLASS(CJS_Field, Field) @@ -375,7 +377,7 @@ CPDF_FormControl* Field::GetSmartFieldControl(CPDF_FormField* pFormField) { return pFormField->GetControl(m_nFormControlIndex); } -bool Field::alignment(IJS_Context* cc, +bool Field::alignment(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -431,7 +433,7 @@ void Field::SetAlignment(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::borderStyle(IJS_Context* cc, +bool Field::borderStyle(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -540,7 +542,7 @@ void Field::SetBorderStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv, } } -bool Field::buttonAlignX(IJS_Context* cc, +bool Field::buttonAlignX(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -589,7 +591,7 @@ void Field::SetButtonAlignX(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::buttonAlignY(IJS_Context* cc, +bool Field::buttonAlignY(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -638,7 +640,7 @@ void Field::SetButtonAlignY(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::buttonFitBounds(IJS_Context* cc, +bool Field::buttonFitBounds(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -682,7 +684,7 @@ void Field::SetButtonFitBounds(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::buttonPosition(IJS_Context* cc, +bool Field::buttonPosition(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -725,7 +727,7 @@ void Field::SetButtonPosition(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::buttonScaleHow(IJS_Context* cc, +bool Field::buttonScaleHow(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -773,7 +775,7 @@ void Field::SetButtonScaleHow(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::buttonScaleWhen(IJS_Context* cc, +bool Field::buttonScaleWhen(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -832,7 +834,7 @@ void Field::SetButtonScaleWhen(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::calcOrderIndex(IJS_Context* cc, +bool Field::calcOrderIndex(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -876,7 +878,7 @@ void Field::SetCalcOrderIndex(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::charLimit(IJS_Context* cc, +bool Field::charLimit(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -915,7 +917,9 @@ void Field::SetCharLimit(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::comb(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::comb(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { ASSERT(m_pFormFillEnv); if (vp.IsSetting()) { @@ -956,7 +960,7 @@ void Field::SetComb(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::commitOnSelChange(IJS_Context* cc, +bool Field::commitOnSelChange(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -1001,11 +1005,9 @@ void Field::SetCommitOnSelChange(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::currentValueIndices(IJS_Context* cc, +bool Field::currentValueIndices(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - if (vp.IsSetting()) { if (!m_bCanSet) return false; @@ -1087,7 +1089,7 @@ void Field::SetCurrentValueIndices(CPDFSDK_FormFillEnvironment* pFormFillEnv, } } -bool Field::defaultStyle(IJS_Context* cc, +bool Field::defaultStyle(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return false; @@ -1099,7 +1101,7 @@ void Field::SetDefaultStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::defaultValue(IJS_Context* cc, +bool Field::defaultValue(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -1140,7 +1142,7 @@ void Field::SetDefaultValue(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::doNotScroll(IJS_Context* cc, +bool Field::doNotScroll(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -1183,7 +1185,7 @@ void Field::SetDoNotScroll(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::doNotSpellCheck(IJS_Context* cc, +bool Field::doNotSpellCheck(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -1223,22 +1225,23 @@ void Field::SetDelay(bool bDelay) { } } -bool Field::delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - if (vp.IsSetting()) { - if (!m_bCanSet) - return false; - - bool bVP; - vp >> bVP; - - SetDelay(bVP); - } else { +bool Field::delay(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + if (!vp.IsSetting()) { vp << m_bDelay; + return true; } + if (!m_bCanSet) + return false; + + bool bVP; + vp >> bVP; + SetDelay(bVP); return true; } -bool Field::display(IJS_Context* cc, +bool Field::display(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -1247,43 +1250,40 @@ bool Field::display(IJS_Context* cc, int nVP; vp >> nVP; - if (m_bDelay) { AddDelay_Int(FP_DISPLAY, nVP); } else { Field::SetDisplay(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, nVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - ASSERT(pFormField); - CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); - CPDFSDK_Widget* pWidget = - pInterForm->GetWidget(GetSmartFieldControl(pFormField)); - if (!pWidget) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - uint32_t dwFlag = pWidget->GetFlags(); + CPDF_FormField* pFormField = FieldArray[0]; + ASSERT(pFormField); + CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); + CPDFSDK_Widget* pWidget = + pInterForm->GetWidget(GetSmartFieldControl(pFormField)); + if (!pWidget) + return false; - if (ANNOTFLAG_INVISIBLE & dwFlag || ANNOTFLAG_HIDDEN & dwFlag) { - vp << (int32_t)1; - } else { - if (ANNOTFLAG_PRINT & dwFlag) { - if (ANNOTFLAG_NOVIEW & dwFlag) { - vp << (int32_t)3; - } else { - vp << (int32_t)0; - } + uint32_t dwFlag = pWidget->GetFlags(); + if (ANNOTFLAG_INVISIBLE & dwFlag || ANNOTFLAG_HIDDEN & dwFlag) { + vp << (int32_t)1; + } else { + if (ANNOTFLAG_PRINT & dwFlag) { + if (ANNOTFLAG_NOVIEW & dwFlag) { + vp << (int32_t)3; } else { - vp << (int32_t)2; + vp << (int32_t)0; } + } else { + vp << (int32_t)2; } } - return true; } @@ -1323,15 +1323,17 @@ void Field::SetDisplay(CPDFSDK_FormFillEnvironment* pFormFillEnv, } } -bool Field::doc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - if (!vp.IsGetting()) { +bool Field::doc(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + if (!vp.IsGetting()) return false; - } + vp << m_pJSDoc->GetCJSDoc(); return true; } -bool Field::editable(IJS_Context* cc, +bool Field::editable(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -1340,25 +1342,21 @@ bool Field::editable(IJS_Context* cc, bool bVP; vp >> bVP; - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX) - return false; - - if (pFormField->GetFieldFlags() & FIELDFLAG_EDIT) - vp << true; - else - vp << false; + return true; } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_COMBOBOX) + return false; + + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_EDIT); return true; } -bool Field::exportValues(IJS_Context* cc, +bool Field::exportValues(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); @@ -1370,42 +1368,35 @@ bool Field::exportValues(IJS_Context* cc, pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) { return false; } + if (vp.IsSetting()) + return m_bCanSet && vp.GetJSValue()->IsArrayObject(); - if (vp.IsSetting()) { - if (!m_bCanSet) + CJS_Array ExportValusArray; + if (m_nFormControlIndex < 0) { + for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { + CPDF_FormControl* pFormControl = pFormField->GetControl(i); + ExportValusArray.SetElement( + pRuntime, i, + CJS_Value(pRuntime, pFormControl->GetExportValue().c_str())); + } + } else { + if (m_nFormControlIndex >= pFormField->CountControls()) return false; - if (!vp.GetJSValue()->IsArrayObject()) + CPDF_FormControl* pFormControl = + pFormField->GetControl(m_nFormControlIndex); + if (!pFormControl) return false; - } else { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - CJS_Array ExportValusArray; - if (m_nFormControlIndex < 0) { - for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { - CPDF_FormControl* pFormControl = pFormField->GetControl(i); - ExportValusArray.SetElement( - pRuntime, i, - CJS_Value(pRuntime, pFormControl->GetExportValue().c_str())); - } - } else { - if (m_nFormControlIndex >= pFormField->CountControls()) - return false; - CPDF_FormControl* pFormControl = - pFormField->GetControl(m_nFormControlIndex); - if (!pFormControl) - return false; - - ExportValusArray.SetElement( - pRuntime, 0, - CJS_Value(pRuntime, pFormControl->GetExportValue().c_str())); - } - vp << ExportValusArray; + ExportValusArray.SetElement( + pRuntime, 0, + CJS_Value(pRuntime, pFormControl->GetExportValue().c_str())); } + vp << ExportValusArray; return true; } -bool Field::fileSelect(IJS_Context* cc, +bool Field::fileSelect(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); @@ -1422,19 +1413,15 @@ bool Field::fileSelect(IJS_Context* cc, bool bVP; vp >> bVP; - } else { - if (pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT) - vp << true; - else - vp << false; + return true; } + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_FILESELECT); return true; } -bool Field::fillColor(IJS_Context* cc, +bool Field::fillColor(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array crArray; std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); if (FieldArray.empty()) @@ -1457,41 +1444,39 @@ bool Field::fillColor(IJS_Context* cc, Field::SetFillColor(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, color); } - } else { - CPDF_FormField* pFormField = FieldArray[0]; - ASSERT(pFormField); - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; - - int iColorType; - pFormControl->GetBackgroundColor(iColorType); - - CPWL_Color color; - if (iColorType == COLORTYPE_TRANSPARENT) { - color = CPWL_Color(COLORTYPE_TRANSPARENT); - } else if (iColorType == COLORTYPE_GRAY) { - color = CPWL_Color(COLORTYPE_GRAY, - pFormControl->GetOriginalBackgroundColor(0)); - } else if (iColorType == COLORTYPE_RGB) { - color = - CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBackgroundColor(0), - pFormControl->GetOriginalBackgroundColor(1), - pFormControl->GetOriginalBackgroundColor(2)); - } else if (iColorType == COLORTYPE_CMYK) { - color = CPWL_Color(COLORTYPE_CMYK, - pFormControl->GetOriginalBackgroundColor(0), - pFormControl->GetOriginalBackgroundColor(1), - pFormControl->GetOriginalBackgroundColor(2), - pFormControl->GetOriginalBackgroundColor(3)); - } else { - return false; - } - - color::ConvertPWLColorToArray(pRuntime, color, &crArray); - vp << crArray; + return true; } + CPDF_FormField* pFormField = FieldArray[0]; + ASSERT(pFormField); + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; + int iColorType; + pFormControl->GetBackgroundColor(iColorType); + + CPWL_Color color; + if (iColorType == COLORTYPE_TRANSPARENT) { + color = CPWL_Color(COLORTYPE_TRANSPARENT); + } else if (iColorType == COLORTYPE_GRAY) { + color = + CPWL_Color(COLORTYPE_GRAY, pFormControl->GetOriginalBackgroundColor(0)); + } else if (iColorType == COLORTYPE_RGB) { + color = + CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBackgroundColor(0), + pFormControl->GetOriginalBackgroundColor(1), + pFormControl->GetOriginalBackgroundColor(2)); + } else if (iColorType == COLORTYPE_CMYK) { + color = + CPWL_Color(COLORTYPE_CMYK, pFormControl->GetOriginalBackgroundColor(0), + pFormControl->GetOriginalBackgroundColor(1), + pFormControl->GetOriginalBackgroundColor(2), + pFormControl->GetOriginalBackgroundColor(3)); + } else { + return false; + } + color::ConvertPWLColorToArray(pRuntime, color, &crArray); + vp << crArray; return true; } @@ -1502,40 +1487,40 @@ void Field::SetFillColor(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::hidden(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsSetting()) { if (!m_bCanSet) return false; bool bVP; vp >> bVP; - if (m_bDelay) { AddDelay_Bool(FP_HIDDEN, bVP); } else { Field::SetHidden(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, bVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - ASSERT(pFormField); - CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); - CPDFSDK_Widget* pWidget = - pInterForm->GetWidget(GetSmartFieldControl(pFormField)); - if (!pWidget) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - uint32_t dwFlags = pWidget->GetFlags(); + CPDF_FormField* pFormField = FieldArray[0]; + ASSERT(pFormField); + CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); + CPDFSDK_Widget* pWidget = + pInterForm->GetWidget(GetSmartFieldControl(pFormField)); + if (!pWidget) + return false; - if (ANNOTFLAG_INVISIBLE & dwFlags || ANNOTFLAG_HIDDEN & dwFlags) - vp << true; - else - vp << false; - } + uint32_t dwFlags = pWidget->GetFlags(); + if (ANNOTFLAG_INVISIBLE & dwFlags || ANNOTFLAG_HIDDEN & dwFlags) + vp << true; + else + vp << false; return true; } @@ -1548,11 +1533,10 @@ void Field::SetHidden(CPDFSDK_FormFillEnvironment* pFormFillEnv, SetDisplay(pFormFillEnv, swFieldName, nControlIndex, display); } -bool Field::highlight(IJS_Context* cc, +bool Field::highlight(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); - if (vp.IsSetting()) { if (!m_bCanSet) return false; @@ -1566,39 +1550,38 @@ bool Field::highlight(IJS_Context* cc, Field::SetHighlight(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, strMode); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON) - return false; + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_PUSHBUTTON) + return false; - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - int eHM = pFormControl->GetHighlightingMode(); - switch (eHM) { - case CPDF_FormControl::None: - vp << L"none"; - break; - case CPDF_FormControl::Push: - vp << L"push"; - break; - case CPDF_FormControl::Invert: - vp << L"invert"; - break; - case CPDF_FormControl::Outline: - vp << L"outline"; - break; - case CPDF_FormControl::Toggle: - vp << L"toggle"; - break; - } + int eHM = pFormControl->GetHighlightingMode(); + switch (eHM) { + case CPDF_FormControl::None: + vp << L"none"; + break; + case CPDF_FormControl::Push: + vp << L"push"; + break; + case CPDF_FormControl::Invert: + vp << L"invert"; + break; + case CPDF_FormControl::Outline: + vp << L"outline"; + break; + case CPDF_FormControl::Toggle: + vp << L"toggle"; + break; } - return true; } @@ -1609,7 +1592,7 @@ void Field::SetHighlight(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::lineWidth(IJS_Context* cc, +bool Field::lineWidth(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -1625,28 +1608,27 @@ bool Field::lineWidth(IJS_Context* cc, Field::SetLineWidth(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, iWidth); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - ASSERT(pFormField); - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); - if (!pFormField->CountControls()) - return false; + CPDF_FormField* pFormField = FieldArray[0]; + ASSERT(pFormField); + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormField->GetControl(0)); - if (!pWidget) - return false; + CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); + if (!pFormField->CountControls()) + return false; - vp << (int32_t)pWidget->GetBorderWidth(); - } + CPDFSDK_Widget* pWidget = pInterForm->GetWidget(pFormField->GetControl(0)); + if (!pWidget) + return false; + vp << (int32_t)pWidget->GetBorderWidth(); return true; } @@ -1689,7 +1671,7 @@ void Field::SetLineWidth(CPDFSDK_FormFillEnvironment* pFormFillEnv, } } -bool Field::multiline(IJS_Context* cc, +bool Field::multiline(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -1707,20 +1689,20 @@ bool Field::multiline(IJS_Context* cc, Field::SetMultiline(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, bVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) - return false; + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) + return false; - if (pFormField->GetFieldFlags() & FIELDFLAG_MULTILINE) - vp << true; - else - vp << false; - } + if (pFormField->GetFieldFlags() & FIELDFLAG_MULTILINE) + vp << true; + else + vp << false; return true; } @@ -1732,39 +1714,33 @@ void Field::SetMultiline(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::multipleSelection(IJS_Context* cc, +bool Field::multipleSelection(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); - if (vp.IsSetting()) { if (!m_bCanSet) return false; bool bVP; vp >> bVP; - if (m_bDelay) { AddDelay_Bool(FP_MULTIPLESELECTION, bVP); } else { Field::SetMultipleSelection(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, bVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX) - return false; - - if (pFormField->GetFieldFlags() & FIELDFLAG_MULTISELECT) - vp << true; - else - vp << false; + return true; } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; + + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_LISTBOX) + return false; + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_MULTISELECT); return true; } @@ -1775,7 +1751,9 @@ void Field::SetMultipleSelection(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::name(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; @@ -1784,11 +1762,10 @@ bool Field::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return false; vp << m_FieldName; - return true; } -bool Field::numItems(IJS_Context* cc, +bool Field::numItems(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) @@ -1808,7 +1785,9 @@ bool Field::numItems(IJS_Context* cc, return true; } -bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::page(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) { sError = JSGetStringFromID(IDS_STRING_JSREADONLY); return false; @@ -1829,7 +1808,6 @@ bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return true; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array PageArray; int i = 0; for (const auto& pObserved : widgets) { @@ -1852,7 +1830,7 @@ bool Field::page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Field::password(IJS_Context* cc, +bool Field::password(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -1863,28 +1841,24 @@ bool Field::password(IJS_Context* cc, bool bVP; vp >> bVP; - if (m_bDelay) { AddDelay_Bool(FP_PASSWORD, bVP); } else { Field::SetPassword(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, bVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) - return false; + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - if (pFormField->GetFieldFlags() & FIELDFLAG_PASSWORD) - vp << true; - else - vp << false; - } + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) + return false; + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_PASSWORD); return true; } @@ -1895,7 +1869,9 @@ void Field::SetPassword(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::print(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::print(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); if (FieldArray.empty()) @@ -1951,23 +1927,20 @@ bool Field::print(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { } } } - } else { - CPDF_FormField* pFormField = FieldArray[0]; - CPDFSDK_Widget* pWidget = - pInterForm->GetWidget(GetSmartFieldControl(pFormField)); - if (!pWidget) - return false; - - if (pWidget->GetFlags() & ANNOTFLAG_PRINT) - vp << true; - else - vp << false; + return true; } + CPDF_FormField* pFormField = FieldArray[0]; + CPDFSDK_Widget* pWidget = + pInterForm->GetWidget(GetSmartFieldControl(pFormField)); + if (!pWidget) + return false; + + vp << !!(pWidget->GetFlags() & ANNOTFLAG_PRINT); return true; } -bool Field::radiosInUnison(IJS_Context* cc, +bool Field::radiosInUnison(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); @@ -1980,22 +1953,17 @@ bool Field::radiosInUnison(IJS_Context* cc, bool bVP; vp >> bVP; - - } else { - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) - return false; - - if (pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON) - vp << true; - else - vp << false; + return true; } + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON) + return false; + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_RADIOSINUNISON); return true; } -bool Field::readonly(IJS_Context* cc, +bool Field::readonly(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); @@ -2008,20 +1976,15 @@ bool Field::readonly(IJS_Context* cc, bool bVP; vp >> bVP; - - } else { - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldFlags() & FIELDFLAG_READONLY) - vp << true; - else - vp << false; + return true; } - + vp << !!(FieldArray[0]->GetFieldFlags() & FIELDFLAG_READONLY); return true; } -bool Field::rect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); +bool Field::rect(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { CJS_Value Upper_Leftx(pRuntime); CJS_Value Upper_Lefty(pRuntime); CJS_Value Lower_Rightx(pRuntime); @@ -2053,31 +2016,31 @@ bool Field::rect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { Field::SetRect(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, crRect); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPDF_FormField* pFormField = FieldArray[0]; - CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); - CPDFSDK_Widget* pWidget = - pInterForm->GetWidget(GetSmartFieldControl(pFormField)); - if (!pWidget) - return false; + CPDF_FormField* pFormField = FieldArray[0]; + CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm(); + CPDFSDK_Widget* pWidget = + pInterForm->GetWidget(GetSmartFieldControl(pFormField)); + if (!pWidget) + return false; - CFX_FloatRect crRect = pWidget->GetRect(); - Upper_Leftx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.left)); - Upper_Lefty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.top)); - Lower_Rightx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.right)); - Lower_Righty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.bottom)); + CFX_FloatRect crRect = pWidget->GetRect(); + Upper_Leftx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.left)); + Upper_Lefty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.top)); + Lower_Rightx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.right)); + Lower_Righty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.bottom)); - CJS_Array rcArray; - rcArray.SetElement(pRuntime, 0, Upper_Leftx); - rcArray.SetElement(pRuntime, 1, Upper_Lefty); - rcArray.SetElement(pRuntime, 2, Lower_Rightx); - rcArray.SetElement(pRuntime, 3, Lower_Righty); - vp << rcArray; - } + CJS_Array rcArray; + rcArray.SetElement(pRuntime, 0, Upper_Leftx); + rcArray.SetElement(pRuntime, 1, Upper_Lefty); + rcArray.SetElement(pRuntime, 2, Lower_Rightx); + rcArray.SetElement(pRuntime, 3, Lower_Righty); + vp << rcArray; return true; } @@ -2139,7 +2102,7 @@ void Field::SetRect(CPDFSDK_FormFillEnvironment* pFormFillEnv, } } -bool Field::required(IJS_Context* cc, +bool Field::required(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); @@ -2152,22 +2115,17 @@ bool Field::required(IJS_Context* cc, bool bVP; vp >> bVP; - - } else { - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON) - return false; - - if (pFormField->GetFieldFlags() & FIELDFLAG_REQUIRED) - vp << true; - else - vp << false; + return true; } + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() == FIELDTYPE_PUSHBUTTON) + return false; + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_REQUIRED); return true; } -bool Field::richText(IJS_Context* cc, +bool Field::richText(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -2178,35 +2136,31 @@ bool Field::richText(IJS_Context* cc, bool bVP; vp >> bVP; - - if (m_bDelay) { + if (m_bDelay) AddDelay_Bool(FP_RICHTEXT, bVP); - } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) - return false; - - if (pFormField->GetFieldFlags() & FIELDFLAG_RICHTEXT) - vp << true; - else - vp << false; + return true; } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; + + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_TEXTFIELD) + return false; + + vp << !!(pFormField->GetFieldFlags() & FIELDFLAG_RICHTEXT); return true; } -bool Field::richValue(IJS_Context* cc, +bool Field::richValue(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Field::rotation(IJS_Context* cc, +bool Field::rotation(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -2217,26 +2171,24 @@ bool Field::rotation(IJS_Context* cc, int nVP; vp >> nVP; - if (m_bDelay) { AddDelay_Int(FP_ROTATION, nVP); } else { Field::SetRotation(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, nVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; - - vp << (int32_t)pFormControl->GetRotation(); + return true; } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; + CPDF_FormField* pFormField = FieldArray[0]; + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; + + vp << (int32_t)pFormControl->GetRotation(); return true; } @@ -2247,10 +2199,9 @@ void Field::SetRotation(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::strokeColor(IJS_Context* cc, +bool Field::strokeColor(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array crArray; if (vp.IsSetting()) { @@ -2264,49 +2215,46 @@ bool Field::strokeColor(IJS_Context* cc, CPWL_Color color; color::ConvertArrayToPWLColor(pRuntime, crArray, &color); - if (m_bDelay) { AddDelay_Color(FP_STROKECOLOR, color); } else { Field::SetStrokeColor(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, color); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; - - int iColorType; - pFormControl->GetBorderColor(iColorType); + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPWL_Color color; - if (iColorType == COLORTYPE_TRANSPARENT) { - color = CPWL_Color(COLORTYPE_TRANSPARENT); - } else if (iColorType == COLORTYPE_GRAY) { - color = - CPWL_Color(COLORTYPE_GRAY, pFormControl->GetOriginalBorderColor(0)); - } else if (iColorType == COLORTYPE_RGB) { - color = CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBorderColor(0), - pFormControl->GetOriginalBorderColor(1), - pFormControl->GetOriginalBorderColor(2)); - } else if (iColorType == COLORTYPE_CMYK) { - color = - CPWL_Color(COLORTYPE_CMYK, pFormControl->GetOriginalBorderColor(0), - pFormControl->GetOriginalBorderColor(1), - pFormControl->GetOriginalBorderColor(2), - pFormControl->GetOriginalBorderColor(3)); - } else { - return false; - } + CPDF_FormField* pFormField = FieldArray[0]; + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - color::ConvertPWLColorToArray(pRuntime, color, &crArray); - vp << crArray; + int iColorType; + pFormControl->GetBorderColor(iColorType); + + CPWL_Color color; + if (iColorType == COLORTYPE_TRANSPARENT) { + color = CPWL_Color(COLORTYPE_TRANSPARENT); + } else if (iColorType == COLORTYPE_GRAY) { + color = CPWL_Color(COLORTYPE_GRAY, pFormControl->GetOriginalBorderColor(0)); + } else if (iColorType == COLORTYPE_RGB) { + color = CPWL_Color(COLORTYPE_RGB, pFormControl->GetOriginalBorderColor(0), + pFormControl->GetOriginalBorderColor(1), + pFormControl->GetOriginalBorderColor(2)); + } else if (iColorType == COLORTYPE_CMYK) { + color = CPWL_Color(COLORTYPE_CMYK, pFormControl->GetOriginalBorderColor(0), + pFormControl->GetOriginalBorderColor(1), + pFormControl->GetOriginalBorderColor(2), + pFormControl->GetOriginalBorderColor(3)); + } else { + return false; } + + color::ConvertPWLColorToArray(pRuntime, color, &crArray); + vp << crArray; return true; } @@ -2317,7 +2265,9 @@ void Field::SetStrokeColor(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::style(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::style(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { ASSERT(m_pFormFillEnv); if (vp.IsSetting()) { @@ -2333,47 +2283,46 @@ bool Field::style(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { Field::SetStyle(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, csBCaption); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPDF_FormField* pFormField = FieldArray[0]; - if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON && - pFormField->GetFieldType() != FIELDTYPE_CHECKBOX) { - return false; - } + CPDF_FormField* pFormField = FieldArray[0]; + if (pFormField->GetFieldType() != FIELDTYPE_RADIOBUTTON && + pFormField->GetFieldType() != FIELDTYPE_CHECKBOX) { + return false; + } - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - CFX_WideString csWCaption = pFormControl->GetNormalCaption(); - CFX_ByteString csBCaption; + CFX_WideString csWCaption = pFormControl->GetNormalCaption(); + CFX_ByteString csBCaption; - switch (csWCaption[0]) { - case L'l': - csBCaption = "circle"; - break; - case L'8': - csBCaption = "cross"; - break; - case L'u': - csBCaption = "diamond"; - break; - case L'n': - csBCaption = "square"; - break; - case L'H': - csBCaption = "star"; - break; - default: // L'4' - csBCaption = "check"; - break; - } - vp << csBCaption; + switch (csWCaption[0]) { + case L'l': + csBCaption = "circle"; + break; + case L'8': + csBCaption = "cross"; + break; + case L'u': + csBCaption = "diamond"; + break; + case L'n': + csBCaption = "square"; + break; + case L'H': + csBCaption = "star"; + break; + default: // L'4' + csBCaption = "check"; + break; } - + vp << csBCaption; return true; } @@ -2384,16 +2333,15 @@ void Field::SetStyle(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::submitName(IJS_Context* cc, +bool Field::submitName(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool Field::textColor(IJS_Context* cc, +bool Field::textColor(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array crArray; if (vp.IsSetting()) { @@ -2407,40 +2355,42 @@ bool Field::textColor(IJS_Context* cc, CPWL_Color color; color::ConvertArrayToPWLColor(pRuntime, crArray, &color); - if (m_bDelay) { AddDelay_Color(FP_TEXTCOLOR, color); } else { Field::SetTextColor(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, color); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CPDF_FormField* pFormField = FieldArray[0]; - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; + CPDF_FormField* pFormField = FieldArray[0]; + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - int iColorType; - FX_ARGB color; - CPDF_DefaultAppearance FieldAppearance = - pFormControl->GetDefaultAppearance(); - FieldAppearance.GetColor(color, iColorType); - int32_t a, r, g, b; - ArgbDecode(color, a, r, g, b); + int iColorType; + FX_ARGB color; + CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance(); + FieldAppearance.GetColor(color, iColorType); - CPWL_Color crRet = - CPWL_Color(COLORTYPE_RGB, r / 255.0f, g / 255.0f, b / 255.0f); + int32_t a; + int32_t r; + int32_t g; + int32_t b; + ArgbDecode(color, a, r, g, b); - if (iColorType == COLORTYPE_TRANSPARENT) - crRet = CPWL_Color(COLORTYPE_TRANSPARENT); + CPWL_Color crRet = + CPWL_Color(COLORTYPE_RGB, r / 255.0f, g / 255.0f, b / 255.0f); - color::ConvertPWLColorToArray(pRuntime, crRet, &crArray); - vp << crArray; - } + if (iColorType == COLORTYPE_TRANSPARENT) + crRet = CPWL_Color(COLORTYPE_TRANSPARENT); + + color::ConvertPWLColorToArray(pRuntime, crRet, &crArray); + vp << crArray; return true; } @@ -2451,7 +2401,7 @@ void Field::SetTextColor(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::textFont(IJS_Context* cc, +bool Field::textFont(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -2471,32 +2421,28 @@ bool Field::textFont(IJS_Context* cc, Field::SetTextFont(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, csFontName); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - ASSERT(pFormField); - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; - - int nFieldType = pFormField->GetFieldType(); + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - if (nFieldType == FIELDTYPE_PUSHBUTTON || - nFieldType == FIELDTYPE_COMBOBOX || nFieldType == FIELDTYPE_LISTBOX || - nFieldType == FIELDTYPE_TEXTFIELD) { - CPDF_Font* pFont = pFormControl->GetDefaultControlFont(); - if (!pFont) - return false; + CPDF_FormField* pFormField = FieldArray[0]; + ASSERT(pFormField); + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - vp << pFont->GetBaseFont(); - } else { - return false; - } + int nFieldType = pFormField->GetFieldType(); + if (nFieldType != FIELDTYPE_PUSHBUTTON && nFieldType != FIELDTYPE_COMBOBOX && + nFieldType != FIELDTYPE_LISTBOX && nFieldType != FIELDTYPE_TEXTFIELD) { + return false; } + CPDF_Font* pFont = pFormControl->GetDefaultControlFont(); + if (!pFont) + return false; + vp << pFont->GetBaseFont(); return true; } @@ -2507,7 +2453,7 @@ void Field::SetTextFont(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::textSize(IJS_Context* cc, +bool Field::textSize(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -2518,34 +2464,30 @@ bool Field::textSize(IJS_Context* cc, int nVP; vp >> nVP; - if (m_bDelay) { AddDelay_Int(FP_TEXTSIZE, nVP); } else { Field::SetTextSize(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, nVP); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - ASSERT(pFormField); - CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); - if (!pFormControl) - return false; - - CPDF_DefaultAppearance FieldAppearance = - pFormControl->GetDefaultAppearance(); + return true; + } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; - CFX_ByteString csFontNameTag; - FX_FLOAT fFontSize; - FieldAppearance.GetFont(csFontNameTag, fFontSize); + CPDF_FormField* pFormField = FieldArray[0]; + ASSERT(pFormField); + CPDF_FormControl* pFormControl = GetSmartFieldControl(pFormField); + if (!pFormControl) + return false; - vp << (int)fFontSize; - } + CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance(); + CFX_ByteString csFontNameTag; + FX_FLOAT fFontSize; + FieldAppearance.GetFont(csFontNameTag, fFontSize); + vp << (int)fFontSize; return true; } @@ -2556,7 +2498,9 @@ void Field::SetTextSize(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::type(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; @@ -2594,11 +2538,10 @@ bool Field::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { vp << L"unknown"; break; } - return true; } -bool Field::userName(IJS_Context* cc, +bool Field::userName(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { ASSERT(m_pFormFillEnv); @@ -2616,15 +2559,13 @@ bool Field::userName(IJS_Context* cc, Field::SetUserName(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, swName); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; - - CPDF_FormField* pFormField = FieldArray[0]; - vp << (CFX_WideString)pFormField->GetAlternateName(); + return true; } + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; + vp << FieldArray[0]->GetAlternateName(); return true; } @@ -2635,9 +2576,9 @@ void Field::SetUserName(CPDFSDK_FormFillEnvironment* pFormFillEnv, // Not supported. } -bool Field::value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - +bool Field::value(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsSetting()) { if (!m_bCanSet) return false; @@ -2663,57 +2604,58 @@ bool Field::value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { Field::SetValue(m_pFormFillEnv.Get(), m_FieldName, m_nFormControlIndex, strArray); } - } else { - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); - if (FieldArray.empty()) - return false; + return true; + } - CPDF_FormField* pFormField = FieldArray[0]; - switch (pFormField->GetFieldType()) { - case FIELDTYPE_PUSHBUTTON: - return false; - case FIELDTYPE_COMBOBOX: - case FIELDTYPE_TEXTFIELD: { - vp << pFormField->GetValue(); - } break; - case FIELDTYPE_LISTBOX: { - if (pFormField->CountSelectedItems() > 1) { - CJS_Array ValueArray; - CJS_Value ElementValue(pRuntime); - int iIndex; - for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { - iIndex = pFormField->GetSelectedIndex(i); + std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); + if (FieldArray.empty()) + return false; + + CPDF_FormField* pFormField = FieldArray[0]; + switch (pFormField->GetFieldType()) { + case FIELDTYPE_PUSHBUTTON: + return false; + case FIELDTYPE_COMBOBOX: + case FIELDTYPE_TEXTFIELD: { + vp << pFormField->GetValue(); + } break; + case FIELDTYPE_LISTBOX: { + if (pFormField->CountSelectedItems() > 1) { + CJS_Array ValueArray; + CJS_Value ElementValue(pRuntime); + int iIndex; + for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) { + iIndex = pFormField->GetSelectedIndex(i); + ElementValue = + CJS_Value(pRuntime, pFormField->GetOptionValue(iIndex).c_str()); + if (FXSYS_wcslen(ElementValue.ToCFXWideString(pRuntime).c_str()) == + 0) { ElementValue = - CJS_Value(pRuntime, pFormField->GetOptionValue(iIndex).c_str()); - if (FXSYS_wcslen(ElementValue.ToCFXWideString(pRuntime).c_str()) == - 0) { - ElementValue = CJS_Value( - pRuntime, pFormField->GetOptionLabel(iIndex).c_str()); - } - ValueArray.SetElement(pRuntime, i, ElementValue); - } - vp << ValueArray; - } else { - vp << pFormField->GetValue(); - } - } break; - case FIELDTYPE_CHECKBOX: - case FIELDTYPE_RADIOBUTTON: { - bool bFind = false; - for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { - if (pFormField->GetControl(i)->IsChecked()) { - vp << pFormField->GetControl(i)->GetExportValue(); - bFind = true; - break; + CJS_Value(pRuntime, pFormField->GetOptionLabel(iIndex).c_str()); } + ValueArray.SetElement(pRuntime, i, ElementValue); } - if (!bFind) - vp << L"Off"; - } break; - default: + vp << ValueArray; + } else { vp << pFormField->GetValue(); - break; - } + } + } break; + case FIELDTYPE_CHECKBOX: + case FIELDTYPE_RADIOBUTTON: { + bool bFind = false; + for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) { + if (pFormField->GetControl(i)->IsChecked()) { + vp << pFormField->GetControl(i)->GetExportValue(); + bFind = true; + break; + } + } + if (!bFind) + vp << L"Off"; + } break; + default: + vp << pFormField->GetValue(); + break; } vp.GetJSValue()->MaybeCoerceToNumber(pRuntime); return true; @@ -2773,7 +2715,7 @@ void Field::SetValue(CPDFSDK_FormFillEnvironment* pFormFillEnv, } } -bool Field::valueAsString(IJS_Context* cc, +bool Field::valueAsString(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) @@ -2815,7 +2757,7 @@ bool Field::valueAsString(IJS_Context* cc, return true; } -bool Field::browseForFileToSubmit(IJS_Context* cc, +bool Field::browseForFileToSubmit(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -2836,12 +2778,10 @@ bool Field::browseForFileToSubmit(IJS_Context* cc, return false; } -bool Field::buttonGetCaption(IJS_Context* cc, +bool Field::buttonGetCaption(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - int nface = 0; int iSize = params.size(); if (iSize >= 1) @@ -2871,17 +2811,15 @@ bool Field::buttonGetCaption(IJS_Context* cc, return true; } -bool Field::buttonGetIcon(IJS_Context* cc, +bool Field::buttonGetIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - - int nface = 0; - int iSize = params.size(); - if (iSize >= 1) - nface = params[0].ToInt(pRuntime); + if (params.size() >= 1) { + int nFace = params[0].ToInt(pRuntime); + if (nFace < 0 || nFace > 2) + return false; + } std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); if (FieldArray.empty()) @@ -2897,48 +2835,36 @@ bool Field::buttonGetIcon(IJS_Context* cc, v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(CJS_Icon::g_nObjDefnID); - ASSERT(pObj.IsEmpty() == false); - - CJS_Icon* pJS_Icon = static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj)); - Icon* pIcon = (Icon*)pJS_Icon->GetEmbedObject(); - - CPDF_Stream* pIconStream = nullptr; - if (nface == 0) - pIconStream = pFormControl->GetNormalIcon(); - else if (nface == 1) - pIconStream = pFormControl->GetDownIcon(); - else if (nface == 2) - pIconStream = pFormControl->GetRolloverIcon(); - else + if (pObj.IsEmpty()) return false; - pIcon->SetStream(pIconStream); + CJS_Icon* pJS_Icon = static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj)); vRet = CJS_Value(pRuntime, pJS_Icon); return true; } -bool Field::buttonImportIcon(IJS_Context* cc, +bool Field::buttonImportIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Field::buttonSetCaption(IJS_Context* cc, +bool Field::buttonSetCaption(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::buttonSetIcon(IJS_Context* cc, +bool Field::buttonSetIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::checkThisBox(IJS_Context* cc, +bool Field::checkThisBox(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -2949,9 +2875,7 @@ bool Field::checkThisBox(IJS_Context* cc, if (!m_bCanSet) return false; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int nWidget = params[0].ToInt(pRuntime); - bool bCheckit = true; if (iSize >= 2) bCheckit = params[1].ToBool(pRuntime); @@ -2977,14 +2901,14 @@ bool Field::checkThisBox(IJS_Context* cc, return true; } -bool Field::clearItems(IJS_Context* cc, +bool Field::clearItems(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Field::defaultIsChecked(IJS_Context* cc, +bool Field::defaultIsChecked(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -2995,9 +2919,7 @@ bool Field::defaultIsChecked(IJS_Context* cc, if (iSize < 1) return false; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int nWidget = params[0].ToInt(pRuntime); - std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName); if (FieldArray.empty()) return false; @@ -3013,14 +2935,14 @@ bool Field::defaultIsChecked(IJS_Context* cc, return true; } -bool Field::deleteItemAt(IJS_Context* cc, +bool Field::deleteItemAt(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Field::getArray(IJS_Context* cc, +bool Field::getArray(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -3039,15 +2961,14 @@ bool Field::getArray(IJS_Context* cc, [](const std::unique_ptr<CFX_WideString>& p1, const std::unique_ptr<CFX_WideString>& p2) { return *p1 < *p2; }); - CJS_Context* pContext = (CJS_Context*)cc; - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); CJS_Array FormFieldArray; int j = 0; for (const auto& pStr : swSort) { v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID); - ASSERT(!pObj.IsEmpty()); + if (pObj.IsEmpty()) + return false; CJS_Field* pJSField = static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pObj)); @@ -3060,12 +2981,10 @@ bool Field::getArray(IJS_Context* cc, return true; } -bool Field::getItemAt(IJS_Context* cc, +bool Field::getItemAt(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - int iSize = params.size(); int nIdx = -1; if (iSize >= 1) @@ -3100,26 +3019,24 @@ bool Field::getItemAt(IJS_Context* cc, return true; } -bool Field::getLock(IJS_Context* cc, +bool Field::getLock(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::insertItemAt(IJS_Context* cc, +bool Field::insertItemAt(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Field::isBoxChecked(IJS_Context* cc, +bool Field::isBoxChecked(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - int nIndex = -1; if (params.size() >= 1) nIndex = params[0].ToInt(pRuntime); @@ -3140,12 +3057,10 @@ bool Field::isBoxChecked(IJS_Context* cc, return true; } -bool Field::isDefaultChecked(IJS_Context* cc, +bool Field::isDefaultChecked(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - int nIndex = -1; if (params.size() >= 1) nIndex = params[0].ToInt(pRuntime); @@ -3165,14 +3080,14 @@ bool Field::isDefaultChecked(IJS_Context* cc, return true; } -bool Field::setAction(IJS_Context* cc, +bool Field::setAction(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Field::setFocus(IJS_Context* cc, +bool Field::setFocus(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -3217,63 +3132,65 @@ bool Field::setFocus(IJS_Context* cc, return true; } -bool Field::setItems(IJS_Context* cc, +bool Field::setItems(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool Field::setLock(IJS_Context* cc, +bool Field::setLock(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::signatureGetModifications(IJS_Context* cc, +bool Field::signatureGetModifications(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::signatureGetSeedValue(IJS_Context* cc, +bool Field::signatureGetSeedValue(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::signatureInfo(IJS_Context* cc, +bool Field::signatureInfo(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::signatureSetSeedValue(IJS_Context* cc, +bool Field::signatureSetSeedValue(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::signatureSign(IJS_Context* cc, +bool Field::signatureSign(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::signatureValidate(IJS_Context* cc, +bool Field::signatureValidate(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool Field::source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Field::source(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (vp.IsGetting()) { vp << (CJS_Object*)nullptr; } diff --git a/fpdfsdk/javascript/Field.h b/fpdfsdk/javascript/Field.h index f3948fff5..462c1271a 100644 --- a/fpdfsdk/javascript/Field.h +++ b/fpdfsdk/javascript/Field.h @@ -77,182 +77,240 @@ class Field : public CJS_EmbedObj { explicit Field(CJS_Object* pJSObject); ~Field() override; - bool alignment(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool borderStyle(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool buttonAlignX(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool buttonAlignY(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool buttonFitBounds(IJS_Context* cc, + bool alignment(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool borderStyle(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool buttonAlignX(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool buttonAlignY(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool buttonFitBounds(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool buttonPosition(IJS_Context* cc, + bool buttonPosition(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool buttonScaleHow(IJS_Context* cc, + bool buttonScaleHow(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool buttonScaleWhen(IJS_Context* cc, + bool buttonScaleWhen(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool calcOrderIndex(IJS_Context* cc, + bool calcOrderIndex(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool charLimit(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool comb(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool commitOnSelChange(IJS_Context* cc, + bool charLimit(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool comb(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool commitOnSelChange(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool currentValueIndices(IJS_Context* cc, + bool currentValueIndices(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool defaultStyle(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool defaultValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool doNotScroll(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool doNotSpellCheck(IJS_Context* cc, + bool defaultStyle(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool defaultValue(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool doNotScroll(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool doNotSpellCheck(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool delay(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool display(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool doc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool editable(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool exportValues(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool fileSelect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool fillColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool hidden(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool highlight(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool lineWidth(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool multiline(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool multipleSelection(IJS_Context* cc, + bool delay(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool display(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool doc(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool editable(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool exportValues(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool fileSelect(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool fillColor(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool hidden(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool highlight(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool lineWidth(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool multiline(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool multipleSelection(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool numItems(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool page(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool password(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool print(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool radiosInUnison(IJS_Context* cc, + bool name(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool numItems(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool page(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool password(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool print(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool radiosInUnison(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool readonly(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool rect(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool required(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool richText(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool richValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool rotation(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool strokeColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool style(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool submitName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool textColor(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool textFont(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool textSize(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool userName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool valueAsString(IJS_Context* cc, + bool readonly(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool rect(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool required(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool richText(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool richValue(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool rotation(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool strokeColor(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool style(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool submitName(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool textColor(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool textFont(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool textSize(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool type(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool userName(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool value(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool valueAsString(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); + bool source(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool browseForFileToSubmit(IJS_Context* cc, + bool browseForFileToSubmit(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool buttonGetCaption(IJS_Context* cc, + bool buttonGetCaption(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool buttonGetIcon(IJS_Context* cc, + bool buttonGetIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool buttonImportIcon(IJS_Context* cc, + bool buttonImportIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool buttonSetCaption(IJS_Context* cc, + bool buttonSetCaption(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool buttonSetIcon(IJS_Context* cc, + bool buttonSetIcon(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool checkThisBox(IJS_Context* cc, + bool checkThisBox(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool clearItems(IJS_Context* cc, + bool clearItems(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool defaultIsChecked(IJS_Context* cc, + bool defaultIsChecked(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool deleteItemAt(IJS_Context* cc, + bool deleteItemAt(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getArray(IJS_Context* cc, + bool getArray(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getItemAt(IJS_Context* cc, + bool getItemAt(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool getLock(IJS_Context* cc, + bool getLock(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool insertItemAt(IJS_Context* cc, + bool insertItemAt(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool isBoxChecked(IJS_Context* cc, + bool isBoxChecked(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool isDefaultChecked(IJS_Context* cc, + bool isDefaultChecked(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool setAction(IJS_Context* cc, + bool setAction(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool setFocus(IJS_Context* cc, + bool setFocus(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool setItems(IJS_Context* cc, + bool setItems(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool setLock(IJS_Context* cc, + bool setLock(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool signatureGetModifications(IJS_Context* cc, + bool signatureGetModifications(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool signatureGetSeedValue(IJS_Context* cc, + bool signatureGetSeedValue(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool signatureInfo(IJS_Context* cc, + bool signatureInfo(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool signatureSetSeedValue(IJS_Context* cc, + bool signatureSetSeedValue(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool signatureSign(IJS_Context* cc, + bool signatureSign(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool signatureValidate(IJS_Context* cc, + bool signatureValidate(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); diff --git a/fpdfsdk/javascript/Icon.cpp b/fpdfsdk/javascript/Icon.cpp index 94841ef87..fa2f92f3c 100644 --- a/fpdfsdk/javascript/Icon.cpp +++ b/fpdfsdk/javascript/Icon.cpp @@ -10,41 +10,24 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -BEGIN_JS_STATIC_CONST(CJS_Icon) -END_JS_STATIC_CONST() +JSConstSpec CJS_Icon::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_Icon) -JS_STATIC_PROP_ENTRY(name) -END_JS_STATIC_PROP() +JSPropertySpec CJS_Icon::PropertySpecs[] = { + {"name", get_name_static, set_name_static}, + {0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_Icon) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_Icon::MethodSpecs[] = {{0, 0}}; IMPLEMENT_JS_CLASS(CJS_Icon, Icon) Icon::Icon(CJS_Object* pJSObject) - : CJS_EmbedObj(pJSObject), m_pIconStream(nullptr), m_swIconName(L"") {} + : CJS_EmbedObj(pJSObject), m_swIconName(L"") {} Icon::~Icon() {} -void Icon::SetStream(CPDF_Stream* pIconStream) { - if (pIconStream) - m_pIconStream = pIconStream; -} - -CPDF_Stream* Icon::GetStream() { - return m_pIconStream; -} - -void Icon::SetIconName(CFX_WideString name) { - m_swIconName = name; -} - -CFX_WideString Icon::GetIconName() { - return m_swIconName; -} - -bool Icon::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool Icon::name(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; diff --git a/fpdfsdk/javascript/Icon.h b/fpdfsdk/javascript/Icon.h index 98a479c14..5580678fd 100644 --- a/fpdfsdk/javascript/Icon.h +++ b/fpdfsdk/javascript/Icon.h @@ -16,14 +16,11 @@ class Icon : public CJS_EmbedObj { explicit Icon(CJS_Object* pJSObject); ~Icon() override; - bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - void SetStream(CPDF_Stream* pIconStream); - CPDF_Stream* GetStream(); - void SetIconName(CFX_WideString name); - CFX_WideString GetIconName(); + bool name(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + CFX_WideString GetIconName() const { return m_swIconName; } + void SetIconName(CFX_WideString name) { m_swIconName = name; } private: - CPDF_Stream* m_pIconStream; CFX_WideString m_swIconName; }; diff --git a/fpdfsdk/javascript/JS_Define.h b/fpdfsdk/javascript/JS_Define.h index feab4d199..375ca3ac3 100644 --- a/fpdfsdk/javascript/JS_Define.h +++ b/fpdfsdk/javascript/JS_Define.h @@ -15,62 +15,26 @@ #include "fxjs/fxjs_v8.h" struct JSConstSpec { - const wchar_t* pName; + enum Type { Number = 0, String = 1 }; + + const char* pName; + Type eType; double number; - const wchar_t* str; - uint8_t t; // 0:double 1:str + const char* pStr; }; struct JSPropertySpec { - const wchar_t* pName; + const char* pName; v8::AccessorGetterCallback pPropGet; v8::AccessorSetterCallback pPropPut; }; struct JSMethodSpec { - const wchar_t* pName; + const char* pName; v8::FunctionCallback pMethodCall; }; -#define JS_WIDESTRING(widestring) L## #widestring -#define BEGIN_JS_STATIC_CONST(js_class_name) \ - JSConstSpec js_class_name::JS_Class_Consts[] = { -#define JS_STATIC_CONST_ENTRY_NUMBER(const_name, pValue) \ - { const_name, pValue, L"", 0 } \ - , - -#define JS_STATIC_CONST_ENTRY_STRING(const_name, pValue) \ - { const_name, 0, pValue, 1 } \ - , - -#define END_JS_STATIC_CONST() \ - { 0, 0, 0, 0 } \ - } \ - ; // NOLINT - -#define BEGIN_JS_STATIC_PROP(js_class_name) \ - JSPropertySpec js_class_name::JS_Class_Properties[] = { -#define JS_STATIC_PROP_ENTRY(prop_name) \ - {JS_WIDESTRING(prop_name), get_##prop_name##_static, \ - set_##prop_name##_static}, // NOLINT - -#define END_JS_STATIC_PROP() \ - { 0, 0, 0 } \ - } \ - ; // NOLINT - -#define BEGIN_JS_STATIC_METHOD(js_class_name) \ - JSMethodSpec js_class_name::JS_Class_Methods[] = { -#define JS_STATIC_METHOD_ENTRY(method_name) \ - { JS_WIDESTRING(method_name), method_name##_static } \ - , - -#define END_JS_STATIC_METHOD() \ - { 0, 0 } \ - } \ - ; // NOLINT - -template <class C, bool (C::*M)(IJS_Context*, CJS_PropValue&, CFX_WideString&)> +template <class C, bool (C::*M)(CJS_Runtime*, CJS_PropValue&, CFX_WideString&)> void JSPropGetter(const char* prop_name_string, const char* class_name_string, v8::Local<v8::String> property, @@ -81,11 +45,13 @@ void JSPropGetter(const char* prop_name_string, return; CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject()); CFX_WideString sError; CJS_PropValue value(pRuntime); value.StartGetting(); - if (!(pObj->*M)(pRuntime->GetCurrentContext(), value, sError)) { + if (!(pObj->*M)(pRuntime, value, sError)) { pRuntime->Error( JSFormatErrorString(class_name_string, prop_name_string, sError)); return; @@ -93,7 +59,7 @@ void JSPropGetter(const char* prop_name_string, info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(pRuntime)); } -template <class C, bool (C::*M)(IJS_Context*, CJS_PropValue&, CFX_WideString&)> +template <class C, bool (C::*M)(CJS_Runtime*, CJS_PropValue&, CFX_WideString&)> void JSPropSetter(const char* prop_name_string, const char* class_name_string, v8::Local<v8::String> property, @@ -105,11 +71,13 @@ void JSPropSetter(const char* prop_name_string, return; CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject()); CFX_WideString sError; CJS_PropValue propValue(pRuntime, CJS_Value(pRuntime, value)); propValue.StartSetting(); - if (!(pObj->*M)(pRuntime->GetCurrentContext(), propValue, sError)) { + if (!(pObj->*M)(pRuntime, propValue, sError)) { pRuntime->Error( JSFormatErrorString(class_name_string, prop_name_string, sError)); } @@ -130,7 +98,7 @@ void JSPropSetter(const char* prop_name_string, } template <class C, - bool (C::*M)(IJS_Context*, + bool (C::*M)(CJS_Runtime*, const std::vector<CJS_Value>&, CJS_Value&, CFX_WideString&)> @@ -147,11 +115,12 @@ void JSMethod(const char* method_name_string, } CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject()); CFX_WideString sError; CJS_Value valueRes(pRuntime); - if (!(pObj->*M)(pRuntime->GetCurrentContext(), parameters, valueRes, - sError)) { + if (!(pObj->*M)(pRuntime, parameters, valueRes, sError)) { pRuntime->Error( JSFormatErrorString(class_name_string, method_name_string, sError)); return; @@ -176,13 +145,13 @@ void JSMethod(const char* method_name_string, // All JS classes have a name, an object defintion ID, and the ability to // register themselves with FXJS_V8. We never make a BASE class on its own // because it can't really do anything. -#define DECLARE_JS_CLASS_BASE_PART() \ - static const wchar_t* g_pClassName; \ - static int g_nObjDefnID; \ +#define DECLARE_JS_CLASS_BASE_PART() \ + static const char* g_pClassName; \ + static int g_nObjDefnID; \ static void DefineJSObjects(CFXJS_Engine* pEngine, FXJSOBJTYPE eObjType); -#define IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \ - const wchar_t* js_class_name::g_pClassName = JS_WIDESTRING(class_name); \ +#define IMPLEMENT_JS_CLASS_BASE_PART(js_class_name, class_name) \ + const char* js_class_name::g_pClassName = #class_name; \ int js_class_name::g_nObjDefnID = -1; // CONST classes provide constants, but not constructors, methods, or props. @@ -200,19 +169,18 @@ void JSMethod(const char* method_name_string, DefineConsts(pEngine); \ } -#define DECLARE_JS_CLASS_CONST_PART() \ - static JSConstSpec JS_Class_Consts[]; \ +#define DECLARE_JS_CLASS_CONST_PART() \ + static JSConstSpec ConstSpecs[]; \ static void DefineConsts(CFXJS_Engine* pEngine); -#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name) \ - void js_class_name::DefineConsts(CFXJS_Engine* pEngine) { \ - for (size_t i = 0; i < FX_ArraySize(JS_Class_Consts) - 1; ++i) { \ - pEngine->DefineObjConst( \ - g_nObjDefnID, JS_Class_Consts[i].pName, \ - JS_Class_Consts[i].t == 0 \ - ? pEngine->NewNumber(JS_Class_Consts[i].number) \ - : pEngine->NewString(JS_Class_Consts[i].str)); \ - } \ +#define IMPLEMENT_JS_CLASS_CONST_PART(js_class_name, class_name) \ + void js_class_name::DefineConsts(CFXJS_Engine* pEngine) { \ + for (size_t i = 0; i < FX_ArraySize(ConstSpecs) - 1; ++i) { \ + pEngine->DefineObjConst(g_nObjDefnID, ConstSpecs[i].pName, \ + ConstSpecs[i].eType == JSConstSpec::Number \ + ? pEngine->NewNumber(ConstSpecs[i].number) \ + : pEngine->NewString(ConstSpecs[i].pStr)); \ + } \ } // Convenience macros for declaring classes without an alternate. @@ -245,36 +213,34 @@ void JSMethod(const char* method_name_string, static void JSDestructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj); \ static void DefineProps(CFXJS_Engine* pEngine); \ static void DefineMethods(CFXJS_Engine* pEngine); \ - static JSPropertySpec JS_Class_Properties[]; \ - static JSMethodSpec JS_Class_Methods[]; - -#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, \ - class_name) \ - void js_class_name::JSConstructor(CFXJS_Engine* pEngine, \ - v8::Local<v8::Object> obj) { \ - CJS_Object* pObj = new js_class_name(obj); \ - pObj->SetEmbedObject(new class_alternate(pObj)); \ - pEngine->SetObjectPrivate(obj, (void*)pObj); \ - pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine)); \ - } \ - void js_class_name::JSDestructor(CFXJS_Engine* pEngine, \ - v8::Local<v8::Object> obj) { \ - js_class_name* pObj = \ - static_cast<js_class_name*>(pEngine->GetObjectPrivate(obj)); \ - delete pObj; \ - } \ - void js_class_name::DefineProps(CFXJS_Engine* pEngine) { \ - for (size_t i = 0; i < FX_ArraySize(JS_Class_Properties) - 1; ++i) { \ - pEngine->DefineObjProperty(g_nObjDefnID, JS_Class_Properties[i].pName, \ - JS_Class_Properties[i].pPropGet, \ - JS_Class_Properties[i].pPropPut); \ - } \ - } \ - void js_class_name::DefineMethods(CFXJS_Engine* pEngine) { \ - for (size_t i = 0; i < FX_ArraySize(JS_Class_Methods) - 1; ++i) { \ - pEngine->DefineObjMethod(g_nObjDefnID, JS_Class_Methods[i].pName, \ - JS_Class_Methods[i].pMethodCall); \ - } \ + static JSPropertySpec PropertySpecs[]; \ + static JSMethodSpec MethodSpecs[]; + +#define IMPLEMENT_JS_CLASS_RICH_PART(js_class_name, class_alternate, \ + class_name) \ + void js_class_name::JSConstructor(CFXJS_Engine* pEngine, \ + v8::Local<v8::Object> obj) { \ + CJS_Object* pObj = new js_class_name(obj); \ + pObj->SetEmbedObject(new class_alternate(pObj)); \ + pEngine->SetObjectPrivate(obj, (void*)pObj); \ + pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine)); \ + } \ + void js_class_name::JSDestructor(CFXJS_Engine* pEngine, \ + v8::Local<v8::Object> obj) { \ + delete static_cast<js_class_name*>(pEngine->GetObjectPrivate(obj)); \ + } \ + void js_class_name::DefineProps(CFXJS_Engine* pEngine) { \ + for (size_t i = 0; i < FX_ArraySize(PropertySpecs) - 1; ++i) { \ + pEngine->DefineObjProperty(g_nObjDefnID, PropertySpecs[i].pName, \ + PropertySpecs[i].pPropGet, \ + PropertySpecs[i].pPropPut); \ + } \ + } \ + void js_class_name::DefineMethods(CFXJS_Engine* pEngine) { \ + for (size_t i = 0; i < FX_ArraySize(MethodSpecs) - 1; ++i) { \ + pEngine->DefineObjMethod(g_nObjDefnID, MethodSpecs[i].pName, \ + MethodSpecs[i].pMethodCall); \ + } \ } // Special JS classes implement methods, props, and queries, but not consts. @@ -348,12 +314,18 @@ void JSSpecialPropQuery(const char*, const v8::PropertyCallbackInfo<v8::Integer>& info) { CJS_Runtime* pRuntime = CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); - v8::String::Utf8Value utf8_value(property); - CFX_WideString propname = CFX_WideString::FromUTF8( - CFX_ByteStringC(*utf8_value, utf8_value.length())); + if (!pRuntime) + return; + CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; + Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); + v8::String::Utf8Value utf8_value(property); + CFX_WideString propname = CFX_WideString::FromUTF8( + CFX_ByteStringC(*utf8_value, utf8_value.length())); bool bRet = pObj->QueryProperty(propname.c_str()); info.GetReturnValue().Set(bRet ? 4 : 0); } @@ -366,8 +338,12 @@ void JSSpecialPropGet(const char* class_name, CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); if (!pRuntime) return; + CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; + Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); v8::String::Utf8Value utf8_value(property); CFX_WideString propname = CFX_WideString::FromUTF8( @@ -375,8 +351,7 @@ void JSSpecialPropGet(const char* class_name, CFX_WideString sError; CJS_PropValue value(pRuntime); value.StartGetting(); - if (!pObj->DoProperty(pRuntime->GetCurrentContext(), propname.c_str(), value, - sError)) { + if (!pObj->DoProperty(pRuntime, propname.c_str(), value, sError)) { pRuntime->Error(JSFormatErrorString(class_name, "GetProperty", sError)); return; } @@ -392,8 +367,12 @@ void JSSpecialPropPut(const char* class_name, CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); if (!pRuntime) return; + CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; + Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); v8::String::Utf8Value utf8_value(property); CFX_WideString propname = CFX_WideString::FromUTF8( @@ -401,8 +380,7 @@ void JSSpecialPropPut(const char* class_name, CFX_WideString sError; CJS_PropValue PropValue(pRuntime, CJS_Value(pRuntime, value)); PropValue.StartSetting(); - if (!pObj->DoProperty(pRuntime->GetCurrentContext(), propname.c_str(), - PropValue, sError)) { + if (!pObj->DoProperty(pRuntime, propname.c_str(), PropValue, sError)) { pRuntime->Error(JSFormatErrorString(class_name, "PutProperty", sError)); } } @@ -415,22 +393,25 @@ void JSSpecialPropDel(const char* class_name, CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate()); if (!pRuntime) return; + CJS_Object* pJSObj = static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder())); + if (!pJSObj) + return; + Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject()); v8::String::Utf8Value utf8_value(property); CFX_WideString propname = CFX_WideString::FromUTF8( CFX_ByteStringC(*utf8_value, utf8_value.length())); CFX_WideString sError; - if (!pObj->DelProperty(pRuntime->GetCurrentContext(), propname.c_str(), - sError)) { + if (!pObj->DelProperty(pRuntime, propname.c_str(), sError)) { CFX_ByteString cbName; cbName.Format("%s.%s", class_name, "DelProperty"); // Probably a missing call to JSFX_Error(). } } -template <bool (*F)(IJS_Context*, +template <bool (*F)(CJS_Runtime*, const std::vector<CJS_Value>&, CJS_Value&, CFX_WideString&)> @@ -446,7 +427,7 @@ void JSGlobalFunc(const char* func_name_string, } CJS_Value valueRes(pRuntime); CFX_WideString sError; - if (!(*F)(pRuntime->GetCurrentContext(), parameters, valueRes, sError)) { + if (!(*F)(pRuntime, parameters, valueRes, sError)) { pRuntime->Error(JSFormatErrorString(func_name_string, nullptr, sError)); return; } @@ -459,24 +440,17 @@ void JSGlobalFunc(const char* func_name_string, JSGlobalFunc<fun_name>(#fun_name, info); \ } -#define JS_STATIC_DECLARE_GLOBAL_FUN() \ - static JSMethodSpec global_methods[]; \ +#define JS_STATIC_DECLARE_GLOBAL_FUN() \ + static JSMethodSpec GlobalFunctionSpecs[]; \ static void DefineJSObjects(CFXJS_Engine* pEngine) -#define BEGIN_JS_STATIC_GLOBAL_FUN(js_class_name) \ - JSMethodSpec js_class_name::global_methods[] = { -#define JS_STATIC_GLOBAL_FUN_ENTRY(method_name) \ - JS_STATIC_METHOD_ENTRY(method_name) - -#define END_JS_STATIC_GLOBAL_FUN() END_JS_STATIC_METHOD() - -#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \ - void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine) { \ - for (size_t i = 0; i < FX_ArraySize(global_methods) - 1; ++i) { \ - pEngine->DefineGlobalMethod( \ - js_class_name::global_methods[i].pName, \ - js_class_name::global_methods[i].pMethodCall); \ - } \ +#define IMPLEMENT_JS_STATIC_GLOBAL_FUN(js_class_name) \ + void js_class_name::DefineJSObjects(CFXJS_Engine* pEngine) { \ + for (size_t i = 0; i < FX_ArraySize(GlobalFunctionSpecs) - 1; ++i) { \ + pEngine->DefineGlobalMethod( \ + js_class_name::GlobalFunctionSpecs[i].pName, \ + js_class_name::GlobalFunctionSpecs[i].pMethodCall); \ + } \ } #endif // FPDFSDK_JAVASCRIPT_JS_DEFINE_H_ diff --git a/fpdfsdk/javascript/JS_EventHandler.cpp b/fpdfsdk/javascript/JS_EventHandler.cpp index 5715cb921..bd1c8e29d 100644 --- a/fpdfsdk/javascript/JS_EventHandler.cpp +++ b/fpdfsdk/javascript/JS_EventHandler.cpp @@ -11,11 +11,11 @@ #include "fpdfsdk/javascript/JS_Define.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" -CJS_EventHandler::CJS_EventHandler(CJS_Context* pContext) - : m_pJSContext(pContext), +CJS_EventHandler::CJS_EventHandler(CJS_EventContext* pContext) + : m_pJSEventContext(pContext), m_eEventType(JET_UNKNOWN), m_bValid(false), m_pWideStrChange(nullptr), @@ -45,60 +45,60 @@ void CJS_EventHandler::OnApp_Init() { void CJS_EventHandler::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv, const CFX_WideString& strTargetName) { Initial(JET_DOC_OPEN); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); m_strTargetName = strTargetName; } void CJS_EventHandler::OnDoc_WillPrint( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_DOC_WILLPRINT); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnDoc_DidPrint( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_DOC_DIDPRINT); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnDoc_WillSave( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_DOC_WILLSAVE); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnDoc_DidSave( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_DOC_DIDSAVE); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnDoc_WillClose( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_DOC_WILLCLOSE); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_PAGE_OPEN); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_PAGE_CLOSE); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnPage_InView( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_PAGE_INVIEW); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnPage_OutView( CPDFSDK_FormFillEnvironment* pFormFillEnv) { Initial(JET_PAGE_OUTVIEW); - m_pTargetFormFillEnv = pFormFillEnv; + m_pTargetFormFillEnv.Reset(pFormFillEnv); } void CJS_EventHandler::OnField_MouseEnter(bool bModifier, @@ -247,7 +247,7 @@ void CJS_EventHandler::OnScreen_Focus(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_Blur(bool bModifier, @@ -257,7 +257,7 @@ void CJS_EventHandler::OnScreen_Blur(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_Open(bool bModifier, @@ -267,7 +267,7 @@ void CJS_EventHandler::OnScreen_Open(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_Close(bool bModifier, @@ -277,7 +277,7 @@ void CJS_EventHandler::OnScreen_Close(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_MouseDown(bool bModifier, @@ -287,7 +287,7 @@ void CJS_EventHandler::OnScreen_MouseDown(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_MouseUp(bool bModifier, @@ -297,7 +297,7 @@ void CJS_EventHandler::OnScreen_MouseUp(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_MouseEnter(bool bModifier, @@ -307,7 +307,7 @@ void CJS_EventHandler::OnScreen_MouseEnter(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_MouseExit(bool bModifier, @@ -317,38 +317,35 @@ void CJS_EventHandler::OnScreen_MouseExit(bool bModifier, m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_InView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen) { Initial(JET_SCREEN_INVIEW); - m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnScreen_OutView(bool bModifier, bool bShift, CPDFSDK_Annot* pScreen) { Initial(JET_SCREEN_OUTVIEW); - m_bModifier = bModifier; m_bShift = bShift; - m_pTargetAnnot = pScreen; + m_pTargetAnnot.Reset(pScreen); } void CJS_EventHandler::OnLink_MouseUp( CPDFSDK_FormFillEnvironment* pTargetFormFillEnv) { Initial(JET_LINK_MOUSEUP); - m_pTargetFormFillEnv = pTargetFormFillEnv; + m_pTargetFormFillEnv.Reset(pTargetFormFillEnv); } void CJS_EventHandler::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) { Initial(JET_BOOKMARK_MOUSEUP); - m_pTargetBookMark = pBookMark; } @@ -356,7 +353,7 @@ void CJS_EventHandler::OnMenu_Exec( CPDFSDK_FormFillEnvironment* pTargetFormFillEnv, const CFX_WideString& strTargetName) { Initial(JET_MENU_EXEC); - m_pTargetFormFillEnv = pTargetFormFillEnv; + m_pTargetFormFillEnv.Reset(pTargetFormFillEnv); m_strTargetName = strTargetName; } @@ -367,7 +364,7 @@ void CJS_EventHandler::OnExternal_Exec() { void CJS_EventHandler::OnBatchExec( CPDFSDK_FormFillEnvironment* pTargetFormFillEnv) { Initial(JET_BATCH_EXEC); - m_pTargetFormFillEnv = pTargetFormFillEnv; + m_pTargetFormFillEnv.Reset(pTargetFormFillEnv); } void CJS_EventHandler::OnConsole_Exec() { @@ -397,8 +394,8 @@ void CJS_EventHandler::Initial(JS_EVENT_T type) { m_bRcDu = false; m_pTargetBookMark = nullptr; - m_pTargetFormFillEnv = nullptr; - m_pTargetAnnot = nullptr; + m_pTargetFormFillEnv.Reset(); + m_pTargetAnnot.Reset(); m_bValid = true; } @@ -590,49 +587,55 @@ bool CJS_EventHandler::Shift() { } Field* CJS_EventHandler::Source() { - CJS_Runtime* pRuntime = m_pJSContext->GetJSRuntime(); + CJS_Runtime* pRuntime = m_pJSEventContext->GetJSRuntime(); v8::Local<v8::Object> pDocObj = pRuntime->NewFxDynamicObj(CJS_Document::g_nObjDefnID); - ASSERT(!pDocObj.IsEmpty()); + if (pDocObj.IsEmpty()) + return nullptr; v8::Local<v8::Object> pFieldObj = pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID); - ASSERT(!pFieldObj.IsEmpty()); + if (pFieldObj.IsEmpty()) + return nullptr; CJS_Document* pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pDocObj)); - Document* pDocument = (Document*)pJSDocument->GetEmbedObject(); - pDocument->SetFormFillEnv(m_pTargetFormFillEnv - ? m_pTargetFormFillEnv - : m_pJSContext->GetFormFillEnv()); - CJS_Field* pJSField = static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pFieldObj)); - Field* pField = (Field*)pJSField->GetEmbedObject(); + + Document* pDocument = static_cast<Document*>(pJSDocument->GetEmbedObject()); + pDocument->SetFormFillEnv(m_pTargetFormFillEnv + ? m_pTargetFormFillEnv.Get() + : m_pJSEventContext->GetFormFillEnv()); + + Field* pField = static_cast<Field*>(pJSField->GetEmbedObject()); pField->AttachField(pDocument, m_strSourceName); return pField; } Field* CJS_EventHandler::Target_Field() { - CJS_Runtime* pRuntime = m_pJSContext->GetJSRuntime(); + CJS_Runtime* pRuntime = m_pJSEventContext->GetJSRuntime(); v8::Local<v8::Object> pDocObj = pRuntime->NewFxDynamicObj(CJS_Document::g_nObjDefnID); - ASSERT(!pDocObj.IsEmpty()); + if (pDocObj.IsEmpty()) + return nullptr; v8::Local<v8::Object> pFieldObj = pRuntime->NewFxDynamicObj(CJS_Field::g_nObjDefnID); - ASSERT(!pFieldObj.IsEmpty()); + if (pFieldObj.IsEmpty()) + return nullptr; CJS_Document* pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pDocObj)); - Document* pDocument = (Document*)pJSDocument->GetEmbedObject(); - pDocument->SetFormFillEnv(m_pTargetFormFillEnv - ? m_pTargetFormFillEnv - : m_pJSContext->GetFormFillEnv()); - CJS_Field* pJSField = static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pFieldObj)); - Field* pField = (Field*)pJSField->GetEmbedObject(); + + Document* pDocument = static_cast<Document*>(pJSDocument->GetEmbedObject()); + pDocument->SetFormFillEnv(m_pTargetFormFillEnv + ? m_pTargetFormFillEnv.Get() + : m_pJSEventContext->GetFormFillEnv()); + + Field* pField = static_cast<Field*>(pJSField->GetEmbedObject()); pField->AttachField(pDocument, m_strTargetName); return pField; } diff --git a/fpdfsdk/javascript/JS_EventHandler.h b/fpdfsdk/javascript/JS_EventHandler.h index 8cfcfa7eb..b9836b04e 100644 --- a/fpdfsdk/javascript/JS_EventHandler.h +++ b/fpdfsdk/javascript/JS_EventHandler.h @@ -9,10 +9,10 @@ #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" +#include "fpdfsdk/cpdfsdk_formfillenvironment.h" -class CJS_Context; +class CJS_EventContext; class CPDFSDK_Annot; -class CPDFSDK_FormFillEnvironment; class CPDF_Bookmark; class CPDF_FormField; class Field; @@ -60,7 +60,7 @@ enum JS_EVENT_T { class CJS_EventHandler { public: - explicit CJS_EventHandler(CJS_Context* pContext); + explicit CJS_EventHandler(CJS_EventContext* pContext); virtual ~CJS_EventHandler(); void OnApp_Init(); @@ -165,7 +165,7 @@ class CJS_EventHandler { JS_EVENT_T EventType() { return m_eEventType; } public: - CJS_Context* m_pJSContext; + CJS_EventContext* const m_pJSEventContext; // Not Owned. JS_EVENT_T m_eEventType; bool m_bValid; @@ -189,8 +189,8 @@ class CJS_EventHandler { bool m_bRcDu; CPDF_Bookmark* m_pTargetBookMark; - CPDFSDK_FormFillEnvironment* m_pTargetFormFillEnv; - CPDFSDK_Annot* m_pTargetAnnot; + CPDFSDK_FormFillEnvironment::ObservedPtr m_pTargetFormFillEnv; + CPDFSDK_Annot::ObservedPtr m_pTargetAnnot; }; #endif // FPDFSDK_JAVASCRIPT_JS_EVENTHANDLER_H_ diff --git a/fpdfsdk/javascript/JS_Object.cpp b/fpdfsdk/javascript/JS_Object.cpp index 9ef6cdd23..cd8688933 100644 --- a/fpdfsdk/javascript/JS_Object.cpp +++ b/fpdfsdk/javascript/JS_Object.cpp @@ -7,7 +7,7 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Define.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" CJS_EmbedObj::CJS_EmbedObj(CJS_Object* pJSObject) : m_pJSObject(pJSObject) {} diff --git a/fpdfsdk/javascript/JS_Object.h b/fpdfsdk/javascript/JS_Object.h index 658a5e212..2e5c75c94 100644 --- a/fpdfsdk/javascript/JS_Object.h +++ b/fpdfsdk/javascript/JS_Object.h @@ -14,7 +14,7 @@ #include "fpdfsdk/javascript/cjs_runtime.h" #include "fxjs/fxjs_v8.h" -class CJS_Context; +class CJS_EventContext; class CJS_Object; class CPDFSDK_FormFillEnvironment; diff --git a/fpdfsdk/javascript/JS_Runtime_Stub.cpp b/fpdfsdk/javascript/JS_Runtime_Stub.cpp index 96148d83a..dcd8ceb97 100644 --- a/fpdfsdk/javascript/JS_Runtime_Stub.cpp +++ b/fpdfsdk/javascript/JS_Runtime_Stub.cpp @@ -6,16 +6,16 @@ #include <memory> -#include "fpdfsdk/javascript/ijs_context.h" +#include "fpdfsdk/javascript/ijs_event_context.h" #include "fpdfsdk/javascript/ijs_runtime.h" #include "third_party/base/ptr_util.h" -class CJS_ContextStub final : public IJS_Context { +class CJS_EventContextStub final : public IJS_EventContext { public: - CJS_ContextStub() {} - ~CJS_ContextStub() override {} + CJS_EventContextStub() {} + ~CJS_EventContextStub() override {} - // IJS_Context: + // IJS_EventContext: bool RunScript(const CFX_WideString& script, CFX_WideString* info) override { return false; } @@ -124,14 +124,13 @@ class CJS_RuntimeStub final : public IJS_Runtime { : m_pFormFillEnv(pFormFillEnv) {} ~CJS_RuntimeStub() override {} - IJS_Context* NewContext() override { + IJS_EventContext* NewEventContext() override { if (!m_pContext) - m_pContext = pdfium::MakeUnique<CJS_ContextStub>(); - return GetCurrentContext(); + m_pContext = pdfium::MakeUnique<CJS_EventContextStub>(); + return m_pContext.get(); } - IJS_Context* GetCurrentContext() override { return m_pContext.get(); } - void ReleaseContext(IJS_Context* pContext) override {} + void ReleaseEventContext(IJS_EventContext* pContext) override {} CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override { return m_pFormFillEnv; @@ -154,7 +153,7 @@ class CJS_RuntimeStub final : public IJS_Runtime { protected: CPDFSDK_FormFillEnvironment* m_pFormFillEnv; - std::unique_ptr<CJS_ContextStub> m_pContext; + std::unique_ptr<CJS_EventContextStub> m_pContext; }; // static diff --git a/fpdfsdk/javascript/JS_Value.cpp b/fpdfsdk/javascript/JS_Value.cpp index 7900914a8..b05884756 100644 --- a/fpdfsdk/javascript/JS_Value.cpp +++ b/fpdfsdk/javascript/JS_Value.cpp @@ -677,8 +677,9 @@ double JS_DateParse(const CFX_WideString& str) { if (v->IsFunction()) { v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v); const int argc = 1; - v8::Local<v8::String> timeStr = - CJS_Runtime::CurrentRuntimeFromIsolate(pIsolate)->WSToJSString(str); + v8::Local<v8::Value> timeStr = + CJS_Runtime::CurrentRuntimeFromIsolate(pIsolate)->NewString( + str.AsStringC()); v8::Local<v8::Value> argv[argc] = {timeStr}; v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked(); if (v->IsNumber()) { diff --git a/fpdfsdk/javascript/PublicMethods.cpp b/fpdfsdk/javascript/PublicMethods.cpp index c0ea84c0a..3bcbc341a 100644 --- a/fpdfsdk/javascript/PublicMethods.cpp +++ b/fpdfsdk/javascript/PublicMethods.cpp @@ -22,7 +22,7 @@ #include "fpdfsdk/javascript/JS_EventHandler.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" #include "fpdfsdk/javascript/color.h" #include "fpdfsdk/javascript/resource.h" @@ -30,30 +30,30 @@ #define DOUBLE_CORRECT 0.000000000000001 -BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods) -JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format) -JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke) -JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format) -JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke) -JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx) -JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx) -JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format) -JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke) -JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx) -JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx) -JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format) -JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke) -JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format) -JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke) -JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx) -JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple) -JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber) -JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate) -JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate) -JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange) -JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx) -JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums) -END_JS_STATIC_GLOBAL_FUN() +JSMethodSpec CJS_PublicMethods::GlobalFunctionSpecs[] = { + {"AFNumber_Format", AFNumber_Format_static}, + {"AFNumber_Keystroke", AFNumber_Keystroke_static}, + {"AFPercent_Format", AFPercent_Format_static}, + {"AFPercent_Keystroke", AFPercent_Keystroke_static}, + {"AFDate_FormatEx", AFDate_FormatEx_static}, + {"AFDate_KeystrokeEx", AFDate_KeystrokeEx_static}, + {"AFDate_Format", AFDate_Format_static}, + {"AFDate_Keystroke", AFDate_Keystroke_static}, + {"AFTime_FormatEx", AFTime_FormatEx_static}, + {"AFTime_KeystrokeEx", AFTime_KeystrokeEx_static}, + {"AFTime_Format", AFTime_Format_static}, + {"AFTime_Keystroke", AFTime_Keystroke_static}, + {"AFSpecial_Format", AFSpecial_Format_static}, + {"AFSpecial_Keystroke", AFSpecial_Keystroke_static}, + {"AFSpecial_KeystrokeEx", AFSpecial_KeystrokeEx_static}, + {"AFSimple", AFSimple_static}, + {"AFMakeNumber", AFMakeNumber_static}, + {"AFSimple_Calculate", AFSimple_Calculate_static}, + {"AFRange_Validate", AFRange_Validate_static}, + {"AFMergeChange", AFMergeChange_static}, + {"AFParseDateEx", AFParseDateEx_static}, + {"AFExtractNums", AFExtractNums_static}, + {0, 0}}; IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods) @@ -82,7 +82,7 @@ CFX_WideString StrTrim(const CFX_WideString& pStr) { return result; } -void AlertIfPossible(CJS_Context* pContext, const FX_WCHAR* swMsg) { +void AlertIfPossible(CJS_EventContext* pContext, const FX_WCHAR* swMsg) { CPDFSDK_FormFillEnvironment* pFormFillEnv = pContext->GetFormFillEnv(); if (pFormFillEnv) pFormFillEnv->JS_appAlert(swMsg, nullptr, 0, 3); @@ -750,7 +750,7 @@ CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate, // function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency, // bCurrencyPrepend) -bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc, +bool CJS_PublicMethods::AFNumber_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -760,9 +760,8 @@ bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc, return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); if (!pEvent->m_pValue) return false; @@ -855,7 +854,7 @@ bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc, vProp.StartGetting(); vProp << arColor; vProp.StartSetting(); - fTarget->textColor(cc, vProp, sError); // red + fTarget->textColor(pRuntime, vProp, sError); // red } } } else { @@ -872,7 +871,7 @@ bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc, CJS_PropValue vProp(pRuntime); vProp.StartGetting(); - fTarget->textColor(cc, vProp, sError); + fTarget->textColor(pRuntime, vProp, sError); CJS_Array aProp; vProp.GetJSValue()->ConvertToArray(pRuntime, aProp); @@ -887,7 +886,7 @@ bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc, vProp2.StartGetting(); vProp2 << arColor; vProp2.StartSetting(); - fTarget->textColor(cc, vProp2, sError); + fTarget->textColor(pRuntime, vProp2, sError); } } } @@ -898,16 +897,15 @@ bool CJS_PublicMethods::AFNumber_Format(IJS_Context* cc, // function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, // bCurrencyPrepend) -bool CJS_PublicMethods::AFNumber_Keystroke(IJS_Context* cc, +bool CJS_PublicMethods::AFNumber_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); - if (params.size() < 2) return false; + CJS_EventContext* pContext = pRuntime->GetCurrentEventContext(); + CJS_EventHandler* pEvent = pContext->GetEventHandler(); if (!pEvent->m_pValue) return false; @@ -945,7 +943,6 @@ bool CJS_PublicMethods::AFNumber_Keystroke(IJS_Context* cc, } } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iSepStyle = params[1].ToInt(pRuntime); if (iSepStyle < 0 || iSepStyle > 3) iSepStyle = 0; @@ -999,19 +996,18 @@ bool CJS_PublicMethods::AFNumber_Keystroke(IJS_Context* cc, } // function AFPercent_Format(nDec, sepStyle) -bool CJS_PublicMethods::AFPercent_Format(IJS_Context* cc, +bool CJS_PublicMethods::AFPercent_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { #if _FX_OS_ != _FX_ANDROID_ - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); - if (params.size() != 2) { sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR); return false; } + + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); if (!pEvent->m_pValue) return false; @@ -1092,26 +1088,25 @@ bool CJS_PublicMethods::AFPercent_Format(IJS_Context* cc, } // AFPercent_Keystroke(nDec, sepStyle) bool CJS_PublicMethods::AFPercent_Keystroke( - IJS_Context* cc, + CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - return AFNumber_Keystroke(cc, params, vRet, sError); + return AFNumber_Keystroke(pRuntime, params, vRet, sError); } // function AFDate_FormatEx(cFormat) -bool CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc, +bool CJS_PublicMethods::AFDate_FormatEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); - if (params.size() != 1) { sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR); return false; } + + CJS_EventContext* pContext = pRuntime->GetCurrentEventContext(); + CJS_EventHandler* pEvent = pContext->GetEventHandler(); if (!pEvent->m_pValue) return false; @@ -1200,22 +1195,21 @@ double CJS_PublicMethods::MakeInterDate(const CFX_WideString& strValue) { } // AFDate_KeystrokeEx(cFormat) -bool CJS_PublicMethods::AFDate_KeystrokeEx(IJS_Context* cc, +bool CJS_PublicMethods::AFDate_KeystrokeEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); - if (params.size() != 1) { sError = L"AFDate_KeystrokeEx's parameters' size r not correct"; return false; } + CJS_EventContext* pContext = pRuntime->GetCurrentEventContext(); + CJS_EventHandler* pEvent = pContext->GetEventHandler(); if (pEvent->WillCommit()) { if (!pEvent->m_pValue) return false; + CFX_WideString strValue = pEvent->Value(); if (strValue.IsEmpty()) return true; @@ -1235,7 +1229,7 @@ bool CJS_PublicMethods::AFDate_KeystrokeEx(IJS_Context* cc, return true; } -bool CJS_PublicMethods::AFDate_Format(IJS_Context* cc, +bool CJS_PublicMethods::AFDate_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1244,7 +1238,6 @@ bool CJS_PublicMethods::AFDate_Format(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iIndex = params[0].ToInt(pRuntime); const FX_WCHAR* cFormats[] = {L"m/d", L"m/d/yy", @@ -1265,13 +1258,12 @@ bool CJS_PublicMethods::AFDate_Format(IJS_Context* cc, iIndex = 0; std::vector<CJS_Value> newParams; - newParams.push_back( - CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex])); - return AFDate_FormatEx(cc, newParams, vRet, sError); + newParams.push_back(CJS_Value(pRuntime, cFormats[iIndex])); + return AFDate_FormatEx(pRuntime, newParams, vRet, sError); } // AFDate_KeystrokeEx(cFormat) -bool CJS_PublicMethods::AFDate_Keystroke(IJS_Context* cc, +bool CJS_PublicMethods::AFDate_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1280,7 +1272,6 @@ bool CJS_PublicMethods::AFDate_Keystroke(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iIndex = params[0].ToInt(pRuntime); const FX_WCHAR* cFormats[] = {L"m/d", L"m/d/yy", @@ -1301,13 +1292,12 @@ bool CJS_PublicMethods::AFDate_Keystroke(IJS_Context* cc, iIndex = 0; std::vector<CJS_Value> newParams; - newParams.push_back( - CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex])); - return AFDate_KeystrokeEx(cc, newParams, vRet, sError); + newParams.push_back(CJS_Value(pRuntime, cFormats[iIndex])); + return AFDate_KeystrokeEx(pRuntime, newParams, vRet, sError); } // function AFTime_Format(ptf) -bool CJS_PublicMethods::AFTime_Format(IJS_Context* cc, +bool CJS_PublicMethods::AFTime_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1316,7 +1306,6 @@ bool CJS_PublicMethods::AFTime_Format(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iIndex = params[0].ToInt(pRuntime); const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"}; @@ -1325,12 +1314,11 @@ bool CJS_PublicMethods::AFTime_Format(IJS_Context* cc, iIndex = 0; std::vector<CJS_Value> newParams; - newParams.push_back( - CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex])); - return AFDate_FormatEx(cc, newParams, vRet, sError); + newParams.push_back(CJS_Value(pRuntime, cFormats[iIndex])); + return AFDate_FormatEx(pRuntime, newParams, vRet, sError); } -bool CJS_PublicMethods::AFTime_Keystroke(IJS_Context* cc, +bool CJS_PublicMethods::AFTime_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1339,7 +1327,6 @@ bool CJS_PublicMethods::AFTime_Keystroke(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iIndex = params[0].ToInt(pRuntime); const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"}; @@ -1348,27 +1335,26 @@ bool CJS_PublicMethods::AFTime_Keystroke(IJS_Context* cc, iIndex = 0; std::vector<CJS_Value> newParams; - newParams.push_back( - CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex])); - return AFDate_KeystrokeEx(cc, newParams, vRet, sError); + newParams.push_back(CJS_Value(pRuntime, cFormats[iIndex])); + return AFDate_KeystrokeEx(pRuntime, newParams, vRet, sError); } -bool CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc, +bool CJS_PublicMethods::AFTime_FormatEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - return AFDate_FormatEx(cc, params, vRet, sError); + return AFDate_FormatEx(pRuntime, params, vRet, sError); } -bool CJS_PublicMethods::AFTime_KeystrokeEx(IJS_Context* cc, +bool CJS_PublicMethods::AFTime_KeystrokeEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - return AFDate_KeystrokeEx(cc, params, vRet, sError); + return AFDate_KeystrokeEx(pRuntime, params, vRet, sError); } // function AFSpecial_Format(psf) -bool CJS_PublicMethods::AFSpecial_Format(IJS_Context* cc, +bool CJS_PublicMethods::AFSpecial_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1377,12 +1363,11 @@ bool CJS_PublicMethods::AFSpecial_Format(IJS_Context* cc, return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); if (!pEvent->m_pValue) return false; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString wsSource = pEvent->Value(); CFX_WideString wsFormat; switch (params[0].ToInt(pRuntime)) { @@ -1409,19 +1394,17 @@ bool CJS_PublicMethods::AFSpecial_Format(IJS_Context* cc, // function AFSpecial_KeystrokeEx(mask) bool CJS_PublicMethods::AFSpecial_KeystrokeEx( - IJS_Context* cc, + CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); - if (params.size() < 1) { sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR); return false; } + CJS_EventContext* pContext = pRuntime->GetCurrentEventContext(); + CJS_EventHandler* pEvent = pContext->GetEventHandler(); if (!pEvent->m_pValue) return false; @@ -1494,7 +1477,7 @@ bool CJS_PublicMethods::AFSpecial_KeystrokeEx( // function AFSpecial_Keystroke(psf) bool CJS_PublicMethods::AFSpecial_Keystroke( - IJS_Context* cc, + CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1503,13 +1486,12 @@ bool CJS_PublicMethods::AFSpecial_Keystroke( return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); if (!pEvent->m_pValue) return false; const char* cFormat = ""; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); switch (params[0].ToInt(pRuntime)) { case 0: cFormat = "99999"; @@ -1529,11 +1511,11 @@ bool CJS_PublicMethods::AFSpecial_Keystroke( } std::vector<CJS_Value> params2; - params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat)); - return AFSpecial_KeystrokeEx(cc, params2, vRet, sError); + params2.push_back(CJS_Value(pRuntime, cFormat)); + return AFSpecial_KeystrokeEx(pRuntime, params2, vRet, sError); } -bool CJS_PublicMethods::AFMergeChange(IJS_Context* cc, +bool CJS_PublicMethods::AFMergeChange(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1542,9 +1524,8 @@ bool CJS_PublicMethods::AFMergeChange(IJS_Context* cc, return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); - CJS_EventHandler* pEventHandler = pContext->GetEventHandler(); + CJS_EventHandler* pEventHandler = + pRuntime->GetCurrentEventContext()->GetEventHandler(); CFX_WideString swValue; if (pEventHandler->m_pValue) @@ -1574,7 +1555,7 @@ bool CJS_PublicMethods::AFMergeChange(IJS_Context* cc, return true; } -bool CJS_PublicMethods::AFParseDateEx(IJS_Context* cc, +bool CJS_PublicMethods::AFParseDateEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1583,17 +1564,14 @@ bool CJS_PublicMethods::AFParseDateEx(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString sValue = params[0].ToCFXWideString(pRuntime); CFX_WideString sFormat = params[1].ToCFXWideString(pRuntime); - double dDate = MakeRegularDate(sValue, sFormat, nullptr); - if (JS_PortIsNan(dDate)) { CFX_WideString swMsg; swMsg.Format(JSGetStringFromID(IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str()); - AlertIfPossible((CJS_Context*)cc, swMsg.c_str()); + AlertIfPossible(pRuntime->GetCurrentEventContext(), swMsg.c_str()); return false; } @@ -1601,7 +1579,7 @@ bool CJS_PublicMethods::AFParseDateEx(IJS_Context* cc, return true; } -bool CJS_PublicMethods::AFSimple(IJS_Context* cc, +bool CJS_PublicMethods::AFSimple(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1610,7 +1588,6 @@ bool CJS_PublicMethods::AFSimple(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); vRet = CJS_Value(pRuntime, static_cast<double>(AF_Simple( params[0].ToCFXWideString(pRuntime).c_str(), params[1].ToDouble(pRuntime), @@ -1619,7 +1596,7 @@ bool CJS_PublicMethods::AFSimple(IJS_Context* cc, return true; } -bool CJS_PublicMethods::AFMakeNumber(IJS_Context* cc, +bool CJS_PublicMethods::AFMakeNumber(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1628,7 +1605,6 @@ bool CJS_PublicMethods::AFMakeNumber(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString ws = params[0].ToCFXWideString(pRuntime); ws.Replace(L",", L"."); vRet = CJS_Value(pRuntime, ws.c_str()); @@ -1638,7 +1614,7 @@ bool CJS_PublicMethods::AFMakeNumber(IJS_Context* cc, return true; } -bool CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc, +bool CJS_PublicMethods::AFSimple_Calculate(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1653,10 +1629,8 @@ bool CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc, return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CPDFSDK_InterForm* pReaderInterForm = - pContext->GetFormFillEnv()->GetInterForm(); + pRuntime->GetFormFillEnv()->GetInterForm(); CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm(); CFX_WideString sFunction = params[0].ToCFXWideString(pRuntime); @@ -1727,7 +1701,9 @@ bool CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc, dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) / FXSYS_pow((double)10, (double)6); + CJS_Value jsValue(pRuntime, dValue); + CJS_EventContext* pContext = pRuntime->GetCurrentEventContext(); if (pContext->GetEventHandler()->m_pValue) pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString(pRuntime); @@ -1737,7 +1713,7 @@ bool CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc, /* This function validates the current event to ensure that its value is ** within the specified range. */ -bool CJS_PublicMethods::AFRange_Validate(IJS_Context* cc, +bool CJS_PublicMethods::AFRange_Validate(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1745,8 +1721,7 @@ bool CJS_PublicMethods::AFRange_Validate(IJS_Context* cc, sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR); return false; } - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); + CJS_EventContext* pContext = pRuntime->GetCurrentEventContext(); CJS_EventHandler* pEvent = pContext->GetEventHandler(); if (!pEvent->m_pValue) return false; @@ -1784,7 +1759,7 @@ bool CJS_PublicMethods::AFRange_Validate(IJS_Context* cc, return true; } -bool CJS_PublicMethods::AFExtractNums(IJS_Context* cc, +bool CJS_PublicMethods::AFExtractNums(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -1793,14 +1768,12 @@ bool CJS_PublicMethods::AFExtractNums(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString str = params[0].ToCFXWideString(pRuntime); - CFX_WideString sPart; - CJS_Array nums; - if (str.GetAt(0) == L'.' || str.GetAt(0) == L',') str = L"0" + str; + CFX_WideString sPart; + CJS_Array nums; int nIndex = 0; for (int i = 0, sz = str.GetLength(); i < sz; i++) { FX_WCHAR wc = str.GetAt(i); diff --git a/fpdfsdk/javascript/PublicMethods.h b/fpdfsdk/javascript/PublicMethods.h index 0820c40c3..060c74303 100644 --- a/fpdfsdk/javascript/PublicMethods.h +++ b/fpdfsdk/javascript/PublicMethods.h @@ -18,91 +18,91 @@ class CJS_PublicMethods : public CJS_Object { : CJS_Object(pObject) {} ~CJS_PublicMethods() override {} - static bool AFNumber_Format(IJS_Context* cc, + static bool AFNumber_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFNumber_Keystroke(IJS_Context* cc, + static bool AFNumber_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFPercent_Format(IJS_Context* cc, + static bool AFPercent_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFPercent_Keystroke(IJS_Context* cc, + static bool AFPercent_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFDate_FormatEx(IJS_Context* cc, + static bool AFDate_FormatEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFDate_KeystrokeEx(IJS_Context* cc, + static bool AFDate_KeystrokeEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFDate_Format(IJS_Context* cc, + static bool AFDate_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFDate_Keystroke(IJS_Context* cc, + static bool AFDate_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFTime_FormatEx(IJS_Context* cc, + static bool AFTime_FormatEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); // - static bool AFTime_KeystrokeEx(IJS_Context* cc, + static bool AFTime_KeystrokeEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFTime_Format(IJS_Context* cc, + static bool AFTime_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFTime_Keystroke(IJS_Context* cc, + static bool AFTime_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFSpecial_Format(IJS_Context* cc, + static bool AFSpecial_Format(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFSpecial_Keystroke(IJS_Context* cc, + static bool AFSpecial_Keystroke(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFSpecial_KeystrokeEx(IJS_Context* cc, + static bool AFSpecial_KeystrokeEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); // - static bool AFSimple(IJS_Context* cc, + static bool AFSimple(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFMakeNumber(IJS_Context* cc, + static bool AFMakeNumber(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFSimple_Calculate(IJS_Context* cc, + static bool AFSimple_Calculate(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFRange_Validate(IJS_Context* cc, + static bool AFRange_Validate(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFMergeChange(IJS_Context* cc, + static bool AFMergeChange(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFParseDateEx(IJS_Context* cc, + static bool AFParseDateEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - static bool AFExtractNums(IJS_Context* cc, + static bool AFExtractNums(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp index 6562d1b59..3a8bf088f 100644 --- a/fpdfsdk/javascript/app.cpp +++ b/fpdfsdk/javascript/app.cpp @@ -17,7 +17,7 @@ #include "fpdfsdk/javascript/JS_EventHandler.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" #include "fpdfsdk/javascript/resource.h" #include "third_party/base/stl_util.h" @@ -55,7 +55,7 @@ class GlobalTimer { const uint32_t m_dwTimeOut; const CFX_WideString m_swJScript; CJS_Runtime::ObservedPtr m_pRuntime; - CPDFSDK_FormFillEnvironment* const m_pFormFillEnv; + CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; }; GlobalTimer::GlobalTimer(app* pObj, @@ -131,14 +131,11 @@ GlobalTimer::TimerMap* GlobalTimer::GetGlobalTimerMap() { return s_TimerMap; } -BEGIN_JS_STATIC_CONST(CJS_TimerObj) -END_JS_STATIC_CONST() +JSConstSpec CJS_TimerObj::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_TimerObj) -END_JS_STATIC_PROP() +JSPropertySpec CJS_TimerObj::PropertySpecs[] = {{0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_TimerObj) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_TimerObj::MethodSpecs[] = {{0, 0}}; IMPLEMENT_JS_CLASS(CJS_TimerObj, TimerObj) @@ -161,47 +158,46 @@ void TimerObj::SetTimer(GlobalTimer* pTimer) { #endif // PDF_ENABLE_XFA #define JS_NUM_FORMSVERSION 7 -BEGIN_JS_STATIC_CONST(CJS_App) -END_JS_STATIC_CONST() - -BEGIN_JS_STATIC_PROP(CJS_App) -JS_STATIC_PROP_ENTRY(activeDocs) -JS_STATIC_PROP_ENTRY(calculate) -JS_STATIC_PROP_ENTRY(formsVersion) -JS_STATIC_PROP_ENTRY(fs) -JS_STATIC_PROP_ENTRY(fullscreen) -JS_STATIC_PROP_ENTRY(language) -JS_STATIC_PROP_ENTRY(media) -JS_STATIC_PROP_ENTRY(platform) -JS_STATIC_PROP_ENTRY(runtimeHighlight) -JS_STATIC_PROP_ENTRY(viewerType) -JS_STATIC_PROP_ENTRY(viewerVariation) -JS_STATIC_PROP_ENTRY(viewerVersion) -END_JS_STATIC_PROP() - -BEGIN_JS_STATIC_METHOD(CJS_App) -JS_STATIC_METHOD_ENTRY(alert) -JS_STATIC_METHOD_ENTRY(beep) -JS_STATIC_METHOD_ENTRY(browseForDoc) -JS_STATIC_METHOD_ENTRY(clearInterval) -JS_STATIC_METHOD_ENTRY(clearTimeOut) -JS_STATIC_METHOD_ENTRY(execDialog) -JS_STATIC_METHOD_ENTRY(execMenuItem) -JS_STATIC_METHOD_ENTRY(findComponent) -JS_STATIC_METHOD_ENTRY(goBack) -JS_STATIC_METHOD_ENTRY(goForward) -JS_STATIC_METHOD_ENTRY(launchURL) -JS_STATIC_METHOD_ENTRY(mailMsg) -JS_STATIC_METHOD_ENTRY(newFDF) -JS_STATIC_METHOD_ENTRY(newDoc) -JS_STATIC_METHOD_ENTRY(openDoc) -JS_STATIC_METHOD_ENTRY(openFDF) -JS_STATIC_METHOD_ENTRY(popUpMenuEx) -JS_STATIC_METHOD_ENTRY(popUpMenu) -JS_STATIC_METHOD_ENTRY(response) -JS_STATIC_METHOD_ENTRY(setInterval) -JS_STATIC_METHOD_ENTRY(setTimeOut) -END_JS_STATIC_METHOD() +JSConstSpec CJS_App::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; + +JSPropertySpec CJS_App::PropertySpecs[] = { + {"activeDocs", get_activeDocs_static, set_activeDocs_static}, + {"calculate", get_calculate_static, set_calculate_static}, + {"formsVersion", get_formsVersion_static, set_formsVersion_static}, + {"fs", get_fs_static, set_fs_static}, + {"fullscreen", get_fullscreen_static, set_fullscreen_static}, + {"language", get_language_static, set_language_static}, + {"media", get_media_static, set_media_static}, + {"platform", get_platform_static, set_platform_static}, + {"runtimeHighlight", get_runtimeHighlight_static, + set_runtimeHighlight_static}, + {"viewerType", get_viewerType_static, set_viewerType_static}, + {"viewerVariation", get_viewerVariation_static, set_viewerVariation_static}, + {"viewerVersion", get_viewerVersion_static, set_viewerVersion_static}, + {0, 0, 0}}; + +JSMethodSpec CJS_App::MethodSpecs[] = {{"alert", alert_static}, + {"beep", beep_static}, + {"browseForDoc", browseForDoc_static}, + {"clearInterval", clearInterval_static}, + {"clearTimeOut", clearTimeOut_static}, + {"execDialog", execDialog_static}, + {"execMenuItem", execMenuItem_static}, + {"findComponent", findComponent_static}, + {"goBack", goBack_static}, + {"goForward", goForward_static}, + {"launchURL", launchURL_static}, + {"mailMsg", mailMsg_static}, + {"newFDF", newFDF_static}, + {"newDoc", newDoc_static}, + {"openDoc", openDoc_static}, + {"openFDF", openFDF_static}, + {"popUpMenuEx", popUpMenuEx_static}, + {"popUpMenu", popUpMenu_static}, + {"response", response_static}, + {"setInterval", setInterval_static}, + {"setTimeOut", setTimeOut_static}, + {0, 0}}; IMPLEMENT_JS_CLASS(CJS_App, app) @@ -211,23 +207,19 @@ app::app(CJS_Object* pJSObject) app::~app() { } -bool app::activeDocs(IJS_Context* cc, +bool app::activeDocs(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_Runtime* pRuntime = pContext->GetJSRuntime(); CJS_Document* pJSDocument = nullptr; v8::Local<v8::Object> pObj = pRuntime->GetThisObj(); - if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID) { + if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID) pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pObj)); - } CJS_Array aDocs; aDocs.SetElement(pRuntime, 0, CJS_Value(pRuntime, pJSDocument)); - if (aDocs.GetLength(pRuntime) > 0) vp << aDocs; else @@ -236,16 +228,14 @@ bool app::activeDocs(IJS_Context* cc, return true; } -bool app::calculate(IJS_Context* cc, +bool app::calculate(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { bool bVP; vp >> bVP; m_bCalculate = (bool)bVP; - - CJS_Context* pContext = (CJS_Context*)cc; - pContext->GetFormFillEnv()->GetInterForm()->EnableCalculate( + pRuntime->GetFormFillEnv()->GetInterForm()->EnableCalculate( (bool)m_bCalculate); } else { vp << (bool)m_bCalculate; @@ -253,7 +243,7 @@ bool app::calculate(IJS_Context* cc, return true; } -bool app::formsVersion(IJS_Context* cc, +bool app::formsVersion(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsGetting()) { @@ -264,7 +254,7 @@ bool app::formsVersion(IJS_Context* cc, return false; } -bool app::viewerType(IJS_Context* cc, +bool app::viewerType(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsGetting()) { @@ -275,7 +265,7 @@ bool app::viewerType(IJS_Context* cc, return false; } -bool app::viewerVariation(IJS_Context* cc, +bool app::viewerVariation(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsGetting()) { @@ -286,14 +276,13 @@ bool app::viewerVariation(IJS_Context* cc, return false; } -bool app::viewerVersion(IJS_Context* cc, +bool app::viewerVersion(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; #ifdef PDF_ENABLE_XFA - CJS_Context* pJSContext = static_cast<CJS_Context*>(cc); - CPDFXFA_Context* pXFAContext = pJSContext->GetFormFillEnv()->GetXFAContext(); + CPDFXFA_Context* pXFAContext = pRuntime->GetFormFillEnv()->GetXFAContext(); if (pXFAContext->GetDocType() == 1 || pXFAContext->GetDocType() == 2) { vp << JS_NUM_VIEWERVERSION_XFA; return true; @@ -303,12 +292,13 @@ bool app::viewerVersion(IJS_Context* cc, return true; } -bool app::platform(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool app::platform(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; #ifdef PDF_ENABLE_XFA - CPDFSDK_FormFillEnvironment* pFormFillEnv = - static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetFormFillEnv(); + CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); if (!pFormFillEnv) return false; CFX_WideString platfrom = pFormFillEnv->GetPlatform(); @@ -321,12 +311,13 @@ bool app::platform(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool app::language(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool app::language(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; #ifdef PDF_ENABLE_XFA - CPDFSDK_FormFillEnvironment* pFormFillEnv = - static_cast<CJS_Context*>(cc)->GetJSRuntime()->GetFormFillEnv(); + CPDFSDK_FormFillEnvironment* pFormFillEnv = pRuntime->GetFormFillEnv(); if (!pFormFillEnv) return false; CFX_WideString language = pFormFillEnv->GetLanguage(); @@ -343,7 +334,7 @@ bool app::language(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { // comment: need reader support // note: // CFDF_Document * CPDFSDK_FormFillEnvironment::NewFDF(); -bool app::newFDF(IJS_Context* cc, +bool app::newFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -356,18 +347,17 @@ bool app::newFDF(IJS_Context* cc, // CFDF_Document * CPDFSDK_FormFillEnvironment::OpenFDF(string strPath,bool // bUserConv); -bool app::openFDF(IJS_Context* cc, +bool app::openFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool app::alert(IJS_Context* cc, +bool app::alert(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); std::vector<CJS_Value> newParams = JS_ExpandKeywordParams( pRuntime, params, 4, L"cMsg", L"nIcon", L"nType", L"cTitle"); @@ -425,12 +415,11 @@ bool app::alert(IJS_Context* cc, return true; } -bool app::beep(IJS_Context* cc, +bool app::beep(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { if (params.size() == 1) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); pRuntime->GetFormFillEnv()->JS_appBeep(params[0].ToInt(pRuntime)); return true; } @@ -439,25 +428,25 @@ bool app::beep(IJS_Context* cc, return false; } -bool app::findComponent(IJS_Context* cc, +bool app::findComponent(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool app::popUpMenuEx(IJS_Context* cc, +bool app::popUpMenuEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool app::fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool app::fs(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return false; } -bool app::setInterval(IJS_Context* cc, +bool app::setInterval(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -466,7 +455,6 @@ bool app::setInterval(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString(pRuntime) : L""; if (script.IsEmpty()) { @@ -482,6 +470,9 @@ bool app::setInterval(IJS_Context* cc, v8::Local<v8::Object> pRetObj = pRuntime->NewFxDynamicObj(CJS_TimerObj::g_nObjDefnID); + if (pRetObj.IsEmpty()) + return false; + CJS_TimerObj* pJS_TimerObj = static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj)); TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject()); @@ -491,7 +482,7 @@ bool app::setInterval(IJS_Context* cc, return true; } -bool app::setTimeOut(IJS_Context* cc, +bool app::setTimeOut(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -500,7 +491,6 @@ bool app::setTimeOut(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CFX_WideString script = params[0].ToCFXWideString(pRuntime); if (script.IsEmpty()) { sError = JSGetStringFromID(IDS_STRING_JSAFNUMBER_KEYSTROKE); @@ -515,18 +505,18 @@ bool app::setTimeOut(IJS_Context* cc, v8::Local<v8::Object> pRetObj = pRuntime->NewFxDynamicObj(CJS_TimerObj::g_nObjDefnID); + if (pRetObj.IsEmpty()) + return false; CJS_TimerObj* pJS_TimerObj = static_cast<CJS_TimerObj*>(pRuntime->GetObjectPrivate(pRetObj)); - TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject()); pTimerObj->SetTimer(timerRef); - vRet = CJS_Value(pRuntime, pRetObj); return true; } -bool app::clearTimeOut(IJS_Context* cc, +bool app::clearTimeOut(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -535,11 +525,11 @@ bool app::clearTimeOut(IJS_Context* cc, return false; } - app::ClearTimerCommon(CJS_Runtime::FromContext(cc), params[0]); + app::ClearTimerCommon(pRuntime, params[0]); return true; } -bool app::clearInterval(IJS_Context* cc, +bool app::clearInterval(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -548,7 +538,7 @@ bool app::clearInterval(IJS_Context* cc, return false; } - app::ClearTimerCommon(CJS_Runtime::FromContext(cc), params[0]); + app::ClearTimerCommon(pRuntime, params[0]); return true; } @@ -571,7 +561,7 @@ void app::ClearTimerCommon(CJS_Runtime* pRuntime, const CJS_Value& param) { GlobalTimer::Cancel(pTimerObj->GetTimerID()); } -bool app::execMenuItem(IJS_Context* cc, +bool app::execMenuItem(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -590,15 +580,15 @@ void app::CancelProc(GlobalTimer* pTimer) { void app::RunJsScript(CJS_Runtime* pRuntime, const CFX_WideString& wsScript) { if (!pRuntime->IsBlocking()) { - IJS_Context* pContext = pRuntime->NewContext(); + IJS_EventContext* pContext = pRuntime->NewEventContext(); pContext->OnExternal_Exec(); CFX_WideString wtInfo; pContext->RunScript(wsScript, &wtInfo); - pRuntime->ReleaseContext(pContext); + pRuntime->ReleaseEventContext(pContext); } } -bool app::goBack(IJS_Context* cc, +bool app::goBack(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -606,7 +596,7 @@ bool app::goBack(IJS_Context* cc, return true; } -bool app::goForward(IJS_Context* cc, +bool app::goForward(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -614,11 +604,10 @@ bool app::goForward(IJS_Context* cc, return true; } -bool app::mailMsg(IJS_Context* cc, +bool app::mailMsg(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); std::vector<CJS_Value> newParams = JS_ExpandKeywordParams(pRuntime, params, 6, L"bUI", L"cTo", L"cCc", L"cBcc", L"cSubject", L"cMsg"); @@ -657,15 +646,14 @@ bool app::mailMsg(IJS_Context* cc, cMsg = newParams[5].ToCFXWideString(pRuntime); pRuntime->BeginBlock(); - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - pContext->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(), + pRuntime->GetFormFillEnv()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(), cMsg.c_str()); pRuntime->EndBlock(); return true; } -bool app::launchURL(IJS_Context* cc, +bool app::launchURL(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -673,7 +661,7 @@ bool app::launchURL(IJS_Context* cc, return true; } -bool app::runtimeHighlight(IJS_Context* cc, +bool app::runtimeHighlight(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (vp.IsSetting()) { @@ -684,20 +672,20 @@ bool app::runtimeHighlight(IJS_Context* cc, return true; } -bool app::fullscreen(IJS_Context* cc, +bool app::fullscreen(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return false; } -bool app::popUpMenu(IJS_Context* cc, +bool app::popUpMenu(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool app::browseForDoc(IJS_Context* cc, +bool app::browseForDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -723,25 +711,24 @@ CFX_WideString app::SysPathToPDFPath(const CFX_WideString& sOldPath) { return sRet; } -bool app::newDoc(IJS_Context* cc, +bool app::newDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool app::openDoc(IJS_Context* cc, +bool app::openDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return false; } -bool app::response(IJS_Context* cc, +bool app::response(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); std::vector<CJS_Value> newParams = JS_ExpandKeywordParams(pRuntime, params, 5, L"cQuestion", L"cTitle", L"cDefault", L"bPassword", L"cLabel"); @@ -772,8 +759,7 @@ bool app::response(IJS_Context* cc, std::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]); memset(pBuff.get(), 0, MAX_INPUT_BYTES + 2); - CJS_Context* pContext = static_cast<CJS_Context*>(cc); - int nLengthBytes = pContext->GetFormFillEnv()->JS_appResponse( + int nLengthBytes = pRuntime->GetFormFillEnv()->JS_appResponse( swQuestion.c_str(), swTitle.c_str(), swDefault.c_str(), swLabel.c_str(), bPassword, pBuff.get(), MAX_INPUT_BYTES); @@ -790,11 +776,13 @@ bool app::response(IJS_Context* cc, return true; } -bool app::media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool app::media(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { return false; } -bool app::execDialog(IJS_Context* cc, +bool app::execDialog(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { diff --git a/fpdfsdk/javascript/app.h b/fpdfsdk/javascript/app.h index e8c72417b..9e11b8241 100644 --- a/fpdfsdk/javascript/app.h +++ b/fpdfsdk/javascript/app.h @@ -41,106 +41,120 @@ class app : public CJS_EmbedObj { explicit app(CJS_Object* pJSObject); ~app() override; - bool activeDocs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool calculate(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool formsVersion(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool fs(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool fullscreen(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool language(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool media(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool platform(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool runtimeHighlight(IJS_Context* cc, + bool activeDocs(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool calculate(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool formsVersion(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool fs(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool fullscreen(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool language(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool media(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool platform(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool runtimeHighlight(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool viewerType(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool viewerVariation(IJS_Context* cc, + bool viewerType(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool viewerVariation(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool viewerVersion(IJS_Context* cc, + bool viewerVersion(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool alert(IJS_Context* cc, + bool alert(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool beep(IJS_Context* cc, + bool beep(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool browseForDoc(IJS_Context* cc, + bool browseForDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool clearInterval(IJS_Context* cc, + bool clearInterval(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool clearTimeOut(IJS_Context* cc, + bool clearTimeOut(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool execDialog(IJS_Context* cc, + bool execDialog(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool execMenuItem(IJS_Context* cc, + bool execMenuItem(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool findComponent(IJS_Context* cc, + bool findComponent(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool goBack(IJS_Context* cc, + bool goBack(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool goForward(IJS_Context* cc, + bool goForward(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool launchURL(IJS_Context* cc, + bool launchURL(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool mailMsg(IJS_Context* cc, + bool mailMsg(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool newFDF(IJS_Context* cc, + bool newFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool newDoc(IJS_Context* cc, + bool newDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool openDoc(IJS_Context* cc, + bool openDoc(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool openFDF(IJS_Context* cc, + bool openFDF(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool popUpMenuEx(IJS_Context* cc, + bool popUpMenuEx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool popUpMenu(IJS_Context* cc, + bool popUpMenu(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool response(IJS_Context* cc, + bool response(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool setInterval(IJS_Context* cc, + bool setInterval(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool setTimeOut(IJS_Context* cc, + bool setTimeOut(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); diff --git a/fpdfsdk/javascript/cjs_context.cpp b/fpdfsdk/javascript/cjs_context.cpp deleted file mode 100644 index e356bdd90..000000000 --- a/fpdfsdk/javascript/cjs_context.cpp +++ /dev/null @@ -1,272 +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 "fpdfsdk/javascript/cjs_context.h" - -#include "fpdfsdk/javascript/JS_EventHandler.h" -#include "fpdfsdk/javascript/cjs_runtime.h" -#include "fpdfsdk/javascript/resource.h" - -CJS_Context::CJS_Context(CJS_Runtime* pRuntime) - : m_pRuntime(pRuntime), - m_pEventHandler(new CJS_EventHandler(this)), - m_bBusy(false) {} - -CJS_Context::~CJS_Context() {} - -CPDFSDK_FormFillEnvironment* CJS_Context::GetFormFillEnv() { - return m_pRuntime->GetFormFillEnv(); -} - -bool CJS_Context::RunScript(const CFX_WideString& script, - CFX_WideString* info) { - v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate()); - v8::HandleScope handle_scope(m_pRuntime->GetIsolate()); - v8::Local<v8::Context> context = m_pRuntime->NewLocalContext(); - v8::Context::Scope context_scope(context); - - if (m_bBusy) { - *info = JSGetStringFromID(IDS_STRING_JSBUSY); - return false; - } - m_bBusy = true; - - ASSERT(m_pEventHandler->IsValid()); - CJS_Runtime::FieldEvent event(m_pEventHandler->TargetName(), - m_pEventHandler->EventType()); - if (!m_pRuntime->AddEventToSet(event)) { - *info = JSGetStringFromID(IDS_STRING_JSEVENT); - return false; - } - - CFX_WideString sErrorMessage; - int nRet = 0; - if (script.GetLength() > 0) { - nRet = m_pRuntime->ExecuteScript(script.c_str(), &sErrorMessage); - } - - if (nRet < 0) { - *info += sErrorMessage; - } else { - *info = JSGetStringFromID(IDS_STRING_RUN); - } - - m_pRuntime->RemoveEventFromSet(event); - m_pEventHandler->Destroy(); - m_bBusy = false; - - return nRet >= 0; -} - -void CJS_Context::OnApp_Init() { - m_pEventHandler->OnApp_Init(); -} - -void CJS_Context::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv, - const CFX_WideString& strTargetName) { - m_pEventHandler->OnDoc_Open(pFormFillEnv, strTargetName); -} - -void CJS_Context::OnDoc_WillPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnDoc_WillPrint(pFormFillEnv); -} - -void CJS_Context::OnDoc_DidPrint(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnDoc_DidPrint(pFormFillEnv); -} - -void CJS_Context::OnDoc_WillSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnDoc_WillSave(pFormFillEnv); -} - -void CJS_Context::OnDoc_DidSave(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnDoc_DidSave(pFormFillEnv); -} - -void CJS_Context::OnDoc_WillClose(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnDoc_WillClose(pFormFillEnv); -} - -void CJS_Context::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnPage_Open(pFormFillEnv); -} - -void CJS_Context::OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnPage_Close(pFormFillEnv); -} - -void CJS_Context::OnPage_InView(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnPage_InView(pFormFillEnv); -} - -void CJS_Context::OnPage_OutView(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnPage_OutView(pFormFillEnv); -} - -void CJS_Context::OnField_MouseDown(bool bModifier, - bool bShift, - CPDF_FormField* pTarget) { - m_pEventHandler->OnField_MouseDown(bModifier, bShift, pTarget); -} - -void CJS_Context::OnField_MouseEnter(bool bModifier, - bool bShift, - CPDF_FormField* pTarget) { - m_pEventHandler->OnField_MouseEnter(bModifier, bShift, pTarget); -} - -void CJS_Context::OnField_MouseExit(bool bModifier, - bool bShift, - CPDF_FormField* pTarget) { - m_pEventHandler->OnField_MouseExit(bModifier, bShift, pTarget); -} - -void CJS_Context::OnField_MouseUp(bool bModifier, - bool bShift, - CPDF_FormField* pTarget) { - m_pEventHandler->OnField_MouseUp(bModifier, bShift, pTarget); -} - -void CJS_Context::OnField_Focus(bool bModifier, - bool bShift, - CPDF_FormField* pTarget, - const CFX_WideString& Value) { - m_pEventHandler->OnField_Focus(bModifier, bShift, pTarget, Value); -} - -void CJS_Context::OnField_Blur(bool bModifier, - bool bShift, - CPDF_FormField* pTarget, - const CFX_WideString& Value) { - m_pEventHandler->OnField_Blur(bModifier, bShift, pTarget, Value); -} - -void CJS_Context::OnField_Calculate(CPDF_FormField* pSource, - CPDF_FormField* pTarget, - CFX_WideString& Value, - bool& bRc) { - m_pEventHandler->OnField_Calculate(pSource, pTarget, Value, bRc); -} - -void CJS_Context::OnField_Format(CPDF_FormField* pTarget, - CFX_WideString& Value, - bool bWillCommit) { - m_pEventHandler->OnField_Format(pTarget, Value, bWillCommit); -} - -void CJS_Context::OnField_Keystroke(CFX_WideString& strChange, - const CFX_WideString& strChangeEx, - bool bKeyDown, - bool bModifier, - int& nSelEnd, - int& nSelStart, - bool bShift, - CPDF_FormField* pTarget, - CFX_WideString& Value, - bool bWillCommit, - bool bFieldFull, - bool& bRc) { - m_pEventHandler->OnField_Keystroke( - strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift, - pTarget, Value, bWillCommit, bFieldFull, bRc); -} - -void CJS_Context::OnField_Validate(CFX_WideString& strChange, - const CFX_WideString& strChangeEx, - bool bKeyDown, - bool bModifier, - bool bShift, - CPDF_FormField* pTarget, - CFX_WideString& Value, - bool& bRc) { - m_pEventHandler->OnField_Validate(strChange, strChangeEx, bKeyDown, bModifier, - bShift, pTarget, Value, bRc); -} - -void CJS_Context::OnScreen_Focus(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_Focus(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_Blur(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_Blur(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_Open(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_Open(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_Close(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_Close(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_MouseDown(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_MouseDown(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_MouseUp(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_MouseUp(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_MouseEnter(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_MouseEnter(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_MouseExit(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_MouseExit(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_InView(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_InView(bModifier, bShift, pScreen); -} - -void CJS_Context::OnScreen_OutView(bool bModifier, - bool bShift, - CPDFSDK_Annot* pScreen) { - m_pEventHandler->OnScreen_OutView(bModifier, bShift, pScreen); -} - -void CJS_Context::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) { - m_pEventHandler->OnBookmark_MouseUp(pBookMark); -} - -void CJS_Context::OnLink_MouseUp(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnLink_MouseUp(pFormFillEnv); -} - -void CJS_Context::OnConsole_Exec() { - m_pEventHandler->OnConsole_Exec(); -} - -void CJS_Context::OnExternal_Exec() { - m_pEventHandler->OnExternal_Exec(); -} - -void CJS_Context::OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pEventHandler->OnBatchExec(pFormFillEnv); -} - -void CJS_Context::OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv, - const CFX_WideString& strTargetName) { - m_pEventHandler->OnMenu_Exec(pFormFillEnv, strTargetName); -} diff --git a/fpdfsdk/javascript/cjs_event_context.cpp b/fpdfsdk/javascript/cjs_event_context.cpp new file mode 100644 index 000000000..abfb6da36 --- /dev/null +++ b/fpdfsdk/javascript/cjs_event_context.cpp @@ -0,0 +1,280 @@ +// Copyright 2017 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 "fpdfsdk/javascript/cjs_event_context.h" + +#include "fpdfsdk/javascript/JS_EventHandler.h" +#include "fpdfsdk/javascript/cjs_runtime.h" +#include "fpdfsdk/javascript/resource.h" + +CJS_EventContext::CJS_EventContext(CJS_Runtime* pRuntime) + : m_pRuntime(pRuntime), + m_pEventHandler(new CJS_EventHandler(this)), + m_bBusy(false) { + ASSERT(pRuntime); +} + +CJS_EventContext::~CJS_EventContext() {} + +CPDFSDK_FormFillEnvironment* CJS_EventContext::GetFormFillEnv() { + return m_pRuntime->GetFormFillEnv(); +} + +bool CJS_EventContext::RunScript(const CFX_WideString& script, + CFX_WideString* info) { + v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate()); + v8::HandleScope handle_scope(m_pRuntime->GetIsolate()); + v8::Local<v8::Context> context = m_pRuntime->NewLocalContext(); + v8::Context::Scope context_scope(context); + + if (m_bBusy) { + *info = JSGetStringFromID(IDS_STRING_JSBUSY); + return false; + } + + CFX_AutoRestorer<bool> restorer(&m_bBusy); + m_bBusy = true; + + ASSERT(m_pEventHandler->IsValid()); + CJS_Runtime::FieldEvent event(m_pEventHandler->TargetName(), + m_pEventHandler->EventType()); + if (!m_pRuntime->AddEventToSet(event)) { + *info = JSGetStringFromID(IDS_STRING_JSEVENT); + return false; + } + + CFX_WideString sErrorMessage; + int nRet = 0; + if (script.GetLength() > 0) + nRet = m_pRuntime->ExecuteScript(script.c_str(), &sErrorMessage); + + if (nRet < 0) + *info += sErrorMessage; + else + *info = JSGetStringFromID(IDS_STRING_RUN); + + m_pRuntime->RemoveEventFromSet(event); + m_pEventHandler->Destroy(); + return nRet >= 0; +} + +void CJS_EventContext::OnApp_Init() { + m_pEventHandler->OnApp_Init(); +} + +void CJS_EventContext::OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv, + const CFX_WideString& strTargetName) { + m_pEventHandler->OnDoc_Open(pFormFillEnv, strTargetName); +} + +void CJS_EventContext::OnDoc_WillPrint( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnDoc_WillPrint(pFormFillEnv); +} + +void CJS_EventContext::OnDoc_DidPrint( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnDoc_DidPrint(pFormFillEnv); +} + +void CJS_EventContext::OnDoc_WillSave( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnDoc_WillSave(pFormFillEnv); +} + +void CJS_EventContext::OnDoc_DidSave( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnDoc_DidSave(pFormFillEnv); +} + +void CJS_EventContext::OnDoc_WillClose( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnDoc_WillClose(pFormFillEnv); +} + +void CJS_EventContext::OnPage_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnPage_Open(pFormFillEnv); +} + +void CJS_EventContext::OnPage_Close(CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnPage_Close(pFormFillEnv); +} + +void CJS_EventContext::OnPage_InView( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnPage_InView(pFormFillEnv); +} + +void CJS_EventContext::OnPage_OutView( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnPage_OutView(pFormFillEnv); +} + +void CJS_EventContext::OnField_MouseDown(bool bModifier, + bool bShift, + CPDF_FormField* pTarget) { + m_pEventHandler->OnField_MouseDown(bModifier, bShift, pTarget); +} + +void CJS_EventContext::OnField_MouseEnter(bool bModifier, + bool bShift, + CPDF_FormField* pTarget) { + m_pEventHandler->OnField_MouseEnter(bModifier, bShift, pTarget); +} + +void CJS_EventContext::OnField_MouseExit(bool bModifier, + bool bShift, + CPDF_FormField* pTarget) { + m_pEventHandler->OnField_MouseExit(bModifier, bShift, pTarget); +} + +void CJS_EventContext::OnField_MouseUp(bool bModifier, + bool bShift, + CPDF_FormField* pTarget) { + m_pEventHandler->OnField_MouseUp(bModifier, bShift, pTarget); +} + +void CJS_EventContext::OnField_Focus(bool bModifier, + bool bShift, + CPDF_FormField* pTarget, + const CFX_WideString& Value) { + m_pEventHandler->OnField_Focus(bModifier, bShift, pTarget, Value); +} + +void CJS_EventContext::OnField_Blur(bool bModifier, + bool bShift, + CPDF_FormField* pTarget, + const CFX_WideString& Value) { + m_pEventHandler->OnField_Blur(bModifier, bShift, pTarget, Value); +} + +void CJS_EventContext::OnField_Calculate(CPDF_FormField* pSource, + CPDF_FormField* pTarget, + CFX_WideString& Value, + bool& bRc) { + m_pEventHandler->OnField_Calculate(pSource, pTarget, Value, bRc); +} + +void CJS_EventContext::OnField_Format(CPDF_FormField* pTarget, + CFX_WideString& Value, + bool bWillCommit) { + m_pEventHandler->OnField_Format(pTarget, Value, bWillCommit); +} + +void CJS_EventContext::OnField_Keystroke(CFX_WideString& strChange, + const CFX_WideString& strChangeEx, + bool bKeyDown, + bool bModifier, + int& nSelEnd, + int& nSelStart, + bool bShift, + CPDF_FormField* pTarget, + CFX_WideString& Value, + bool bWillCommit, + bool bFieldFull, + bool& bRc) { + m_pEventHandler->OnField_Keystroke( + strChange, strChangeEx, bKeyDown, bModifier, nSelEnd, nSelStart, bShift, + pTarget, Value, bWillCommit, bFieldFull, bRc); +} + +void CJS_EventContext::OnField_Validate(CFX_WideString& strChange, + const CFX_WideString& strChangeEx, + bool bKeyDown, + bool bModifier, + bool bShift, + CPDF_FormField* pTarget, + CFX_WideString& Value, + bool& bRc) { + m_pEventHandler->OnField_Validate(strChange, strChangeEx, bKeyDown, bModifier, + bShift, pTarget, Value, bRc); +} + +void CJS_EventContext::OnScreen_Focus(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_Focus(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_Blur(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_Blur(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_Open(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_Open(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_Close(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_Close(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_MouseDown(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_MouseDown(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_MouseUp(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_MouseUp(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_MouseEnter(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_MouseEnter(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_MouseExit(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_MouseExit(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_InView(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_InView(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnScreen_OutView(bool bModifier, + bool bShift, + CPDFSDK_Annot* pScreen) { + m_pEventHandler->OnScreen_OutView(bModifier, bShift, pScreen); +} + +void CJS_EventContext::OnBookmark_MouseUp(CPDF_Bookmark* pBookMark) { + m_pEventHandler->OnBookmark_MouseUp(pBookMark); +} + +void CJS_EventContext::OnLink_MouseUp( + CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnLink_MouseUp(pFormFillEnv); +} + +void CJS_EventContext::OnConsole_Exec() { + m_pEventHandler->OnConsole_Exec(); +} + +void CJS_EventContext::OnExternal_Exec() { + m_pEventHandler->OnExternal_Exec(); +} + +void CJS_EventContext::OnBatchExec(CPDFSDK_FormFillEnvironment* pFormFillEnv) { + m_pEventHandler->OnBatchExec(pFormFillEnv); +} + +void CJS_EventContext::OnMenu_Exec(CPDFSDK_FormFillEnvironment* pFormFillEnv, + const CFX_WideString& strTargetName) { + m_pEventHandler->OnMenu_Exec(pFormFillEnv, strTargetName); +} diff --git a/fpdfsdk/javascript/cjs_context.h b/fpdfsdk/javascript/cjs_event_context.h index 95a63ada6..7bfe52816 100644 --- a/fpdfsdk/javascript/cjs_context.h +++ b/fpdfsdk/javascript/cjs_event_context.h @@ -1,28 +1,28 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyright 2017 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 FPDFSDK_JAVASCRIPT_CJS_CONTEXT_H_ -#define FPDFSDK_JAVASCRIPT_CJS_CONTEXT_H_ +#ifndef FPDFSDK_JAVASCRIPT_CJS_EVENT_CONTEXT_H_ +#define FPDFSDK_JAVASCRIPT_CJS_EVENT_CONTEXT_H_ #include <memory> #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" -#include "fpdfsdk/javascript/ijs_context.h" +#include "fpdfsdk/javascript/ijs_event_context.h" class CJS_EventHandler; class CJS_Runtime; class CPDFSDK_FormFillEnvironment; -class CJS_Context : public IJS_Context { +class CJS_EventContext : public IJS_EventContext { public: - explicit CJS_Context(CJS_Runtime* pRuntime); - ~CJS_Context() override; + explicit CJS_EventContext(CJS_Runtime* pRuntime); + ~CJS_EventContext() override; - // IJS_Context + // IJS_EventContext bool RunScript(const CFX_WideString& script, CFX_WideString* info) override; void OnApp_Init() override; void OnDoc_Open(CPDFSDK_FormFillEnvironment* pFormFillEnv, @@ -132,4 +132,4 @@ class CJS_Context : public IJS_Context { bool m_bBusy; }; -#endif // FPDFSDK_JAVASCRIPT_CJS_CONTEXT_H_ +#endif // FPDFSDK_JAVASCRIPT_CJS_EVENT_CONTEXT_H_ diff --git a/fpdfsdk/javascript/cjs_runtime.cpp b/fpdfsdk/javascript/cjs_runtime.cpp index f55a59cee..1ece0b6f7 100644 --- a/fpdfsdk/javascript/cjs_runtime.cpp +++ b/fpdfsdk/javascript/cjs_runtime.cpp @@ -21,7 +21,7 @@ #include "fpdfsdk/javascript/JS_Value.h" #include "fpdfsdk/javascript/PublicMethods.h" #include "fpdfsdk/javascript/app.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/color.h" #include "fpdfsdk/javascript/console.h" #include "fpdfsdk/javascript/event.h" @@ -51,12 +51,6 @@ IJS_Runtime* IJS_Runtime::Create(CPDFSDK_FormFillEnvironment* pFormFillEnv) { } // static -CJS_Runtime* CJS_Runtime::FromContext(const IJS_Context* cc) { - const CJS_Context* pContext = static_cast<const CJS_Context*>(cc); - return pContext->GetJSRuntime(); -} - -// static CJS_Runtime* CJS_Runtime::CurrentRuntimeFromIsolate(v8::Isolate* pIsolate) { return static_cast<CJS_Runtime*>( CFXJS_Engine::CurrentEngineFromIsolate(pIsolate)); @@ -89,10 +83,9 @@ CJS_Runtime::CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv) if (m_isolateManaged || FXJS_GlobalIsolateRefCount() == 0) DefineJSObjects(); - CJS_Context* pContext = (CJS_Context*)NewContext(); + IJS_EventContext* pContext = NewEventContext(); InitializeEngine(); - ReleaseContext(pContext); - + ReleaseEventContext(pContext); SetFormFillEnvToDocument(); } @@ -153,22 +146,23 @@ void CJS_Runtime::DefineJSObjects() { CJS_Annot::DefineJSObjects(this, FXJSOBJTYPE_DYNAMIC); } -IJS_Context* CJS_Runtime::NewContext() { - m_ContextArray.push_back(std::unique_ptr<CJS_Context>(new CJS_Context(this))); - return m_ContextArray.back().get(); +IJS_EventContext* CJS_Runtime::NewEventContext() { + m_EventContextArray.push_back( + std::unique_ptr<CJS_EventContext>(new CJS_EventContext(this))); + return m_EventContextArray.back().get(); } -void CJS_Runtime::ReleaseContext(IJS_Context* pContext) { - for (auto it = m_ContextArray.begin(); it != m_ContextArray.end(); ++it) { - if (it->get() == static_cast<CJS_Context*>(pContext)) { - m_ContextArray.erase(it); - return; - } - } +void CJS_Runtime::ReleaseEventContext(IJS_EventContext* pContext) { + auto it = std::find(m_EventContextArray.begin(), m_EventContextArray.end(), + pdfium::FakeUniquePtr<CJS_EventContext>( + static_cast<CJS_EventContext*>(pContext))); + if (it != m_EventContextArray.end()) + m_EventContextArray.erase(it); } -IJS_Context* CJS_Runtime::GetCurrentContext() { - return m_ContextArray.empty() ? nullptr : m_ContextArray.back().get(); +CJS_EventContext* CJS_Runtime::GetCurrentEventContext() const { + return m_EventContextArray.empty() ? nullptr + : m_EventContextArray.back().get(); } void CJS_Runtime::SetFormFillEnvToDocument() { @@ -193,11 +187,11 @@ void CJS_Runtime::SetFormFillEnvToDocument() { if (!pDocument) return; - pDocument->SetFormFillEnv(m_pFormFillEnv); + pDocument->SetFormFillEnv(m_pFormFillEnv.Get()); } CPDFSDK_FormFillEnvironment* CJS_Runtime::GetFormFillEnv() const { - return m_pFormFillEnv; + return m_pFormFillEnv.Get(); } int CJS_Runtime::ExecuteScript(const CFX_WideString& script, diff --git a/fpdfsdk/javascript/cjs_runtime.h b/fpdfsdk/javascript/cjs_runtime.h index 66f08772e..0bde51f9d 100644 --- a/fpdfsdk/javascript/cjs_runtime.h +++ b/fpdfsdk/javascript/cjs_runtime.h @@ -15,11 +15,12 @@ #include "core/fxcrt/cfx_observable.h" #include "core/fxcrt/fx_basic.h" +#include "fpdfsdk/cpdfsdk_formfillenvironment.h" #include "fpdfsdk/javascript/JS_EventHandler.h" #include "fpdfsdk/javascript/ijs_runtime.h" #include "fxjs/fxjs_v8.h" -class CJS_Context; +class CJS_EventContext; class CJS_Runtime : public IJS_Runtime, public CFXJS_Engine, @@ -27,22 +28,20 @@ class CJS_Runtime : public IJS_Runtime, public: using FieldEvent = std::pair<CFX_WideString, JS_EVENT_T>; - static CJS_Runtime* FromContext(const IJS_Context* cc); static CJS_Runtime* CurrentRuntimeFromIsolate(v8::Isolate* pIsolate); explicit CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv); ~CJS_Runtime() override; // IJS_Runtime - IJS_Context* NewContext() override; - void ReleaseContext(IJS_Context* pContext) override; - IJS_Context* GetCurrentContext() override; - + IJS_EventContext* NewEventContext() override; + void ReleaseEventContext(IJS_EventContext* pContext) override; CPDFSDK_FormFillEnvironment* GetFormFillEnv() const override; - int ExecuteScript(const CFX_WideString& script, CFX_WideString* info) override; + CJS_EventContext* GetCurrentEventContext() const; + // Returns true if the event isn't already found in the set. bool AddEventToSet(const FieldEvent& event); void RemoveEventFromSet(const FieldEvent& event); @@ -62,8 +61,8 @@ class CJS_Runtime : public IJS_Runtime, void DefineJSObjects(); void SetFormFillEnvToDocument(); - std::vector<std::unique_ptr<CJS_Context>> m_ContextArray; - CPDFSDK_FormFillEnvironment* const m_pFormFillEnv; + std::vector<std::unique_ptr<CJS_EventContext>> m_EventContextArray; + CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; bool m_bBlocking; bool m_isolateManaged; std::set<FieldEvent> m_FieldEventSet; diff --git a/fpdfsdk/javascript/color.cpp b/fpdfsdk/javascript/color.cpp index 882a9035e..b5ccbadab 100644 --- a/fpdfsdk/javascript/color.cpp +++ b/fpdfsdk/javascript/color.cpp @@ -12,31 +12,29 @@ #include "fpdfsdk/javascript/JS_EventHandler.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" -BEGIN_JS_STATIC_CONST(CJS_Color) -END_JS_STATIC_CONST() - -BEGIN_JS_STATIC_PROP(CJS_Color) -JS_STATIC_PROP_ENTRY(black) -JS_STATIC_PROP_ENTRY(blue) -JS_STATIC_PROP_ENTRY(cyan) -JS_STATIC_PROP_ENTRY(dkGray) -JS_STATIC_PROP_ENTRY(gray) -JS_STATIC_PROP_ENTRY(green) -JS_STATIC_PROP_ENTRY(ltGray) -JS_STATIC_PROP_ENTRY(magenta) -JS_STATIC_PROP_ENTRY(red) -JS_STATIC_PROP_ENTRY(transparent) -JS_STATIC_PROP_ENTRY(white) -JS_STATIC_PROP_ENTRY(yellow) -END_JS_STATIC_PROP() - -BEGIN_JS_STATIC_METHOD(CJS_Color) -JS_STATIC_METHOD_ENTRY(convert) -JS_STATIC_METHOD_ENTRY(equal) -END_JS_STATIC_METHOD() +JSConstSpec CJS_Color::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; + +JSPropertySpec CJS_Color::PropertySpecs[] = { + {"black", get_black_static, set_black_static}, + {"blue", get_blue_static, set_blue_static}, + {"cyan", get_cyan_static, set_cyan_static}, + {"dkGray", get_dkGray_static, set_dkGray_static}, + {"gray", get_gray_static, set_gray_static}, + {"green", get_green_static, set_green_static}, + {"ltGray", get_ltGray_static, set_ltGray_static}, + {"magenta", get_magenta_static, set_magenta_static}, + {"red", get_red_static, set_red_static}, + {"transparent", get_transparent_static, set_transparent_static}, + {"white", get_white_static, set_white_static}, + {"yellow", get_yellow_static, set_yellow_static}, + {0, 0, 0}}; + +JSMethodSpec CJS_Color::MethodSpecs[] = {{"convert", convert_static}, + {"equal", equal_static}, + {0, 0}}; IMPLEMENT_JS_CLASS(CJS_Color, color) @@ -133,36 +131,95 @@ void color::ConvertArrayToPWLColor(CJS_Runtime* pRuntime, } } -#define JS_IMPLEMENT_COLORPROP(prop, var) \ - bool color::prop(IJS_Context* cc, CJS_PropValue& vp, \ - CFX_WideString& sError) { \ - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); \ - CJS_Array array; \ - if (vp.IsGetting()) { \ - ConvertPWLColorToArray(pRuntime, var, &array); \ - vp << array; \ - } else { \ - if (!vp.GetJSValue()->ConvertToArray(pRuntime, array)) \ - return false; \ - ConvertArrayToPWLColor(pRuntime, array, &var); \ - } \ - return true; \ +bool color::transparent(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crTransparent); +} + +bool color::black(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crBlack); +} + +bool color::white(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crWhite); +} + +bool color::red(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crRed); +} + +bool color::green(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crGreen); +} + +bool color::blue(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crBlue); +} + +bool color::cyan(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crCyan); +} + +bool color::magenta(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crMagenta); +} + +bool color::yellow(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crYellow); +} + +bool color::dkGray(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crDKGray); +} + +bool color::gray(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crGray); +} + +bool color::ltGray(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + return PropertyHelper(pRuntime, vp, &m_crLTGray); +} + +bool color::PropertyHelper(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CPWL_Color* var) { + CJS_Array array; + if (vp.IsGetting()) { + ConvertPWLColorToArray(pRuntime, *var, &array); + vp << array; + return true; } + if (!vp.GetJSValue()->ConvertToArray(pRuntime, array)) + return false; + + ConvertArrayToPWLColor(pRuntime, array, var); + return true; +} -JS_IMPLEMENT_COLORPROP(transparent, m_crTransparent) -JS_IMPLEMENT_COLORPROP(black, m_crBlack) -JS_IMPLEMENT_COLORPROP(white, m_crWhite) -JS_IMPLEMENT_COLORPROP(red, m_crRed) -JS_IMPLEMENT_COLORPROP(green, m_crGreen) -JS_IMPLEMENT_COLORPROP(blue, m_crBlue) -JS_IMPLEMENT_COLORPROP(cyan, m_crCyan) -JS_IMPLEMENT_COLORPROP(magenta, m_crMagenta) -JS_IMPLEMENT_COLORPROP(yellow, m_crYellow) -JS_IMPLEMENT_COLORPROP(dkGray, m_crDKGray) -JS_IMPLEMENT_COLORPROP(gray, m_crGray) -JS_IMPLEMENT_COLORPROP(ltGray, m_crLTGray) - -bool color::convert(IJS_Context* cc, +bool color::convert(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -170,7 +227,6 @@ bool color::convert(IJS_Context* cc, if (iSize < 2) return false; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array aSource; if (!params[0].ConvertToArray(pRuntime, aSource)) return false; @@ -192,22 +248,20 @@ bool color::convert(IJS_Context* cc, } CJS_Array aDest; - CPWL_Color crDest = crSource; - crDest.ConvertColorType(nColorType); + CPWL_Color crDest = crSource.ConvertColorType(nColorType); ConvertPWLColorToArray(pRuntime, crDest, &aDest); vRet = CJS_Value(pRuntime, aDest); return true; } -bool color::equal(IJS_Context* cc, +bool color::equal(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { if (params.size() < 2) return false; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Array array1; CJS_Array array2; if (!params[0].ConvertToArray(pRuntime, array1)) @@ -219,7 +273,7 @@ bool color::equal(IJS_Context* cc, CPWL_Color color2; ConvertArrayToPWLColor(pRuntime, array1, &color1); ConvertArrayToPWLColor(pRuntime, array2, &color2); - color1.ConvertColorType(color2.nColorType); + color1 = color1.ConvertColorType(color2.nColorType); vRet = CJS_Value(pRuntime, color1 == color2); return true; } diff --git a/fpdfsdk/javascript/color.h b/fpdfsdk/javascript/color.h index 9ea4d6335..8d6187a17 100644 --- a/fpdfsdk/javascript/color.h +++ b/fpdfsdk/javascript/color.h @@ -17,24 +17,28 @@ class color : public CJS_EmbedObj { explicit color(CJS_Object* pJSObject); ~color() override; - bool black(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool blue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool cyan(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool dkGray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool gray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool green(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool ltGray(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool magenta(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool red(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool transparent(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool white(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool yellow(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); + bool black(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool blue(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool cyan(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool dkGray(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool gray(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool green(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool ltGray(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool magenta(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool red(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool transparent(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool white(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool yellow(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); - bool convert(IJS_Context* cc, + bool convert(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool equal(IJS_Context* cc, + bool equal(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); @@ -47,6 +51,10 @@ class color : public CJS_EmbedObj { CPWL_Color* color); private: + bool PropertyHelper(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CPWL_Color* val); + CPWL_Color m_crTransparent; CPWL_Color m_crBlack; CPWL_Color m_crWhite; diff --git a/fpdfsdk/javascript/console.cpp b/fpdfsdk/javascript/console.cpp index 0a8c1e05b..e9d130820 100644 --- a/fpdfsdk/javascript/console.cpp +++ b/fpdfsdk/javascript/console.cpp @@ -12,20 +12,17 @@ #include "fpdfsdk/javascript/JS_EventHandler.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" -BEGIN_JS_STATIC_CONST(CJS_Console) -END_JS_STATIC_CONST() +JSConstSpec CJS_Console::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_Console) -END_JS_STATIC_PROP() +JSPropertySpec CJS_Console::PropertySpecs[] = {{0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_Console) -JS_STATIC_METHOD_ENTRY(clear) -JS_STATIC_METHOD_ENTRY(hide) -JS_STATIC_METHOD_ENTRY(println) -JS_STATIC_METHOD_ENTRY(show) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_Console::MethodSpecs[] = {{"clear", clear_static}, + {"hide", hide_static}, + {"println", println_static}, + {"show", show_static}, + {0, 0}}; IMPLEMENT_JS_CLASS(CJS_Console, console) @@ -33,21 +30,21 @@ console::console(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {} console::~console() {} -bool console::clear(IJS_Context* cc, +bool console::clear(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool console::hide(IJS_Context* cc, +bool console::hide(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { return true; } -bool console::println(IJS_Context* cc, +bool console::println(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -57,7 +54,7 @@ bool console::println(IJS_Context* cc, return true; } -bool console::show(IJS_Context* cc, +bool console::show(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { diff --git a/fpdfsdk/javascript/console.h b/fpdfsdk/javascript/console.h index 069a81d02..a7e4d8ed9 100644 --- a/fpdfsdk/javascript/console.h +++ b/fpdfsdk/javascript/console.h @@ -17,19 +17,19 @@ class console : public CJS_EmbedObj { ~console() override; public: - bool clear(IJS_Context* cc, + bool clear(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool hide(IJS_Context* cc, + bool hide(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool println(IJS_Context* cc, + bool println(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool show(IJS_Context* cc, + bool show(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); diff --git a/fpdfsdk/javascript/event.cpp b/fpdfsdk/javascript/event.cpp index b4fb95177..2b00cbc10 100644 --- a/fpdfsdk/javascript/event.cpp +++ b/fpdfsdk/javascript/event.cpp @@ -11,36 +11,34 @@ #include "fpdfsdk/javascript/JS_EventHandler.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" - -BEGIN_JS_STATIC_CONST(CJS_Event) -END_JS_STATIC_CONST() - -BEGIN_JS_STATIC_PROP(CJS_Event) -JS_STATIC_PROP_ENTRY(change) -JS_STATIC_PROP_ENTRY(changeEx) -JS_STATIC_PROP_ENTRY(commitKey) -JS_STATIC_PROP_ENTRY(fieldFull) -JS_STATIC_PROP_ENTRY(keyDown) -JS_STATIC_PROP_ENTRY(modifier) -JS_STATIC_PROP_ENTRY(name) -JS_STATIC_PROP_ENTRY(rc) -JS_STATIC_PROP_ENTRY(richChange) -JS_STATIC_PROP_ENTRY(richChangeEx) -JS_STATIC_PROP_ENTRY(richValue) -JS_STATIC_PROP_ENTRY(selEnd) -JS_STATIC_PROP_ENTRY(selStart) -JS_STATIC_PROP_ENTRY(shift) -JS_STATIC_PROP_ENTRY(source) -JS_STATIC_PROP_ENTRY(target) -JS_STATIC_PROP_ENTRY(targetName) -JS_STATIC_PROP_ENTRY(type) -JS_STATIC_PROP_ENTRY(value) -JS_STATIC_PROP_ENTRY(willCommit) -END_JS_STATIC_PROP() - -BEGIN_JS_STATIC_METHOD(CJS_Event) -END_JS_STATIC_METHOD() +#include "fpdfsdk/javascript/cjs_event_context.h" + +JSConstSpec CJS_Event::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; + +JSPropertySpec CJS_Event::PropertySpecs[] = { + {"change", get_change_static, set_change_static}, + {"changeEx", get_changeEx_static, set_changeEx_static}, + {"commitKey", get_commitKey_static, set_commitKey_static}, + {"fieldFull", get_fieldFull_static, set_fieldFull_static}, + {"keyDown", get_keyDown_static, set_keyDown_static}, + {"modifier", get_modifier_static, set_modifier_static}, + {"name", get_name_static, set_name_static}, + {"rc", get_rc_static, set_rc_static}, + {"richChange", get_richChange_static, set_richChange_static}, + {"richChangeEx", get_richChangeEx_static, set_richChangeEx_static}, + {"richValue", get_richValue_static, set_richValue_static}, + {"selEnd", get_selEnd_static, set_selEnd_static}, + {"selStart", get_selStart_static, set_selStart_static}, + {"shift", get_shift_static, set_shift_static}, + {"source", get_source_static, set_source_static}, + {"target", get_target_static, set_target_static}, + {"targetName", get_targetName_static, set_targetName_static}, + {"type", get_type_static, set_type_static}, + {"value", get_value_static, set_value_static}, + {"willCommit", get_willCommit_static, set_willCommit_static}, + {0, 0, 0}}; + +JSMethodSpec CJS_Event::MethodSpecs[] = {{0, 0}}; IMPLEMENT_JS_CLASS(CJS_Event, event) @@ -48,260 +46,264 @@ event::event(CJS_Object* pJsObject) : CJS_EmbedObj(pJsObject) {} event::~event() {} -bool event::change(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); +bool event::change(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); CFX_WideString& wChange = pEvent->Change(); if (vp.IsSetting()) { if (vp.GetJSValue()->GetType() == CJS_Value::VT_string) vp >> wChange; - } else { - vp << wChange; + return true; } + vp << wChange; return true; } -bool event::changeEx(IJS_Context* cc, +bool event::changeEx(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->ChangeEx(); return true; } -bool event::commitKey(IJS_Context* cc, +bool event::commitKey(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->CommitKey(); return true; } -bool event::fieldFull(IJS_Context* cc, +bool event::fieldFull(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); if (!vp.IsGetting() && wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) return false; - if (pEvent->FieldFull()) - vp << true; - else - vp << false; + vp << pEvent->FieldFull(); return true; } -bool event::keyDown(IJS_Context* cc, +bool event::keyDown(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); - if (pEvent->KeyDown()) - vp << true; - else - vp << false; + vp << pEvent->KeyDown(); return true; } -bool event::modifier(IJS_Context* cc, +bool event::modifier(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); - if (pEvent->Modifier()) - vp << true; - else - vp << false; + vp << pEvent->Modifier(); return true; } -bool event::name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool event::name(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->Name(); return true; } -bool event::rc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); +bool event::rc(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); bool& bRc = pEvent->Rc(); - if (vp.IsSetting()) { + if (vp.IsSetting()) vp >> bRc; - } else { + else vp << bRc; - } + return true; } -bool event::richChange(IJS_Context* cc, +bool event::richChange(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool event::richChangeEx(IJS_Context* cc, +bool event::richChangeEx(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool event::richValue(IJS_Context* cc, +bool event::richValue(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { return true; } -bool event::selEnd(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); +bool event::selEnd(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); - if (wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) { + if (wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) return true; - } int& iSelEnd = pEvent->SelEnd(); - if (vp.IsSetting()) { + if (vp.IsSetting()) vp >> iSelEnd; - } else { + else vp << iSelEnd; - } + return true; } -bool event::selStart(IJS_Context* cc, +bool event::selStart(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); - if (wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) { + if (wcscmp((const wchar_t*)pEvent->Name(), L"Keystroke") != 0) return true; - } + int& iSelStart = pEvent->SelStart(); - if (vp.IsSetting()) { + if (vp.IsSetting()) vp >> iSelStart; - } else { + else vp << iSelStart; - } + return true; } -bool event::shift(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool event::shift(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); - if (pEvent->Shift()) - vp << true; - else - vp << false; + vp << pEvent->Shift(); return true; } -bool event::source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool event::source(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->Source()->GetJSObject(); return true; } -bool event::target(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool event::target(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->Target_Field()->GetJSObject(); return true; } -bool event::targetName(IJS_Context* cc, +bool event::targetName(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->TargetName(); return true; } -bool event::type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { +bool event::type(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); vp << pEvent->Type(); return true; } -bool event::value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); +bool event::value(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError) { + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); if (wcscmp((const wchar_t*)pEvent->Type(), L"Field") != 0) return false; + if (!pEvent->m_pValue) return false; + CFX_WideString& val = pEvent->Value(); - if (vp.IsSetting()) { + if (vp.IsSetting()) vp >> val; - } else { + else vp << val; - } + return true; } -bool event::willCommit(IJS_Context* cc, +bool event::willCommit(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError) { if (!vp.IsGetting()) return false; - CJS_Context* pContext = (CJS_Context*)cc; - CJS_EventHandler* pEvent = pContext->GetEventHandler(); + CJS_EventHandler* pEvent = + pRuntime->GetCurrentEventContext()->GetEventHandler(); - if (pEvent->WillCommit()) - vp << true; - else - vp << false; + vp << pEvent->WillCommit(); return true; } diff --git a/fpdfsdk/javascript/event.h b/fpdfsdk/javascript/event.h index 67194944d..2be8a0adb 100644 --- a/fpdfsdk/javascript/event.h +++ b/fpdfsdk/javascript/event.h @@ -15,26 +15,48 @@ class event : public CJS_EmbedObj { ~event() override; public: - bool change(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool changeEx(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool commitKey(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool fieldFull(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool keyDown(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool modifier(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool name(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool rc(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool richChange(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool richChangeEx(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool richValue(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool selEnd(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool selStart(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool shift(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool source(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool target(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool targetName(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool type(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool value(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); - bool willCommit(IJS_Context* cc, CJS_PropValue& vp, CFX_WideString& sError); + bool change(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool changeEx(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool commitKey(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool fieldFull(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool keyDown(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool modifier(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool name(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool rc(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool richChange(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool richChangeEx(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool richValue(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool selEnd(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool selStart(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool shift(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool source(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool target(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool targetName(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); + bool type(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool value(CJS_Runtime* pRuntime, CJS_PropValue& vp, CFX_WideString& sError); + bool willCommit(CJS_Runtime* pRuntime, + CJS_PropValue& vp, + CFX_WideString& sError); }; class CJS_Event : public CJS_Object { diff --git a/fpdfsdk/javascript/global.cpp b/fpdfsdk/javascript/global.cpp index aca86979a..a450606b1 100644 --- a/fpdfsdk/javascript/global.cpp +++ b/fpdfsdk/javascript/global.cpp @@ -14,18 +14,16 @@ #include "fpdfsdk/javascript/JS_GlobalData.h" #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/resource.h" -BEGIN_JS_STATIC_CONST(CJS_Global) -END_JS_STATIC_CONST() +JSConstSpec CJS_Global::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_Global) -END_JS_STATIC_PROP() +JSPropertySpec CJS_Global::PropertySpecs[] = {{0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_Global) -JS_STATIC_METHOD_ENTRY(setPersistent) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_Global::MethodSpecs[] = { + {"setPersistent", setPersistent_static}, + {0, 0}}; IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, JSGlobalAlternate, global); @@ -57,7 +55,7 @@ JSGlobalAlternate::~JSGlobalAlternate() { } void JSGlobalAlternate::Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv) { - m_pFormFillEnv = pFormFillEnv; + m_pFormFillEnv.Reset(pFormFillEnv); m_pGlobalData = CJS_GlobalData::GetRetainedInstance(pFormFillEnv); UpdateGlobalPersistentVariables(); } @@ -66,7 +64,7 @@ bool JSGlobalAlternate::QueryProperty(const FX_WCHAR* propname) { return CFX_WideString(propname) != L"setPersistent"; } -bool JSGlobalAlternate::DelProperty(IJS_Context* cc, +bool JSGlobalAlternate::DelProperty(CJS_Runtime* pRuntime, const FX_WCHAR* propname, CFX_WideString& sError) { auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname)); @@ -77,11 +75,10 @@ bool JSGlobalAlternate::DelProperty(IJS_Context* cc, return true; } -bool JSGlobalAlternate::DoProperty(IJS_Context* cc, +bool JSGlobalAlternate::DoProperty(CJS_Runtime* pRuntime, const FX_WCHAR* propname, CJS_PropValue& vp, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); if (vp.IsSetting()) { CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname); switch (vp.GetJSValue()->GetType()) { @@ -114,7 +111,7 @@ bool JSGlobalAlternate::DoProperty(IJS_Context* cc, false, "", v8::Local<v8::Object>(), false); } case CJS_Value::VT_undefined: { - DelProperty(cc, propname, sError); + DelProperty(pRuntime, propname, sError); return true; } default: @@ -157,7 +154,7 @@ bool JSGlobalAlternate::DoProperty(IJS_Context* cc, return false; } -bool JSGlobalAlternate::setPersistent(IJS_Context* cc, +bool JSGlobalAlternate::setPersistent(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -166,7 +163,6 @@ bool JSGlobalAlternate::setPersistent(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); auto it = m_mapGlobal.find(params[0].ToCFXByteString(pRuntime)); if (it != m_mapGlobal.end()) { JSGlobalData* pData = it->second; @@ -210,7 +206,7 @@ void JSGlobalAlternate::UpdateGlobalPersistentVariables() { pData->bPersistent == 1); pRuntime->PutObjectProperty( m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(), - pRuntime->NewString(pData->data.sData.UTF8Decode())); + pRuntime->NewString(pData->data.sData.UTF8Decode().AsStringC())); break; case JS_GlobalDataType::OBJECT: { v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(-1); @@ -232,7 +228,8 @@ void JSGlobalAlternate::UpdateGlobalPersistentVariables() { } } -void JSGlobalAlternate::CommitGlobalPersisitentVariables(IJS_Context* cc) { +void JSGlobalAlternate::CommitGlobalPersisitentVariables( + CJS_Runtime* pRuntime) { for (auto it = m_mapGlobal.begin(); it != m_mapGlobal.end(); ++it) { CFX_ByteString name = it->first; JSGlobalData* pData = it->second; @@ -256,7 +253,7 @@ void JSGlobalAlternate::CommitGlobalPersisitentVariables(IJS_Context* cc) { CJS_GlobalVariableArray array; v8::Local<v8::Object> obj = v8::Local<v8::Object>::New( GetJSObject()->GetIsolate(), pData->pData); - ObjectToArray(cc, obj, array); + ObjectToArray(pRuntime, obj, array); m_pGlobalData->SetGlobalVariableObject(name, array); m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent); } break; @@ -269,10 +266,9 @@ void JSGlobalAlternate::CommitGlobalPersisitentVariables(IJS_Context* cc) { } } -void JSGlobalAlternate::ObjectToArray(IJS_Context* cc, +void JSGlobalAlternate::ObjectToArray(CJS_Runtime* pRuntime, v8::Local<v8::Object> pObj, CJS_GlobalVariableArray& array) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); std::vector<CFX_WideString> pKeyList = pRuntime->GetObjectPropertyNames(pObj); for (const auto& ws : pKeyList) { CFX_ByteString sKey = ws.UTF8Encode(); @@ -305,7 +301,7 @@ void JSGlobalAlternate::ObjectToArray(IJS_Context* cc, CJS_KeyValue* pObjElement = new CJS_KeyValue; pObjElement->nType = JS_GlobalDataType::OBJECT; pObjElement->sKey = sKey; - ObjectToArray(cc, pRuntime->ToObject(v), pObjElement->objData); + ObjectToArray(pRuntime, pRuntime->ToObject(v), pObjElement->objData); array.Add(pObjElement); } break; case CJS_Value::VT_null: { @@ -339,7 +335,7 @@ void JSGlobalAlternate::PutObjectProperty(v8::Local<v8::Object> pObj, case JS_GlobalDataType::STRING: pRuntime->PutObjectProperty( pObj, pObjData->sKey.UTF8Decode(), - pRuntime->NewString(pObjData->sData.UTF8Decode())); + pRuntime->NewString(pObjData->sData.UTF8Decode().AsStringC())); break; case JS_GlobalDataType::OBJECT: { v8::Local<v8::Object> pNewObj = pRuntime->NewFxDynamicObj(-1); diff --git a/fpdfsdk/javascript/global.h b/fpdfsdk/javascript/global.h index 9a6568bc2..e313929be 100644 --- a/fpdfsdk/javascript/global.h +++ b/fpdfsdk/javascript/global.h @@ -35,23 +35,23 @@ class JSGlobalAlternate : public CJS_EmbedObj { explicit JSGlobalAlternate(CJS_Object* pJSObject); ~JSGlobalAlternate() override; - bool setPersistent(IJS_Context* cc, + bool setPersistent(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); bool QueryProperty(const FX_WCHAR* propname); - bool DoProperty(IJS_Context* cc, + bool DoProperty(CJS_Runtime* pRuntime, const FX_WCHAR* propname, CJS_PropValue& vp, CFX_WideString& sError); - bool DelProperty(IJS_Context* cc, + bool DelProperty(CJS_Runtime* pRuntime, const FX_WCHAR* propname, CFX_WideString& sError); void Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv); private: void UpdateGlobalPersistentVariables(); - void CommitGlobalPersisitentVariables(IJS_Context* cc); + void CommitGlobalPersisitentVariables(CJS_Runtime* pRuntime); void DestroyGlobalPersisitentVariables(); bool SetGlobalVariables(const CFX_ByteString& propname, JS_GlobalDataType nType, @@ -60,7 +60,7 @@ class JSGlobalAlternate : public CJS_EmbedObj { const CFX_ByteString& sData, v8::Local<v8::Object> pData, bool bDefaultPersistent); - void ObjectToArray(IJS_Context* cc, + void ObjectToArray(CJS_Runtime* pRuntime, v8::Local<v8::Object> pObj, CJS_GlobalVariableArray& array); void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData); @@ -68,7 +68,7 @@ class JSGlobalAlternate : public CJS_EmbedObj { std::map<CFX_ByteString, JSGlobalData*> m_mapGlobal; CFX_WideString m_sFilePath; CJS_GlobalData* m_pGlobalData; - CPDFSDK_FormFillEnvironment* m_pFormFillEnv; + CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv; }; class CJS_Global : public CJS_Object { diff --git a/fpdfsdk/javascript/ijs_context.h b/fpdfsdk/javascript/ijs_event_context.h index 2d2248f53..8428072cd 100644 --- a/fpdfsdk/javascript/ijs_context.h +++ b/fpdfsdk/javascript/ijs_event_context.h @@ -4,8 +4,8 @@ // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com -#ifndef FPDFSDK_JAVASCRIPT_IJS_CONTEXT_H_ -#define FPDFSDK_JAVASCRIPT_IJS_CONTEXT_H_ +#ifndef FPDFSDK_JAVASCRIPT_IJS_EVENT_CONTEXT_H_ +#define FPDFSDK_JAVASCRIPT_IJS_EVENT_CONTEXT_H_ #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" @@ -15,8 +15,10 @@ class CPDF_FormField; class CPDFSDK_Annot; class CPDFSDK_FormFillEnvironment; -// Records the details of an event and triggers JS execution for it. -class IJS_Context { +// Records the details of an event and triggers JS execution for it. There +// can be more than one of these at any given time, as JS callbacks to C++ +// may trigger new events on top of one another. +class IJS_EventContext { public: virtual bool RunScript(const CFX_WideString& script, CFX_WideString* info) = 0; @@ -126,7 +128,7 @@ class IJS_Context { virtual void OnExternal_Exec() = 0; protected: - virtual ~IJS_Context() {} + virtual ~IJS_EventContext() {} }; -#endif // FPDFSDK_JAVASCRIPT_IJS_CONTEXT_H_ +#endif // FPDFSDK_JAVASCRIPT_IJS_EVENT_CONTEXT_H_ diff --git a/fpdfsdk/javascript/ijs_runtime.h b/fpdfsdk/javascript/ijs_runtime.h index 027c500ec..babc41842 100644 --- a/fpdfsdk/javascript/ijs_runtime.h +++ b/fpdfsdk/javascript/ijs_runtime.h @@ -15,7 +15,7 @@ #endif // PDF_ENABLE_XFA class CPDFSDK_FormFillEnvironment; -class IJS_Context; +class IJS_EventContext; // Owns the FJXS objects needed to actually execute JS. class IJS_Runtime { @@ -25,12 +25,9 @@ class IJS_Runtime { static IJS_Runtime* Create(CPDFSDK_FormFillEnvironment* pFormFillEnv); virtual ~IJS_Runtime() {} - virtual IJS_Context* NewContext() = 0; - virtual void ReleaseContext(IJS_Context* pContext) = 0; - virtual IJS_Context* GetCurrentContext() = 0; - + virtual IJS_EventContext* NewEventContext() = 0; + virtual void ReleaseEventContext(IJS_EventContext* pContext) = 0; virtual CPDFSDK_FormFillEnvironment* GetFormFillEnv() const = 0; - virtual int ExecuteScript(const CFX_WideString& script, CFX_WideString* info) = 0; diff --git a/fpdfsdk/javascript/report.cpp b/fpdfsdk/javascript/report.cpp index ba6e97d87..c9c986d19 100644 --- a/fpdfsdk/javascript/report.cpp +++ b/fpdfsdk/javascript/report.cpp @@ -12,16 +12,13 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" -BEGIN_JS_STATIC_CONST(CJS_Report) -END_JS_STATIC_CONST() +JSConstSpec CJS_Report::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_Report) -END_JS_STATIC_PROP() +JSPropertySpec CJS_Report::PropertySpecs[] = {{0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_Report) -JS_STATIC_METHOD_ENTRY(save) -JS_STATIC_METHOD_ENTRY(writeText) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_Report::MethodSpecs[] = {{"save", save_static}, + {"writeText", writeText_static}, + {0, 0}}; IMPLEMENT_JS_CLASS(CJS_Report, Report) @@ -29,7 +26,7 @@ Report::Report(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {} Report::~Report() {} -bool Report::writeText(IJS_Context* cc, +bool Report::writeText(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -37,7 +34,7 @@ bool Report::writeText(IJS_Context* cc, return true; } -bool Report::save(IJS_Context* cc, +bool Report::save(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { diff --git a/fpdfsdk/javascript/report.h b/fpdfsdk/javascript/report.h index fef236943..c66db80fd 100644 --- a/fpdfsdk/javascript/report.h +++ b/fpdfsdk/javascript/report.h @@ -17,11 +17,11 @@ class Report : public CJS_EmbedObj { ~Report() override; public: - bool save(IJS_Context* cc, + bool save(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool writeText(IJS_Context* cc, + bool writeText(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); diff --git a/fpdfsdk/javascript/resource.h b/fpdfsdk/javascript/resource.h index 663cf3b04..af7788ff7 100644 --- a/fpdfsdk/javascript/resource.h +++ b/fpdfsdk/javascript/resource.h @@ -9,7 +9,7 @@ #include "core/fxcrt/fx_string.h" -class CJS_Context; +class CJS_EventContext; #define IDS_STRING_JSALERT 25613 #define IDS_STRING_JSPARAMERROR 25614 diff --git a/fpdfsdk/javascript/util.cpp b/fpdfsdk/javascript/util.cpp index 3967ceb0c..3221cfb0c 100644 --- a/fpdfsdk/javascript/util.cpp +++ b/fpdfsdk/javascript/util.cpp @@ -18,7 +18,7 @@ #include "fpdfsdk/javascript/JS_Object.h" #include "fpdfsdk/javascript/JS_Value.h" #include "fpdfsdk/javascript/PublicMethods.h" -#include "fpdfsdk/javascript/cjs_context.h" +#include "fpdfsdk/javascript/cjs_event_context.h" #include "fpdfsdk/javascript/cjs_runtime.h" #include "fpdfsdk/javascript/resource.h" @@ -26,19 +26,14 @@ #include <ctype.h> #endif -BEGIN_JS_STATIC_CONST(CJS_Util) -END_JS_STATIC_CONST() +JSConstSpec CJS_Util::ConstSpecs[] = {{0, JSConstSpec::Number, 0, 0}}; -BEGIN_JS_STATIC_PROP(CJS_Util) -END_JS_STATIC_PROP() +JSPropertySpec CJS_Util::PropertySpecs[] = {{0, 0, 0}}; -BEGIN_JS_STATIC_METHOD(CJS_Util) -JS_STATIC_METHOD_ENTRY(printd) -JS_STATIC_METHOD_ENTRY(printf) -JS_STATIC_METHOD_ENTRY(printx) -JS_STATIC_METHOD_ENTRY(scand) -JS_STATIC_METHOD_ENTRY(byteToChar) -END_JS_STATIC_METHOD() +JSMethodSpec CJS_Util::MethodSpecs[] = { + {"printd", printd_static}, {"printf", printf_static}, + {"printx", printx_static}, {"scand", scand_static}, + {"byteToChar", byteToChar_static}, {0, 0}}; IMPLEMENT_JS_CLASS(CJS_Util, util) @@ -114,11 +109,10 @@ util::util(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {} util::~util() {} -bool util::printf(IJS_Context* cc, +bool util::printf(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iSize = params.size(); if (iSize < 1) return false; @@ -177,7 +171,7 @@ bool util::printf(IJS_Context* cc, return true; } -bool util::printd(IJS_Context* cc, +bool util::printd(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -185,7 +179,6 @@ bool util::printd(IJS_Context* cc, if (iSize < 2) return false; - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); CJS_Value p1 = params[0]; CJS_Value p2 = params[1]; CJS_Date jsDate; @@ -307,7 +300,7 @@ bool util::printd(IJS_Context* cc, return false; } -bool util::printx(IJS_Context* cc, +bool util::printx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -316,7 +309,6 @@ bool util::printx(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); vRet = CJS_Value(pRuntime, printx(params[0].ToCFXWideString(pRuntime), params[1].ToCFXWideString(pRuntime)) .c_str()); @@ -425,11 +417,10 @@ CFX_WideString util::printx(const CFX_WideString& wsFormat, return wsResult; } -bool util::scand(IJS_Context* cc, +bool util::scand(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int iSize = params.size(); if (iSize < 2) return false; @@ -450,7 +441,7 @@ bool util::scand(IJS_Context* cc, return true; } -bool util::byteToChar(IJS_Context* cc, +bool util::byteToChar(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError) { @@ -459,7 +450,6 @@ bool util::byteToChar(IJS_Context* cc, return false; } - CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); int arg = params[0].ToInt(pRuntime); if (arg < 0 || arg > 255) { sError = JSGetStringFromID(IDS_STRING_JSVALUEERROR); diff --git a/fpdfsdk/javascript/util.h b/fpdfsdk/javascript/util.h index 80763d1e2..98761b6f3 100644 --- a/fpdfsdk/javascript/util.h +++ b/fpdfsdk/javascript/util.h @@ -17,23 +17,23 @@ class util : public CJS_EmbedObj { explicit util(CJS_Object* pJSObject); ~util() override; - bool printd(IJS_Context* cc, + bool printd(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool printf(IJS_Context* cc, + bool printf(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool printx(IJS_Context* cc, + bool printx(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool scand(IJS_Context* cc, + bool scand(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); - bool byteToChar(IJS_Context* cc, + bool byteToChar(CJS_Runtime* pRuntime, const std::vector<CJS_Value>& params, CJS_Value& vRet, CFX_WideString& sError); diff --git a/fpdfsdk/pdfwindow/PWL_Button.cpp b/fpdfsdk/pdfwindow/PWL_Button.cpp index 972e55eda..96be46945 100644 --- a/fpdfsdk/pdfwindow/PWL_Button.cpp +++ b/fpdfsdk/pdfwindow/PWL_Button.cpp @@ -20,7 +20,7 @@ void CPWL_Button::OnCreate(PWL_CREATEPARAM& cp) { cp.eCursorType = FXCT_HAND; } -bool CPWL_Button::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_Button::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); m_bMouseDown = true; @@ -29,7 +29,7 @@ bool CPWL_Button::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_Button::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_Button::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); ReleaseCapture(); diff --git a/fpdfsdk/pdfwindow/PWL_Button.h b/fpdfsdk/pdfwindow/PWL_Button.h index f35e9adf3..2d1193f89 100644 --- a/fpdfsdk/pdfwindow/PWL_Button.h +++ b/fpdfsdk/pdfwindow/PWL_Button.h @@ -17,8 +17,8 @@ class CPWL_Button : public CPWL_Wnd { // CPWL_Wnd CFX_ByteString GetClassName() const override; void OnCreate(PWL_CREATEPARAM& cp) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; protected: bool m_bMouseDown; diff --git a/fpdfsdk/pdfwindow/PWL_Caret.cpp b/fpdfsdk/pdfwindow/PWL_Caret.cpp index 8a5f53959..3360bbf62 100644 --- a/fpdfsdk/pdfwindow/PWL_Caret.cpp +++ b/fpdfsdk/pdfwindow/PWL_Caret.cpp @@ -14,6 +14,8 @@ #define PWL_CARET_FLASHINTERVAL 500 +PWL_CARET_INFO::PWL_CARET_INFO() : bVisible(false) {} + CPWL_Caret::CPWL_Caret() : m_bFlash(false), m_fWidth(0.4f), m_nDelay(0) {} CPWL_Caret::~CPWL_Caret() {} @@ -23,7 +25,7 @@ CFX_ByteString CPWL_Caret::GetClassName() const { } void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { - GetCaretApp(sAppStream, CFX_FloatPoint(0.0f, 0.0f)); + GetCaretApp(sAppStream, CFX_PointF()); } void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, @@ -32,26 +34,23 @@ void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_FloatRect rcRect = GetCaretRect(); CFX_FloatRect rcClip = GetClipRect(); CFX_PathData path; - path.SetPointCount(2); FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f; FX_FLOAT fCaretTop = rcRect.top; FX_FLOAT fCaretBottom = rcRect.bottom; if (!rcClip.IsEmpty()) { rcRect.Intersect(rcClip); - if (!rcRect.IsEmpty()) { - fCaretTop = rcRect.top; - fCaretBottom = rcRect.bottom; - path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); - path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); - } else { + if (rcRect.IsEmpty()) return; - } - } else { - path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO); - path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO); + + fCaretTop = rcRect.top; + fCaretBottom = rcRect.bottom; } + path.AppendPoint(CFX_PointF(fCaretX, fCaretBottom), FXPT_TYPE::MoveTo, + false); + path.AppendPoint(CFX_PointF(fCaretX, fCaretTop), FXPT_TYPE::LineTo, false); + CFX_GraphStateData gsd; gsd.m_LineWidth = m_fWidth; pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255, 0, 0, 0), @@ -60,7 +59,7 @@ void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, } void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf& sAppStream, - const CFX_FloatPoint& ptOffset) { + const CFX_PointF& ptOffset) { if (IsVisible() && m_bFlash) { CFX_ByteTextBuf sCaret; @@ -85,7 +84,7 @@ void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf& sAppStream, } CFX_ByteString CPWL_Caret::GetCaretAppearanceStream( - const CFX_FloatPoint& ptOffset) { + const CFX_PointF& ptOffset) { CFX_ByteTextBuf sCaret; GetCaretApp(sCaret, ptOffset); return sCaret.MakeString(); @@ -106,8 +105,8 @@ CFX_FloatRect CPWL_Caret::GetCaretRect() const { } void CPWL_Caret::SetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot) { + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot) { if (bVisible) { if (IsVisible()) { if (m_ptHead != ptHead || m_ptFoot != ptFoot) { @@ -126,8 +125,8 @@ void CPWL_Caret::SetCaret(bool bVisible, Move(m_rcInvalid, false, true); } } else { - m_ptHead = CFX_FloatPoint(); - m_ptFoot = CFX_FloatPoint(); + m_ptHead = CFX_PointF(); + m_ptFoot = CFX_PointF(); m_bFlash = false; if (IsVisible()) { EndTimer(); diff --git a/fpdfsdk/pdfwindow/PWL_Caret.h b/fpdfsdk/pdfwindow/PWL_Caret.h index ccee96109..60ebbdc8e 100644 --- a/fpdfsdk/pdfwindow/PWL_Caret.h +++ b/fpdfsdk/pdfwindow/PWL_Caret.h @@ -11,11 +11,11 @@ struct PWL_CARET_INFO { public: - PWL_CARET_INFO() : bVisible(false) {} + PWL_CARET_INFO(); bool bVisible; - CFX_FloatPoint ptHead; - CFX_FloatPoint ptFoot; + CFX_PointF ptHead; + CFX_PointF ptFoot; }; class CPWL_Caret : public CPWL_Wnd { @@ -33,18 +33,18 @@ class CPWL_Caret : public CPWL_Wnd { void TimerProc() override; void SetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot); - CFX_ByteString GetCaretAppearanceStream(const CFX_FloatPoint& ptOffset); + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot); + CFX_ByteString GetCaretAppearanceStream(const CFX_PointF& ptOffset); void SetInvalidRect(CFX_FloatRect rc) { m_rcInvalid = rc; } private: - void GetCaretApp(CFX_ByteTextBuf& sAppStream, const CFX_FloatPoint& ptOffset); + void GetCaretApp(CFX_ByteTextBuf& sAppStream, const CFX_PointF& ptOffset); CFX_FloatRect GetCaretRect() const; bool m_bFlash; - CFX_FloatPoint m_ptHead; - CFX_FloatPoint m_ptFoot; + CFX_PointF m_ptHead; + CFX_PointF m_ptFoot; FX_FLOAT m_fWidth; int32_t m_nDelay; CFX_FloatRect m_rcInvalid; diff --git a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp index 8e9a04b97..bc6909a07 100644 --- a/fpdfsdk/pdfwindow/PWL_ComboBox.cpp +++ b/fpdfsdk/pdfwindow/PWL_ComboBox.cpp @@ -18,7 +18,7 @@ #define PWLCB_DEFAULTFONTSIZE 12.0f -bool CPWL_CBListBox::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_CBListBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); if (!m_bMouseDown) @@ -102,14 +102,14 @@ void CPWL_CBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { if (IsVisible() && !rectWnd.IsEmpty()) { CFX_ByteTextBuf sButton; - CFX_FloatPoint ptCenter = GetCenterPoint(); + CFX_PointF ptCenter = GetCenterPoint(); - CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, - ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, - ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt3(ptCenter.x, - ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, + ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, + ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt3(ptCenter.x, + ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); if (IsFloatBigger(rectWnd.right - rectWnd.left, PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) && @@ -133,36 +133,33 @@ void CPWL_CBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_FloatRect rectWnd = CPWL_Wnd::GetWindowRect(); if (IsVisible() && !rectWnd.IsEmpty()) { - CFX_FloatPoint ptCenter = GetCenterPoint(); + CFX_PointF ptCenter = GetCenterPoint(); - CFX_FloatPoint pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, - ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, - ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt3(ptCenter.x, - ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt1(ptCenter.x - PWL_CBBUTTON_TRIANGLE_HALFLEN, + ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt2(ptCenter.x + PWL_CBBUTTON_TRIANGLE_HALFLEN, + ptCenter.y + PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt3(ptCenter.x, + ptCenter.y - PWL_CBBUTTON_TRIANGLE_HALFLEN * 0.5f); if (IsFloatBigger(rectWnd.right - rectWnd.left, PWL_CBBUTTON_TRIANGLE_HALFLEN * 2) && IsFloatBigger(rectWnd.top - rectWnd.bottom, PWL_CBBUTTON_TRIANGLE_HALFLEN)) { CFX_PathData path; - - path.SetPointCount(4); - path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); - path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); - path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); - path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); + path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false); + path.AppendPoint(pt2, FXPT_TYPE::LineTo, false); + path.AppendPoint(pt3, FXPT_TYPE::LineTo, false); + path.AppendPoint(pt1, FXPT_TYPE::LineTo, false); pDevice->DrawPath(&path, pUser2Device, nullptr, - CPWL_Utils::PWLColorToFXColor(PWL_DEFAULT_BLACKCOLOR, - GetTransparency()), - 0, FXFILL_ALTERNATE); + PWL_DEFAULT_BLACKCOLOR.ToFXColor(GetTransparency()), 0, + FXFILL_ALTERNATE); } } } -bool CPWL_CBButton::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_CBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); SetCapture(); @@ -175,7 +172,7 @@ bool CPWL_CBButton::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_CBButton::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_CBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); ReleaseCapture(); diff --git a/fpdfsdk/pdfwindow/PWL_ComboBox.h b/fpdfsdk/pdfwindow/PWL_ComboBox.h index 84261199e..e1a8df756 100644 --- a/fpdfsdk/pdfwindow/PWL_ComboBox.h +++ b/fpdfsdk/pdfwindow/PWL_ComboBox.h @@ -23,7 +23,7 @@ class CPWL_CBListBox : public CPWL_ListBox { ~CPWL_CBListBox() override {} // CPWL_ListBox - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; bool OnKeyDownWithExit(uint16_t nChar, bool& bExit, uint32_t nFlag); bool OnCharWithExit(uint16_t nChar, bool& bExit, uint32_t nFlag); @@ -40,8 +40,8 @@ class CPWL_CBButton : public CPWL_Wnd { void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override; void DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; }; class CPWL_ComboBox : public CPWL_Wnd { diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp index bb8ec9115..b77aad9ab 100644 --- a/fpdfsdk/pdfwindow/PWL_Edit.cpp +++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp @@ -6,6 +6,7 @@ #include "fpdfsdk/pdfwindow/PWL_Edit.h" +#include <memory> #include <vector> #include "core/fpdfapi/font/cpdf_font.h" @@ -41,35 +42,41 @@ void CPWL_Edit::OnDestroy() {} void CPWL_Edit::SetText(const CFX_WideString& csText) { CFX_WideString swText = csText; - if (HasFlag(PES_RICH)) { - CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText); - if (CXML_Element* pXML = - CXML_Element::Parse(sValue.c_str(), sValue.GetLength())) { - int32_t nCount = pXML->CountChildren(); - bool bFirst = true; - - swText.clear(); - - for (int32_t i = 0; i < nCount; i++) { - if (CXML_Element* pSubElement = pXML->GetElement(i)) { - CFX_ByteString tag = pSubElement->GetTagName(); - if (tag.EqualNoCase("p")) { - int nChild = pSubElement->CountChildren(); - CFX_WideString swSection; - for (int32_t j = 0; j < nChild; j++) { - swSection += pSubElement->GetContent(j); - } - - if (bFirst) - bFirst = false; - else - swText += FWL_VKEY_Return; - swText += swSection; - } - } - } + if (!HasFlag(PES_RICH)) { + m_pEdit->SetText(swText); + return; + } + + CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText); + std::unique_ptr<CXML_Element> pXML( + CXML_Element::Parse(sValue.c_str(), sValue.GetLength())); + if (!pXML) { + m_pEdit->SetText(swText); + return; + } + + int32_t nCount = pXML->CountChildren(); + bool bFirst = true; + + swText.clear(); + + for (int32_t i = 0; i < nCount; i++) { + CXML_Element* pSubElement = pXML->GetElement(i); + if (!pSubElement) + continue; - delete pXML; + CFX_ByteString tag = pSubElement->GetTagName(); + if (tag.EqualNoCase("p")) { + int nChild = pSubElement->CountChildren(); + CFX_WideString swSection; + for (int32_t j = 0; j < nChild; j++) + swSection += pSubElement->GetContent(j); + + if (bFirst) + bFirst = false; + else + swText += FWL_VKEY_Return; + swText += swSection; } } @@ -243,7 +250,7 @@ void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { sAppStream << sLine; CFX_ByteTextBuf sText; - CFX_FloatPoint ptOffset = CFX_FloatPoint(); + CFX_PointF ptOffset; CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange(); CPVT_WordRange wrSelect = GetSelectWordRange(); CPVT_WordRange wrVisible = @@ -266,7 +273,8 @@ void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { m_pEdit->GetPasswordChar()); if (sEditBefore.GetLength() > 0) - sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC() + sText << "BT\n" + << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC() << sEditBefore.AsStringC() << "ET\n"; wrTemp = CPWL_Utils::OverlapWordRange(wrVisible, wrSelect); @@ -286,7 +294,8 @@ void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { m_pEdit->GetPasswordChar()); if (sEditAfter.GetLength() > 0) - sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC() + sText << "BT\n" + << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC() << sEditAfter.AsStringC() << "ET\n"; if (sText.GetLength() > 0) { @@ -323,25 +332,24 @@ void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice, gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth(); CFX_PathData path; - path.SetPointCount(nCharArraySafe.ValueOrDie()); for (int32_t i = 0; i < nCharArray - 1; i++) { - path.SetPoint( - i * 2, - rcClient.left + - ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), - rcClient.bottom, FXPT_MOVETO); - path.SetPoint( - i * 2 + 1, - rcClient.left + - ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), - rcClient.top, FXPT_LINETO); + path.AppendPoint( + CFX_PointF( + rcClient.left + + ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), + rcClient.bottom), + FXPT_TYPE::MoveTo, false); + path.AppendPoint( + CFX_PointF( + rcClient.left + + ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), + rcClient.top), + FXPT_TYPE::LineTo, false); } - if (path.GetPointCount() > 0) { - pDevice->DrawPath( - &path, pUser2Device, &gsd, 0, - CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255), - FXFILL_ALTERNATE); + if (!path.GetPoints().empty()) { + pDevice->DrawPath(&path, pUser2Device, &gsd, 0, + GetBorderColor().ToFXColor(255), FXFILL_ALTERNATE); } break; } @@ -355,25 +363,23 @@ void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice, gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase; CFX_PathData path; - path.SetPointCount(nCharArraySafe.ValueOrDie()); - for (int32_t i = 0; i < nCharArray - 1; i++) { - path.SetPoint( - i * 2, - rcClient.left + - ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), - rcClient.bottom, FXPT_MOVETO); - path.SetPoint( - i * 2 + 1, - rcClient.left + - ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), - rcClient.top, FXPT_LINETO); + path.AppendPoint( + CFX_PointF( + rcClient.left + + ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), + rcClient.bottom), + FXPT_TYPE::MoveTo, false); + path.AppendPoint( + CFX_PointF( + rcClient.left + + ((rcClient.right - rcClient.left) / nCharArray) * (i + 1), + rcClient.top), + FXPT_TYPE::LineTo, false); } - if (path.GetPointCount() > 0) { - pDevice->DrawPath( - &path, pUser2Device, &gsd, 0, - CPWL_Utils::PWLColorToFXColor(GetBorderColor(), 255), - FXFILL_ALTERNATE); + if (!path.GetPoints().empty()) { + pDevice->DrawPath(&path, pUser2Device, &gsd, 0, + GetBorderColor().ToFXColor(255), FXFILL_ALTERNATE); } break; } @@ -391,14 +397,12 @@ void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice, } CFX_SystemHandler* pSysHandler = GetSystemHandler(); - CFX_Edit::DrawEdit( - pDevice, pUser2Device, m_pEdit.get(), - CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), - CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(), GetTransparency()), - rcClip, CFX_FloatPoint(), pRange, pSysHandler, m_pFormFiller); + CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pEdit.get(), + GetTextColor().ToFXColor(GetTransparency()), rcClip, + CFX_PointF(), pRange, pSysHandler, m_pFormFiller); } -bool CPWL_Edit::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_Edit::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) { @@ -414,7 +418,7 @@ bool CPWL_Edit::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_Edit::OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_Edit::OnLButtonDblClk(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDblClk(point, nFlag); if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point)) { @@ -424,7 +428,7 @@ bool CPWL_Edit::OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_Edit::OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_Edit::OnRButtonUp(const CFX_PointF& point, uint32_t nFlag) { if (m_bMouseDown) return false; @@ -454,7 +458,7 @@ void CPWL_Edit::OnSetFocus() { void CPWL_Edit::OnKillFocus() { ShowVScrollBar(false); m_pEdit->SelectNone(); - SetCaret(false, CFX_FloatPoint(), CFX_FloatPoint()); + SetCaret(false, CFX_PointF(), CFX_PointF()); SetCharSet(FXFONT_ANSI_CHARSET); m_bFocus = false; } @@ -464,7 +468,7 @@ void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace) { } CFX_ByteString CPWL_Edit::GetSelectAppearanceStream( - const CFX_FloatPoint& ptOffset) const { + const CFX_PointF& ptOffset) const { CPVT_WordRange wr = GetSelectWordRange(); return CPWL_Utils::GetEditSelAppStream(m_pEdit.get(), ptOffset, &wr); } @@ -486,35 +490,34 @@ CPVT_WordRange CPWL_Edit::GetSelectWordRange() const { } CFX_ByteString CPWL_Edit::GetTextAppearanceStream( - const CFX_FloatPoint& ptOffset) const { + const CFX_PointF& ptOffset) const { CFX_ByteTextBuf sRet; CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit.get(), ptOffset); if (sEdit.GetLength() > 0) { - sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC() + sRet << "BT\n" + << CPWL_Utils::GetColorAppStream(GetTextColor()).AsStringC() << sEdit.AsStringC() << "ET\n"; } return sRet.MakeString(); } CFX_ByteString CPWL_Edit::GetCaretAppearanceStream( - const CFX_FloatPoint& ptOffset) const { + const CFX_PointF& ptOffset) const { if (m_pEditCaret) return m_pEditCaret->GetCaretAppearanceStream(ptOffset); return CFX_ByteString(); } -CFX_FloatPoint CPWL_Edit::GetWordRightBottomPoint( - const CPVT_WordPlace& wpWord) { +CFX_PointF CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord) { CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator(); CPVT_WordPlace wpOld = pIterator->GetAt(); pIterator->SetAt(wpWord); - CFX_FloatPoint pt; + CFX_PointF pt; CPVT_Word word; if (pIterator->GetWord(word)) { - pt = CFX_FloatPoint(word.ptWord.x + word.fWidth, - word.ptWord.y + word.fDescent); + pt = CFX_PointF(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent); } pIterator->SetAt(wpOld); return pt; @@ -720,10 +723,10 @@ bool CPWL_Edit::OnChar(uint16_t nChar, uint32_t nFlag) { } bool CPWL_Edit::OnMouseWheel(short zDelta, - const CFX_FloatPoint& point, + const CFX_PointF& point, uint32_t nFlag) { if (HasFlag(PES_MULTILINE)) { - CFX_FloatPoint ptScroll = GetScrollPos(); + CFX_PointF ptScroll = GetScrollPos(); if (zDelta > 0) { ptScroll.y += GetFontSize(); @@ -805,8 +808,7 @@ CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1, return wrRet; } -CPVT_WordRange CPWL_Edit::GetLatinWordsRange( - const CFX_FloatPoint& point) const { +CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CFX_PointF& point) const { return GetSameWordsRange(m_pEdit->SearchWordPlace(point), true, false); } @@ -874,21 +876,3 @@ CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace& place, range.Set(wpStart, wpEnd); return range; } - -void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder, - const CFX_FloatPoint& ptOffset, - std::vector<CPDF_TextObject*>* ObjArray) { - CFX_Edit::GeneratePageObjects( - pObjectHolder, m_pEdit.get(), ptOffset, nullptr, - CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), - ObjArray); -} - -void CPWL_Edit::GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder, - const CFX_FloatPoint& ptOffset) { - std::vector<CPDF_TextObject*> ObjArray; - CFX_Edit::GeneratePageObjects( - pObjectHolder, m_pEdit.get(), ptOffset, nullptr, - CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), - &ObjArray); -} diff --git a/fpdfsdk/pdfwindow/PWL_Edit.h b/fpdfsdk/pdfwindow/PWL_Edit.h index 801dedd0a..b6d01300f 100644 --- a/fpdfsdk/pdfwindow/PWL_Edit.h +++ b/fpdfsdk/pdfwindow/PWL_Edit.h @@ -60,11 +60,11 @@ class CPWL_Edit : public CPWL_EditCtrl { void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override; void DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonDblClk(const CFX_PointF& point, uint32_t nFlag) override; + bool OnRButtonUp(const CFX_PointF& point, uint32_t nFlag) override; bool OnMouseWheel(short zDelta, - const CFX_FloatPoint& point, + const CFX_PointF& point, uint32_t nFlag) override; bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override; bool OnChar(uint16_t nChar, uint32_t nFlag) override; @@ -90,10 +90,9 @@ class CPWL_Edit : public CPWL_EditCtrl { void SetText(const CFX_WideString& csText); void ReplaceSel(const CFX_WideString& csText); - CFX_ByteString GetTextAppearanceStream(const CFX_FloatPoint& ptOffset) const; - CFX_ByteString GetCaretAppearanceStream(const CFX_FloatPoint& ptOffset) const; - CFX_ByteString GetSelectAppearanceStream( - const CFX_FloatPoint& ptOffset) const; + CFX_ByteString GetTextAppearanceStream(const CFX_PointF& ptOffset) const; + CFX_ByteString GetCaretAppearanceStream(const CFX_PointF& ptOffset) const; + CFX_ByteString GetSelectAppearanceStream(const CFX_PointF& ptOffset) const; bool IsTextFull() const; @@ -105,12 +104,6 @@ class CPWL_Edit : public CPWL_EditCtrl { m_pFillerNotify = pNotify; } - void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder, - const CFX_FloatPoint& ptOffset, - std::vector<CPDF_TextObject*>* ObjArray); - void GeneratePageObjects(CPDF_PageObjectHolder* pObjectHolder, - const CFX_FloatPoint& ptOffset); - bool IsProceedtoOnChar(uint16_t nKeyCode, uint32_t nFlag); void AttachFFLData(CFFL_FormFiller* pData) { m_pFormFiller = pData; } @@ -131,11 +124,11 @@ class CPWL_Edit : public CPWL_EditCtrl { void SetParamByFlag(); FX_FLOAT GetCharArrayAutoFontSize(int32_t nCharArray); - CFX_FloatPoint GetWordRightBottomPoint(const CPVT_WordPlace& wpWord); + CFX_PointF GetWordRightBottomPoint(const CPVT_WordPlace& wpWord); CPVT_WordRange CombineWordRange(const CPVT_WordRange& wr1, const CPVT_WordRange& wr2); - CPVT_WordRange GetLatinWordsRange(const CFX_FloatPoint& point) const; + CPVT_WordRange GetLatinWordsRange(const CFX_PointF& point) const; CPVT_WordRange GetLatinWordsRange(const CPVT_WordPlace& place) const; CPVT_WordRange GetArabicWordsRange(const CPVT_WordPlace& place) const; CPVT_WordRange GetSameWordsRange(const CPVT_WordPlace& place, diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp index 94592159d..4921ab7a0 100644 --- a/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp +++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.cpp @@ -40,13 +40,7 @@ void CPWL_EditCtrl::OnCreated() { bool CPWL_EditCtrl::IsWndHorV() { CFX_Matrix mt = GetWindowMatrix(); - CFX_FloatPoint point1(0, 1); - CFX_FloatPoint point2(1, 1); - - mt.Transform(point1.x, point1.y); - mt.Transform(point2.x, point2.y); - - return point2.y == point1.y; + return mt.Transform(CFX_PointF(1, 1)).y == mt.Transform(CFX_PointF(0, 1)).y; } void CPWL_EditCtrl::SetCursor() { @@ -93,8 +87,7 @@ void CPWL_EditCtrl::OnNotify(CPWL_Wnd* pWnd, FX_FLOAT fPos = *(FX_FLOAT*)lParam; switch (wParam) { case SBT_VSCROLL: - m_pEdit->SetScrollPos( - CFX_FloatPoint(m_pEdit->GetScrollPos().x, fPos)); + m_pEdit->SetScrollPos(CFX_PointF(m_pEdit->GetScrollPos().x, fPos)); break; } } break; @@ -281,7 +274,7 @@ bool CPWL_EditCtrl::OnChar(uint16_t nChar, uint32_t nFlag) { return true; } -bool CPWL_EditCtrl::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_EditCtrl::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); if (ClientHitTest(point)) { @@ -297,7 +290,7 @@ bool CPWL_EditCtrl::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_EditCtrl::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_EditCtrl::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); if (m_bMouseDown) { @@ -312,7 +305,7 @@ bool CPWL_EditCtrl::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_EditCtrl::OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_EditCtrl::OnMouseMove(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnMouseMove(point, nFlag); if (m_bMouseDown) @@ -326,44 +319,36 @@ CFX_FloatRect CPWL_EditCtrl::GetContentRect() const { } void CPWL_EditCtrl::SetEditCaret(bool bVisible) { - CFX_FloatPoint ptHead; - CFX_FloatPoint ptFoot; + CFX_PointF ptHead; + CFX_PointF ptFoot; if (bVisible) - GetCaretInfo(ptHead, ptFoot); + GetCaretInfo(&ptHead, &ptFoot); CPVT_WordPlace wpTemp = m_pEdit->GetCaretWordPlace(); IOnSetCaret(bVisible, ptHead, ptFoot, wpTemp); } -void CPWL_EditCtrl::GetCaretInfo(CFX_FloatPoint& ptHead, - CFX_FloatPoint& ptFoot) const { +void CPWL_EditCtrl::GetCaretInfo(CFX_PointF* ptHead, CFX_PointF* ptFoot) const { CFX_Edit_Iterator* pIterator = m_pEdit->GetIterator(); pIterator->SetAt(m_pEdit->GetCaret()); CPVT_Word word; CPVT_Line line; if (pIterator->GetWord(word)) { - ptHead.x = word.ptWord.x + word.fWidth; - ptHead.y = word.ptWord.y + word.fAscent; - ptFoot.x = word.ptWord.x + word.fWidth; - ptFoot.y = word.ptWord.y + word.fDescent; + ptHead->x = word.ptWord.x + word.fWidth; + ptHead->y = word.ptWord.y + word.fAscent; + ptFoot->x = word.ptWord.x + word.fWidth; + ptFoot->y = word.ptWord.y + word.fDescent; } else if (pIterator->GetLine(line)) { - ptHead.x = line.ptLine.x; - ptHead.y = line.ptLine.y + line.fLineAscent; - ptFoot.x = line.ptLine.x; - ptFoot.y = line.ptLine.y + line.fLineDescent; + ptHead->x = line.ptLine.x; + ptHead->y = line.ptLine.y + line.fLineAscent; + ptFoot->x = line.ptLine.x; + ptFoot->y = line.ptLine.y + line.fLineDescent; } } -void CPWL_EditCtrl::GetCaretPos(int32_t& x, int32_t& y) const { - CFX_FloatPoint ptHead; - CFX_FloatPoint ptFoot; - GetCaretInfo(ptHead, ptFoot); - PWLtoWnd(ptHead, x, y); -} - void CPWL_EditCtrl::SetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot) { + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot) { if (m_pEditCaret) { if (!IsFocused() || m_pEdit->IsSelected()) bVisible = false; @@ -413,11 +398,11 @@ int32_t CPWL_EditCtrl::GetTotalWords() const { return m_pEdit->GetTotalWords(); } -void CPWL_EditCtrl::SetScrollPos(const CFX_FloatPoint& point) { +void CPWL_EditCtrl::SetScrollPos(const CFX_PointF& point) { m_pEdit->SetScrollPos(point); } -CFX_FloatPoint CPWL_EditCtrl::GetScrollPos() const { +CFX_PointF CPWL_EditCtrl::GetScrollPos() const { return m_pEdit->GetScrollPos(); } @@ -544,8 +529,8 @@ void CPWL_EditCtrl::IOnSetScrollPosY(FX_FLOAT fy) { } void CPWL_EditCtrl::IOnSetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot, + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot, const CPVT_WordPlace& place) { PWL_CARET_INFO cInfo; cInfo.bVisible = bVisible; @@ -572,9 +557,9 @@ void CPWL_EditCtrl::GetTextRange(const CFX_FloatRect& rect, int32_t& nStartChar, int32_t& nEndChar) const { nStartChar = m_pEdit->WordPlaceToWordIndex( - m_pEdit->SearchWordPlace(CFX_FloatPoint(rect.left, rect.top))); + m_pEdit->SearchWordPlace(CFX_PointF(rect.left, rect.top))); nEndChar = m_pEdit->WordPlaceToWordIndex( - m_pEdit->SearchWordPlace(CFX_FloatPoint(rect.right, rect.bottom))); + m_pEdit->SearchWordPlace(CFX_PointF(rect.right, rect.bottom))); } CFX_WideString CPWL_EditCtrl::GetText(int32_t& nStartChar, diff --git a/fpdfsdk/pdfwindow/PWL_EditCtrl.h b/fpdfsdk/pdfwindow/PWL_EditCtrl.h index 3ff5cc66c..498570b3b 100644 --- a/fpdfsdk/pdfwindow/PWL_EditCtrl.h +++ b/fpdfsdk/pdfwindow/PWL_EditCtrl.h @@ -34,7 +34,6 @@ class CPWL_EditCtrl : public CPWL_Wnd { ~CPWL_EditCtrl() override; CFX_FloatRect GetContentRect() const; - void GetCaretPos(int32_t& x, int32_t& y) const; CFX_WideString GetText() const; void SetSel(int32_t nStartChar, int32_t nEndChar); @@ -53,8 +52,8 @@ class CPWL_EditCtrl : public CPWL_Wnd { void Paint(); void EnableRefresh(bool bRefresh); - CFX_FloatPoint GetScrollPos() const; - void SetScrollPos(const CFX_FloatPoint& point); + CFX_PointF GetScrollPos() const; + void SetScrollPos(const CFX_PointF& point); void SetCharSet(uint8_t nCharSet) { m_nCharSet = nCharSet; } int32_t GetCharSet() const; @@ -77,9 +76,9 @@ class CPWL_EditCtrl : public CPWL_Wnd { void OnCreated() override; bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override; bool OnChar(uint16_t nChar, uint32_t nFlag) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; + bool OnMouseMove(const CFX_PointF& point, uint32_t nFlag) override; void OnNotify(CPWL_Wnd* pWnd, uint32_t msg, intptr_t wParam = 0, @@ -98,8 +97,8 @@ class CPWL_EditCtrl : public CPWL_Wnd { FX_FLOAT fBigStep); void IOnSetScrollPosY(FX_FLOAT fy); void IOnSetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot, + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot, const CPVT_WordPlace& place); void IOnCaretChange(const CPVT_SecProps& secProps, const CPVT_WordProps& wordProps); @@ -121,10 +120,10 @@ class CPWL_EditCtrl : public CPWL_Wnd { void Delete(); void Backspace(); - void GetCaretInfo(CFX_FloatPoint& ptHead, CFX_FloatPoint& ptFoot) const; + void GetCaretInfo(CFX_PointF* ptHead, CFX_PointF* ptFoot) const; void SetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot); + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot); void SetEditCaret(bool bVisible); diff --git a/fpdfsdk/pdfwindow/PWL_Icon.cpp b/fpdfsdk/pdfwindow/PWL_Icon.cpp index 877921d6e..b0d0c7686 100644 --- a/fpdfsdk/pdfwindow/PWL_Icon.cpp +++ b/fpdfsdk/pdfwindow/PWL_Icon.cpp @@ -6,6 +6,8 @@ #include "fpdfsdk/pdfwindow/PWL_Icon.h" +#include <algorithm> + #include "core/fpdfapi/parser/cpdf_array.h" #include "core/fpdfapi/parser/cpdf_stream.h" #include "fpdfsdk/pdfwindow/PWL_Utils.h" @@ -39,8 +41,8 @@ CFX_ByteString CPWL_Image::GetImageAppStream() { sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx << " " << rcPlate.bottom + fy << " cm\n"; - sAppStream << mt.GetA() << " " << mt.GetB() << " " << mt.GetC() << " " - << mt.GetD() << " " << mt.GetE() << " " << mt.GetF() << " cm\n"; + sAppStream << mt.a << " " << mt.b << " " << mt.c << " " << mt.d << " " + << mt.e << " " << mt.f << " cm\n"; sAppStream << "0 g 0 G 1 w /" << sAlias.AsStringC() << " Do\n" << "Q\n"; @@ -169,20 +171,20 @@ void CPWL_Icon::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) { switch (nScaleMethod) { default: case 0: - fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f); - fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f); + fHScale = fPlateWidth / std::max(fImageWidth, 1.0f); + fVScale = fPlateHeight / std::max(fImageHeight, 1.0f); break; case 1: if (fPlateWidth < fImageWidth) - fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f); + fHScale = fPlateWidth / std::max(fImageWidth, 1.0f); if (fPlateHeight < fImageHeight) - fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f); + fVScale = fPlateHeight / std::max(fImageHeight, 1.0f); break; case 2: if (fPlateWidth > fImageWidth) - fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f); + fHScale = fPlateWidth / std::max(fImageWidth, 1.0f); if (fPlateHeight > fImageHeight) - fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f); + fVScale = fPlateHeight / std::max(fImageHeight, 1.0f); break; case 3: break; @@ -190,7 +192,7 @@ void CPWL_Icon::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) { FX_FLOAT fMinScale; if (IsProportionalScale()) { - fMinScale = PWL_MIN(fHScale, fVScale); + fMinScale = std::min(fHScale, fVScale); fHScale = fMinScale; fVScale = fMinScale; } diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.cpp b/fpdfsdk/pdfwindow/PWL_ListBox.cpp index 12cad7b9d..ed96e203f 100644 --- a/fpdfsdk/pdfwindow/PWL_ListBox.cpp +++ b/fpdfsdk/pdfwindow/PWL_ListBox.cpp @@ -106,7 +106,7 @@ void CPWL_ListBox::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom) continue; - CFX_FloatPoint ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f); + CFX_PointF ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f); if (m_pList->IsItemSelected(i)) { sListItems << CPWL_Utils::GetRectFillAppStream(rcItem, PWL_DEFAULT_SELBACKCOLOR) @@ -158,7 +158,7 @@ void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice, if (rcItem.bottom > rcPlate.top || rcItem.top < rcPlate.bottom) continue; - CFX_FloatPoint ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f); + CFX_PointF ptOffset(rcItem.left, (rcItem.top + rcItem.bottom) * 0.5f); if (CFX_Edit* pEdit = m_pList->GetItemEdit(i)) { CFX_FloatRect rcContent = pEdit->GetContentRect(); if (rcContent.Width() > rcClient.Width()) @@ -171,24 +171,21 @@ void CPWL_ListBox::DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_SystemHandler* pSysHandler = GetSystemHandler(); if (pSysHandler && pSysHandler->IsSelectionImplemented()) { CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), - CPWL_Utils::PWLColorToFXColor(GetTextColor()), - CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()), - rcList, ptOffset, nullptr, pSysHandler, - m_pFormFiller); + GetTextColor().ToFXColor(255), rcList, ptOffset, + nullptr, pSysHandler, m_pFormFiller); pSysHandler->OutputSelectedRect(m_pFormFiller, rcItem); } else { CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcItem, ArgbEncode(255, 0, 51, 113)); CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), - ArgbEncode(255, 255, 255, 255), 0, rcList, ptOffset, + ArgbEncode(255, 255, 255, 255), rcList, ptOffset, nullptr, pSysHandler, m_pFormFiller); } } else { CFX_SystemHandler* pSysHandler = GetSystemHandler(); CFX_Edit::DrawEdit(pDevice, pUser2Device, m_pList->GetItemEdit(i), - CPWL_Utils::PWLColorToFXColor(GetTextColor()), - CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor()), - rcList, ptOffset, nullptr, pSysHandler, nullptr); + GetTextColor().ToFXColor(255), rcList, ptOffset, + nullptr, pSysHandler, nullptr); } } } @@ -249,7 +246,7 @@ bool CPWL_ListBox::OnChar(uint16_t nChar, uint32_t nFlag) { return true; } -bool CPWL_ListBox::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_ListBox::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); if (ClientHitTest(point)) { @@ -263,7 +260,7 @@ bool CPWL_ListBox::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_ListBox::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_ListBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); if (m_bMouseDown) { @@ -281,7 +278,7 @@ void CPWL_ListBox::SetHoverSel(bool bHoverSel) { m_bHoverSel = bHoverSel; } -bool CPWL_ListBox::OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_ListBox::OnMouseMove(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnMouseMove(point, nFlag); if (m_bHoverSel && !IsCaptureMouse() && ClientHitTest(point)) @@ -323,7 +320,7 @@ void CPWL_ListBox::OnNotify(CPWL_Wnd* pWnd, fPos = *(FX_FLOAT*)lParam; switch (wParam) { case SBT_VSCROLL: - m_pList->SetScrollPos(CFX_FloatPoint(0, fPos)); + m_pList->SetScrollPos(CFX_PointF(0, fPos)); break; } break; @@ -449,7 +446,7 @@ CFX_FloatRect CPWL_ListBox::GetListRect() const { } bool CPWL_ListBox::OnMouseWheel(short zDelta, - const CFX_FloatPoint& point, + const CFX_PointF& point, uint32_t nFlag) { if (zDelta < 0) m_pList->OnVK_DOWN(IsSHIFTpressed(nFlag), IsCTRLpressed(nFlag)); diff --git a/fpdfsdk/pdfwindow/PWL_ListBox.h b/fpdfsdk/pdfwindow/PWL_ListBox.h index 6db4ecb38..f9108a17d 100644 --- a/fpdfsdk/pdfwindow/PWL_ListBox.h +++ b/fpdfsdk/pdfwindow/PWL_ListBox.h @@ -35,8 +35,8 @@ class CPWL_List_Notify { void IOnInvalidateRect(CFX_FloatRect* pRect); void IOnSetCaret(bool bVisible, - const CFX_FloatPoint& ptHead, - const CFX_FloatPoint& ptFoot, + const CFX_PointF& ptHead, + const CFX_PointF& ptFoot, const CPVT_WordPlace& place); private: @@ -57,11 +57,11 @@ class CPWL_ListBox : public CPWL_Wnd { CFX_Matrix* pUser2Device) override; bool OnKeyDown(uint16_t nChar, uint32_t nFlag) override; bool OnChar(uint16_t nChar, uint32_t nFlag) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; + bool OnMouseMove(const CFX_PointF& point, uint32_t nFlag) override; bool OnMouseWheel(short zDelta, - const CFX_FloatPoint& point, + const CFX_PointF& point, uint32_t nFlag) override; void KillFocus() override; void OnNotify(CPWL_Wnd* pWnd, diff --git a/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp index 8a09ac663..e3799366a 100644 --- a/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp +++ b/fpdfsdk/pdfwindow/PWL_ScrollBar.cpp @@ -137,18 +137,17 @@ void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { sAppStream << "q\n"; - CFX_FloatPoint ptCenter = GetCenterPoint(); + CFX_PointF ptCenter = GetCenterPoint(); switch (m_eScrollBarType) { case SBT_HSCROLL: switch (m_eSBButtonType) { case PSBT_MIN: { - CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y); - CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y + PWL_TRIANGLE_HALFLEN); - CFX_FloatPoint pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y - PWL_TRIANGLE_HALFLEN); + CFX_PointF pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); + CFX_PointF pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y + PWL_TRIANGLE_HALFLEN); + CFX_PointF pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y - PWL_TRIANGLE_HALFLEN); if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { @@ -162,12 +161,11 @@ void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { } } break; case PSBT_MAX: { - CFX_FloatPoint pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y); - CFX_FloatPoint pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y + PWL_TRIANGLE_HALFLEN); - CFX_FloatPoint pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y - PWL_TRIANGLE_HALFLEN); + CFX_PointF pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); + CFX_PointF pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y + PWL_TRIANGLE_HALFLEN); + CFX_PointF pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y - PWL_TRIANGLE_HALFLEN); if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { @@ -187,12 +185,11 @@ void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { case SBT_VSCROLL: switch (m_eSBButtonType) { case PSBT_MIN: { - CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN, - ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN, - ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt3(ptCenter.x, - ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN, + ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN, + ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt3(ptCenter.x, ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { @@ -206,12 +203,11 @@ void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) { } } break; case PSBT_MAX: { - CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN, - ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN, - ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); - CFX_FloatPoint pt3(ptCenter.x, - ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN, + ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN, + ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f); + CFX_PointF pt3(ptCenter.x, ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f); if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { @@ -244,58 +240,50 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, if (rectWnd.IsEmpty()) return; - CFX_FloatPoint ptCenter = GetCenterPoint(); - int32_t nTransparancy = GetTransparency(); + CFX_PointF ptCenter = GetCenterPoint(); + int32_t nTransparency = GetTransparency(); switch (m_eScrollBarType) { case SBT_HSCROLL: CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device); switch (m_eSBButtonType) { case PSBT_MIN: { - CFX_FloatPoint pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y); - CFX_FloatPoint pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y + PWL_TRIANGLE_HALFLEN); - CFX_FloatPoint pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y - PWL_TRIANGLE_HALFLEN); + CFX_PointF pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); + CFX_PointF pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y + PWL_TRIANGLE_HALFLEN); + CFX_PointF pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y - PWL_TRIANGLE_HALFLEN); if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { CFX_PathData path; - - path.SetPointCount(4); - path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); - path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); - path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); - path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); + path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false); + path.AppendPoint(pt2, FXPT_TYPE::LineTo, false); + path.AppendPoint(pt3, FXPT_TYPE::LineTo, false); + path.AppendPoint(pt1, FXPT_TYPE::LineTo, false); pDevice->DrawPath(&path, pUser2Device, nullptr, - CPWL_Utils::PWLColorToFXColor( - PWL_DEFAULT_BLACKCOLOR, nTransparancy), + PWL_DEFAULT_BLACKCOLOR.ToFXColor(nTransparency), 0, FXFILL_ALTERNATE); } } break; case PSBT_MAX: { - CFX_FloatPoint pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y); - CFX_FloatPoint pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y + PWL_TRIANGLE_HALFLEN); - CFX_FloatPoint pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, - ptCenter.y - PWL_TRIANGLE_HALFLEN); + CFX_PointF pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y); + CFX_PointF pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y + PWL_TRIANGLE_HALFLEN); + CFX_PointF pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, + ptCenter.y - PWL_TRIANGLE_HALFLEN); if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 && rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) { CFX_PathData path; - - path.SetPointCount(4); - path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); - path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); - path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); - path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); + path.AppendPoint(pt1, FXPT_TYPE::MoveTo, false); + path.AppendPoint(pt2, FXPT_TYPE::LineTo, false); + path.AppendPoint(pt3, FXPT_TYPE::LineTo, false); + path.AppendPoint(pt1, FXPT_TYPE::LineTo, false); pDevice->DrawPath(&path, pUser2Device, nullptr, - CPWL_Utils::PWLColorToFXColor( - PWL_DEFAULT_BLACKCOLOR, nTransparancy), + PWL_DEFAULT_BLACKCOLOR.ToFXColor(nTransparency), 0, FXFILL_ALTERNATE); } } break; @@ -309,13 +297,13 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, // draw border CFX_FloatRect rcDraw = rectWnd; CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, - ArgbEncode(nTransparancy, 100, 100, 100), + ArgbEncode(nTransparency, 100, 100, 100), 0.0f); // draw inner border rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f); CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, - ArgbEncode(nTransparancy, 255, 255, 255), + ArgbEncode(nTransparency, 255, 255, 255), 1.0f); // draw background @@ -324,7 +312,7 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, if (IsEnabled()) CPWL_Utils::DrawShadow(pDevice, pUser2Device, true, false, rcDraw, - nTransparancy, 80, 220); + nTransparency, 80, 220); else CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw, ArgbEncode(255, 255, 255, 255)); @@ -334,42 +322,42 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, if (rectWnd.top - rectWnd.bottom > 6.0f) { FX_FLOAT fX = rectWnd.left + 1.5f; FX_FLOAT fY = rectWnd.bottom; - CFX_FloatPoint pts[7] = {CFX_FloatPoint(fX + 2.5f, fY + 4.0f), - CFX_FloatPoint(fX + 2.5f, fY + 3.0f), - CFX_FloatPoint(fX + 4.5f, fY + 5.0f), - CFX_FloatPoint(fX + 6.5f, fY + 3.0f), - CFX_FloatPoint(fX + 6.5f, fY + 4.0f), - CFX_FloatPoint(fX + 4.5f, fY + 6.0f), - CFX_FloatPoint(fX + 2.5f, fY + 4.0f)}; + CFX_PointF pts[7] = {CFX_PointF(fX + 2.5f, fY + 4.0f), + CFX_PointF(fX + 2.5f, fY + 3.0f), + CFX_PointF(fX + 4.5f, fY + 5.0f), + CFX_PointF(fX + 6.5f, fY + 3.0f), + CFX_PointF(fX + 6.5f, fY + 4.0f), + CFX_PointF(fX + 4.5f, fY + 6.0f), + CFX_PointF(fX + 2.5f, fY + 4.0f)}; if (IsEnabled()) CPWL_Utils::DrawFillArea( pDevice, pUser2Device, pts, 7, - ArgbEncode(nTransparancy, 255, 255, 255)); + ArgbEncode(nTransparency, 255, 255, 255)); else - CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7, - CPWL_Utils::PWLColorToFXColor( - PWL_DEFAULT_HEAVYGRAYCOLOR, 255)); + CPWL_Utils::DrawFillArea( + pDevice, pUser2Device, pts, 7, + PWL_DEFAULT_HEAVYGRAYCOLOR.ToFXColor(255)); } } break; case PSBT_MAX: { // draw border CFX_FloatRect rcDraw = rectWnd; CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, - ArgbEncode(nTransparancy, 100, 100, 100), + ArgbEncode(nTransparency, 100, 100, 100), 0.0f); // draw inner border rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f); CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, - ArgbEncode(nTransparancy, 255, 255, 255), + ArgbEncode(nTransparency, 255, 255, 255), 1.0f); // draw background rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f); if (IsEnabled()) CPWL_Utils::DrawShadow(pDevice, pUser2Device, true, false, rcDraw, - nTransparancy, 80, 220); + nTransparency, 80, 220); else CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw, ArgbEncode(255, 255, 255, 255)); @@ -380,113 +368,112 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, FX_FLOAT fX = rectWnd.left + 1.5f; FX_FLOAT fY = rectWnd.bottom; - CFX_FloatPoint pts[7] = {CFX_FloatPoint(fX + 2.5f, fY + 5.0f), - CFX_FloatPoint(fX + 2.5f, fY + 6.0f), - CFX_FloatPoint(fX + 4.5f, fY + 4.0f), - CFX_FloatPoint(fX + 6.5f, fY + 6.0f), - CFX_FloatPoint(fX + 6.5f, fY + 5.0f), - CFX_FloatPoint(fX + 4.5f, fY + 3.0f), - CFX_FloatPoint(fX + 2.5f, fY + 5.0f)}; + CFX_PointF pts[7] = {CFX_PointF(fX + 2.5f, fY + 5.0f), + CFX_PointF(fX + 2.5f, fY + 6.0f), + CFX_PointF(fX + 4.5f, fY + 4.0f), + CFX_PointF(fX + 6.5f, fY + 6.0f), + CFX_PointF(fX + 6.5f, fY + 5.0f), + CFX_PointF(fX + 4.5f, fY + 3.0f), + CFX_PointF(fX + 2.5f, fY + 5.0f)}; if (IsEnabled()) CPWL_Utils::DrawFillArea( pDevice, pUser2Device, pts, 7, - ArgbEncode(nTransparancy, 255, 255, 255)); + ArgbEncode(nTransparency, 255, 255, 255)); else - CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7, - CPWL_Utils::PWLColorToFXColor( - PWL_DEFAULT_HEAVYGRAYCOLOR, 255)); + CPWL_Utils::DrawFillArea( + pDevice, pUser2Device, pts, 7, + PWL_DEFAULT_HEAVYGRAYCOLOR.ToFXColor(255)); } } break; case PSBT_POS: { // draw border CFX_FloatRect rcDraw = rectWnd; CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, - ArgbEncode(nTransparancy, 100, 100, 100), + ArgbEncode(nTransparency, 100, 100, 100), 0.0f); // draw inner border rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f); CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw, - ArgbEncode(nTransparancy, 255, 255, 255), + ArgbEncode(nTransparency, 255, 255, 255), 1.0f); if (IsEnabled()) { // draw shadow effect - CFX_FloatPoint ptTop = - CFX_FloatPoint(rectWnd.left, rectWnd.top - 1.0f); - CFX_FloatPoint ptBottom = - CFX_FloatPoint(rectWnd.left, rectWnd.bottom + 1.0f); + CFX_PointF ptTop = CFX_PointF(rectWnd.left, rectWnd.top - 1.0f); + CFX_PointF ptBottom = + CFX_PointF(rectWnd.left, rectWnd.bottom + 1.0f); ptTop.x += 1.5f; ptBottom.x += 1.5f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 210, 210, 210), + ArgbEncode(nTransparency, 210, 210, 210), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 220, 220, 220), + ArgbEncode(nTransparency, 220, 220, 220), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 240, 240, 240), + ArgbEncode(nTransparency, 240, 240, 240), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 240, 240, 240), + ArgbEncode(nTransparency, 240, 240, 240), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 210, 210, 210), + ArgbEncode(nTransparency, 210, 210, 210), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 180, 180, 180), + ArgbEncode(nTransparency, 180, 180, 180), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 150, 150, 150), + ArgbEncode(nTransparency, 150, 150, 150), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 150, 150, 150), + ArgbEncode(nTransparency, 150, 150, 150), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 180, 180, 180), + ArgbEncode(nTransparency, 180, 180, 180), 1.0f); ptTop.x += 1.0f; ptBottom.x += 1.0f; CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom, - ArgbEncode(nTransparancy, 210, 210, 210), + ArgbEncode(nTransparency, 210, 210, 210), 1.0f); } else { CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw, @@ -496,20 +483,19 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, // draw friction if (rectWnd.Height() > 8.0f) { - FX_COLORREF crStroke = ArgbEncode(nTransparancy, 120, 120, 120); + FX_COLORREF crStroke = ArgbEncode(nTransparency, 120, 120, 120); if (!IsEnabled()) - crStroke = CPWL_Utils::PWLColorToFXColor( - PWL_DEFAULT_HEAVYGRAYCOLOR, 255); + crStroke = PWL_DEFAULT_HEAVYGRAYCOLOR.ToFXColor(255); FX_FLOAT nFrictionWidth = 5.0f; FX_FLOAT nFrictionHeight = 5.5f; - CFX_FloatPoint ptLeft = - CFX_FloatPoint(ptCenter.x - nFrictionWidth / 2.0f, - ptCenter.y - nFrictionHeight / 2.0f + 0.5f); - CFX_FloatPoint ptRight = - CFX_FloatPoint(ptCenter.x + nFrictionWidth / 2.0f, - ptCenter.y - nFrictionHeight / 2.0f + 0.5f); + CFX_PointF ptLeft = + CFX_PointF(ptCenter.x - nFrictionWidth / 2.0f, + ptCenter.y - nFrictionHeight / 2.0f + 0.5f); + CFX_PointF ptRight = + CFX_PointF(ptCenter.x + nFrictionWidth / 2.0f, + ptCenter.y - nFrictionHeight / 2.0f + 0.5f); CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight, crStroke, 1.0f); @@ -536,7 +522,7 @@ void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice, } } -bool CPWL_SBButton::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_SBButton::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); if (CPWL_Wnd* pParent = GetParentWindow()) @@ -548,7 +534,7 @@ bool CPWL_SBButton::OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_SBButton::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_SBButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); if (CPWL_Wnd* pParent = GetParentWindow()) @@ -560,7 +546,7 @@ bool CPWL_SBButton::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { return true; } -bool CPWL_SBButton::OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_SBButton::OnMouseMove(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnMouseMove(point, nFlag); if (CPWL_Wnd* pParent = GetParentWindow()) { @@ -683,20 +669,19 @@ void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice, CPWL_Utils::DrawStrokeLine( pDevice, pUser2Device, - CFX_FloatPoint(rectWnd.left + 2.0f, rectWnd.top - 2.0f), - CFX_FloatPoint(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f), + CFX_PointF(rectWnd.left + 2.0f, rectWnd.top - 2.0f), + CFX_PointF(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f), ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f); CPWL_Utils::DrawStrokeLine( pDevice, pUser2Device, - CFX_FloatPoint(rectWnd.right - 2.0f, rectWnd.top - 2.0f), - CFX_FloatPoint(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f), + CFX_PointF(rectWnd.right - 2.0f, rectWnd.top - 2.0f), + CFX_PointF(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f), ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f); } } -bool CPWL_ScrollBar::OnLButtonDown(const CFX_FloatPoint& point, - uint32_t nFlag) { +bool CPWL_ScrollBar::OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonDown(point, nFlag); if (HasFlag(PWS_AUTOTRANSPARENT)) { @@ -735,13 +720,13 @@ bool CPWL_ScrollBar::OnLButtonDown(const CFX_FloatPoint& point, rcMinArea.Normalize(); rcMaxArea.Normalize(); - if (rcMinArea.Contains(point.x, point.y)) { + if (rcMinArea.Contains(point)) { m_sData.SubBig(); MovePosButton(true); NotifyScrollWindow(); } - if (rcMaxArea.Contains(point.x, point.y)) { + if (rcMaxArea.Contains(point)) { m_sData.AddBig(); MovePosButton(true); NotifyScrollWindow(); @@ -751,12 +736,12 @@ bool CPWL_ScrollBar::OnLButtonDown(const CFX_FloatPoint& point, return true; } -bool CPWL_ScrollBar::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_ScrollBar::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { CPWL_Wnd::OnLButtonUp(point, nFlag); if (HasFlag(PWS_AUTOTRANSPARENT)) { - if (GetTransparency() != PWL_SCROLLBAR_TRANSPARANCY) { - SetTransparency(PWL_SCROLLBAR_TRANSPARANCY); + if (GetTransparency() != PWL_SCROLLBAR_TRANSPARENCY) { + SetTransparency(PWL_SCROLLBAR_TRANSPARENCY); InvalidateRect(); } } @@ -776,41 +761,41 @@ void CPWL_ScrollBar::OnNotify(CPWL_Wnd* pWnd, switch (msg) { case PNM_LBUTTONDOWN: if (pWnd == m_pMinButton) { - OnMinButtonLBDown(*(CFX_FloatPoint*)lParam); + OnMinButtonLBDown(*(CFX_PointF*)lParam); } if (pWnd == m_pMaxButton) { - OnMaxButtonLBDown(*(CFX_FloatPoint*)lParam); + OnMaxButtonLBDown(*(CFX_PointF*)lParam); } if (pWnd == m_pPosButton) { - OnPosButtonLBDown(*(CFX_FloatPoint*)lParam); + OnPosButtonLBDown(*(CFX_PointF*)lParam); } break; case PNM_LBUTTONUP: if (pWnd == m_pMinButton) { - OnMinButtonLBUp(*(CFX_FloatPoint*)lParam); + OnMinButtonLBUp(*(CFX_PointF*)lParam); } if (pWnd == m_pMaxButton) { - OnMaxButtonLBUp(*(CFX_FloatPoint*)lParam); + OnMaxButtonLBUp(*(CFX_PointF*)lParam); } if (pWnd == m_pPosButton) { - OnPosButtonLBUp(*(CFX_FloatPoint*)lParam); + OnPosButtonLBUp(*(CFX_PointF*)lParam); } break; case PNM_MOUSEMOVE: if (pWnd == m_pMinButton) { - OnMinButtonMouseMove(*(CFX_FloatPoint*)lParam); + OnMinButtonMouseMove(*(CFX_PointF*)lParam); } if (pWnd == m_pMaxButton) { - OnMaxButtonMouseMove(*(CFX_FloatPoint*)lParam); + OnMaxButtonMouseMove(*(CFX_PointF*)lParam); } if (pWnd == m_pPosButton) { - OnPosButtonMouseMove(*(CFX_FloatPoint*)lParam); + OnPosButtonMouseMove(*(CFX_PointF*)lParam); } break; case PNM_SETSCROLLINFO: { @@ -954,7 +939,7 @@ void CPWL_ScrollBar::MovePosButton(bool bRefresh) { } } -void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_FloatPoint& point) { +void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_PointF& point) { m_sData.SubSmall(); MovePosButton(true); NotifyScrollWindow(); @@ -965,11 +950,11 @@ void CPWL_ScrollBar::OnMinButtonLBDown(const CFX_FloatPoint& point) { BeginTimer(100); } -void CPWL_ScrollBar::OnMinButtonLBUp(const CFX_FloatPoint& point) {} +void CPWL_ScrollBar::OnMinButtonLBUp(const CFX_PointF& point) {} -void CPWL_ScrollBar::OnMinButtonMouseMove(const CFX_FloatPoint& point) {} +void CPWL_ScrollBar::OnMinButtonMouseMove(const CFX_PointF& point) {} -void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_FloatPoint& point) { +void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_PointF& point) { m_sData.AddSmall(); MovePosButton(true); NotifyScrollWindow(); @@ -980,11 +965,11 @@ void CPWL_ScrollBar::OnMaxButtonLBDown(const CFX_FloatPoint& point) { BeginTimer(100); } -void CPWL_ScrollBar::OnMaxButtonLBUp(const CFX_FloatPoint& point) {} +void CPWL_ScrollBar::OnMaxButtonLBUp(const CFX_PointF& point) {} -void CPWL_ScrollBar::OnMaxButtonMouseMove(const CFX_FloatPoint& point) {} +void CPWL_ScrollBar::OnMaxButtonMouseMove(const CFX_PointF& point) {} -void CPWL_ScrollBar::OnPosButtonLBDown(const CFX_FloatPoint& point) { +void CPWL_ScrollBar::OnPosButtonLBDown(const CFX_PointF& point) { m_bMouseDown = true; if (m_pPosButton) { @@ -1003,7 +988,7 @@ void CPWL_ScrollBar::OnPosButtonLBDown(const CFX_FloatPoint& point) { } } -void CPWL_ScrollBar::OnPosButtonLBUp(const CFX_FloatPoint& point) { +void CPWL_ScrollBar::OnPosButtonLBUp(const CFX_PointF& point) { if (m_bMouseDown) { if (!m_bNotifyForever) NotifyScrollWindow(); @@ -1011,7 +996,7 @@ void CPWL_ScrollBar::OnPosButtonLBUp(const CFX_FloatPoint& point) { m_bMouseDown = false; } -void CPWL_ScrollBar::OnPosButtonMouseMove(const CFX_FloatPoint& point) { +void CPWL_ScrollBar::OnPosButtonMouseMove(const CFX_PointF& point) { FX_FLOAT fOldScrollPos = m_sData.fScrollPos; FX_FLOAT fNewPos = 0; diff --git a/fpdfsdk/pdfwindow/PWL_ScrollBar.h b/fpdfsdk/pdfwindow/PWL_ScrollBar.h index bcfb0a687..9546a9e57 100644 --- a/fpdfsdk/pdfwindow/PWL_ScrollBar.h +++ b/fpdfsdk/pdfwindow/PWL_ScrollBar.h @@ -53,9 +53,9 @@ class CPWL_SBButton : public CPWL_Wnd { void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override; void DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; + bool OnMouseMove(const CFX_PointF& point, uint32_t nFlag) override; protected: PWL_SCROLLBAR_TYPE m_eScrollBarType; @@ -127,8 +127,8 @@ class CPWL_ScrollBar : public CPWL_Wnd { void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) override; void DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device) override; - bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag) override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; void OnNotify(CPWL_Wnd* pWnd, uint32_t msg, intptr_t wParam = 0, @@ -152,17 +152,17 @@ class CPWL_ScrollBar : public CPWL_Wnd { private: void CreateButtons(const PWL_CREATEPARAM& cp); - void OnMinButtonLBDown(const CFX_FloatPoint& point); - void OnMinButtonLBUp(const CFX_FloatPoint& point); - void OnMinButtonMouseMove(const CFX_FloatPoint& point); + void OnMinButtonLBDown(const CFX_PointF& point); + void OnMinButtonLBUp(const CFX_PointF& point); + void OnMinButtonMouseMove(const CFX_PointF& point); - void OnMaxButtonLBDown(const CFX_FloatPoint& point); - void OnMaxButtonLBUp(const CFX_FloatPoint& point); - void OnMaxButtonMouseMove(const CFX_FloatPoint& point); + void OnMaxButtonLBDown(const CFX_PointF& point); + void OnMaxButtonLBUp(const CFX_PointF& point); + void OnMaxButtonMouseMove(const CFX_PointF& point); - void OnPosButtonLBDown(const CFX_FloatPoint& point); - void OnPosButtonLBUp(const CFX_FloatPoint& point); - void OnPosButtonMouseMove(const CFX_FloatPoint& point); + void OnPosButtonLBDown(const CFX_PointF& point); + void OnPosButtonLBUp(const CFX_PointF& point); + void OnPosButtonMouseMove(const CFX_PointF& point); FX_FLOAT TrueToFace(FX_FLOAT); FX_FLOAT FaceToTrue(FX_FLOAT); diff --git a/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp b/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp index defb992c5..1c46c375a 100644 --- a/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp +++ b/fpdfsdk/pdfwindow/PWL_SpecialButton.cpp @@ -37,7 +37,7 @@ bool CPWL_CheckBox::IsChecked() const { return m_bChecked; } -bool CPWL_CheckBox::OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) { +bool CPWL_CheckBox::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { if (IsReadOnly()) return false; @@ -58,8 +58,7 @@ CFX_ByteString CPWL_RadioButton::GetClassName() const { return "CPWL_RadioButton"; } -bool CPWL_RadioButton::OnLButtonUp(const CFX_FloatPoint& point, - uint32_t nFlag) { +bool CPWL_RadioButton::OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) { if (IsReadOnly()) return false; diff --git a/fpdfsdk/pdfwindow/PWL_SpecialButton.h b/fpdfsdk/pdfwindow/PWL_SpecialButton.h index 0aa6c4510..93f611b74 100644 --- a/fpdfsdk/pdfwindow/PWL_SpecialButton.h +++ b/fpdfsdk/pdfwindow/PWL_SpecialButton.h @@ -26,7 +26,7 @@ class CPWL_CheckBox : public CPWL_Button { // CPWL_Button CFX_ByteString GetClassName() const override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; bool OnChar(uint16_t nChar, uint32_t nFlag) override; void SetCheck(bool bCheck); @@ -43,7 +43,7 @@ class CPWL_RadioButton : public CPWL_Button { // CPWL_Button CFX_ByteString GetClassName() const override; - bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag) override; + bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag) override; bool OnChar(uint16_t nChar, uint32_t nFlag) override; void SetCheck(bool bCheck); diff --git a/fpdfsdk/pdfwindow/PWL_Utils.cpp b/fpdfsdk/pdfwindow/PWL_Utils.cpp index 713a193fb..45668b6a2 100644 --- a/fpdfsdk/pdfwindow/PWL_Utils.cpp +++ b/fpdfsdk/pdfwindow/PWL_Utils.cpp @@ -17,71 +17,6 @@ #include "fpdfsdk/pdfwindow/PWL_Icon.h" #include "fpdfsdk/pdfwindow/PWL_Wnd.h" -CFX_ByteString CPWL_Utils::GetAppStreamFromArray(const CPWL_PathData* pPathData, - int32_t nCount) { - CFX_ByteTextBuf csAP; - - for (int32_t i = 0; i < nCount; i++) { - switch (pPathData[i].type) { - case PWLPT_MOVETO: - csAP << pPathData[i].point.x << " " << pPathData[i].point.y << " m\n"; - break; - case PWLPT_LINETO: - csAP << pPathData[i].point.x << " " << pPathData[i].point.y << " l\n"; - break; - case PWLPT_BEZIERTO: - csAP << pPathData[i].point.x << " " << pPathData[i].point.y << " " - << pPathData[i + 1].point.x << " " << pPathData[i + 1].point.y - << " " << pPathData[i + 2].point.x << " " - << pPathData[i + 2].point.y << " c\n"; - - i += 2; - break; - default: - break; - } - } - - return csAP.MakeString(); -} - -void CPWL_Utils::GetPathDataFromArray(CFX_PathData& path, - const CPWL_PathData* pPathData, - int32_t nCount) { - path.SetPointCount(nCount); - - for (int32_t i = 0; i < nCount; i++) { - switch (pPathData[i].type) { - case PWLPT_MOVETO: - path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y, - FXPT_MOVETO); - break; - case PWLPT_LINETO: - path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y, - FXPT_LINETO); - break; - case PWLPT_BEZIERTO: - path.SetPoint(i, pPathData[i].point.x, pPathData[i].point.y, - FXPT_BEZIERTO); - break; - default: - break; - } - } -} - -CFX_FloatRect CPWL_Utils::MaxRect(const CFX_FloatRect& rect1, - const CFX_FloatRect& rect2) { - CFX_FloatRect rcRet; - - rcRet.left = PWL_MIN(rect1.left, rect2.left); - rcRet.bottom = PWL_MIN(rect1.bottom, rect2.bottom); - rcRet.right = PWL_MAX(rect1.right, rect2.right); - rcRet.top = PWL_MAX(rect1.top, rect2.top); - - return rcRet; -} - CFX_FloatRect CPWL_Utils::OffsetRect(const CFX_FloatRect& rect, FX_FLOAT x, FX_FLOAT y) { @@ -89,28 +24,6 @@ CFX_FloatRect CPWL_Utils::OffsetRect(const CFX_FloatRect& rect, rect.top + y); } -bool CPWL_Utils::ContainsRect(const CFX_FloatRect& rcParent, - const CFX_FloatRect& rcChild) { - return rcChild.left >= rcParent.left && rcChild.bottom >= rcParent.bottom && - rcChild.right <= rcParent.right && rcChild.top <= rcParent.top; -} - -bool CPWL_Utils::IntersectRect(const CFX_FloatRect& rect1, - const CFX_FloatRect& rect2) { - FX_FLOAT left = rect1.left > rect2.left ? rect1.left : rect2.left; - FX_FLOAT right = rect1.right < rect2.right ? rect1.right : rect2.right; - FX_FLOAT bottom = rect1.bottom > rect2.bottom ? rect1.bottom : rect2.bottom; - FX_FLOAT top = rect1.top < rect2.top ? rect1.top : rect2.top; - - return left < right && bottom < top; -} - -CFX_FloatPoint CPWL_Utils::OffsetPoint(const CFX_FloatPoint& point, - FX_FLOAT x, - FX_FLOAT y) { - return CFX_FloatPoint(point.x + x, point.y + y); -} - CPVT_WordRange CPWL_Utils::OverlapWordRange(const CPVT_WordRange& wr1, const CPVT_WordRange& wr2) { CPVT_WordRange wrRet; @@ -141,22 +54,22 @@ CFX_ByteString CPWL_Utils::GetAP_Check(const CFX_FloatRect& crBBox) { const FX_FLOAT fWidth = crBBox.right - crBBox.left; const FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - CPWL_Point pts[8][3] = {{CPWL_Point(0.28f, 0.52f), CPWL_Point(0.27f, 0.48f), - CPWL_Point(0.29f, 0.40f)}, - {CPWL_Point(0.30f, 0.33f), CPWL_Point(0.31f, 0.29f), - CPWL_Point(0.31f, 0.28f)}, - {CPWL_Point(0.39f, 0.28f), CPWL_Point(0.49f, 0.29f), - CPWL_Point(0.77f, 0.67f)}, - {CPWL_Point(0.76f, 0.68f), CPWL_Point(0.78f, 0.69f), - CPWL_Point(0.76f, 0.75f)}, - {CPWL_Point(0.76f, 0.75f), CPWL_Point(0.73f, 0.80f), - CPWL_Point(0.68f, 0.75f)}, - {CPWL_Point(0.68f, 0.74f), CPWL_Point(0.68f, 0.74f), - CPWL_Point(0.44f, 0.47f)}, - {CPWL_Point(0.43f, 0.47f), CPWL_Point(0.40f, 0.47f), - CPWL_Point(0.41f, 0.58f)}, - {CPWL_Point(0.40f, 0.60f), CPWL_Point(0.28f, 0.66f), - CPWL_Point(0.30f, 0.56f)}}; + CFX_PointF pts[8][3] = {{CFX_PointF(0.28f, 0.52f), CFX_PointF(0.27f, 0.48f), + CFX_PointF(0.29f, 0.40f)}, + {CFX_PointF(0.30f, 0.33f), CFX_PointF(0.31f, 0.29f), + CFX_PointF(0.31f, 0.28f)}, + {CFX_PointF(0.39f, 0.28f), CFX_PointF(0.49f, 0.29f), + CFX_PointF(0.77f, 0.67f)}, + {CFX_PointF(0.76f, 0.68f), CFX_PointF(0.78f, 0.69f), + CFX_PointF(0.76f, 0.75f)}, + {CFX_PointF(0.76f, 0.75f), CFX_PointF(0.73f, 0.80f), + CFX_PointF(0.68f, 0.75f)}, + {CFX_PointF(0.68f, 0.74f), CFX_PointF(0.68f, 0.74f), + CFX_PointF(0.44f, 0.47f)}, + {CFX_PointF(0.43f, 0.47f), CFX_PointF(0.40f, 0.47f), + CFX_PointF(0.41f, 0.58f)}, + {CFX_PointF(0.40f, 0.60f), CFX_PointF(0.28f, 0.66f), + CFX_PointF(0.30f, 0.56f)}}; for (size_t i = 0; i < FX_ArraySize(pts); ++i) { for (size_t j = 0; j < FX_ArraySize(pts[0]); ++j) { @@ -192,10 +105,10 @@ CFX_ByteString CPWL_Utils::GetAP_Circle(const CFX_FloatRect& crBBox) { FX_FLOAT fWidth = crBBox.right - crBBox.left; FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - CFX_FloatPoint pt1(crBBox.left, crBBox.bottom + fHeight / 2); - CFX_FloatPoint pt2(crBBox.left + fWidth / 2, crBBox.top); - CFX_FloatPoint pt3(crBBox.right, crBBox.bottom + fHeight / 2); - CFX_FloatPoint pt4(crBBox.left + fWidth / 2, crBBox.bottom); + CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2); + CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top); + CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2); + CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom); csAP << pt1.x << " " << pt1.y << " m\n"; @@ -245,10 +158,10 @@ CFX_ByteString CPWL_Utils::GetAP_Diamond(const CFX_FloatRect& crBBox) { FX_FLOAT fWidth = crBBox.right - crBBox.left; FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - CFX_FloatPoint pt1(crBBox.left, crBBox.bottom + fHeight / 2); - CFX_FloatPoint pt2(crBBox.left + fWidth / 2, crBBox.top); - CFX_FloatPoint pt3(crBBox.right, crBBox.bottom + fHeight / 2); - CFX_FloatPoint pt4(crBBox.left + fWidth / 2, crBBox.bottom); + CFX_PointF pt1(crBBox.left, crBBox.bottom + fHeight / 2); + CFX_PointF pt2(crBBox.left + fWidth / 2, crBBox.top); + CFX_PointF pt3(crBBox.right, crBBox.bottom + fHeight / 2); + CFX_PointF pt4(crBBox.left + fWidth / 2, crBBox.bottom); csAP << pt1.x << " " << pt1.y << " m\n"; csAP << pt2.x << " " << pt2.y << " l\n"; @@ -276,8 +189,8 @@ CFX_ByteString CPWL_Utils::GetAP_Star(const CFX_FloatRect& crBBox) { FX_FLOAT fRadius = (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(FX_PI / 5.0f)); - CFX_FloatPoint ptCenter = CFX_FloatPoint((crBBox.left + crBBox.right) / 2.0f, - (crBBox.top + crBBox.bottom) / 2.0f); + CFX_PointF ptCenter = CFX_PointF((crBBox.left + crBBox.right) / 2.0f, + (crBBox.top + crBBox.bottom) / 2.0f); FX_FLOAT px[5], py[5]; @@ -310,9 +223,9 @@ CFX_ByteString CPWL_Utils::GetAP_HalfCircle(const CFX_FloatRect& crBBox, FX_FLOAT fWidth = crBBox.right - crBBox.left; FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - CFX_FloatPoint pt1(-fWidth / 2, 0); - CFX_FloatPoint pt2(0, fHeight / 2); - CFX_FloatPoint pt3(fWidth / 2, 0); + CFX_PointF pt1(-fWidth / 2, 0); + CFX_PointF pt2(0, fHeight / 2); + CFX_PointF pt3(fWidth / 2, 0); FX_FLOAT px, py; @@ -365,8 +278,8 @@ CFX_FloatRect CPWL_Utils::ScaleRect(const CFX_FloatRect& rcRect, FX_FLOAT fHalfWidth = (rcRect.right - rcRect.left) / 2.0f; FX_FLOAT fHalfHeight = (rcRect.top - rcRect.bottom) / 2.0f; - CFX_FloatPoint ptCenter = CFX_FloatPoint((rcRect.left + rcRect.right) / 2, - (rcRect.top + rcRect.bottom) / 2); + CFX_PointF ptCenter = CFX_PointF((rcRect.left + rcRect.right) / 2, + (rcRect.top + rcRect.bottom) / 2); return CFX_FloatRect( ptCenter.x - fHalfWidth * fScale, ptCenter.y - fHalfHeight * fScale, @@ -411,7 +324,7 @@ CFX_FloatRect CPWL_Utils::GetCenterSquare(const CFX_FloatRect& rect) { } CFX_ByteString CPWL_Utils::GetEditAppStream(CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange, bool bContinuous, uint16_t SubWord) { @@ -420,45 +333,11 @@ CFX_ByteString CPWL_Utils::GetEditAppStream(CFX_Edit* pEdit, } CFX_ByteString CPWL_Utils::GetEditSelAppStream(CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange) { return CFX_Edit::GetSelectAppearanceStream(pEdit, ptOffset, pRange); } -CFX_ByteString CPWL_Utils::GetTextAppStream(const CFX_FloatRect& rcBBox, - IPVT_FontMap* pFontMap, - const CFX_WideString& sText, - int32_t nAlignmentH, - int32_t nAlignmentV, - FX_FLOAT fFontSize, - bool bMultiLine, - bool bAutoReturn, - const CPWL_Color& crText) { - CFX_ByteTextBuf sRet; - - std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit); - pEdit->SetFontMap(pFontMap); - pEdit->SetPlateRect(rcBBox); - pEdit->SetAlignmentH(nAlignmentH, true); - pEdit->SetAlignmentV(nAlignmentV, true); - pEdit->SetMultiLine(bMultiLine, true); - pEdit->SetAutoReturn(bAutoReturn, true); - if (IsFloatZero(fFontSize)) - pEdit->SetAutoFontSize(true, true); - else - pEdit->SetFontSize(fFontSize); - - pEdit->Initialize(); - pEdit->SetText(sText); - - CFX_ByteString sEdit = - CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f)); - if (sEdit.GetLength() > 0) - sRet << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"; - - return sRet.MakeString(); -} - CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CFX_FloatRect& rcBBox, IPVT_FontMap* pFontMap, CPDF_Stream* pIconStream, @@ -664,7 +543,7 @@ CFX_ByteString CPWL_Utils::GetPushButtonAppStream(const CFX_FloatRect& rcBBox, if (!rcLabel.IsEmpty()) { pEdit->SetPlateRect(rcLabel); CFX_ByteString sEdit = - CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_FloatPoint(0.0f, 0.0f)); + CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, 0.0f)); if (sEdit.GetLength() > 0) { sTemp << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"; @@ -920,57 +799,6 @@ CFX_ByteString CPWL_Utils::GetCircleBorderAppStream( return sAppStream.MakeString(); } -CPWL_Color CPWL_Utils::SubstractColor(const CPWL_Color& sColor, - FX_FLOAT fColorSub) { - CPWL_Color sRet; - sRet.nColorType = sColor.nColorType; - - switch (sColor.nColorType) { - case COLORTYPE_TRANSPARENT: - sRet.nColorType = COLORTYPE_RGB; - sRet.fColor1 = PWL_MAX(1 - fColorSub, 0.0f); - sRet.fColor2 = PWL_MAX(1 - fColorSub, 0.0f); - sRet.fColor3 = PWL_MAX(1 - fColorSub, 0.0f); - break; - case COLORTYPE_RGB: - case COLORTYPE_GRAY: - case COLORTYPE_CMYK: - sRet.fColor1 = PWL_MAX(sColor.fColor1 - fColorSub, 0.0f); - sRet.fColor2 = PWL_MAX(sColor.fColor2 - fColorSub, 0.0f); - sRet.fColor3 = PWL_MAX(sColor.fColor3 - fColorSub, 0.0f); - sRet.fColor4 = PWL_MAX(sColor.fColor4 - fColorSub, 0.0f); - break; - } - - return sRet; -} - -CPWL_Color CPWL_Utils::DevideColor(const CPWL_Color& sColor, - FX_FLOAT fColorDevide) { - CPWL_Color sRet; - sRet.nColorType = sColor.nColorType; - - switch (sColor.nColorType) { - case COLORTYPE_TRANSPARENT: - sRet.nColorType = COLORTYPE_RGB; - sRet.fColor1 = 1 / fColorDevide; - sRet.fColor2 = 1 / fColorDevide; - sRet.fColor3 = 1 / fColorDevide; - break; - case COLORTYPE_RGB: - case COLORTYPE_GRAY: - case COLORTYPE_CMYK: - sRet = sColor; - sRet.fColor1 /= fColorDevide; - sRet.fColor2 /= fColorDevide; - sRet.fColor3 /= fColorDevide; - sRet.fColor4 /= fColorDevide; - break; - } - - return sRet; -} - CFX_ByteString CPWL_Utils::GetAppStream_Check(const CFX_FloatRect& rcBBox, const CPWL_Color& crText) { CFX_ByteTextBuf sAP; @@ -1089,8 +917,8 @@ CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CFX_FloatRect& rcBBox) { CPWL_Dash(3, 0, 0)) << "Q\n"; - CFX_FloatPoint ptCenter = CFX_FloatPoint((rcBBox.left + rcBBox.right) / 2, - (rcBBox.top + rcBBox.bottom) / 2); + CFX_PointF ptCenter = CFX_PointF((rcBBox.left + rcBBox.right) / 2, + (rcBBox.top + rcBBox.bottom) / 2); if (IsFloatBigger(rcBBox.right - rcBBox.left, 6) && IsFloatBigger(rcBBox.top - rcBBox.bottom, 6)) { sAppStream << "q\n" @@ -1106,118 +934,6 @@ CFX_ByteString CPWL_Utils::GetDropButtonAppStream(const CFX_FloatRect& rcBBox) { return sAppStream.MakeString(); } -void CPWL_Utils::ConvertCMYK2GRAY(FX_FLOAT dC, - FX_FLOAT dM, - FX_FLOAT dY, - FX_FLOAT dK, - FX_FLOAT& dGray) { - if (dC < 0 || dC > 1 || dM < 0 || dM > 1 || dY < 0 || dY > 1 || dK < 0 || - dK > 1) - return; - dGray = 1.0f - std::min(1.0f, 0.3f * dC + 0.59f * dM + 0.11f * dY + dK); -} - -void CPWL_Utils::ConvertGRAY2CMYK(FX_FLOAT dGray, - FX_FLOAT& dC, - FX_FLOAT& dM, - FX_FLOAT& dY, - FX_FLOAT& dK) { - if (dGray < 0 || dGray > 1) - return; - dC = 0.0f; - dM = 0.0f; - dY = 0.0f; - dK = 1.0f - dGray; -} - -void CPWL_Utils::ConvertGRAY2RGB(FX_FLOAT dGray, - FX_FLOAT& dR, - FX_FLOAT& dG, - FX_FLOAT& dB) { - if (dGray < 0 || dGray > 1) - return; - dR = dGray; - dG = dGray; - dB = dGray; -} - -void CPWL_Utils::ConvertRGB2GRAY(FX_FLOAT dR, - FX_FLOAT dG, - FX_FLOAT dB, - FX_FLOAT& dGray) { - if (dR < 0 || dR > 1 || dG < 0 || dG > 0 || dB < 0 || dB > 1) - return; - dGray = 0.3f * dR + 0.59f * dG + 0.11f * dB; -} - -void CPWL_Utils::ConvertCMYK2RGB(FX_FLOAT dC, - FX_FLOAT dM, - FX_FLOAT dY, - FX_FLOAT dK, - FX_FLOAT& dR, - FX_FLOAT& dG, - FX_FLOAT& dB) { - if (dC < 0 || dC > 1 || dM < 0 || dM > 1 || dY < 0 || dY > 1 || dK < 0 || - dK > 1) - return; - dR = 1.0f - std::min(1.0f, dC + dK); - dG = 1.0f - std::min(1.0f, dM + dK); - dB = 1.0f - std::min(1.0f, dY + dK); -} - -void CPWL_Utils::ConvertRGB2CMYK(FX_FLOAT dR, - FX_FLOAT dG, - FX_FLOAT dB, - FX_FLOAT& dC, - FX_FLOAT& dM, - FX_FLOAT& dY, - FX_FLOAT& dK) { - if (dR < 0 || dR > 1 || dG < 0 || dG > 1 || dB < 0 || dB > 1) - return; - - dC = 1.0f - dR; - dM = 1.0f - dG; - dY = 1.0f - dB; - dK = std::min(dC, std::min(dM, dY)); -} - -void CPWL_Utils::PWLColorToARGB(const CPWL_Color& color, - int32_t& alpha, - FX_FLOAT& red, - FX_FLOAT& green, - FX_FLOAT& blue) { - switch (color.nColorType) { - case COLORTYPE_TRANSPARENT: { - alpha = 0; - } break; - case COLORTYPE_GRAY: { - ConvertGRAY2RGB(color.fColor1, red, green, blue); - } break; - case COLORTYPE_RGB: { - red = color.fColor1; - green = color.fColor2; - blue = color.fColor3; - } break; - case COLORTYPE_CMYK: { - ConvertCMYK2RGB(color.fColor1, color.fColor2, color.fColor3, - color.fColor4, red, green, blue); - } break; - } -} - -FX_COLORREF CPWL_Utils::PWLColorToFXColor(const CPWL_Color& color, - int32_t nTransparancy) { - int32_t nAlpha = nTransparancy; - FX_FLOAT dRed = 0; - FX_FLOAT dGreen = 0; - FX_FLOAT dBlue = 0; - - PWLColorToARGB(color, nAlpha, dRed, dGreen, dBlue); - - return ArgbEncode(nAlpha, (int32_t)(dRed * 255), (int32_t)(dGreen * 255), - (int32_t)(dBlue * 255)); -} - void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, const CFX_FloatRect& rect, @@ -1230,15 +946,13 @@ void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice, void CPWL_Utils::DrawFillArea(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, - const CFX_FloatPoint* pPts, + const CFX_PointF* pPts, int32_t nCount, const FX_COLORREF& color) { CFX_PathData path; - path.SetPointCount(nCount); - - path.SetPoint(0, pPts[0].x, pPts[0].y, FXPT_MOVETO); + path.AppendPoint(pPts[0], FXPT_TYPE::MoveTo, false); for (int32_t i = 1; i < nCount; i++) - path.SetPoint(i, pPts[i].x, pPts[i].y, FXPT_LINETO); + path.AppendPoint(pPts[i], FXPT_TYPE::LineTo, false); pDevice->DrawPath(&path, pUser2Device, nullptr, color, 0, FXFILL_ALTERNATE); } @@ -1260,14 +974,13 @@ void CPWL_Utils::DrawStrokeRect(CFX_RenderDevice* pDevice, void CPWL_Utils::DrawStrokeLine(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, - const CFX_FloatPoint& ptMoveTo, - const CFX_FloatPoint& ptLineTo, + const CFX_PointF& ptMoveTo, + const CFX_PointF& ptLineTo, const FX_COLORREF& color, FX_FLOAT fWidth) { CFX_PathData path; - path.SetPointCount(2); - path.SetPoint(0, ptMoveTo.x, ptMoveTo.y, FXPT_MOVETO); - path.SetPoint(1, ptLineTo.x, ptLineTo.y, FXPT_LINETO); + path.AppendPoint(ptMoveTo, FXPT_TYPE::MoveTo, false); + path.AppendPoint(ptLineTo, FXPT_TYPE::LineTo, false); CFX_GraphStateData gsd; gsd.m_LineWidth = fWidth; @@ -1279,9 +992,9 @@ void CPWL_Utils::DrawFillRect(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, const CFX_FloatRect& rect, const CPWL_Color& color, - int32_t nTransparancy) { + int32_t nTransparency) { CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rect, - PWLColorToFXColor(color, nTransparancy)); + color.ToFXColor(nTransparency)); } void CPWL_Utils::DrawShadow(CFX_RenderDevice* pDevice, @@ -1289,7 +1002,7 @@ void CPWL_Utils::DrawShadow(CFX_RenderDevice* pDevice, bool bVertical, bool bHorizontal, CFX_FloatRect rect, - int32_t nTransparancy, + int32_t nTransparency, int32_t nStartGray, int32_t nEndGray) { FX_FLOAT fStepGray = 1.0f; @@ -1300,9 +1013,9 @@ void CPWL_Utils::DrawShadow(CFX_RenderDevice* pDevice, for (FX_FLOAT fy = rect.bottom + 0.5f; fy <= rect.top - 0.5f; fy += 1.0f) { int32_t nGray = nStartGray + (int32_t)(fStepGray * (fy - rect.bottom)); CPWL_Utils::DrawStrokeLine( - pDevice, pUser2Device, CFX_FloatPoint(rect.left, fy), - CFX_FloatPoint(rect.right, fy), - ArgbEncode(nTransparancy, nGray, nGray, nGray), 1.5f); + pDevice, pUser2Device, CFX_PointF(rect.left, fy), + CFX_PointF(rect.right, fy), + ArgbEncode(nTransparency, nGray, nGray, nGray), 1.5f); } } @@ -1312,9 +1025,9 @@ void CPWL_Utils::DrawShadow(CFX_RenderDevice* pDevice, for (FX_FLOAT fx = rect.left + 0.5f; fx <= rect.right - 0.5f; fx += 1.0f) { int32_t nGray = nStartGray + (int32_t)(fStepGray * (fx - rect.left)); CPWL_Utils::DrawStrokeLine( - pDevice, pUser2Device, CFX_FloatPoint(fx, rect.bottom), - CFX_FloatPoint(fx, rect.top), - ArgbEncode(nTransparancy, nGray, nGray, nGray), 1.5f); + pDevice, pUser2Device, CFX_PointF(fx, rect.bottom), + CFX_PointF(fx, rect.top), + ArgbEncode(nTransparency, nGray, nGray, nGray), 1.5f); } } } @@ -1327,7 +1040,7 @@ void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice, const CPWL_Color& crLeftTop, const CPWL_Color& crRightBottom, BorderStyle nStyle, - int32_t nTransparancy) { + int32_t nTransparency) { FX_FLOAT fLeft = rect.left; FX_FLOAT fRight = rect.right; FX_FLOAT fTop = rect.top; @@ -1344,24 +1057,26 @@ void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice, path.AppendRect(fLeft + fWidth, fBottom + fWidth, fRight - fWidth, fTop - fWidth); pDevice->DrawPath(&path, pUser2Device, nullptr, - PWLColorToFXColor(color, nTransparancy), 0, - FXFILL_ALTERNATE); + color.ToFXColor(nTransparency), 0, FXFILL_ALTERNATE); break; } case BorderStyle::DASH: { CFX_PathData path; - - path.SetPointCount(5); - path.SetPoint(0, fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f, - FXPT_MOVETO); - path.SetPoint(1, fLeft + fWidth / 2.0f, fTop - fWidth / 2.0f, - FXPT_LINETO); - path.SetPoint(2, fRight - fWidth / 2.0f, fTop - fWidth / 2.0f, - FXPT_LINETO); - path.SetPoint(3, fRight - fWidth / 2.0f, fBottom + fWidth / 2.0f, - FXPT_LINETO); - path.SetPoint(4, fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f, - FXPT_LINETO); + path.AppendPoint( + CFX_PointF(fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f), + FXPT_TYPE::MoveTo, false); + path.AppendPoint( + CFX_PointF(fLeft + fWidth / 2.0f, fTop - fWidth / 2.0f), + FXPT_TYPE::LineTo, false); + path.AppendPoint( + CFX_PointF(fRight - fWidth / 2.0f, fTop - fWidth / 2.0f), + FXPT_TYPE::LineTo, false); + path.AppendPoint( + CFX_PointF(fRight - fWidth / 2.0f, fBottom + fWidth / 2.0f), + FXPT_TYPE::LineTo, false); + path.AppendPoint( + CFX_PointF(fLeft + fWidth / 2.0f, fBottom + fWidth / 2.0f), + FXPT_TYPE::LineTo, false); CFX_GraphStateData gsd; gsd.SetDashCount(2); @@ -1371,8 +1086,7 @@ void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice, gsd.m_LineWidth = fWidth; pDevice->DrawPath(&path, pUser2Device, &gsd, 0, - PWLColorToFXColor(color, nTransparancy), - FXFILL_WINDING); + color.ToFXColor(nTransparency), FXFILL_WINDING); break; } case BorderStyle::BEVELED: @@ -1382,42 +1096,50 @@ void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice, CFX_PathData pathLT; - pathLT.SetPointCount(7); - pathLT.SetPoint(0, fLeft + fHalfWidth, fBottom + fHalfWidth, - FXPT_MOVETO); - pathLT.SetPoint(1, fLeft + fHalfWidth, fTop - fHalfWidth, FXPT_LINETO); - pathLT.SetPoint(2, fRight - fHalfWidth, fTop - fHalfWidth, FXPT_LINETO); - pathLT.SetPoint(3, fRight - fHalfWidth * 2, fTop - fHalfWidth * 2, - FXPT_LINETO); - pathLT.SetPoint(4, fLeft + fHalfWidth * 2, fTop - fHalfWidth * 2, - FXPT_LINETO); - pathLT.SetPoint(5, fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2, - FXPT_LINETO); - pathLT.SetPoint(6, fLeft + fHalfWidth, fBottom + fHalfWidth, - FXPT_LINETO); + pathLT.AppendPoint(CFX_PointF(fLeft + fHalfWidth, fBottom + fHalfWidth), + FXPT_TYPE::MoveTo, false); + pathLT.AppendPoint(CFX_PointF(fLeft + fHalfWidth, fTop - fHalfWidth), + FXPT_TYPE::LineTo, false); + pathLT.AppendPoint(CFX_PointF(fRight - fHalfWidth, fTop - fHalfWidth), + FXPT_TYPE::LineTo, false); + pathLT.AppendPoint( + CFX_PointF(fRight - fHalfWidth * 2, fTop - fHalfWidth * 2), + FXPT_TYPE::LineTo, false); + pathLT.AppendPoint( + CFX_PointF(fLeft + fHalfWidth * 2, fTop - fHalfWidth * 2), + FXPT_TYPE::LineTo, false); + pathLT.AppendPoint( + CFX_PointF(fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2), + FXPT_TYPE::LineTo, false); + pathLT.AppendPoint(CFX_PointF(fLeft + fHalfWidth, fBottom + fHalfWidth), + FXPT_TYPE::LineTo, false); pDevice->DrawPath(&pathLT, pUser2Device, &gsd, - PWLColorToFXColor(crLeftTop, nTransparancy), 0, + crLeftTop.ToFXColor(nTransparency), 0, FXFILL_ALTERNATE); CFX_PathData pathRB; - - pathRB.SetPointCount(7); - pathRB.SetPoint(0, fRight - fHalfWidth, fTop - fHalfWidth, FXPT_MOVETO); - pathRB.SetPoint(1, fRight - fHalfWidth, fBottom + fHalfWidth, - FXPT_LINETO); - pathRB.SetPoint(2, fLeft + fHalfWidth, fBottom + fHalfWidth, - FXPT_LINETO); - pathRB.SetPoint(3, fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2, - FXPT_LINETO); - pathRB.SetPoint(4, fRight - fHalfWidth * 2, fBottom + fHalfWidth * 2, - FXPT_LINETO); - pathRB.SetPoint(5, fRight - fHalfWidth * 2, fTop - fHalfWidth * 2, - FXPT_LINETO); - pathRB.SetPoint(6, fRight - fHalfWidth, fTop - fHalfWidth, FXPT_LINETO); + pathRB.AppendPoint(CFX_PointF(fRight - fHalfWidth, fTop - fHalfWidth), + FXPT_TYPE::MoveTo, false); + pathRB.AppendPoint( + CFX_PointF(fRight - fHalfWidth, fBottom + fHalfWidth), + FXPT_TYPE::LineTo, false); + pathRB.AppendPoint(CFX_PointF(fLeft + fHalfWidth, fBottom + fHalfWidth), + FXPT_TYPE::LineTo, false); + pathRB.AppendPoint( + CFX_PointF(fLeft + fHalfWidth * 2, fBottom + fHalfWidth * 2), + FXPT_TYPE::LineTo, false); + pathRB.AppendPoint( + CFX_PointF(fRight - fHalfWidth * 2, fBottom + fHalfWidth * 2), + FXPT_TYPE::LineTo, false); + pathRB.AppendPoint( + CFX_PointF(fRight - fHalfWidth * 2, fTop - fHalfWidth * 2), + FXPT_TYPE::LineTo, false); + pathRB.AppendPoint(CFX_PointF(fRight - fHalfWidth, fTop - fHalfWidth), + FXPT_TYPE::LineTo, false); pDevice->DrawPath(&pathRB, pUser2Device, &gsd, - PWLColorToFXColor(crRightBottom, nTransparancy), 0, + crRightBottom.ToFXColor(nTransparency), 0, FXFILL_ALTERNATE); CFX_PathData path; @@ -1427,1936 +1149,24 @@ void CPWL_Utils::DrawBorder(CFX_RenderDevice* pDevice, fRight - fHalfWidth, fTop - fHalfWidth); pDevice->DrawPath(&path, pUser2Device, &gsd, - PWLColorToFXColor(color, nTransparancy), 0, - FXFILL_ALTERNATE); + color.ToFXColor(nTransparency), 0, FXFILL_ALTERNATE); break; } case BorderStyle::UNDERLINE: { CFX_PathData path; - - path.SetPointCount(2); - path.SetPoint(0, fLeft, fBottom + fWidth / 2, FXPT_MOVETO); - path.SetPoint(1, fRight, fBottom + fWidth / 2, FXPT_LINETO); + path.AppendPoint(CFX_PointF(fLeft, fBottom + fWidth / 2), + FXPT_TYPE::MoveTo, false); + path.AppendPoint(CFX_PointF(fRight, fBottom + fWidth / 2), + FXPT_TYPE::LineTo, false); CFX_GraphStateData gsd; gsd.m_LineWidth = fWidth; pDevice->DrawPath(&path, pUser2Device, &gsd, 0, - PWLColorToFXColor(color, nTransparancy), - FXFILL_ALTERNATE); + color.ToFXColor(nTransparency), FXFILL_ALTERNATE); break; } } } } -bool CPWL_Utils::IsBlackOrWhite(const CPWL_Color& color) { - switch (color.nColorType) { - case COLORTYPE_TRANSPARENT: - return false; - case COLORTYPE_GRAY: - return color.fColor1 < 0.5f; - case COLORTYPE_RGB: - return color.fColor1 + color.fColor2 + color.fColor3 < 1.5f; - case COLORTYPE_CMYK: - return color.fColor1 + color.fColor2 + color.fColor3 + color.fColor4 > - 2.0f; - } - - return true; -} - -CPWL_Color CPWL_Utils::GetReverseColor(const CPWL_Color& color) { - CPWL_Color crRet = color; - - switch (color.nColorType) { - case COLORTYPE_GRAY: - crRet.fColor1 = 1.0f - crRet.fColor1; - break; - case COLORTYPE_RGB: - crRet.fColor1 = 1.0f - crRet.fColor1; - crRet.fColor2 = 1.0f - crRet.fColor2; - crRet.fColor3 = 1.0f - crRet.fColor3; - break; - case COLORTYPE_CMYK: - crRet.fColor1 = 1.0f - crRet.fColor1; - crRet.fColor2 = 1.0f - crRet.fColor2; - crRet.fColor3 = 1.0f - crRet.fColor3; - crRet.fColor4 = 1.0f - crRet.fColor4; - break; - } - - return crRet; -} - -CFX_ByteString CPWL_Utils::GetIconAppStream(int32_t nType, - const CFX_FloatRect& rect, - const CPWL_Color& crFill, - const CPWL_Color& crStroke) { - CFX_ByteString sAppStream = CPWL_Utils::GetColorAppStream(crStroke, false); - sAppStream += CPWL_Utils::GetColorAppStream(crFill, true); - - CFX_ByteString sPath; - CFX_PathData path; - - switch (nType) { - case PWL_ICONTYPE_CHECKMARK: - GetGraphics_Checkmark(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_CIRCLE: - GetGraphics_Circle(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_COMMENT: - GetGraphics_Comment(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_CROSS: - GetGraphics_Cross(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_HELP: - GetGraphics_Help(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_INSERTTEXT: - GetGraphics_InsertText(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_KEY: - GetGraphics_Key(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_NEWPARAGRAPH: - GetGraphics_NewParagraph(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_TEXTNOTE: - GetGraphics_TextNote(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_PARAGRAPH: - GetGraphics_Paragraph(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_RIGHTARROW: - GetGraphics_RightArrow(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_RIGHTPOINTER: - GetGraphics_RightPointer(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_STAR: - GetGraphics_Star(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_UPARROW: - GetGraphics_UpArrow(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_UPLEFTARROW: - GetGraphics_UpLeftArrow(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_GRAPH: - GetGraphics_Graph(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_PAPERCLIP: - GetGraphics_Paperclip(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_ATTACHMENT: - GetGraphics_Attachment(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_TAG: - GetGraphics_Tag(sPath, path, rect, PWLPT_STREAM); - break; - case PWL_ICONTYPE_FOXIT: - GetGraphics_Foxit(sPath, path, rect, PWLPT_STREAM); - break; - } - - sAppStream += sPath; - if (crStroke.nColorType != COLORTYPE_TRANSPARENT) - sAppStream += "B*\n"; - else - sAppStream += "f*\n"; - - return sAppStream; -} - -void CPWL_Utils::DrawIconAppStream(CFX_RenderDevice* pDevice, - CFX_Matrix* pUser2Device, - int32_t nType, - const CFX_FloatRect& rect, - const CPWL_Color& crFill, - const CPWL_Color& crStroke, - const int32_t nTransparancy) { - CFX_GraphStateData gsd; - gsd.m_LineWidth = 1.0f; - - CFX_ByteString sPath; - CFX_PathData path; - - switch (nType) { - case PWL_ICONTYPE_CHECKMARK: - GetGraphics_Checkmark(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_CIRCLE: - GetGraphics_Circle(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_COMMENT: - GetGraphics_Comment(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_CROSS: - GetGraphics_Cross(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_HELP: - GetGraphics_Help(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_INSERTTEXT: - GetGraphics_InsertText(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_KEY: - GetGraphics_Key(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_NEWPARAGRAPH: - GetGraphics_NewParagraph(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_TEXTNOTE: - GetGraphics_TextNote(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_PARAGRAPH: - GetGraphics_Paragraph(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_RIGHTARROW: - GetGraphics_RightArrow(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_RIGHTPOINTER: - GetGraphics_RightPointer(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_STAR: - GetGraphics_Star(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_UPARROW: - GetGraphics_UpArrow(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_UPLEFTARROW: - GetGraphics_UpLeftArrow(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_GRAPH: - GetGraphics_Graph(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_PAPERCLIP: - GetGraphics_Paperclip(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_ATTACHMENT: - GetGraphics_Attachment(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_TAG: - GetGraphics_Tag(sPath, path, rect, PWLPT_PATHDATA); - break; - case PWL_ICONTYPE_FOXIT: - GetGraphics_Foxit(sPath, path, rect, PWLPT_PATHDATA); - break; - default: - return; - } - - pDevice->DrawPath( - &path, pUser2Device, &gsd, PWLColorToFXColor(crFill, nTransparancy), - PWLColorToFXColor(crStroke, nTransparancy), FXFILL_ALTERNATE); -} - -void CPWL_Utils::GetGraphics_Checkmark(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight * 2 / 5.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 15.0f + - FX_BEZIER * (fWidth / 7.0f - fWidth / 15.0f), - crBBox.bottom + fHeight * 2 / 5.0f + - FX_BEZIER * (fHeight * 2 / 7.0f - fHeight * 2 / 5.0f)), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 4.5f + - FX_BEZIER * (fWidth / 5.0f - fWidth / 4.5f), - crBBox.bottom + fHeight / 16.0f + - FX_BEZIER * (fHeight / 5.0f - fHeight / 16.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 4.5f, - crBBox.bottom + fHeight / 16.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 4.5f + - FX_BEZIER * (fWidth / 4.4f - fWidth / 4.5f), - crBBox.bottom + fHeight / 16.0f - - FX_BEZIER * fHeight / 16.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f + - FX_BEZIER * (fWidth / 4.0f - fWidth / 3.0f), - crBBox.bottom), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f, crBBox.bottom), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.0f + - FX_BEZIER * fWidth * (1 / 7.0f + 2 / 15.0f), - crBBox.bottom + FX_BEZIER * fHeight * 4 / 5.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 14 / 15.0f + - FX_BEZIER * fWidth * (1 / 7.0f - 7 / 15.0f), - crBBox.bottom + fHeight * 15 / 16.0f + - FX_BEZIER * (fHeight * 4 / 5.0f - - fHeight * 15 / 16.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 14 / 15.0f, - crBBox.bottom + fHeight * 15 / 16.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point( - crBBox.left + fWidth * 14 / 15.0f + - FX_BEZIER * (fWidth * 7 / 15.0f - fWidth * 14 / 15.0f), - crBBox.bottom + fHeight * 15 / 16.0f + - FX_BEZIER * (fHeight * 8 / 7.0f - fHeight * 15 / 16.0f)), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 3.6f + - FX_BEZIER * (fWidth / 3.4f - fWidth / 3.6f), - crBBox.bottom + fHeight / 3.5f + - FX_BEZIER * (fHeight / 3.5f - fHeight / 3.5f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 3.6f, - crBBox.bottom + fHeight / 3.5f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 3.6f, - crBBox.bottom + fHeight / 3.5f + - FX_BEZIER * (fHeight / 4.0f - fHeight / 3.5f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f + - FX_BEZIER * (fWidth / 3.5f - fWidth / 15.0f), - crBBox.bottom + fHeight * 2 / 5.0f + - FX_BEZIER * (fHeight * 3.5f / 5.0f - - fHeight * 2 / 5.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight * 2 / 5.0f), - PWLPT_BEZIERTO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 16); - else - GetPathDataFromArray(path, PathArray, 16); -} - -void CPWL_Utils::GetGraphics_Circle(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f - - FX_BEZIER * (fWidth / 2.0f - fWidth / 15.0f), - crBBox.top - fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f + - FX_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f), - crBBox.top - fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * (fHeight * 14 / 15.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f - - FX_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f + - FX_BEZIER * (fWidth * 14 / 15.0f - fWidth / 2.0f), - crBBox.bottom + fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f - - FX_BEZIER * (fWidth / 2.0f - fWidth / 15.0f), - crBBox.bottom + fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f - - FX_BEZIER * (fHeight / 2.0f - fHeight / 15.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f - - FX_BEZIER * (fWidth / 2.0f - fWidth * 3 / 15.0f), - crBBox.top - fHeight * 3 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.top - fHeight * 3 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f + - FX_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f), - crBBox.top - fHeight * 3 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f - - FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f + - FX_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f), - crBBox.bottom + fHeight * 3 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.bottom + fHeight * 3 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f - - FX_BEZIER * (fWidth * 4 / 5.0f - fWidth / 2.0f), - crBBox.bottom + fHeight * 3 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f - - FX_BEZIER * (fHeight * 4 / 5.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 3 / 15.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_BEZIERTO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 26); - else - GetPathDataFromArray(path, PathArray, 26); -} - -void CPWL_Utils::GetGraphics_Comment(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 15.0f, crBBox.top - fHeight / 6.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.top - fHeight / 6.0f + - FX_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f - - FX_BEZIER * fWidth / 15.0f, - crBBox.top - fHeight / 10.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f, - crBBox.top - fHeight / 10.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f, - crBBox.top - fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f + - FX_BEZIER * fWidth / 15.0f, - crBBox.top - fHeight / 10.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.top - fHeight / 6 + - FX_BEZIER * (fHeight / 6.0f - fHeight / 10.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.top - fHeight / 6.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.bottom + fHeight / 3.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.bottom + fHeight * 4 / 15.0f + - FX_BEZIER * fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f + - FX_BEZIER * fWidth / 15.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f, - crBBox.bottom + fHeight * 2 / 15 + - FX_BEZIER * fHeight * 2 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 5 / 15.0f - - FX_BEZIER * fWidth * 2 / 15.0f, - crBBox.bottom + fHeight * 2 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 6 / 30.0f, - crBBox.bottom + fHeight * 2 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f + - FX_BEZIER * fWidth / 30.0f, - crBBox.bottom + fHeight * 2 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f, - crBBox.bottom + fHeight * 2 / 15.0f + - FX_BEZIER * fHeight * 2 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 30.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f - - FX_BEZIER * fWidth / 15.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight / 3.0f - - FX_BEZIER * fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 15.0f, - crBBox.bottom + fHeight / 3.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 15.0f, crBBox.top - fHeight / 6.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f, - crBBox.top - fHeight * 8 / 30.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f, - crBBox.top - fHeight * 8 / 30.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15, - crBBox.top - fHeight * 25 / 60.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 2 / 15.0f, - crBBox.top - fHeight * 25 / 60.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 2 / 15.0f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 4 / 15.0f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 30); - else - GetPathDataFromArray(path, PathArray, 30); -} - -void CPWL_Utils::GetGraphics_Cross(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - CPWL_Point center_point(crBBox.left + fWidth / 2, - crBBox.bottom + fHeight / 2); - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(center_point.x, center_point.y + fHeight / 10.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(center_point.x + fWidth * 0.3f, - center_point.y + fHeight / 10.0f + fWidth * 0.3f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x + fWidth / 10.0f + fWidth * 0.3f, - center_point.y + fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x + fWidth / 10.0f, center_point.y), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x + fWidth / 10.0f + fWidth * 0.3f, - center_point.y - fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(center_point.x + fWidth * 0.3f, - center_point.y - fHeight / 10.0f - fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(center_point.x, center_point.y - fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x - fWidth * 0.3f, - center_point.y - fHeight / 10 - fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x - fWidth / 10.0f - fWidth * 0.3f, - center_point.y - fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x - fWidth / 10, center_point.y), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(center_point.x - fWidth / 10 - fWidth * 0.3f, - center_point.y + fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(center_point.x - fWidth * 0.3f, - center_point.y + fHeight / 10.0f + fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(center_point.x, center_point.y + fHeight / 10.0f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 13); - else - GetPathDataFromArray(path, PathArray, 13); -} - -void CPWL_Utils::GetGraphics_Help(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f - - FX_BEZIER * (fWidth / 2.0f - fWidth / 60.0f), - crBBox.bottom + fHeight / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.bottom + fHeight / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f + - FX_BEZIER * fWidth * 29 / 60.0f, - crBBox.bottom + fHeight / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * (fHeight / 60.0f - fHeight / 2.0f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * fHeight * 29 / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f + - FX_BEZIER * fWidth * 29 / 60.0f, - crBBox.top - fHeight / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f - - FX_BEZIER * fWidth * 29 / 60.0f, - crBBox.top - fHeight / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f + - FX_BEZIER * fHeight * 29 / 60.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60.0f, - crBBox.bottom + fHeight / 2.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f, - crBBox.top - fHeight * 0.36f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f, - crBBox.top - fHeight * 0.36f + - FX_BEZIER * fHeight * 0.23f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f - FX_BEZIER * fWidth * 0.23f, - crBBox.bottom + fHeight * 0.87f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f, - crBBox.bottom + fHeight * 0.87f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f + FX_BEZIER * fWidth * 0.23f, - crBBox.bottom + fHeight * 0.87f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.27f, - crBBox.top - fHeight * 0.36f + - FX_BEZIER * fHeight * 0.23f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.27f, - crBBox.top - fHeight * 0.36f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.27f - fWidth * 0.08f * 0.2f, - crBBox.top - fHeight * 0.36f - fHeight * 0.15f * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.35f + fWidth * 0.08f * 0.2f, - crBBox.top - fHeight * 0.51f + fHeight * 0.15f * 0.2f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.35f, - crBBox.top - fHeight * 0.51f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.35f - fWidth * 0.1f * 0.5f, - crBBox.top - fHeight * 0.51f - fHeight * 0.15f * 0.3f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.45f - fWidth * 0.1f * 0.5f, - crBBox.top - fHeight * 0.68f + fHeight * 0.15f * 0.5f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.45f, - crBBox.top - fHeight * 0.68f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.45f, - crBBox.bottom + fHeight * 0.30f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.45f, - crBBox.bottom + fHeight * 0.30f - fWidth * 0.1f * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.55f, - crBBox.bottom + fHeight * 0.30f - fWidth * 0.1f * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.55f, - crBBox.bottom + fHeight * 0.30f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.55f, - crBBox.top - fHeight * 0.66f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.55f - fWidth * 0.1f * 0.05f, - crBBox.top - fHeight * 0.66f + fHeight * 0.18f * 0.5f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.45f - fWidth * 0.1f * 0.05f, - crBBox.top - fHeight * 0.48f - fHeight * 0.18f * 0.3f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.45f, - crBBox.top - fHeight * 0.48f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.45f + fWidth * 0.08f * 0.2f, - crBBox.top - fHeight * 0.48f + fHeight * 0.18f * 0.2f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.37f - fWidth * 0.08f * 0.2f, - crBBox.top - fHeight * 0.36f - fHeight * 0.18f * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.37f, - crBBox.top - fHeight * 0.36f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.37f, - crBBox.top - fHeight * 0.36f + - FX_BEZIER * fHeight * 0.13f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f + FX_BEZIER * fWidth * 0.13f, - crBBox.bottom + fHeight * 0.77f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f, - crBBox.bottom + fHeight * 0.77f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f - FX_BEZIER * fWidth * 0.13f, - crBBox.bottom + fHeight * 0.77f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.37f, - crBBox.top - fHeight * 0.36f + - FX_BEZIER * fHeight * 0.13f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.37f, - crBBox.top - fHeight * 0.36f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.37f, - crBBox.top - fHeight * 0.36f - fWidth * 0.1f * 0.6f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.27f, - crBBox.top - fHeight * 0.36f - fWidth * 0.1f * 0.6f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.27f, - crBBox.top - fHeight * 0.36f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f, - crBBox.bottom + fHeight * 0.13f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f, - crBBox.bottom + fHeight * 0.13f + - FX_BEZIER * fHeight * 0.055f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f - - FX_BEZIER * fWidth * 0.095f, - crBBox.bottom + fHeight * 0.185f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f, - crBBox.bottom + fHeight * 0.185f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f + - FX_BEZIER * fWidth * 0.065f, - crBBox.bottom + fHeight * 0.185f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f, - crBBox.bottom + fHeight * 0.13f + - FX_BEZIER * fHeight * 0.055f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f, - crBBox.bottom + fHeight * 0.13f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.44f, - crBBox.bottom + fHeight * 0.13f - - FX_BEZIER * fHeight * 0.055f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f + - FX_BEZIER * fWidth * 0.065f, - crBBox.bottom + fHeight * 0.075f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f, - crBBox.bottom + fHeight * 0.075f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.505f - - FX_BEZIER * fWidth * 0.065f, - crBBox.bottom + fHeight * 0.075f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f, - crBBox.bottom + fHeight * 0.13f - - FX_BEZIER * fHeight * 0.055f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.56f, - crBBox.bottom + fHeight * 0.13f), - PWLPT_BEZIERTO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 59); - else - GetPathDataFromArray(path, PathArray, 59); -} - -void CPWL_Utils::GetGraphics_InsertText(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 10, crBBox.bottom + fHeight / 10), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2, crBBox.top - fHeight * 2 / 15), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 10, crBBox.bottom + fHeight / 10), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 10, crBBox.bottom + fHeight / 10), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 4); - else - GetPathDataFromArray(path, PathArray, 4); -} - -void CPWL_Utils::GetGraphics_Key(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - FX_FLOAT k = -fHeight / fWidth; - CPWL_Point tail; - CPWL_Point CicleCenter; - tail.x = crBBox.left + fWidth * 0.9f; - tail.y = k * (tail.x - crBBox.right) + crBBox.bottom; - CicleCenter.x = crBBox.left + fWidth * 0.15f; - CicleCenter.y = k * (CicleCenter.x - crBBox.right) + crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30.0f, -fWidth / 30.0f / k + tail.y), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(tail.x + fWidth / 30.0f - fWidth * 0.18f, - -k * fWidth * 0.18f - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f + fWidth * 0.07f, - -fWidth * 0.07f / k - k * fWidth * 0.18f - - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 + - fWidth * 0.07f, - -fWidth * 0.07f / k - k * fWidth / 20 - - k * fWidth * 0.18f - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point( - tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20, - -k * fWidth / 20 - k * fWidth * 0.18f - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point( - tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 - fWidth / 15, - -k * fWidth / 15 - k * fWidth / 20 - k * fWidth * 0.18f - - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 - - fWidth / 15 + fWidth * 0.07f, - -fWidth * 0.07f / k - k * fWidth / 15 - k * fWidth / 20 - - k * fWidth * 0.18f - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 - - fWidth / 15 - fWidth / 20 + fWidth * 0.07f, - -fWidth * 0.07f / k + -k * fWidth / 20 + -k * fWidth / 15 - - k * fWidth / 20 - k * fWidth * 0.18f - - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.18f - fWidth / 20 - - fWidth / 15 - fWidth / 20, - -k * fWidth / 20 + -k * fWidth / 15 - k * fWidth / 20 - - k * fWidth * 0.18f - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.45f, - -k * fWidth * 0.45f - fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 30 - fWidth * 0.45f + fWidth * 0.2f, - -fWidth * 0.4f / k - k * fWidth * 0.45f - fWidth / 30 / k + - tail.y), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.2f, - -fWidth * 0.1f / k + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x, CicleCenter.y), PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x - fWidth / 60.0f, - -k * fWidth / 60 + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x - fWidth / 60, - -k * fWidth / 60 + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x, CicleCenter.y), PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(CicleCenter.x - fWidth * 0.22f, - fWidth * 0.35f / k + CicleCenter.y - fHeight * 0.05f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(tail.x - fWidth / 30 - fWidth * 0.45f - fWidth * 0.18f, - fWidth * 0.05f / k - k * fWidth * 0.45f + fWidth / 30 / k + - tail.y - fHeight * 0.05f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(tail.x - fWidth / 30.0f - fWidth * 0.45f, - -k * fWidth * 0.45f + fWidth / 30.0f / k + tail.y), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(tail.x - fWidth / 30.0f, fWidth / 30.0f / k + tail.y), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(tail.x + fWidth / 30, -fWidth / 30 / k + tail.y), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.08f, - k * fWidth * 0.08f + CicleCenter.y), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(CicleCenter.x + fWidth * 0.08f + fWidth * 0.1f, - -fWidth * 0.1f / k + k * fWidth * 0.08f + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(CicleCenter.x + fWidth * 0.22f + fWidth * 0.1f, - k * fWidth * 0.22f + CicleCenter.y - fWidth * 0.1f / k), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.22f, - k * fWidth * 0.22f + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(CicleCenter.x + fWidth * 0.22f - fWidth * 0.1f, - fWidth * 0.1f / k + k * fWidth * 0.22f + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(CicleCenter.x + fWidth * 0.08f - fWidth * 0.1f, - fWidth * 0.1f / k + k * fWidth * 0.08f + CicleCenter.y), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(CicleCenter.x + fWidth * 0.08f, - k * fWidth * 0.08f + CicleCenter.y), - PWLPT_BEZIERTO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 28); - else - GetPathDataFromArray(path, PathArray, 28); -} - -void CPWL_Utils::GetGraphics_NewParagraph(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 20.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 10.0f, crBBox.top - fHeight / 2.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f, - crBBox.top - fHeight / 2.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 20.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.12f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.12f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.22f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.22f, - crBBox.top - fHeight * 17 / 30.0f - fWidth * 0.14f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.38f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.48f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.48f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.38f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.38f, - crBBox.bottom + fWidth * 0.24f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.22f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.12f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.bottom + fHeight / 10.0f + fHeight / 7.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.97f, - crBBox.bottom + fHeight / 10.0f + fHeight / 7.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.97f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.top - fHeight * 17 / 30.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.bottom + fHeight / 10.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.bottom + fHeight / 7 + fHeight * 0.18f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.85f, - crBBox.bottom + fHeight / 7 + fHeight * 0.18f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.85f, - crBBox.top - fHeight * 17 / 30.0f - fHeight * 0.08f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.top - fHeight * 17 / 30.0f - fHeight * 0.08f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.bottom + fHeight / 7 + fHeight * 0.18f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 28); - else - GetPathDataFromArray(path, PathArray, 28); -} - -void CPWL_Utils::GetGraphics_TextNote(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 7 / 10.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f, - crBBox.top - fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 10.0f, - crBBox.top - fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 10.0f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f, - crBBox.bottom + fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 5.0f, - crBBox.top - fHeight * 4 / 15.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 5.0f, - crBBox.top - fHeight * 4 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 5.0f, - crBBox.top - fHeight * 7 / 15.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 5.0f, - crBBox.top - fHeight * 7 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 5.0f, - crBBox.top - fHeight * 10 / 15.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 3 / 10.0f, - crBBox.top - fHeight * 10 / 15.0f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 17); - else - GetPathDataFromArray(path, PathArray, 17); -} - -void CPWL_Utils::GetGraphics_Paragraph(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.7f, crBBox.top - fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.634f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.634f, - crBBox.top - fHeight * 2 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.566f, - crBBox.top - fHeight * 2 / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.566f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.top - fHeight / 15.0f - fHeight * 0.4f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.2f, - crBBox.top - fHeight / 15.0f - fHeight * 0.4f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.2f, crBBox.top - fHeight / 15.0f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f), - PWLPT_BEZIERTO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 12); - else - GetPathDataFromArray(path, PathArray, 12); -} - -void CPWL_Utils::GetGraphics_RightArrow(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.top - fHeight / 2.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f + fWidth / 8.0f, - crBBox.bottom + fHeight / 5.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f, - crBBox.bottom + fHeight / 5.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f - fWidth * 0.15f, - crBBox.top - fHeight / 2.0f - fWidth / 25.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.1f, - crBBox.top - fHeight / 2.0f - fWidth / 25.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.1f, - crBBox.top - fHeight / 2.0f + fWidth / 25.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f - fWidth * 0.15f, - crBBox.top - fHeight / 2.0f + fWidth / 25.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 5.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 2.0f + fWidth / 8.0f, - crBBox.top - fHeight / 5.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15.0f, - crBBox.top - fHeight / 2.0f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 10); - else - GetPathDataFromArray(path, PathArray, 10); -} - -void CPWL_Utils::GetGraphics_RightPointer(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30.0f, - crBBox.top - fHeight / 2.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 30.0f, - crBBox.bottom + fHeight / 6.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 4 / 15.0f, - crBBox.top - fHeight / 2.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 30.0f, crBBox.top - fHeight / 6.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30.0f, - crBBox.top - fHeight / 2.0f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 5); - else - GetPathDataFromArray(path, PathArray, 5); -} - -void CPWL_Utils::GetGraphics_Star(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fLongRadius = - (crBBox.top - crBBox.bottom) / (1 + (FX_FLOAT)cos(FX_PI / 5.0f)); - fLongRadius = fLongRadius * 0.7f; - FX_FLOAT fShortRadius = fLongRadius * 0.55f; - CFX_FloatPoint ptCenter = CFX_FloatPoint((crBBox.left + crBBox.right) / 2.0f, - (crBBox.top + crBBox.bottom) / 2.0f); - - FX_FLOAT px1[5], py1[5]; - FX_FLOAT px2[5], py2[5]; - - FX_FLOAT fAngel = FX_PI / 10.0f; - - for (int32_t i = 0; i < 5; i++) { - px1[i] = ptCenter.x + fLongRadius * (FX_FLOAT)cos(fAngel); - py1[i] = ptCenter.y + fLongRadius * (FX_FLOAT)sin(fAngel); - - fAngel += FX_PI * 2 / 5.0f; - } - - fAngel = FX_PI / 5.0f + FX_PI / 10.0f; - - for (int32_t j = 0; j < 5; j++) { - px2[j] = ptCenter.x + fShortRadius * (FX_FLOAT)cos(fAngel); - py2[j] = ptCenter.y + fShortRadius * (FX_FLOAT)sin(fAngel); - - fAngel += FX_PI * 2 / 5.0f; - } - - CPWL_PathData PathArray[11]; - PathArray[0] = CPWL_PathData(CPWL_Point(px1[0], py1[0]), PWLPT_MOVETO); - PathArray[1] = CPWL_PathData(CPWL_Point(px2[0], py2[0]), PWLPT_LINETO); - - for (int32_t k = 0; k < 4; k++) { - PathArray[(k + 1) * 2] = - CPWL_PathData(CPWL_Point(px1[k + 1], py1[k + 1]), PWLPT_LINETO); - PathArray[(k + 1) * 2 + 1] = - CPWL_PathData(CPWL_Point(px2[k + 1], py2[k + 1]), PWLPT_LINETO); - } - - PathArray[10] = CPWL_PathData(CPWL_Point(px1[0], py1[0]), PWLPT_LINETO); - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 11); - else - GetPathDataFromArray(path, PathArray, 11); -} - -void CPWL_Utils::GetGraphics_UpArrow(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 10.0f, - crBBox.top - fWidth * 3 / 5.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.top - fWidth * 3 / 5.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.4f, - crBBox.bottom + fHeight / 15.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.4f, - crBBox.top - fWidth * 3 / 5.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 10, crBBox.top - fWidth * 3 / 5.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 2.0f, crBBox.top - fHeight / 15.0f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 8); - else - GetPathDataFromArray(path, PathArray, 8); -} - -void CPWL_Utils::GetGraphics_UpLeftArrow(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - CPWL_Point leftup(crBBox.left, crBBox.top); - CPWL_Point rightdown(crBBox.right, crBBox.bottom); - FX_FLOAT k = -fHeight / fWidth; - CPWL_Point tail; - tail.x = crBBox.left + fWidth * 4 / 5.0f; - tail.y = k * (tail.x - crBBox.right) + rightdown.y; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point( - crBBox.left + fWidth / 20.0f, - k * (crBBox.left + fWidth / 20.0f - rightdown.x) + rightdown.y), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(fHeight * 17 / 60.0f / k + tail.x + - fWidth / 10.0f + fWidth / 5.0f, - -fWidth / 5.0f / k + tail.y - - fWidth / 10.0f / k + fHeight * 17 / 60.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(fHeight * 17 / 60.0f / k + tail.x + fWidth / 10.0f, - tail.y - fWidth / 10.0f / k + fHeight * 17 / 60.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x + fWidth / 10.0f, tail.y - fWidth / 10.0f / k), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(tail.x - fWidth / 10.0f, tail.y + fWidth / 10.0f / k), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(fHeight * 17 / 60.0f / k + tail.x - fWidth / 10.0f, - tail.y + fWidth / 10.0f / k + fHeight * 17 / 60.0f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(fHeight * 17 / 60.0f / k + tail.x - - fWidth / 10.0f - fWidth / 5.0f, - fWidth / 5.0f / k + tail.y + fWidth / 10.0f / k + - fHeight * 17 / 60.0f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point( - crBBox.left + fWidth / 20.0f, - k * (crBBox.left + fWidth / 20.0f - rightdown.x) + rightdown.y), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 8); - else - GetPathDataFromArray(path, PathArray, 8); -} - -void CPWL_Utils::GetGraphics_Graph(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.05f, crBBox.top - fWidth * 0.15f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.25f, - crBBox.top - fHeight * 0.15f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.275f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.05f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.05f, crBBox.top - fWidth * 0.15f), - PWLPT_LINETO), - - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.275f, - crBBox.top - fWidth * 0.45f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.475f, - crBBox.top - fWidth * 0.45f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.475f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.275f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.275f, - crBBox.top - fWidth * 0.45f), - PWLPT_LINETO), - - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f, crBBox.top - fHeight * 0.05f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.7f, crBBox.top - fHeight * 0.05f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.7f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f, crBBox.top - fHeight * 0.05f), - PWLPT_LINETO), - - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.725f, - crBBox.top - fWidth * 0.35f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.925f, - crBBox.top - fWidth * 0.35f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.925f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.725f, - crBBox.bottom + fHeight * 0.08f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.725f, - crBBox.top - fWidth * 0.35f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 20); - else - GetPathDataFromArray(path, PathArray, 20); -} - -void CPWL_Utils::GetGraphics_Paperclip(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 60, crBBox.top - fHeight * 0.25f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60, - crBBox.bottom + fHeight * 0.25f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60, - crBBox.bottom + fHeight * 0.25f - - fWidth * 57 / 60.0f * 0.35f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30, - crBBox.bottom + fHeight * 0.25f - - fWidth * 57 / 60.0f * 0.35f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30, - crBBox.bottom + fHeight * 0.25f), - PWLPT_BEZIERTO), - - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 30, crBBox.top - fHeight * 0.33f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 30, - crBBox.top - fHeight * 0.33f + fHeight / 15 * 0.5f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 30 - fWidth * 0.12f, - crBBox.top - fHeight * 0.33f + fHeight / 15 * 0.5f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30 - fWidth * 0.12f, - crBBox.top - fHeight * 0.33f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 30 - fWidth * 0.12f, - crBBox.bottom + fHeight * 0.2f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 30 - fWidth * 0.12f, - crBBox.bottom + fHeight * 0.2f - - (fWidth * 57 / 60.0f - fWidth * 0.24f) * 0.25f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 60 + fWidth * 0.12f, - crBBox.bottom + fHeight * 0.2f - - (fWidth * 57 / 60.0f - fWidth * 0.24f) * 0.25f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60 + fWidth * 0.12f, - crBBox.bottom + fHeight * 0.2f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60 + fWidth * 0.12f, - crBBox.top - fHeight * 0.2f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 60 + fWidth * 0.12f, - crBBox.top - fHeight * 0.2f + - (fWidth * 11 / 12.0f - fWidth * 0.36f) * 0.25f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.24f, - crBBox.top - fHeight * 0.2f + - (fWidth * 11 / 12.0f - fWidth * 0.36f) * 0.25f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.24f, - crBBox.top - fHeight * 0.2f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.24f, - crBBox.bottom + fHeight * 0.25f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.24f, - crBBox.bottom + fHeight * 0.25f - - (fWidth * 14 / 15.0f - fWidth * 0.53f) * 0.25f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.29f, - crBBox.bottom + fHeight * 0.25f - - (fWidth * 14 / 15.0f - fWidth * 0.53f) * 0.25f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.29f, - crBBox.bottom + fHeight * 0.25f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.29f, - crBBox.top - fHeight * 0.33f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.29f, - crBBox.top - fHeight * 0.33f + fWidth * 0.12f * 0.35f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.17f, - crBBox.top - fHeight * 0.33f + fWidth * 0.12f * 0.35f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.17f, - crBBox.top - fHeight * 0.33f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.17f, - crBBox.bottom + fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.17f, - crBBox.bottom + fHeight * 0.3f - - fWidth * (14 / 15.0f - 0.29f) * 0.35f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.12f, - crBBox.bottom + fHeight * 0.3f - - fWidth * (14 / 15.0f - 0.29f) * 0.35f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.12f, - crBBox.bottom + fHeight * 0.3f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.12f, - crBBox.top - fHeight * 0.25f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth / 15 - fWidth * 0.12f, - crBBox.top - fHeight * 0.25f + - fWidth * 0.35f * (11 / 12.0f - 0.12f)), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth / 60, - crBBox.top - fHeight * 0.25f + - fWidth * 0.35f * (11 / 12.0f - 0.12f)), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth / 60, crBBox.top - fHeight * 0.25f), - PWLPT_BEZIERTO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 33); - else - GetPathDataFromArray(path, PathArray, 33); -} - -void CPWL_Utils::GetGraphics_Attachment(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.25f, crBBox.top - fHeight * 0.1f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.23f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.5f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.4f, - crBBox.top - fHeight * 0.5f + fWidth * 0.04f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.top - fHeight * 0.5f + fWidth * 0.04f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.6f, crBBox.top - fHeight * 0.5f), - PWLPT_BEZIERTO), - - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.6f, crBBox.top - fHeight * 0.23f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.25f, - crBBox.top - fHeight * 0.1f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.25f, crBBox.top - fHeight * 0.1f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.23f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.6f, crBBox.top - fHeight * 0.23f), - PWLPT_LINETO), - - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.5f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f - fWidth * 0.25f * 0.4f, - crBBox.top - fHeight * 0.5f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.15f, - crBBox.top - fHeight * 0.65f + fHeight * 0.15f * 0.4f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.15f, - crBBox.top - fHeight * 0.65f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.15f, - crBBox.top - fHeight * 0.65f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.15f, - crBBox.top - fHeight * 0.65f + fHeight * 0.15f * 0.4f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.6f + fWidth * 0.25f * 0.4f, - crBBox.top - fHeight * 0.5f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.6f, crBBox.top - fHeight * 0.5f), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.6f, - crBBox.top - fHeight * 0.5f + fWidth * 0.04f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.4f, - crBBox.top - fHeight * 0.5f + fWidth * 0.04f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.5f), - PWLPT_BEZIERTO), - - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.5f, crBBox.top - fHeight * 0.65f), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.5f, - crBBox.bottom + fHeight * 0.1f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 24); - else - GetPathDataFromArray(path, PathArray, 24); -} - -void CPWL_Utils::GetGraphics_Tag(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fWidth = crBBox.right - crBBox.left; - FX_FLOAT fHeight = crBBox.top - crBBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.1f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.1f, crBBox.top - fHeight * 0.5f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.left + fWidth * 0.3f, - crBBox.bottom + fHeight * 0.1f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crBBox.right - fWidth * 0.1f, - crBBox.bottom + fHeight * 0.1f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.1f, crBBox.top - fHeight * 0.1f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.1f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.3f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.2f, crBBox.top - fHeight * 0.3f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.5f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.2f, crBBox.top - fHeight * 0.5f), - PWLPT_LINETO), - CPWL_PathData( - CPWL_Point(crBBox.left + fWidth * 0.4f, crBBox.top - fHeight * 0.7f), - PWLPT_MOVETO), - CPWL_PathData( - CPWL_Point(crBBox.right - fWidth * 0.2f, crBBox.top - fHeight * 0.7f), - PWLPT_LINETO)}; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 12); - else - GetPathDataFromArray(path, PathArray, 12); -} - -void CPWL_Utils::GetGraphics_Foxit(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type) { - FX_FLOAT fOutWidth = crBBox.right - crBBox.left; - FX_FLOAT fOutHeight = crBBox.top - crBBox.bottom; - - CFX_FloatRect crInBox = crBBox; - crInBox.left = crBBox.left + fOutWidth * 0.08f; - crInBox.right = crBBox.right - fOutWidth * 0.08f; - crInBox.top = crBBox.top - fOutHeight * 0.08f; - crInBox.bottom = crBBox.bottom + fOutHeight * 0.08f; - - FX_FLOAT fWidth = crInBox.right - crInBox.left; - FX_FLOAT fHeight = crInBox.top - crInBox.bottom; - - CPWL_PathData PathArray[] = { - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top), PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.45f, crInBox.top), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.45f, - crInBox.top - FX_BEZIER * fHeight * 0.4f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crInBox.left + fWidth * 0.45f - FX_BEZIER * fWidth * 0.45f, - crInBox.top - fHeight * 0.4f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.4f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top), PWLPT_LINETO), - - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.60f, crInBox.top), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.75f, crInBox.top), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.75f, - crInBox.top - FX_BEZIER * fHeight * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crInBox.left + fWidth * 0.75f - FX_BEZIER * fWidth * 0.75f, - crInBox.top - fHeight * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.7f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.55f), - PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crInBox.left + FX_BEZIER * fWidth * 0.60f, - crInBox.top - fHeight * 0.55f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.60f, - crInBox.top - FX_BEZIER * fHeight * 0.55f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.60f, crInBox.top), - PWLPT_BEZIERTO), - - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.90f, crInBox.top), - PWLPT_MOVETO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.90f, - crInBox.top - FX_BEZIER * fHeight * 0.85f), - PWLPT_BEZIERTO), - CPWL_PathData( - CPWL_Point(crInBox.left + fWidth * 0.90f - FX_BEZIER * fWidth * 0.90f, - crInBox.top - fHeight * 0.85f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.top - fHeight * 0.85f), - PWLPT_BEZIERTO), - CPWL_PathData(CPWL_Point(crInBox.left, crInBox.bottom), PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crInBox.right, crInBox.bottom), PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crInBox.right, crInBox.top), PWLPT_LINETO), - CPWL_PathData(CPWL_Point(crInBox.left + fWidth * 0.90f, crInBox.top), - PWLPT_LINETO), - }; - - if (type == PWLPT_STREAM) - sPathData = GetAppStreamFromArray(PathArray, 23); - else - GetPathDataFromArray(path, PathArray, 23); -} - -void CPWL_Color::ConvertColorType(int32_t nConvertColorType) { - if (nColorType == nConvertColorType) - return; - - switch (nColorType) { - case COLORTYPE_TRANSPARENT: - break; - case COLORTYPE_GRAY: - switch (nConvertColorType) { - case COLORTYPE_RGB: - CPWL_Utils::ConvertGRAY2RGB(fColor1, fColor1, fColor2, fColor3); - break; - case COLORTYPE_CMYK: - CPWL_Utils::ConvertGRAY2CMYK(fColor1, fColor1, fColor2, fColor3, - fColor4); - break; - } - break; - case COLORTYPE_RGB: - switch (nConvertColorType) { - case COLORTYPE_GRAY: - CPWL_Utils::ConvertRGB2GRAY(fColor1, fColor2, fColor3, fColor1); - break; - case COLORTYPE_CMYK: - CPWL_Utils::ConvertRGB2CMYK(fColor1, fColor2, fColor3, fColor1, - fColor2, fColor3, fColor4); - break; - } - break; - case COLORTYPE_CMYK: - switch (nConvertColorType) { - case COLORTYPE_GRAY: - CPWL_Utils::ConvertCMYK2GRAY(fColor1, fColor2, fColor3, fColor4, - fColor1); - break; - case COLORTYPE_RGB: - CPWL_Utils::ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4, - fColor1, fColor2, fColor3); - break; - } - break; - } - nColorType = nConvertColorType; -} diff --git a/fpdfsdk/pdfwindow/PWL_Utils.h b/fpdfsdk/pdfwindow/PWL_Utils.h index f14c3c796..a4ecc19ee 100644 --- a/fpdfsdk/pdfwindow/PWL_Utils.h +++ b/fpdfsdk/pdfwindow/PWL_Utils.h @@ -11,51 +11,10 @@ #include "fpdfsdk/pdfwindow/PWL_Wnd.h" class CFX_Edit; -class CFX_PathData; - struct CPWL_Color; -template <class T> -T PWL_MIN(const T& i, const T& j) { - return ((i < j) ? i : j); -} -template <class T> -T PWL_MAX(const T& i, const T& j) { - return ((i > j) ? i : j); -} - -#define PWL_PDF2WIN(color) (uint8_t(color * 255)) -#define PWL_WIN2PDF(color) ((FX_FLOAT)((FX_FLOAT)color / 255.0f)) - #define PWL_MAKEDWORD(low, high) \ ((uint32_t)((uint16_t)(low) | (uint32_t)(((uint16_t)(high)) << 16))) -#define PWL_GETLOWWORD(dword) ((uint16_t)(dword)) -#define PWL_GETHIGHWORD(dword) ((uint16_t)(dword >> 16)) - -#define PWL_ICONTYPE_CHECKMARK 0 -#define PWL_ICONTYPE_CIRCLE 1 -#define PWL_ICONTYPE_COMMENT 2 -#define PWL_ICONTYPE_CROSS 3 -#define PWL_ICONTYPE_HELP 4 -#define PWL_ICONTYPE_INSERTTEXT 5 -#define PWL_ICONTYPE_KEY 6 -#define PWL_ICONTYPE_NEWPARAGRAPH 7 -#define PWL_ICONTYPE_TEXTNOTE 8 -#define PWL_ICONTYPE_PARAGRAPH 9 -#define PWL_ICONTYPE_RIGHTARROW 10 -#define PWL_ICONTYPE_RIGHTPOINTER 11 -#define PWL_ICONTYPE_STAR 12 -#define PWL_ICONTYPE_UPARROW 13 -#define PWL_ICONTYPE_UPLEFTARROW 14 - -#define PWL_ICONTYPE_GRAPH 15 -#define PWL_ICONTYPE_PAPERCLIP 16 -#define PWL_ICONTYPE_ATTACHMENT 17 -#define PWL_ICONTYPE_TAG 18 - -#define PWL_ICONTYPE_FOXIT 19 - -#define PWL_ICONTYPE_UNKNOWN -1 // checkbox & radiobutton style #define PCS_CHECK 0 @@ -74,60 +33,18 @@ T PWL_MAX(const T& i, const T& j) { #define PPBL_LABELLEFTICONRIGHT 5 #define PPBL_LABELOVERICON 6 -class CPWL_Point : public CFX_FloatPoint { - public: - CPWL_Point() {} - CPWL_Point(FX_FLOAT fx, FX_FLOAT fy) : CFX_FloatPoint(fx, fy) {} - CPWL_Point(const CPWL_Point& point) : CFX_FloatPoint(point.x, point.y) {} -}; - -enum PWL_PATHDATA_TYPE { - PWLPT_MOVETO, - PWLPT_LINETO, - PWLPT_BEZIERTO, - PWLPT_UNKNOWN -}; - -enum PWL_PATH_TYPE { PWLPT_PATHDATA, PWLPT_STREAM }; - -class CPWL_PathData { - public: - CPWL_PathData() : point(), type(PWLPT_UNKNOWN) {} - CPWL_PathData(const CPWL_Point& pt, PWL_PATHDATA_TYPE tp) - : point(pt), type(tp) {} - - CPWL_Point point; - PWL_PATHDATA_TYPE type; -}; - class CPWL_Utils { public: static CFX_FloatRect InflateRect(const CFX_FloatRect& rcRect, FX_FLOAT fSize); static CFX_FloatRect DeflateRect(const CFX_FloatRect& rcRect, FX_FLOAT fSize); - static bool IntersectRect(const CFX_FloatRect& rect1, - const CFX_FloatRect& rect2); - static bool ContainsRect(const CFX_FloatRect& rcParent, - const CFX_FloatRect& rcChild); - static CFX_FloatRect ScaleRect(const CFX_FloatRect& rcRect, FX_FLOAT fScale); + static CPVT_WordRange OverlapWordRange(const CPVT_WordRange& wr1, const CPVT_WordRange& wr2); static CFX_FloatRect GetCenterSquare(const CFX_FloatRect& rect); - static CPWL_Color SubstractColor(const CPWL_Color& sColor, - FX_FLOAT fColorSub); - static CPWL_Color DevideColor(const CPWL_Color& sColor, - FX_FLOAT fColorDevide); - static CFX_FloatRect MaxRect(const CFX_FloatRect& rect1, - const CFX_FloatRect& rect2); + static CFX_FloatRect OffsetRect(const CFX_FloatRect& rect, FX_FLOAT x, FX_FLOAT y); - static CFX_FloatPoint OffsetPoint(const CFX_FloatPoint& point, - FX_FLOAT x, - FX_FLOAT y); - static FX_COLORREF PWLColorToFXColor(const CPWL_Color& color, - int32_t nTransparancy = 255); - static bool IsBlackOrWhite(const CPWL_Color& color); - static CPWL_Color GetReverseColor(const CPWL_Color& color); static CFX_ByteString GetColorAppStream(const CPWL_Color& color, const bool& bFillOrStroke = true); @@ -150,7 +67,6 @@ class CPWL_Utils { const CPWL_Color& color); static CFX_ByteString GetCircleFillAppStream(const CFX_FloatRect& rect, const CPWL_Color& color); - static CFX_ByteString GetPushButtonAppStream(const CFX_FloatRect& rcBBox, IPVT_FontMap* pFontMap, CPDF_Stream* pIconStream, @@ -165,32 +81,22 @@ class CPWL_Utils { static CFX_ByteString GetRadioButtonAppStream(const CFX_FloatRect& rcBBox, int32_t nStyle, const CPWL_Color& crText); - static CFX_ByteString GetEditAppStream(CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange = nullptr, bool bContinuous = true, uint16_t SubWord = 0); static CFX_ByteString GetEditSelAppStream( CFX_Edit* pEdit, - const CFX_FloatPoint& ptOffset, + const CFX_PointF& ptOffset, const CPVT_WordRange* pRange = nullptr); - static CFX_ByteString GetTextAppStream(const CFX_FloatRect& rcBBox, - IPVT_FontMap* pFontMap, - const CFX_WideString& sText, - int32_t nAlignmentH, - int32_t nAlignmentV, - FX_FLOAT fFontSize, - bool bMultiLine, - bool bAutoReturn, - const CPWL_Color& crText); static CFX_ByteString GetDropButtonAppStream(const CFX_FloatRect& rcBBox); static void DrawFillRect(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, const CFX_FloatRect& rect, const CPWL_Color& color, - int32_t nTransparancy); + int32_t nTransparency); static void DrawFillRect(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, const CFX_FloatRect& rect, @@ -202,8 +108,8 @@ class CPWL_Utils { FX_FLOAT fWidth); static void DrawStrokeLine(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, - const CFX_FloatPoint& ptMoveTo, - const CFX_FloatPoint& ptLineTo, + const CFX_PointF& ptMoveTo, + const CFX_PointF& ptLineTo, const FX_COLORREF& color, FX_FLOAT fWidth); static void DrawBorder(CFX_RenderDevice* pDevice, @@ -214,10 +120,10 @@ class CPWL_Utils { const CPWL_Color& crLeftTop, const CPWL_Color& crRightBottom, BorderStyle nStyle, - int32_t nTransparancy); + int32_t nTransparency); static void DrawFillArea(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device, - const CFX_FloatPoint* pPts, + const CFX_PointF* pPts, int32_t nCount, const FX_COLORREF& color); static void DrawShadow(CFX_RenderDevice* pDevice, @@ -225,72 +131,12 @@ class CPWL_Utils { bool bVertical, bool bHorizontal, CFX_FloatRect rect, - int32_t nTransparancy, + int32_t nTransparency, int32_t nStartGray, int32_t nEndGray); - public: - static void ConvertCMYK2RGB(FX_FLOAT dC, - FX_FLOAT dM, - FX_FLOAT dY, - FX_FLOAT dK, - FX_FLOAT& dR, - FX_FLOAT& dG, - FX_FLOAT& dB); - static void ConvertRGB2CMYK(FX_FLOAT dR, - FX_FLOAT dG, - FX_FLOAT dB, - FX_FLOAT& dC, - FX_FLOAT& dM, - FX_FLOAT& dY, - FX_FLOAT& dK); - - static void ConvertRGB2GRAY(FX_FLOAT dR, - FX_FLOAT dG, - FX_FLOAT dB, - FX_FLOAT& dGray); - static void ConvertGRAY2RGB(FX_FLOAT dGray, - FX_FLOAT& dR, - FX_FLOAT& dG, - FX_FLOAT& dB); - - static void ConvertCMYK2GRAY(FX_FLOAT dC, - FX_FLOAT dM, - FX_FLOAT dY, - FX_FLOAT dK, - FX_FLOAT& dGray); - static void ConvertGRAY2CMYK(FX_FLOAT dGray, - FX_FLOAT& dC, - FX_FLOAT& dM, - FX_FLOAT& dY, - FX_FLOAT& dK); - - static void PWLColorToARGB(const CPWL_Color& color, - int32_t& alpha, - FX_FLOAT& red, - FX_FLOAT& green, - FX_FLOAT& blue); - - public: - static CFX_ByteString GetIconAppStream( - int32_t nType, - const CFX_FloatRect& rect, - const CPWL_Color& crFill, - const CPWL_Color& crStroke = PWL_DEFAULT_BLACKCOLOR); - static void DrawIconAppStream(CFX_RenderDevice* pDevice, - CFX_Matrix* pUser2Device, - int32_t nType, - const CFX_FloatRect& rect, - const CPWL_Color& crFill, - const CPWL_Color& crStroke, - const int32_t nTransparancy); - private: - static CFX_ByteString GetAppStreamFromArray(const CPWL_PathData* pPathData, - int32_t nCount); - static void GetPathDataFromArray(CFX_PathData& path, - const CPWL_PathData* pPathData, - int32_t nCount); + static CFX_FloatRect ScaleRect(const CFX_FloatRect& rcRect, FX_FLOAT fScale); static CFX_ByteString GetAppStream_Check(const CFX_FloatRect& rcBBox, const CPWL_Color& crText); @@ -313,87 +159,6 @@ class CPWL_Utils { static CFX_ByteString GetAP_Star(const CFX_FloatRect& crBBox); static CFX_ByteString GetAP_HalfCircle(const CFX_FloatRect& crBBox, FX_FLOAT fRotate); - - static void GetGraphics_Checkmark(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Circle(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Comment(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Cross(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Help(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_InsertText(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Key(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_NewParagraph(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_TextNote(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Paragraph(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_RightArrow(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_RightPointer(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Star(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_UpArrow(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_UpLeftArrow(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Graph(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Paperclip(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Attachment(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Tag(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); - static void GetGraphics_Foxit(CFX_ByteString& sPathData, - CFX_PathData& path, - const CFX_FloatRect& crBBox, - const PWL_PATH_TYPE type); }; #endif // FPDFSDK_PDFWINDOW_PWL_UTILS_H_ diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.cpp b/fpdfsdk/pdfwindow/PWL_Wnd.cpp index 8fd7b1621..14024dd5d 100644 --- a/fpdfsdk/pdfwindow/PWL_Wnd.cpp +++ b/fpdfsdk/pdfwindow/PWL_Wnd.cpp @@ -32,7 +32,6 @@ PWL_CREATEPARAM::PWL_CREATEPARAM() dwBorderWidth(1), sBorderColor(), sTextColor(), - sTextStrokeColor(), nTransparency(255), fFontSize(PWL_DEFAULT_FONTSIZE), sDash(3, 0, 0), @@ -421,13 +420,11 @@ void CPWL_Wnd::InvalidateRect(CFX_FloatRect* pRect) { } PWL_IMPLEMENT_KEY_METHOD(OnKeyDown) -PWL_IMPLEMENT_KEY_METHOD(OnKeyUp) PWL_IMPLEMENT_KEY_METHOD(OnChar) #undef PWL_IMPLEMENT_KEY_METHOD #define PWL_IMPLEMENT_MOUSE_METHOD(mouse_method_name) \ - bool CPWL_Wnd::mouse_method_name(const CFX_FloatPoint& point, \ - uint32_t nFlag) { \ + bool CPWL_Wnd::mouse_method_name(const CFX_PointF& point, uint32_t nFlag) { \ if (!IsValid() || !IsVisible() || !IsEnabled()) \ return false; \ if (IsWndCaptureMouse(this)) { \ @@ -453,16 +450,13 @@ PWL_IMPLEMENT_KEY_METHOD(OnChar) PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDblClk) PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonDown) PWL_IMPLEMENT_MOUSE_METHOD(OnLButtonUp) -PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDblClk) -PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonDown) -PWL_IMPLEMENT_MOUSE_METHOD(OnMButtonUp) PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonDown) PWL_IMPLEMENT_MOUSE_METHOD(OnRButtonUp) PWL_IMPLEMENT_MOUSE_METHOD(OnMouseMove) #undef PWL_IMPLEMENT_MOUSE_METHOD bool CPWL_Wnd::OnMouseWheel(short zDelta, - const CFX_FloatPoint& point, + const CFX_PointF& point, uint32_t nFlag) { if (!IsValid() || !IsVisible() || !IsEnabled()) return false; @@ -534,10 +528,10 @@ CFX_FloatRect CPWL_Wnd::GetClientRect() const { return rcWindow.Contains(rcClient) ? rcClient : CFX_FloatRect(); } -CFX_FloatPoint CPWL_Wnd::GetCenterPoint() const { +CFX_PointF CPWL_Wnd::GetCenterPoint() const { CFX_FloatRect rcClient = GetClientRect(); - return CFX_FloatPoint((rcClient.left + rcClient.right) * 0.5f, - (rcClient.top + rcClient.bottom) * 0.5f); + return CFX_PointF((rcClient.left + rcClient.right) * 0.5f, + (rcClient.top + rcClient.bottom) * 0.5f); } bool CPWL_Wnd::HasFlag(uint32_t dwFlags) const { @@ -560,22 +554,10 @@ void CPWL_Wnd::SetBackgroundColor(const CPWL_Color& color) { m_sPrivateParam.sBackgroundColor = color; } -void CPWL_Wnd::SetTextColor(const CPWL_Color& color) { - m_sPrivateParam.sTextColor = color; -} - -void CPWL_Wnd::SetTextStrokeColor(const CPWL_Color& color) { - m_sPrivateParam.sTextStrokeColor = color; -} - CPWL_Color CPWL_Wnd::GetTextColor() const { return m_sPrivateParam.sTextColor; } -CPWL_Color CPWL_Wnd::GetTextStrokeColor() const { - return m_sPrivateParam.sTextStrokeColor; -} - BorderStyle CPWL_Wnd::GetBorderStyle() const { return m_sPrivateParam.nBorderStyle; } @@ -633,7 +615,7 @@ void CPWL_Wnd::CreateVScrollBar(const PWL_CREATEPARAM& cp) { scp.pParentWnd = this; scp.sBackgroundColor = PWL_DEFAULT_WHITECOLOR; scp.eCursorType = FXCT_ARROW; - scp.nTransparency = PWL_SCROLLBAR_TRANSPARANCY; + scp.nTransparency = PWL_SCROLLBAR_TRANSPARENCY; m_pVScrollBar = new CPWL_ScrollBar(SBT_VSCROLL); m_pVScrollBar->Create(scp); @@ -673,12 +655,12 @@ void CPWL_Wnd::OnSetFocus() {} void CPWL_Wnd::OnKillFocus() {} -bool CPWL_Wnd::WndHitTest(const CFX_FloatPoint& point) const { - return IsValid() && IsVisible() && GetWindowRect().Contains(point.x, point.y); +bool CPWL_Wnd::WndHitTest(const CFX_PointF& point) const { + return IsValid() && IsVisible() && GetWindowRect().Contains(point); } -bool CPWL_Wnd::ClientHitTest(const CFX_FloatPoint& point) const { - return IsValid() && IsVisible() && GetClientRect().Contains(point.x, point.y); +bool CPWL_Wnd::ClientHitTest(const CFX_PointF& point) const { + return IsValid() && IsVisible() && GetClientRect().Contains(point); } const CPWL_Wnd* CPWL_Wnd::GetRootWnd() const { @@ -823,7 +805,7 @@ CPWL_Color CPWL_Wnd::GetBorderLeftTopColor(BorderStyle nBorderStyle) const { CPWL_Color CPWL_Wnd::GetBorderRightBottomColor(BorderStyle nBorderStyle) const { switch (nBorderStyle) { case BorderStyle::BEVELED: - return CPWL_Utils::DevideColor(GetBackgroundColor(), 2); + return GetBackgroundColor() / 2.0f; case BorderStyle::INSET: return CPWL_Color(COLORTYPE_GRAY, 0.75f); default: @@ -850,16 +832,6 @@ CFX_Matrix CPWL_Wnd::GetWindowMatrix() const { return mt; } -void CPWL_Wnd::PWLtoWnd(const CFX_FloatPoint& point, - int32_t& x, - int32_t& y) const { - CFX_Matrix mt = GetWindowMatrix(); - CFX_FloatPoint pt = point; - mt.Transform(pt.x, pt.y); - x = (int32_t)(pt.x + 0.5); - y = (int32_t)(pt.y + 0.5); -} - FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const { CFX_FloatRect rcTemp = rect; CFX_Matrix mt = GetWindowMatrix(); @@ -868,35 +840,13 @@ FX_RECT CPWL_Wnd::PWLtoWnd(const CFX_FloatRect& rect) const { (int32_t)(rcTemp.right + 0.5), (int32_t)(rcTemp.top + 0.5)); } -CFX_FloatPoint CPWL_Wnd::ChildToParent(const CFX_FloatPoint& point) const { - CFX_Matrix mt = GetChildMatrix(); - if (mt.IsIdentity()) - return point; - - CFX_FloatPoint pt = point; - mt.Transform(pt.x, pt.y); - return pt; -} - -CFX_FloatRect CPWL_Wnd::ChildToParent(const CFX_FloatRect& rect) const { - CFX_Matrix mt = GetChildMatrix(); - if (mt.IsIdentity()) - return rect; - - CFX_FloatRect rc = rect; - mt.TransformRect(rc); - return rc; -} - -CFX_FloatPoint CPWL_Wnd::ParentToChild(const CFX_FloatPoint& point) const { +CFX_PointF CPWL_Wnd::ParentToChild(const CFX_PointF& point) const { CFX_Matrix mt = GetChildMatrix(); if (mt.IsIdentity()) return point; mt.SetReverse(mt); - CFX_FloatPoint pt = point; - mt.Transform(pt.x, pt.y); - return pt; + return mt.Transform(point); } CFX_FloatRect CPWL_Wnd::ParentToChild(const CFX_FloatRect& rect) const { @@ -910,18 +860,6 @@ CFX_FloatRect CPWL_Wnd::ParentToChild(const CFX_FloatRect& rect) const { return rc; } -FX_FLOAT CPWL_Wnd::GetItemHeight(FX_FLOAT fLimitWidth) { - return 0; -} - -FX_FLOAT CPWL_Wnd::GetItemLeftMargin() { - return 0; -} - -FX_FLOAT CPWL_Wnd::GetItemRightMargin() { - return 0; -} - CFX_Matrix CPWL_Wnd::GetChildToRoot() const { CFX_Matrix mt(1, 0, 0, 1, 0, 0); if (HasFlag(PWS_CHILD)) { @@ -959,40 +897,19 @@ void CPWL_Wnd::EnableWindow(bool bEnable) { pChild->EnableWindow(bEnable); } m_bEnabled = bEnable; - if (bEnable) - OnEnabled(); - else - OnDisabled(); -} - -bool CPWL_Wnd::IsEnabled() { - return m_bEnabled; } -void CPWL_Wnd::OnEnabled() {} - -void CPWL_Wnd::OnDisabled() {} - bool CPWL_Wnd::IsCTRLpressed(uint32_t nFlag) const { - if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) { - return pSystemHandler->IsCTRLKeyDown(nFlag); - } - - return false; + CFX_SystemHandler* pSystemHandler = GetSystemHandler(); + return pSystemHandler && pSystemHandler->IsCTRLKeyDown(nFlag); } bool CPWL_Wnd::IsSHIFTpressed(uint32_t nFlag) const { - if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) { - return pSystemHandler->IsSHIFTKeyDown(nFlag); - } - - return false; + CFX_SystemHandler* pSystemHandler = GetSystemHandler(); + return pSystemHandler && pSystemHandler->IsSHIFTKeyDown(nFlag); } bool CPWL_Wnd::IsALTpressed(uint32_t nFlag) const { - if (CFX_SystemHandler* pSystemHandler = GetSystemHandler()) { - return pSystemHandler->IsALTKeyDown(nFlag); - } - - return false; + CFX_SystemHandler* pSystemHandler = GetSystemHandler(); + return pSystemHandler && pSystemHandler->IsALTKeyDown(nFlag); } diff --git a/fpdfsdk/pdfwindow/PWL_Wnd.h b/fpdfsdk/pdfwindow/PWL_Wnd.h index dd4f321d8..55836d43a 100644 --- a/fpdfsdk/pdfwindow/PWL_Wnd.h +++ b/fpdfsdk/pdfwindow/PWL_Wnd.h @@ -121,7 +121,7 @@ inline bool operator!=(const CPWL_Color& c1, const CPWL_Color& c2) { #define PWL_SCROLLBAR_WIDTH 12.0f #define PWL_SCROLLBAR_BUTTON_WIDTH 9.0f #define PWL_SCROLLBAR_POSBUTTON_MINWIDTH 2.0f -#define PWL_SCROLLBAR_TRANSPARANCY 150 +#define PWL_SCROLLBAR_TRANSPARENCY 150 #define PWL_SCROLLBAR_BKCOLOR \ CPWL_Color(COLORTYPE_RGB, 220.0f / 255.0f, 220.0f / 255.0f, 220.0f / 255.0f) #define PWL_DEFAULT_SELTEXTCOLOR CPWL_Color(COLORTYPE_RGB, 1, 1, 1) @@ -181,7 +181,6 @@ struct PWL_CREATEPARAM { dwBorderWidth = 0; sBorderColor.Reset(); sTextColor.Reset(); - sTextStrokeColor.Reset(); nTransparency = 0; fFontSize = 0.0f; sDash.Reset(); @@ -204,7 +203,6 @@ struct PWL_CREATEPARAM { int32_t dwBorderWidth; // optional CPWL_Color sBorderColor; // optional CPWL_Color sTextColor; // optional - CPWL_Color sTextStrokeColor; // optional int32_t nTransparency; // optional FX_FLOAT fFontSize; // optional CPWL_Dash sDash; // optional @@ -245,85 +243,83 @@ class CPWL_TimerHandler { }; class CPWL_Wnd : public CPWL_TimerHandler { - friend class CPWL_MsgControl; - public: CPWL_Wnd(); ~CPWL_Wnd() override; - void Create(const PWL_CREATEPARAM& cp); virtual CFX_ByteString GetClassName() const; - void InvalidateFocusHandler(IPWL_FocusHandler* handler); - void InvalidateProvider(IPWL_Provider* provider); - void Destroy(); - void Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh); virtual void InvalidateRect(CFX_FloatRect* pRect = nullptr); - void DrawAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device); - virtual bool OnKeyDown(uint16_t nChar, uint32_t nFlag); - virtual bool OnKeyUp(uint16_t nChar, uint32_t nFlag); virtual bool OnChar(uint16_t nChar, uint32_t nFlag); - virtual bool OnLButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnLButtonDown(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnLButtonUp(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnMButtonDblClk(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnMButtonDown(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnMButtonUp(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnRButtonDown(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnRButtonUp(const CFX_FloatPoint& point, uint32_t nFlag); - virtual bool OnMouseMove(const CFX_FloatPoint& point, uint32_t nFlag); + virtual bool OnLButtonDblClk(const CFX_PointF& point, uint32_t nFlag); + virtual bool OnLButtonDown(const CFX_PointF& point, uint32_t nFlag); + virtual bool OnLButtonUp(const CFX_PointF& point, uint32_t nFlag); + virtual bool OnRButtonDown(const CFX_PointF& point, uint32_t nFlag); + virtual bool OnRButtonUp(const CFX_PointF& point, uint32_t nFlag); + virtual bool OnMouseMove(const CFX_PointF& point, uint32_t nFlag); virtual bool OnMouseWheel(short zDelta, - const CFX_FloatPoint& point, + const CFX_PointF& point, uint32_t nFlag); - - virtual void SetFocus(); - virtual void KillFocus(); - void SetCapture(); - void ReleaseCapture(); - virtual void OnNotify(CPWL_Wnd* pWnd, uint32_t msg, intptr_t wParam = 0, intptr_t lParam = 0); - virtual void SetTextColor(const CPWL_Color& color); - virtual void SetTextStrokeColor(const CPWL_Color& color); + virtual void SetFocus(); + virtual void KillFocus(); + virtual void SetCursor(); virtual void SetVisible(bool bVisible); + virtual void SetFontSize(FX_FLOAT fFontSize); + virtual FX_FLOAT GetFontSize() const; virtual CFX_FloatRect GetFocusRect() const; - virtual CPWL_Color GetBackgroundColor() const; - virtual CPWL_Color GetBorderColor() const; - virtual CPWL_Color GetTextColor() const; - virtual CPWL_Color GetTextStrokeColor() const; - virtual FX_FLOAT GetFontSize() const; - virtual int32_t GetInnerBorderWidth() const; - virtual CPWL_Color GetBorderLeftTopColor(BorderStyle nBorderStyle) const; - virtual CPWL_Color GetBorderRightBottomColor(BorderStyle nBorderStyle) const; + virtual CFX_FloatRect GetClientRect() const; - virtual void SetFontSize(FX_FLOAT fFontSize); + void InvalidateFocusHandler(IPWL_FocusHandler* handler); + void InvalidateProvider(IPWL_Provider* provider); + void Create(const PWL_CREATEPARAM& cp); + void Destroy(); + void Move(const CFX_FloatRect& rcNew, bool bReset, bool bRefresh); + + void SetCapture(); + void ReleaseCapture(); + + void DrawAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device); + CPWL_Color GetBackgroundColor() const; void SetBackgroundColor(const CPWL_Color& color); - void SetClipRect(const CFX_FloatRect& rect); + CPWL_Color GetBorderColor() const; + CPWL_Color GetTextColor() const; + void SetTextColor(const CPWL_Color& color); + CPWL_Color GetBorderLeftTopColor(BorderStyle nBorderStyle) const; + CPWL_Color GetBorderRightBottomColor(BorderStyle nBorderStyle) const; + void SetBorderStyle(BorderStyle eBorderStyle); + BorderStyle GetBorderStyle() const; + const CPWL_Dash& GetBorderDash() const; - virtual CFX_FloatRect GetWindowRect() const; - virtual CFX_FloatRect GetClientRect() const; - CFX_FloatPoint GetCenterPoint() const; int32_t GetBorderWidth() const; + int32_t GetInnerBorderWidth() const; + CFX_FloatRect GetWindowRect() const; + CFX_PointF GetCenterPoint() const; + bool IsVisible() const { return m_bVisible; } bool HasFlag(uint32_t dwFlags) const; void AddFlag(uint32_t dwFlags); void RemoveFlag(uint32_t dwFlags); + + void SetClipRect(const CFX_FloatRect& rect); const CFX_FloatRect& GetClipRect() const; + CPWL_Wnd* GetParentWindow() const; - BorderStyle GetBorderStyle() const; - const CPWL_Dash& GetBorderDash() const; void* GetAttachedData() const; - bool WndHitTest(const CFX_FloatPoint& point) const; - bool ClientHitTest(const CFX_FloatPoint& point) const; + bool WndHitTest(const CFX_PointF& point) const; + bool ClientHitTest(const CFX_PointF& point) const; bool IsCaptureMouse() const; + void EnableWindow(bool bEnable); + bool IsEnabled() const { return m_bEnabled; } const CPWL_Wnd* GetFocused() const; bool IsFocused() const; bool IsReadOnly() const; @@ -341,34 +337,18 @@ class CPWL_Wnd : public CPWL_TimerHandler { void SetChildMatrix(const CFX_Matrix& mt); CFX_Matrix GetWindowMatrix() const; - virtual CFX_FloatPoint ChildToParent(const CFX_FloatPoint& point) const; - virtual CFX_FloatRect ChildToParent(const CFX_FloatRect& rect) const; - virtual CFX_FloatPoint ParentToChild(const CFX_FloatPoint& point) const; - virtual CFX_FloatRect ParentToChild(const CFX_FloatRect& rect) const; - - // those methods only implemented by listctrl item - virtual FX_FLOAT GetItemHeight(FX_FLOAT fLimitWidth); - virtual FX_FLOAT GetItemLeftMargin(); - virtual FX_FLOAT GetItemRightMargin(); - - void EnableWindow(bool bEnable); - bool IsEnabled(); - virtual void SetCursor(); - protected: + friend class CPWL_MsgControl; + // CPWL_TimerHandler CFX_SystemHandler* GetSystemHandler() const override; virtual void CreateChildWnd(const PWL_CREATEPARAM& cp); virtual void RePosChildWnd(); - void GetAppearanceStream(CFX_ByteTextBuf& sAppStream); virtual void GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream); - virtual void GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream); virtual void DrawThisAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device); - virtual void DrawChildAppearance(CFX_RenderDevice* pDevice, - CFX_Matrix* pUser2Device); virtual void OnCreate(PWL_CREATEPARAM& cp); virtual void OnCreated(); @@ -377,9 +357,7 @@ class CPWL_Wnd : public CPWL_TimerHandler { virtual void OnSetFocus(); virtual void OnKillFocus(); - virtual void OnEnabled(); - virtual void OnDisabled(); - + void GetAppearanceStream(CFX_ByteTextBuf& sAppStream); void SetNotifyFlag(bool bNotifying = true) { m_bNotifying = bNotifying; } bool IsValid() const; @@ -389,9 +367,6 @@ class CPWL_Wnd : public CPWL_TimerHandler { void InvalidateRectMove(const CFX_FloatRect& rcOld, const CFX_FloatRect& rcNew); - void PWLtoWnd(const CFX_FloatPoint& point, int32_t& x, int32_t& y) const; - FX_RECT PWLtoWnd(const CFX_FloatRect& rect) const; - bool IsWndCaptureMouse(const CPWL_Wnd* pWnd) const; bool IsWndCaptureKeyboard(const CPWL_Wnd* pWnd) const; const CPWL_Wnd* GetRootWnd() const; @@ -401,6 +376,14 @@ class CPWL_Wnd : public CPWL_TimerHandler { bool IsALTpressed(uint32_t nFlag) const; private: + CFX_PointF ParentToChild(const CFX_PointF& point) const; + CFX_FloatRect ParentToChild(const CFX_FloatRect& rect) const; + + void GetChildAppearanceStream(CFX_ByteTextBuf& sAppStream); + void DrawChildAppearance(CFX_RenderDevice* pDevice, CFX_Matrix* pUser2Device); + + FX_RECT PWLtoWnd(const CFX_FloatRect& rect) const; + void AddChild(CPWL_Wnd* pWnd); void RemoveChild(CPWL_Wnd* pWnd); @@ -413,10 +396,7 @@ class CPWL_Wnd : public CPWL_TimerHandler { CPWL_MsgControl* GetMsgControl() const; - protected: std::vector<CPWL_Wnd*> m_Children; - - private: PWL_CREATEPARAM m_sPrivateParam; CPWL_ScrollBar* m_pVScrollBar; CFX_FloatRect m_rcWindow; diff --git a/fpdfsdk/pdfwindow/cpwl_color.cpp b/fpdfsdk/pdfwindow/cpwl_color.cpp new file mode 100644 index 000000000..9c9ca3eff --- /dev/null +++ b/fpdfsdk/pdfwindow/cpwl_color.cpp @@ -0,0 +1,179 @@ +// Copyright 2017 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 "fpdfsdk/pdfwindow/cpwl_color.h" + +#include <algorithm> + +namespace { + +bool InRange(FX_FLOAT comp) { + return comp >= 0.0f && comp <= 1.0f; +} + +CPWL_Color ConvertCMYK2GRAY(FX_FLOAT dC, + FX_FLOAT dM, + FX_FLOAT dY, + FX_FLOAT dK) { + if (!InRange(dC) || !InRange(dM) || !InRange(dY) || !InRange(dK)) + return CPWL_Color(COLORTYPE_GRAY); + return CPWL_Color( + COLORTYPE_GRAY, + 1.0f - std::min(1.0f, 0.3f * dC + 0.59f * dM + 0.11f * dY + dK)); +} + +CPWL_Color ConvertGRAY2CMYK(FX_FLOAT dGray) { + if (!InRange(dGray)) + return CPWL_Color(COLORTYPE_CMYK); + return CPWL_Color(COLORTYPE_CMYK, 0.0f, 0.0f, 0.0f, 1.0f - dGray); +} + +CPWL_Color ConvertGRAY2RGB(FX_FLOAT dGray) { + if (!InRange(dGray)) + return CPWL_Color(COLORTYPE_RGB); + return CPWL_Color(COLORTYPE_RGB, dGray, dGray, dGray); +} + +CPWL_Color ConvertRGB2GRAY(FX_FLOAT dR, FX_FLOAT dG, FX_FLOAT dB) { + if (!InRange(dR) || !InRange(dG) || !InRange(dB)) + return CPWL_Color(COLORTYPE_GRAY); + return CPWL_Color(COLORTYPE_GRAY, 0.3f * dR + 0.59f * dG + 0.11f * dB); +} + +CPWL_Color ConvertCMYK2RGB(FX_FLOAT dC, FX_FLOAT dM, FX_FLOAT dY, FX_FLOAT dK) { + if (!InRange(dC) || !InRange(dM) || !InRange(dY) || !InRange(dK)) + return CPWL_Color(COLORTYPE_RGB); + return CPWL_Color(COLORTYPE_RGB, 1.0f - std::min(1.0f, dC + dK), + 1.0f - std::min(1.0f, dM + dK), + 1.0f - std::min(1.0f, dY + dK)); +} + +CPWL_Color ConvertRGB2CMYK(FX_FLOAT dR, FX_FLOAT dG, FX_FLOAT dB) { + if (!InRange(dR) || !InRange(dG) || !InRange(dB)) + return CPWL_Color(COLORTYPE_CMYK); + + FX_FLOAT c = 1.0f - dR; + FX_FLOAT m = 1.0f - dG; + FX_FLOAT y = 1.0f - dB; + return CPWL_Color(COLORTYPE_CMYK, c, m, y, std::min(c, std::min(m, y))); +} + +} // namespace + +CPWL_Color CPWL_Color::ConvertColorType(int32_t nConvertColorType) const { + if (nColorType == nConvertColorType) + return *this; + + CPWL_Color ret; + switch (nColorType) { + case COLORTYPE_TRANSPARENT: + ret = *this; + ret.nColorType = COLORTYPE_TRANSPARENT; + break; + case COLORTYPE_GRAY: + switch (nConvertColorType) { + case COLORTYPE_RGB: + ret = ConvertGRAY2RGB(fColor1); + break; + case COLORTYPE_CMYK: + ret = ConvertGRAY2CMYK(fColor1); + break; + } + break; + case COLORTYPE_RGB: + switch (nConvertColorType) { + case COLORTYPE_GRAY: + ret = ConvertRGB2GRAY(fColor1, fColor2, fColor3); + break; + case COLORTYPE_CMYK: + ret = ConvertRGB2CMYK(fColor1, fColor2, fColor3); + break; + } + break; + case COLORTYPE_CMYK: + switch (nConvertColorType) { + case COLORTYPE_GRAY: + ret = ConvertCMYK2GRAY(fColor1, fColor2, fColor3, fColor4); + break; + case COLORTYPE_RGB: + ret = ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4); + break; + } + break; + } + return ret; +} + +FX_COLORREF CPWL_Color::ToFXColor(int32_t nTransparency) const { + CPWL_Color ret; + switch (nColorType) { + case COLORTYPE_TRANSPARENT: { + ret = CPWL_Color(COLORTYPE_TRANSPARENT, 0, 0, 0, 0); + break; + } + case COLORTYPE_GRAY: { + ret = ConvertGRAY2RGB(fColor1); + ret.fColor4 = nTransparency; + break; + } + case COLORTYPE_RGB: { + ret = CPWL_Color(COLORTYPE_RGB, fColor1, fColor2, fColor3); + ret.fColor4 = nTransparency; + break; + } + case COLORTYPE_CMYK: { + ret = ConvertCMYK2RGB(fColor1, fColor2, fColor3, fColor4); + ret.fColor4 = nTransparency; + break; + } + } + return ArgbEncode(ret.fColor4, static_cast<int32_t>(ret.fColor1 * 255), + static_cast<int32_t>(ret.fColor2 * 255), + static_cast<int32_t>(ret.fColor3 * 255)); +} + +CPWL_Color CPWL_Color::operator-(FX_FLOAT fColorSub) const { + CPWL_Color sRet(nColorType); + switch (nColorType) { + case COLORTYPE_TRANSPARENT: + sRet.nColorType = COLORTYPE_RGB; + sRet.fColor1 = std::max(1.0f - fColorSub, 0.0f); + sRet.fColor2 = std::max(1.0f - fColorSub, 0.0f); + sRet.fColor3 = std::max(1.0f - fColorSub, 0.0f); + break; + case COLORTYPE_RGB: + case COLORTYPE_GRAY: + case COLORTYPE_CMYK: + sRet.fColor1 = std::max(fColor1 - fColorSub, 0.0f); + sRet.fColor2 = std::max(fColor2 - fColorSub, 0.0f); + sRet.fColor3 = std::max(fColor3 - fColorSub, 0.0f); + sRet.fColor4 = std::max(fColor4 - fColorSub, 0.0f); + break; + } + return sRet; +} + +CPWL_Color CPWL_Color::operator/(FX_FLOAT fColorDivide) const { + CPWL_Color sRet(nColorType); + switch (nColorType) { + case COLORTYPE_TRANSPARENT: + sRet.nColorType = COLORTYPE_RGB; + sRet.fColor1 = 1.0f / fColorDivide; + sRet.fColor2 = 1.0f / fColorDivide; + sRet.fColor3 = 1.0f / fColorDivide; + break; + case COLORTYPE_RGB: + case COLORTYPE_GRAY: + case COLORTYPE_CMYK: + sRet = *this; + sRet.fColor1 /= fColorDivide; + sRet.fColor2 /= fColorDivide; + sRet.fColor3 /= fColorDivide; + sRet.fColor4 /= fColorDivide; + break; + } + return sRet; +} diff --git a/fpdfsdk/pdfwindow/cpwl_color.h b/fpdfsdk/pdfwindow/cpwl_color.h index c1f9e6ea9..f1b34c7eb 100644 --- a/fpdfsdk/pdfwindow/cpwl_color.h +++ b/fpdfsdk/pdfwindow/cpwl_color.h @@ -28,7 +28,12 @@ struct CPWL_Color { fColor3(b / 255.0f), fColor4(0) {} - void ConvertColorType(int32_t other_nColorType); + CPWL_Color operator/(FX_FLOAT fColorDivide) const; + CPWL_Color operator-(FX_FLOAT fColorSub) const; + + CPWL_Color ConvertColorType(int32_t other_nColorType) const; + + FX_COLORREF ToFXColor(int32_t nTransparency) const; void Reset() { nColorType = COLORTYPE_TRANSPARENT; diff --git a/fxjs/fxjs_v8.cpp b/fxjs/fxjs_v8.cpp index c96cc1f0e..b0e1a1b26 100644 --- a/fxjs/fxjs_v8.cpp +++ b/fxjs/fxjs_v8.cpp @@ -20,12 +20,32 @@ static v8::Isolate* g_isolate = nullptr; static size_t g_isolate_ref_count = 0; static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr; static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr; +static wchar_t kPerObjectDataTag[] = L"CFXJS_PerObjectData"; class CFXJS_PerObjectData { public: explicit CFXJS_PerObjectData(int nObjDefID) : m_ObjDefID(nObjDefID), m_pPrivate(nullptr) {} + static void SetInObject(CFXJS_PerObjectData* pData, + v8::Local<v8::Object> pObj) { + if (pObj->InternalFieldCount() == 2) { + pObj->SetAlignedPointerInInternalField(0, pData); + pObj->SetAlignedPointerInInternalField( + 1, static_cast<void*>(kPerObjectDataTag)); + } + } + + static CFXJS_PerObjectData* GetFromObject(v8::Local<v8::Object> pObj) { + if (pObj.IsEmpty() || pObj->InternalFieldCount() != 2 || + pObj->GetAlignedPointerFromInternalField(1) != + static_cast<void*>(kPerObjectDataTag)) { + return nullptr; + } + return static_cast<CFXJS_PerObjectData*>( + pObj->GetAlignedPointerFromInternalField(0)); + } + const int m_ObjDefID; void* m_pPrivate; }; @@ -42,7 +62,7 @@ class CFXJS_ObjDefinition { } CFXJS_ObjDefinition(v8::Isolate* isolate, - const wchar_t* sObjName, + const char* sObjName, FXJSOBJTYPE eObjType, CFXJS_Engine::Constructor pConstructor, CFXJS_Engine::Destructor pDestructor) @@ -56,6 +76,12 @@ class CFXJS_ObjDefinition { v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); fun->InstanceTemplate()->SetInternalFieldCount(2); + fun->SetCallHandler([](const v8::FunctionCallbackInfo<v8::Value>& info) { + v8::Local<v8::Object> holder = info.Holder(); + ASSERT(holder->InternalFieldCount() == 2); + holder->SetAlignedPointerInInternalField(0, nullptr); + holder->SetAlignedPointerInInternalField(1, nullptr); + }); if (eObjType == FXJSOBJTYPE_GLOBAL) { fun->InstanceTemplate()->Set( v8::Symbol::GetToStringTag(isolate), @@ -86,7 +112,7 @@ class CFXJS_ObjDefinition { return scope.Escape(m_Signature.Get(m_pIsolate)); } - const wchar_t* const m_ObjName; + const char* const m_ObjName; const FXJSOBJTYPE m_ObjType; const CFXJS_Engine::Constructor m_pConstructor; const CFXJS_Engine::Destructor m_pDestructor; @@ -235,13 +261,8 @@ CFXJS_Engine* CFXJS_Engine::CurrentEngineFromIsolate(v8::Isolate* pIsolate) { // static int CFXJS_Engine::GetObjDefnID(v8::Local<v8::Object> pObj) { - if (pObj.IsEmpty() || !pObj->InternalFieldCount()) - return -1; - CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>( - pObj->GetAlignedPointerFromInternalField(0)); - if (!pPerObjectData) - return -1; - return pPerObjectData->m_ObjDefID; + CFXJS_PerObjectData* pData = CFXJS_PerObjectData::GetFromObject(pObj); + return pData ? pData->m_ObjDefID : -1; } // static @@ -251,13 +272,13 @@ void CFXJS_Engine::FreeObjectPrivate(void* pPerObjectData) { // static void CFXJS_Engine::FreeObjectPrivate(v8::Local<v8::Object> pObj) { - if (pObj.IsEmpty() || !pObj->InternalFieldCount()) - return; - FreeObjectPrivate(pObj->GetAlignedPointerFromInternalField(0)); + CFXJS_PerObjectData* pData = CFXJS_PerObjectData::GetFromObject(pObj); pObj->SetAlignedPointerInInternalField(0, nullptr); + pObj->SetAlignedPointerInInternalField(1, nullptr); + delete pData; } -int CFXJS_Engine::DefineObj(const wchar_t* sObjName, +int CFXJS_Engine::DefineObj(const char* sObjName, FXJSOBJTYPE eObjType, CFXJS_Engine::Constructor pConstructor, CFXJS_Engine::Destructor pDestructor) { @@ -270,35 +291,32 @@ int CFXJS_Engine::DefineObj(const wchar_t* sObjName, } void CFXJS_Engine::DefineObjMethod(int nObjDefnID, - const wchar_t* sMethodName, + const char* sMethodName, v8::FunctionCallback pMethodCall) { v8::Isolate::Scope isolate_scope(m_isolate); v8::HandleScope handle_scope(m_isolate); - CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID); v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New( m_isolate, pMethodCall, v8::Local<v8::Value>(), pObjDef->GetSignature()); fun->RemovePrototype(); pObjDef->GetInstanceTemplate()->Set( - v8::String::NewFromUtf8(m_isolate, bsMethodName.c_str(), + v8::String::NewFromUtf8(m_isolate, sMethodName, v8::NewStringType::kNormal) .ToLocalChecked(), fun, v8::ReadOnly); } void CFXJS_Engine::DefineObjProperty(int nObjDefnID, - const wchar_t* sPropName, + const char* sPropName, v8::AccessorGetterCallback pPropGet, v8::AccessorSetterCallback pPropPut) { v8::Isolate::Scope isolate_scope(m_isolate); v8::HandleScope handle_scope(m_isolate); - CFX_ByteString bsPropertyName = CFX_WideString(sPropName).UTF8Encode(); CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID); pObjDef->GetInstanceTemplate()->SetAccessor( - v8::String::NewFromUtf8(m_isolate, bsPropertyName.c_str(), - v8::NewStringType::kNormal) + v8::String::NewFromUtf8(m_isolate, sPropName, v8::NewStringType::kNormal) .ToLocalChecked(), pPropGet, pPropPut); } @@ -318,26 +336,24 @@ void CFXJS_Engine::DefineObjAllProperties( } void CFXJS_Engine::DefineObjConst(int nObjDefnID, - const wchar_t* sConstName, + const char* sConstName, v8::Local<v8::Value> pDefault) { v8::Isolate::Scope isolate_scope(m_isolate); v8::HandleScope handle_scope(m_isolate); - CFX_ByteString bsConstName = CFX_WideString(sConstName).UTF8Encode(); CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID); - pObjDef->GetInstanceTemplate()->Set(m_isolate, bsConstName.c_str(), pDefault); + pObjDef->GetInstanceTemplate()->Set(m_isolate, sConstName, pDefault); } -void CFXJS_Engine::DefineGlobalMethod(const wchar_t* sMethodName, +void CFXJS_Engine::DefineGlobalMethod(const char* sMethodName, v8::FunctionCallback pMethodCall) { v8::Isolate::Scope isolate_scope(m_isolate); v8::HandleScope handle_scope(m_isolate); - CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode(); v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(m_isolate, pMethodCall); fun->RemovePrototype(); GetGlobalObjectTemplate(m_isolate)->Set( - v8::String::NewFromUtf8(m_isolate, bsMethodName.c_str(), + v8::String::NewFromUtf8(m_isolate, sMethodName, v8::NewStringType::kNormal) .ToLocalChecked(), fun, v8::ReadOnly); @@ -347,7 +363,7 @@ void CFXJS_Engine::DefineGlobalConst(const wchar_t* sConstName, v8::FunctionCallback pConstGetter) { v8::Isolate::Scope isolate_scope(m_isolate); v8::HandleScope handle_scope(m_isolate); - CFX_ByteString bsConst = CFX_WideString(sConstName).UTF8Encode(); + CFX_ByteString bsConst = FX_UTF8Encode(CFX_WideStringC(sConstName)); v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(m_isolate, pConstGetter); fun->RemovePrototype(); @@ -380,26 +396,26 @@ void CFXJS_Engine::InitializeEngine() { for (int i = 0; i < maxID; ++i) { CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(m_isolate, i); if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) { - v8Context->Global() - ->GetPrototype() - ->ToObject(v8Context) - .ToLocalChecked() - ->SetAlignedPointerInInternalField(0, new CFXJS_PerObjectData(i)); - - if (pObjDef->m_pConstructor) + CFXJS_PerObjectData::SetInObject(new CFXJS_PerObjectData(i), + v8Context->Global() + ->GetPrototype() + ->ToObject(v8Context) + .ToLocalChecked()); + if (pObjDef->m_pConstructor) { pObjDef->m_pConstructor(this, v8Context->Global() ->GetPrototype() ->ToObject(v8Context) .ToLocalChecked()); + } } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) { - CFX_ByteString bs = CFX_WideString(pObjDef->m_ObjName).UTF8Encode(); - v8::Local<v8::String> m_ObjName = - v8::String::NewFromUtf8(m_isolate, bs.c_str(), - v8::NewStringType::kNormal, bs.GetLength()) + v8::Local<v8::String> pObjName = + v8::String::NewFromUtf8(m_isolate, pObjDef->m_ObjName, + v8::NewStringType::kNormal, + strlen(pObjDef->m_ObjName)) .ToLocalChecked(); v8::Local<v8::Object> obj = NewFxDynamicObj(i, true); - v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust(); + v8Context->Global()->Set(v8Context, pObjName, obj).FromJust(); m_StaticObjects[i] = new v8::Global<v8::Object>(m_isolate, obj); } } @@ -499,15 +515,14 @@ v8::Local<v8::Object> CFXJS_Engine::NewFxDynamicObj(int nObjDefnID, if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj)) return v8::Local<v8::Object>(); - CFXJS_PerObjectData* pPerObjData = new CFXJS_PerObjectData(nObjDefnID); - obj->SetAlignedPointerInInternalField(0, pPerObjData); + CFXJS_PerObjectData* pObjData = new CFXJS_PerObjectData(nObjDefnID); + CFXJS_PerObjectData::SetInObject(pObjData, obj); if (pObjDef->m_pConstructor) pObjDef->m_pConstructor(this, obj); - if (!bStatic && FXJS_PerIsolateData::Get(m_isolate)->m_pDynamicObjsMap) { - FXJS_PerIsolateData::Get(m_isolate)->m_pDynamicObjsMap->set(pPerObjData, - obj); - } + if (!bStatic && FXJS_PerIsolateData::Get(m_isolate)->m_pDynamicObjsMap) + FXJS_PerIsolateData::Get(m_isolate)->m_pDynamicObjsMap->set(pObjData, obj); + return obj; } @@ -533,43 +548,25 @@ void CFXJS_Engine::Error(const CFX_WideString& message) { } void CFXJS_Engine::SetObjectPrivate(v8::Local<v8::Object> pObj, void* p) { - if (pObj.IsEmpty() || !pObj->InternalFieldCount()) - return; - CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>( - pObj->GetAlignedPointerFromInternalField(0)); + CFXJS_PerObjectData* pPerObjectData = + CFXJS_PerObjectData::GetFromObject(pObj); if (!pPerObjectData) return; pPerObjectData->m_pPrivate = p; } void* CFXJS_Engine::GetObjectPrivate(v8::Local<v8::Object> pObj) { - if (pObj.IsEmpty()) - return nullptr; - CFXJS_PerObjectData* pPerObjectData = nullptr; - if (pObj->InternalFieldCount()) { - pPerObjectData = static_cast<CFXJS_PerObjectData*>( - pObj->GetAlignedPointerFromInternalField(0)); - } else { + CFXJS_PerObjectData* pData = CFXJS_PerObjectData::GetFromObject(pObj); + if (!pData && !pObj.IsEmpty()) { // It could be a global proxy object. v8::Local<v8::Value> v = pObj->GetPrototype(); v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); if (v->IsObject()) { - pPerObjectData = static_cast<CFXJS_PerObjectData*>( - v->ToObject(context) - .ToLocalChecked() - ->GetAlignedPointerFromInternalField(0)); + pData = CFXJS_PerObjectData::GetFromObject( + v->ToObject(context).ToLocalChecked()); } } - return pPerObjectData ? pPerObjectData->m_pPrivate : nullptr; -} - -v8::Local<v8::String> CFXJS_Engine::WSToJSString( - const CFX_WideString& wsPropertyName) { - v8::Isolate* pIsolate = m_isolate ? m_isolate : v8::Isolate::GetCurrent(); - CFX_ByteString bs = wsPropertyName.UTF8Encode(); - return v8::String::NewFromUtf8(pIsolate, bs.c_str(), - v8::NewStringType::kNormal, bs.GetLength()) - .ToLocalChecked(); + return pData ? pData->m_pPrivate : nullptr; } v8::Local<v8::Value> CFXJS_Engine::GetObjectProperty( @@ -578,7 +575,8 @@ v8::Local<v8::Value> CFXJS_Engine::GetObjectProperty( if (pObj.IsEmpty()) return v8::Local<v8::Value>(); v8::Local<v8::Value> val; - if (!pObj->Get(m_isolate->GetCurrentContext(), WSToJSString(wsPropertyName)) + if (!pObj->Get(m_isolate->GetCurrentContext(), + NewString(wsPropertyName.AsStringC())) .ToLocal(&val)) return v8::Local<v8::Value>(); return val; @@ -607,7 +605,8 @@ void CFXJS_Engine::PutObjectProperty(v8::Local<v8::Object> pObj, v8::Local<v8::Value> pPut) { if (pObj.IsEmpty()) return; - pObj->Set(m_isolate->GetCurrentContext(), WSToJSString(wsPropertyName), pPut) + pObj->Set(m_isolate->GetCurrentContext(), + NewString(wsPropertyName.AsStringC()), pPut) .FromJust(); } @@ -666,8 +665,15 @@ v8::Local<v8::Value> CFXJS_Engine::NewBoolean(bool b) { return v8::Boolean::New(m_isolate, b); } -v8::Local<v8::Value> CFXJS_Engine::NewString(const CFX_WideString& str) { - return WSToJSString(str.c_str()); +v8::Local<v8::Value> CFXJS_Engine::NewString(const CFX_ByteStringC& str) { + v8::Isolate* pIsolate = m_isolate ? m_isolate : v8::Isolate::GetCurrent(); + return v8::String::NewFromUtf8(pIsolate, str.c_str(), + v8::NewStringType::kNormal, str.GetLength()) + .ToLocalChecked(); +} + +v8::Local<v8::Value> CFXJS_Engine::NewString(const CFX_WideStringC& str) { + return NewString(FX_UTF8Encode(str).AsStringC()); } v8::Local<v8::Value> CFXJS_Engine::NewNull() { diff --git a/fxjs/fxjs_v8.h b/fxjs/fxjs_v8.h index 6cf3ca578..50b0b2c6d 100644 --- a/fxjs/fxjs_v8.h +++ b/fxjs/fxjs_v8.h @@ -33,7 +33,7 @@ class CFXJS_ObjDefinition; // FXJS_V8 places no restrictions on this class; it merely passes it // on to caller-provided methods. -class IJS_Context; // A description of the event that caused JS execution. +class IJS_EventContext; // A description of the event that caused JS execution. enum FXJSOBJTYPE { FXJSOBJTYPE_DYNAMIC = 0, // Created by native method and returned to JS. @@ -142,16 +142,16 @@ class CFXJS_Engine { v8::Isolate* GetIsolate() const { return m_isolate; } // Always returns a valid, newly-created objDefnID. - int DefineObj(const wchar_t* sObjName, + int DefineObj(const char* sObjName, FXJSOBJTYPE eObjType, Constructor pConstructor, Destructor pDestructor); void DefineObjMethod(int nObjDefnID, - const wchar_t* sMethodName, + const char* sMethodName, v8::FunctionCallback pMethodCall); void DefineObjProperty(int nObjDefnID, - const wchar_t* sPropName, + const char* sPropName, v8::AccessorGetterCallback pPropGet, v8::AccessorSetterCallback pPropPut); void DefineObjAllProperties(int nObjDefnID, @@ -160,9 +160,9 @@ class CFXJS_Engine { v8::NamedPropertySetterCallback pPropPut, v8::NamedPropertyDeleterCallback pPropDel); void DefineObjConst(int nObjDefnID, - const wchar_t* sConstName, + const char* sConstName, v8::Local<v8::Value> pDefault); - void DefineGlobalMethod(const wchar_t* sMethodName, + void DefineGlobalMethod(const char* sMethodName, v8::FunctionCallback pMethodCall); void DefineGlobalConst(const wchar_t* sConstName, v8::FunctionCallback pConstGetter); @@ -184,7 +184,8 @@ class CFXJS_Engine { v8::Local<v8::Value> NewNumber(double number); v8::Local<v8::Value> NewNumber(float number); v8::Local<v8::Value> NewBoolean(bool b); - v8::Local<v8::Value> NewString(const CFX_WideString& str); + v8::Local<v8::Value> NewString(const CFX_ByteStringC& str); + v8::Local<v8::Value> NewString(const CFX_WideStringC& str); v8::Local<v8::Date> NewDate(double d); v8::Local<v8::Object> NewFxDynamicObj(int nObjDefnID, bool bStatic = false); @@ -221,7 +222,6 @@ class CFXJS_Engine { void SetConstArray(const CFX_WideString& name, v8::Local<v8::Array> array); v8::Local<v8::Array> GetConstArray(const CFX_WideString& name); - v8::Local<v8::String> WSToJSString(const CFX_WideString& wsPropertyName); void Error(const CFX_WideString& message); protected: diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index a62140148..7062e43a4 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg @@ -14,6 +14,11 @@ rietveld { verifiers { reviewer_lgtm { committer_list: "project-pdfium-committers" + dry_run_access_list: "project-pdfium-tryjob-access" + } + gerrit_cq_ability { + committer_list: "project-pdfium-committers" + dry_run_access_list: "project-pdfium-tryjob-access" } tree_status { @@ -41,7 +46,6 @@ verifiers { } builders { name: "linux_skia" - experiment_percentage: 100 } builders { name: "linux_xfa" @@ -60,7 +64,6 @@ verifiers { } builders { name: "mac_skia" - experiment_percentage: 100 } builders { name: "mac_xfa" @@ -76,7 +79,6 @@ verifiers { } builders { name: "win_skia" - experiment_percentage: 100 } builders { name: "win_xfa" diff --git a/pdfium.gni b/pdfium.gni index 5737224f7..8ce09f968 100644 --- a/pdfium.gni +++ b/pdfium.gni @@ -17,6 +17,18 @@ declare_args() { # Build PDFium either with or without XFA Forms support. pdf_enable_xfa = pdf_enable_xfa_override + # If XFA, also support bmp codec. Ignored if not XFA. + pdf_enable_xfa_bmp = true + + # If XFA, also support gif codec. Ignored if not XFA. + pdf_enable_xfa_gif = true + + # If XFA, also support png codec. Ignored if not XFA. + pdf_enable_xfa_png = true + + # If XFA, also support png codec. Ignored if not XFA. + pdf_enable_xfa_tiff = true + # Build PDFium against skia (experimental) rather than agg. Use Skia to draw everything. pdf_use_skia = pdf_use_skia_override @@ -63,6 +63,8 @@ LOCAL_SRC_FILES := \ fpdfsdk/fpdfdoc.cpp \ fpdfsdk/fpdfeditimg.cpp \ fpdfsdk/fpdfeditpage.cpp \ + fpdfsdk/fpdfeditpath.cpp \ + fpdfsdk/fpdfedittext.cpp \ fpdfsdk/fpdfformfill.cpp \ fpdfsdk/fpdfppo.cpp \ fpdfsdk/fpdfsave.cpp \ diff --git a/pdfiumpdfwindow.mk b/pdfiumpdfwindow.mk index d25c8b3f6..4bd27ef01 100644 --- a/pdfiumpdfwindow.mk +++ b/pdfiumpdfwindow.mk @@ -29,6 +29,7 @@ LOCAL_SRC_FILES := \ fpdfsdk/pdfwindow/PWL_SpecialButton.cpp \ fpdfsdk/pdfwindow/PWL_Utils.cpp \ fpdfsdk/pdfwindow/PWL_Wnd.cpp \ + fpdfsdk/pdfwindow/cpwl_color.cpp \ LOCAL_C_INCLUDES := \ external/pdfium \ diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index 640d97ed0..3350b5c6a 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -27,6 +27,9 @@ #define FPDF_PAGEOBJ_SHADING 4 #define FPDF_PAGEOBJ_FORM 5 +#define FPDF_FILLMODE_ALTERNATE 1 +#define FPDF_FILLMODE_WINDING 2 + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -260,6 +263,161 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages, FPDF_PAGEOBJECT image_object, FPDF_BITMAP bitmap); +// Create a new path object at an initial position. +// +// x - initial horizontal position. +// y - initial vertical position. +// +// Returns a handle to a new path object. +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewPath(float x, float y); + +// Create a closed path consisting of a rectangle. +// +// x - horizontal position for the left boundary of the rectangle. +// y - vertical position for the bottom boundary of the rectangle. +// w - width of the rectangle. +// h - height of the rectangle. +// +// Returns a handle to the new path object. +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_CreateNewRect(float x, + float y, + float w, + float h); + +// Set the stroke RGBA of a path. Range of values: 0 - 255. +// +// path - the handle to the path object. +// R - the red component for the path stroke color. +// G - the green component for the path stroke color. +// B - the blue component for the path stroke color. +// A - the stroke alpha for the path. +// +// Returns TRUE on success. +DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A); + +// Set the stroke width of a path. +// +// path - the handle to the path object. +// width - the width of the stroke. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_SetStrokeWidth(FPDF_PAGEOBJECT path, float width); + +// Set the fill RGBA of a path. Range of values: 0 - 255. +// +// path - the handle to the path object. +// R - the red component for the path fill color. +// G - the green component for the path fill color. +// B - the blue component for the path fill color. +// A - the fill alpha for the path. +// +// Returns TRUE on success. +DLLEXPORT FPDF_BOOL FPDFPath_SetFillColor(FPDF_PAGEOBJECT path, + unsigned int R, + unsigned int G, + unsigned int B, + unsigned int A); + +// Move a path's current point. +// +// path - the handle to the path object. +// x - the horizontal position of the new current point. +// y - the vertical position of the new current point. +// +// Note that no line will be created between the previous current point and the +// new one. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_MoveTo(FPDF_PAGEOBJECT path, float x, float y); + +// Add a line between the current point and a new point in the path. +// +// path - the handle to the path object. +// x - the horizontal position of the new point. +// y - the vertical position of the new point. +// +// The path's current point is changed to (x, y). +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_LineTo(FPDF_PAGEOBJECT path, float x, float y); + +// Add a cubic Bezier curve to the given path, starting at the current point. +// +// path - the handle to the path object. +// x1 - the horizontal position of the first Bezier control point. +// y1 - the vertical position of the first Bezier control point. +// x2 - the horizontal position of the second Bezier control point. +// y2 - the vertical position of the second Bezier control point. +// x3 - the horizontal position of the ending point of the Bezier curve. +// y3 - the vertical position of the ending point of the Bezier curve. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_BezierTo(FPDF_PAGEOBJECT path, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3); + +// Close the current subpath of a given path. +// +// path - the handle to the path object. +// +// This will add a line between the current point and the initial point of the +// subpath, thus terminating the current subpath. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_Close(FPDF_PAGEOBJECT path); + +// Set the drawing mode of a path. +// +// path - the handle to the path object. +// fillmode - the filling mode to be set: 0 for no fill, 1 for alternate, 2 for +// winding. +// stroke - a boolean specifying if the path should be stroked or not. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL FPDFPath_SetDrawMode(FPDF_PAGEOBJECT path, + int fillmode, + FPDF_BOOL stroke); + +// Create a new text object using one of the standard PDF fonts. +// +// document - handle to the document. +// font - string containing the font name, without spaces. +// font_size - the font size for the new text object. +// +// Returns a handle to a new text object, or NULL on failure +DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewTextObj(FPDF_DOCUMENT document, + FPDF_BYTESTRING font, + float font_size); + +// Set the text for a textobject. If it had text, it will be replaced. +// +// text_object - handle to the text object. +// text - string containing the text to be added. +// +// Returns TRUE on success +DLLEXPORT FPDF_BOOL STDCALL FPDFText_SetText(FPDF_PAGEOBJECT text_object, + FPDF_BYTESTRING text); + +// Returns a type 1 font object loaded from a stream of data. The font is loaded +// into the document. The caller does not need to free the returned object. +// +// document - handle to the document. +// data - the stream of data, which will be copied by the font object. +// size - size of the stream, in bytes. +// +// Returns NULL on failure +DLLEXPORT FPDF_FONT STDCALL FPDFText_LoadType1Font(FPDF_DOCUMENT document, + const uint8_t* data, + uint32_t size); + #ifdef __cplusplus } // extern "C" #endif // __cplusplus diff --git a/public/fpdfview.h b/public/fpdfview.h index 7378d5f9b..1c47a366b 100644 --- a/public/fpdfview.h +++ b/public/fpdfview.h @@ -252,7 +252,8 @@ DLLEXPORT void STDCALL FPDF_SetPrintTextWithGDI(FPDF_BOOL use_gdi); // All other values are invalid. // Return value: // True if successful, false if unsucessful (typically invalid input). -DLLEXPORT FPDF_BOOL STDCALL FPDF_SetPrintPostscriptLevel(FPDF_BOOL use_gdi); +DLLEXPORT FPDF_BOOL STDCALL +FPDF_SetPrintPostscriptLevel(FPDF_BOOL postscript_level); #endif // defined(_WIN32) // Function: FPDF_LoadDocument diff --git a/samples/BUILD.gn b/samples/BUILD.gn index b66554d60..23f4d0ca5 100644 --- a/samples/BUILD.gn +++ b/samples/BUILD.gn @@ -3,7 +3,6 @@ # found in the LICENSE file. import("//build/config/sanitizers/sanitizers.gni") -import("//build_overrides/v8.gni") import("../pdfium.gni") group("samples") { @@ -15,6 +14,8 @@ group("samples") { } config("pdfium_samples_config") { + cflags = [] + ldflags = [] defines = [ "PNG_PREFIX", "PNG_USE_READ_MACROS", @@ -29,6 +30,17 @@ config("pdfium_samples_config") { if (pdf_use_skia) { defines += [ "PDF_ENABLE_SKIA" ] } + if (is_asan) { + defines += [ "PDF_ENABLE_ASAN" ] + } + if (use_coverage && is_clang) { + cflags += [ + "--coverage", + "-g", + "-O0", + ] + ldflags += [ "--coverage" ] + } } executable("pdfium_test") { diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc index 1e0a5be50..a0afd4d09 100644 --- a/samples/pdfium_test.cc +++ b/samples/pdfium_test.cc @@ -893,6 +893,11 @@ static void ShowConfig() { config.append("XFA"); maybe_comma = ","; #endif // PDF_ENABLE_XFA +#ifdef PDF_ENABLE_ASAN + config.append(maybe_comma); + config.append("ASAN"); + maybe_comma = ","; +#endif // PDF_ENABLE_ASAN printf("%s\n", config.c_str()); } diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 178b6945b..723e872b0 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn @@ -205,6 +205,7 @@ component("skia") { #pdfium "//third_party/skia/src/ports/SkDiscardableMemory_none.cpp", "//third_party/skia/src/ports/SkFontMgr_custom.cpp", + "//third_party/skia/src/ports/SkFontMgr_custom_empty.cpp", "//third_party/skia/src/ports/SkFontMgr_custom_empty_factory.cpp", "//third_party/skia/src/ports/SkMemory_malloc.cpp", ] @@ -229,7 +230,6 @@ component("skia") { "//third_party/skia/src/utils/SkDumpCanvas.cpp", "//third_party/skia/src/utils/SkFrontBufferedStream.cpp", "//third_party/skia/src/utils/SkInterpolator.cpp", - "//third_party/skia/src/utils/SkLayer.cpp", "//third_party/skia/src/utils/SkMeshUtils.cpp", "//third_party/skia/src/utils/SkParsePath.cpp", ] diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index f505c50f9..e09a2351b 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h @@ -127,9 +127,6 @@ // ===== Begin Chrome-specific definitions ===== -#define SK_SCALAR_IS_FLOAT -#undef SK_SCALAR_IS_FIXED - #define SK_MSCALAR_IS_FLOAT #undef SK_MSCALAR_IS_DOUBLE diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS index 2d5424751..447c9fa52 100644 --- a/testing/SUPPRESSIONS +++ b/testing/SUPPRESSIONS @@ -484,6 +484,21 @@ zh_file1.pdf mac * * zh_function_list.pdf mac * * zh_shared_document.pdf mac * * +bug_679643.in * * noxfa +bug_679642.in * * noxfa + +### TODO(dsinclair): These need to be fixed .... +Test_DateField_locale_en_CA.pdf asan * * +Test_DateField_locale_en_GB.pdf asan * * +Test_DateField_locale_en_US.pdf asan * * +Test_DateField_locale_fr_CA.pdf asan * * +Test_DateField_locale_fr_FR.pdf asan * * +Test_DateField_locale_nl_NL.pdf asan * * +Test_DateField_locale_zh_CN.pdf asan * * +Test_DateField_locale_zh_HK.pdf asan * * +Test_PasswordField.pdf asan * * +format_custom_format.pdf asan * * + # # xfa_specific # diff --git a/testing/libfuzzer/pdf_css_fuzzer.cc b/testing/libfuzzer/pdf_css_fuzzer.cc index 9135b25f3..f02f006ea 100644 --- a/testing/libfuzzer/pdf_css_fuzzer.cc +++ b/testing/libfuzzer/pdf_css_fuzzer.cc @@ -15,8 +15,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { CFX_WideString input = CFX_WideString::FromUTF8( CFX_ByteStringC(data, static_cast<FX_STRSIZE>(size))); + // If we convert the input into an empty string bail out. + if (input.GetLength() == 0) + return 0; + CFDE_CSSSyntaxParser parser; - parser.Init(input.c_str(), size); + parser.Init(input.c_str(), input.GetLength()); FDE_CSSSyntaxStatus status; do { diff --git a/testing/libfuzzer/pdf_streamparser_fuzzer.cc b/testing/libfuzzer/pdf_streamparser_fuzzer.cc index 5cfa318c6..46113d42c 100644 --- a/testing/libfuzzer/pdf_streamparser_fuzzer.cc +++ b/testing/libfuzzer/pdf_streamparser_fuzzer.cc @@ -10,7 +10,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { CPDF_StreamParser parser(data, size); - while (std::unique_ptr<CPDF_Object> pObj = parser.ReadNextObject(true, 0)) + while (std::unique_ptr<CPDF_Object> pObj = + parser.ReadNextObject(true, false, 0)) continue; return 0; diff --git a/testing/libfuzzer/xfa_codec_fuzzer.h b/testing/libfuzzer/xfa_codec_fuzzer.h index 860899339..9a8b23e36 100644 --- a/testing/libfuzzer/xfa_codec_fuzzer.h +++ b/testing/libfuzzer/xfa_codec_fuzzer.h @@ -7,16 +7,26 @@ #include <memory> +#include "core/fxcodec/codec/ccodec_bmpmodule.h" +#include "core/fxcodec/codec/ccodec_gifmodule.h" +#include "core/fxcodec/codec/ccodec_pngmodule.h" #include "core/fxcodec/codec/ccodec_progressivedecoder.h" +#include "core/fxcodec/codec/ccodec_tiffmodule.h" #include "core/fxcodec/fx_codec.h" #include "core/fxcrt/fx_stream.h" +#include "third_party/base/ptr_util.h" class XFACodecFuzzer { public: static int Fuzz(const uint8_t* data, size_t size, FXCODEC_IMAGE_TYPE type) { - std::unique_ptr<CCodec_ModuleMgr> mgr(new CCodec_ModuleMgr()); - std::unique_ptr<CCodec_ProgressiveDecoder> decoder( - mgr->CreateProgressiveDecoder()); + auto mgr = pdfium::MakeUnique<CCodec_ModuleMgr>(); + mgr->SetBmpModule(pdfium::MakeUnique<CCodec_BmpModule>()); + mgr->SetGifModule(pdfium::MakeUnique<CCodec_GifModule>()); + mgr->SetPngModule(pdfium::MakeUnique<CCodec_PngModule>()); + mgr->SetTiffModule(pdfium::MakeUnique<CCodec_TiffModule>()); + + std::unique_ptr<CCodec_ProgressiveDecoder> decoder = + mgr->CreateProgressiveDecoder(); CFX_RetainPtr<Reader> source(new Reader(data, size)); FXCODEC_STATUS status = decoder->LoadImageInfo(source, type, nullptr, true); if (status != FXCODEC_STATUS_FRAME_READY) diff --git a/testing/resources/javascript/bug_695826.in b/testing/resources/javascript/bug_695826.in new file mode 100644 index 000000000..b20908bc7 --- /dev/null +++ b/testing/resources/javascript/bug_695826.in @@ -0,0 +1,47 @@ +{{header}} +{{object 1 0}} << + /Type /Catalog + /Pages 2 0 R + /OpenAction 10 0 R +>> +endobj +{{object 2 0}} << + /Type /Pages + /Count 1 + /Kids [ + 3 0 R + ] +>> +endobj +% Page number 0. +{{object 3 0}} << + /Type /Page + /Parent 2 0 R + /Resources << + /Font <</F1 15 0 R>> + >> + /Contents [21 0 R] + /MediaBox [0 0 612 792] +>> +% OpenAction action +{{object 10 0}} << + /Type /Action + /S /JavaScript + /JS 11 0 R +>> +endobj +% JS program to exexute +{{object 11 0}} << +>> +stream +var obj = new this.constructor; +obj.author = 3; +app.alert('Done!'); +endstream +endobj +{{xref}} +trailer << + /Root 1 0 R +>> +{{startxref}} +%%EOF diff --git a/testing/resources/javascript/bug_695826_expected.txt b/testing/resources/javascript/bug_695826_expected.txt new file mode 100644 index 000000000..5bb6e8596 --- /dev/null +++ b/testing/resources/javascript/bug_695826_expected.txt @@ -0,0 +1 @@ +Alert: Done! diff --git a/testing/tools/common.py b/testing/tools/common.py index a0cc946f1..b6e4a7d62 100755 --- a/testing/tools/common.py +++ b/testing/tools/common.py @@ -43,38 +43,6 @@ def RunCommandExtractHashedFiles(cmd): except subprocess.CalledProcessError as e: return e, None -# Adjust Dr. Memory wrapper to have separate log directory for each test -# for better error reporting. -def DrMemoryWrapper(wrapper, pdf_name): - if not wrapper: - return [] - # convert string to list - cmd_to_run = wrapper.split() - - # Do nothing if using default log directory. - if cmd_to_run.count("-logdir") == 0: - return cmd_to_run - # Usually, we pass "-logdir" "foo\bar\spam path" args to Dr. Memory. - # To group reports per test, we want to put the reports for each test into a - # separate directory. This code can be simplified when we have - # https://github.com/DynamoRIO/drmemory/issues/684 fixed. - logdir_idx = cmd_to_run.index("-logdir") - old_logdir = cmd_to_run[logdir_idx + 1] - wrapper_pid = str(os.getpid()) - - # We are using the same pid of the same python process, so append the number - # of entries in the logdir at the end of wrapper_pid to avoid conflict. - wrapper_pid += "_%d" % len(glob.glob(old_logdir + "\\*")) - - cmd_to_run[logdir_idx + 1] += "\\testcase.%s.logs" % wrapper_pid - os.makedirs(cmd_to_run[logdir_idx + 1]) - - f = open(old_logdir + "\\testcase.%s.name" % wrapper_pid, "w") - print >>f, pdf_name + ".pdf" - f.close() - - return cmd_to_run - class DirectoryFinder: '''A class for finding directories and paths under either a standalone diff --git a/testing/tools/gold.py b/testing/tools/gold.py index 7598caffd..db3bf81b7 100644 --- a/testing/tools/gold.py +++ b/testing/tools/gold.py @@ -51,7 +51,8 @@ import shutil # } # class GoldResults(object): - def __init__(self, source_type, outputDir, propertiesStr, keyStr): + def __init__(self, source_type, outputDir, propertiesStr, keyStr, + ignore_hashes_file): """ source_type is the source_type (=corpus) field used for all results. output_dir is the directory where the resulting images are copied and @@ -60,6 +61,8 @@ class GoldResults(object): is used to set the top level fields in the output JSON file. keyStr is a string with space separated key/value pairs that is used to set the 'key' field in the output JSON file. + ignore_hashes_file is a file that contains a list of image hashes + that should be ignored. """ self._source_type = source_type self._properties = self._parseKeyValuePairs(propertiesStr) @@ -71,13 +74,22 @@ class GoldResults(object): if not os.path.exists(outputDir): os.makedirs(outputDir) + self._ignore_hashes = set() + if ignore_hashes_file: + with open(ignore_hashes_file, 'r') as ig_file: + hashes=[x.strip() for x in ig_file.readlines() if x.strip()] + self._ignore_hashes = set(hashes) + def AddTestResult(self, testName, md5Hash, outputImagePath): - # Copy the image to <output_dir>/<md5Hash>.<image_extension> + # If the hash is in the list of hashes to ignore then we don'try + # make a copy, but add it to the result. imgExt = os.path.splitext(outputImagePath)[1].lstrip(".") - if not imgExt: - raise ValueError("File %s does not have an extension" % outputImagePath) - newFilePath = os.path.join(self._outputDir, md5Hash + '.' + imgExt) - shutil.copy2(outputImagePath, newFilePath) + if md5Hash not in self._ignore_hashes: + # Copy the image to <output_dir>/<md5Hash>.<image_extension> + if not imgExt: + raise ValueError("File %s does not have an extension" % outputImagePath) + newFilePath = os.path.join(self._outputDir, md5Hash + '.' + imgExt) + shutil.copy2(outputImagePath, newFilePath) # Add an entry to the list of test results self._results.append({ @@ -123,7 +135,11 @@ if __name__ == "__main__": keyStr = "arch arm64 compiler Clang configuration Debug" - gr = GoldResults("pdfium", testDir, propStr, keyStr) + hash_file = os.path.join(testDir, "ignore_hashes.txt") + with open(hash_file, 'wb') as f: + f.write("\n".join(["hash-1","hash-4"]) + "\n") + + gr = GoldResults("pdfium", testDir, propStr, keyStr, hash_file) gr.AddTestResult("test-1", "hash-1", os.path.join(testDir, "image1.png")) gr.AddTestResult("test-2", "hash-2", os.path.join(testDir, "image2.png")) gr.AddTestResult("test-3", "hash-3", os.path.join(testDir, "image3.png")) diff --git a/testing/tools/suppressor.py b/testing/tools/suppressor.py index b7629ef6f..86d2668ad 100755 --- a/testing/tools/suppressor.py +++ b/testing/tools/suppressor.py @@ -12,8 +12,10 @@ class Suppressor: feature_vector = feature_string.strip().split(",") self.has_v8 = "V8" in feature_vector self.has_xfa = "XFA" in feature_vector + self.is_asan = "ASAN" in feature_vector v8_option = "v8" if self.has_v8 else "nov8" xfa_option = "xfa" if self.has_xfa else "noxfa" + with open(os.path.join(finder.TestingDir(), 'SUPPRESSIONS')) as f: self.suppression_set = set(self._FilterSuppressions( common.os_name(), v8_option, xfa_option, self._ExtractSuppressions(f))) @@ -31,6 +33,8 @@ class Suppressor: os_column = item[1].split(","); js_column = item[2].split(","); xfa_column = item[3].split(","); + if self.is_asan and 'asan' in os_column: + return True return (('*' in os_column or os in os_column) and ('*' in js_column or js in js_column) and ('*' in xfa_column or xfa in xfa_column)) diff --git a/testing/tools/test_runner.py b/testing/tools/test_runner.py index 92db9118d..6cd3a6c05 100644 --- a/testing/tools/test_runner.py +++ b/testing/tools/test_runner.py @@ -107,9 +107,7 @@ class TestRunner: txt_path = os.path.join(self.working_dir, input_root + '.txt') with open(txt_path, 'w') as outfile: - # add Dr. Memory wrapper if exist - cmd_to_run = common.DrMemoryWrapper(self.drmem_wrapper, input_root) - cmd_to_run.extend([self.pdfium_test_path, pdf_path]) + cmd_to_run = [self.pdfium_test_path, pdf_path] subprocess.check_call(cmd_to_run, stdout=outfile) cmd = [sys.executable, self.text_diff_path, expected_txt_path, txt_path] @@ -117,16 +115,15 @@ class TestRunner: def TestPixel(self, input_root, pdf_path): - cmd_to_run = common.DrMemoryWrapper(self.drmem_wrapper, input_root) - cmd_to_run.extend([self.pdfium_test_path, '--send-events', '--png']) + cmd_to_run = [self.pdfium_test_path, '--send-events', '--png'] if self.gold_results: cmd_to_run.append('--md5') cmd_to_run.append(pdf_path) return common.RunCommandExtractHashedFiles(cmd_to_run) def HandleResult(self, input_filename, input_path, result): + success, image_paths = result if self.gold_results: - success, image_paths = result if image_paths: for img_path, md5_hash in image_paths: # the output filename (without extension becomes the test name) @@ -134,10 +131,10 @@ class TestRunner: self.gold_results.AddTestResult(test_name, md5_hash, img_path) if self.test_suppressor.IsResultSuppressed(input_filename): - if result: + if success: self.surprises.append(input_path) else: - if not result: + if not success: self.failures.append(input_path) @@ -151,9 +148,6 @@ class TestRunner: dest='num_workers', type='int', help='run NUM_WORKERS jobs in parallel') - parser.add_option('--wrapper', default='', dest="wrapper", - help='wrapper for running test under Dr. Memory') - parser.add_option('--gold_properties', default='', dest="gold_properties", help='Key value pairs that are written to the top level of the JSON file that is ingested by Gold.') @@ -163,6 +157,9 @@ class TestRunner: parser.add_option('--gold_output_dir', default='', dest="gold_output_dir", help='Path of where to write the JSON output to be uploaded to Gold.') + parser.add_option('--gold_ignore_hashes', default='', dest="gold_ignore_hashes", + help='Path to a file with MD5 hashes we wish to ignore.') + parser.add_option('--ignore_errors', action="store_true", dest="ignore_errors", help='Prevents the return value from being non-zero when image comparison fails.') @@ -172,8 +169,6 @@ class TestRunner: self.fixup_path = finder.ScriptPath('fixup_pdf_template.py') self.text_diff_path = finder.ScriptPath('text_diff.py') - self.drmem_wrapper = options.wrapper - self.source_dir = finder.TestingDir() if self.test_dir != 'corpus': test_dir = finder.TestingDir(os.path.join('resources', self.test_dir)) @@ -227,7 +222,8 @@ class TestRunner: self.gold_results = gold.GoldResults("pdfium", options.gold_output_dir, options.gold_properties, - options.gold_key) + options.gold_key, + options.gold_ignore_hashes) if options.num_workers > 1 and len(test_cases) > 1: try: @@ -267,6 +263,7 @@ class TestRunner: print '\n\nSummary of Failures:' for failure in self.failures: print failure - if not options.ignore_errors: - return 1 + + if not options.ignore_errors: + return 1 return 0 diff --git a/third_party/agg23/agg_rasterizer_scanline_aa.cpp b/third_party/agg23/agg_rasterizer_scanline_aa.cpp index c6b3f013a..af6dd58fe 100644 --- a/third_party/agg23/agg_rasterizer_scanline_aa.cpp +++ b/third_party/agg23/agg_rasterizer_scanline_aa.cpp @@ -283,8 +283,8 @@ void outline_aa::render_line(int x1, int y1, int x2, int y2) incr = -1; dy = -dy; } - delta = safeP.ValueOrDie() / dy; - mod = safeP.ValueOrDie() % dy; + delta = (safeP / dy).ValueOrDie(); + mod = (safeP % dy).ValueOrDie(); if(mod < 0) { delta--; mod += dy; @@ -298,8 +298,8 @@ void outline_aa::render_line(int x1, int y1, int x2, int y2) safeP *= dx; if (!safeP.IsValid()) return; - lift = safeP.ValueOrDie() / dy; - rem = safeP.ValueOrDie() % dy; + lift = (safeP / dy).ValueOrDie(); + rem = (safeP % dy).ValueOrDie(); if (rem < 0) { lift--; rem += dy; diff --git a/third_party/agg23/agg_rasterizer_scanline_aa.h b/third_party/agg23/agg_rasterizer_scanline_aa.h index 77e04edee..fc28290f5 100644 --- a/third_party/agg23/agg_rasterizer_scanline_aa.h +++ b/third_party/agg23/agg_rasterizer_scanline_aa.h @@ -390,10 +390,12 @@ public: unsigned cmd; vs.rewind(path_id); while(!is_stop(cmd = vs.vertex(&x, &y))) { - if (pMatrix) { - pMatrix->Transform(x, y); - } - add_vertex(x, y, cmd); + if (pMatrix) { + CFX_PointF ret = pMatrix->Transform(CFX_PointF(x, y)); + x = ret.x; + y = ret.y; + } + add_vertex(x, y, cmd); } } private: diff --git a/third_party/base/numerics/safe_conversions.h b/third_party/base/numerics/safe_conversions.h index dd0d1e47d..dc61d9c9c 100644 --- a/third_party/base/numerics/safe_conversions.h +++ b/third_party/base/numerics/safe_conversions.h @@ -2,65 +2,271 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PDFIUM_THIRD_PARTY_BASE_SAFE_CONVERSIONS_H_ -#define PDFIUM_THIRD_PARTY_BASE_SAFE_CONVERSIONS_H_ +#ifndef PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_CONVERSIONS_H_ +#define PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_CONVERSIONS_H_ + +#include <stddef.h> #include <limits> +#include <ostream> +#include <type_traits> -#include "safe_conversions_impl.h" -#include "third_party/base/logging.h" +#include "third_party/base/numerics/safe_conversions_impl.h" namespace pdfium { namespace base { +// The following are helper constexpr template functions and classes for safely +// performing a range of conversions, assignments, and tests: +// +// checked_cast<> - Analogous to static_cast<> for numeric types, except +// that it CHECKs that the specified numeric conversion will not overflow +// or underflow. NaN source will always trigger a CHECK. +// The default CHECK triggers a crash, but the handler can be overriden. +// saturated_cast<> - Analogous to static_cast<> for numeric types, except +// that it returns a saturated result when the specified numeric conversion +// would otherwise overflow or underflow. An NaN source returns 0 by +// default, but can be overridden to return a different result. +// strict_cast<> - Analogous to static_cast<> for numeric types, except that +// it will cause a compile failure if the destination type is not large +// enough to contain any value in the source type. It performs no runtime +// checking and thus introduces no runtime overhead. +// IsValueInRangeForNumericType<>() - A convenience function that returns true +// if the type supplied to the template parameter can represent the value +// passed as an argument to the function. +// IsValueNegative<>() - A convenience function that will accept any arithmetic +// type as an argument and will return whether the value is less than zero. +// Unsigned types always return false. +// SafeUnsignedAbs() - Returns the absolute value of the supplied integer +// parameter as an unsigned result (thus avoiding an overflow if the value +// is the signed, two's complement minimum). +// StrictNumeric<> - A wrapper type that performs assignments and copies via +// the strict_cast<> template, and can perform valid arithmetic comparisons +// across any range of arithmetic types. StrictNumeric is the return type +// for values extracted from a CheckedNumeric class instance. The raw +// arithmetic value is extracted via static_cast to the underlying type. +// MakeStrictNum() - Creates a new StrictNumeric from the underlying type of +// the supplied arithmetic or StrictNumeric type. + // Convenience function that returns true if the supplied value is in range // for the destination type. template <typename Dst, typename Src> -inline bool IsValueInRangeForNumericType(Src value) { - return internal::DstRangeRelationToSrcRange<Dst>(value) == - internal::RANGE_VALID; +constexpr bool IsValueInRangeForNumericType(Src value) { + return internal::DstRangeRelationToSrcRange<Dst>(value).IsValid(); } +// Forces a crash, like a CHECK(false). Used for numeric boundary errors. +struct CheckOnFailure { + template <typename T> + static T HandleFailure() { +#if defined(__GNUC__) || defined(__clang__) + __builtin_trap(); +#else + ((void)(*(volatile char*)0 = 0)); +#endif + return T(); + } +}; + // checked_cast<> is analogous to static_cast<> for numeric types, // except that it CHECKs that the specified numeric conversion will not // overflow or underflow. NaN source will always trigger a CHECK. -template <typename Dst, typename Src> -inline Dst checked_cast(Src value) { - CHECK(IsValueInRangeForNumericType<Dst>(value)); - return static_cast<Dst>(value); +template <typename Dst, class CheckHandler = CheckOnFailure, typename Src> +constexpr Dst checked_cast(Src value) { + // This throws a compile-time error on evaluating the constexpr if it can be + // determined at compile-time as failing, otherwise it will CHECK at runtime. + using SrcType = typename internal::UnderlyingType<Src>::type; + return IsValueInRangeForNumericType<Dst, SrcType>(value) + ? static_cast<Dst>(static_cast<SrcType>(value)) + : CheckHandler::template HandleFailure<Dst>(); +} + +// Default boundaries for integral/float: max/infinity, lowest/-infinity, 0/NaN. +template <typename T> +struct SaturationDefaultHandler { + static constexpr T NaN() { + return std::numeric_limits<T>::has_quiet_NaN + ? std::numeric_limits<T>::quiet_NaN() + : T(); + } + static constexpr T max() { return std::numeric_limits<T>::max(); } + static constexpr T Overflow() { + return std::numeric_limits<T>::has_infinity + ? std::numeric_limits<T>::infinity() + : std::numeric_limits<T>::max(); + } + static constexpr T lowest() { return std::numeric_limits<T>::lowest(); } + static constexpr T Underflow() { + return std::numeric_limits<T>::has_infinity + ? std::numeric_limits<T>::infinity() * -1 + : std::numeric_limits<T>::lowest(); + } +}; + +namespace internal { + +template <typename Dst, template <typename> class S, typename Src> +constexpr Dst saturated_cast_impl(Src value, RangeCheck constraint) { + // For some reason clang generates much better code when the branch is + // structured exactly this way, rather than a sequence of checks. + return !constraint.IsOverflowFlagSet() + ? (!constraint.IsUnderflowFlagSet() ? static_cast<Dst>(value) + : S<Dst>::Underflow()) + // Skip this check for integral Src, which cannot be NaN. + : (std::is_integral<Src>::value || !constraint.IsUnderflowFlagSet() + ? S<Dst>::Overflow() + : S<Dst>::NaN()); } // saturated_cast<> is analogous to static_cast<> for numeric types, except -// that the specified numeric conversion will saturate rather than overflow or -// underflow. NaN assignment to an integral will trigger a CHECK condition. +// that the specified numeric conversion will saturate by default rather than +// overflow or underflow, and NaN assignment to an integral will return 0. +// All boundary condition behaviors can be overriden with a custom handler. +template <typename Dst, + template <typename> + class SaturationHandler = SaturationDefaultHandler, + typename Src> +constexpr Dst saturated_cast(Src value) { + using SrcType = typename UnderlyingType<Src>::type; + return saturated_cast_impl<Dst, SaturationHandler, SrcType>( + value, + DstRangeRelationToSrcRange<Dst, SaturationHandler, SrcType>(value)); +} + +// strict_cast<> is analogous to static_cast<> for numeric types, except that +// it will cause a compile failure if the destination type is not large enough +// to contain any value in the source type. It performs no runtime checking. template <typename Dst, typename Src> -inline Dst saturated_cast(Src value) { - // Optimization for floating point values, which already saturate. - if (std::numeric_limits<Dst>::is_iec559) - return static_cast<Dst>(value); +constexpr Dst strict_cast(Src value) { + using SrcType = typename UnderlyingType<Src>::type; + static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric."); + static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric."); - switch (internal::DstRangeRelationToSrcRange<Dst>(value)) { - case internal::RANGE_VALID: - return static_cast<Dst>(value); + // If you got here from a compiler error, it's because you tried to assign + // from a source type to a destination type that has insufficient range. + // The solution may be to change the destination type you're assigning to, + // and use one large enough to represent the source. + // Alternatively, you may be better served with the checked_cast<> or + // saturated_cast<> template functions for your particular use case. + static_assert(StaticDstRangeRelationToSrcRange<Dst, SrcType>::value == + NUMERIC_RANGE_CONTAINED, + "The source type is out of range for the destination type. " + "Please see strict_cast<> comments for more information."); - case internal::RANGE_UNDERFLOW: - return std::numeric_limits<Dst>::min(); + return static_cast<Dst>(static_cast<SrcType>(value)); +} - case internal::RANGE_OVERFLOW: - return std::numeric_limits<Dst>::max(); +// Some wrappers to statically check that a type is in range. +template <typename Dst, typename Src, class Enable = void> +struct IsNumericRangeContained { + static const bool value = false; +}; - // Should fail only on attempting to assign NaN to a saturated integer. - case internal::RANGE_INVALID: - CHECK(false); - return std::numeric_limits<Dst>::max(); +template <typename Dst, typename Src> +struct IsNumericRangeContained< + Dst, + Src, + typename std::enable_if<ArithmeticOrUnderlyingEnum<Dst>::value && + ArithmeticOrUnderlyingEnum<Src>::value>::type> { + static const bool value = StaticDstRangeRelationToSrcRange<Dst, Src>::value == + NUMERIC_RANGE_CONTAINED; +}; + +// StrictNumeric implements compile time range checking between numeric types by +// wrapping assignment operations in a strict_cast. This class is intended to be +// used for function arguments and return types, to ensure the destination type +// can always contain the source type. This is essentially the same as enforcing +// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied +// incrementally at API boundaries, making it easier to convert code so that it +// compiles cleanly with truncation warnings enabled. +// This template should introduce no runtime overhead, but it also provides no +// runtime checking of any of the associated mathematical operations. Use +// CheckedNumeric for runtime range checks of the actual value being assigned. +template <typename T> +class StrictNumeric { + public: + using type = T; + + constexpr StrictNumeric() : value_(0) {} + + // Copy constructor. + template <typename Src> + constexpr StrictNumeric(const StrictNumeric<Src>& rhs) + : value_(strict_cast<T>(rhs.value_)) {} + + // This is not an explicit constructor because we implicitly upgrade regular + // numerics to StrictNumerics to make them easier to use. + template <typename Src> + constexpr StrictNumeric(Src value) // NOLINT(runtime/explicit) + : value_(strict_cast<T>(value)) {} + + // If you got here from a compiler error, it's because you tried to assign + // from a source type to a destination type that has insufficient range. + // The solution may be to change the destination type you're assigning to, + // and use one large enough to represent the source. + // If you're assigning from a CheckedNumeric<> class, you may be able to use + // the AssignIfValid() member function, specify a narrower destination type to + // the member value functions (e.g. val.template ValueOrDie<Dst>()), use one + // of the value helper functions (e.g. ValueOrDieForType<Dst>(val)). + // If you've encountered an _ambiguous overload_ you can use a static_cast<> + // to explicitly cast the result to the destination type. + // If none of that works, you may be better served with the checked_cast<> or + // saturated_cast<> template functions for your particular use case. + template <typename Dst, + typename std::enable_if< + IsNumericRangeContained<Dst, T>::value>::type* = nullptr> + constexpr operator Dst() const { + return static_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_); } - NOTREACHED(); - return static_cast<Dst>(value); + private: + const T value_; +}; + +// Convience wrapper returns a StrictNumeric from the provided arithmetic type. +template <typename T> +constexpr StrictNumeric<typename UnderlyingType<T>::type> MakeStrictNum( + const T value) { + return value; +} + +// Overload the ostream output operator to make logging work nicely. +template <typename T> +std::ostream& operator<<(std::ostream& os, const StrictNumeric<T>& value) { + os << static_cast<T>(value); + return os; } +#define STRICT_COMPARISON_OP(NAME, OP) \ + template <typename L, typename R, \ + typename std::enable_if< \ + internal::IsStrictOp<L, R>::value>::type* = nullptr> \ + constexpr bool operator OP(const L lhs, const R rhs) { \ + return SafeCompare<NAME, typename UnderlyingType<L>::type, \ + typename UnderlyingType<R>::type>(lhs, rhs); \ + } + +STRICT_COMPARISON_OP(IsLess, <); +STRICT_COMPARISON_OP(IsLessOrEqual, <=); +STRICT_COMPARISON_OP(IsGreater, >); +STRICT_COMPARISON_OP(IsGreaterOrEqual, >=); +STRICT_COMPARISON_OP(IsEqual, ==); +STRICT_COMPARISON_OP(IsNotEqual, !=); + +#undef STRICT_COMPARISON_OP +}; + +using internal::strict_cast; +using internal::saturated_cast; +using internal::SafeUnsignedAbs; +using internal::StrictNumeric; +using internal::MakeStrictNum; +using internal::IsValueNegative; + +// Explicitly make a shorter size_t alias for convenience. +using SizeT = StrictNumeric<size_t>; + } // namespace base } // namespace pdfium -#endif // PDFIUM_THIRD_PARTY_BASE_SAFE_CONVERSIONS_H_ - +#endif // PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_CONVERSIONS_H_ diff --git a/third_party/base/numerics/safe_conversions_impl.h b/third_party/base/numerics/safe_conversions_impl.h index e1c4c3b75..2a7ce146e 100644 --- a/third_party/base/numerics/safe_conversions_impl.h +++ b/third_party/base/numerics/safe_conversions_impl.h @@ -2,29 +2,81 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PDFIUM_THIRD_PARTY_BASE_SAFE_CONVERSIONS_IMPL_H_ -#define PDFIUM_THIRD_PARTY_BASE_SAFE_CONVERSIONS_IMPL_H_ +#ifndef PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ +#define PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ -#include <assert.h> -#include <limits> +#include <stdint.h> -#include "third_party/base/macros.h" +#include <limits> +#include <type_traits> namespace pdfium { namespace base { namespace internal { // The std library doesn't provide a binary max_exponent for integers, however -// we can compute one by adding one to the number of non-sign bits. This allows -// for accurate range comparisons between floating point and integer types. +// we can compute an analog using std::numeric_limits<>::digits. template <typename NumericType> struct MaxExponent { - static const int value = std::numeric_limits<NumericType>::is_iec559 + static const int value = std::is_floating_point<NumericType>::value ? std::numeric_limits<NumericType>::max_exponent - : (sizeof(NumericType) * 8 + 1 - - std::numeric_limits<NumericType>::is_signed); + : std::numeric_limits<NumericType>::digits + 1; +}; + +// The number of bits (including the sign) in an integer. Eliminates sizeof +// hacks. +template <typename NumericType> +struct IntegerBitsPlusSign { + static const int value = std::numeric_limits<NumericType>::digits + + std::is_signed<NumericType>::value; +}; + +// Helper templates for integer manipulations. + +template <typename Integer> +struct PositionOfSignBit { + static const size_t value = IntegerBitsPlusSign<Integer>::value - 1; }; +// Determines if a numeric value is negative without throwing compiler +// warnings on: unsigned(value) < 0. +template <typename T, + typename std::enable_if<std::is_signed<T>::value>::type* = nullptr> +constexpr bool IsValueNegative(T value) { + static_assert(std::is_arithmetic<T>::value, "Argument must be numeric."); + return value < 0; +} + +template <typename T, + typename std::enable_if<!std::is_signed<T>::value>::type* = nullptr> +constexpr bool IsValueNegative(T) { + static_assert(std::is_arithmetic<T>::value, "Argument must be numeric."); + return false; +} + +// This performs a fast negation, returning a signed value. It works on unsigned +// arguments, but probably doesn't do what you want for any unsigned value +// larger than max / 2 + 1 (i.e. signed min cast to unsigned). +template <typename T> +constexpr typename std::make_signed<T>::type ConditionalNegate( + T x, + bool is_negative) { + static_assert(std::is_integral<T>::value, "Type must be integral"); + using SignedT = typename std::make_signed<T>::type; + using UnsignedT = typename std::make_unsigned<T>::type; + return static_cast<SignedT>( + (static_cast<UnsignedT>(x) ^ -SignedT(is_negative)) + is_negative); +} + +// This performs a safe, absolute value via unsigned overflow. +template <typename T> +constexpr typename std::make_unsigned<T>::type SafeUnsignedAbs(T value) { + static_assert(std::is_integral<T>::value, "Type must be integral"); + using UnsignedT = typename std::make_unsigned<T>::type; + return IsValueNegative(value) ? 0 - static_cast<UnsignedT>(value) + : static_cast<UnsignedT>(value); +} + enum IntegerRepresentation { INTEGER_REPRESENTATION_UNSIGNED, INTEGER_REPRESENTATION_SIGNED @@ -32,7 +84,7 @@ enum IntegerRepresentation { // A range for a given nunmeric Src type is contained for a given numeric Dst // type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and -// numeric_limits<Src>::min() >= numeric_limits<Dst>::min() are true. +// numeric_limits<Src>::lowest() >= numeric_limits<Dst>::lowest() are true. // We implement this as template specializations rather than simple static // comparisons to ensure type correctness in our comparisons. enum NumericRangeRepresentation { @@ -43,16 +95,14 @@ enum NumericRangeRepresentation { // Helper templates to statically determine if our destination type can contain // maximum and minimum values represented by the source type. -template < - typename Dst, - typename Src, - IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - IntegerRepresentation SrcSign = - std::numeric_limits<Src>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED > +template <typename Dst, + typename Src, + IntegerRepresentation DstSign = std::is_signed<Dst>::value + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED, + IntegerRepresentation SrcSign = std::is_signed<Src>::value + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED> struct StaticDstRangeRelationToSrcRange; // Same sign: Dst is guaranteed to contain Src only if its range is equal or @@ -87,132 +137,598 @@ struct StaticDstRangeRelationToSrcRange<Dst, static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED; }; -enum RangeConstraint { - RANGE_VALID = 0x0, // Value can be represented by the destination type. - RANGE_UNDERFLOW = 0x1, // Value would overflow. - RANGE_OVERFLOW = 0x2, // Value would underflow. - RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN). +// This class wraps the range constraints as separate booleans so the compiler +// can identify constants and eliminate unused code paths. +class RangeCheck { + public: + constexpr RangeCheck(bool is_in_lower_bound, bool is_in_upper_bound) + : is_underflow_(!is_in_lower_bound), is_overflow_(!is_in_upper_bound) {} + constexpr RangeCheck() : is_underflow_(0), is_overflow_(0) {} + constexpr bool IsValid() const { return !is_overflow_ && !is_underflow_; } + constexpr bool IsInvalid() const { return is_overflow_ && is_underflow_; } + constexpr bool IsOverflow() const { return is_overflow_ && !is_underflow_; } + constexpr bool IsUnderflow() const { return !is_overflow_ && is_underflow_; } + constexpr bool IsOverflowFlagSet() const { return is_overflow_; } + constexpr bool IsUnderflowFlagSet() const { return is_underflow_; } + constexpr bool operator==(const RangeCheck rhs) const { + return is_underflow_ == rhs.is_underflow_ && + is_overflow_ == rhs.is_overflow_; + } + constexpr bool operator!=(const RangeCheck rhs) const { + return !(*this == rhs); + } + + private: + // Do not change the order of these member variables. The integral conversion + // optimization depends on this exact order. + const bool is_underflow_; + const bool is_overflow_; }; -// Helper function for coercing an int back to a RangeContraint. -inline RangeConstraint GetRangeConstraint(int integer_range_constraint) { - assert(integer_range_constraint >= RANGE_VALID && - integer_range_constraint <= RANGE_INVALID); - return static_cast<RangeConstraint>(integer_range_constraint); -} +// The following helper template addresses a corner case in range checks for +// conversion from a floating-point type to an integral type of smaller range +// but larger precision (e.g. float -> unsigned). The problem is as follows: +// 1. Integral maximum is always one less than a power of two, so it must be +// truncated to fit the mantissa of the floating point. The direction of +// rounding is implementation defined, but by default it's always IEEE +// floats, which round to nearest and thus result in a value of larger +// magnitude than the integral value. +// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX +// // is 4294967295u. +// 2. If the floating point value is equal to the promoted integral maximum +// value, a range check will erroneously pass. +// Example: (4294967296f <= 4294967295u) // This is true due to a precision +// // loss in rounding up to float. +// 3. When the floating point value is then converted to an integral, the +// resulting value is out of range for the target integral type and +// thus is implementation defined. +// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0. +// To fix this bug we manually truncate the maximum value when the destination +// type is an integral of larger precision than the source floating-point type, +// such that the resulting maximum is represented exactly as a floating point. +template <typename Dst, typename Src, template <typename> class Bounds> +struct NarrowingRange { + using SrcLimits = std::numeric_limits<Src>; + using DstLimits = typename std::numeric_limits<Dst>; -// This function creates a RangeConstraint from an upper and lower bound -// check by taking advantage of the fact that only NaN can be out of range in -// both directions at once. -inline RangeConstraint GetRangeConstraint(bool is_in_upper_bound, - bool is_in_lower_bound) { - return GetRangeConstraint((is_in_upper_bound ? 0 : RANGE_OVERFLOW) | - (is_in_lower_bound ? 0 : RANGE_UNDERFLOW)); -} + // Computes the mask required to make an accurate comparison between types. + static const int kShift = + (MaxExponent<Src>::value > MaxExponent<Dst>::value && + SrcLimits::digits < DstLimits::digits) + ? (DstLimits::digits - SrcLimits::digits) + : 0; + template < + typename T, + typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> -template < - typename Dst, - typename Src, - IntegerRepresentation DstSign = std::numeric_limits<Dst>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - IntegerRepresentation SrcSign = std::numeric_limits<Src>::is_signed - ? INTEGER_REPRESENTATION_SIGNED - : INTEGER_REPRESENTATION_UNSIGNED, - NumericRangeRepresentation DstRange = - StaticDstRangeRelationToSrcRange<Dst, Src>::value > + // Masks out the integer bits that are beyond the precision of the + // intermediate type used for comparison. + static constexpr T Adjust(T value) { + static_assert(std::is_same<T, Dst>::value, ""); + static_assert(kShift < DstLimits::digits, ""); + return static_cast<T>( + ConditionalNegate(SafeUnsignedAbs(value) & ~((T(1) << kShift) - T(1)), + IsValueNegative(value))); + } + + template <typename T, + typename std::enable_if<std::is_floating_point<T>::value>::type* = + nullptr> + static constexpr T Adjust(T value) { + static_assert(std::is_same<T, Dst>::value, ""); + static_assert(kShift == 0, ""); + return value; + } + + static constexpr Dst max() { return Adjust(Bounds<Dst>::max()); } + static constexpr Dst lowest() { return Adjust(Bounds<Dst>::lowest()); } +}; + +template <typename Dst, + typename Src, + template <typename> class Bounds, + IntegerRepresentation DstSign = std::is_signed<Dst>::value + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED, + IntegerRepresentation SrcSign = std::is_signed<Src>::value + ? INTEGER_REPRESENTATION_SIGNED + : INTEGER_REPRESENTATION_UNSIGNED, + NumericRangeRepresentation DstRange = + StaticDstRangeRelationToSrcRange<Dst, Src>::value> struct DstRangeRelationToSrcRangeImpl; // The following templates are for ranges that must be verified at runtime. We // split it into checks based on signedness to avoid confusing casts and // compiler warnings on signed an unsigned comparisons. -// Dst range is statically determined to contain Src: Nothing to check. +// Same sign narrowing: The range is contained for normal limits. template <typename Dst, typename Src, + template <typename> class Bounds, IntegerRepresentation DstSign, IntegerRepresentation SrcSign> struct DstRangeRelationToSrcRangeImpl<Dst, Src, + Bounds, DstSign, SrcSign, NUMERIC_RANGE_CONTAINED> { - static RangeConstraint Check(Src value) { return RANGE_VALID; } + static constexpr RangeCheck Check(Src value) { + using SrcLimits = std::numeric_limits<Src>; + using DstLimits = NarrowingRange<Dst, Src, Bounds>; + return RangeCheck( + static_cast<Dst>(SrcLimits::lowest()) >= DstLimits::lowest() || + static_cast<Dst>(value) >= DstLimits::lowest(), + static_cast<Dst>(SrcLimits::max()) <= DstLimits::max() || + static_cast<Dst>(value) <= DstLimits::max()); + } }; // Signed to signed narrowing: Both the upper and lower boundaries may be -// exceeded. -template <typename Dst, typename Src> +// exceeded for standard limits. +template <typename Dst, typename Src, template <typename> class Bounds> struct DstRangeRelationToSrcRangeImpl<Dst, Src, + Bounds, INTEGER_REPRESENTATION_SIGNED, INTEGER_REPRESENTATION_SIGNED, NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return std::numeric_limits<Dst>::is_iec559 - ? GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), - value >= -std::numeric_limits<Dst>::max()) - : GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), - value >= std::numeric_limits<Dst>::min()); + static constexpr RangeCheck Check(Src value) { + using DstLimits = NarrowingRange<Dst, Src, Bounds>; + return RangeCheck(value >= DstLimits::lowest(), value <= DstLimits::max()); } }; -// Unsigned to unsigned narrowing: Only the upper boundary can be exceeded. -template <typename Dst, typename Src> +// Unsigned to unsigned narrowing: Only the upper bound can be exceeded for +// standard limits. +template <typename Dst, typename Src, template <typename> class Bounds> struct DstRangeRelationToSrcRangeImpl<Dst, Src, + Bounds, INTEGER_REPRESENTATION_UNSIGNED, INTEGER_REPRESENTATION_UNSIGNED, NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return GetRangeConstraint(value <= std::numeric_limits<Dst>::max(), true); + static constexpr RangeCheck Check(Src value) { + using DstLimits = NarrowingRange<Dst, Src, Bounds>; + return RangeCheck( + DstLimits::lowest() == Dst(0) || value >= DstLimits::lowest(), + value <= DstLimits::max()); } }; -// Unsigned to signed: The upper boundary may be exceeded. -template <typename Dst, typename Src> +// Unsigned to signed: Only the upper bound can be exceeded for standard limits. +template <typename Dst, typename Src, template <typename> class Bounds> struct DstRangeRelationToSrcRangeImpl<Dst, Src, + Bounds, INTEGER_REPRESENTATION_SIGNED, INTEGER_REPRESENTATION_UNSIGNED, NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return sizeof(Dst) > sizeof(Src) - ? RANGE_VALID - : GetRangeConstraint( - value <= static_cast<Src>(std::numeric_limits<Dst>::max()), - true); + static constexpr RangeCheck Check(Src value) { + using DstLimits = NarrowingRange<Dst, Src, Bounds>; + using Promotion = decltype(Src() + Dst()); + return RangeCheck(DstLimits::lowest() <= Dst(0) || + static_cast<Promotion>(value) >= + static_cast<Promotion>(DstLimits::lowest()), + static_cast<Promotion>(value) <= + static_cast<Promotion>(DstLimits::max())); } }; // Signed to unsigned: The upper boundary may be exceeded for a narrower Dst, -// and any negative value exceeds the lower boundary. -template <typename Dst, typename Src> +// and any negative value exceeds the lower boundary for standard limits. +template <typename Dst, typename Src, template <typename> class Bounds> struct DstRangeRelationToSrcRangeImpl<Dst, Src, + Bounds, INTEGER_REPRESENTATION_UNSIGNED, INTEGER_REPRESENTATION_SIGNED, NUMERIC_RANGE_NOT_CONTAINED> { - static RangeConstraint Check(Src value) { - return (MaxExponent<Dst>::value >= MaxExponent<Src>::value) - ? GetRangeConstraint(true, value >= static_cast<Src>(0)) - : GetRangeConstraint( - value <= static_cast<Src>(std::numeric_limits<Dst>::max()), - value >= static_cast<Src>(0)); + static constexpr RangeCheck Check(Src value) { + using SrcLimits = std::numeric_limits<Src>; + using DstLimits = NarrowingRange<Dst, Src, Bounds>; + using Promotion = decltype(Src() + Dst()); + return RangeCheck( + value >= Src(0) && (DstLimits::lowest() == 0 || + static_cast<Dst>(value) >= DstLimits::lowest()), + static_cast<Promotion>(SrcLimits::max()) <= + static_cast<Promotion>(DstLimits::max()) || + static_cast<Promotion>(value) <= + static_cast<Promotion>(DstLimits::max())); } }; -template <typename Dst, typename Src> -inline RangeConstraint DstRangeRelationToSrcRange(Src value) { - COMPILE_ASSERT(std::numeric_limits<Src>::is_specialized, - argument_must_be_numeric); - COMPILE_ASSERT(std::numeric_limits<Dst>::is_specialized, - result_must_be_numeric); - return DstRangeRelationToSrcRangeImpl<Dst, Src>::Check(value); +template <typename Dst, + template <typename> class Bounds = std::numeric_limits, + typename Src> +constexpr RangeCheck DstRangeRelationToSrcRange(Src value) { + static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric."); + static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric."); + static_assert(Bounds<Dst>::lowest() < Bounds<Dst>::max(), ""); + return DstRangeRelationToSrcRangeImpl<Dst, Src, Bounds>::Check(value); } +// Integer promotion templates used by the portable checked integer arithmetic. +template <size_t Size, bool IsSigned> +struct IntegerForDigitsAndSign; + +#define INTEGER_FOR_DIGITS_AND_SIGN(I) \ + template <> \ + struct IntegerForDigitsAndSign<IntegerBitsPlusSign<I>::value, \ + std::is_signed<I>::value> { \ + using type = I; \ + } + +INTEGER_FOR_DIGITS_AND_SIGN(int8_t); +INTEGER_FOR_DIGITS_AND_SIGN(uint8_t); +INTEGER_FOR_DIGITS_AND_SIGN(int16_t); +INTEGER_FOR_DIGITS_AND_SIGN(uint16_t); +INTEGER_FOR_DIGITS_AND_SIGN(int32_t); +INTEGER_FOR_DIGITS_AND_SIGN(uint32_t); +INTEGER_FOR_DIGITS_AND_SIGN(int64_t); +INTEGER_FOR_DIGITS_AND_SIGN(uint64_t); +#undef INTEGER_FOR_DIGITS_AND_SIGN + +// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to +// support 128-bit math, then the ArithmeticPromotion template below will need +// to be updated (or more likely replaced with a decltype expression). +static_assert(IntegerBitsPlusSign<intmax_t>::value == 64, + "Max integer size not supported for this toolchain."); + +template <typename Integer, bool IsSigned = std::is_signed<Integer>::value> +struct TwiceWiderInteger { + using type = + typename IntegerForDigitsAndSign<IntegerBitsPlusSign<Integer>::value * 2, + IsSigned>::type; +}; + +enum ArithmeticPromotionCategory { + LEFT_PROMOTION, // Use the type of the left-hand argument. + RIGHT_PROMOTION // Use the type of the right-hand argument. +}; + +// Determines the type that can represent the largest positive value. +template <typename Lhs, + typename Rhs, + ArithmeticPromotionCategory Promotion = + (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) + ? LEFT_PROMOTION + : RIGHT_PROMOTION> +struct MaxExponentPromotion; + +template <typename Lhs, typename Rhs> +struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION> { + using type = Lhs; +}; + +template <typename Lhs, typename Rhs> +struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION> { + using type = Rhs; +}; + +// Determines the type that can represent the lowest arithmetic value. +template <typename Lhs, + typename Rhs, + ArithmeticPromotionCategory Promotion = + std::is_signed<Lhs>::value + ? (std::is_signed<Rhs>::value + ? (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value + ? LEFT_PROMOTION + : RIGHT_PROMOTION) + : LEFT_PROMOTION) + : (std::is_signed<Rhs>::value + ? RIGHT_PROMOTION + : (MaxExponent<Lhs>::value < MaxExponent<Rhs>::value + ? LEFT_PROMOTION + : RIGHT_PROMOTION))> +struct LowestValuePromotion; + +template <typename Lhs, typename Rhs> +struct LowestValuePromotion<Lhs, Rhs, LEFT_PROMOTION> { + using type = Lhs; +}; + +template <typename Lhs, typename Rhs> +struct LowestValuePromotion<Lhs, Rhs, RIGHT_PROMOTION> { + using type = Rhs; +}; + +// Determines the type that is best able to represent an arithmetic result. +template < + typename Lhs, + typename Rhs = Lhs, + bool is_intmax_type = + std::is_integral<typename MaxExponentPromotion<Lhs, Rhs>::type>::value&& + IntegerBitsPlusSign<typename MaxExponentPromotion<Lhs, Rhs>::type>:: + value == IntegerBitsPlusSign<intmax_t>::value, + bool is_max_exponent = + StaticDstRangeRelationToSrcRange< + typename MaxExponentPromotion<Lhs, Rhs>::type, + Lhs>::value == + NUMERIC_RANGE_CONTAINED&& StaticDstRangeRelationToSrcRange< + typename MaxExponentPromotion<Lhs, Rhs>::type, + Rhs>::value == NUMERIC_RANGE_CONTAINED> +struct BigEnoughPromotion; + +// The side with the max exponent is big enough. +template <typename Lhs, typename Rhs, bool is_intmax_type> +struct BigEnoughPromotion<Lhs, Rhs, is_intmax_type, true> { + using type = typename MaxExponentPromotion<Lhs, Rhs>::type; + static const bool is_contained = true; +}; + +// We can use a twice wider type to fit. +template <typename Lhs, typename Rhs> +struct BigEnoughPromotion<Lhs, Rhs, false, false> { + using type = + typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type, + std::is_signed<Lhs>::value || + std::is_signed<Rhs>::value>::type; + static const bool is_contained = true; +}; + +// No type is large enough. +template <typename Lhs, typename Rhs> +struct BigEnoughPromotion<Lhs, Rhs, true, false> { + using type = typename MaxExponentPromotion<Lhs, Rhs>::type; + static const bool is_contained = false; +}; + +// We can statically check if operations on the provided types can wrap, so we +// can skip the checked operations if they're not needed. So, for an integer we +// care if the destination type preserves the sign and is twice the width of +// the source. +template <typename T, typename Lhs, typename Rhs = Lhs> +struct IsIntegerArithmeticSafe { + static const bool value = + !std::is_floating_point<T>::value && + !std::is_floating_point<Lhs>::value && + !std::is_floating_point<Rhs>::value && + std::is_signed<T>::value >= std::is_signed<Lhs>::value && + IntegerBitsPlusSign<T>::value >= (2 * IntegerBitsPlusSign<Lhs>::value) && + std::is_signed<T>::value >= std::is_signed<Rhs>::value && + IntegerBitsPlusSign<T>::value >= (2 * IntegerBitsPlusSign<Rhs>::value); +}; + +// Promotes to a type that can represent any possible result of a binary +// arithmetic operation with the source types. +template <typename Lhs, + typename Rhs, + bool is_promotion_possible = IsIntegerArithmeticSafe< + typename std::conditional<std::is_signed<Lhs>::value || + std::is_signed<Rhs>::value, + intmax_t, + uintmax_t>::type, + typename MaxExponentPromotion<Lhs, Rhs>::type>::value> +struct FastIntegerArithmeticPromotion; + +template <typename Lhs, typename Rhs> +struct FastIntegerArithmeticPromotion<Lhs, Rhs, true> { + using type = + typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type, + std::is_signed<Lhs>::value || + std::is_signed<Rhs>::value>::type; + static_assert(IsIntegerArithmeticSafe<type, Lhs, Rhs>::value, ""); + static const bool is_contained = true; +}; + +template <typename Lhs, typename Rhs> +struct FastIntegerArithmeticPromotion<Lhs, Rhs, false> { + using type = typename BigEnoughPromotion<Lhs, Rhs>::type; + static const bool is_contained = false; +}; + +// This hacks around libstdc++ 4.6 missing stuff in type_traits. +#if defined(__GLIBCXX__) +#define PRIV_GLIBCXX_4_7_0 20120322 +#define PRIV_GLIBCXX_4_5_4 20120702 +#define PRIV_GLIBCXX_4_6_4 20121127 +#if (__GLIBCXX__ < PRIV_GLIBCXX_4_7_0 || __GLIBCXX__ == PRIV_GLIBCXX_4_5_4 || \ + __GLIBCXX__ == PRIV_GLIBCXX_4_6_4) +#define PRIV_USE_FALLBACKS_FOR_OLD_GLIBCXX +#undef PRIV_GLIBCXX_4_7_0 +#undef PRIV_GLIBCXX_4_5_4 +#undef PRIV_GLIBCXX_4_6_4 +#endif +#endif + +// Extracts the underlying type from an enum. +template <typename T, bool is_enum = std::is_enum<T>::value> +struct ArithmeticOrUnderlyingEnum; + +template <typename T> +struct ArithmeticOrUnderlyingEnum<T, true> { +#if defined(PRIV_USE_FALLBACKS_FOR_OLD_GLIBCXX) + using type = __underlying_type(T); +#else + using type = typename std::underlying_type<T>::type; +#endif + static const bool value = std::is_arithmetic<type>::value; +}; + +#if defined(PRIV_USE_FALLBACKS_FOR_OLD_GLIBCXX) +#undef PRIV_USE_FALLBACKS_FOR_OLD_GLIBCXX +#endif + +template <typename T> +struct ArithmeticOrUnderlyingEnum<T, false> { + using type = T; + static const bool value = std::is_arithmetic<type>::value; +}; + +// The following are helper templates used in the CheckedNumeric class. +template <typename T> +class CheckedNumeric; + +template <typename T> +class StrictNumeric; + +// Used to treat CheckedNumeric and arithmetic underlying types the same. +template <typename T> +struct UnderlyingType { + using type = typename ArithmeticOrUnderlyingEnum<T>::type; + static const bool is_numeric = std::is_arithmetic<type>::value; + static const bool is_checked = false; + static const bool is_strict = false; +}; + +template <typename T> +struct UnderlyingType<CheckedNumeric<T>> { + using type = T; + static const bool is_numeric = true; + static const bool is_checked = true; + static const bool is_strict = false; +}; + +template <typename T> +struct UnderlyingType<StrictNumeric<T>> { + using type = T; + static const bool is_numeric = true; + static const bool is_checked = false; + static const bool is_strict = true; +}; + +template <typename L, typename R> +struct IsCheckedOp { + static const bool value = + UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && + (UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked); +}; + +template <typename L, typename R> +struct IsStrictOp { + static const bool value = + UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric && + (UnderlyingType<L>::is_strict || UnderlyingType<R>::is_strict); +}; + +template <typename L, typename R> +constexpr bool IsLessImpl(const L lhs, + const R rhs, + const RangeCheck l_range, + const RangeCheck r_range) { + return l_range.IsUnderflow() || r_range.IsOverflow() || + (l_range == r_range && + static_cast<decltype(lhs + rhs)>(lhs) < + static_cast<decltype(lhs + rhs)>(rhs)); +} + +template <typename L, typename R> +struct IsLess { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + static constexpr bool Test(const L lhs, const R rhs) { + return IsLessImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs), + DstRangeRelationToSrcRange<L>(rhs)); + } +}; + +template <typename L, typename R> +constexpr bool IsLessOrEqualImpl(const L lhs, + const R rhs, + const RangeCheck l_range, + const RangeCheck r_range) { + return l_range.IsUnderflow() || r_range.IsOverflow() || + (l_range == r_range && + static_cast<decltype(lhs + rhs)>(lhs) <= + static_cast<decltype(lhs + rhs)>(rhs)); +} + +template <typename L, typename R> +struct IsLessOrEqual { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + static constexpr bool Test(const L lhs, const R rhs) { + return IsLessOrEqualImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs), + DstRangeRelationToSrcRange<L>(rhs)); + } +}; + +template <typename L, typename R> +constexpr bool IsGreaterImpl(const L lhs, + const R rhs, + const RangeCheck l_range, + const RangeCheck r_range) { + return l_range.IsOverflow() || r_range.IsUnderflow() || + (l_range == r_range && + static_cast<decltype(lhs + rhs)>(lhs) > + static_cast<decltype(lhs + rhs)>(rhs)); +} + +template <typename L, typename R> +struct IsGreater { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + static constexpr bool Test(const L lhs, const R rhs) { + return IsGreaterImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs), + DstRangeRelationToSrcRange<L>(rhs)); + } +}; + +template <typename L, typename R> +constexpr bool IsGreaterOrEqualImpl(const L lhs, + const R rhs, + const RangeCheck l_range, + const RangeCheck r_range) { + return l_range.IsOverflow() || r_range.IsUnderflow() || + (l_range == r_range && + static_cast<decltype(lhs + rhs)>(lhs) >= + static_cast<decltype(lhs + rhs)>(rhs)); +} + +template <typename L, typename R> +struct IsGreaterOrEqual { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + static constexpr bool Test(const L lhs, const R rhs) { + return IsGreaterOrEqualImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs), + DstRangeRelationToSrcRange<L>(rhs)); + } +}; + +template <typename L, typename R> +struct IsEqual { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + static constexpr bool Test(const L lhs, const R rhs) { + return DstRangeRelationToSrcRange<R>(lhs) == + DstRangeRelationToSrcRange<L>(rhs) && + static_cast<decltype(lhs + rhs)>(lhs) == + static_cast<decltype(lhs + rhs)>(rhs); + } +}; + +template <typename L, typename R> +struct IsNotEqual { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + static constexpr bool Test(const L lhs, const R rhs) { + return DstRangeRelationToSrcRange<R>(lhs) != + DstRangeRelationToSrcRange<L>(rhs) || + static_cast<decltype(lhs + rhs)>(lhs) != + static_cast<decltype(lhs + rhs)>(rhs); + } +}; + +// These perform the actual math operations on the CheckedNumerics. +// Binary arithmetic operations. +template <template <typename, typename> class C, typename L, typename R> +constexpr bool SafeCompare(const L lhs, const R rhs) { + static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value, + "Types must be numeric."); + using Promotion = BigEnoughPromotion<L, R>; + using BigType = typename Promotion::type; + return Promotion::is_contained + // Force to a larger type for speed if both are contained. + ? C<BigType, BigType>::Test( + static_cast<BigType>(static_cast<L>(lhs)), + static_cast<BigType>(static_cast<R>(rhs))) + // Let the template functions figure it out for mixed types. + : C<L, R>::Test(lhs, rhs); +}; + } // namespace internal } // namespace base } // namespace pdfium -#endif // PDFIUM_THIRD_PARTY_BASE_SAFE_CONVERSIONS_IMPL_H_ +#endif // PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ diff --git a/third_party/base/numerics/safe_math.h b/third_party/base/numerics/safe_math.h index 013af1eb6..a0c41a467 100644 --- a/third_party/base/numerics/safe_math.h +++ b/third_party/base/numerics/safe_math.h @@ -2,140 +2,268 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef PDFIUM_THIRD_PARTY_BASE_SAFE_MATH_H_ -#define PDFIUM_THIRD_PARTY_BASE_SAFE_MATH_H_ +#ifndef PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_MATH_H_ +#define PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_MATH_H_ -#include "safe_math_impl.h" +#include <stddef.h> + +#include <limits> +#include <type_traits> + +#include "third_party/base/numerics/safe_math_impl.h" namespace pdfium { namespace base { namespace internal { -// CheckedNumeric implements all the logic and operators for detecting integer +// CheckedNumeric<> implements all the logic and operators for detecting integer // boundary conditions such as overflow, underflow, and invalid conversions. // The CheckedNumeric type implicitly converts from floating point and integer // data types, and contains overloads for basic arithmetic operations (i.e.: +, -// -, *, /, %). +// -, *, / for all types and %, <<, >>, &, |, ^ for integers). Type promotions +// are a slightly modified version of the standard C arithmetic rules with the +// two differences being that there is no default promotion to int and bitwise +// logical operations always return an unsigned of the wider type. +// +// You may also use one of the variadic convenience functions, which accept +// standard arithmetic or CheckedNumeric types, perform arithmetic operations, +// and return a CheckedNumeric result. The supported functions are: +// CheckAdd() - Addition. +// CheckSub() - Subtraction. +// CheckMul() - Multiplication. +// CheckDiv() - Division. +// CheckMod() - Modulous (integer only). +// CheckLsh() - Left integer shift (integer only). +// CheckRsh() - Right integer shift (integer only). +// CheckAnd() - Bitwise AND (integer only with unsigned result). +// CheckOr() - Bitwise OR (integer only with unsigned result). +// CheckXor() - Bitwise XOR (integer only with unsigned result). +// CheckMax() - Maximum of supplied arguments. +// CheckMin() - Minimum of supplied arguments. +// +// The unary negation, increment, and decrement operators are supported, along +// with the following unary arithmetic methods, which return a new +// CheckedNumeric as a result of the operation: +// Abs() - Absolute value. +// UnsignedAbs() - Absolute value as an equal-width unsigned underlying type +// (valid for only integral types). +// Max() - Returns whichever is greater of the current instance or argument. +// The underlying return type is whichever has the greatest magnitude. +// Min() - Returns whichever is lowest of the current instance or argument. +// The underlying return type is whichever has can represent the lowest +// number in the smallest width (e.g. int8_t over unsigned, int over +// int8_t, and float over int). // // The following methods convert from CheckedNumeric to standard numeric values: -// IsValid() - Returns true if the underlying numeric value is valid (i.e. has -// has not wrapped and is not the result of an invalid conversion). -// ValueOrDie() - Returns the underlying value. If the state is not valid this -// call will crash on a CHECK. -// ValueOrDefault() - Returns the current value, or the supplied default if the -// state is not valid. -// ValueFloating() - Returns the underlying floating point value (valid only -// only for floating point CheckedNumeric types). +// AssignIfValid() - Assigns the underlying value to the supplied destination +// pointer if the value is currently valid and within the range +// supported by the destination type. Returns true on success. +// **************************************************************************** +// * WARNING: All of the following functions return a StrictNumeric, which * +// * is valid for comparison and assignment operations, but will trigger a * +// * compile failure on attempts to assign to a type of insufficient range. * +// **************************************************************************** +// IsValid() - Returns true if the underlying numeric value is valid (i.e. has +// has not wrapped and is not the result of an invalid conversion). +// ValueOrDie() - Returns the underlying value. If the state is not valid this +// call will crash on a CHECK. +// ValueOrDefault() - Returns the current value, or the supplied default if the +// state is not valid (will not trigger a CHECK). // -// Bitwise operations are explicitly not supported, because correct -// handling of some cases (e.g. sign manipulation) is ambiguous. Comparison -// operations are explicitly not supported because they could result in a crash -// on a CHECK condition. You should use patterns like the following for these -// operations: -// Bitwise operation: -// CheckedNumeric<int> checked_int = untrusted_input_value; -// int x = checked_int.ValueOrDefault(0) | kFlagValues; -// Comparison: -// CheckedNumeric<size_t> checked_size; -// CheckedNumeric<int> checked_size = untrusted_input_value; -// checked_size = checked_size + HEADER LENGTH; +// The following wrapper functions can be used to avoid the template +// disambiguator syntax when converting a destination type. +// IsValidForType<>() in place of: a.template IsValid<Dst>() +// ValueOrDieForType<>() in place of: a.template ValueOrDie() +// ValueOrDefaultForType<>() in place of: a.template ValueOrDefault(default) +// +// The following are general utility methods that are useful for converting +// between arithmetic types and CheckedNumeric types: +// CheckedNumeric::Cast<Dst>() - Instance method returning a CheckedNumeric +// derived from casting the current instance to a CheckedNumeric of +// the supplied destination type. +// MakeCheckedNum() - Creates a new CheckedNumeric from the underlying type of +// the supplied arithmetic, CheckedNumeric, or StrictNumeric type. +// +// Comparison operations are explicitly not supported because they could result +// in a crash on an unexpected CHECK condition. You should use patterns like the +// following for comparisons: +// CheckedNumeric<size_t> checked_size = untrusted_input_value; +// checked_size += HEADER LENGTH; // if (checked_size.IsValid() && checked_size.ValueOrDie() < buffer_size) // Do stuff... + template <typename T> class CheckedNumeric { + static_assert(std::is_arithmetic<T>::value, + "CheckedNumeric<T>: T must be a numeric type."); + public: - typedef T type; + using type = T; - CheckedNumeric() {} + constexpr CheckedNumeric() {} // Copy constructor. template <typename Src> - CheckedNumeric(const CheckedNumeric<Src>& rhs) - : state_(rhs.ValueUnsafe(), rhs.validity()) {} + constexpr CheckedNumeric(const CheckedNumeric<Src>& rhs) + : state_(rhs.state_.value(), rhs.IsValid()) {} template <typename Src> - CheckedNumeric(Src value, RangeConstraint validity) - : state_(value, validity) {} + friend class CheckedNumeric; // This is not an explicit constructor because we implicitly upgrade regular // numerics to CheckedNumerics to make them easier to use. template <typename Src> - CheckedNumeric(Src value) + constexpr CheckedNumeric(Src value) // NOLINT(runtime/explicit) : state_(value) { - COMPILE_ASSERT(std::numeric_limits<Src>::is_specialized, - argument_must_be_numeric); + static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric."); + } + + // This is not an explicit constructor because we want a seamless conversion + // from StrictNumeric types. + template <typename Src> + constexpr CheckedNumeric( + StrictNumeric<Src> value) // NOLINT(runtime/explicit) + : state_(static_cast<Src>(value)) {} + + // IsValid() - The public API to test if a CheckedNumeric is currently valid. + // A range checked destination type can be supplied using the Dst template + // parameter. + template <typename Dst = T> + constexpr bool IsValid() const { + return state_.is_valid() && + IsValueInRangeForNumericType<Dst>(state_.value()); } - // IsValid() is the public API to test if a CheckedNumeric is currently valid. - bool IsValid() const { return validity() == RANGE_VALID; } + // AssignIfValid(Dst) - Assigns the underlying value if it is currently valid + // and is within the range supported by the destination type. Returns true if + // successful and false otherwise. + template <typename Dst> + constexpr bool AssignIfValid(Dst* result) const { + return IsValid<Dst>() ? ((*result = static_cast<Dst>(state_.value())), true) + : false; + } - // ValueOrDie() The primary accessor for the underlying value. If the current - // state is not valid it will CHECK and crash. - T ValueOrDie() const { - CHECK(IsValid()); - return state_.value(); + // ValueOrDie() - The primary accessor for the underlying value. If the + // current state is not valid it will CHECK and crash. + // A range checked destination type can be supplied using the Dst template + // parameter, which will trigger a CHECK if the value is not in bounds for + // the destination. + // The CHECK behavior can be overridden by supplying a handler as a + // template parameter, for test code, etc. However, the handler cannot access + // the underlying value, and it is not available through other means. + template <typename Dst = T, class CheckHandler = CheckOnFailure> + constexpr StrictNumeric<Dst> ValueOrDie() const { + return IsValid<Dst>() ? static_cast<Dst>(state_.value()) + : CheckHandler::template HandleFailure<Dst>(); } - // ValueOrDefault(T default_value) A convenience method that returns the + // ValueOrDefault(T default_value) - A convenience method that returns the // current value if the state is valid, and the supplied default_value for // any other state. - T ValueOrDefault(T default_value) const { - return IsValid() ? state_.value() : default_value; + // A range checked destination type can be supplied using the Dst template + // parameter. WARNING: This function may fail to compile or CHECK at runtime + // if the supplied default_value is not within range of the destination type. + template <typename Dst = T, typename Src> + constexpr StrictNumeric<Dst> ValueOrDefault(const Src default_value) const { + return IsValid<Dst>() ? static_cast<Dst>(state_.value()) + : checked_cast<Dst>(default_value); } - // ValueFloating() - Since floating point values include their validity state, - // we provide an easy method for extracting them directly, without a risk of - // crashing on a CHECK. - T ValueFloating() const { - COMPILE_ASSERT(std::numeric_limits<T>::is_iec559, argument_must_be_float); - return CheckedNumeric<T>::cast(*this).ValueUnsafe(); + // Returns a checked numeric of the specified type, cast from the current + // CheckedNumeric. If the current state is invalid or the destination cannot + // represent the result then the returned CheckedNumeric will be invalid. + template <typename Dst> + constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const { + return *this; } - // validity() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now for - // tests and to avoid a big matrix of friend operator overloads. But the - // values it returns are likely to change in the future. - // Returns: current validity state (i.e. valid, overflow, underflow, nan). - // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for - // saturation/wrapping so we can expose this state consistently and implement - // saturated arithmetic. - RangeConstraint validity() const { return state_.validity(); } - - // ValueUnsafe() - DO NOT USE THIS IN EXTERNAL CODE - It is public right now - // for tests and to avoid a big matrix of friend operator overloads. But the - // values it returns are likely to change in the future. - // Returns: the raw numeric value, regardless of the current state. - // TODO(jschuh): crbug.com/332611 Figure out and implement semantics for - // saturation/wrapping so we can expose this state consistently and implement - // saturated arithmetic. - T ValueUnsafe() const { return state_.value(); } + // This friend method is available solely for providing more detailed logging + // in the the tests. Do not implement it in production code, because the + // underlying values may change at any time. + template <typename U> + friend U GetNumericValueForTest(const CheckedNumeric<U>& src); // Prototypes for the supported arithmetic operator overloads. - template <typename Src> CheckedNumeric& operator+=(Src rhs); - template <typename Src> CheckedNumeric& operator-=(Src rhs); - template <typename Src> CheckedNumeric& operator*=(Src rhs); - template <typename Src> CheckedNumeric& operator/=(Src rhs); - template <typename Src> CheckedNumeric& operator%=(Src rhs); - - CheckedNumeric operator-() const { - RangeConstraint validity; - T value = CheckedNeg(state_.value(), &validity); - // Negation is always valid for floating point. - if (std::numeric_limits<T>::is_iec559) - return CheckedNumeric<T>(value); - - validity = GetRangeConstraint(state_.validity() | validity); - return CheckedNumeric<T>(value, validity); + template <typename Src> + CheckedNumeric& operator+=(const Src rhs); + template <typename Src> + CheckedNumeric& operator-=(const Src rhs); + template <typename Src> + CheckedNumeric& operator*=(const Src rhs); + template <typename Src> + CheckedNumeric& operator/=(const Src rhs); + template <typename Src> + CheckedNumeric& operator%=(const Src rhs); + template <typename Src> + CheckedNumeric& operator<<=(const Src rhs); + template <typename Src> + CheckedNumeric& operator>>=(const Src rhs); + template <typename Src> + CheckedNumeric& operator&=(const Src rhs); + template <typename Src> + CheckedNumeric& operator|=(const Src rhs); + template <typename Src> + CheckedNumeric& operator^=(const Src rhs); + + constexpr CheckedNumeric operator-() const { + return CheckedNumeric<T>( + NegateWrapper(state_.value()), + IsValid() && + (!std::is_signed<T>::value || std::is_floating_point<T>::value || + NegateWrapper(state_.value()) != + std::numeric_limits<T>::lowest())); + } + + constexpr CheckedNumeric operator~() const { + return CheckedNumeric<decltype(InvertWrapper(T()))>( + InvertWrapper(state_.value()), IsValid()); } - CheckedNumeric Abs() const { - RangeConstraint validity; - T value = CheckedAbs(state_.value(), &validity); - // Absolute value is always valid for floating point. - if (std::numeric_limits<T>::is_iec559) - return CheckedNumeric<T>(value); + constexpr CheckedNumeric Abs() const { + return CheckedNumeric<T>( + AbsWrapper(state_.value()), + IsValid() && + (!std::is_signed<T>::value || std::is_floating_point<T>::value || + AbsWrapper(state_.value()) != std::numeric_limits<T>::lowest())); + } + + template <typename U> + constexpr CheckedNumeric<typename MathWrapper<CheckedMaxOp, T, U>::type> Max( + const U rhs) const { + using R = typename UnderlyingType<U>::type; + using result_type = typename MathWrapper<CheckedMaxOp, T, U>::type; + // TODO(jschuh): This can be converted to the MathOp version and remain + // constexpr once we have C++14 support. + return CheckedNumeric<result_type>( + static_cast<result_type>( + IsGreater<T, R>::Test(state_.value(), Wrapper<U>::value(rhs)) + ? state_.value() + : Wrapper<U>::value(rhs)), + state_.is_valid() && Wrapper<U>::is_valid(rhs)); + } - validity = GetRangeConstraint(state_.validity() | validity); - return CheckedNumeric<T>(value, validity); + template <typename U> + constexpr CheckedNumeric<typename MathWrapper<CheckedMinOp, T, U>::type> Min( + const U rhs) const { + using R = typename UnderlyingType<U>::type; + using result_type = typename MathWrapper<CheckedMinOp, T, U>::type; + // TODO(jschuh): This can be converted to the MathOp version and remain + // constexpr once we have C++14 support. + return CheckedNumeric<result_type>( + static_cast<result_type>( + IsLess<T, R>::Test(state_.value(), Wrapper<U>::value(rhs)) + ? state_.value() + : Wrapper<U>::value(rhs)), + state_.is_valid() && Wrapper<U>::is_valid(rhs)); + } + + // This function is available only for integral types. It returns an unsigned + // integer of the same width as the source type, containing the absolute value + // of the source, and properly handling signed min. + constexpr CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> + UnsignedAbs() const { + return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>( + SafeUnsignedAbs(state_.value()), state_.is_valid()); } CheckedNumeric& operator++() { @@ -160,113 +288,223 @@ class CheckedNumeric { return value; } - // These static methods behave like a convenience cast operator targeting - // the desired CheckedNumeric type. As an optimization, a reference is - // returned when Src is the same type as T. + // These perform the actual math operations on the CheckedNumerics. + // Binary arithmetic operations. + template <template <typename, typename, typename> class M, + typename L, + typename R> + static CheckedNumeric MathOp(const L lhs, const R rhs) { + using Math = typename MathWrapper<M, L, R>::math; + T result = 0; + bool is_valid = + Wrapper<L>::is_valid(lhs) && Wrapper<R>::is_valid(rhs) && + Math::Do(Wrapper<L>::value(lhs), Wrapper<R>::value(rhs), &result); + return CheckedNumeric<T>(result, is_valid); + }; + + // Assignment arithmetic operations. + template <template <typename, typename, typename> class M, typename R> + CheckedNumeric& MathOp(const R rhs) { + using Math = typename MathWrapper<M, T, R>::math; + T result = 0; // Using T as the destination saves a range check. + bool is_valid = state_.is_valid() && Wrapper<R>::is_valid(rhs) && + Math::Do(state_.value(), Wrapper<R>::value(rhs), &result); + *this = CheckedNumeric<T>(result, is_valid); + return *this; + }; + + private: + CheckedNumericState<T> state_; + template <typename Src> - static CheckedNumeric<T> cast( - Src u, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) { - return u; - } + constexpr CheckedNumeric(Src value, bool is_valid) + : state_(value, is_valid) {} + // These wrappers allow us to handle state the same way for both + // CheckedNumeric and POD arithmetic types. template <typename Src> - static CheckedNumeric<T> cast( - const CheckedNumeric<Src>& u, - typename std::enable_if<!std::is_same<Src, T>::value, int>::type = 0) { - return u; - } + struct Wrapper { + static constexpr bool is_valid(Src) { return true; } + static constexpr Src value(Src value) { return value; } + }; - static const CheckedNumeric<T>& cast(const CheckedNumeric<T>& u) { return u; } + template <typename Src> + struct Wrapper<CheckedNumeric<Src>> { + static constexpr bool is_valid(const CheckedNumeric<Src> v) { + return v.IsValid(); + } + static constexpr Src value(const CheckedNumeric<Src> v) { + return v.state_.value(); + } + }; - private: - CheckedNumericState<T> state_; + template <typename Src> + struct Wrapper<StrictNumeric<Src>> { + static constexpr bool is_valid(const StrictNumeric<Src>) { return true; } + static constexpr Src value(const StrictNumeric<Src> v) { + return static_cast<Src>(v); + } + }; }; -// This is the boilerplate for the standard arithmetic operator overloads. A -// macro isn't the prettiest solution, but it beats rewriting these five times. -// Some details worth noting are: -// * We apply the standard arithmetic promotions. -// * We skip range checks for floating points. -// * We skip range checks for destination integers with sufficient range. -// TODO(jschuh): extract these out into templates. -#define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \ - /* Binary arithmetic operator for CheckedNumerics of the same type. */ \ - template <typename T> \ - CheckedNumeric<typename ArithmeticPromotion<T>::type> operator OP( \ - const CheckedNumeric<T>& lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T>::type Promotion; \ - /* Floating point always takes the fast path */ \ - if (std::numeric_limits<T>::is_iec559) \ - return CheckedNumeric<T>(lhs.ValueUnsafe() OP rhs.ValueUnsafe()); \ - if (IsIntegerArithmeticSafe<Promotion, T, T>::value) \ - return CheckedNumeric<Promotion>( \ - lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ - GetRangeConstraint(rhs.validity() | lhs.validity())); \ - RangeConstraint validity = RANGE_VALID; \ - T result = Checked##NAME(static_cast<Promotion>(lhs.ValueUnsafe()), \ - static_cast<Promotion>(rhs.ValueUnsafe()), \ - &validity); \ - return CheckedNumeric<Promotion>( \ - result, \ - GetRangeConstraint(validity | lhs.validity() | rhs.validity())); \ - } \ - /* Assignment arithmetic operator implementation from CheckedNumeric. */ \ - template <typename T> \ - template <typename Src> \ - CheckedNumeric<T>& CheckedNumeric<T>::operator COMPOUND_OP(Src rhs) { \ - *this = CheckedNumeric<T>::cast(*this) OP CheckedNumeric<Src>::cast(rhs); \ - return *this; \ - } \ - /* Binary arithmetic operator for CheckedNumeric of different type. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - const CheckedNumeric<Src>& lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>( \ - lhs.ValueUnsafe() OP rhs.ValueUnsafe(), \ - GetRangeConstraint(rhs.validity() | lhs.validity())); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } \ - /* Binary arithmetic operator for left CheckedNumeric and right numeric. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - const CheckedNumeric<T>& lhs, Src rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>(lhs.ValueUnsafe() OP rhs, \ - lhs.validity()); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } \ - /* Binary arithmetic operator for right numeric and left CheckedNumeric. */ \ - template <typename T, typename Src> \ - CheckedNumeric<typename ArithmeticPromotion<T, Src>::type> operator OP( \ - Src lhs, const CheckedNumeric<T>& rhs) { \ - typedef typename ArithmeticPromotion<T, Src>::type Promotion; \ - if (IsIntegerArithmeticSafe<Promotion, T, Src>::value) \ - return CheckedNumeric<Promotion>(lhs OP rhs.ValueUnsafe(), \ - rhs.validity()); \ - return CheckedNumeric<Promotion>::cast(lhs) \ - OP CheckedNumeric<Promotion>::cast(rhs); \ - } +// Convenience functions to avoid the ugly template disambiguator syntax. +template <typename Dst, typename Src> +constexpr bool IsValidForType(const CheckedNumeric<Src> value) { + return value.template IsValid<Dst>(); +} + +template <typename Dst, typename Src> +constexpr StrictNumeric<Dst> ValueOrDieForType( + const CheckedNumeric<Src> value) { + return value.template ValueOrDie<Dst>(); +} + +template <typename Dst, typename Src, typename Default> +constexpr StrictNumeric<Dst> ValueOrDefaultForType( + const CheckedNumeric<Src> value, + const Default default_value) { + return value.template ValueOrDefault<Dst>(default_value); +} + +// These variadic templates work out the return types. +// TODO(jschuh): Rip all this out once we have C++14 non-trailing auto support. +template <template <typename, typename, typename> class M, + typename L, + typename R, + typename... Args> +struct ResultType; + +template <template <typename, typename, typename> class M, + typename L, + typename R> +struct ResultType<M, L, R> { + using type = typename MathWrapper<M, L, R>::type; +}; + +template <template <typename, typename, typename> class M, + typename L, + typename R, + typename... Args> +struct ResultType { + using type = + typename ResultType<M, typename ResultType<M, L, R>::type, Args...>::type; +}; + +// Convience wrapper to return a new CheckedNumeric from the provided arithmetic +// or CheckedNumericType. +template <typename T> +constexpr CheckedNumeric<typename UnderlyingType<T>::type> MakeCheckedNum( + const T value) { + return value; +} + +// These implement the variadic wrapper for the math operations. +template <template <typename, typename, typename> class M, + typename L, + typename R> +CheckedNumeric<typename MathWrapper<M, L, R>::type> ChkMathOp(const L lhs, + const R rhs) { + using Math = typename MathWrapper<M, L, R>::math; + return CheckedNumeric<typename Math::result_type>::template MathOp<M>(lhs, + rhs); +} + +// General purpose wrapper template for arithmetic operations. +template <template <typename, typename, typename> class M, + typename L, + typename R, + typename... Args> +CheckedNumeric<typename ResultType<M, L, R, Args...>::type> +ChkMathOp(const L lhs, const R rhs, const Args... args) { + auto tmp = ChkMathOp<M>(lhs, rhs); + return tmp.IsValid() ? ChkMathOp<M>(tmp, args...) + : decltype(ChkMathOp<M>(tmp, args...))(tmp); +}; -BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, += ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /= ) -BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %= ) +// The following macros are just boilerplate for the standard arithmetic +// operator overloads and variadic function templates. A macro isn't the nicest +// solution, but it beats rewriting these over and over again. +#define BASE_NUMERIC_ARITHMETIC_VARIADIC(NAME) \ + template <typename L, typename R, typename... Args> \ + CheckedNumeric<typename ResultType<Checked##NAME##Op, L, R, Args...>::type> \ + Check##NAME(const L lhs, const R rhs, const Args... args) { \ + return ChkMathOp<Checked##NAME##Op, L, R, Args...>(lhs, rhs, args...); \ + } +#define BASE_NUMERIC_ARITHMETIC_OPERATORS(NAME, OP, COMPOUND_OP) \ + /* Binary arithmetic operator for all CheckedNumeric operations. */ \ + template <typename L, typename R, \ + typename std::enable_if<IsCheckedOp<L, R>::value>::type* = \ + nullptr> \ + CheckedNumeric<typename MathWrapper<Checked##NAME##Op, L, R>::type> \ + operator OP(const L lhs, const R rhs) { \ + return decltype(lhs OP rhs)::template MathOp<Checked##NAME##Op>(lhs, rhs); \ + } \ + /* Assignment arithmetic operator implementation from CheckedNumeric. */ \ + template <typename L> \ + template <typename R> \ + CheckedNumeric<L>& CheckedNumeric<L>::operator COMPOUND_OP(const R rhs) { \ + return MathOp<Checked##NAME##Op>(rhs); \ + } \ + /* Variadic arithmetic functions that return CheckedNumeric. */ \ + BASE_NUMERIC_ARITHMETIC_VARIADIC(NAME) + +BASE_NUMERIC_ARITHMETIC_OPERATORS(Add, +, +=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Sub, -, -=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Mul, *, *=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Div, /, /=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Mod, %, %=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Lsh, <<, <<=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Rsh, >>, >>=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(And, &, &=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Or, |, |=) +BASE_NUMERIC_ARITHMETIC_OPERATORS(Xor, ^, ^=) +BASE_NUMERIC_ARITHMETIC_VARIADIC(Max) +BASE_NUMERIC_ARITHMETIC_VARIADIC(Min) + +#undef BASE_NUMERIC_ARITHMETIC_VARIADIC #undef BASE_NUMERIC_ARITHMETIC_OPERATORS +// These are some extra StrictNumeric operators to support simple pointer +// arithmetic with our result types. Since wrapping on a pointer is always +// bad, we trigger the CHECK condition here. +template <typename L, typename R> +L* operator+(L* lhs, const StrictNumeric<R> rhs) { + uintptr_t result = CheckAdd(reinterpret_cast<uintptr_t>(lhs), + CheckMul(sizeof(L), static_cast<R>(rhs))) + .template ValueOrDie<uintptr_t>(); + return reinterpret_cast<L*>(result); +} + +template <typename L, typename R> +L* operator-(L* lhs, const StrictNumeric<R> rhs) { + uintptr_t result = CheckSub(reinterpret_cast<uintptr_t>(lhs), + CheckMul(sizeof(L), static_cast<R>(rhs))) + .template ValueOrDie<uintptr_t>(); + return reinterpret_cast<L*>(result); +} + } // namespace internal using internal::CheckedNumeric; +using internal::IsValidForType; +using internal::ValueOrDieForType; +using internal::ValueOrDefaultForType; +using internal::MakeCheckedNum; +using internal::CheckMax; +using internal::CheckMin; +using internal::CheckAdd; +using internal::CheckSub; +using internal::CheckMul; +using internal::CheckDiv; +using internal::CheckMod; +using internal::CheckLsh; +using internal::CheckRsh; +using internal::CheckAnd; +using internal::CheckOr; +using internal::CheckXor; } // namespace base } // namespace pdfium -#endif // PDFIUM_THIRD_PARTY_BASE_SAFE_MATH_H_ +#endif // PDFIUM_THIRD_PARTY_BASE_NUMERICS_SAFE_MATH_H_ diff --git a/third_party/base/numerics/safe_math_impl.h b/third_party/base/numerics/safe_math_impl.h index f950f5d51..5ad79ce19 100644 --- a/third_party/base/numerics/safe_math_impl.h +++ b/third_party/base/numerics/safe_math_impl.h @@ -14,7 +14,6 @@ #include <limits> #include <type_traits> -#include "third_party/base/macros.h" #include "third_party/base/numerics/safe_conversions.h" namespace pdfium { @@ -25,355 +24,486 @@ namespace internal { // but it may not be fast. This code could be split based on // platform/architecture and replaced with potentially faster implementations. -// Integer promotion templates used by the portable checked integer arithmetic. -template <size_t Size, bool IsSigned> -struct IntegerForSizeAndSign; -template <> -struct IntegerForSizeAndSign<1, true> { - typedef int8_t type; -}; -template <> -struct IntegerForSizeAndSign<1, false> { - typedef uint8_t type; -}; -template <> -struct IntegerForSizeAndSign<2, true> { - typedef int16_t type; -}; -template <> -struct IntegerForSizeAndSign<2, false> { - typedef uint16_t type; -}; -template <> -struct IntegerForSizeAndSign<4, true> { - typedef int32_t type; -}; -template <> -struct IntegerForSizeAndSign<4, false> { - typedef uint32_t type; -}; -template <> -struct IntegerForSizeAndSign<8, true> { - typedef int64_t type; -}; -template <> -struct IntegerForSizeAndSign<8, false> { - typedef uint64_t type; -}; - -// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to -// support 128-bit math, then the ArithmeticPromotion template below will need -// to be updated (or more likely replaced with a decltype expression). - -template <typename Integer> -struct UnsignedIntegerForSize { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign<sizeof(Integer), false>::type>::type type; -}; - -template <typename Integer> -struct SignedIntegerForSize { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign<sizeof(Integer), true>::type>::type type; -}; - -template <typename Integer> -struct TwiceWiderInteger { - typedef typename std::enable_if< - std::numeric_limits<Integer>::is_integer, - typename IntegerForSizeAndSign< - sizeof(Integer) * 2, - std::numeric_limits<Integer>::is_signed>::type>::type type; -}; - -template <typename Integer> -struct PositionOfSignBit { - static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, - size_t>::type value = - CHAR_BIT * sizeof(Integer) - 1; -}; - // This is used for UnsignedAbs, where we need to support floating-point // template instantiations even though we don't actually support the operations. -// However, there is no corresponding implementation of e.g. CheckedUnsignedAbs, +// However, there is no corresponding implementation of e.g. SafeUnsignedAbs, // so the float versions will not compile. template <typename Numeric, - bool IsInteger = std::numeric_limits<Numeric>::is_integer, - bool IsFloat = std::numeric_limits<Numeric>::is_iec559> + bool IsInteger = std::is_integral<Numeric>::value, + bool IsFloat = std::is_floating_point<Numeric>::value> struct UnsignedOrFloatForSize; template <typename Numeric> struct UnsignedOrFloatForSize<Numeric, true, false> { - typedef typename UnsignedIntegerForSize<Numeric>::type type; + using type = typename std::make_unsigned<Numeric>::type; }; template <typename Numeric> struct UnsignedOrFloatForSize<Numeric, false, true> { - typedef Numeric type; + using type = Numeric; }; -// Helper templates for integer manipulations. - -template <typename T> -constexpr bool HasSignBit(T x) { - // Cast to unsigned since right shift on signed is undefined. - return !!(static_cast<typename UnsignedIntegerForSize<T>::type>(x) >> - PositionOfSignBit<T>::value); -} - -// This wrapper undoes the standard integer promotions. -template <typename T> -constexpr T BinaryComplement(T x) { - return static_cast<T>(~x); -} - -// Here are the actual portable checked integer math implementations. -// TODO(jschuh): Break this code out from the enable_if pattern and find a clean -// way to coalesce things into the CheckedNumericState specializations below. +// Probe for builtin math overflow support on Clang and version check on GCC. +#if defined(__has_builtin) +#define USE_OVERFLOW_BUILTINS (__has_builtin(__builtin_add_overflow)) +#elif defined(__GNUC__) +#define USE_OVERFLOW_BUILTINS (__GNUC__ >= 5) +#else +#define USE_OVERFLOW_BUILTINS (0) +#endif template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type -CheckedAdd(T x, T y, RangeConstraint* validity) { +bool CheckedAddImpl(T x, T y, T* result) { + static_assert(std::is_integral<T>::value, "Type must be integral"); // Since the value of x+y is undefined if we have a signed type, we compute // it using the unsigned type of the same size. - typedef typename UnsignedIntegerForSize<T>::type UnsignedDst; + using UnsignedDst = typename std::make_unsigned<T>::type; + using SignedDst = typename std::make_signed<T>::type; UnsignedDst ux = static_cast<UnsignedDst>(x); UnsignedDst uy = static_cast<UnsignedDst>(y); UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy); + *result = static_cast<T>(uresult); // Addition is valid if the sign of (x + y) is equal to either that of x or // that of y. - if (std::numeric_limits<T>::is_signed) { - if (HasSignBit(BinaryComplement( - static_cast<UnsignedDst>((uresult ^ ux) & (uresult ^ uy))))) { - *validity = RANGE_VALID; - } else { // Direction of wrap is inverse of result sign. - *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; + return (std::is_signed<T>::value) + ? static_cast<SignedDst>((uresult ^ ux) & (uresult ^ uy)) >= 0 + : uresult >= uy; // Unsigned is either valid or underflow. +} + +template <typename T, typename U, class Enable = void> +struct CheckedAddOp {}; + +template <typename T, typename U> +struct CheckedAddOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename MaxExponentPromotion<T, U>::type; + template <typename V> + static bool Do(T x, U y, V* result) { +#if USE_OVERFLOW_BUILTINS + return !__builtin_add_overflow(x, y, result); +#else + using Promotion = typename BigEnoughPromotion<T, U>::type; + Promotion presult; + // Fail if either operand is out of range for the promoted type. + // TODO(jschuh): This could be made to work for a broader range of values. + bool is_valid = IsValueInRangeForNumericType<Promotion>(x) && + IsValueInRangeForNumericType<Promotion>(y); + + if (IsIntegerArithmeticSafe<Promotion, T, U>::value) { + presult = static_cast<Promotion>(x) + static_cast<Promotion>(y); + } else { + is_valid &= CheckedAddImpl(static_cast<Promotion>(x), + static_cast<Promotion>(y), &presult); } - } else { // Unsigned is either valid or overflow. - *validity = BinaryComplement(x) >= y ? RANGE_VALID : RANGE_OVERFLOW; + *result = static_cast<V>(presult); + return is_valid && IsValueInRangeForNumericType<V>(presult); +#endif } - return static_cast<T>(uresult); -} +}; template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer, T>::type -CheckedSub(T x, T y, RangeConstraint* validity) { +bool CheckedSubImpl(T x, T y, T* result) { + static_assert(std::is_integral<T>::value, "Type must be integral"); // Since the value of x+y is undefined if we have a signed type, we compute // it using the unsigned type of the same size. - typedef typename UnsignedIntegerForSize<T>::type UnsignedDst; + using UnsignedDst = typename std::make_unsigned<T>::type; + using SignedDst = typename std::make_signed<T>::type; UnsignedDst ux = static_cast<UnsignedDst>(x); UnsignedDst uy = static_cast<UnsignedDst>(y); UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy); + *result = static_cast<T>(uresult); // Subtraction is valid if either x and y have same sign, or (x-y) and x have // the same sign. - if (std::numeric_limits<T>::is_signed) { - if (HasSignBit(BinaryComplement( - static_cast<UnsignedDst>((uresult ^ ux) & (ux ^ uy))))) { - *validity = RANGE_VALID; - } else { // Direction of wrap is inverse of result sign. - *validity = HasSignBit(uresult) ? RANGE_OVERFLOW : RANGE_UNDERFLOW; + return (std::is_signed<T>::value) + ? static_cast<SignedDst>((uresult ^ ux) & (ux ^ uy)) >= 0 + : x >= y; +} + +template <typename T, typename U, class Enable = void> +struct CheckedSubOp {}; + +template <typename T, typename U> +struct CheckedSubOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename MaxExponentPromotion<T, U>::type; + template <typename V> + static bool Do(T x, U y, V* result) { +#if USE_OVERFLOW_BUILTINS + return !__builtin_sub_overflow(x, y, result); +#else + using Promotion = typename BigEnoughPromotion<T, U>::type; + Promotion presult; + // Fail if either operand is out of range for the promoted type. + // TODO(jschuh): This could be made to work for a broader range of values. + bool is_valid = IsValueInRangeForNumericType<Promotion>(x) && + IsValueInRangeForNumericType<Promotion>(y); + + if (IsIntegerArithmeticSafe<Promotion, T, U>::value) { + presult = static_cast<Promotion>(x) - static_cast<Promotion>(y); + } else { + is_valid &= CheckedSubImpl(static_cast<Promotion>(x), + static_cast<Promotion>(y), &presult); } - } else { // Unsigned is either valid or underflow. - *validity = x >= y ? RANGE_VALID : RANGE_UNDERFLOW; + *result = static_cast<V>(presult); + return is_valid && IsValueInRangeForNumericType<V>(presult); +#endif } - return static_cast<T>(uresult); -} +}; -// Integer multiplication is a bit complicated. In the fast case we just -// we just promote to a twice wider type, and range check the result. In the -// slow case we need to manually check that the result won't be truncated by -// checking with division against the appropriate bound. template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - sizeof(T) * 2 <= sizeof(uintmax_t), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - typedef typename TwiceWiderInteger<T>::type IntermediateType; - IntermediateType tmp = - static_cast<IntermediateType>(x) * static_cast<IntermediateType>(y); - *validity = DstRangeRelationToSrcRange<T>(tmp); - return static_cast<T>(tmp); +bool CheckedMulImpl(T x, T y, T* result) { + static_assert(std::is_integral<T>::value, "Type must be integral"); + // Since the value of x*y is potentially undefined if we have a signed type, + // we compute it using the unsigned type of the same size. + using UnsignedDst = typename std::make_unsigned<T>::type; + using SignedDst = typename std::make_signed<T>::type; + const UnsignedDst ux = SafeUnsignedAbs(x); + const UnsignedDst uy = SafeUnsignedAbs(y); + UnsignedDst uresult = static_cast<UnsignedDst>(ux * uy); + const bool is_negative = + std::is_signed<T>::value && static_cast<SignedDst>(x ^ y) < 0; + *result = is_negative ? 0 - uresult : uresult; + // We have a fast out for unsigned identity or zero on the second operand. + // After that it's an unsigned overflow check on the absolute value, with + // a +1 bound for a negative result. + return uy <= UnsignedDst(!std::is_signed<T>::value || is_negative) || + ux <= (std::numeric_limits<T>::max() + UnsignedDst(is_negative)) / uy; } -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - // If either side is zero then the result will be zero. - if (!x || !y) { - *validity = RANGE_VALID; - return static_cast<T>(0); - } - if (x > 0) { - if (y > 0) { - *validity = - x <= std::numeric_limits<T>::max() / y ? RANGE_VALID : RANGE_OVERFLOW; +template <typename T, typename U, class Enable = void> +struct CheckedMulOp {}; + +template <typename T, typename U> +struct CheckedMulOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename MaxExponentPromotion<T, U>::type; + template <typename V> + static bool Do(T x, U y, V* result) { +#if USE_OVERFLOW_BUILTINS +#if defined(__clang__) + // TODO(jschuh): Get the Clang runtime library issues sorted out so we can + // support full-width, mixed-sign multiply builtins. + // https://crbug.com/613003 + static const bool kUseMaxInt = + // Narrower type than uintptr_t is always safe. + std::numeric_limits<__typeof__(x * y)>::digits < + std::numeric_limits<intptr_t>::digits || + // Safe for intptr_t and uintptr_t if the sign matches. + (IntegerBitsPlusSign<__typeof__(x * y)>::value == + IntegerBitsPlusSign<intptr_t>::value && + std::is_signed<T>::value == std::is_signed<U>::value); +#else + static const bool kUseMaxInt = true; +#endif + if (kUseMaxInt) + return !__builtin_mul_overflow(x, y, result); +#endif + using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type; + Promotion presult; + // Fail if either operand is out of range for the promoted type. + // TODO(jschuh): This could be made to work for a broader range of values. + bool is_valid = IsValueInRangeForNumericType<Promotion>(x) && + IsValueInRangeForNumericType<Promotion>(y); + + if (IsIntegerArithmeticSafe<Promotion, T, U>::value) { + presult = static_cast<Promotion>(x) * static_cast<Promotion>(y); } else { - *validity = y >= std::numeric_limits<T>::min() / x ? RANGE_VALID - : RANGE_UNDERFLOW; - } - } else { - if (y > 0) { - *validity = x >= std::numeric_limits<T>::min() / y ? RANGE_VALID - : RANGE_UNDERFLOW; - } else { - *validity = - y >= std::numeric_limits<T>::max() / x ? RANGE_VALID : RANGE_OVERFLOW; + is_valid &= CheckedMulImpl(static_cast<Promotion>(x), + static_cast<Promotion>(y), &presult); } + *result = static_cast<V>(presult); + return is_valid && IsValueInRangeForNumericType<V>(presult); } - return static_cast<T>(*validity == RANGE_VALID ? x * y : 0); -} +}; -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed && - (sizeof(T) * 2 > sizeof(uintmax_t)), - T>::type -CheckedMul(T x, T y, RangeConstraint* validity) { - *validity = (y == 0 || x <= std::numeric_limits<T>::max() / y) - ? RANGE_VALID - : RANGE_OVERFLOW; - return static_cast<T>(*validity == RANGE_VALID ? x * y : 0); -} +// Avoid poluting the namespace once we're done with the macro. +#undef USE_OVERFLOW_BUILTINS // Division just requires a check for a zero denominator or an invalid negation // on signed min/-1. template <typename T> -T CheckedDiv(T x, - T y, - RangeConstraint* validity, - typename std::enable_if<std::numeric_limits<T>::is_integer, - int>::type = 0) { - if (y == 0) { - *validity = RANGE_INVALID; - return static_cast<T>(0); - } - if (std::numeric_limits<T>::is_signed && x == std::numeric_limits<T>::min() && - y == static_cast<T>(-1)) { - *validity = RANGE_OVERFLOW; - return std::numeric_limits<T>::min(); +bool CheckedDivImpl(T x, T y, T* result) { + static_assert(std::is_integral<T>::value, "Type must be integral"); + if (y && (!std::is_signed<T>::value || + x != std::numeric_limits<T>::lowest() || y != static_cast<T>(-1))) { + *result = x / y; + return true; } - - *validity = RANGE_VALID; - return static_cast<T>(x / y); + return false; } -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedMod(T x, T y, RangeConstraint* validity) { - *validity = y > 0 ? RANGE_VALID : RANGE_INVALID; - return static_cast<T>(*validity == RANGE_VALID ? x % y : 0); -} +template <typename T, typename U, class Enable = void> +struct CheckedDivOp {}; + +template <typename T, typename U> +struct CheckedDivOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename MaxExponentPromotion<T, U>::type; + template <typename V> + static bool Do(T x, U y, V* result) { + using Promotion = typename BigEnoughPromotion<T, U>::type; + Promotion presult; + // Fail if either operand is out of range for the promoted type. + // TODO(jschuh): This could be made to work for a broader range of values. + bool is_valid = IsValueInRangeForNumericType<Promotion>(x) && + IsValueInRangeForNumericType<Promotion>(y); + is_valid &= CheckedDivImpl(static_cast<Promotion>(x), + static_cast<Promotion>(y), &presult); + *result = static_cast<V>(presult); + return is_valid && IsValueInRangeForNumericType<V>(presult); + } +}; template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedMod(T x, T y, RangeConstraint* validity) { - *validity = y != 0 ? RANGE_VALID : RANGE_INVALID; - return static_cast<T>(*validity == RANGE_VALID ? x % y : 0); +bool CheckedModImpl(T x, T y, T* result) { + static_assert(std::is_integral<T>::value, "Type must be integral"); + if (y > 0) { + *result = static_cast<T>(x % y); + return true; + } + return false; } -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedNeg(T value, RangeConstraint* validity) { - *validity = - value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; - // The negation of signed min is min, so catch that one. - return static_cast<T>(*validity == RANGE_VALID ? -value : 0); -} +template <typename T, typename U, class Enable = void> +struct CheckedModOp {}; + +template <typename T, typename U> +struct CheckedModOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename MaxExponentPromotion<T, U>::type; + template <typename V> + static bool Do(T x, U y, V* result) { + using Promotion = typename BigEnoughPromotion<T, U>::type; + Promotion presult; + bool is_valid = CheckedModImpl(static_cast<Promotion>(x), + static_cast<Promotion>(y), &presult); + *result = static_cast<V>(presult); + return is_valid && IsValueInRangeForNumericType<V>(presult); + } +}; -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedNeg(T value, RangeConstraint* validity) { - // The only legal unsigned negation is zero. - *validity = value ? RANGE_UNDERFLOW : RANGE_VALID; - return static_cast<T>( - *validity == RANGE_VALID - ? -static_cast<typename SignedIntegerForSize<T>::type>(value) - : 0); -} +template <typename T, typename U, class Enable = void> +struct CheckedLshOp {}; + +// Left shift. Shifts less than 0 or greater than or equal to the number +// of bits in the promoted type are undefined. Shifts of negative values +// are undefined. Otherwise it is defined when the result fits. +template <typename T, typename U> +struct CheckedLshOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = T; + template <typename V> + static bool Do(T x, U shift, V* result) { + using ShiftType = typename std::make_unsigned<T>::type; + static const ShiftType kBitWidth = IntegerBitsPlusSign<T>::value; + const ShiftType real_shift = static_cast<ShiftType>(shift); + // Signed shift is not legal on negative values. + if (!IsValueNegative(x) && real_shift < kBitWidth) { + // Just use a multiplication because it's easy. + // TODO(jschuh): This could probably be made more efficient. + if (!std::is_signed<T>::value || real_shift != kBitWidth - 1) + return CheckedMulOp<T, T>::Do(x, static_cast<T>(1) << shift, result); + return !x; // Special case zero for a full width signed shift. + } + return false; + } +}; -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - T>::type -CheckedAbs(T value, RangeConstraint* validity) { - *validity = - value != std::numeric_limits<T>::min() ? RANGE_VALID : RANGE_OVERFLOW; - return static_cast<T>(*validity == RANGE_VALID ? std::abs(value) : 0); -} +template <typename T, typename U, class Enable = void> +struct CheckedRshOp {}; + +// Right shift. Shifts less than 0 or greater than or equal to the number +// of bits in the promoted type are undefined. Otherwise, it is always defined, +// but a right shift of a negative value is implementation-dependent. +template <typename T, typename U> +struct CheckedRshOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = T; + template <typename V = result_type> + static bool Do(T x, U shift, V* result) { + // Use the type conversion push negative values out of range. + using ShiftType = typename std::make_unsigned<T>::type; + if (static_cast<ShiftType>(shift) < IntegerBitsPlusSign<T>::value) { + T tmp = x >> shift; + *result = static_cast<V>(tmp); + return IsValueInRangeForNumericType<V>(tmp); + } + return false; + } +}; -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedAbs(T value, RangeConstraint* validity) { - // T is unsigned, so |value| must already be positive. - *validity = RANGE_VALID; - return value; -} +template <typename T, typename U, class Enable = void> +struct CheckedAndOp {}; + +// For simplicity we support only unsigned integer results. +template <typename T, typename U> +struct CheckedAndOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename std::make_unsigned< + typename MaxExponentPromotion<T, U>::type>::type; + template <typename V = result_type> + static bool Do(T x, U y, V* result) { + result_type tmp = static_cast<result_type>(x) & static_cast<result_type>(y); + *result = static_cast<V>(tmp); + return IsValueInRangeForNumericType<V>(tmp); + } +}; -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - std::numeric_limits<T>::is_signed, - typename UnsignedIntegerForSize<T>::type>::type -CheckedUnsignedAbs(T value) { - typedef typename UnsignedIntegerForSize<T>::type UnsignedT; - return value == std::numeric_limits<T>::min() - ? static_cast<UnsignedT>(std::numeric_limits<T>::max()) + 1 - : static_cast<UnsignedT>(std::abs(value)); -} +template <typename T, typename U, class Enable = void> +struct CheckedOrOp {}; + +// For simplicity we support only unsigned integers. +template <typename T, typename U> +struct CheckedOrOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename std::make_unsigned< + typename MaxExponentPromotion<T, U>::type>::type; + template <typename V = result_type> + static bool Do(T x, U y, V* result) { + result_type tmp = static_cast<result_type>(x) | static_cast<result_type>(y); + *result = static_cast<V>(tmp); + return IsValueInRangeForNumericType<V>(tmp); + } +}; -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_integer && - !std::numeric_limits<T>::is_signed, - T>::type -CheckedUnsignedAbs(T value) { - // T is unsigned, so |value| must already be positive. - return static_cast<T>(value); -} +template <typename T, typename U, class Enable = void> +struct CheckedXorOp {}; + +// For simplicity we support only unsigned integers. +template <typename T, typename U> +struct CheckedXorOp<T, + U, + typename std::enable_if<std::is_integral<T>::value && + std::is_integral<U>::value>::type> { + using result_type = typename std::make_unsigned< + typename MaxExponentPromotion<T, U>::type>::type; + template <typename V = result_type> + static bool Do(T x, U y, V* result) { + result_type tmp = static_cast<result_type>(x) ^ static_cast<result_type>(y); + *result = static_cast<V>(tmp); + return IsValueInRangeForNumericType<V>(tmp); + } +}; -// These are the floating point stubs that the compiler needs to see. Only the -// negation operation is ever called. -#define BASE_FLOAT_ARITHMETIC_STUBS(NAME) \ - template <typename T> \ - typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type \ - Checked##NAME(T, T, RangeConstraint*) { \ - NOTREACHED(); \ - return static_cast<T>(0); \ +// Max doesn't really need to be implemented this way because it can't fail, +// but it makes the code much cleaner to use the MathOp wrappers. +template <typename T, typename U, class Enable = void> +struct CheckedMaxOp {}; + +template <typename T, typename U> +struct CheckedMaxOp< + T, + U, + typename std::enable_if<std::is_arithmetic<T>::value && + std::is_arithmetic<U>::value>::type> { + using result_type = typename MaxExponentPromotion<T, U>::type; + template <typename V = result_type> + static bool Do(T x, U y, V* result) { + *result = IsGreater<T, U>::Test(x, y) ? static_cast<result_type>(x) + : static_cast<result_type>(y); + return true; } +}; -BASE_FLOAT_ARITHMETIC_STUBS(Add) -BASE_FLOAT_ARITHMETIC_STUBS(Sub) -BASE_FLOAT_ARITHMETIC_STUBS(Mul) -BASE_FLOAT_ARITHMETIC_STUBS(Div) -BASE_FLOAT_ARITHMETIC_STUBS(Mod) +// Min doesn't really need to be implemented this way because it can't fail, +// but it makes the code much cleaner to use the MathOp wrappers. +template <typename T, typename U, class Enable = void> +struct CheckedMinOp {}; + +template <typename T, typename U> +struct CheckedMinOp< + T, + U, + typename std::enable_if<std::is_arithmetic<T>::value && + std::is_arithmetic<U>::value>::type> { + using result_type = typename LowestValuePromotion<T, U>::type; + template <typename V = result_type> + static bool Do(T x, U y, V* result) { + *result = IsLess<T, U>::Test(x, y) ? static_cast<result_type>(x) + : static_cast<result_type>(y); + return true; + } +}; -#undef BASE_FLOAT_ARITHMETIC_STUBS +// This is just boilerplate that wraps the standard floating point arithmetic. +// A macro isn't the nicest solution, but it beats rewriting these repeatedly. +#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \ + template <typename T, typename U> \ + struct Checked##NAME##Op< \ + T, U, typename std::enable_if<std::is_floating_point<T>::value || \ + std::is_floating_point<U>::value>::type> { \ + using result_type = typename MaxExponentPromotion<T, U>::type; \ + template <typename V> \ + static bool Do(T x, U y, V* result) { \ + using Promotion = typename MaxExponentPromotion<T, U>::type; \ + Promotion presult = x OP y; \ + *result = static_cast<V>(presult); \ + return IsValueInRangeForNumericType<V>(presult); \ + } \ + }; + +BASE_FLOAT_ARITHMETIC_OPS(Add, +) +BASE_FLOAT_ARITHMETIC_OPS(Sub, -) +BASE_FLOAT_ARITHMETIC_OPS(Mul, *) +BASE_FLOAT_ARITHMETIC_OPS(Div, /) + +#undef BASE_FLOAT_ARITHMETIC_OPS + +// Wrap the unary operations to allow SFINAE when instantiating integrals versus +// floating points. These don't perform any overflow checking. Rather, they +// exhibit well-defined overflow semantics and rely on the caller to detect +// if an overflow occured. + +template <typename T, + typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> +constexpr T NegateWrapper(T value) { + using UnsignedT = typename std::make_unsigned<T>::type; + // This will compile to a NEG on Intel, and is normal negation on ARM. + return static_cast<T>(UnsignedT(0) - static_cast<UnsignedT>(value)); +} -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedNeg( - T value, - RangeConstraint*) { - return static_cast<T>(-value); +template < + typename T, + typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> +constexpr T NegateWrapper(T value) { + return -value; } -template <typename T> -typename std::enable_if<std::numeric_limits<T>::is_iec559, T>::type CheckedAbs( - T value, - RangeConstraint*) { - return static_cast<T>(std::abs(value)); +template <typename T, + typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> +constexpr typename std::make_unsigned<T>::type InvertWrapper(T value) { + return ~value; +} + +template <typename T, + typename std::enable_if<std::is_integral<T>::value>::type* = nullptr> +constexpr T AbsWrapper(T value) { + return static_cast<T>(SafeUnsignedAbs(value)); +} + +template < + typename T, + typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr> +constexpr T AbsWrapper(T value) { + return value < 0 ? -value : value; } // Floats carry around their validity state with them, but integers do not. So, @@ -388,10 +518,10 @@ enum NumericRepresentation { template <typename NumericType> struct GetNumericRepresentation { static const NumericRepresentation value = - std::numeric_limits<NumericType>::is_integer + std::is_integral<NumericType>::value ? NUMERIC_INTEGER - : (std::numeric_limits<NumericType>::is_iec559 ? NUMERIC_FLOATING - : NUMERIC_UNKNOWN); + : (std::is_floating_point<NumericType>::value ? NUMERIC_FLOATING + : NUMERIC_UNKNOWN); }; template <typename T, NumericRepresentation type = @@ -402,41 +532,48 @@ class CheckedNumericState {}; template <typename T> class CheckedNumericState<T, NUMERIC_INTEGER> { private: + // is_valid_ precedes value_ because member intializers in the constructors + // are evaluated in field order, and is_valid_ must be read when initializing + // value_. + bool is_valid_; T value_; - RangeConstraint validity_ : CHAR_BIT; // Actually requires only two bits. + + // Ensures that a type conversion does not trigger undefined behavior. + template <typename Src> + static constexpr T WellDefinedConversionOrZero(const Src value, + const bool is_valid) { + using SrcType = typename internal::UnderlyingType<Src>::type; + return (std::is_integral<SrcType>::value || is_valid) + ? static_cast<T>(value) + : static_cast<T>(0); + } public: template <typename Src, NumericRepresentation type> friend class CheckedNumericState; - CheckedNumericState() : value_(0), validity_(RANGE_VALID) {} + constexpr CheckedNumericState() : is_valid_(true), value_(0) {} template <typename Src> - CheckedNumericState(Src value, RangeConstraint validity) - : value_(static_cast<T>(value)), - validity_(GetRangeConstraint(validity | - DstRangeRelationToSrcRange<T>(value))) { - static_assert(std::numeric_limits<Src>::is_specialized, - "Argument must be numeric."); + constexpr CheckedNumericState(Src value, bool is_valid) + : is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)), + value_(WellDefinedConversionOrZero(value, is_valid_)) { + static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric."); } // Copy constructor. template <typename Src> - CheckedNumericState(const CheckedNumericState<Src>& rhs) - : value_(static_cast<T>(rhs.value())), - validity_(GetRangeConstraint( - rhs.validity() | DstRangeRelationToSrcRange<T>(rhs.value()))) {} + constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs) + : is_valid_(rhs.IsValid()), + value_(WellDefinedConversionOrZero(rhs.value(), is_valid_)) {} template <typename Src> - explicit CheckedNumericState( - Src value, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) - : value_(static_cast<T>(value)), - validity_(DstRangeRelationToSrcRange<T>(value)) {} - - RangeConstraint validity() const { return validity_; } - T value() const { return value_; } + constexpr explicit CheckedNumericState(Src value) + : is_valid_(IsValueInRangeForNumericType<T>(value)), + value_(WellDefinedConversionOrZero(value, is_valid_)) {} + + constexpr bool is_valid() const { return is_valid_; } + constexpr T value() const { return value_; } }; // Floating points maintain their own validity, but need translation wrappers. @@ -445,94 +582,58 @@ class CheckedNumericState<T, NUMERIC_FLOATING> { private: T value_; + // Ensures that a type conversion does not trigger undefined behavior. + template <typename Src> + static constexpr T WellDefinedConversionOrNaN(const Src value, + const bool is_valid) { + using SrcType = typename internal::UnderlyingType<Src>::type; + return (StaticDstRangeRelationToSrcRange<T, SrcType>::value == + NUMERIC_RANGE_CONTAINED || + is_valid) + ? static_cast<T>(value) + : std::numeric_limits<T>::quiet_NaN(); + } + public: template <typename Src, NumericRepresentation type> friend class CheckedNumericState; - CheckedNumericState() : value_(0.0) {} + constexpr CheckedNumericState() : value_(0.0) {} template <typename Src> - CheckedNumericState( - Src value, - RangeConstraint validity, - typename std::enable_if<std::numeric_limits<Src>::is_integer, int>::type = - 0) { - switch (DstRangeRelationToSrcRange<T>(value)) { - case RANGE_VALID: - value_ = static_cast<T>(value); - break; - - case RANGE_UNDERFLOW: - value_ = -std::numeric_limits<T>::infinity(); - break; - - case RANGE_OVERFLOW: - value_ = std::numeric_limits<T>::infinity(); - break; - - case RANGE_INVALID: - value_ = std::numeric_limits<T>::quiet_NaN(); - break; - - default: - NOTREACHED(); - } - } + constexpr CheckedNumericState(Src value, bool is_valid) + : value_(WellDefinedConversionOrNaN(value, is_valid)) {} template <typename Src> - explicit CheckedNumericState( - Src value, - typename std::enable_if<std::numeric_limits<Src>::is_specialized, - int>::type = 0) - : value_(static_cast<T>(value)) {} + constexpr explicit CheckedNumericState(Src value) + : value_(WellDefinedConversionOrNaN( + value, + IsValueInRangeForNumericType<T>(value))) {} // Copy constructor. template <typename Src> - CheckedNumericState(const CheckedNumericState<Src>& rhs) - : value_(static_cast<T>(rhs.value())) {} - - RangeConstraint validity() const { - return GetRangeConstraint(value_ <= std::numeric_limits<T>::max(), - value_ >= -std::numeric_limits<T>::max()); + constexpr CheckedNumericState(const CheckedNumericState<Src>& rhs) + : value_(WellDefinedConversionOrNaN( + rhs.value(), + rhs.is_valid() && IsValueInRangeForNumericType<T>(rhs.value()))) {} + + constexpr bool is_valid() const { + // Written this way because std::isfinite is not reliably constexpr. + // TODO(jschuh): Fix this if the libraries ever get fixed. + return value_ <= std::numeric_limits<T>::max() && + value_ >= std::numeric_limits<T>::lowest(); } - T value() const { return value_; } -}; - -// For integers less than 128-bit and floats 32-bit or larger, we have the type -// with the larger maximum exponent take precedence. -enum ArithmeticPromotionCategory { LEFT_PROMOTION, RIGHT_PROMOTION }; - -template <typename Lhs, - typename Rhs = Lhs, - ArithmeticPromotionCategory Promotion = - (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) - ? LEFT_PROMOTION - : RIGHT_PROMOTION> -struct ArithmeticPromotion; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, LEFT_PROMOTION> { - typedef Lhs type; -}; - -template <typename Lhs, typename Rhs> -struct ArithmeticPromotion<Lhs, Rhs, RIGHT_PROMOTION> { - typedef Rhs type; + constexpr T value() const { return value_; } }; -// We can statically check if operations on the provided types can wrap, so we -// can skip the checked operations if they're not needed. So, for an integer we -// care if the destination type preserves the sign and is twice the width of -// the source. -template <typename T, typename Lhs, typename Rhs> -struct IsIntegerArithmeticSafe { - static const bool value = !std::numeric_limits<T>::is_iec559 && - StaticDstRangeRelationToSrcRange<T, Lhs>::value == - NUMERIC_RANGE_CONTAINED && - sizeof(T) >= (2 * sizeof(Lhs)) && - StaticDstRangeRelationToSrcRange<T, Rhs>::value != - NUMERIC_RANGE_CONTAINED && - sizeof(T) >= (2 * sizeof(Rhs)); +template <template <typename, typename, typename> class M, + typename L, + typename R> +struct MathWrapper { + using math = M<typename UnderlyingType<L>::type, + typename UnderlyingType<R>::type, + void>; + using type = typename math::result_type; }; } // namespace internal diff --git a/third_party/lcms2-2.6/0016-check-LUT-and-MPE.patch b/third_party/lcms2-2.6/0016-check-LUT-and-MPE.patch new file mode 100644 index 000000000..bfa84e2ee --- /dev/null +++ b/third_party/lcms2-2.6/0016-check-LUT-and-MPE.patch @@ -0,0 +1,170 @@ +diff --git a/third_party/lcms2-2.6/src/cmslut.c b/third_party/lcms2-2.6/src/cmslut.c +index 9b0eb4b54..19d43361f 100644 +--- a/third_party/lcms2-2.6/src/cmslut.c ++++ b/third_party/lcms2-2.6/src/cmslut.c +@@ -1255,21 +1255,39 @@ cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe) + // *********************************************************************************************************** + + // This function sets up the channel count +- + static +-void BlessLUT(cmsPipeline* lut) ++cmsBool BlessLUT(cmsPipeline* lut) + { + // We can set the input/ouput channels only if we have elements. + if (lut ->Elements != NULL) { + +- cmsStage *First, *Last; ++ cmsStage* prev; ++ cmsStage* next; ++ cmsStage* First; ++ cmsStage* Last; + + First = cmsPipelineGetPtrToFirstStage(lut); + Last = cmsPipelineGetPtrToLastStage(lut); + +- if (First != NULL)lut ->InputChannels = First ->InputChannels; +- if (Last != NULL) lut ->OutputChannels = Last ->OutputChannels; ++ if (First == NULL || Last == NULL) return FALSE; ++ ++ lut->InputChannels = First->InputChannels; ++ lut->OutputChannels = Last->OutputChannels; ++ ++ // Check chain consistency ++ prev = First; ++ next = prev->Next; ++ ++ while (next != NULL) ++ { ++ if (next->InputChannels != prev->OutputChannels) ++ return FALSE; ++ ++ next = next->Next; ++ prev = prev->Next; ++ } + } ++ return TRUE; + } + + +@@ -1331,6 +1349,7 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In + { + cmsPipeline* NewLUT; + ++ // A value of zero in channels is allowed as placeholder + if (InputChannels >= cmsMAXCHANNELS || + OutputChannels >= cmsMAXCHANNELS) return NULL; + +@@ -1348,7 +1367,11 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In + NewLUT ->Data = NewLUT; + NewLUT ->ContextID = ContextID; + +- BlessLUT(NewLUT); ++ if (!BlessLUT(NewLUT)) ++ { ++ _cmsFree(ContextID, NewLUT); ++ return NULL; ++ } + + return NewLUT; + } +@@ -1454,7 +1477,12 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut) + + NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits; + +- BlessLUT(NewLUT); ++ if (!BlessLUT(NewLUT)) ++ { ++ _cmsFree(lut->ContextID, NewLUT); ++ return NULL; ++ } ++ + return NewLUT; + } + +@@ -1491,8 +1519,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage + return FALSE; + } + +- BlessLUT(lut); +- return TRUE; ++ return BlessLUT(lut); + } + + // Unlink an element and return the pointer to it +@@ -1547,6 +1574,7 @@ void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag + else + cmsStageFree(Unlinked); + ++ // May fail, but we ignore it + BlessLUT(lut); + } + +@@ -1573,8 +1601,7 @@ cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2) + return FALSE; + } + +- BlessLUT(l1); +- return TRUE; ++ return BlessLUT(l1); + } + + +diff --git a/third_party/lcms2-2.6/src/cmstypes.c b/third_party/lcms2-2.6/src/cmstypes.c +index e5ed06c33..0256e247b 100644 +--- a/third_party/lcms2-2.6/src/cmstypes.c ++++ b/third_party/lcms2-2.6/src/cmstypes.c +@@ -1755,8 +1755,8 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms + if (!_cmsReadUInt8Number(io, NULL)) goto Error; + + // Do some checking +- if (InputChannels > cmsMAXCHANNELS) goto Error; +- if (OutputChannels > cmsMAXCHANNELS) goto Error; ++ if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; ++ if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; + + // Allocates an empty Pipeline + NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); +@@ -2048,8 +2048,8 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm + if (!_cmsReadUInt8Number(io, NULL)) return NULL; + + // Do some checking +- if (InputChannels > cmsMAXCHANNELS) goto Error; +- if (OutputChannels > cmsMAXCHANNELS) goto Error; ++ if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; ++ if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; + + // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); +@@ -2486,7 +2486,10 @@ void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c + if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; + if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; + +- // Allocates an empty LUT ++ if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; ++ if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; ++ ++ // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); + if (NewLUT == NULL) return NULL; + +@@ -2794,6 +2797,9 @@ void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c + if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; + if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; + ++ if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; ++ if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; ++ + // Padding + if (!_cmsReadUInt16Number(io, NULL)) return NULL; + +@@ -4443,6 +4449,9 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU + if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; + if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + ++ if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) return NULL; ++ if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) return NULL; ++ + // Allocates an empty LUT + NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans); + if (NewLUT == NULL) return NULL; diff --git a/third_party/lcms2-2.6/0017-upstream-integer-overflow-MPEmatrix_Read.patch b/third_party/lcms2-2.6/0017-upstream-integer-overflow-MPEmatrix_Read.patch new file mode 100644 index 000000000..47df7a887 --- /dev/null +++ b/third_party/lcms2-2.6/0017-upstream-integer-overflow-MPEmatrix_Read.patch @@ -0,0 +1,85 @@ +diff --git a/third_party/lcms2-2.6/src/cmscgats.c b/third_party/lcms2-2.6/src/cmscgats.c +index 5720c66a7..cce4cedba 100644 +--- a/third_party/lcms2-2.6/src/cmscgats.c ++++ b/third_party/lcms2-2.6/src/cmscgats.c +@@ -150,23 +150,24 @@ typedef struct { + SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast + + // Parser state machine +- SYMBOL sy; // Current symbol +- int ch; // Current character ++ SYMBOL sy; // Current symbol ++ int ch; // Current character ++ ++ cmsInt32Number inum; // integer value ++ cmsFloat64Number dnum; // real value + +- int inum; // integer value +- cmsFloat64Number dnum; // real value + char id[MAXID]; // identifier + char str[MAXSTR]; // string + + // Allowed keywords & datasets. They have visibility on whole stream +- KEYVALUE* ValidKeywords; +- KEYVALUE* ValidSampleID; ++ KEYVALUE* ValidKeywords; ++ KEYVALUE* ValidSampleID; + + char* Source; // Points to loc. being parsed +- int lineno; // line counter for error reporting ++ cmsInt32Number lineno; // line counter for error reporting + + FILECTX* FileStack[MAXINCLUDE]; // Stack of files being parsed +- int IncludeSP; // Include Stack Pointer ++ cmsInt32Number IncludeSP; // Include Stack Pointer + + char* MemoryBlock; // The stream if holded in memory + +@@ -568,8 +569,8 @@ void ReadReal(cmsIT8* it8, int inum) + // Exponent, example 34.00E+20 + if (toupper(it8->ch) == 'E') { + +- int e; +- int sgn; ++ cmsInt32Number e; ++ cmsInt32Number sgn; + + NextCh(it8); sgn = 1; + +@@ -587,7 +588,7 @@ void ReadReal(cmsIT8* it8, int inum) + e = 0; + while (isdigit(it8->ch)) { + +- if ((cmsFloat64Number) e * 10L < INT_MAX) ++ if ((cmsFloat64Number) e * 10L < (cmsFloat64Number) +2147483647.0) + e = e * 10 + (it8->ch - '0'); + + NextCh(it8); +@@ -777,7 +778,7 @@ void InSymbol(cmsIT8* it8) + + while (isdigit(it8->ch)) { + +- if ((long) it8->inum * 10L > (long) INT_MAX) { ++ if ((cmsFloat64Number) it8->inum * 10L > (cmsFloat64Number) +2147483647.0) { + ReadReal(it8, it8->inum); + it8->sy = SDNUM; + it8->dnum *= sign; +diff --git a/third_party/lcms2-2.6/src/cmstypes.c b/third_party/lcms2-2.6/src/cmstypes.c +index 0256e247b..75f1fae32 100644 +--- a/third_party/lcms2-2.6/src/cmstypes.c ++++ b/third_party/lcms2-2.6/src/cmstypes.c +@@ -4199,9 +4199,13 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io + if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + + ++ // Input and output chans may be ANY (up to 0xffff), ++ // but we choose to limit to 16 channels for now ++ if (InputChans >= cmsMAXCHANNELS) return NULL; ++ if (OutputChans >= cmsMAXCHANNELS) return NULL; ++ + nElems = InputChans * OutputChans; + +- // Input and output chans may be ANY (up to 0xffff) + Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number)); + if (Matrix == NULL) return NULL; + diff --git a/third_party/lcms2-2.6/README.pdfium b/third_party/lcms2-2.6/README.pdfium index c775609e0..650429826 100644 --- a/third_party/lcms2-2.6/README.pdfium +++ b/third_party/lcms2-2.6/README.pdfium @@ -27,4 +27,6 @@ Local Modifications: 0014-avoid-fixed-inf.patch: Avoid fixed number LUT optimization on inf values. 0015-sanitize-float-read.patch: Sanitize floating point read. Partially backport from upstream https://github.com/mm2/Little-CMS/commit/4011a6e3 +0016-check-LUT-and-MPE.patch: check LUT consistency and sanitize MPE profiles. +0017-upstream-integer-overflow-MPEmatrix_Read.patch: fix some integer overflows. TODO(ochang): List other patches. diff --git a/third_party/lcms2-2.6/src/cmscgats.c b/third_party/lcms2-2.6/src/cmscgats.c index 5720c66a7..cce4cedba 100644 --- a/third_party/lcms2-2.6/src/cmscgats.c +++ b/third_party/lcms2-2.6/src/cmscgats.c @@ -150,23 +150,24 @@ typedef struct { SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast // Parser state machine - SYMBOL sy; // Current symbol - int ch; // Current character + SYMBOL sy; // Current symbol + int ch; // Current character + + cmsInt32Number inum; // integer value + cmsFloat64Number dnum; // real value - int inum; // integer value - cmsFloat64Number dnum; // real value char id[MAXID]; // identifier char str[MAXSTR]; // string // Allowed keywords & datasets. They have visibility on whole stream - KEYVALUE* ValidKeywords; - KEYVALUE* ValidSampleID; + KEYVALUE* ValidKeywords; + KEYVALUE* ValidSampleID; char* Source; // Points to loc. being parsed - int lineno; // line counter for error reporting + cmsInt32Number lineno; // line counter for error reporting FILECTX* FileStack[MAXINCLUDE]; // Stack of files being parsed - int IncludeSP; // Include Stack Pointer + cmsInt32Number IncludeSP; // Include Stack Pointer char* MemoryBlock; // The stream if holded in memory @@ -568,8 +569,8 @@ void ReadReal(cmsIT8* it8, int inum) // Exponent, example 34.00E+20 if (toupper(it8->ch) == 'E') { - int e; - int sgn; + cmsInt32Number e; + cmsInt32Number sgn; NextCh(it8); sgn = 1; @@ -587,7 +588,7 @@ void ReadReal(cmsIT8* it8, int inum) e = 0; while (isdigit(it8->ch)) { - if ((cmsFloat64Number) e * 10L < INT_MAX) + if ((cmsFloat64Number) e * 10L < (cmsFloat64Number) +2147483647.0) e = e * 10 + (it8->ch - '0'); NextCh(it8); @@ -777,7 +778,7 @@ void InSymbol(cmsIT8* it8) while (isdigit(it8->ch)) { - if ((long) it8->inum * 10L > (long) INT_MAX) { + if ((cmsFloat64Number) it8->inum * 10L > (cmsFloat64Number) +2147483647.0) { ReadReal(it8, it8->inum); it8->sy = SDNUM; it8->dnum *= sign; diff --git a/third_party/lcms2-2.6/src/cmslut.c b/third_party/lcms2-2.6/src/cmslut.c index 9b0eb4b54..19d43361f 100644 --- a/third_party/lcms2-2.6/src/cmslut.c +++ b/third_party/lcms2-2.6/src/cmslut.c @@ -1255,21 +1255,39 @@ cmsStage* CMSEXPORT cmsStageDup(cmsStage* mpe) // *********************************************************************************************************** // This function sets up the channel count - static -void BlessLUT(cmsPipeline* lut) +cmsBool BlessLUT(cmsPipeline* lut) { // We can set the input/ouput channels only if we have elements. if (lut ->Elements != NULL) { - cmsStage *First, *Last; + cmsStage* prev; + cmsStage* next; + cmsStage* First; + cmsStage* Last; First = cmsPipelineGetPtrToFirstStage(lut); Last = cmsPipelineGetPtrToLastStage(lut); - if (First != NULL)lut ->InputChannels = First ->InputChannels; - if (Last != NULL) lut ->OutputChannels = Last ->OutputChannels; + if (First == NULL || Last == NULL) return FALSE; + + lut->InputChannels = First->InputChannels; + lut->OutputChannels = Last->OutputChannels; + + // Check chain consistency + prev = First; + next = prev->Next; + + while (next != NULL) + { + if (next->InputChannels != prev->OutputChannels) + return FALSE; + + next = next->Next; + prev = prev->Next; + } } + return TRUE; } @@ -1331,6 +1349,7 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In { cmsPipeline* NewLUT; + // A value of zero in channels is allowed as placeholder if (InputChannels >= cmsMAXCHANNELS || OutputChannels >= cmsMAXCHANNELS) return NULL; @@ -1348,7 +1367,11 @@ cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number In NewLUT ->Data = NewLUT; NewLUT ->ContextID = ContextID; - BlessLUT(NewLUT); + if (!BlessLUT(NewLUT)) + { + _cmsFree(ContextID, NewLUT); + return NULL; + } return NewLUT; } @@ -1454,7 +1477,12 @@ cmsPipeline* CMSEXPORT cmsPipelineDup(const cmsPipeline* lut) NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits; - BlessLUT(NewLUT); + if (!BlessLUT(NewLUT)) + { + _cmsFree(lut->ContextID, NewLUT); + return NULL; + } + return NewLUT; } @@ -1491,8 +1519,7 @@ int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage return FALSE; } - BlessLUT(lut); - return TRUE; + return BlessLUT(lut); } // Unlink an element and return the pointer to it @@ -1547,6 +1574,7 @@ void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStag else cmsStageFree(Unlinked); + // May fail, but we ignore it BlessLUT(lut); } @@ -1573,8 +1601,7 @@ cmsBool CMSEXPORT cmsPipelineCat(cmsPipeline* l1, const cmsPipeline* l2) return FALSE; } - BlessLUT(l1); - return TRUE; + return BlessLUT(l1); } diff --git a/third_party/lcms2-2.6/src/cmstypes.c b/third_party/lcms2-2.6/src/cmstypes.c index e5ed06c33..75f1fae32 100644 --- a/third_party/lcms2-2.6/src/cmstypes.c +++ b/third_party/lcms2-2.6/src/cmstypes.c @@ -1755,8 +1755,8 @@ void *Type_LUT8_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cms if (!_cmsReadUInt8Number(io, NULL)) goto Error; // Do some checking - if (InputChannels > cmsMAXCHANNELS) goto Error; - if (OutputChannels > cmsMAXCHANNELS) goto Error; + if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; + if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; // Allocates an empty Pipeline NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); @@ -2048,8 +2048,8 @@ void *Type_LUT16_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cm if (!_cmsReadUInt8Number(io, NULL)) return NULL; // Do some checking - if (InputChannels > cmsMAXCHANNELS) goto Error; - if (OutputChannels > cmsMAXCHANNELS) goto Error; + if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; + if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; // Allocates an empty LUT NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); @@ -2486,7 +2486,10 @@ void* Type_LUTA2B_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; - // Allocates an empty LUT + if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; + if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; + + // Allocates an empty LUT NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); if (NewLUT == NULL) return NULL; @@ -2794,6 +2797,9 @@ void* Type_LUTB2A_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, c if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; + if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; + if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; + // Padding if (!_cmsReadUInt16Number(io, NULL)) return NULL; @@ -4193,9 +4199,13 @@ void *Type_MPEmatrix_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + // Input and output chans may be ANY (up to 0xffff), + // but we choose to limit to 16 channels for now + if (InputChans >= cmsMAXCHANNELS) return NULL; + if (OutputChans >= cmsMAXCHANNELS) return NULL; + nElems = InputChans * OutputChans; - // Input and output chans may be ANY (up to 0xffff) Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number)); if (Matrix == NULL) return NULL; @@ -4443,6 +4453,9 @@ void *Type_MPE_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsU if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) return NULL; + if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) return NULL; + // Allocates an empty LUT NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans); if (NewLUT == NULL) return NULL; diff --git a/third_party/libopenjpeg20/0025-opj_j2k_add_mct_null_data.patch b/third_party/libopenjpeg20/0025-opj_j2k_add_mct_null_data.patch new file mode 100644 index 000000000..4a371e5c8 --- /dev/null +++ b/third_party/libopenjpeg20/0025-opj_j2k_add_mct_null_data.patch @@ -0,0 +1,22 @@ +diff --git a/third_party/libopenjpeg20/j2k.c b/third_party/libopenjpeg20/j2k.c +index 5de89cf0e..400ca8098 100644 +--- a/third_party/libopenjpeg20/j2k.c ++++ b/third_party/libopenjpeg20/j2k.c +@@ -5715,7 +5715,7 @@ static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UI + + if (l_deco_array) { + l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps * p_image->numcomps; +- if (l_deco_array->m_data_size != l_data_size) { ++ if (l_deco_array->m_data_size != l_data_size || ! l_deco_array->m_data) { + return OPJ_FALSE; + } + +@@ -5734,7 +5734,7 @@ static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UI + + if (l_offset_array) { + l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * p_image->numcomps; +- if (l_offset_array->m_data_size != l_data_size) { ++ if (l_offset_array->m_data_size != l_data_size || ! l_offset_array->m_data) { + return OPJ_FALSE; + } + diff --git a/third_party/libopenjpeg20/0026-use_opj_uint_ceildiv.patch b/third_party/libopenjpeg20/0026-use_opj_uint_ceildiv.patch new file mode 100644 index 000000000..a196a4434 --- /dev/null +++ b/third_party/libopenjpeg20/0026-use_opj_uint_ceildiv.patch @@ -0,0 +1,70 @@ +diff --git a/third_party/libopenjpeg20/j2k.c b/third_party/libopenjpeg20/j2k.c +index 400ca8098..e77edd22b 100644 +--- a/third_party/libopenjpeg20/j2k.c ++++ b/third_party/libopenjpeg20/j2k.c +@@ -2155,8 +2155,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, + } + + /* Compute the number of tiles */ +- l_cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->x1 - l_cp->tx0), (OPJ_INT32)l_cp->tdx); +- l_cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->y1 - l_cp->ty0), (OPJ_INT32)l_cp->tdy); ++ l_cp->tw = opj_uint_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx); ++ l_cp->th = opj_uint_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy); + + /* Check that the number of tiles is valid */ + if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) { +@@ -2171,8 +2171,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, + if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) { + p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx; + p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy; +- p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), (OPJ_INT32)l_cp->tdx); +- p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), (OPJ_INT32)l_cp->tdy); ++ p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_uint_ceildiv(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0, l_cp->tdx); ++ p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_uint_ceildiv(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0, l_cp->tdy); + } + else { + p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; +@@ -6354,8 +6354,8 @@ OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k, + */ + + if (parameters->tile_size_on) { +- cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->x1 - cp->tx0), (OPJ_INT32)cp->tdx); +- cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->y1 - cp->ty0), (OPJ_INT32)cp->tdy); ++ cp->tw = opj_uint_ceildiv(image->x1 - cp->tx0, cp->tdx); ++ cp->th = opj_uint_ceildiv(image->y1 - cp->ty0, cp->tdy); + } else { + cp->tdx = image->x1 - cp->tx0; + cp->tdy = image->y1 - cp->ty0; +@@ -8529,8 +8529,8 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, + { + OPJ_INT32 l_h,l_w; + +- l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx); +- l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy); ++ l_img_comp->x0 = opj_uint_ceildiv(p_image->x0, l_img_comp->dx); ++ l_img_comp->y0 = opj_uint_ceildiv(p_image->y0, l_img_comp->dy); + l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); + l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); + +@@ -9887,8 +9887,8 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k, + + l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor; + +- l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx); +- l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy); ++ l_img_comp->x0 = opj_uint_ceildiv(p_image->x0, l_img_comp->dx); ++ l_img_comp->y0 = opj_uint_ceildiv(p_image->y0, l_img_comp->dy); + l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); + l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); + +@@ -10169,8 +10169,8 @@ static void opj_get_tile_dimensions(opj_image_t * l_image, + + *l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); + *l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); +- *l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); +- *l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); ++ *l_offset_x = opj_uint_ceildiv(l_image->x0, l_img_comp->dx); ++ *l_offset_y = opj_uint_ceildiv(l_image->y0, l_img_comp->dy); + *l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); + *l_stride = *l_image_width - *l_width; + *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width; diff --git a/third_party/libopenjpeg20/0027-undefined-shift-opj_t1_decode_cblk.patch b/third_party/libopenjpeg20/0027-undefined-shift-opj_t1_decode_cblk.patch new file mode 100644 index 000000000..7ba877ab9 --- /dev/null +++ b/third_party/libopenjpeg20/0027-undefined-shift-opj_t1_decode_cblk.patch @@ -0,0 +1,13 @@ +diff --git a/third_party/libopenjpeg20/t1.c b/third_party/libopenjpeg20/t1.c +index a119db1f7..1ad850c77 100644 +--- a/third_party/libopenjpeg20/t1.c ++++ b/third_party/libopenjpeg20/t1.c +@@ -1411,7 +1411,7 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1, + } + } + +- for (passno = 0; passno < seg->real_num_passes; ++passno) { ++ for (passno = 0; (passno < seg->real_num_passes) && (bpno_plus_one >= 1); ++passno) { + switch (passtype) { + case 0: + if (type == T1_TYPE_RAW) { diff --git a/third_party/libopenjpeg20/0028-upstream-check-size-in-opj_j2k_read_siz.patch b/third_party/libopenjpeg20/0028-upstream-check-size-in-opj_j2k_read_siz.patch new file mode 100644 index 000000000..22d5562a7 --- /dev/null +++ b/third_party/libopenjpeg20/0028-upstream-check-size-in-opj_j2k_read_siz.patch @@ -0,0 +1,22 @@ +diff --git a/third_party/libopenjpeg20/j2k.c b/third_party/libopenjpeg20/j2k.c +index e77edd22b..cb5a28373 100644 +--- a/third_party/libopenjpeg20/j2k.c ++++ b/third_party/libopenjpeg20/j2k.c +@@ -2117,10 +2117,16 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, + if( l_img_comp->dx < 1 || l_img_comp->dx > 255 || + l_img_comp->dy < 1 || l_img_comp->dy > 255 ) { + opj_event_msg(p_manager, EVT_ERROR, +- "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)", ++ "Invalid values for comp = %d : dx=%u dy=%u (should be between 1 and 255 according to the JPEG2000 norm)\n", + i, l_img_comp->dx, l_img_comp->dy); + return OPJ_FALSE; + } ++ if( l_img_comp->prec > 38) { /* TODO openjpeg won't handle more than ? */ ++ opj_event_msg(p_manager, EVT_ERROR, ++ "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm)\n", ++ i, l_img_comp->prec); ++ return OPJ_FALSE; ++ } + + #ifdef USE_JPWL + if (l_cp->correct) { diff --git a/third_party/libopenjpeg20/README.pdfium b/third_party/libopenjpeg20/README.pdfium index 0f453373f..6c2a3c74b 100644 --- a/third_party/libopenjpeg20/README.pdfium +++ b/third_party/libopenjpeg20/README.pdfium @@ -34,4 +34,8 @@ Local Modifications: 0022-jp2_apply_pclr_overflow.patch: Prevent integer overflow in opj_jp2_apply_pclr. 0023-opj_j2k_read_mct_records.patch: Fix opj_j2k_read to prevent heap-use-after-free. 0024-l_marker_size_check.patch: Return error before overflow in opj_j2k_read_header_procedure. +0025-opj_j2k_add_mct_null_data.patch: Check m_data != null before trying to read from it. +0026-use_opj_uint_ceildiv.patch: Remove (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)a, (OPJ_INT32) b). +0027-undefined-shift-opj_t1_decode_cblk.patch: upstream fix for a ubsan bug. +0028-upstream-check-size-in-opj_j2k_read_siz.patch: upstream patch in j2k.c. TODO(thestig): List all the other patches. diff --git a/third_party/libopenjpeg20/j2k.c b/third_party/libopenjpeg20/j2k.c index 5de89cf0e..cb5a28373 100644 --- a/third_party/libopenjpeg20/j2k.c +++ b/third_party/libopenjpeg20/j2k.c @@ -2117,10 +2117,16 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, if( l_img_comp->dx < 1 || l_img_comp->dx > 255 || l_img_comp->dy < 1 || l_img_comp->dy > 255 ) { opj_event_msg(p_manager, EVT_ERROR, - "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)", + "Invalid values for comp = %d : dx=%u dy=%u (should be between 1 and 255 according to the JPEG2000 norm)\n", i, l_img_comp->dx, l_img_comp->dy); return OPJ_FALSE; } + if( l_img_comp->prec > 38) { /* TODO openjpeg won't handle more than ? */ + opj_event_msg(p_manager, EVT_ERROR, + "Invalid values for comp = %d : prec=%u (should be between 1 and 38 according to the JPEG2000 norm)\n", + i, l_img_comp->prec); + return OPJ_FALSE; + } #ifdef USE_JPWL if (l_cp->correct) { @@ -2155,8 +2161,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, } /* Compute the number of tiles */ - l_cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->x1 - l_cp->tx0), (OPJ_INT32)l_cp->tdx); - l_cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->y1 - l_cp->ty0), (OPJ_INT32)l_cp->tdy); + l_cp->tw = opj_uint_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx); + l_cp->th = opj_uint_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy); /* Check that the number of tiles is valid */ if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) { @@ -2171,8 +2177,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) { p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx; p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy; - p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), (OPJ_INT32)l_cp->tdx); - p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), (OPJ_INT32)l_cp->tdy); + p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_uint_ceildiv(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0, l_cp->tdx); + p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_uint_ceildiv(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0, l_cp->tdy); } else { p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; @@ -5715,7 +5721,7 @@ static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UI if (l_deco_array) { l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps * p_image->numcomps; - if (l_deco_array->m_data_size != l_data_size) { + if (l_deco_array->m_data_size != l_data_size || ! l_deco_array->m_data) { return OPJ_FALSE; } @@ -5734,7 +5740,7 @@ static OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UI if (l_offset_array) { l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * p_image->numcomps; - if (l_offset_array->m_data_size != l_data_size) { + if (l_offset_array->m_data_size != l_data_size || ! l_offset_array->m_data) { return OPJ_FALSE; } @@ -6354,8 +6360,8 @@ OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k, */ if (parameters->tile_size_on) { - cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->x1 - cp->tx0), (OPJ_INT32)cp->tdx); - cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->y1 - cp->ty0), (OPJ_INT32)cp->tdy); + cp->tw = opj_uint_ceildiv(image->x1 - cp->tx0, cp->tdx); + cp->th = opj_uint_ceildiv(image->y1 - cp->ty0, cp->tdy); } else { cp->tdx = image->x1 - cp->tx0; cp->tdy = image->y1 - cp->ty0; @@ -8529,8 +8535,8 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, { OPJ_INT32 l_h,l_w; - l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx); - l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy); + l_img_comp->x0 = opj_uint_ceildiv(p_image->x0, l_img_comp->dx); + l_img_comp->y0 = opj_uint_ceildiv(p_image->y0, l_img_comp->dy); l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); @@ -9887,8 +9893,8 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k, l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor; - l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx); - l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy); + l_img_comp->x0 = opj_uint_ceildiv(p_image->x0, l_img_comp->dx); + l_img_comp->y0 = opj_uint_ceildiv(p_image->y0, l_img_comp->dy); l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); @@ -10169,8 +10175,8 @@ static void opj_get_tile_dimensions(opj_image_t * l_image, *l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); *l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); - *l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); - *l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); + *l_offset_x = opj_uint_ceildiv(l_image->x0, l_img_comp->dx); + *l_offset_y = opj_uint_ceildiv(l_image->y0, l_img_comp->dy); *l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); *l_stride = *l_image_width - *l_width; *l_tile_offset = ((OPJ_UINT32)l_tilec->x0 - *l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - *l_offset_y) * *l_image_width; diff --git a/third_party/libopenjpeg20/t1.c b/third_party/libopenjpeg20/t1.c index a119db1f7..1ad850c77 100644 --- a/third_party/libopenjpeg20/t1.c +++ b/third_party/libopenjpeg20/t1.c @@ -1411,7 +1411,7 @@ static OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1, } } - for (passno = 0; passno < seg->real_num_passes; ++passno) { + for (passno = 0; (passno < seg->real_num_passes) && (bpno_plus_one >= 1); ++passno) { switch (passtype) { case 0: if (type == T1_TYPE_RAW) { diff --git a/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch b/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch new file mode 100644 index 000000000..10c507739 --- /dev/null +++ b/third_party/libtiff/0017-safe_skews_in_gtTileContig.patch @@ -0,0 +1,88 @@ +diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c +index 2861cdd1e..5ed1b7a37 100644 +--- a/third_party/libtiff/tif_getimage.c ++++ b/third_party/libtiff/tif_getimage.c +@@ -31,6 +31,7 @@ + */ + #include "tiffiop.h" + #include <stdio.h> ++#include <limits.h> + + static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); + static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); +@@ -612,6 +613,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) + uint32 tw, th; + unsigned char* buf; + int32 fromskew, toskew; ++ int64 safeskew; + uint32 nrow; + int ret = 1, flip; + uint32 this_tw, tocol; +@@ -631,19 +633,37 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) + flip = setorientation(img); + if (flip & FLIP_VERTICALLY) { + y = h - 1; +- toskew = -(int32)(tw + w); ++ safeskew = 0; ++ safeskew -= tw; ++ safeskew -= w; + } + else { + y = 0; +- toskew = -(int32)(tw - w); ++ safeskew = 0; ++ safeskew -= tw; ++ safeskew +=w; + } ++ if(safeskew > INT_MAX || safeskew < INT_MIN){ ++ _TIFFfree(buf); ++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); ++ return (0); ++ } ++ toskew = safeskew; ++ + + /* + * Leftmost tile is clipped on left side if col_offset > 0. + */ + leftmost_fromskew = img->col_offset % tw; + leftmost_tw = tw - leftmost_fromskew; +- leftmost_toskew = toskew + leftmost_fromskew; ++ safeskew = toskew; ++ safeskew += leftmost_fromskew; ++ if(safeskew > INT_MAX || safeskew < INT_MIN){ ++ _TIFFfree(buf); ++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); ++ return (0); ++ } ++ leftmost_toskew = safeskew; + for (row = 0; row < h; row += nrow) + { + rowstoread = th - (row + img->row_offset) % th; +@@ -668,9 +688,24 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) + /* + * Rightmost tile is clipped on right side. + */ +- fromskew = tw - (w - tocol); ++ safeskew = tw; ++ safeskew -= w; ++ safeskew += tocol; ++ if(safeskew > INT_MAX || safeskew < INT_MIN){ ++ _TIFFfree(buf); ++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); ++ return (0); ++ } ++ fromskew = safeskew; + this_tw = tw - fromskew; +- this_toskew = toskew + fromskew; ++ safeskew = toskew; ++ safeskew += fromskew; ++ if(safeskew > INT_MAX || safeskew < INT_MIN){ ++ _TIFFfree(buf); ++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); ++ return (0); ++ } ++ this_toskew = safeskew; + } + (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos); + tocol += this_tw; diff --git a/third_party/libtiff/0018-fix-leak-in-PredictorSetupDecode.patch b/third_party/libtiff/0018-fix-leak-in-PredictorSetupDecode.patch new file mode 100644 index 000000000..a18df7740 --- /dev/null +++ b/third_party/libtiff/0018-fix-leak-in-PredictorSetupDecode.patch @@ -0,0 +1,39 @@ +diff --git a/third_party/libtiff/tif_pixarlog.c b/third_party/libtiff/tif_pixarlog.c +index 80006d5b1..29535d31e 100644 +--- a/third_party/libtiff/tif_pixarlog.c ++++ b/third_party/libtiff/tif_pixarlog.c +@@ -697,9 +697,6 @@ PixarLogSetupDecode(TIFF* tif) + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) + sp->user_datafmt = PixarLogGuessDataFmt(td); + if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { +- _TIFFfree(sp->tbuf); +- sp->tbuf = NULL; +- sp->tbuf_size = 0; + TIFFErrorExt(tif->tif_clientdata, module, + "PixarLog compression can't handle bits depth/data format combination (depth: %d)", + td->td_bitspersample); +@@ -707,9 +704,6 @@ PixarLogSetupDecode(TIFF* tif) + } + + if (inflateInit(&sp->stream) != Z_OK) { +- _TIFFfree(sp->tbuf); +- sp->tbuf = NULL; +- sp->tbuf_size = 0; + TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); + return (0); + } else { +diff --git a/third_party/libtiff/tif_predict.c b/third_party/libtiff/tif_predict.c +index 1388dde59..8975672ae 100644 +--- a/third_party/libtiff/tif_predict.c ++++ b/third_party/libtiff/tif_predict.c +@@ -109,7 +109,10 @@ PredictorSetupDecode(TIFF* tif) + TIFFDirectory* td = &tif->tif_dir; + + if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) ++ { ++ (*tif->tif_cleanup)(tif); + return 0; ++ } + + if (sp->predictor == 2) { + switch (td->td_bitspersample) { diff --git a/third_party/libtiff/0019-fix-invalid-reads-TIFFFetchNormalTag.patch b/third_party/libtiff/0019-fix-invalid-reads-TIFFFetchNormalTag.patch new file mode 100644 index 000000000..9ebb7ef8d --- /dev/null +++ b/third_party/libtiff/0019-fix-invalid-reads-TIFFFetchNormalTag.patch @@ -0,0 +1,28 @@ +diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c +index bc4102184..0e3f8ccd4 100644 +--- a/third_party/libtiff/tif_dirread.c ++++ b/third_party/libtiff/tif_dirread.c +@@ -4983,6 +4983,11 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) + if (err==TIFFReadDirEntryErrOk) + { + int m; ++ if( dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) ++ { ++ TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); ++ data[dp->tdir_count-1] = '\0'; ++ } + m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); +@@ -5155,6 +5160,11 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) + if (err==TIFFReadDirEntryErrOk) + { + int m; ++ if( dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) ++ { ++ TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); ++ data[dp->tdir_count-1] = '\0'; ++ } + m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); + if (data!=0) + _TIFFfree(data); diff --git a/third_party/libtiff/0020-unreasonable-td-bitspersample.patch b/third_party/libtiff/0020-unreasonable-td-bitspersample.patch new file mode 100644 index 000000000..1ad5e34e3 --- /dev/null +++ b/third_party/libtiff/0020-unreasonable-td-bitspersample.patch @@ -0,0 +1,22 @@ +diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c +index 0e3f8ccd4..e0403aef3 100644 +--- a/third_party/libtiff/tif_dirread.c ++++ b/third_party/libtiff/tif_dirread.c +@@ -3754,6 +3754,17 @@ TIFFReadDirectory(TIFF* tif) + fip ? fip->field_name : "unknown tagname"); + continue; + } ++ /* ColorMap or TransferFunction for high bit */ ++ /* depths do not make much sense and could be */ ++ /* used as a denial of service vector */ ++ if (tif->tif_dir.td_bitspersample > 24) ++ { ++ TIFFWarningExt(tif->tif_clientdata,module, ++ "Ignoring %s because BitsPerSample=%d>24", ++ fip ? fip->field_name : "unknown tagname", ++ tif->tif_dir.td_bitspersample); ++ continue; ++ } + countpersample=(1L<<tif->tif_dir.td_bitspersample); + if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) + { diff --git a/third_party/libtiff/0021-fix-leaks-ojpegreaderinfosectables.patch b/third_party/libtiff/0021-fix-leaks-ojpegreaderinfosectables.patch new file mode 100644 index 000000000..e3b4bd896 --- /dev/null +++ b/third_party/libtiff/0021-fix-leaks-ojpegreaderinfosectables.patch @@ -0,0 +1,31 @@ +diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c +index f69b00148..276d562df 100644 +--- a/third_party/libtiff/tif_ojpeg.c ++++ b/third_party/libtiff/tif_ojpeg.c +@@ -1794,6 +1794,8 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) + _TIFFfree(ob); + return(0); + } ++ if (sp->qtable[m]!=0) ++ _TIFFfree(sp->qtable[m]); + sp->qtable[m]=ob; + sp->sof_tq[m]=m; + } +@@ -1861,6 +1863,8 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) + _TIFFfree(rb); + return(0); + } ++ if (sp->dctable[m]!=0) ++ _TIFFfree(sp->dctable[m]); + sp->dctable[m]=rb; + sp->sos_tda[m]=(m<<4); + } +@@ -1928,6 +1932,8 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) + _TIFFfree(rb); + return(0); + } ++ if (sp->actable[m]) ++ _TIFFfree(sp->actable[m]); + sp->actable[m]=rb; + sp->sos_tda[m]=(sp->sos_tda[m]|m); + } diff --git a/third_party/libtiff/README.pdfium b/third_party/libtiff/README.pdfium index 23c8450ef..e4436d21f 100644 --- a/third_party/libtiff/README.pdfium +++ b/third_party/libtiff/README.pdfium @@ -26,3 +26,8 @@ Local Modifications: 0014-cast-to-unsigned-in-putagreytile.patch: casting to avoid undefined shifts. 0015-fix-leaks-in-tif_ojpeg.patch: fix direct leaks in tif_ojpeg.c methods 0016-fix-leak-in-pixarlogsetupdecode.patch: Free sp->tbuf if setup fails +0017-safe_skews_in_gtTileContig.patch: return error if to/from skews overflow from int32. +0018-fix-leak-in-PredictorSetupDecode.patch: call tif->tif_cleanup if the setup fails. +0019-fix-invalid-reads-TIFFFetchNormalTag.patch: upstream security fix in tif_dirread. +0020-unreasonable-td-bitspersample.patch: upstream patch ignoring large td_bitspersample. +0021-fix-leaks-ojpegreaderinfosectables.patch: more direct leak fixes in tif_ojpeg.c. diff --git a/third_party/libtiff/tif_dirread.c b/third_party/libtiff/tif_dirread.c index bc4102184..e0403aef3 100644 --- a/third_party/libtiff/tif_dirread.c +++ b/third_party/libtiff/tif_dirread.c @@ -3754,6 +3754,17 @@ TIFFReadDirectory(TIFF* tif) fip ? fip->field_name : "unknown tagname"); continue; } + /* ColorMap or TransferFunction for high bit */ + /* depths do not make much sense and could be */ + /* used as a denial of service vector */ + if (tif->tif_dir.td_bitspersample > 24) + { + TIFFWarningExt(tif->tif_clientdata,module, + "Ignoring %s because BitsPerSample=%d>24", + fip ? fip->field_name : "unknown tagname", + tif->tif_dir.td_bitspersample); + continue; + } countpersample=(1L<<tif->tif_dir.td_bitspersample); if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample)) { @@ -4983,6 +4994,11 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) if (err==TIFFReadDirEntryErrOk) { int m; + if( dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) + { + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); + data[dp->tdir_count-1] = '\0'; + } m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data); if (data!=0) _TIFFfree(data); @@ -5155,6 +5171,11 @@ TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover) if (err==TIFFReadDirEntryErrOk) { int m; + if( dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' ) + { + TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name); + data[dp->tdir_count-1] = '\0'; + } m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data); if (data!=0) _TIFFfree(data); diff --git a/third_party/libtiff/tif_getimage.c b/third_party/libtiff/tif_getimage.c index 2861cdd1e..5ed1b7a37 100644 --- a/third_party/libtiff/tif_getimage.c +++ b/third_party/libtiff/tif_getimage.c @@ -31,6 +31,7 @@ */ #include "tiffiop.h" #include <stdio.h> +#include <limits.h> static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32); static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32); @@ -612,6 +613,7 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) uint32 tw, th; unsigned char* buf; int32 fromskew, toskew; + int64 safeskew; uint32 nrow; int ret = 1, flip; uint32 this_tw, tocol; @@ -631,19 +633,37 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) flip = setorientation(img); if (flip & FLIP_VERTICALLY) { y = h - 1; - toskew = -(int32)(tw + w); + safeskew = 0; + safeskew -= tw; + safeskew -= w; } else { y = 0; - toskew = -(int32)(tw - w); + safeskew = 0; + safeskew -= tw; + safeskew +=w; } + if(safeskew > INT_MAX || safeskew < INT_MIN){ + _TIFFfree(buf); + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); + return (0); + } + toskew = safeskew; + /* * Leftmost tile is clipped on left side if col_offset > 0. */ leftmost_fromskew = img->col_offset % tw; leftmost_tw = tw - leftmost_fromskew; - leftmost_toskew = toskew + leftmost_fromskew; + safeskew = toskew; + safeskew += leftmost_fromskew; + if(safeskew > INT_MAX || safeskew < INT_MIN){ + _TIFFfree(buf); + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); + return (0); + } + leftmost_toskew = safeskew; for (row = 0; row < h; row += nrow) { rowstoread = th - (row + img->row_offset) % th; @@ -668,9 +688,24 @@ gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) /* * Rightmost tile is clipped on right side. */ - fromskew = tw - (w - tocol); + safeskew = tw; + safeskew -= w; + safeskew += tocol; + if(safeskew > INT_MAX || safeskew < INT_MIN){ + _TIFFfree(buf); + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); + return (0); + } + fromskew = safeskew; this_tw = tw - fromskew; - this_toskew = toskew + fromskew; + safeskew = toskew; + safeskew += fromskew; + if(safeskew > INT_MAX || safeskew < INT_MIN){ + _TIFFfree(buf); + TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "Invalid skew"); + return (0); + } + this_toskew = safeskew; } (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos); tocol += this_tw; diff --git a/third_party/libtiff/tif_ojpeg.c b/third_party/libtiff/tif_ojpeg.c index f69b00148..276d562df 100644 --- a/third_party/libtiff/tif_ojpeg.c +++ b/third_party/libtiff/tif_ojpeg.c @@ -1794,6 +1794,8 @@ OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif) _TIFFfree(ob); return(0); } + if (sp->qtable[m]!=0) + _TIFFfree(sp->qtable[m]); sp->qtable[m]=ob; sp->sof_tq[m]=m; } @@ -1861,6 +1863,8 @@ OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif) _TIFFfree(rb); return(0); } + if (sp->dctable[m]!=0) + _TIFFfree(sp->dctable[m]); sp->dctable[m]=rb; sp->sos_tda[m]=(m<<4); } @@ -1928,6 +1932,8 @@ OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif) _TIFFfree(rb); return(0); } + if (sp->actable[m]) + _TIFFfree(sp->actable[m]); sp->actable[m]=rb; sp->sos_tda[m]=(sp->sos_tda[m]|m); } diff --git a/third_party/libtiff/tif_pixarlog.c b/third_party/libtiff/tif_pixarlog.c index 80006d5b1..29535d31e 100644 --- a/third_party/libtiff/tif_pixarlog.c +++ b/third_party/libtiff/tif_pixarlog.c @@ -697,9 +697,6 @@ PixarLogSetupDecode(TIFF* tif) if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) sp->user_datafmt = PixarLogGuessDataFmt(td); if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) { - _TIFFfree(sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle bits depth/data format combination (depth: %d)", td->td_bitspersample); @@ -707,9 +704,6 @@ PixarLogSetupDecode(TIFF* tif) } if (inflateInit(&sp->stream) != Z_OK) { - _TIFFfree(sp->tbuf); - sp->tbuf = NULL; - sp->tbuf_size = 0; TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg); return (0); } else { diff --git a/third_party/libtiff/tif_predict.c b/third_party/libtiff/tif_predict.c index 1388dde59..8975672ae 100644 --- a/third_party/libtiff/tif_predict.c +++ b/third_party/libtiff/tif_predict.c @@ -109,7 +109,10 @@ PredictorSetupDecode(TIFF* tif) TIFFDirectory* td = &tif->tif_dir; if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif)) + { + (*tif->tif_cleanup)(tif); return 0; + } if (sp->predictor == 2) { switch (td->td_bitspersample) { diff --git a/tools/drmemory/DrMemory-Windows-sfx.exe b/tools/drmemory/DrMemory-Windows-sfx.exe Binary files differdeleted file mode 100644 index cd3992b84..000000000 --- a/tools/drmemory/DrMemory-Windows-sfx.exe +++ /dev/null diff --git a/tools/drmemory/README b/tools/drmemory/README deleted file mode 100644 index 1db5410e4..000000000 --- a/tools/drmemory/README +++ /dev/null @@ -1,86 +0,0 @@ - -# Dr. Memory - -Dr. Memory (www.drmemory.org) is an open-source dynamic memory -monitoring tool for Windows, Linux, and Mac. - -## About Dr. Memory - -Dr. Memory operates on unmodified application binaries running on -Windows, Linux, or Mac on commodity x86 and ARM32 (forthcoming) hardware. -It is capable of identifying memory-related programming errors including: - * accesses of uninitialized memory - * accesses to unaddressable memory (heap underflow and overflow) - * accesses to freed memory - * double frees - * memory leaks - * handle leaks (on Windows) - * GDI API usage errors (on Windows) - * accesses to un-reserved thread local storage slots (on Windows) - -## Using Dr. Memory (Windows only) - -Build your application with debug information and then run it under -Dr. Memory. Errors found are printed to the screen, and a summary is -shown at the end of the run. - -### Obtain Dr. Memory - -The Dr. Memory package is provided as a self-extracting archive -(DrMemory-Windows-sfx.exe) in tools/drmemory directory, which can be -extracted by running command 'DrMemory-Windows-sfx.exe -ounpacked -y'. - -The Dr. Memory release package can be downloaded from -https://github.com/DynamoRIO/drmemory/wiki/Downloads. - -Nightly builds can be downloaded from -https://build.chromium.org/p/client.drmemory/builds/. - -The Dr. Memory source code can be found at -https://github.com/DynamoRIO/drmemory. - -### Run your application with Dr. Memory - -To run your application with Dr. Memory, simply put 'drmemory.exe --' -before the command that invokes the application. - - * Running pdfium_unittests with Dr. Memory: - tools\drmemory\unpaced\bin\drmemory.exe -- out\Debug\pdfium_unittests.exe - - * Running pdfium_tests with Dr. Memory: - tools\drmemory\unpaced\bin\drmemory.exe -- out\Debug\pdfium_tests.exe --png YourInputPDF.pdf - -### Run test suite with Dr. Memory - -A set of scripts are provided to run PDFium test suite with Dr. Memory -on buildbots, which can also be used for running test suite locally. - - * Running pdfium_unittests with Dr. Memory: - tools\drmemory\scripts\pdfium_tests.bat -t pdfium_unittests - - * Running pixel test suite with Dr. Memory: - tools\drmemory\scripts\pdfium_tests.bat -t pdfium_pixel - -## Documentation - -Command 'drmemory.exe -help' prints a list of Dr. Memory runtime -options with short description. - -To view the full documention, point your web browser at -http://drmemory.org/docs/. - - -## Contact - -This project is provided as-is, with no official support. -Use the Dr. Memory Users group at -http://groups.google.com/group/drmemory-users/ to ask questions and -seek help on using Dr. Memory. - -Dr. Memory's source code and issue tracker live at -https://github.com/DynamoRIO/drmemory - -If you would like to submit a patch, you will need to first sign a -Contributor License Agreement. -See https://github.com/DynamoRIO/drmemory/wiki/Contributing for more -information. diff --git a/tools/drmemory/scripts/common.py b/tools/drmemory/scripts/common.py deleted file mode 100644 index 7e163e3c6..000000000 --- a/tools/drmemory/scripts/common.py +++ /dev/null @@ -1,252 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import logging -import platform -import os -import signal -import subprocess -import sys -import time - - -class NotImplementedError(Exception): - pass - - -class TimeoutError(Exception): - pass - - -def RunSubprocessInBackground(proc): - """Runs a subprocess in the background. Returns a handle to the process.""" - logging.info("running %s in the background" % " ".join(proc)) - return subprocess.Popen(proc) - - -def RunSubprocess(proc, timeout=0): - """ Runs a subprocess, until it finishes or |timeout| is exceeded and the - process is killed with taskkill. A |timeout| <= 0 means no timeout. - - Args: - proc: list of process components (exe + args) - timeout: how long to wait before killing, <= 0 means wait forever - """ - - logging.info("running %s, timeout %d sec" % (" ".join(proc), timeout)) - sys.stdout.flush() - sys.stderr.flush() - - # Manually read and print out stdout and stderr. - # By default, the subprocess is supposed to inherit these from its parent, - # however when run under buildbot, it seems unable to read data from a - # grandchild process, so we have to read the child and print the data as if - # it came from us for buildbot to read it. We're not sure why this is - # necessary. - # TODO(erikkay): should we buffer stderr and stdout separately? - p = subprocess.Popen(proc, universal_newlines=True, - bufsize=0, # unbuffered - stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - - logging.info("started subprocess") - - did_timeout = False - if timeout > 0: - wait_until = time.time() + timeout - while p.poll() is None and not did_timeout: - # Have to use readline rather than readlines() or "for line in p.stdout:", - # otherwise we get buffered even with bufsize=0. - line = p.stdout.readline() - while line and not did_timeout: - sys.stdout.write(line) - sys.stdout.flush() - line = p.stdout.readline() - if timeout > 0: - did_timeout = time.time() > wait_until - - if did_timeout: - logging.info("process timed out") - else: - logging.info("process ended, did not time out") - - if did_timeout: - if IsWindows(): - subprocess.call(["taskkill", "/T", "/F", "/PID", str(p.pid)]) - else: - # Does this kill all children, too? - os.kill(p.pid, signal.SIGINT) - logging.error("KILLED %d" % p.pid) - # Give the process a chance to actually die before continuing - # so that cleanup can happen safely. - time.sleep(1.0) - logging.error("TIMEOUT waiting for %s" % proc[0]) - raise TimeoutError(proc[0]) - else: - for line in p.stdout: - sys.stdout.write(line) - if not IsMac(): # stdout flush fails on Mac - logging.info("flushing stdout") - sys.stdout.flush() - - logging.info("collecting result code") - result = p.poll() - if result: - logging.error("%s exited with non-zero result code %d" % (proc[0], result)) - return result - - -def IsLinux(): - return sys.platform.startswith('linux') - - -def IsMac(): - return sys.platform.startswith('darwin') - - -def IsWindows(): - return sys.platform == 'cygwin' or sys.platform.startswith('win') - - -def WindowsVersionName(): - """Returns the name of the Windows version if it is known, or None. - - Possible return values are: xp, vista, 7, 8, or None - """ - if sys.platform == 'cygwin': - # Windows version number is hiding in system name. Looks like: - # CYGWIN_NT-6.1-WOW64 - try: - version_str = platform.uname()[0].split('-')[1] - except: - return None - elif sys.platform.startswith('win'): - # Normal Windows version string. Mine: 6.1.7601 - version_str = platform.version() - else: - return None - - parts = version_str.split('.') - try: - major = int(parts[0]) - minor = int(parts[1]) - except: - return None # Can't parse, unknown version. - - if major == 5: - return 'xp' - elif major == 6 and minor == 0: - return 'vista' - elif major == 6 and minor == 1: - return '7' - elif major == 6 and minor == 2: - return '8' # Future proof. ;) - return None - - -def PlatformNames(): - """Return an array of string to be used in paths for the platform - (e.g. suppressions, gtest filters, ignore files etc.) - The first element of the array describes the 'main' platform - """ - if IsLinux(): - return ['linux'] - if IsMac(): - return ['mac'] - if IsWindows(): - names = ['win32'] - version_name = WindowsVersionName() - if version_name is not None: - names.append('win-%s' % version_name) - return names - raise NotImplementedError('Unknown platform "%s".' % sys.platform) - - -def PutEnvAndLog(env_name, env_value): - os.putenv(env_name, env_value) - logging.info('export %s=%s', env_name, env_value) - -def BoringCallers(mangled, use_re_wildcards): - """Return a list of 'boring' function names (optinally mangled) - with */? wildcards (optionally .*/.). - Boring = we drop off the bottom of stack traces below such functions. - """ - - need_mangling = [ - # Don't show our testing framework: - ("testing::Test::Run", "_ZN7testing4Test3RunEv"), - ("testing::TestInfo::Run", "_ZN7testing8TestInfo3RunEv"), - ("testing::internal::Handle*ExceptionsInMethodIfSupported*", - "_ZN7testing8internal3?Handle*ExceptionsInMethodIfSupported*"), - - # Depend on scheduling: - ("MessageLoop::Run", "_ZN11MessageLoop3RunEv"), - ("MessageLoop::RunTask", "_ZN11MessageLoop7RunTask*"), - ("RunnableMethod*", "_ZN14RunnableMethod*"), - ("DispatchToMethod*", "_Z*16DispatchToMethod*"), - ("base::internal::Invoker*::DoInvoke*", - "_ZN4base8internal8Invoker*DoInvoke*"), # Invoker{1,2,3} - ("base::internal::RunnableAdapter*::Run*", - "_ZN4base8internal15RunnableAdapter*Run*"), - ] - - ret = [] - for pair in need_mangling: - ret.append(pair[1 if mangled else 0]) - - ret += [ - # Also don't show the internals of libc/pthread. - "start_thread", - "main", - "BaseThreadInitThunk", - ] - - if use_re_wildcards: - for i in range(0, len(ret)): - ret[i] = ret[i].replace('*', '.*').replace('?', '.') - - return ret - -def NormalizeWindowsPath(path): - """If we're using Cygwin Python, turn the path into a Windows path. - - Don't turn forward slashes into backslashes for easier copy-pasting and - escaping. - - TODO(rnk): If we ever want to cut out the subprocess invocation, we can use - _winreg to get the root Cygwin directory from the registry key: - HKEY_LOCAL_MACHINE\SOFTWARE\Cygwin\setup\rootdir. - """ - if sys.platform.startswith("cygwin"): - p = subprocess.Popen(["cygpath", "-m", path], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() - if err: - logging.warning("WARNING: cygpath error: %s", err) - return out.strip() - else: - return path - -############################ -# Common output format code - -def PrintUsedSuppressionsList(suppcounts): - """ Prints out the list of used suppressions in a format common to all the - memory tools. If the list is empty, prints nothing and returns False, - otherwise True. - - suppcounts: a dictionary of used suppression counts, - Key -> name, Value -> count. - """ - if not suppcounts: - return False - - print "-----------------------------------------------------" - print "Suppressions used:" - print " count name" - for (name, count) in sorted(suppcounts.items(), key=lambda (k,v): (v,k)): - print "%7d %s" % (count, name) - print "-----------------------------------------------------" - sys.stdout.flush() - return True diff --git a/tools/drmemory/scripts/drmemory_analyze.py b/tools/drmemory/scripts/drmemory_analyze.py deleted file mode 100644 index 29fc0ed4b..000000000 --- a/tools/drmemory/scripts/drmemory_analyze.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# drmemory_analyze.py - -''' Given a Dr. Memory output file, parses errors and uniques them.''' - -from collections import defaultdict -import common -import hashlib -import logging -import optparse -import os -import re -import subprocess -import sys -import time - -class DrMemoryError: - def __init__(self, report, suppression, testcase): - self._report = report - self._testcase = testcase - - # Chromium-specific transformations of the suppressions: - # Replace 'any_test.exe' and 'chrome.dll' with '*', then remove the - # Dr.Memory-generated error ids from the name= lines as they don't - # make sense in a multiprocess report. - supp_lines = suppression.split("\n") - for l in xrange(len(supp_lines)): - if supp_lines[l].startswith("name="): - supp_lines[l] = "name=<insert_a_suppression_name_here>" - if supp_lines[l].startswith("chrome.dll!"): - supp_lines[l] = supp_lines[l].replace("chrome.dll!", "*!") - bang_index = supp_lines[l].find("!") - d_exe_index = supp_lines[l].find(".exe!") - if bang_index >= 4 and d_exe_index + 4 == bang_index: - supp_lines[l] = "*" + supp_lines[l][bang_index:] - self._suppression = "\n".join(supp_lines) - - def __str__(self): - output = "" - output += "### BEGIN MEMORY TOOL REPORT (error hash=#%016X#)\n" % \ - self.ErrorHash() - output += self._report + "\n" - if self._testcase: - output += "The report came from the `%s` test.\n" % self._testcase - output += "Suppression (error hash=#%016X#):\n" % self.ErrorHash() - output += (" For more info on using suppressions see " - "http://dev.chromium.org/developers/how-tos/using-drmemory#TOC-Suppressing-error-reports-from-the-\n") - output += "{\n%s\n}\n" % self._suppression - output += "### END MEMORY TOOL REPORT (error hash=#%016X#)\n" % \ - self.ErrorHash() - return output - - # This is a device-independent hash identifying the suppression. - # By printing out this hash we can find duplicate reports between tests and - # different shards running on multiple buildbots - def ErrorHash(self): - return int(hashlib.md5(self._suppression).hexdigest()[:16], 16) - - def __hash__(self): - return hash(self._suppression) - - def __eq__(self, rhs): - return self._suppression == rhs - - -class DrMemoryAnalyzer: - ''' Given a set of Dr.Memory output files, parse all the errors out of - them, unique them and output the results.''' - - def __init__(self): - self.known_errors = set() - self.error_count = 0; - - def ReadLine(self): - self.line_ = self.cur_fd_.readline() - - def ReadSection(self): - result = [self.line_] - self.ReadLine() - while len(self.line_.strip()) > 0: - result.append(self.line_) - self.ReadLine() - return result - - def ParseReportFile(self, filename, testcase): - ret = [] - - # First, read the generated suppressions file so we can easily lookup a - # suppression for a given error. - supp_fd = open(filename.replace("results", "suppress"), 'r') - generated_suppressions = {} # Key -> Error #, Value -> Suppression text. - for line in supp_fd: - # NOTE: this regexp looks fragile. Might break if the generated - # suppression format slightly changes. - m = re.search("# Suppression for Error #([0-9]+)", line.strip()) - if not m: - continue - error_id = int(m.groups()[0]) - assert error_id not in generated_suppressions - # OK, now read the next suppression: - cur_supp = "" - for supp_line in supp_fd: - if supp_line.startswith("#") or supp_line.strip() == "": - break - cur_supp += supp_line - generated_suppressions[error_id] = cur_supp.strip() - supp_fd.close() - - self.cur_fd_ = open(filename, 'r') - while True: - self.ReadLine() - if (self.line_ == ''): break - - match = re.search("^Error #([0-9]+): (.*)", self.line_) - if match: - error_id = int(match.groups()[0]) - self.line_ = match.groups()[1].strip() + "\n" - report = "".join(self.ReadSection()).strip() - suppression = generated_suppressions[error_id] - ret.append(DrMemoryError(report, suppression, testcase)) - - if re.search("SUPPRESSIONS USED:", self.line_): - self.ReadLine() - while self.line_.strip() != "": - line = self.line_.strip() - (count, name) = re.match(" *([0-9\?]+)x(?: \(.*?\))?: (.*)", - line).groups() - if (count == "?"): - # Whole-module have no count available: assume 1 - count = 1 - else: - count = int(count) - self.used_suppressions[name] += count - self.ReadLine() - - if self.line_.startswith("ASSERT FAILURE"): - ret.append(self.line_.strip()) - - self.cur_fd_.close() - return ret - - def Report(self, filenames, testcase, check_sanity): - sys.stdout.flush() - # TODO(timurrrr): support positive tests / check_sanity==True - self.used_suppressions = defaultdict(int) - - to_report = [] - reports_for_this_test = set() - for f in filenames: - cur_reports = self.ParseReportFile(f, testcase) - - # Filter out the reports that were there in previous tests. - for r in cur_reports: - if r in reports_for_this_test: - # A similar report is about to be printed for this test. - pass - elif r in self.known_errors: - # A similar report has already been printed in one of the prev tests. - to_report.append("This error was already printed in some " - "other test, see 'hash=#%016X#'" % r.ErrorHash()) - reports_for_this_test.add(r) - else: - self.known_errors.add(r) - reports_for_this_test.add(r) - to_report.append(r) - - common.PrintUsedSuppressionsList(self.used_suppressions) - - if not to_report: - logging.info("PASS: No error reports found") - return 0 - - sys.stdout.flush() - sys.stderr.flush() - logging.info("Found %i error reports" % len(to_report)) - for report in to_report: - self.error_count += 1 - logging.info("Report #%d\n%s" % (self.error_count, report)) - logging.info("Total: %i error reports" % len(to_report)) - sys.stdout.flush() - return -1 - - -def main(): - '''For testing only. The DrMemoryAnalyze class should be imported instead.''' - parser = optparse.OptionParser("usage: %prog <files to analyze>") - - (options, args) = parser.parse_args() - if len(args) == 0: - parser.error("no filename specified") - filenames = args - - logging.getLogger().setLevel(logging.INFO) - return DrMemoryAnalyzer().Report(filenames, None, False) - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/tools/drmemory/scripts/logging_utils.py b/tools/drmemory/scripts/logging_utils.py deleted file mode 100644 index ef2d67495..000000000 --- a/tools/drmemory/scripts/logging_utils.py +++ /dev/null @@ -1,82 +0,0 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -''' Utility functions and objects for logging. -''' - -import logging -import sys - -class StdoutStderrHandler(logging.Handler): - ''' Subclass of logging.Handler which outputs to either stdout or stderr - based on a threshold level. - ''' - - def __init__(self, threshold=logging.WARNING, err=sys.stderr, out=sys.stdout): - ''' Args: - threshold: below this logging level messages are sent to stdout, - otherwise they are sent to stderr - err: a stream object that error messages are sent to, defaults to - sys.stderr - out: a stream object that non-error messages are sent to, defaults to - sys.stdout - ''' - logging.Handler.__init__(self) - self._err = logging.StreamHandler(err) - self._out = logging.StreamHandler(out) - self._threshold = threshold - self._last_was_err = False - - def setLevel(self, lvl): - logging.Handler.setLevel(self, lvl) - self._err.setLevel(lvl) - self._out.setLevel(lvl) - - def setFormatter(self, formatter): - logging.Handler.setFormatter(self, formatter) - self._err.setFormatter(formatter) - self._out.setFormatter(formatter) - - def emit(self, record): - if record.levelno < self._threshold: - self._out.emit(record) - self._last_was_err = False - else: - self._err.emit(record) - self._last_was_err = False - - def flush(self): - # preserve order on the flushing, the stalest stream gets flushed first - if self._last_was_err: - self._out.flush() - self._err.flush() - else: - self._err.flush() - self._out.flush() - - -FORMAT = "%(asctime)s %(filename)s [%(levelname)s] %(message)s" -DATEFMT = "%H:%M:%S" - -def config_root(level=logging.INFO, threshold=logging.WARNING, format=FORMAT, - datefmt=DATEFMT): - ''' Configure the root logger to use a StdoutStderrHandler and some default - formatting. - Args: - level: messages below this level are ignored - threshold: below this logging level messages are sent to stdout, - otherwise they are sent to stderr - format: format for log messages, see logger.Format - datefmt: format for date in log messages - - ''' - # to set the handler of the root logging object, we need to do setup - # manually rather than using basicConfig - root = logging.getLogger() - root.setLevel(level) - formatter = logging.Formatter(format, datefmt) - handler = StdoutStderrHandler(threshold=threshold) - handler.setLevel(level) - handler.setFormatter(formatter) - root.addHandler(handler) diff --git a/tools/drmemory/scripts/path_utils.py b/tools/drmemory/scripts/path_utils.py deleted file mode 100644 index 6ab431204..000000000 --- a/tools/drmemory/scripts/path_utils.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Some utility methods for getting and manipulating paths.""" - -# TODO(pamg): Have the buildbot use these, too. - - -import errno -import os -import sys - -class PathNotFound(Exception): pass - -def ScriptDir(): - """Get the full path to the directory containing the current script.""" - script_filename = os.path.abspath(sys.argv[0]) - return os.path.dirname(script_filename) - -def FindAncestor(start_dir, ancestor): - """Finds an ancestor dir in a path. - - For example, FindAncestor('c:\foo\bar\baz', 'bar') would return - 'c:\foo\bar'. Unlike FindUpward*, this only looks at direct path ancestors. - """ - start_dir = os.path.abspath(start_dir) - path = start_dir - while True: - (parent, tail) = os.path.split(path) - if tail == ancestor: - return path - if not tail: - break - path = parent - raise PathNotFound("Unable to find ancestor %s in %s" % (ancestor, start_dir)) - -def FindUpwardParent(start_dir, *desired_list): - """Finds the desired object's parent, searching upward from the start_dir. - - Searches start_dir and all its parents looking for the desired directory - or file, which may be given in one or more path components. Returns the - first directory in which the top desired path component was found, or raises - PathNotFound if it wasn't. - """ - desired_path = os.path.join(*desired_list) - last_dir = '' - cur_dir = start_dir - found_path = os.path.join(cur_dir, desired_path) - while not os.path.exists(found_path): - last_dir = cur_dir - cur_dir = os.path.dirname(cur_dir) - if last_dir == cur_dir: - raise PathNotFound('Unable to find %s above %s' % - (desired_path, start_dir)) - found_path = os.path.join(cur_dir, desired_path) - # Strip the entire original desired path from the end of the one found - # and remove a trailing path separator, if present. - found_path = found_path[:len(found_path) - len(desired_path)] - if found_path.endswith(os.sep): - found_path = found_path[:len(found_path) - 1] - return found_path - - -def FindUpward(start_dir, *desired_list): - """Returns a path to the desired directory or file, searching upward. - - Searches start_dir and all its parents looking for the desired directory - or file, which may be given in one or more path components. Returns the full - path to the desired object, or raises PathNotFound if it wasn't found. - """ - parent = FindUpwardParent(start_dir, *desired_list) - return os.path.join(parent, *desired_list) - - -def MaybeMakeDirectory(*path): - """Creates an entire path, if it doesn't already exist.""" - file_path = os.path.join(*path) - try: - os.makedirs(file_path) - except OSError, e: - # errno.EEXIST is "File exists". If we see another error, re-raise. - if e.errno != errno.EEXIST: - raise diff --git a/tools/drmemory/scripts/pdfium_tests.bat b/tools/drmemory/scripts/pdfium_tests.bat deleted file mode 100644 index 4618a0e94..000000000 --- a/tools/drmemory/scripts/pdfium_tests.bat +++ /dev/null @@ -1,24 +0,0 @@ -@echo off
-:: Copyright (c) 2011 The Chromium Authors. All rights reserved.
-:: Use of this source code is governed by a BSD-style license that can be
-:: found in the LICENSE file.
-
-set THISDIR=%~dp0
-set TOOL_NAME="drmemory_full"
-
-:: Set up DRMEMORY_COMMAND to invoke Dr. Memory {{{1
-set DRMEMORY_PATH=%THISDIR%..
-set DRMEMORY_SFX=%DRMEMORY_PATH%\drmemory-windows-sfx.exe
-if EXIST %DRMEMORY_SFX% GOTO DRMEMORY_BINARY_OK
-echo "Can't find Dr. Memory executables."
-echo "See http://www.chromium.org/developers/how-tos/using-valgrind/dr-memory"
-echo "for the instructions on how to get them."
-exit /B 1
-
-:DRMEMORY_BINARY_OK
-%DRMEMORY_SFX% -o%DRMEMORY_PATH%\unpacked -y
-set DRMEMORY_COMMAND=%DRMEMORY_PATH%\unpacked\bin\drmemory.exe
-:: }}}
-
-:RUN_TESTS
-python %THISDIR%/pdfium_tests.py %*
diff --git a/tools/drmemory/scripts/pdfium_tests.py b/tools/drmemory/scripts/pdfium_tests.py deleted file mode 100644 index f1d5308f9..000000000 --- a/tools/drmemory/scripts/pdfium_tests.py +++ /dev/null @@ -1,399 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -''' Runs various chrome tests through valgrind_test.py.''' - -import glob -import logging -import optparse -import os -import subprocess -import sys - -import logging_utils -import path_utils - -import common -import valgrind_test - -class TestNotFound(Exception): pass - -class MultipleGTestFiltersSpecified(Exception): pass - -class BuildDirNotFound(Exception): pass - -class BuildDirAmbiguous(Exception): pass - -class ExecutableNotFound(Exception): pass - -class BadBinary(Exception): pass - -class ChromeTests: - SLOW_TOOLS = ["drmemory"] - - def __init__(self, options, args, test): - if ':' in test: - (self._test, self._gtest_filter) = test.split(':', 1) - else: - self._test = test - self._gtest_filter = options.gtest_filter - - if self._test not in self._test_list: - raise TestNotFound("Unknown test: %s" % test) - - if options.gtest_filter and options.gtest_filter != self._gtest_filter: - raise MultipleGTestFiltersSpecified("Can not specify both --gtest_filter " - "and --test %s" % test) - - self._options = options - self._args = args - - # Compute the top of the tree (the "source dir") from the script dir - # (where this script lives). We assume that the script dir is in - # tools/drmemory/scripts relative to the top of the tree. - script_dir = os.path.dirname(path_utils.ScriptDir()) - self._source_dir = os.path.dirname(os.path.dirname(script_dir)) - # Setup Dr. Memory if it's not set up yet. - drmem_cmd = os.getenv("DRMEMORY_COMMAND") - if not drmem_cmd: - drmem_sfx = os.path.join(script_dir, "drmemory-windows-sfx.exe") - if not os.path.isfile(drmem_sfx): - raise RuntimeError, "Cannot find drmemory-windows-sfx.exe" - drmem_dir = os.path.join(script_dir, "unpacked") - subprocess.call([drmem_sfx, "-o" + drmem_dir, "-y"], 0) - drmem_cmd = os.path.join(drmem_dir, "bin", "drmemory.exe") - os.environ["DRMEMORY_COMMAND"] = drmem_cmd - # since this path is used for string matching, make sure it's always - # an absolute Unix-style path - self._source_dir = os.path.abspath(self._source_dir).replace('\\', '/') - self._command_preamble = ["--source-dir=%s" % (self._source_dir)] - - if not self._options.build_dir: - dirs = [ - os.path.join(self._source_dir, "xcodebuild", "Debug"), - os.path.join(self._source_dir, "out", "Debug"), - os.path.join(self._source_dir, "build", "Debug"), - ] - build_dir = [d for d in dirs if os.path.isdir(d)] - if len(build_dir) > 1: - raise BuildDirAmbiguous("Found more than one suitable build dir:\n" - "%s\nPlease specify just one " - "using --build-dir" % ", ".join(build_dir)) - elif build_dir: - self._options.build_dir = build_dir[0] - else: - self._options.build_dir = None - - if self._options.build_dir: - build_dir = os.path.abspath(self._options.build_dir) - self._command_preamble += ["--build-dir=%s" % (self._options.build_dir)] - - def _EnsureBuildDirFound(self): - if not self._options.build_dir: - raise BuildDirNotFound("Oops, couldn't find a build dir, please " - "specify it manually using --build-dir") - - def _DefaultCommand(self, tool, exe=None, valgrind_test_args=None): - '''Generates the default command array that most tests will use.''' - if exe and common.IsWindows(): - exe += '.exe' - - cmd = list(self._command_preamble) - - # Find all suppressions matching the following pattern: - # tools/valgrind/TOOL/suppressions[_PLATFORM].txt - # and list them with --suppressions= prefix. - script_dir = path_utils.ScriptDir() - suppression_file = os.path.join(script_dir, "..", "suppressions.txt") - if os.path.exists(suppression_file): - cmd.append("--suppressions=%s" % suppression_file) - # Platform-specific suppression - for platform in common.PlatformNames(): - platform_suppression_file = \ - os.path.join(script_dir, "..", 'suppressions_%s.txt' % platform) - if os.path.exists(platform_suppression_file): - cmd.append("--suppressions=%s" % platform_suppression_file) - - if self._options.valgrind_tool_flags: - cmd += self._options.valgrind_tool_flags.split(" ") - if self._options.keep_logs: - cmd += ["--keep_logs"] - if valgrind_test_args != None: - for arg in valgrind_test_args: - cmd.append(arg) - if exe: - self._EnsureBuildDirFound() - exe_path = os.path.join(self._options.build_dir, exe) - if not os.path.exists(exe_path): - raise ExecutableNotFound("Couldn't find '%s'" % exe_path) - - cmd.append(exe_path) - # Valgrind runs tests slowly, so slow tests hurt more; show elapased time - # so we can find the slowpokes. - cmd.append("--gtest_print_time") - # Built-in test launcher for gtest-based executables runs tests using - # multiple process by default. Force the single-process mode back. - cmd.append("--single-process-tests") - if self._options.gtest_repeat: - cmd.append("--gtest_repeat=%s" % self._options.gtest_repeat) - if self._options.gtest_shuffle: - cmd.append("--gtest_shuffle") - if self._options.gtest_break_on_failure: - cmd.append("--gtest_break_on_failure") - if self._options.test_launcher_bot_mode: - cmd.append("--test-launcher-bot-mode") - if self._options.test_launcher_total_shards is not None: - cmd.append("--test-launcher-total-shards=%d" % self._options.test_launcher_total_shards) - if self._options.test_launcher_shard_index is not None: - cmd.append("--test-launcher-shard-index=%d" % self._options.test_launcher_shard_index) - return cmd - - def Run(self): - ''' Runs the test specified by command-line argument --test ''' - logging.info("running test %s" % (self._test)) - return self._test_list[self._test](self) - - def _AppendGtestFilter(self, tool, name, cmd): - '''Append an appropriate --gtest_filter flag to the googletest binary - invocation. - If the user passed his own filter mentioning only one test, just use it. - Othewise, filter out tests listed in the appropriate gtest_exclude files. - ''' - if (self._gtest_filter and - ":" not in self._gtest_filter and - "?" not in self._gtest_filter and - "*" not in self._gtest_filter): - cmd.append("--gtest_filter=%s" % self._gtest_filter) - return - - filters = [] - gtest_files_dir = os.path.join(path_utils.ScriptDir(), "gtest_exclude") - - gtest_filter_files = [ - os.path.join(gtest_files_dir, name + ".gtest-%s.txt" % tool.ToolName())] - # Use ".gtest.txt" files only for slow tools, as they now contain - # Valgrind- and Dr.Memory-specific filters. - # TODO(glider): rename the files to ".gtest_slow.txt" - if tool.ToolName() in ChromeTests.SLOW_TOOLS: - gtest_filter_files += [os.path.join(gtest_files_dir, name + ".gtest.txt")] - for platform_suffix in common.PlatformNames(): - gtest_filter_files += [ - os.path.join(gtest_files_dir, name + ".gtest_%s.txt" % platform_suffix), - os.path.join(gtest_files_dir, name + ".gtest-%s_%s.txt" % \ - (tool.ToolName(), platform_suffix))] - logging.info("Reading gtest exclude filter files:") - for filename in gtest_filter_files: - # strip the leading absolute path (may be very long on the bot) - # and the following / or \. - readable_filename = filename.replace("\\", "/") # '\' on Windows - readable_filename = readable_filename.replace(self._source_dir, "")[1:] - if not os.path.exists(filename): - logging.info(" \"%s\" - not found" % readable_filename) - continue - logging.info(" \"%s\" - OK" % readable_filename) - f = open(filename, 'r') - for line in f.readlines(): - if line.startswith("#") or line.startswith("//") or line.isspace(): - continue - line = line.rstrip() - test_prefixes = ["FLAKY", "FAILS"] - for p in test_prefixes: - # Strip prefixes from the test names. - line = line.replace(".%s_" % p, ".") - # Exclude the original test name. - filters.append(line) - if line[-2:] != ".*": - # List all possible prefixes if line doesn't end with ".*". - for p in test_prefixes: - filters.append(line.replace(".", ".%s_" % p)) - # Get rid of duplicates. - filters = set(filters) - gtest_filter = self._gtest_filter - if len(filters): - if gtest_filter: - gtest_filter += ":" - if gtest_filter.find("-") < 0: - gtest_filter += "-" - else: - gtest_filter = "-" - gtest_filter += ":".join(filters) - if gtest_filter: - cmd.append("--gtest_filter=%s" % gtest_filter) - - @staticmethod - def ShowTests(): - test_to_names = {} - for name, test_function in ChromeTests._test_list.iteritems(): - test_to_names.setdefault(test_function, []).append(name) - - name_to_aliases = {} - for names in test_to_names.itervalues(): - names.sort(key=lambda name: len(name)) - name_to_aliases[names[0]] = names[1:] - - print - print "Available tests:" - print "----------------" - for name, aliases in sorted(name_to_aliases.iteritems()): - if aliases: - print " {} (aka {})".format(name, ', '.join(aliases)) - else: - print " {}".format(name) - - def SetupLdPath(self, requires_build_dir): - if requires_build_dir: - self._EnsureBuildDirFound() - elif not self._options.build_dir: - return - - # Append build_dir to LD_LIBRARY_PATH so external libraries can be loaded. - if (os.getenv("LD_LIBRARY_PATH")): - os.putenv("LD_LIBRARY_PATH", "%s:%s" % (os.getenv("LD_LIBRARY_PATH"), - self._options.build_dir)) - else: - os.putenv("LD_LIBRARY_PATH", self._options.build_dir) - - def SimpleTest(self, module, name, valgrind_test_args=None, cmd_args=None): - tool = valgrind_test.CreateTool(self._options.valgrind_tool) - cmd = self._DefaultCommand(tool, name, valgrind_test_args) - self._AppendGtestFilter(tool, name, cmd) - cmd.extend(['--test-tiny-timeout=1000']) - if cmd_args: - cmd.extend(cmd_args) - - self.SetupLdPath(True) - return tool.Run(cmd, module) - - def RunCmdLine(self): - tool = valgrind_test.CreateTool(self._options.valgrind_tool) - cmd = self._DefaultCommand(tool, None, self._args) - self.SetupLdPath(False) - return tool.Run(cmd, None) - - def TestPDFiumUnitTests(self): - return self.SimpleTest("pdfium_unittests", "pdfium_unittests") - - def TestPDFiumEmbedderTests(self): - return self.SimpleTest("pdfium_embeddertests", "pdfium_embeddertests") - - def TestPDFiumTest(self, script_name): - # Build the command line in 'cmd'. - # It's going to be roughly - # python valgrind_test.py ... - # but we'll use the --indirect_pdfium_test flag to valgrind_test.py - # to avoid valgrinding python. - - # Start by building the valgrind_test.py commandline. - tool = valgrind_test.CreateTool(self._options.valgrind_tool) - cmd = self._DefaultCommand(tool) - cmd.append("--trace_children") - cmd.append("--indirect_pdfium_test") - cmd.append("--ignore_exit_code") - # Now build script_cmd, the run_corpus_tests commandline. - script = os.path.join(self._source_dir, "testing", "tools", script_name) - script_cmd = ["python", script] - if self._options.build_dir: - script_cmd.extend(["--build-dir", self._options.build_dir]) - # Now run script_cmd with the wrapper in cmd - cmd.append("--") - cmd.extend(script_cmd) - - ret = tool.Run(cmd, "layout", min_runtime_in_seconds=0) - return ret - - def TestPDFiumJavascript(self): - return self.TestPDFiumTest("run_javascript_tests.py") - - def TestPDFiumPixel(self): - return self.TestPDFiumTest("run_pixel_tests.py") - - def TestPDFiumCorpus(self): - return self.TestPDFiumTest("run_corpus_tests.py") - - # The known list of tests. - _test_list = { - "cmdline" : RunCmdLine, - "pdfium_corpus": TestPDFiumCorpus, - "pdfium_embeddertests": TestPDFiumEmbedderTests, - "pdfium_javascript": TestPDFiumJavascript, - "pdfium_pixel": TestPDFiumPixel, - "pdfium_unittests": TestPDFiumUnitTests, - } - - -def _main(): - parser = optparse.OptionParser("usage: %prog -b <dir> -t <test> " - "[-t <test> ...]") - - parser.add_option("--help-tests", dest="help_tests", action="store_true", - default=False, help="List all available tests") - parser.add_option("-b", "--build-dir", - help="the location of the compiler output") - parser.add_option("--target", help="Debug or Release") - parser.add_option("-t", "--test", action="append", default=[], - help="which test to run, supports test:gtest_filter format " - "as well.") - parser.add_option("--gtest_filter", - help="additional arguments to --gtest_filter") - parser.add_option("--gtest_repeat", help="argument for --gtest_repeat") - parser.add_option("--gtest_shuffle", action="store_true", default=False, - help="Randomize tests' orders on every iteration.") - parser.add_option("--gtest_break_on_failure", action="store_true", - default=False, - help="Drop in to debugger on assertion failure. Also " - "useful for forcing tests to exit with a stack dump " - "on the first assertion failure when running with " - "--gtest_repeat=-1") - parser.add_option("-v", "--verbose", action="store_true", default=False, - help="verbose output - enable debug log messages") - parser.add_option("--tool", dest="valgrind_tool", default="drmemory_full", - help="specify a valgrind tool to run the tests under") - parser.add_option("--tool_flags", dest="valgrind_tool_flags", default="", - help="specify custom flags for the selected valgrind tool") - parser.add_option("--keep_logs", action="store_true", default=False, - help="store memory tool logs in the <tool>.logs directory " - "instead of /tmp.\nThis can be useful for tool " - "developers/maintainers.\nPlease note that the <tool>" - ".logs directory will be clobbered on tool startup.") - parser.add_option("--test-launcher-bot-mode", action="store_true", - help="run the tests with --test-launcher-bot-mode") - parser.add_option("--test-launcher-total-shards", type=int, - help="run the tests with --test-launcher-total-shards") - parser.add_option("--test-launcher-shard-index", type=int, - help="run the tests with --test-launcher-shard-index") - - options, args = parser.parse_args() - - # Bake target into build_dir. - if options.target and options.build_dir: - assert (options.target != - os.path.basename(os.path.dirname(options.build_dir))) - options.build_dir = os.path.join(os.path.abspath(options.build_dir), - options.target) - - if options.verbose: - logging_utils.config_root(logging.DEBUG) - else: - logging_utils.config_root() - - if options.help_tests: - ChromeTests.ShowTests() - return 0 - - if not options.test: - parser.error("--test not specified") - - if len(options.test) != 1 and options.gtest_filter: - parser.error("--gtest_filter and multiple tests don't make sense together") - - for t in options.test: - tests = ChromeTests(options, args, t) - ret = tests.Run() - if ret: return ret - return 0 - - -if __name__ == "__main__": - sys.exit(_main()) diff --git a/tools/drmemory/scripts/valgrind_test.py b/tools/drmemory/scripts/valgrind_test.py deleted file mode 100644 index 92960c79a..000000000 --- a/tools/drmemory/scripts/valgrind_test.py +++ /dev/null @@ -1,487 +0,0 @@ -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Runs an exe through Valgrind and puts the intermediate files in a -directory. -""" - -import datetime -import glob -import logging -import optparse -import os -import re -import shutil -import stat -import subprocess -import sys -import tempfile - -import common - -import drmemory_analyze - -class BaseTool(object): - """Abstract class for running dynamic error detection tools. - - Always subclass this and implement ToolCommand with framework- and - tool-specific stuff. - """ - - def __init__(self): - temp_parent_dir = None - self.log_parent_dir = "" - if common.IsWindows(): - # gpu process on Windows Vista+ runs at Low Integrity and can only - # write to certain directories (http://crbug.com/119131) - # - # TODO(bruening): if scripts die in middle and don't clean up temp - # dir, we'll accumulate files in profile dir. should remove - # really old files automatically. - profile = os.getenv("USERPROFILE") - if profile: - self.log_parent_dir = profile + "\\AppData\\LocalLow\\" - if os.path.exists(self.log_parent_dir): - self.log_parent_dir = common.NormalizeWindowsPath(self.log_parent_dir) - temp_parent_dir = self.log_parent_dir - # Generated every time (even when overridden) - self.temp_dir = tempfile.mkdtemp(prefix="vg_logs_", dir=temp_parent_dir) - self.log_dir = self.temp_dir # overridable by --keep_logs - self.option_parser_hooks = [] - # TODO(glider): we may not need some of the env vars on some of the - # platforms. - self._env = { - "G_SLICE" : "always-malloc", - "NSS_DISABLE_UNLOAD" : "1", - "NSS_DISABLE_ARENA_FREE_LIST" : "1", - "GTEST_DEATH_TEST_USE_FORK": "1", - } - - def ToolName(self): - raise NotImplementedError, "This method should be implemented " \ - "in the tool-specific subclass" - - def Analyze(self, check_sanity=False): - raise NotImplementedError, "This method should be implemented " \ - "in the tool-specific subclass" - - def RegisterOptionParserHook(self, hook): - # Frameworks and tools can add their own flags to the parser. - self.option_parser_hooks.append(hook) - - def CreateOptionParser(self): - # Defines Chromium-specific flags. - self._parser = optparse.OptionParser("usage: %prog [options] <program to " - "test>") - self._parser.disable_interspersed_args() - self._parser.add_option("-t", "--timeout", - dest="timeout", metavar="TIMEOUT", default=100000, - help="timeout in seconds for the run (default 100000)") - self._parser.add_option("", "--build-dir", - help="the location of the compiler output") - self._parser.add_option("", "--source-dir", - help="path to top of source tree for this build" - "(used to normalize source paths in baseline)") - self._parser.add_option("", "--gtest_filter", default="", - help="which test case to run") - self._parser.add_option("", "--gtest_repeat", - help="how many times to run each test") - self._parser.add_option("", "--gtest_print_time", action="store_true", - default=False, - help="show how long each test takes") - self._parser.add_option("", "--ignore_exit_code", action="store_true", - default=False, - help="ignore exit code of the test " - "(e.g. test failures)") - self._parser.add_option("", "--keep_logs", action="store_true", - default=False, - help="store memory tool logs in the <tool>.logs " - "directory instead of /tmp.\nThis can be " - "useful for tool developers/maintainers.\n" - "Please note that the <tool>.logs directory " - "will be clobbered on tool startup.") - - # To add framework- or tool-specific flags, please add a hook using - # RegisterOptionParserHook in the corresponding subclass. - # See ValgrindTool for an example. - for hook in self.option_parser_hooks: - hook(self, self._parser) - - def ParseArgv(self, args): - self.CreateOptionParser() - - # self._tool_flags will store those tool flags which we don't parse - # manually in this script. - self._tool_flags = [] - known_args = [] - - """ We assume that the first argument not starting with "-" is a program - name and all the following flags should be passed to the program. - TODO(timurrrr): customize optparse instead - """ - while len(args) > 0 and args[0][:1] == "-": - arg = args[0] - if (arg == "--"): - break - if self._parser.has_option(arg.split("=")[0]): - known_args += [arg] - else: - self._tool_flags += [arg] - args = args[1:] - - if len(args) > 0: - known_args += args - - self._options, self._args = self._parser.parse_args(known_args) - - self._timeout = int(self._options.timeout) - self._source_dir = self._options.source_dir - if self._options.keep_logs: - # log_parent_dir has trailing slash if non-empty - self.log_dir = self.log_parent_dir + "%s.logs" % self.ToolName() - if os.path.exists(self.log_dir): - shutil.rmtree(self.log_dir) - os.mkdir(self.log_dir) - logging.info("Logs are in " + self.log_dir) - - self._ignore_exit_code = self._options.ignore_exit_code - if self._options.gtest_filter != "": - self._args.append("--gtest_filter=%s" % self._options.gtest_filter) - if self._options.gtest_repeat: - self._args.append("--gtest_repeat=%s" % self._options.gtest_repeat) - if self._options.gtest_print_time: - self._args.append("--gtest_print_time") - - return True - - def Setup(self, args): - return self.ParseArgv(args) - - def ToolCommand(self): - raise NotImplementedError, "This method should be implemented " \ - "in the tool-specific subclass" - - def Cleanup(self): - # You may override it in the tool-specific subclass - pass - - def Execute(self): - """ Execute the app to be tested after successful instrumentation. - Full execution command-line provided by subclassers via proc.""" - logging.info("starting execution...") - proc = self.ToolCommand() - for var in self._env: - common.PutEnvAndLog(var, self._env[var]) - return common.RunSubprocess(proc, self._timeout) - - def RunTestsAndAnalyze(self, check_sanity): - exec_retcode = self.Execute() - analyze_retcode = self.Analyze(check_sanity) - - if analyze_retcode: - logging.error("Analyze failed.") - logging.info("Search the log for '[ERROR]' to see the error reports.") - return analyze_retcode - - if exec_retcode: - if self._ignore_exit_code: - logging.info("Test execution failed, but the exit code is ignored.") - else: - logging.error("Test execution failed.") - return exec_retcode - else: - logging.info("Test execution completed successfully.") - - if not analyze_retcode: - logging.info("Analysis completed successfully.") - - return 0 - - def Main(self, args, check_sanity, min_runtime_in_seconds): - """Call this to run through the whole process: Setup, Execute, Analyze""" - start_time = datetime.datetime.now() - retcode = -1 - if self.Setup(args): - retcode = self.RunTestsAndAnalyze(check_sanity) - shutil.rmtree(self.temp_dir, ignore_errors=True) - self.Cleanup() - else: - logging.error("Setup failed") - end_time = datetime.datetime.now() - runtime_in_seconds = (end_time - start_time).seconds - hours = runtime_in_seconds / 3600 - seconds = runtime_in_seconds % 3600 - minutes = seconds / 60 - seconds = seconds % 60 - logging.info("elapsed time: %02d:%02d:%02d" % (hours, minutes, seconds)) - if (min_runtime_in_seconds > 0 and - runtime_in_seconds < min_runtime_in_seconds): - logging.error("Layout tests finished too quickly. " - "It should have taken at least %d seconds. " - "Something went wrong?" % min_runtime_in_seconds) - retcode = -1 - return retcode - - def Run(self, args, module, min_runtime_in_seconds=0): - MODULES_TO_SANITY_CHECK = ["base"] - - check_sanity = module in MODULES_TO_SANITY_CHECK - return self.Main(args, check_sanity, min_runtime_in_seconds) - - -class DrMemory(BaseTool): - """Dr.Memory - Dynamic memory error detector for Windows. - - http://dev.chromium.org/developers/how-tos/using-drmemory - It is not very mature at the moment, some things might not work properly. - """ - - def __init__(self, full_mode, pattern_mode): - super(DrMemory, self).__init__() - self.full_mode = full_mode - self.pattern_mode = pattern_mode - self.RegisterOptionParserHook(DrMemory.ExtendOptionParser) - - def ToolName(self): - return "drmemory" - - def ExtendOptionParser(self, parser): - parser.add_option("", "--suppressions", default=[], - action="append", - help="path to a drmemory suppression file") - parser.add_option("", "--follow_python", action="store_true", - default=False, dest="follow_python", - help="Monitor python child processes. If off, neither " - "python children nor any children of python children " - "will be monitored.") - parser.add_option("", "--indirect_pdfium_test", action="store_true", - default=False, - help="set --wrapper rather than running Dr. Memory " - "directly.") - parser.add_option("", "--use_debug", action="store_true", - default=False, dest="use_debug", - help="Run Dr. Memory debug build") - parser.add_option("", "--trace_children", action="store_true", - default=True, - help="TODO: default value differs from Valgrind") - - def ToolCommand(self): - """Get the tool command to run.""" - # WINHEAP is what Dr. Memory supports as there are issues w/ both - # jemalloc (https://github.com/DynamoRIO/drmemory/issues/320) and - # tcmalloc (https://github.com/DynamoRIO/drmemory/issues/314) - add_env = { - "CHROME_ALLOCATOR" : "WINHEAP", - "JSIMD_FORCEMMX" : "1", # https://github.com/DynamoRIO/drmemory/issues/540 - } - for k,v in add_env.iteritems(): - logging.info("export %s=%s", k, v) - os.putenv(k, v) - - drmem_cmd = os.getenv("DRMEMORY_COMMAND") - if not drmem_cmd: - raise RuntimeError, "Please set DRMEMORY_COMMAND environment variable " \ - "with the path to drmemory.exe" - proc = drmem_cmd.split(" ") - - # By default, don't run python (this will exclude python's children as well) - # to reduce runtime. We're not really interested in spending time finding - # bugs in the python implementation. - # With file-based config we must update the file every time, and - # it will affect simultaneous drmem uses by this user. While file-based - # config has many advantages, here we may want this-instance-only - # (https://github.com/DynamoRIO/drmemory/issues/334). - drconfig_cmd = [ proc[0].replace("drmemory.exe", "drconfig.exe") ] - drconfig_cmd += ["-quiet"] # suppress errors about no 64-bit libs - run_drconfig = True - if self._options.follow_python: - logging.info("Following python children") - # -unreg fails if not already registered so query for that first - query_cmd = drconfig_cmd + ["-isreg", "python.exe"] - query_proc = subprocess.Popen(query_cmd, stdout=subprocess.PIPE, - shell=True) - (query_out, query_err) = query_proc.communicate() - if re.search("exe not registered", query_out): - run_drconfig = False # all set - else: - drconfig_cmd += ["-unreg", "python.exe"] - else: - logging.info("Excluding python children") - drconfig_cmd += ["-reg", "python.exe", "-norun"] - if run_drconfig: - drconfig_retcode = common.RunSubprocess(drconfig_cmd, self._timeout) - if drconfig_retcode: - logging.error("Configuring whether to follow python children failed " \ - "with %d.", drconfig_retcode) - raise RuntimeError, "Configuring python children failed " - - suppression_count = 0 - supp_files = self._options.suppressions - if self.full_mode: - supp_files += [s.replace(".txt", "_full.txt") for s in supp_files] - for suppression_file in supp_files: - if os.path.exists(suppression_file): - suppression_count += 1 - proc += ["-suppress", common.NormalizeWindowsPath(suppression_file)] - - if not suppression_count: - logging.warning("WARNING: NOT USING SUPPRESSIONS!") - - # Un-comment to dump Dr.Memory events on error - #proc += ["-dr_ops", "-dumpcore_mask", "-dr_ops", "0x8bff"] - - # Un-comment and comment next line to debug Dr.Memory - #proc += ["-dr_ops", "-no_hide"] - #proc += ["-dr_ops", "-msgbox_mask", "-dr_ops", "15"] - #Proc += ["-dr_ops", "-stderr_mask", "-dr_ops", "15"] - # Ensure we see messages about Dr. Memory crashing! - proc += ["-dr_ops", "-stderr_mask", "-dr_ops", "12"] - - if self._options.use_debug: - proc += ["-debug"] - - proc += ["-logdir", common.NormalizeWindowsPath(self.log_dir)] - - if self.log_parent_dir: - # gpu process on Windows Vista+ runs at Low Integrity and can only - # write to certain directories (http://crbug.com/119131) - symcache_dir = os.path.join(self.log_parent_dir, "drmemory.symcache") - elif self._options.build_dir: - # The other case is only possible with -t cmdline. - # Anyways, if we omit -symcache_dir the -logdir's value is used which - # should be fine. - symcache_dir = os.path.join(self._options.build_dir, "drmemory.symcache") - if symcache_dir: - if not os.path.exists(symcache_dir): - try: - os.mkdir(symcache_dir) - except OSError: - logging.warning("Can't create symcache dir?") - if os.path.exists(symcache_dir): - proc += ["-symcache_dir", common.NormalizeWindowsPath(symcache_dir)] - - # Use -no_summary to suppress DrMemory's summary and init-time - # notifications. We generate our own with drmemory_analyze.py. - proc += ["-batch", "-no_summary"] - - # Un-comment to disable interleaved output. Will also suppress error - # messages normally printed to stderr. - #proc += ["-quiet", "-no_results_to_stderr"] - - proc += ["-callstack_max_frames", "40"] - - # disable leak scan for now - proc += ["-no_count_leaks", "-no_leak_scan"] - - # disable warnings about unaddressable prefetches - proc += ["-no_check_prefetch"] - - # crbug.com/413215, no heap mismatch check for Windows release build binary - if common.IsWindows() and "Release" in self._options.build_dir: - proc += ["-no_check_delete_mismatch"] - - # make callstacks easier to read - proc += ["-callstack_srcfile_prefix", - "build\\src,chromium\\src,crt_build\\self_x86"] - proc += ["-callstack_modname_hide", - "*drmemory*,chrome.dll"] - - boring_callers = common.BoringCallers(mangled=False, use_re_wildcards=False) - # TODO(timurrrr): In fact, we want "starting from .." instead of "below .." - proc += ["-callstack_truncate_below", ",".join(boring_callers)] - - if self.pattern_mode: - proc += ["-pattern", "0xf1fd", "-no_count_leaks", "-redzone_size", "0x20"] - elif not self.full_mode: - proc += ["-light"] - - proc += self._tool_flags - - # Dr.Memory requires -- to separate tool flags from the executable name. - proc += ["--"] - - if self._options.indirect_pdfium_test: - wrapper = " ".join(proc) - logging.info("pdfium wrapper = " + wrapper) - proc = self._args - proc += ["--wrapper", wrapper] - return proc - - # Note that self._args begins with the name of the exe to be run. - self._args[0] = common.NormalizeWindowsPath(self._args[0]) - proc += self._args - return proc - - def CreateBrowserWrapper(self, command): - os.putenv("BROWSER_WRAPPER", command) - - def Analyze(self, check_sanity=False): - # Use one analyzer for all the log files to avoid printing duplicate reports - # - # TODO(timurrrr): unify this with Valgrind and other tools when we have - # https://github.com/DynamoRIO/drmemory/issues/684 - analyzer = drmemory_analyze.DrMemoryAnalyzer() - - ret = 0 - if not self._options.indirect_pdfium_test: - filenames = glob.glob(self.log_dir + "/*/results.txt") - - ret = analyzer.Report(filenames, None, check_sanity) - else: - testcases = glob.glob(self.log_dir + "/testcase.*.logs") - # If we have browser wrapper, the per-test logdirs are named as - # "testcase.wrapper_PID.name". - # Let's extract the list of wrapper_PIDs and name it ppids. - # NOTE: ppids may contain '_', i.e. they are not ints! - ppids = set([f.split(".")[-2] for f in testcases]) - - for ppid in ppids: - testcase_name = None - try: - f = open("%s/testcase.%s.name" % (self.log_dir, ppid)) - testcase_name = f.read().strip() - f.close() - except IOError: - pass - print "=====================================================" - print " Below is the report for drmemory wrapper PID=%s." % ppid - if testcase_name: - print " It was used while running the `%s` test." % testcase_name - else: - # TODO(timurrrr): hm, the PID line is suppressed on Windows... - print " You can find the corresponding test" - print " by searching the above log for 'PID=%s'" % ppid - sys.stdout.flush() - ppid_filenames = glob.glob("%s/testcase.%s.logs/*/results.txt" % - (self.log_dir, ppid)) - ret |= analyzer.Report(ppid_filenames, testcase_name, False) - print "=====================================================" - sys.stdout.flush() - - logging.info("Please see http://dev.chromium.org/developers/how-tos/" - "using-drmemory for the info on Dr. Memory") - return ret - - -class ToolFactory: - def Create(self, tool_name): - if tool_name == "drmemory" or tool_name == "drmemory_light": - # TODO(timurrrr): remove support for "drmemory" when buildbots are - # switched to drmemory_light OR make drmemory==drmemory_full the default - # mode when the tool is mature enough. - return DrMemory(False, False) - if tool_name == "drmemory_full": - return DrMemory(True, False) - if tool_name == "drmemory_pattern": - return DrMemory(False, True) - try: - platform_name = common.PlatformNames()[0] - except common.NotImplementedError: - platform_name = sys.platform + "(Unknown)" - raise RuntimeError, "Unknown tool (tool=%s, platform=%s)" % (tool_name, - platform_name) - -def CreateTool(tool): - return ToolFactory().Create(tool) diff --git a/tools/drmemory/suppressions.txt b/tools/drmemory/suppressions.txt deleted file mode 100644 index 2ad8236ca..000000000 --- a/tools/drmemory/suppressions.txt +++ /dev/null @@ -1,28 +0,0 @@ -# This file contains suppressions for the Dr.Memory tool, see -# http://dev.chromium.org/developers/how-tos/using-drmemory - - -# Intended alloc failure -WARNING -name=unittests:fxcrt.FX_AllocOverflow -drmemorylib.dll!replace_calloc -... -*!fxcrt_FX_*AllocOverflow*_Test::TestBody - -# DrMem-i#471: simple floating register copy without meaningful usage -UNINITIALIZED READ -name=embeddertests:DrM-i#471 -*!v8::internal::RegisterValues::GetDoubleRegister -*!v8::internal::FrameDescription::GetDoubleRegister -*!v8::internal::Deoptimizer::CopyDoubleRegisters -*!v8::internal::Deoptimizer::DoComputeCompiledStubFrame -*!v8::internal::Deoptimizer::DoComputeOutputFrames -*!v8::internal::Deoptimizer::ComputeOutputFrames -*!v8::internal::`anonymous namespace'::Invoke -*!v8::internal::Execution::Call - -# PDFium-i#287: new/delete[] mismatch -INVALID HEAP ARGUMENT -name=i#287:new-delete-array-mismatch -drmemorylib.dll!replace_operator_delete_array -*!NumberlikeArray<>::~NumberlikeArray<> diff --git a/xfa/fde/cfde_path.cpp b/xfa/fde/cfde_path.cpp index 23aad5054..5e6cf5cf5 100644 --- a/xfa/fde/cfde_path.cpp +++ b/xfa/fde/cfde_path.cpp @@ -6,70 +6,32 @@ #include "xfa/fde/cfde_path.h" +#include "third_party/base/stl_util.h" #include "xfa/fde/fde_object.h" -bool CFDE_Path::StartFigure() { - return CloseFigure(); -} - -bool CFDE_Path::CloseFigure() { - FX_PATHPOINT* pPoint = GetLastPoint(); - if (pPoint) - pPoint->m_Flag |= FXPT_CLOSEFIGURE; - return true; -} - -FX_PATHPOINT* CFDE_Path::GetLastPoint(int32_t iCount) const { - if (iCount < 1) - return nullptr; - - int32_t iPoints = m_Path.GetPointCount(); - if (iCount > iPoints) - return nullptr; - return m_Path.GetPoints() + iPoints - iCount; +void CFDE_Path::CloseFigure() { + m_Path.ClosePath(); } bool CFDE_Path::FigureClosed() const { - FX_PATHPOINT* pPoint = GetLastPoint(); - return pPoint ? (pPoint->m_Flag & FXPT_CLOSEFIGURE) : true; + const std::vector<FX_PATHPOINT>& points = m_Path.GetPoints(); + return points.empty() ? true : points.back().m_CloseFigure; } -FX_PATHPOINT* CFDE_Path::AddPoints(int32_t iCount) { - if (iCount < 1) - return nullptr; - - int32_t iPoints = m_Path.GetPointCount(); - m_Path.AddPointCount(iCount); - return m_Path.GetPoints() + iPoints; -} - -void CFDE_Path::MoveTo(FX_FLOAT fx, FX_FLOAT fy) { - FX_PATHPOINT* pPoint = AddPoints(1); - pPoint->m_PointX = fx; - pPoint->m_PointY = fy; - pPoint->m_Flag = FXPT_MOVETO; +void CFDE_Path::MoveTo(const CFX_PointF& point) { + m_Path.AppendPoint(point, FXPT_TYPE::MoveTo, false); } -void CFDE_Path::LineTo(FX_FLOAT fx, FX_FLOAT fy) { - FX_PATHPOINT* pPoint = AddPoints(1); - pPoint->m_PointX = fx; - pPoint->m_PointY = fy; - pPoint->m_Flag = FXPT_LINETO; +void CFDE_Path::LineTo(const CFX_PointF& point) { + m_Path.AppendPoint(point, FXPT_TYPE::LineTo, false); } void CFDE_Path::BezierTo(const CFX_PointF& p1, const CFX_PointF& p2, const CFX_PointF& p3) { - FX_PATHPOINT* p = AddPoints(3); - p[0].m_PointX = p1.x; - p[0].m_PointY = p1.y; - p[0].m_Flag = FXPT_BEZIERTO; - p[1].m_PointX = p2.x; - p[1].m_PointY = p2.y; - p[1].m_Flag = FXPT_BEZIERTO; - p[2].m_PointX = p3.x; - p[2].m_PointY = p3.y; - p[2].m_Flag = FXPT_BEZIERTO; + m_Path.AppendPoint(p1, FXPT_TYPE::BezierTo, false); + m_Path.AppendPoint(p2, FXPT_TYPE::BezierTo, false); + m_Path.AppendPoint(p3, FXPT_TYPE::BezierTo, false); } void CFDE_Path::ArcTo(bool bStart, @@ -90,6 +52,7 @@ void CFDE_Path::ArcTo(bool bStart, else alpha -= 2 * FX_PI; } + FX_FLOAT half_delta = (beta - alpha) / 2; FX_FLOAT bcp = 4.0f / 3 * (1 - FXSYS_cos(half_delta)) / FXSYS_sin(half_delta); FX_FLOAT sin_alpha = FXSYS_sin(alpha); @@ -106,39 +69,38 @@ void CFDE_Path::ArcTo(bool bStart, CFX_PointF(cx + rx * cos_beta, cy + ry * sin_beta)); } -void CFDE_Path::AddBezier(const CFX_PointsF& points) { - if (points.GetSize() != 4) +void CFDE_Path::AddBezier(const std::vector<CFX_PointF>& points) { + if (points.size() != 4) return; - const CFX_PointF* p = points.GetData(); - MoveTo(p[0]); - BezierTo(p[1], p[2], p[3]); + MoveTo(points[0]); + BezierTo(points[1], points[2], points[3]); } -void CFDE_Path::AddBeziers(const CFX_PointsF& points) { - int32_t iCount = points.GetSize(); +void CFDE_Path::AddBeziers(const std::vector<CFX_PointF>& points) { + int32_t iCount = points.size(); if (iCount < 4) return; - const CFX_PointF* p = points.GetData(); + const CFX_PointF* p = points.data(); const CFX_PointF* pEnd = p + iCount; MoveTo(p[0]); for (++p; p <= pEnd - 3; p += 3) BezierTo(p[0], p[1], p[2]); } -void CFDE_Path::GetCurveTangents(const CFX_PointsF& points, - CFX_PointsF& tangents, +void CFDE_Path::GetCurveTangents(const std::vector<CFX_PointF>& points, + std::vector<CFX_PointF>* tangents, bool bClosed, FX_FLOAT fTension) const { - int32_t iCount = points.GetSize(); - tangents.SetSize(iCount); + int32_t iCount = pdfium::CollectionSize<int32_t>(points); + tangents->resize(iCount); if (iCount < 3) return; FX_FLOAT fCoefficient = fTension / 3.0f; - const CFX_PointF* pPoints = points.GetData(); - CFX_PointF* pTangents = tangents.GetData(); + const CFX_PointF* pPoints = points.data(); + CFX_PointF* pTangents = tangents->data(); for (int32_t i = 0; i < iCount; ++i) { int32_t r = i + 1; int32_t s = i - 1; @@ -152,17 +114,17 @@ void CFDE_Path::GetCurveTangents(const CFX_PointsF& points, } } -void CFDE_Path::AddCurve(const CFX_PointsF& points, +void CFDE_Path::AddCurve(const std::vector<CFX_PointF>& points, bool bClosed, FX_FLOAT fTension) { - int32_t iLast = points.GetUpperBound(); + int32_t iLast = pdfium::CollectionSize<int32_t>(points) - 1; if (iLast < 1) return; - CFX_PointsF tangents; - GetCurveTangents(points, tangents, bClosed, fTension); - const CFX_PointF* pPoints = points.GetData(); - CFX_PointF* pTangents = tangents.GetData(); + std::vector<CFX_PointF> tangents; + GetCurveTangents(points, &tangents, bClosed, fTension); + const CFX_PointF* pPoints = points.data(); + CFX_PointF* pTangents = tangents.data(); MoveTo(pPoints[0]); for (int32_t i = 0; i < iLast; ++i) { BezierTo(CFX_PointF(pPoints[i].x + pTangents[i].x, @@ -193,9 +155,9 @@ void CFDE_Path::AddEllipse(const CFX_RectF& rect) { } void CFDE_Path::AddLine(const CFX_PointF& pt1, const CFX_PointF& pt2) { - FX_PATHPOINT* pLast = GetLastPoint(); - if (!pLast || FXSYS_fabs(pLast->m_PointX - pt1.x) > 0.001 || - FXSYS_fabs(pLast->m_PointY - pt1.y) > 0.001) { + std::vector<FX_PATHPOINT>& points = m_Path.GetPoints(); + if (points.empty() || FXSYS_fabs(points.back().m_Point.x - pt1.x) > 0.001 || + FXSYS_fabs(points.back().m_Point.y - pt1.y) > 0.001) { MoveTo(pt1); } LineTo(pt2); @@ -205,22 +167,21 @@ void CFDE_Path::AddPath(const CFDE_Path* pSrc, bool bConnect) { if (!pSrc) return; - int32_t iCount = pSrc->m_Path.GetPointCount(); - if (iCount < 1) + if (pSrc->m_Path.GetPoints().empty()) return; if (bConnect) - LineTo(pSrc->m_Path.GetPointX(0), pSrc->m_Path.GetPointY(0)); + LineTo(pSrc->m_Path.GetPoint(0)); m_Path.Append(&pSrc->m_Path, nullptr); } -void CFDE_Path::AddPolygon(const CFX_PointsF& points) { - int32_t iCount = points.GetSize(); +void CFDE_Path::AddPolygon(const std::vector<CFX_PointF>& points) { + size_t iCount = points.size(); if (iCount < 2) return; AddLines(points); - const CFX_PointF* p = points.GetData(); + const CFX_PointF* p = points.data(); if (FXSYS_fabs(p[0].x - p[iCount - 1].x) < 0.01f || FXSYS_fabs(p[0].y - p[iCount - 1].y) < 0.01f) { LineTo(p[0]); @@ -228,12 +189,12 @@ void CFDE_Path::AddPolygon(const CFX_PointsF& points) { CloseFigure(); } -void CFDE_Path::AddLines(const CFX_PointsF& points) { - int32_t iCount = points.GetSize(); +void CFDE_Path::AddLines(const std::vector<CFX_PointF>& points) { + size_t iCount = points.size(); if (iCount < 2) return; - const CFX_PointF* p = points.GetData(); + const CFX_PointF* p = points.data(); const CFX_PointF* pEnd = p + iCount; MoveTo(p[0]); for (++p; p < pEnd; ++p) @@ -248,16 +209,16 @@ void CFDE_Path::AddRectangle(const CFX_RectF& rect) { CloseFigure(); } -void CFDE_Path::GetBBox(CFX_RectF& bbox) const { +CFX_RectF CFDE_Path::GetBBox() const { CFX_FloatRect rect = m_Path.GetBoundingBox(); - bbox.Set(rect.left, rect.top, rect.Width(), rect.Height()); + CFX_RectF bbox = CFX_RectF(rect.left, rect.top, rect.Width(), rect.Height()); bbox.Normalize(); + return bbox; } -void CFDE_Path::GetBBox(CFX_RectF& bbox, - FX_FLOAT fLineWidth, - FX_FLOAT fMiterLimit) const { +CFX_RectF CFDE_Path::GetBBox(FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const { CFX_FloatRect rect = m_Path.GetBoundingBox(fLineWidth, fMiterLimit); - bbox.Set(rect.left, rect.top, rect.Width(), rect.Height()); + CFX_RectF bbox = CFX_RectF(rect.left, rect.top, rect.Width(), rect.Height()); bbox.Normalize(); + return bbox; } diff --git a/xfa/fde/cfde_path.h b/xfa/fde/cfde_path.h index 936a5c8a7..99ff4d368 100644 --- a/xfa/fde/cfde_path.h +++ b/xfa/fde/cfde_path.h @@ -7,34 +7,31 @@ #ifndef XFA_FDE_CFDE_PATH_H_ #define XFA_FDE_CFDE_PATH_H_ +#include <vector> + #include "core/fxge/cfx_pathdata.h" #include "core/fxge/cfx_renderdevice.h" class CFDE_Path { public: - bool StartFigure(); - bool CloseFigure(); + void CloseFigure(); - void AddBezier(const CFX_PointsF& points); - void AddBeziers(const CFX_PointsF& points); - void AddCurve(const CFX_PointsF& points, + void AddBezier(const std::vector<CFX_PointF>& points); + void AddBeziers(const std::vector<CFX_PointF>& points); + void AddCurve(const std::vector<CFX_PointF>& points, bool bClosed, FX_FLOAT fTension = 0.5f); void AddEllipse(const CFX_RectF& rect); - void AddLines(const CFX_PointsF& points); + void AddLines(const std::vector<CFX_PointF>& points); void AddLine(const CFX_PointF& pt1, const CFX_PointF& pt2); void AddPath(const CFDE_Path* pSrc, bool bConnect); - void AddPolygon(const CFX_PointsF& points); + void AddPolygon(const std::vector<CFX_PointF>& points); void AddRectangle(const CFX_RectF& rect); - void GetBBox(CFX_RectF& bbox) const; - void GetBBox(CFX_RectF& bbox, - FX_FLOAT fLineWidth, - FX_FLOAT fMiterLimit) const; - FX_PATHPOINT* AddPoints(int32_t iCount); - FX_PATHPOINT* GetLastPoint(int32_t iCount = 1) const; + + CFX_RectF GetBBox() const; + CFX_RectF GetBBox(FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const; + bool FigureClosed() const; - void MoveTo(FX_FLOAT fx, FX_FLOAT fy); - void LineTo(FX_FLOAT fx, FX_FLOAT fy); void BezierTo(const CFX_PointF& p1, const CFX_PointF& p2, const CFX_PointF& p3); @@ -42,10 +39,11 @@ class CFDE_Path { const CFX_RectF& rect, FX_FLOAT startAngle, FX_FLOAT endAngle); - void MoveTo(const CFX_PointF& p0) { MoveTo(p0.x, p0.y); } - void LineTo(const CFX_PointF& p1) { LineTo(p1.x, p1.y); } - void GetCurveTangents(const CFX_PointsF& points, - CFX_PointsF& tangents, + void MoveTo(const CFX_PointF& p); + void LineTo(const CFX_PointF& p); + + void GetCurveTangents(const std::vector<CFX_PointF>& points, + std::vector<CFX_PointF>* tangents, bool bClosed, FX_FLOAT fTension) const; CFX_PathData m_Path; diff --git a/xfa/fde/cfde_txtedtengine.cpp b/xfa/fde/cfde_txtedtengine.cpp index 7ef6b3ff0..a61f6ab4d 100644 --- a/xfa/fde/cfde_txtedtengine.cpp +++ b/xfa/fde/cfde_txtedtengine.cpp @@ -69,7 +69,6 @@ CFDE_TxtEdtEngine::CFDE_TxtEdtEngine() m_nFirstLineEnd(FDE_TXTEDIT_LINEEND_Auto), m_bAutoLineEnd(true), m_wLineEnd(kUnicodeParagraphSeparator) { - FXSYS_memset(&m_rtCaret, 0, sizeof(CFX_RectF)); m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto); } @@ -663,14 +662,14 @@ int32_t CFDE_TxtEdtEngine::DoLayout(IFX_Pause* pPause) { void CFDE_TxtEdtEngine::EndLayout() { UpdatePages(); int32_t nLength = GetTextLength(); - if (m_nCaret > nLength) { + if (m_nCaret > nLength) m_nCaret = nLength; - } + int32_t nIndex = m_nCaret; - if (!m_bBefore) { + if (!m_bBefore) nIndex--; - } - m_rtCaret.Set(0, 0, 1, m_Param.fFontSize); + + m_rtCaret = CFX_RectF(0, 0, 1, m_Param.fFontSize); Unlock(); } @@ -1381,12 +1380,11 @@ bool CFDE_TxtEdtEngine::IsFitArea(CFX_WideString& wsText) { pTextOut->SetLineSpace(m_Param.fLineSpace); pTextOut->SetFont(m_Param.pFont); pTextOut->SetFontSize(m_Param.fFontSize); - CFX_RectF rcText; - FXSYS_memset(&rcText, 0, sizeof(rcText)); uint32_t dwStyle = 0; if (!(m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines)) dwStyle |= FDE_TTOSTYLE_SingleLine; + CFX_RectF rcText; if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) { dwStyle |= FDE_TTOSTYLE_LineWrap; rcText.width = m_Param.fPlateWidth; diff --git a/xfa/fde/cfde_txtedtpage.cpp b/xfa/fde/cfde_txtedtpage.cpp index 238dba2bc..8b58b2b44 100644 --- a/xfa/fde/cfde_txtedtpage.cpp +++ b/xfa/fde/cfde_txtedtpage.cpp @@ -9,6 +9,7 @@ #include <algorithm> #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fde/cfde_txtedtbuf.h" #include "xfa/fde/cfde_txtedtengine.h" #include "xfa/fde/cfde_txtedtparag.h" @@ -30,7 +31,6 @@ IFDE_TxtEdtPage* IFDE_TxtEdtPage::Create(CFDE_TxtEdtEngine* pEngine, CFDE_TxtEdtPage::CFDE_TxtEdtPage(CFDE_TxtEdtEngine* pEngine, int32_t nPageIndex) : m_pEditEngine(pEngine), - m_PieceMassArr(100), m_pBgnParag(nullptr), m_pEndParag(nullptr), m_nRefCount(0), @@ -38,15 +38,9 @@ CFDE_TxtEdtPage::CFDE_TxtEdtPage(CFDE_TxtEdtEngine* pEngine, int32_t nPageIndex) m_nCharCount(0), m_nPageIndex(nPageIndex), m_bLoaded(false) { - FXSYS_memset(&m_rtPage, 0, sizeof(CFX_RectF)); - FXSYS_memset(&m_rtPageMargin, 0, sizeof(CFX_RectF)); - FXSYS_memset(&m_rtPageContents, 0, sizeof(CFX_RectF)); - FXSYS_memset(&m_rtPageCanvas, 0, sizeof(CFX_RectF)); } -CFDE_TxtEdtPage::~CFDE_TxtEdtPage() { - m_PieceMassArr.RemoveAll(true); -} +CFDE_TxtEdtPage::~CFDE_TxtEdtPage() {} CFDE_TxtEdtEngine* CFDE_TxtEdtPage::GetEngine() const { return m_pEditEngine; @@ -56,25 +50,23 @@ FDE_VISUALOBJTYPE CFDE_TxtEdtPage::GetType() { return FDE_VISUALOBJ_Text; } -void CFDE_TxtEdtPage::GetRect(FDE_TEXTEDITPIECE* hVisualObj, CFX_RectF& rt) {} +CFX_RectF CFDE_TxtEdtPage::GetRect(const FDE_TEXTEDITPIECE& hVisualObj) { + return CFX_RectF(); +} int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex, CFX_RectF& rect, bool bBBox) const { ASSERT(m_nRefCount > 0); ASSERT(nIndex >= 0 && nIndex < m_nCharCount); - if (m_nRefCount < 1) { + if (m_nRefCount < 1) return 0; - } - int32_t nCount = m_PieceMassArr.GetSize(); - for (int32_t i = 0; i < nCount; i++) { - const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); - if (nIndex >= pPiece->nStart && - nIndex < (pPiece->nStart + pPiece->nCount)) { - CFX_RectFArray rectArr; - m_pTextSet->GetCharRects(pPiece, rectArr, bBBox); - rect = rectArr[nIndex - pPiece->nStart]; - return pPiece->nBidiLevel; + + for (const auto& piece : m_Pieces) { + if (nIndex >= piece.nStart && nIndex < piece.nStart + piece.nCount) { + std::vector<CFX_RectF> rectArr = m_pTextSet->GetCharRects(&piece, bBBox); + rect = rectArr[nIndex - piece.nStart]; + return piece.nBidiLevel; } } ASSERT(0); @@ -84,14 +76,14 @@ int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex, int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint, bool& bBefore) { CFX_PointF ptF = fPoint; NormalizePt2Rect(ptF, m_rtPageContents, kTolerance); - int32_t nCount = m_PieceMassArr.GetSize(); + int32_t nCount = pdfium::CollectionSize<int32_t>(m_Pieces); CFX_RectF rtLine; int32_t nBgn = 0; int32_t nEnd = 0; bool bInLine = false; int32_t i = 0; for (i = 0; i < nCount; i++) { - const FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); + const FDE_TEXTEDITPIECE* pPiece = &m_Pieces[i]; if (!bInLine && (pPiece->rtPiece.top <= ptF.y && pPiece->rtPiece.bottom() > ptF.y)) { nBgn = nEnd = i; @@ -110,12 +102,11 @@ int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint, bool& bBefore) { int32_t nCaret = 0; FDE_TEXTEDITPIECE* pPiece = nullptr; for (i = nBgn; i <= nEnd; i++) { - pPiece = m_PieceMassArr.GetPtrAt(i); + pPiece = &m_Pieces[i]; nCaret = m_nPageStart + pPiece->nStart; if (pPiece->rtPiece.Contains(ptF)) { - CFX_RectFArray rectArr; - m_pTextSet->GetCharRects(pPiece, rectArr, false); - int32_t nRtCount = rectArr.GetSize(); + std::vector<CFX_RectF> rectArr = m_pTextSet->GetCharRects(pPiece, false); + int32_t nRtCount = pdfium::CollectionSize<int32_t>(rectArr); for (int32_t j = 0; j < nRtCount; j++) { if (rectArr[j].Contains(ptF)) { nCaret = m_nPageStart + pPiece->nStart + j; @@ -161,17 +152,12 @@ int32_t CFDE_TxtEdtPage::GetDisplayPos(const CFX_RectF& rtClip, CFX_RectF* pBBox) const { pCharPos = FX_Alloc(FXTEXT_CHARPOS, m_nCharCount); int32_t nCharPosCount = 0; - FDE_TEXTEDITPIECE* pPiece = nullptr; - int32_t nVisualObjCount = m_PieceMassArr.GetSize(); FXTEXT_CHARPOS* pos = pCharPos; - CFX_RectF rtObj; - for (int32_t i = 0; i < nVisualObjCount; i++) { - pPiece = m_PieceMassArr.GetPtrAt(i); - m_pTextSet->GetRect(pPiece, rtObj); - if (!rtClip.IntersectWith(rtObj)) { + for (const auto& piece : m_Pieces) { + if (!rtClip.IntersectWith(m_pTextSet->GetRect(piece))) continue; - } - int32_t nCount = m_pTextSet->GetDisplayPos(pPiece, pos, false); + + int32_t nCount = m_pTextSet->GetDisplayPos(piece, pos, false); nCharPosCount += nCount; pos += nCount; } @@ -184,42 +170,39 @@ int32_t CFDE_TxtEdtPage::GetDisplayPos(const CFX_RectF& rtClip, return nCharPosCount; } -void CFDE_TxtEdtPage::CalcRangeRectArray(int32_t nStart, - int32_t nCount, - CFX_RectFArray& RectFArr) const { - int32_t nPieceCount = m_PieceMassArr.GetSize(); +void CFDE_TxtEdtPage::CalcRangeRectArray( + int32_t nStart, + int32_t nCount, + std::vector<CFX_RectF>* pRectFArr) const { int32_t nEnd = nStart + nCount - 1; bool bInRange = false; - for (int32_t i = 0; i < nPieceCount; i++) { - FDE_TEXTEDITPIECE* piece = m_PieceMassArr.GetPtrAt(i); + for (const auto& piece : m_Pieces) { if (!bInRange) { - if (nStart >= piece->nStart && nStart < (piece->nStart + piece->nCount)) { - int32_t nRangeEnd = piece->nCount - 1; + if (nStart >= piece.nStart && nStart < piece.nStart + piece.nCount) { + int32_t nRangeEnd = piece.nCount - 1; bool bEnd = false; - if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) { - nRangeEnd = nEnd - piece->nStart; + if (nEnd >= piece.nStart && nEnd < piece.nStart + piece.nCount) { + nRangeEnd = nEnd - piece.nStart; bEnd = true; } - CFX_RectFArray rcArr; - m_pTextSet->GetCharRects(piece, rcArr, false); - CFX_RectF rectPiece = rcArr[nStart - piece->nStart]; + std::vector<CFX_RectF> rcArr = m_pTextSet->GetCharRects(&piece, false); + CFX_RectF rectPiece = rcArr[nStart - piece.nStart]; rectPiece.Union(rcArr[nRangeEnd]); - RectFArr.Add(rectPiece); - if (bEnd) { + pRectFArr->push_back(rectPiece); + if (bEnd) return; - } + bInRange = true; } } else { - if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) { - CFX_RectFArray rcArr; - m_pTextSet->GetCharRects(piece, rcArr, false); + if (nEnd >= piece.nStart && nEnd < piece.nStart + piece.nCount) { + std::vector<CFX_RectF> rcArr = m_pTextSet->GetCharRects(&piece, false); CFX_RectF rectPiece = rcArr[0]; - rectPiece.Union(rcArr[nEnd - piece->nStart]); - RectFArr.Add(rectPiece); + rectPiece.Union(rcArr[nEnd - piece.nStart]); + pRectFArr->push_back(rectPiece); return; } - RectFArr.Add(piece->rtPiece); + pRectFArr->push_back(piece.rtPiece); } } } @@ -290,7 +273,7 @@ int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox, if (!m_pTextSet) m_pTextSet = pdfium::MakeUnique<CFDE_TxtEdtTextSet>(this); - m_PieceMassArr.RemoveAll(true); + m_Pieces.clear(); uint32_t dwBreakStatus = FX_TXTBREAK_None; int32_t nPieceStart = 0; @@ -364,7 +347,7 @@ int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox, m_rtPageContents.Union(TxtEdtPiece.rtPiece); } nPieceStart += TxtEdtPiece.nCount; - m_PieceMassArr.Add(TxtEdtPiece); + m_Pieces.push_back(TxtEdtPiece); for (int32_t k = 0; k < TxtEdtPiece.nCount; k++) { CFX_Char* ptc = pPiece->GetCharPtr(k); m_CharWidths[TxtEdtPiece.nStart + k] = ptc->m_iCharWidth; @@ -395,19 +378,15 @@ int32_t CFDE_TxtEdtPage::LoadPage(const CFX_RectF* pClipBox, } } FX_FLOAT fOffset = m_rtPageContents.left - fDelta; - int32_t nCount = m_PieceMassArr.GetSize(); - for (int32_t i = 0; i < nCount; i++) { - FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(i); - pPiece->rtPiece.Offset(-fOffset, 0.0f); - } + for (auto& piece : m_Pieces) + piece.rtPiece.Offset(-fOffset, 0.0f); + m_rtPageContents.Offset(-fOffset, 0.0f); } if (m_pEditEngine->GetEditParams()->dwLayoutStyles & FDE_TEXTEDITLAYOUT_LastLineHeight) { m_rtPageContents.height -= pParams->fLineSpace - pParams->fFontSize; - int32_t nCount = m_PieceMassArr.GetSize(); - FDE_TEXTEDITPIECE* pPiece = m_PieceMassArr.GetPtrAt(nCount - 1); - pPiece->rtPiece.height = pParams->fFontSize; + m_Pieces.back().rtPiece.height = pParams->fFontSize; } m_nRefCount = 1; m_bLoaded = true; @@ -420,7 +399,7 @@ void CFDE_TxtEdtPage::UnloadPage(const CFX_RectF* pClipBox) { if (m_nRefCount != 0) return; - m_PieceMassArr.RemoveAll(false); + m_Pieces.clear(); m_pTextSet.reset(); m_CharWidths.clear(); if (m_pBgnParag) { @@ -439,7 +418,7 @@ const CFX_RectF& CFDE_TxtEdtPage::GetContentsBox() { } FX_POSITION CFDE_TxtEdtPage::GetFirstPosition() { - if (m_PieceMassArr.GetSize() < 1) + if (m_Pieces.empty()) return nullptr; return (FX_POSITION)1; } @@ -452,20 +431,20 @@ FDE_TEXTEDITPIECE* CFDE_TxtEdtPage::GetNext(FX_POSITION& pos, } int32_t nPos = (int32_t)(uintptr_t)pos; pVisualSet = m_pTextSet.get(); - if (nPos + 1 > m_PieceMassArr.GetSize()) { + if (nPos + 1 > pdfium::CollectionSize<int32_t>(m_Pieces)) pos = nullptr; - } else { + else pos = (FX_POSITION)(uintptr_t)(nPos + 1); - } - return m_PieceMassArr.GetPtrAt(nPos - 1); + + return &m_Pieces[nPos - 1]; } FX_WCHAR CFDE_TxtEdtPage::GetChar(const FDE_TEXTEDITPIECE* pIdentity, int32_t index) const { int32_t nIndex = m_nPageStart + pIdentity->nStart + index; - if (nIndex != m_pIter->GetAt()) { + if (nIndex != m_pIter->GetAt()) m_pIter->SetAt(nIndex); - } + FX_WCHAR wChar = m_pIter->GetChar(); m_pIter->Next(); return wChar; @@ -480,17 +459,15 @@ int32_t CFDE_TxtEdtPage::GetWidth(const FDE_TEXTEDITPIECE* pIdentity, void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF& ptF, const CFX_RectF& rtF, FX_FLOAT fTolerance) const { - if (rtF.Contains(ptF.x, ptF.y)) { + if (rtF.Contains(ptF)) return; - } - if (ptF.x < rtF.left) { + if (ptF.x < rtF.left) ptF.x = rtF.left; - } else if (ptF.x >= rtF.right()) { + else if (ptF.x >= rtF.right()) ptF.x = rtF.right() - fTolerance; - } - if (ptF.y < rtF.top) { + + if (ptF.y < rtF.top) ptF.y = rtF.top; - } else if (ptF.y >= rtF.bottom()) { + else if (ptF.y >= rtF.bottom()) ptF.y = rtF.bottom() - fTolerance; - } } diff --git a/xfa/fde/cfde_txtedtpage.h b/xfa/fde/cfde_txtedtpage.h index 5cb4501af..63ec7e7cf 100644 --- a/xfa/fde/cfde_txtedtpage.h +++ b/xfa/fde/cfde_txtedtpage.h @@ -7,6 +7,7 @@ #ifndef XFA_FDE_CFDE_TXTEDTPAGE_H_ #define XFA_FDE_CFDE_TXTEDTPAGE_H_ +#include <deque> #include <memory> #include <vector> @@ -30,7 +31,7 @@ class CFDE_TxtEdtPage : public IFDE_TxtEdtPage { int32_t GetCharIndex(const CFX_PointF& fPoint, bool& bBefore) override; void CalcRangeRectArray(int32_t nStart, int32_t nCount, - CFX_RectFArray& RectFArr) const override; + std::vector<CFX_RectF>* RectFArr) const override; int32_t SelectWord(const CFX_PointF& fPoint, int32_t& nCount) override; int32_t GetCharStart() const override; int32_t GetCharCount() const override; @@ -44,7 +45,7 @@ class CFDE_TxtEdtPage : public IFDE_TxtEdtPage { // IFDE_VisualSet: FDE_VISUALOBJTYPE GetType() override; - void GetRect(FDE_TEXTEDITPIECE* pPiece, CFX_RectF& rt) override; + CFX_RectF GetRect(const FDE_TEXTEDITPIECE& pPiece) override; // IFDE_CanvasSet: FX_POSITION GetFirstPosition() override; @@ -65,7 +66,7 @@ class CFDE_TxtEdtPage : public IFDE_TxtEdtPage { std::unique_ptr<IFX_CharIter> m_pIter; std::unique_ptr<CFDE_TxtEdtTextSet> m_pTextSet; CFDE_TxtEdtEngine* const m_pEditEngine; - CFX_MassArrayTemplate<FDE_TEXTEDITPIECE> m_PieceMassArr; + std::deque<FDE_TEXTEDITPIECE> m_Pieces; CFDE_TxtEdtParag* m_pBgnParag; CFDE_TxtEdtParag* m_pEndParag; int32_t m_nRefCount; diff --git a/xfa/fde/cfde_txtedttextset.cpp b/xfa/fde/cfde_txtedttextset.cpp index 4149a6df2..8d32f75ff 100644 --- a/xfa/fde/cfde_txtedttextset.cpp +++ b/xfa/fde/cfde_txtedttextset.cpp @@ -19,8 +19,8 @@ FDE_VISUALOBJTYPE CFDE_TxtEdtTextSet::GetType() { return FDE_VISUALOBJ_Text; } -void CFDE_TxtEdtTextSet::GetRect(FDE_TEXTEDITPIECE* pPiece, CFX_RectF& rt) { - rt = pPiece->rtPiece; +CFX_RectF CFDE_TxtEdtTextSet::GetRect(const FDE_TEXTEDITPIECE& pPiece) { + return pPiece.rtPiece; } int32_t CFDE_TxtEdtTextSet::GetString(FDE_TEXTEDITPIECE* pPiece, @@ -45,14 +45,11 @@ FX_ARGB CFDE_TxtEdtTextSet::GetFontColor() { return m_pPage->GetEngine()->GetEditParams()->dwFontColor; } -int32_t CFDE_TxtEdtTextSet::GetDisplayPos(FDE_TEXTEDITPIECE* pPiece, +int32_t CFDE_TxtEdtTextSet::GetDisplayPos(const FDE_TEXTEDITPIECE& piece, FXTEXT_CHARPOS* pCharPos, bool bCharCode, CFX_WideString* pWSForms) { - if (!pPiece) - return 0; - - int32_t nLength = pPiece->nCount; + int32_t nLength = piece.nCount; if (nLength < 1) return 0; @@ -63,42 +60,37 @@ int32_t CFDE_TxtEdtTextSet::GetDisplayPos(FDE_TEXTEDITPIECE* pPiece, uint32_t dwLayoutStyle = pBreak->GetLayoutStyles(); FX_TXTRUN tr; tr.pAccess = m_pPage; - tr.pIdentity = pPiece; + tr.pIdentity = &piece; tr.iLength = nLength; tr.pFont = pTextParams->pFont; tr.fFontSize = pTextParams->fFontSize; tr.dwStyles = dwLayoutStyle; tr.iCharRotation = pTextParams->nCharRotation; - tr.dwCharStyles = pPiece->dwCharStyles; - tr.pRect = &(pPiece->rtPiece); + tr.dwCharStyles = piece.dwCharStyles; + tr.pRect = &piece.rtPiece; tr.wLineBreakChar = pTextParams->wLineBreakChar; return pBreak->GetDisplayPos(&tr, pCharPos, bCharCode, pWSForms); } -int32_t CFDE_TxtEdtTextSet::GetCharRects(const FDE_TEXTEDITPIECE* pPiece, - CFX_RectFArray& rtArray, - bool bBBox) { - if (!pPiece) - return 0; - - CFDE_TxtEdtEngine* pEngine = - static_cast<CFDE_TxtEdtEngine*>(m_pPage->GetEngine()); - int32_t nLength = pPiece->nCount; - if (nLength < 1) - return 0; +std::vector<CFX_RectF> CFDE_TxtEdtTextSet::GetCharRects( + const FDE_TEXTEDITPIECE* pPiece, + bool bBBox) { + if (!pPiece || pPiece->nCount < 1) + return std::vector<CFX_RectF>(); + auto pEngine = static_cast<CFDE_TxtEdtEngine*>(m_pPage->GetEngine()); const FDE_TXTEDTPARAMS* pTextParams = pEngine->GetEditParams(); uint32_t dwLayoutStyle = pEngine->GetTextBreak()->GetLayoutStyles(); FX_TXTRUN tr; tr.pAccess = m_pPage; tr.pIdentity = pPiece; - tr.iLength = nLength; + tr.iLength = pPiece->nCount; tr.pFont = pTextParams->pFont; tr.fFontSize = pTextParams->fFontSize; tr.dwStyles = dwLayoutStyle; tr.iCharRotation = pTextParams->nCharRotation; tr.dwCharStyles = pPiece->dwCharStyles; - tr.pRect = &(pPiece->rtPiece); + tr.pRect = &pPiece->rtPiece; tr.wLineBreakChar = pTextParams->wLineBreakChar; - return pEngine->GetTextBreak()->GetCharRects(&tr, rtArray, bBBox); + return pEngine->GetTextBreak()->GetCharRects(&tr, bBBox); } diff --git a/xfa/fde/cfde_txtedttextset.h b/xfa/fde/cfde_txtedttextset.h index 6c6266642..8ab657879 100644 --- a/xfa/fde/cfde_txtedttextset.h +++ b/xfa/fde/cfde_txtedttextset.h @@ -7,6 +7,8 @@ #ifndef XFA_FDE_CFDE_TXTEDTTEXTSET_H_ #define XFA_FDE_CFDE_TXTEDTTEXTSET_H_ +#include <vector> + #include "xfa/fde/fde_visualset.h" class CFDE_TxtEdtPage; @@ -18,20 +20,19 @@ class CFDE_TxtEdtTextSet : public IFDE_TextSet { // IFDE_VisualSet FDE_VISUALOBJTYPE GetType() override; - void GetRect(FDE_TEXTEDITPIECE* hVisualObj, CFX_RectF& rt) override; + CFX_RectF GetRect(const FDE_TEXTEDITPIECE& hVisualObj) override; // IFDE_TextSet int32_t GetString(FDE_TEXTEDITPIECE* pPiece, CFX_WideString& wsText) override; CFX_RetainPtr<CFGAS_GEFont> GetFont() override; FX_FLOAT GetFontSize() override; FX_ARGB GetFontColor() override; - int32_t GetDisplayPos(FDE_TEXTEDITPIECE* pPiece, + int32_t GetDisplayPos(const FDE_TEXTEDITPIECE& pPiece, FXTEXT_CHARPOS* pCharPos, bool bCharCode = false, CFX_WideString* pWSForms = nullptr) override; - int32_t GetCharRects(const FDE_TEXTEDITPIECE* pPiece, - CFX_RectFArray& rtArray, - bool bBBox) override; + std::vector<CFX_RectF> GetCharRects(const FDE_TEXTEDITPIECE* pPiece, + bool bBBox) override; private: CFDE_TxtEdtPage* const m_pPage; diff --git a/xfa/fde/css/cfde_cssaccelerator.cpp b/xfa/fde/css/cfde_cssaccelerator.cpp deleted file mode 100644 index 40fa13e05..000000000 --- a/xfa/fde/css/cfde_cssaccelerator.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 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 "xfa/fde/css/cfde_cssaccelerator.h" - -#include "third_party/base/ptr_util.h" - -CFDE_CSSAccelerator::CFDE_CSSAccelerator() {} - -CFDE_CSSAccelerator::~CFDE_CSSAccelerator() {} - -void CFDE_CSSAccelerator::OnEnterTag(CXFA_CSSTagProvider* pTag) { - stack_.push(pdfium::MakeUnique<CFDE_CSSTagCache>(top(), pTag)); -} - -void CFDE_CSSAccelerator::OnLeaveTag(CXFA_CSSTagProvider* pTag) { - ASSERT(!stack_.empty()); - ASSERT(stack_.top()->GetTag() == pTag); - stack_.pop(); -} diff --git a/xfa/fde/css/cfde_cssaccelerator.h b/xfa/fde/css/cfde_cssaccelerator.h deleted file mode 100644 index 4ef493d79..000000000 --- a/xfa/fde/css/cfde_cssaccelerator.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2017 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 XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_ -#define XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_ - -#include <memory> -#include <stack> - -#include "xfa/fde/css/cfde_csstagcache.h" - -class CXFA_CSSTagProvider; - -class CFDE_CSSAccelerator { - public: - CFDE_CSSAccelerator(); - ~CFDE_CSSAccelerator(); - - void OnEnterTag(CXFA_CSSTagProvider* pTag); - void OnLeaveTag(CXFA_CSSTagProvider* pTag); - - void Clear() { - std::stack<std::unique_ptr<CFDE_CSSTagCache>> tmp; - stack_.swap(tmp); - } - - CFDE_CSSTagCache* top() const { - if (stack_.empty()) - return nullptr; - return stack_.top().get(); - } - - private: - std::stack<std::unique_ptr<CFDE_CSSTagCache>> stack_; -}; - -#endif // XFA_FDE_CSS_CFDE_CSSACCELERATOR_H_ diff --git a/xfa/fde/css/cfde_csscomputedstyle.cpp b/xfa/fde/css/cfde_csscomputedstyle.cpp index 010f573c0..01872d18f 100644 --- a/xfa/fde/css/cfde_csscomputedstyle.cpp +++ b/xfa/fde/css/cfde_csscomputedstyle.cpp @@ -10,27 +10,16 @@ #include "xfa/fde/css/cfde_cssstringvalue.h" #include "xfa/fde/css/cfde_cssvaluelist.h" -CFDE_CSSComputedStyle::CFDE_CSSComputedStyle() : m_dwRefCount(1) {} +CFDE_CSSComputedStyle::CFDE_CSSComputedStyle() {} CFDE_CSSComputedStyle::~CFDE_CSSComputedStyle() {} -uint32_t CFDE_CSSComputedStyle::Retain() { - return ++m_dwRefCount; -} - -uint32_t CFDE_CSSComputedStyle::Release() { - uint32_t dwRefCount = --m_dwRefCount; - if (dwRefCount == 0) - delete this; - return dwRefCount; -} - -bool CFDE_CSSComputedStyle::GetCustomStyle(const CFX_WideStringC& wsName, +bool CFDE_CSSComputedStyle::GetCustomStyle(const CFX_WideString& wsName, CFX_WideString& wsValue) const { - for (int32_t i = pdfium::CollectionSize<int32_t>(m_CustomProperties) - 2; - i > -1; i -= 2) { - if (wsName == m_CustomProperties[i]) { - wsValue = m_CustomProperties[i + 1]; + for (auto iter = m_CustomProperties.rbegin(); + iter != m_CustomProperties.rend(); iter++) { + if (wsName == iter->name()) { + wsValue = iter->value(); return true; } } @@ -44,8 +33,8 @@ int32_t CFDE_CSSComputedStyle::CountFontFamilies() const { } const CFX_WideString CFDE_CSSComputedStyle::GetFontFamily(int32_t index) const { - return static_cast<CFDE_CSSStringValue*>( - m_InheritedData.m_pFontFamily->GetValue(index)) + return m_InheritedData.m_pFontFamily->GetValue(index) + .As<CFDE_CSSStringValue>() ->Value(); } @@ -172,10 +161,10 @@ void CFDE_CSSComputedStyle::SetLetterSpacing( m_InheritedData.m_LetterSpacing = letterSpacing; } -void CFDE_CSSComputedStyle::AddCustomStyle(const CFX_WideString& wsName, - const CFX_WideString& wsValue) { - m_CustomProperties.push_back(wsName); - m_CustomProperties.push_back(wsValue); +void CFDE_CSSComputedStyle::AddCustomStyle(const CFDE_CSSCustomProperty& prop) { + // Force the property to be copied so we aren't dependent on the lifetime + // of whatever currently owns it. + m_CustomProperties.push_back(prop); } CFDE_CSSComputedStyle::InheritedData::InheritedData() @@ -191,6 +180,8 @@ CFDE_CSSComputedStyle::InheritedData::InheritedData() m_eFontStyle(FDE_CSSFontStyle::Normal), m_eTextAlign(FDE_CSSTextAlign::Left) {} +CFDE_CSSComputedStyle::InheritedData::~InheritedData() {} + CFDE_CSSComputedStyle::NonInheritedData::NonInheritedData() : m_MarginWidth(FDE_CSSLengthUnit::Point, 0), m_BorderWidth(FDE_CSSLengthUnit::Point, 0), diff --git a/xfa/fde/css/cfde_csscomputedstyle.h b/xfa/fde/css/cfde_csscomputedstyle.h index 73eb996f0..bba4ccbcd 100644 --- a/xfa/fde/css/cfde_csscomputedstyle.h +++ b/xfa/fde/css/cfde_csscomputedstyle.h @@ -11,20 +11,22 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_string.h" +#include "xfa/fde/css/cfde_csscustomproperty.h" #include "xfa/fde/css/fde_css.h" class CFDE_CSSValueList; -class CFDE_CSSComputedStyle : public IFX_Retainable { +class CFDE_CSSComputedStyle : public CFX_Retainable { public: class InheritedData { public: InheritedData(); + ~InheritedData(); FDE_CSSLength m_LetterSpacing; FDE_CSSLength m_WordSpacing; FDE_CSSLength m_TextIndent; - CFDE_CSSValueList* m_pFontFamily; + CFX_RetainPtr<CFDE_CSSValueList> m_pFontFamily; FX_FLOAT m_fFontSize; FX_FLOAT m_fLineHeight; FX_ARGB m_dwFontColor; @@ -54,13 +56,6 @@ class CFDE_CSSComputedStyle : public IFX_Retainable { bool m_bHasPadding; }; - CFDE_CSSComputedStyle(); - ~CFDE_CSSComputedStyle() override; - - // IFX_Retainable - uint32_t Retain() override; - uint32_t Release() override; - int32_t CountFontFamilies() const; const CFX_WideString GetFontFamily(int32_t index) const; uint16_t GetFontWeight() const; @@ -95,18 +90,22 @@ class CFDE_CSSComputedStyle : public IFX_Retainable { void SetNumberVerticalAlign(FX_FLOAT fAlign); void SetTextDecoration(uint32_t dwTextDecoration); void SetLetterSpacing(const FDE_CSSLength& letterSpacing); - void AddCustomStyle(const CFX_WideString& wsName, - const CFX_WideString& wsValue); + void AddCustomStyle(const CFDE_CSSCustomProperty& prop); - bool GetCustomStyle(const CFX_WideStringC& wsName, + bool GetCustomStyle(const CFX_WideString& wsName, CFX_WideString& wsValue) const; InheritedData m_InheritedData; NonInheritedData m_NonInheritedData; private: - uint32_t m_dwRefCount; - std::vector<CFX_WideString> m_CustomProperties; + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); + + CFDE_CSSComputedStyle(); + ~CFDE_CSSComputedStyle() override; + + std::vector<CFDE_CSSCustomProperty> m_CustomProperties; }; #endif // XFA_FDE_CSS_CFDE_CSSCOMPUTEDSTYLE_H_ diff --git a/xfa/fde/css/cfde_csscustomproperty.cpp b/xfa/fde/css/cfde_csscustomproperty.cpp new file mode 100644 index 000000000..92b288eb4 --- /dev/null +++ b/xfa/fde/css/cfde_csscustomproperty.cpp @@ -0,0 +1,15 @@ +// Copyright 2017 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 "xfa/fde/css/cfde_csscustomproperty.h" + +CFDE_CSSCustomProperty::CFDE_CSSCustomProperty(const CFX_WideString& name, + const CFX_WideString& value) + : name_(name), value_(value) {} + +CFDE_CSSCustomProperty::CFDE_CSSCustomProperty( + const CFDE_CSSCustomProperty& prop) + : name_(prop.name_), value_(prop.value_) {} + +CFDE_CSSCustomProperty::~CFDE_CSSCustomProperty() {} diff --git a/xfa/fde/css/cfde_csscustomproperty.h b/xfa/fde/css/cfde_csscustomproperty.h index 6e99630e1..6970d49cb 100644 --- a/xfa/fde/css/cfde_csscustomproperty.h +++ b/xfa/fde/css/cfde_csscustomproperty.h @@ -11,8 +11,17 @@ class CFDE_CSSCustomProperty { public: - const FX_WCHAR* pwsName; - const FX_WCHAR* pwsValue; + CFDE_CSSCustomProperty(const CFX_WideString& name, + const CFX_WideString& value); + CFDE_CSSCustomProperty(const CFDE_CSSCustomProperty& prop); + ~CFDE_CSSCustomProperty(); + + CFX_WideString name() const { return name_; } + CFX_WideString value() const { return value_; } + + private: + CFX_WideString name_; + CFX_WideString value_; }; #endif // XFA_FDE_CSS_CFDE_CSSCUSTOMPROPERTY_H_ diff --git a/xfa/fde/css/cfde_cssdeclaration.cpp b/xfa/fde/css/cfde_cssdeclaration.cpp index 4ed20eb0c..3c776ca77 100644 --- a/xfa/fde/css/cfde_cssdeclaration.cpp +++ b/xfa/fde/css/cfde_cssdeclaration.cpp @@ -133,39 +133,18 @@ CFDE_CSSDeclaration::CFDE_CSSDeclaration() {} CFDE_CSSDeclaration::~CFDE_CSSDeclaration() {} -CFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSProperty eProperty, - bool& bImportant) const { +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::GetProperty( + FDE_CSSProperty eProperty, + bool* bImportant) const { for (const auto& p : properties_) { if (p->eProperty == eProperty) { - bImportant = p->bImportant; - return p->pValue.Get(); + *bImportant = p->bImportant; + return p->pValue; } } return nullptr; } -const FX_WCHAR* CFDE_CSSDeclaration::CopyToLocal( - const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - ASSERT(iValueLen > 0); - std::unordered_map<uint32_t, FX_WCHAR*>* pCache = pArgs->pStringCache; - uint32_t key = 0; - if (pCache) { - key = FX_HashCode_GetW(CFX_WideStringC(pszValue, iValueLen), false); - auto it = pCache->find(key); - if (it != pCache->end()) - return it->second; - } - FX_WCHAR* psz = FX_Alloc(FX_WCHAR, iValueLen + 1); - FXSYS_wcsncpy(psz, pszValue, iValueLen); - psz[iValueLen] = '\0'; - if (pCache) - (*pCache)[key] = psz; - - return psz; -} - void CFDE_CSSDeclaration::AddPropertyHolder(FDE_CSSProperty eProperty, CFX_RetainPtr<CFDE_CSSValue> pValue, bool bImportant) { @@ -176,10 +155,13 @@ void CFDE_CSSDeclaration::AddPropertyHolder(FDE_CSSProperty eProperty, properties_.push_back(std::move(pHolder)); } -void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - ASSERT(iValueLen > 0); +void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyTable* pTable, + const CFX_WideStringC& value) { + ASSERT(!value.IsEmpty()); + + const FX_WCHAR* pszValue = value.c_str(); + int32_t iValueLen = value.GetLength(); + bool bImportant = false; if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' && FXSYS_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) { @@ -188,7 +170,7 @@ void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, bImportant = true; } - const uint32_t dwType = pArgs->pProperty->dwType; + const uint32_t dwType = pTable->dwType; switch (dwType & 0x0F) { case FDE_CSSVALUETYPE_Primitive: { static const uint32_t g_ValueGuessOrder[] = { @@ -205,22 +187,22 @@ void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, CFX_RetainPtr<CFDE_CSSValue> pCSSValue; switch (dwMatch) { case FDE_CSSVALUETYPE_MaybeNumber: - pCSSValue = ParseNumber(pArgs, pszValue, iValueLen); + pCSSValue = ParseNumber(pszValue, iValueLen); break; case FDE_CSSVALUETYPE_MaybeEnum: - pCSSValue = ParseEnum(pArgs, pszValue, iValueLen); + pCSSValue = ParseEnum(pszValue, iValueLen); break; case FDE_CSSVALUETYPE_MaybeColor: - pCSSValue = ParseColor(pArgs, pszValue, iValueLen); + pCSSValue = ParseColor(pszValue, iValueLen); break; case FDE_CSSVALUETYPE_MaybeString: - pCSSValue = ParseString(pArgs, pszValue, iValueLen); + pCSSValue = ParseString(pszValue, iValueLen); break; default: break; } if (pCSSValue) { - AddPropertyHolder(pArgs->pProperty->eName, pCSSValue, bImportant); + AddPropertyHolder(pTable->eName, pCSSValue, bImportant); return; } if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) @@ -230,9 +212,9 @@ void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, } case FDE_CSSVALUETYPE_Shorthand: { CFX_RetainPtr<CFDE_CSSValue> pWidth; - switch (pArgs->pProperty->eName) { + switch (pTable->eName) { case FDE_CSSProperty::Font: - ParseFontProperty(pArgs, pszValue, iValueLen, bImportant); + ParseFontProperty(pszValue, iValueLen, bImportant); return; case FDE_CSSProperty::Border: if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { @@ -280,7 +262,7 @@ void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, } } break; case FDE_CSSVALUETYPE_List: - ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant); + ParseValueListProperty(pTable, pszValue, iValueLen, bImportant); return; default: ASSERT(false); @@ -288,19 +270,13 @@ void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, } } -void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszName, - int32_t iNameLen, - const FX_WCHAR* pszValue, - int32_t iValueLen) { - auto pProperty = pdfium::MakeUnique<CFDE_CSSCustomProperty>(); - pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen); - pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen); - custom_properties_.push_back(std::move(pProperty)); +void CFDE_CSSDeclaration::AddProperty(const CFX_WideString& prop, + const CFX_WideString& value) { + custom_properties_.push_back( + pdfium::MakeUnique<CFDE_CSSCustomProperty>(prop, value)); } CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseNumber( - const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { FX_FLOAT fValue; @@ -311,7 +287,6 @@ CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseNumber( } CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseEnum( - const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { const FDE_CSSPropertyValueTable* pValue = @@ -321,7 +296,6 @@ CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseEnum( } CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseColor( - const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { FX_ARGB dwColor; @@ -331,7 +305,6 @@ CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseColor( } CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseString( - const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { int32_t iOffset; @@ -341,20 +314,20 @@ CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseString( if (iValueLen <= 0) return nullptr; - pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); - return pszValue ? pdfium::MakeRetain<CFDE_CSSStringValue>(pszValue) : nullptr; + return pdfium::MakeRetain<CFDE_CSSStringValue>( + CFX_WideString(pszValue + iOffset, iValueLen)); } void CFDE_CSSDeclaration::ParseValueListProperty( - const FDE_CSSPropertyArgs* pArgs, + const FDE_CSSPropertyTable* pTable, const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant) { FX_WCHAR separator = - (pArgs->pProperty->eName == FDE_CSSProperty::FontFamily) ? ',' : ' '; + (pTable->eName == FDE_CSSProperty::FontFamily) ? ',' : ' '; CFDE_CSSValueListParser parser(pszValue, iValueLen, separator); - const uint32_t dwType = pArgs->pProperty->dwType; + const uint32_t dwType = pTable->dwType; FDE_CSSPrimitiveType eType; std::vector<CFX_RetainPtr<CFDE_CSSValue>> list; while (parser.NextValue(eType, pszValue, iValueLen)) { @@ -387,8 +360,8 @@ void CFDE_CSSDeclaration::ParseValueListProperty( } } if (dwType & FDE_CSSVALUETYPE_MaybeString) { - pszValue = CopyToLocal(pArgs, pszValue, iValueLen); - list.push_back(pdfium::MakeRetain<CFDE_CSSStringValue>(pszValue)); + list.push_back(pdfium::MakeRetain<CFDE_CSSStringValue>( + CFX_WideString(pszValue, iValueLen))); } break; case FDE_CSSPrimitiveType::RGB: @@ -406,7 +379,7 @@ void CFDE_CSSDeclaration::ParseValueListProperty( if (list.empty()) return; - switch (pArgs->pProperty->eName) { + switch (pTable->eName) { case FDE_CSSProperty::BorderWidth: Add4ValuesProperty(list, bImportant, FDE_CSSProperty::BorderLeftWidth, FDE_CSSProperty::BorderTopWidth, @@ -427,7 +400,7 @@ void CFDE_CSSDeclaration::ParseValueListProperty( return; default: { auto pList = pdfium::MakeRetain<CFDE_CSSValueList>(list); - AddPropertyHolder(pArgs->pProperty->eName, pList, bImportant); + AddPropertyHolder(pTable->eName, pList, bImportant); return; } } @@ -524,8 +497,7 @@ bool CFDE_CSSDeclaration::ParseBorderProperty( return true; } -void CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, +void CFDE_CSSDeclaration::ParseFontProperty(const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant) { CFDE_CSSValueListParser parser(pszValue, iValueLen, '/'); @@ -591,7 +563,7 @@ void CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, } if (pFontSize) { familyList.push_back(pdfium::MakeRetain<CFDE_CSSStringValue>( - CopyToLocal(pArgs, pszValue, iValueLen))); + CFX_WideString(pszValue, iValueLen))); } parser.m_Separator = ','; break; @@ -630,21 +602,26 @@ void CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, } } - if (!pStyle) + if (!pStyle) { pStyle = pdfium::MakeRetain<CFDE_CSSEnumValue>(FDE_CSSPropertyValue::Normal); - if (!pVariant) + } + if (!pVariant) { pVariant = pdfium::MakeRetain<CFDE_CSSEnumValue>(FDE_CSSPropertyValue::Normal); - if (!pWeight) + } + if (!pWeight) { pWeight = pdfium::MakeRetain<CFDE_CSSEnumValue>(FDE_CSSPropertyValue::Normal); - if (!pFontSize) + } + if (!pFontSize) { pFontSize = pdfium::MakeRetain<CFDE_CSSEnumValue>(FDE_CSSPropertyValue::Medium); - if (!pLineHeight) + } + if (!pLineHeight) { pLineHeight = pdfium::MakeRetain<CFDE_CSSEnumValue>(FDE_CSSPropertyValue::Normal); + } AddPropertyHolder(FDE_CSSProperty::FontStyle, pStyle, bImportant); AddPropertyHolder(FDE_CSSProperty::FontVariant, pVariant, bImportant); diff --git a/xfa/fde/css/cfde_cssdeclaration.h b/xfa/fde/css/cfde_cssdeclaration.h index 777864efe..eb287308f 100644 --- a/xfa/fde/css/cfde_cssdeclaration.h +++ b/xfa/fde/css/cfde_cssdeclaration.h @@ -8,17 +8,11 @@ #define XFA_FDE_CSS_CFDE_CSSDECLARATION_H_ #include <memory> -#include <unordered_map> #include <utility> #include <vector> #include "xfa/fde/css/fde_cssdatatable.h" -struct FDE_CSSPropertyArgs { - std::unordered_map<uint32_t, FX_WCHAR*>* pStringCache; - const FDE_CSSPropertyTable* pProperty; -}; - class CFDE_CSSPropertyHolder; class CFDE_CSSCustomProperty; @@ -40,7 +34,8 @@ class CFDE_CSSDeclaration { CFDE_CSSDeclaration(); ~CFDE_CSSDeclaration(); - CFDE_CSSValue* GetProperty(FDE_CSSProperty eProperty, bool& bImportant) const; + CFX_RetainPtr<CFDE_CSSValue> GetProperty(FDE_CSSProperty eProperty, + bool* bImportant) const; const_prop_iterator begin() const { return properties_.begin(); } const_prop_iterator end() const { return properties_.end(); } @@ -52,14 +47,9 @@ class CFDE_CSSDeclaration { bool empty() const { return properties_.empty(); } - void AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - void AddProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszName, - int32_t iNameLen, - const FX_WCHAR* pszValue, - int32_t iValueLen); + void AddProperty(const FDE_CSSPropertyTable* pTable, + const CFX_WideStringC& value); + void AddProperty(const CFX_WideString& prop, const CFX_WideString& value); size_t PropertyCountForTesting() const; @@ -68,14 +58,13 @@ class CFDE_CSSDeclaration { FX_ARGB* dwColor) const; private: - void ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, + void ParseFontProperty(const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant); bool ParseBorderProperty(const FX_WCHAR* pszValue, int32_t iValueLen, CFX_RetainPtr<CFDE_CSSValue>& pWidth) const; - void ParseValueListProperty(const FDE_CSSPropertyArgs* pArgs, + void ParseValueListProperty(const FDE_CSSPropertyTable* pTable, const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant); @@ -85,21 +74,14 @@ class CFDE_CSSDeclaration { FDE_CSSProperty eTop, FDE_CSSProperty eRight, FDE_CSSProperty eBottom); - CFX_RetainPtr<CFDE_CSSValue> ParseNumber(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, + CFX_RetainPtr<CFDE_CSSValue> ParseNumber(const FX_WCHAR* pszValue, int32_t iValueLen); - CFX_RetainPtr<CFDE_CSSValue> ParseEnum(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, + CFX_RetainPtr<CFDE_CSSValue> ParseEnum(const FX_WCHAR* pszValue, int32_t iValueLen); - CFX_RetainPtr<CFDE_CSSValue> ParseColor(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, + CFX_RetainPtr<CFDE_CSSValue> ParseColor(const FX_WCHAR* pszValue, int32_t iValueLen); - CFX_RetainPtr<CFDE_CSSValue> ParseString(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, + CFX_RetainPtr<CFDE_CSSValue> ParseString(const FX_WCHAR* pszValue, int32_t iValueLen); - const FX_WCHAR* CopyToLocal(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); void AddPropertyHolder(FDE_CSSProperty eProperty, CFX_RetainPtr<CFDE_CSSValue> pValue, bool bImportant); diff --git a/xfa/fde/css/cfde_cssfontfacerule.cpp b/xfa/fde/css/cfde_cssfontfacerule.cpp deleted file mode 100644 index 5d56eb8c6..000000000 --- a/xfa/fde/css/cfde_cssfontfacerule.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017 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 "xfa/fde/css/cfde_cssfontfacerule.h" - -CFDE_CSSFontFaceRule::CFDE_CSSFontFaceRule() - : CFDE_CSSRule(FDE_CSSRuleType::FontFace) {} - -CFDE_CSSFontFaceRule::~CFDE_CSSFontFaceRule() {} diff --git a/xfa/fde/css/cfde_cssfontfacerule.h b/xfa/fde/css/cfde_cssfontfacerule.h deleted file mode 100644 index e5249ccf1..000000000 --- a/xfa/fde/css/cfde_cssfontfacerule.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2017 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 XFA_FDE_CSS_CFDE_CSSFONTFACERULE_H_ -#define XFA_FDE_CSS_CFDE_CSSFONTFACERULE_H_ - -#include "xfa/fde/css/cfde_cssdeclaration.h" -#include "xfa/fde/css/cfde_cssrule.h" - -class CFDE_CSSFontFaceRule : public CFDE_CSSRule { - public: - CFDE_CSSFontFaceRule(); - ~CFDE_CSSFontFaceRule() override; - - CFDE_CSSDeclaration* GetDeclaration() { return &m_Declaration; } - - private: - CFDE_CSSDeclaration m_Declaration; -}; - -#endif // XFA_FDE_CSS_CFDE_CSSFONTFACERULE_H_ diff --git a/xfa/fde/css/cfde_cssmediarule.cpp b/xfa/fde/css/cfde_cssmediarule.cpp deleted file mode 100644 index 751f9d9fa..000000000 --- a/xfa/fde/css/cfde_cssmediarule.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 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 "xfa/fde/css/cfde_cssmediarule.h" - -#include "third_party/base/stl_util.h" - -CFDE_CSSMediaRule::CFDE_CSSMediaRule(uint32_t dwMediaList) - : CFDE_CSSRule(FDE_CSSRuleType::Media), m_dwMediaList(dwMediaList) {} - -CFDE_CSSMediaRule::~CFDE_CSSMediaRule() {} - -uint32_t CFDE_CSSMediaRule::GetMediaList() const { - return m_dwMediaList; -} - -int32_t CFDE_CSSMediaRule::CountRules() const { - return pdfium::CollectionSize<int32_t>(m_RuleArray); -} - -CFDE_CSSRule* CFDE_CSSMediaRule::GetRule(int32_t index) { - return m_RuleArray[index].get(); -} diff --git a/xfa/fde/css/cfde_cssmediarule.h b/xfa/fde/css/cfde_cssmediarule.h deleted file mode 100644 index 59febb200..000000000 --- a/xfa/fde/css/cfde_cssmediarule.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2017 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 XFA_FDE_CSS_CFDE_CSSMEDIARULE_H_ -#define XFA_FDE_CSS_CFDE_CSSMEDIARULE_H_ - -#include <memory> -#include <vector> - -#include "xfa/fde/css/cfde_cssrule.h" - -class CFDE_CSSMediaRule : public CFDE_CSSRule { - public: - explicit CFDE_CSSMediaRule(uint32_t dwMediaList); - ~CFDE_CSSMediaRule() override; - - uint32_t GetMediaList() const; - int32_t CountRules() const; - CFDE_CSSRule* GetRule(int32_t index); - - std::vector<std::unique_ptr<CFDE_CSSRule>>& GetArray() { return m_RuleArray; } - - protected: - uint32_t m_dwMediaList; - std::vector<std::unique_ptr<CFDE_CSSRule>> m_RuleArray; -}; - -#endif // XFA_FDE_CSS_CFDE_CSSMEDIARULE_H_ diff --git a/xfa/fde/css/cfde_cssrule.cpp b/xfa/fde/css/cfde_cssrule.cpp deleted file mode 100644 index 7a4670388..000000000 --- a/xfa/fde/css/cfde_cssrule.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2017 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 "xfa/fde/css/cfde_cssrule.h" - -CFDE_CSSRule::CFDE_CSSRule(FDE_CSSRuleType type) : m_type(type) {} - -CFDE_CSSRule::~CFDE_CSSRule() {} diff --git a/xfa/fde/css/cfde_cssrule.h b/xfa/fde/css/cfde_cssrule.h deleted file mode 100644 index 946132179..000000000 --- a/xfa/fde/css/cfde_cssrule.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 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 XFA_FDE_CSS_CFDE_CSSRULE_H_ -#define XFA_FDE_CSS_CFDE_CSSRULE_H_ - -#include "xfa/fde/css/fde_css.h" - -class CFDE_CSSRule { - public: - virtual ~CFDE_CSSRule(); - - FDE_CSSRuleType GetType() const { return m_type; } - - protected: - explicit CFDE_CSSRule(FDE_CSSRuleType type); - - private: - FDE_CSSRuleType m_type; -}; - -#endif // XFA_FDE_CSS_CFDE_CSSRULE_H_ diff --git a/xfa/fde/css/cfde_cssrulecollection.cpp b/xfa/fde/css/cfde_cssrulecollection.cpp index 286f619b6..e31865113 100644 --- a/xfa/fde/css/cfde_cssrulecollection.cpp +++ b/xfa/fde/css/cfde_cssrulecollection.cpp @@ -7,152 +7,52 @@ #include "xfa/fde/css/cfde_cssrulecollection.h" #include <algorithm> -#include <map> -#include <memory> +#include <utility> +#include "third_party/base/ptr_util.h" #include "xfa/fde/css/cfde_cssdeclaration.h" -#include "xfa/fde/css/cfde_cssmediarule.h" -#include "xfa/fde/css/cfde_cssrule.h" #include "xfa/fde/css/cfde_cssselector.h" #include "xfa/fde/css/cfde_cssstylerule.h" #include "xfa/fde/css/cfde_cssstylesheet.h" #include "xfa/fde/css/cfde_csssyntaxparser.h" -#include "xfa/fde/css/cfde_csstagcache.h" -#define FDE_CSSUNIVERSALHASH ('*') - -void CFDE_CSSRuleCollection::Clear() { - m_IDRules.clear(); - m_TagRules.clear(); - m_ClassRules.clear(); - m_pUniversalRules = nullptr; - m_iSelectors = 0; -} - -CFDE_CSSRuleCollection::CFDE_CSSRuleCollection() - : m_pUniversalRules(nullptr), m_pPseudoRules(nullptr), m_iSelectors(0) {} +CFDE_CSSRuleCollection::CFDE_CSSRuleCollection() : m_iSelectors(0) {} CFDE_CSSRuleCollection::~CFDE_CSSRuleCollection() { Clear(); } -void CFDE_CSSRuleCollection::AddRulesFrom( - const CFX_ArrayTemplate<CFDE_CSSStyleSheet*>& sheets, - uint32_t dwMediaList, - CFGAS_FontMgr* pFontMgr) { - int32_t iSheets = sheets.GetSize(); - for (int32_t i = 0; i < iSheets; ++i) { - CFDE_CSSStyleSheet* pSheet = sheets.GetAt(i); - if (uint32_t dwMatchMedia = pSheet->GetMediaList() & dwMediaList) { - int32_t iRules = pSheet->CountRules(); - for (int32_t j = 0; j < iRules; j++) { - AddRulesFrom(pSheet, pSheet->GetRule(j), dwMatchMedia, pFontMgr); - } - } - } +void CFDE_CSSRuleCollection::Clear() { + m_TagRules.clear(); + m_iSelectors = 0; } -void CFDE_CSSRuleCollection::AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, - CFDE_CSSRule* pRule, - uint32_t dwMediaList, - CFGAS_FontMgr* pFontMgr) { - switch (pRule->GetType()) { - case FDE_CSSRuleType::Style: { - CFDE_CSSStyleRule* pStyleRule = static_cast<CFDE_CSSStyleRule*>(pRule); - CFDE_CSSDeclaration* pDeclaration = pStyleRule->GetDeclaration(); - int32_t iSelectors = pStyleRule->CountSelectorLists(); - for (int32_t i = 0; i < iSelectors; ++i) { - CFDE_CSSSelector* pSelector = pStyleRule->GetSelectorList(i); - if (pSelector->GetType() == FDE_CSSSelectorType::Pseudo) { - Data* pData = NewRuleData(pSelector, pDeclaration); - AddRuleTo(&m_pPseudoRules, pData); - continue; - } - if (pSelector->GetNameHash() != FDE_CSSUNIVERSALHASH) { - AddRuleTo(&m_TagRules, pSelector->GetNameHash(), pSelector, - pDeclaration); - continue; - } - CFDE_CSSSelector* pNext = pSelector->GetNextSelector(); - if (!pNext) { - Data* pData = NewRuleData(pSelector, pDeclaration); - AddRuleTo(&m_pUniversalRules, pData); - continue; - } - switch (pNext->GetType()) { - case FDE_CSSSelectorType::ID: - AddRuleTo(&m_IDRules, pNext->GetNameHash(), pSelector, - pDeclaration); - break; - case FDE_CSSSelectorType::Class: - AddRuleTo(&m_ClassRules, pNext->GetNameHash(), pSelector, - pDeclaration); - break; - case FDE_CSSSelectorType::Descendant: - case FDE_CSSSelectorType::Element: - AddRuleTo(&m_pUniversalRules, NewRuleData(pSelector, pDeclaration)); - break; - default: - ASSERT(false); - break; - } - } - } break; - case FDE_CSSRuleType::Media: { - CFDE_CSSMediaRule* pMediaRule = static_cast<CFDE_CSSMediaRule*>(pRule); - if (pMediaRule->GetMediaList() & dwMediaList) { - int32_t iRules = pMediaRule->CountRules(); - for (int32_t i = 0; i < iRules; ++i) { - AddRulesFrom(pStyleSheet, pMediaRule->GetRule(i), dwMediaList, - pFontMgr); - } - } - } break; - default: - break; - } +const std::vector<std::unique_ptr<CFDE_CSSRuleCollection::Data>>* +CFDE_CSSRuleCollection::GetTagRuleData(const CFX_WideString& tagname) const { + auto it = m_TagRules.find(FX_HashCode_GetW(tagname.c_str(), true)); + return it != m_TagRules.end() ? &it->second : nullptr; } -void CFDE_CSSRuleCollection::AddRuleTo(std::map<uint32_t, Data*>* pMap, - uint32_t dwKey, - CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl) { - Data* pData = NewRuleData(pSel, pDecl); - Data* pList = (*pMap)[dwKey]; - if (!pList) { - (*pMap)[dwKey] = pData; - } else if (AddRuleTo(&pList, pData)) { - (*pMap)[dwKey] = pList; - } +void CFDE_CSSRuleCollection::AddRulesFrom(const CFDE_CSSStyleSheet* sheet, + CFGAS_FontMgr* pFontMgr) { + int32_t iRules = sheet->CountRules(); + for (int32_t j = 0; j < iRules; j++) + AddRulesFrom(sheet, sheet->GetRule(j), pFontMgr); } -bool CFDE_CSSRuleCollection::AddRuleTo(Data** pList, Data* pData) { - if (*pList) { - pData->pNext = (*pList)->pNext; - (*pList)->pNext = pData; - return false; +void CFDE_CSSRuleCollection::AddRulesFrom(const CFDE_CSSStyleSheet* pStyleSheet, + CFDE_CSSStyleRule* pStyleRule, + CFGAS_FontMgr* pFontMgr) { + CFDE_CSSDeclaration* pDeclaration = pStyleRule->GetDeclaration(); + int32_t iSelectors = pStyleRule->CountSelectorLists(); + for (int32_t i = 0; i < iSelectors; ++i) { + CFDE_CSSSelector* pSelector = pStyleRule->GetSelectorList(i); + m_TagRules[pSelector->GetNameHash()].push_back( + pdfium::MakeUnique<Data>(pSelector, pDeclaration)); + m_iSelectors++; } - *pList = pData; - return true; -} - -CFDE_CSSRuleCollection::Data* CFDE_CSSRuleCollection::NewRuleData( - CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl) { - return new Data(pSel, pDecl, ++m_iSelectors); } CFDE_CSSRuleCollection::Data::Data(CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl, - uint32_t dwPos) - : pSelector(pSel), pDeclaration(pDecl), dwPriority(dwPos), pNext(nullptr) { - static const uint32_t s_Specific[5] = {0x00010000, 0x00010000, 0x00100000, - 0x00100000, 0x01000000}; - for (; pSel; pSel = pSel->GetNextSelector()) { - FDE_CSSSelectorType eType = pSel->GetType(); - if (eType > FDE_CSSSelectorType::Descendant || - pSel->GetNameHash() != FDE_CSSUNIVERSALHASH) { - dwPriority += s_Specific[static_cast<int>(eType)]; - } - } -} + CFDE_CSSDeclaration* pDecl) + : pSelector(pSel), pDeclaration(pDecl) {} diff --git a/xfa/fde/css/cfde_cssrulecollection.h b/xfa/fde/css/cfde_cssrulecollection.h index 1433a5a5f..5d49922fc 100644 --- a/xfa/fde/css/cfde_cssrulecollection.h +++ b/xfa/fde/css/cfde_cssrulecollection.h @@ -8,12 +8,14 @@ #define XFA_FDE_CSS_CFDE_CSSRULECOLLECTION_H_ #include <map> +#include <memory> +#include <vector> #include "core/fxcrt/fx_basic.h" class CFDE_CSSDeclaration; -class CFDE_CSSRule; class CFDE_CSSSelector; +class CFDE_CSSStyleRule; class CFDE_CSSStyleSheet; class CFGAS_FontMgr; @@ -21,58 +23,28 @@ class CFDE_CSSRuleCollection { public: class Data { public: - Data(CFDE_CSSSelector* pSel, CFDE_CSSDeclaration* pDecl, uint32_t dwPos); + Data(CFDE_CSSSelector* pSel, CFDE_CSSDeclaration* pDecl); CFDE_CSSSelector* const pSelector; CFDE_CSSDeclaration* const pDeclaration; - uint32_t dwPriority; - Data* pNext; }; CFDE_CSSRuleCollection(); ~CFDE_CSSRuleCollection(); - void AddRulesFrom(const CFX_ArrayTemplate<CFDE_CSSStyleSheet*>& sheets, - uint32_t dwMediaList, - CFGAS_FontMgr* pFontMgr); + void AddRulesFrom(const CFDE_CSSStyleSheet* sheet, CFGAS_FontMgr* pFontMgr); void Clear(); int32_t CountSelectors() const { return m_iSelectors; } - Data* GetIDRuleData(uint32_t dwIDHash) { - auto it = m_IDRules.find(dwIDHash); - return it != m_IDRules.end() ? it->second : nullptr; - } - - Data* GetTagRuleData(uint32_t dwTagHash) { - auto it = m_TagRules.find(dwTagHash); - return it != m_TagRules.end() ? it->second : nullptr; - } - - Data* GetClassRuleData(uint32_t dwIDHash) { - auto it = m_ClassRules.find(dwIDHash); - return it != m_ClassRules.end() ? it->second : nullptr; - } - - Data* GetUniversalRuleData() { return m_pUniversalRules; } - Data* GetPseudoRuleData() { return m_pPseudoRules; } + const std::vector<std::unique_ptr<Data>>* GetTagRuleData( + const CFX_WideString& tagname) const; - protected: - void AddRulesFrom(CFDE_CSSStyleSheet* pStyleSheet, - CFDE_CSSRule* pRule, - uint32_t dwMediaList, + private: + void AddRulesFrom(const CFDE_CSSStyleSheet* pStyleSheet, + CFDE_CSSStyleRule* pRule, CFGAS_FontMgr* pFontMgr); - void AddRuleTo(std::map<uint32_t, Data*>* pMap, - uint32_t dwKey, - CFDE_CSSSelector* pSel, - CFDE_CSSDeclaration* pDecl); - bool AddRuleTo(Data** pList, Data* pData); - Data* NewRuleData(CFDE_CSSSelector* pSel, CFDE_CSSDeclaration* pDecl); - std::map<uint32_t, Data*> m_IDRules; - std::map<uint32_t, Data*> m_TagRules; - std::map<uint32_t, Data*> m_ClassRules; - Data* m_pUniversalRules; - Data* m_pPseudoRules; + std::map<uint32_t, std::vector<std::unique_ptr<Data>>> m_TagRules; int32_t m_iSelectors; }; diff --git a/xfa/fde/css/cfde_cssselector.cpp b/xfa/fde/css/cfde_cssselector.cpp index 4d32bd1cf..03580236f 100644 --- a/xfa/fde/css/cfde_cssselector.cpp +++ b/xfa/fde/css/cfde_cssselector.cpp @@ -16,19 +16,6 @@ bool IsCSSChar(FX_WCHAR wch) { return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z'); } -int32_t GetCSSPseudoLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { - ASSERT(*psz == ':'); - const FX_WCHAR* pStart = psz; - while (psz < pEnd) { - FX_WCHAR wch = *psz; - if (IsCSSChar(wch) || wch == ':') - ++psz; - else - break; - } - return psz - pStart; -} - int32_t GetCSSNameLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { const FX_WCHAR* pStart = psz; while (psz < pEnd) { @@ -66,17 +53,14 @@ CFDE_CSSSelector* CFDE_CSSSelector::GetNextSelector() const { return m_pNext.get(); } -std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::ReleaseNextSelector() { - return std::move(m_pNext); -} - +// static. std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::FromString( - const FX_WCHAR* psz, - int32_t iLen) { - ASSERT(psz && iLen > 0); + const CFX_WideStringC& str) { + ASSERT(!str.IsEmpty()); + const FX_WCHAR* psz = str.c_str(); const FX_WCHAR* pStart = psz; - const FX_WCHAR* pEnd = psz + iLen; + const FX_WCHAR* pEnd = psz + str.GetLength(); for (; psz < pEnd; ++psz) { switch (*psz) { case '>': @@ -87,44 +71,10 @@ std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::FromString( } std::unique_ptr<CFDE_CSSSelector> pFirst = nullptr; - CFDE_CSSSelector* pLast = nullptr; - std::unique_ptr<CFDE_CSSSelector> pPseudoFirst = nullptr; - CFDE_CSSSelector* pPseudoLast = nullptr; - for (psz = pStart; psz < pEnd;) { FX_WCHAR wch = *psz; - if (wch == '.' || wch == '#') { - if (psz == pStart || psz[-1] == ' ') { - auto p = pdfium::MakeUnique<CFDE_CSSSelector>( - FDE_CSSSelectorType::Element, L"*", 1, true); - - if (pFirst) { - pFirst->SetType(FDE_CSSSelectorType::Descendant); - p->SetNext(std::move(pFirst)); - } - pFirst = std::move(p); - pLast = pFirst.get(); - } - ASSERT(pLast); - - int32_t iNameLen = GetCSSNameLen(++psz, pEnd); - if (iNameLen == 0) - return nullptr; - - FDE_CSSSelectorType eType = - wch == '.' ? FDE_CSSSelectorType::Class : FDE_CSSSelectorType::ID; - auto p = - pdfium::MakeUnique<CFDE_CSSSelector>(eType, psz, iNameLen, false); - - p->SetNext(pLast->ReleaseNextSelector()); - pLast->SetNext(std::move(p)); - pLast = pLast->GetNextSelector(); - psz += iNameLen; - } else if (IsCSSChar(wch) || wch == '*') { + if (IsCSSChar(wch) || wch == '*') { int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd); - if (iNameLen == 0) - return nullptr; - auto p = pdfium::MakeUnique<CFDE_CSSSelector>( FDE_CSSSelectorType::Element, psz, iNameLen, true); if (pFirst) { @@ -132,21 +82,6 @@ std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::FromString( p->SetNext(std::move(pFirst)); } pFirst = std::move(p); - pLast = pFirst.get(); - psz += iNameLen; - } else if (wch == ':') { - int32_t iNameLen = GetCSSPseudoLen(psz, pEnd); - if (iNameLen == 0) - return nullptr; - - auto p = pdfium::MakeUnique<CFDE_CSSSelector>(FDE_CSSSelectorType::Pseudo, - psz, iNameLen, true); - CFDE_CSSSelector* ptr = p.get(); - if (pPseudoFirst) - pPseudoLast->SetNext(std::move(p)); - else - pPseudoFirst = std::move(p); - pPseudoLast = ptr; psz += iNameLen; } else if (wch == ' ') { psz++; @@ -154,9 +89,5 @@ std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::FromString( return nullptr; } } - if (!pPseudoFirst) - return pFirst; - - pPseudoLast->SetNext(std::move(pFirst)); - return pPseudoFirst; + return pFirst; } diff --git a/xfa/fde/css/cfde_cssselector.h b/xfa/fde/css/cfde_cssselector.h index 18a7c340e..d585b3f36 100644 --- a/xfa/fde/css/cfde_cssselector.h +++ b/xfa/fde/css/cfde_cssselector.h @@ -15,8 +15,8 @@ class CFDE_CSSSelector { public: - static std::unique_ptr<CFDE_CSSSelector> FromString(const FX_WCHAR* psz, - int32_t iLen); + static std::unique_ptr<CFDE_CSSSelector> FromString( + const CFX_WideStringC& str); CFDE_CSSSelector(FDE_CSSSelectorType eType, const FX_WCHAR* psz, @@ -27,7 +27,6 @@ class CFDE_CSSSelector { FDE_CSSSelectorType GetType() const; uint32_t GetNameHash() const; CFDE_CSSSelector* GetNextSelector() const; - std::unique_ptr<CFDE_CSSSelector> ReleaseNextSelector(); void SetNext(std::unique_ptr<CFDE_CSSSelector> pNext) { m_pNext = std::move(pNext); diff --git a/xfa/fde/css/cfde_cssstylerule.cpp b/xfa/fde/css/cfde_cssstylerule.cpp index 09c4a43f3..04f6cfff0 100644 --- a/xfa/fde/css/cfde_cssstylerule.cpp +++ b/xfa/fde/css/cfde_cssstylerule.cpp @@ -6,7 +6,7 @@ #include "xfa/fde/css/cfde_cssstylerule.h" -CFDE_CSSStyleRule::CFDE_CSSStyleRule() : CFDE_CSSRule(FDE_CSSRuleType::Style) {} +CFDE_CSSStyleRule::CFDE_CSSStyleRule() {} CFDE_CSSStyleRule::~CFDE_CSSStyleRule() {} diff --git a/xfa/fde/css/cfde_cssstylerule.h b/xfa/fde/css/cfde_cssstylerule.h index bed0a5ec1..075ab8d47 100644 --- a/xfa/fde/css/cfde_cssstylerule.h +++ b/xfa/fde/css/cfde_cssstylerule.h @@ -11,13 +11,12 @@ #include <vector> #include "xfa/fde/css/cfde_cssdeclaration.h" -#include "xfa/fde/css/cfde_cssrule.h" #include "xfa/fde/css/cfde_cssselector.h" -class CFDE_CSSStyleRule : public CFDE_CSSRule { +class CFDE_CSSStyleRule { public: CFDE_CSSStyleRule(); - ~CFDE_CSSStyleRule() override; + ~CFDE_CSSStyleRule(); size_t CountSelectorLists() const; CFDE_CSSSelector* GetSelectorList(int32_t index) const; diff --git a/xfa/fde/css/cfde_cssstyleselector.cpp b/xfa/fde/css/cfde_cssstyleselector.cpp index 153989401..5a7aa1b7f 100644 --- a/xfa/fde/css/cfde_cssstyleselector.cpp +++ b/xfa/fde/css/cfde_cssstyleselector.cpp @@ -7,9 +7,9 @@ #include "xfa/fde/css/cfde_cssstyleselector.h" #include <algorithm> +#include <utility> #include "third_party/base/ptr_util.h" -#include "xfa/fde/css/cfde_cssaccelerator.h" #include "xfa/fde/css/cfde_csscolorvalue.h" #include "xfa/fde/css/cfde_csscomputedstyle.h" #include "xfa/fde/css/cfde_csscustomproperty.h" @@ -17,361 +17,152 @@ #include "xfa/fde/css/cfde_cssenumvalue.h" #include "xfa/fde/css/cfde_csspropertyholder.h" #include "xfa/fde/css/cfde_cssselector.h" +#include "xfa/fde/css/cfde_cssstylesheet.h" #include "xfa/fde/css/cfde_csssyntaxparser.h" -#include "xfa/fde/css/cfde_csstagcache.h" #include "xfa/fde/css/cfde_cssvaluelist.h" #include "xfa/fxfa/app/cxfa_csstagprovider.h" -namespace { - -template <class T> -T* ToValue(CFDE_CSSValue* val) { - return static_cast<T*>(val); -} - -template <class T> -const T* ToValue(const CFDE_CSSValue* val) { - return static_cast<T*>(val); -} - -} // namespace - -#define FDE_CSSUNIVERSALHASH ('*') - CFDE_CSSStyleSelector::CFDE_CSSStyleSelector(CFGAS_FontMgr* pFontMgr) - : m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) { - m_ePriorities[static_cast<int32_t>(FDE_CSSStyleSheetPriority::High)] = - FDE_CSSStyleSheetGroup::Author; - m_ePriorities[static_cast<int32_t>(FDE_CSSStyleSheetPriority::Mid)] = - FDE_CSSStyleSheetGroup::User; - m_ePriorities[static_cast<int32_t>(FDE_CSSStyleSheetPriority::Low)] = - FDE_CSSStyleSheetGroup::UserAgent; -} + : m_pFontMgr(pFontMgr), m_fDefFontSize(12.0f) {} -CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() { - Reset(); -} +CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector() {} void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize) { ASSERT(fFontSize > 0); m_fDefFontSize = fFontSize; } -CFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator() { - if (!m_pAccelerator) - m_pAccelerator = pdfium::MakeUnique<CFDE_CSSAccelerator>(); - m_pAccelerator->Clear(); - return m_pAccelerator.get(); -} - -CFDE_CSSComputedStyle* CFDE_CSSStyleSelector::CreateComputedStyle( +CFX_RetainPtr<CFDE_CSSComputedStyle> CFDE_CSSStyleSelector::CreateComputedStyle( CFDE_CSSComputedStyle* pParentStyle) { - CFDE_CSSComputedStyle* pStyle = new CFDE_CSSComputedStyle(); + auto pStyle = pdfium::MakeRetain<CFDE_CSSComputedStyle>(); if (pParentStyle) pStyle->m_InheritedData = pParentStyle->m_InheritedData; return pStyle; } -bool CFDE_CSSStyleSelector::SetStyleSheet(FDE_CSSStyleSheetGroup eType, - CFDE_CSSStyleSheet* pSheet) { - CFX_ArrayTemplate<CFDE_CSSStyleSheet*>& dest = - m_SheetGroups[static_cast<int32_t>(eType)]; - dest.RemoveAt(0, dest.GetSize()); - if (pSheet) - dest.Add(pSheet); - return true; +void CFDE_CSSStyleSelector::SetUAStyleSheet( + std::unique_ptr<CFDE_CSSStyleSheet> pSheet) { + m_UAStyles = std::move(pSheet); } -bool CFDE_CSSStyleSelector::SetStyleSheets( - FDE_CSSStyleSheetGroup eType, - const CFX_ArrayTemplate<CFDE_CSSStyleSheet*>* pArray) { - CFX_ArrayTemplate<CFDE_CSSStyleSheet*>& dest = - m_SheetGroups[static_cast<int32_t>(eType)]; - if (pArray) - dest.Copy(*pArray); - else - dest.RemoveAt(0, dest.GetSize()); - return true; +void CFDE_CSSStyleSelector::UpdateStyleIndex() { + m_UARules.Clear(); + m_UARules.AddRulesFrom(m_UAStyles.get(), m_pFontMgr); } -void CFDE_CSSStyleSelector::SetStylePriority( - FDE_CSSStyleSheetGroup eType, - FDE_CSSStyleSheetPriority ePriority) { - m_ePriorities[static_cast<int32_t>(ePriority)] = eType; -} +std::vector<const CFDE_CSSDeclaration*> +CFDE_CSSStyleSelector::MatchDeclarations(const CFX_WideString& tagname) { + std::vector<const CFDE_CSSDeclaration*> matchedDecls; + if (m_UARules.CountSelectors() == 0 || tagname.IsEmpty()) + return matchedDecls; -void CFDE_CSSStyleSelector::UpdateStyleIndex(uint32_t dwMediaList) { - Reset(); + auto rules = m_UARules.GetTagRuleData(tagname); + if (!rules) + return matchedDecls; - // TODO(dsinclair): Hard coded size bad. This should probably just be a map. - for (int32_t iGroup = 0; iGroup < 3; ++iGroup) { - CFDE_CSSRuleCollection& rules = m_RuleCollection[iGroup]; - rules.AddRulesFrom(m_SheetGroups[iGroup], dwMediaList, m_pFontMgr); + for (const auto& d : *rules) { + if (MatchSelector(tagname, d->pSelector)) + matchedDecls.push_back(d->pDeclaration); } + return matchedDecls; } -void CFDE_CSSStyleSelector::Reset() { - // TODO(dsinclair): Hard coded size bad. This should probably just be a map. - for (int32_t iGroup = 0; iGroup < 3; ++iGroup) { - m_RuleCollection[iGroup].Clear(); +bool CFDE_CSSStyleSelector::MatchSelector(const CFX_WideString& tagname, + CFDE_CSSSelector* pSel) { + // TODO(dsinclair): The code only supports a single level of selector at this + // point. None of the code using selectors required the complexity so lets + // just say we don't support them to simplify the code for now. + if (!pSel || pSel->GetNextSelector() || + pSel->GetType() == FDE_CSSSelectorType::Descendant) { + return false; } + return pSel->GetNameHash() == FX_HashCode_GetW(tagname.c_str(), true); } -int32_t CFDE_CSSStyleSelector::MatchDeclarations( - CXFA_CSSTagProvider* pTag, - CFX_ArrayTemplate<CFDE_CSSDeclaration*>& matchedDecls, - FDE_CSSPseudo ePseudoType) { - ASSERT(pTag); - CFDE_CSSTagCache* pCache = m_pAccelerator->top(); - ASSERT(pCache && pCache->GetTag() == pTag); - - matchedDecls.RemoveAt(0, matchedDecls.GetSize()); - // TODO(dsinclair): Hard coded size bad ... - for (int32_t ePriority = 2; ePriority >= 0; --ePriority) { - FDE_CSSStyleSheetGroup eGroup = m_ePriorities[ePriority]; - CFDE_CSSRuleCollection& rules = - m_RuleCollection[static_cast<int32_t>(eGroup)]; - if (rules.CountSelectors() == 0) - continue; - - if (ePseudoType == FDE_CSSPseudo::NONE) { - MatchRules(pCache, rules.GetUniversalRuleData(), ePseudoType); - if (pCache->HashTag()) { - MatchRules(pCache, rules.GetTagRuleData(pCache->HashTag()), - ePseudoType); - } - int32_t iCount = pCache->CountHashClass(); - for (int32_t i = 0; i < iCount; i++) { - pCache->SetClassIndex(i); - MatchRules(pCache, rules.GetClassRuleData(pCache->HashClass()), - ePseudoType); - } - } else { - MatchRules(pCache, rules.GetPseudoRuleData(), ePseudoType); +void CFDE_CSSStyleSelector::ComputeStyle( + const std::vector<const CFDE_CSSDeclaration*>& declArray, + const CFX_WideString& styleString, + const CFX_WideString& alignString, + CFDE_CSSComputedStyle* pDest) { + std::unique_ptr<CFDE_CSSDeclaration> pDecl; + if (!styleString.IsEmpty() || !alignString.IsEmpty()) { + pDecl = pdfium::MakeUnique<CFDE_CSSDeclaration>(); + + if (!styleString.IsEmpty()) + AppendInlineStyle(pDecl.get(), styleString); + if (!alignString.IsEmpty()) { + pDecl->AddProperty(FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign), + alignString.AsStringC()); } - - std::sort(m_MatchedRules.begin(), m_MatchedRules.end(), - [](const CFDE_CSSRuleCollection::Data* p1, - const CFDE_CSSRuleCollection::Data* p2) { - return p1->dwPriority < p2->dwPriority; - }); - for (const auto& rule : m_MatchedRules) - matchedDecls.Add(rule->pDeclaration); - m_MatchedRules.clear(); } - return matchedDecls.GetSize(); + ApplyDeclarations(declArray, pDecl.get(), pDest); } -void CFDE_CSSStyleSelector::MatchRules(CFDE_CSSTagCache* pCache, - CFDE_CSSRuleCollection::Data* pList, - FDE_CSSPseudo ePseudoType) { - while (pList) { - if (MatchSelector(pCache, pList->pSelector, ePseudoType)) - m_MatchedRules.push_back(pList); - pList = pList->pNext; - } -} +void CFDE_CSSStyleSelector::ApplyDeclarations( + const std::vector<const CFDE_CSSDeclaration*>& declArray, + const CFDE_CSSDeclaration* extraDecl, + CFDE_CSSComputedStyle* pComputedStyle) { + std::vector<const CFDE_CSSPropertyHolder*> importants; + std::vector<const CFDE_CSSPropertyHolder*> normals; + std::vector<const CFDE_CSSCustomProperty*> customs; -bool CFDE_CSSStyleSelector::MatchSelector(CFDE_CSSTagCache* pCache, - CFDE_CSSSelector* pSel, - FDE_CSSPseudo ePseudoType) { - uint32_t dwHash; - while (pSel && pCache) { - switch (pSel->GetType()) { - case FDE_CSSSelectorType::Descendant: - dwHash = pSel->GetNameHash(); - while ((pCache = pCache->GetParent()) != nullptr) { - if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) { - continue; - } - if (MatchSelector(pCache, pSel->GetNextSelector(), ePseudoType)) { - return true; - } - } - return false; - case FDE_CSSSelectorType::ID: - dwHash = pCache->HashID(); - if (dwHash != pSel->GetNameHash()) { - return false; - } - break; - case FDE_CSSSelectorType::Class: - dwHash = pCache->HashClass(); - if (dwHash != pSel->GetNameHash()) { - return false; - } - break; - case FDE_CSSSelectorType::Element: - dwHash = pSel->GetNameHash(); - if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) { - return false; - } - break; - case FDE_CSSSelectorType::Pseudo: - dwHash = FDE_GetCSSPseudoByEnum(ePseudoType)->dwHash; - if (dwHash != pSel->GetNameHash()) { - return false; - } - break; - default: - ASSERT(false); - break; - } - pSel = pSel->GetNextSelector(); - } - return !pSel && pCache; -} + for (auto& decl : declArray) + ExtractValues(decl, &importants, &normals, &customs); -void CFDE_CSSStyleSelector::ComputeStyle( - CXFA_CSSTagProvider* pTag, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle) { - ASSERT(iDeclCount >= 0); - ASSERT(pDestStyle); - - static const uint32_t s_dwStyleHash = FX_HashCode_GetW(L"style", true); - static const uint32_t s_dwAlignHash = FX_HashCode_GetW(L"align", true); - - if (!pTag->empty()) { - CFDE_CSSDeclaration* pDecl = nullptr; - for (auto it : *pTag) { - CFX_WideString wsAttri = it.first; - CFX_WideString wsValue = it.second; - uint32_t dwAttriHash = FX_HashCode_GetW(wsAttri.AsStringC(), true); - if (dwAttriHash == s_dwStyleHash) { - if (!pDecl) - pDecl = new CFDE_CSSDeclaration; - - AppendInlineStyle(pDecl, wsValue.c_str(), wsValue.GetLength()); - } else if (dwAttriHash == s_dwAlignHash) { - if (!pDecl) - pDecl = new CFDE_CSSDeclaration; - - FDE_CSSPropertyArgs args; - args.pStringCache = nullptr; - args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSProperty::TextAlign); - pDecl->AddProperty(&args, wsValue.c_str(), wsValue.GetLength()); - } - } + if (extraDecl) + ExtractValues(extraDecl, &importants, &normals, &customs); - if (pDecl) { - CFX_ArrayTemplate<CFDE_CSSDeclaration*> decls; - decls.SetSize(iDeclCount + 1); - CFDE_CSSDeclaration** ppInline = decls.GetData(); - FXSYS_memcpy(ppInline, ppDeclArray, - iDeclCount * sizeof(CFDE_CSSDeclaration*)); - ppInline[iDeclCount++] = pDecl; - ApplyDeclarations(true, const_cast<const CFDE_CSSDeclaration**>(ppInline), - iDeclCount, pDestStyle); - ApplyDeclarations(false, - const_cast<const CFDE_CSSDeclaration**>(ppInline), - iDeclCount, pDestStyle); - return; - } - } + for (auto& prop : normals) + ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle); - if (iDeclCount > 0) { - ASSERT(ppDeclArray); + for (auto& prop : customs) + pComputedStyle->AddCustomStyle(*prop); - ApplyDeclarations(true, ppDeclArray, iDeclCount, pDestStyle); - ApplyDeclarations(false, ppDeclArray, iDeclCount, pDestStyle); - } + for (auto& prop : importants) + ApplyProperty(prop->eProperty, prop->pValue, pComputedStyle); } -void CFDE_CSSStyleSelector::ApplyDeclarations( - bool bPriority, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle) { - CFDE_CSSComputedStyle* pComputedStyle = pDestStyle; - - int32_t i; - if (bPriority) { - CFDE_CSSValue* pLastest = nullptr; - CFDE_CSSValue* pImportant = nullptr; - for (i = 0; i < iDeclCount; ++i) { - bool bImportant; - CFDE_CSSValue* pVal = - ppDeclArray[i]->GetProperty(FDE_CSSProperty::FontSize, bImportant); - if (!pVal) - continue; - - if (bImportant) - pImportant = pVal; - else - pLastest = pVal; - } - if (pImportant) { - ApplyProperty(FDE_CSSProperty::FontSize, pImportant, pComputedStyle); - } else if (pLastest) { - ApplyProperty(FDE_CSSProperty::FontSize, pLastest, pComputedStyle); - } - } else { - CFX_ArrayTemplate<CFDE_CSSDeclaration*> importants; - const CFDE_CSSDeclaration* pDecl = nullptr; - - for (i = 0; i < iDeclCount; ++i) { - pDecl = ppDeclArray[i]; - for (auto it = pDecl->begin(); it != pDecl->end(); it++) { - if ((*it)->eProperty == FDE_CSSProperty::FontSize) - continue; - if (!(*it)->bImportant) { - ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); - } else if (importants.GetSize() == 0 || - importants[importants.GetUpperBound()] != pDecl) { - importants.Add(const_cast<CFDE_CSSDeclaration*>(pDecl)); - } - } - } - - iDeclCount = importants.GetSize(); - for (i = 0; i < iDeclCount; ++i) { - pDecl = importants[i]; - - for (auto it = pDecl->begin(); it != pDecl->end(); it++) { - if ((*it)->bImportant && (*it)->eProperty != FDE_CSSProperty::FontSize) - ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); - } - } - - for (auto it = pDecl->custom_begin(); it != pDecl->custom_end(); it++) { - pComputedStyle->AddCustomStyle((*it)->pwsName, (*it)->pwsValue); - } +void CFDE_CSSStyleSelector::ExtractValues( + const CFDE_CSSDeclaration* decl, + std::vector<const CFDE_CSSPropertyHolder*>* importants, + std::vector<const CFDE_CSSPropertyHolder*>* normals, + std::vector<const CFDE_CSSCustomProperty*>* custom) { + for (const auto& holder : *decl) { + if (holder->bImportant) + importants->push_back(holder.get()); + else + normals->push_back(holder.get()); } + for (auto it = decl->custom_begin(); it != decl->custom_end(); it++) + custom->push_back(it->get()); } void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl, - const FX_WCHAR* psz, - int32_t iLen) { - ASSERT(pDecl && psz && iLen > 0); + const CFX_WideString& style) { + ASSERT(pDecl && !style.IsEmpty()); + auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>(); - if (!pSyntax->Init(psz, iLen, 32, true)) + if (!pSyntax->Init(style.c_str(), style.GetLength(), 32, true)) return; int32_t iLen2 = 0; - const FX_WCHAR* psz2; - FDE_CSSPropertyArgs args; - args.pStringCache = nullptr; - args.pProperty = nullptr; + const FDE_CSSPropertyTable* table = nullptr; CFX_WideString wsName; while (1) { FDE_CSSSyntaxStatus eStatus = pSyntax->DoSyntaxParse(); if (eStatus == FDE_CSSSyntaxStatus::PropertyName) { - psz2 = pSyntax->GetCurrentString(iLen2); - args.pProperty = FDE_GetCSSPropertyByName(CFX_WideStringC(psz2, iLen2)); - if (!args.pProperty) - wsName = CFX_WideStringC(psz2, iLen2); + CFX_WideStringC strValue = pSyntax->GetCurrentString(); + table = FDE_GetCSSPropertyByName(strValue); + if (!table) + wsName = CFX_WideString(strValue); } else if (eStatus == FDE_CSSSyntaxStatus::PropertyValue) { - if (args.pProperty) { - psz2 = pSyntax->GetCurrentString(iLen2); - if (iLen2 > 0) - pDecl->AddProperty(&args, psz2, iLen2); - } else if (iLen2 > 0) { - psz2 = pSyntax->GetCurrentString(iLen2); - if (iLen2 > 0) { - pDecl->AddProperty(&args, wsName.c_str(), wsName.GetLength(), psz2, - iLen2); + if (table || iLen2 > 0) { + CFX_WideStringC strValue = pSyntax->GetCurrentString(); + if (!strValue.IsEmpty()) { + if (table) + pDecl->AddProperty(table, strValue); + else if (iLen2 > 0) + pDecl->AddProperty(wsName, CFX_WideString(strValue)); } } } else { @@ -382,7 +173,7 @@ void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration* pDecl, void CFDE_CSSStyleSelector::ApplyProperty( FDE_CSSProperty eProperty, - CFDE_CSSValue* pValue, + const CFX_RetainPtr<CFDE_CSSValue>& pValue, CFDE_CSSComputedStyle* pComputedStyle) { if (pValue->GetType() != FDE_CSSPrimitiveType::List) { FDE_CSSPrimitiveType eType = pValue->GetType(); @@ -390,21 +181,22 @@ void CFDE_CSSStyleSelector::ApplyProperty( case FDE_CSSProperty::Display: if (eType == FDE_CSSPrimitiveType::Enum) { pComputedStyle->m_NonInheritedData.m_eDisplay = - ToDisplay(ToValue<CFDE_CSSEnumValue>(pValue)->Value()); + ToDisplay(pValue.As<CFDE_CSSEnumValue>()->Value()); } break; case FDE_CSSProperty::FontSize: { FX_FLOAT& fFontSize = pComputedStyle->m_InheritedData.m_fFontSize; if (eType == FDE_CSSPrimitiveType::Number) { - fFontSize = ToValue<CFDE_CSSNumberValue>(pValue)->Apply(fFontSize); + fFontSize = pValue.As<CFDE_CSSNumberValue>()->Apply(fFontSize); } else if (eType == FDE_CSSPrimitiveType::Enum) { - fFontSize = ToFontSize(ToValue<CFDE_CSSEnumValue>(pValue)->Value(), - fFontSize); + fFontSize = + ToFontSize(pValue.As<CFDE_CSSEnumValue>()->Value(), fFontSize); } } break; case FDE_CSSProperty::LineHeight: if (eType == FDE_CSSPrimitiveType::Number) { - const CFDE_CSSNumberValue* v = ToValue<CFDE_CSSNumberValue>(pValue); + CFX_RetainPtr<CFDE_CSSNumberValue> v = + pValue.As<CFDE_CSSNumberValue>(); if (v->Kind() == FDE_CSSNumberType::Number) { pComputedStyle->m_InheritedData.m_fLineHeight = v->Value() * pComputedStyle->m_InheritedData.m_fFontSize; @@ -417,7 +209,7 @@ void CFDE_CSSStyleSelector::ApplyProperty( case FDE_CSSProperty::TextAlign: if (eType == FDE_CSSPrimitiveType::Enum) { pComputedStyle->m_InheritedData.m_eTextAlign = - ToTextAlign(ToValue<CFDE_CSSEnumValue>(pValue)->Value()); + ToTextAlign(pValue.As<CFDE_CSSEnumValue>()->Value()); } break; case FDE_CSSProperty::TextIndent: @@ -428,10 +220,10 @@ void CFDE_CSSStyleSelector::ApplyProperty( case FDE_CSSProperty::FontWeight: if (eType == FDE_CSSPrimitiveType::Enum) { pComputedStyle->m_InheritedData.m_wFontWeight = - ToFontWeight(ToValue<CFDE_CSSEnumValue>(pValue)->Value()); + ToFontWeight(pValue.As<CFDE_CSSEnumValue>()->Value()); } else if (eType == FDE_CSSPrimitiveType::Number) { int32_t iValue = - (int32_t)ToValue<CFDE_CSSNumberValue>(pValue)->Value() / 100; + (int32_t)pValue.As<CFDE_CSSNumberValue>()->Value() / 100; if (iValue >= 1 && iValue <= 9) { pComputedStyle->m_InheritedData.m_wFontWeight = iValue * 100; } @@ -440,13 +232,13 @@ void CFDE_CSSStyleSelector::ApplyProperty( case FDE_CSSProperty::FontStyle: if (eType == FDE_CSSPrimitiveType::Enum) { pComputedStyle->m_InheritedData.m_eFontStyle = - ToFontStyle(ToValue<CFDE_CSSEnumValue>(pValue)->Value()); + ToFontStyle(pValue.As<CFDE_CSSEnumValue>()->Value()); } break; case FDE_CSSProperty::Color: if (eType == FDE_CSSPrimitiveType::RGB) { pComputedStyle->m_InheritedData.m_dwFontColor = - ToValue<CFDE_CSSColorValue>(pValue)->Value(); + pValue.As<CFDE_CSSColorValue>()->Value(); } break; case FDE_CSSProperty::MarginLeft: @@ -536,19 +328,19 @@ void CFDE_CSSStyleSelector::ApplyProperty( case FDE_CSSProperty::VerticalAlign: if (eType == FDE_CSSPrimitiveType::Enum) { pComputedStyle->m_NonInheritedData.m_eVerticalAlign = - ToVerticalAlign(ToValue<CFDE_CSSEnumValue>(pValue)->Value()); + ToVerticalAlign(pValue.As<CFDE_CSSEnumValue>()->Value()); } else if (eType == FDE_CSSPrimitiveType::Number) { pComputedStyle->m_NonInheritedData.m_eVerticalAlign = FDE_CSSVerticalAlign::Number; pComputedStyle->m_NonInheritedData.m_fVerticalAlign = - ToValue<CFDE_CSSNumberValue>(pValue)->Apply( + pValue.As<CFDE_CSSNumberValue>()->Apply( pComputedStyle->m_InheritedData.m_fFontSize); } break; case FDE_CSSProperty::FontVariant: if (eType == FDE_CSSPrimitiveType::Enum) { pComputedStyle->m_InheritedData.m_eFontVariant = - ToFontVariant(ToValue<CFDE_CSSEnumValue>(pValue)->Value()); + ToFontVariant(pValue.As<CFDE_CSSEnumValue>()->Value()); } break; case FDE_CSSProperty::LetterSpacing: @@ -556,7 +348,7 @@ void CFDE_CSSStyleSelector::ApplyProperty( pComputedStyle->m_InheritedData.m_LetterSpacing.Set( FDE_CSSLengthUnit::Normal); } else if (eType == FDE_CSSPrimitiveType::Number) { - if (ToValue<CFDE_CSSNumberValue>(pValue)->Kind() == + if (pValue.As<CFDE_CSSNumberValue>()->Kind() == FDE_CSSNumberType::Percent) { break; } @@ -571,7 +363,7 @@ void CFDE_CSSStyleSelector::ApplyProperty( pComputedStyle->m_InheritedData.m_WordSpacing.Set( FDE_CSSLengthUnit::Normal); } else if (eType == FDE_CSSPrimitiveType::Number) { - if (ToValue<CFDE_CSSNumberValue>(pValue)->Kind() == + if (pValue.As<CFDE_CSSNumberValue>()->Kind() == FDE_CSSNumberType::Percent) { break; } @@ -604,7 +396,7 @@ void CFDE_CSSStyleSelector::ApplyProperty( break; } } else if (pValue->GetType() == FDE_CSSPrimitiveType::List) { - CFDE_CSSValueList* pList = ToValue<CFDE_CSSValueList>(pValue); + CFX_RetainPtr<CFDE_CSSValueList> pList = pValue.As<CFDE_CSSValueList>(); int32_t iCount = pList->CountValues(); if (iCount > 0) { switch (eProperty) { @@ -682,15 +474,16 @@ FDE_CSSFontStyle CFDE_CSSStyleSelector::ToFontStyle( } } -bool CFDE_CSSStyleSelector::SetLengthWithPercent(FDE_CSSLength& width, - FDE_CSSPrimitiveType eType, - CFDE_CSSValue* pValue, - FX_FLOAT fFontSize) { +bool CFDE_CSSStyleSelector::SetLengthWithPercent( + FDE_CSSLength& width, + FDE_CSSPrimitiveType eType, + const CFX_RetainPtr<CFDE_CSSValue>& pValue, + FX_FLOAT fFontSize) { if (eType == FDE_CSSPrimitiveType::Number) { - const CFDE_CSSNumberValue* v = ToValue<CFDE_CSSNumberValue>(pValue); + CFX_RetainPtr<CFDE_CSSNumberValue> v = pValue.As<CFDE_CSSNumberValue>(); if (v->Kind() == FDE_CSSNumberType::Percent) { width.Set(FDE_CSSLengthUnit::Percent, - ToValue<CFDE_CSSNumberValue>(pValue)->Value() / 100.0f); + pValue.As<CFDE_CSSNumberValue>()->Value() / 100.0f); return width.NonZero(); } @@ -698,7 +491,7 @@ bool CFDE_CSSStyleSelector::SetLengthWithPercent(FDE_CSSLength& width, width.Set(FDE_CSSLengthUnit::Point, fValue); return width.NonZero(); } else if (eType == FDE_CSSPrimitiveType::Enum) { - switch (ToValue<CFDE_CSSEnumValue>(pValue)->Value()) { + switch (pValue.As<CFDE_CSSEnumValue>()->Value()) { case FDE_CSSPropertyValue::Auto: width.Set(FDE_CSSLengthUnit::Auto); return true; @@ -770,14 +563,15 @@ FDE_CSSVerticalAlign CFDE_CSSStyleSelector::ToVerticalAlign( } } -uint32_t CFDE_CSSStyleSelector::ToTextDecoration(CFDE_CSSValueList* pValue) { +uint32_t CFDE_CSSStyleSelector::ToTextDecoration( + const CFX_RetainPtr<CFDE_CSSValueList>& pValue) { uint32_t dwDecoration = 0; for (int32_t i = pValue->CountValues() - 1; i >= 0; --i) { - CFDE_CSSValue* pVal = pValue->GetValue(i); + const CFX_RetainPtr<CFDE_CSSValue> pVal = pValue->GetValue(i); if (pVal->GetType() != FDE_CSSPrimitiveType::Enum) continue; - switch (ToValue<CFDE_CSSEnumValue>(pVal)->Value()) { + switch (pVal.As<CFDE_CSSEnumValue>()->Value()) { case FDE_CSSPropertyValue::Underline: dwDecoration |= FDE_CSSTEXTDECORATION_Underline; break; diff --git a/xfa/fde/css/cfde_cssstyleselector.h b/xfa/fde/css/cfde_cssstyleselector.h index 6a7ae9921..c7b6b4164 100644 --- a/xfa/fde/css/cfde_cssstyleselector.h +++ b/xfa/fde/css/cfde_cssstyleselector.h @@ -15,16 +15,15 @@ #include "xfa/fde/css/cfde_cssrulecollection.h" #include "xfa/fde/css/fde_css.h" -class CFDE_CSSAccelerator; class CFDE_CSSComputedStyle; +class CFDE_CSSCustomProperty; class CFDE_CSSDeclaration; +class CFDE_CSSPropertyHolder; class CFDE_CSSSelector; class CFDE_CSSStyleSheet; -class CFDE_CSSTagCache; class CFDE_CSSValue; class CFDE_CSSValueList; class CFGAS_FontMgr; -class CXFA_CSSTagProvider; class CFDE_CSSStyleSelector { public: @@ -32,47 +31,43 @@ class CFDE_CSSStyleSelector { ~CFDE_CSSStyleSelector(); void SetDefFontSize(FX_FLOAT fFontSize); + void SetUAStyleSheet(std::unique_ptr<CFDE_CSSStyleSheet> pSheet); + void UpdateStyleIndex(); - bool SetStyleSheet(FDE_CSSStyleSheetGroup eType, CFDE_CSSStyleSheet* pSheet); - bool SetStyleSheets(FDE_CSSStyleSheetGroup eType, - const CFX_ArrayTemplate<CFDE_CSSStyleSheet*>* pArray); - void SetStylePriority(FDE_CSSStyleSheetGroup eType, - FDE_CSSStyleSheetPriority ePriority); - void UpdateStyleIndex(uint32_t dwMediaList); - CFDE_CSSAccelerator* InitAccelerator(); - CFDE_CSSComputedStyle* CreateComputedStyle( + CFX_RetainPtr<CFDE_CSSComputedStyle> CreateComputedStyle( CFDE_CSSComputedStyle* pParentStyle); - int32_t MatchDeclarations( - CXFA_CSSTagProvider* pTag, - CFX_ArrayTemplate<CFDE_CSSDeclaration*>& matchedDecls, - FDE_CSSPseudo ePseudoType = FDE_CSSPseudo::NONE); - void ComputeStyle(CXFA_CSSTagProvider* pTag, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, + + // Note, the dest style has to be an out param because the CXFA_TextParser + // adds non-inherited data from the parent style. Attempting to copy + // internally will fail as you'll lose the non-inherited data. + void ComputeStyle(const std::vector<const CFDE_CSSDeclaration*>& declArray, + const CFX_WideString& styleString, + const CFX_WideString& alignString, CFDE_CSSComputedStyle* pDestStyle); - protected: - void Reset(); - void MatchRules(CFDE_CSSTagCache* pCache, - CFDE_CSSRuleCollection::Data* pList, - FDE_CSSPseudo ePseudoType); - bool MatchSelector(CFDE_CSSTagCache* pCache, - CFDE_CSSSelector* pSel, - FDE_CSSPseudo ePseudoType); + std::vector<const CFDE_CSSDeclaration*> MatchDeclarations( + const CFX_WideString& tagname); + + private: + bool MatchSelector(const CFX_WideString& tagname, CFDE_CSSSelector* pSel); + void AppendInlineStyle(CFDE_CSSDeclaration* pDecl, - const FX_WCHAR* psz, - int32_t iLen); - void ApplyDeclarations(bool bPriority, - const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount, - CFDE_CSSComputedStyle* pDestStyle); + const CFX_WideString& style); + void ApplyDeclarations( + const std::vector<const CFDE_CSSDeclaration*>& declArray, + const CFDE_CSSDeclaration* extraDecl, + CFDE_CSSComputedStyle* pDestStyle); void ApplyProperty(FDE_CSSProperty eProperty, - CFDE_CSSValue* pValue, + const CFX_RetainPtr<CFDE_CSSValue>& pValue, CFDE_CSSComputedStyle* pComputedStyle); + void ExtractValues(const CFDE_CSSDeclaration* decl, + std::vector<const CFDE_CSSPropertyHolder*>* importants, + std::vector<const CFDE_CSSPropertyHolder*>* normals, + std::vector<const CFDE_CSSCustomProperty*>* custom); bool SetLengthWithPercent(FDE_CSSLength& width, FDE_CSSPrimitiveType eType, - CFDE_CSSValue* pValue, + const CFX_RetainPtr<CFDE_CSSValue>& pValue, FX_FLOAT fFontSize); FX_FLOAT ToFontSize(FDE_CSSPropertyValue eValue, FX_FLOAT fCurFontSize); FDE_CSSDisplay ToDisplay(FDE_CSSPropertyValue eValue); @@ -80,16 +75,13 @@ class CFDE_CSSStyleSelector { uint16_t ToFontWeight(FDE_CSSPropertyValue eValue); FDE_CSSFontStyle ToFontStyle(FDE_CSSPropertyValue eValue); FDE_CSSVerticalAlign ToVerticalAlign(FDE_CSSPropertyValue eValue); - uint32_t ToTextDecoration(CFDE_CSSValueList* pList); + uint32_t ToTextDecoration(const CFX_RetainPtr<CFDE_CSSValueList>& pList); FDE_CSSFontVariant ToFontVariant(FDE_CSSPropertyValue eValue); CFGAS_FontMgr* const m_pFontMgr; FX_FLOAT m_fDefFontSize; - CFX_ArrayTemplate<CFDE_CSSStyleSheet*> m_SheetGroups[3]; - CFDE_CSSRuleCollection m_RuleCollection[3]; - FDE_CSSStyleSheetGroup m_ePriorities[3]; - std::unique_ptr<CFDE_CSSAccelerator> m_pAccelerator; - std::vector<CFDE_CSSRuleCollection::Data*> m_MatchedRules; + std::unique_ptr<CFDE_CSSStyleSheet> m_UAStyles; + CFDE_CSSRuleCollection m_UARules; }; #endif // XFA_FDE_CSS_CFDE_CSSSTYLESELECTOR_H_ diff --git a/xfa/fde/css/cfde_cssstylesheet.cpp b/xfa/fde/css/cfde_cssstylesheet.cpp index 4ff1b9791..c8bf70ec2 100644 --- a/xfa/fde/css/cfde_cssstylesheet.cpp +++ b/xfa/fde/css/cfde_cssstylesheet.cpp @@ -11,17 +11,11 @@ #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" #include "xfa/fde/css/cfde_cssdeclaration.h" -#include "xfa/fde/css/cfde_cssfontfacerule.h" -#include "xfa/fde/css/cfde_cssmediarule.h" -#include "xfa/fde/css/cfde_cssrule.h" #include "xfa/fde/css/cfde_cssstylerule.h" #include "xfa/fde/css/fde_cssdatatable.h" #include "xfa/fgas/crt/fgas_codepage.h" -CFDE_CSSStyleSheet::CFDE_CSSStyleSheet() - : m_wRefCount(1), m_dwMediaList(FDE_CSSMEDIATYPE_ALL) { - ASSERT(m_dwMediaList > 0); -} +CFDE_CSSStyleSheet::CFDE_CSSStyleSheet() {} CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet() { Reset(); @@ -32,56 +26,27 @@ void CFDE_CSSStyleSheet::Reset() { m_StringCache.clear(); } -uint32_t CFDE_CSSStyleSheet::Retain() { - return ++m_wRefCount; -} - -uint32_t CFDE_CSSStyleSheet::Release() { - uint32_t dwRefCount = --m_wRefCount; - if (dwRefCount == 0) - delete this; - return dwRefCount; -} - -uint32_t CFDE_CSSStyleSheet::GetMediaList() const { - return m_dwMediaList; -} - int32_t CFDE_CSSStyleSheet::CountRules() const { return pdfium::CollectionSize<int32_t>(m_RuleArray); } -CFDE_CSSRule* CFDE_CSSStyleSheet::GetRule(int32_t index) { +CFDE_CSSStyleRule* CFDE_CSSStyleSheet::GetRule(int32_t index) const { return m_RuleArray[index].get(); } -bool CFDE_CSSStyleSheet::LoadFromBuffer(const FX_WCHAR* pBuffer, - int32_t iBufSize) { +bool CFDE_CSSStyleSheet::LoadBuffer(const FX_WCHAR* pBuffer, int32_t iBufSize) { ASSERT(pBuffer && iBufSize > 0); auto pSyntax = pdfium::MakeUnique<CFDE_CSSSyntaxParser>(); - return pSyntax->Init(pBuffer, iBufSize) && LoadFromSyntax(pSyntax.get()); -} + if (!pSyntax->Init(pBuffer, iBufSize)) + return false; -bool CFDE_CSSStyleSheet::LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax) { Reset(); FDE_CSSSyntaxStatus eStatus; do { switch (eStatus = pSyntax->DoSyntaxParse()) { case FDE_CSSSyntaxStatus::StyleRule: - eStatus = LoadStyleRule(pSyntax, &m_RuleArray); - break; - case FDE_CSSSyntaxStatus::MediaRule: - eStatus = LoadMediaRule(pSyntax); - break; - case FDE_CSSSyntaxStatus::FontFaceRule: - eStatus = LoadFontFaceRule(pSyntax, &m_RuleArray); - break; - case FDE_CSSSyntaxStatus::ImportRule: - eStatus = LoadImportRule(pSyntax); - break; - case FDE_CSSSyntaxStatus::PageRule: - eStatus = LoadPageRule(pSyntax); + eStatus = LoadStyleRule(pSyntax.get(), &m_RuleArray); break; default: break; @@ -92,95 +57,46 @@ bool CFDE_CSSStyleSheet::LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax) { return eStatus != FDE_CSSSyntaxStatus::Error; } -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadMediaRule( - CFDE_CSSSyntaxParser* pSyntax) { - uint32_t dwMediaList = 0; - CFDE_CSSMediaRule* pMediaRule = nullptr; - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::MediaType: { - int32_t iLen; - const FX_WCHAR* psz = pSyntax->GetCurrentString(iLen); - const FDE_CSSMEDIATYPETABLE* pMediaType = - FDE_GetCSSMediaTypeByName(CFX_WideStringC(psz, iLen)); - if (pMediaType) - dwMediaList |= pMediaType->wValue; - } break; - case FDE_CSSSyntaxStatus::StyleRule: - if (pMediaRule) { - FDE_CSSSyntaxStatus eStatus = - LoadStyleRule(pSyntax, &pMediaRule->GetArray()); - if (eStatus < FDE_CSSSyntaxStatus::None) { - return eStatus; - } - } else { - SkipRuleSet(pSyntax); - } - break; - case FDE_CSSSyntaxStatus::DeclOpen: - if ((dwMediaList & m_dwMediaList) > 0 && !pMediaRule) { - m_RuleArray.push_back( - pdfium::MakeUnique<CFDE_CSSMediaRule>(dwMediaList)); - pMediaRule = - static_cast<CFDE_CSSMediaRule*>(m_RuleArray.back().get()); - } - break; - case FDE_CSSSyntaxStatus::DeclClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( CFDE_CSSSyntaxParser* pSyntax, - std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray) { + std::vector<std::unique_ptr<CFDE_CSSStyleRule>>* ruleArray) { std::vector<std::unique_ptr<CFDE_CSSSelector>> selectors; CFDE_CSSStyleRule* pStyleRule = nullptr; - const FX_WCHAR* pszValue = nullptr; int32_t iValueLen = 0; - FDE_CSSPropertyArgs propertyArgs; - propertyArgs.pStringCache = &m_StringCache; - propertyArgs.pProperty = nullptr; + const FDE_CSSPropertyTable* propertyTable = nullptr; CFX_WideString wsName; - for (;;) { + while (1) { switch (pSyntax->DoSyntaxParse()) { case FDE_CSSSyntaxStatus::Selector: { - pszValue = pSyntax->GetCurrentString(iValueLen); - auto pSelector = CFDE_CSSSelector::FromString(pszValue, iValueLen); + CFX_WideStringC strValue = pSyntax->GetCurrentString(); + auto pSelector = CFDE_CSSSelector::FromString(strValue); if (pSelector) selectors.push_back(std::move(pSelector)); break; } - case FDE_CSSSyntaxStatus::PropertyName: - pszValue = pSyntax->GetCurrentString(iValueLen); - propertyArgs.pProperty = - FDE_GetCSSPropertyByName(CFX_WideStringC(pszValue, iValueLen)); - if (!propertyArgs.pProperty) - wsName = CFX_WideStringC(pszValue, iValueLen); + case FDE_CSSSyntaxStatus::PropertyName: { + CFX_WideStringC strValue = pSyntax->GetCurrentString(); + propertyTable = FDE_GetCSSPropertyByName(strValue); + if (!propertyTable) + wsName = CFX_WideString(strValue); break; - case FDE_CSSSyntaxStatus::PropertyValue: - if (propertyArgs.pProperty) { - pszValue = pSyntax->GetCurrentString(iValueLen); - if (iValueLen > 0) { - pStyleRule->GetDeclaration()->AddProperty(&propertyArgs, pszValue, - iValueLen); - } - } else if (iValueLen > 0) { - pszValue = pSyntax->GetCurrentString(iValueLen); - if (iValueLen > 0) { - pStyleRule->GetDeclaration()->AddProperty( - &propertyArgs, wsName.c_str(), wsName.GetLength(), pszValue, - iValueLen); + } + case FDE_CSSSyntaxStatus::PropertyValue: { + if (propertyTable || iValueLen > 0) { + CFX_WideStringC strValue = pSyntax->GetCurrentString(); + auto decl = pStyleRule->GetDeclaration(); + if (!strValue.IsEmpty()) { + if (propertyTable) { + decl->AddProperty(propertyTable, strValue); + } else { + decl->AddProperty(wsName, CFX_WideString(strValue)); + } } } break; - case FDE_CSSSyntaxStatus::DeclOpen: + } + case FDE_CSSSyntaxStatus::DeclOpen: { if (!pStyleRule && !selectors.empty()) { auto rule = pdfium::MakeUnique<CFDE_CSSStyleRule>(); pStyleRule = rule.get(); @@ -191,12 +107,14 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( return FDE_CSSSyntaxStatus::None; } break; - case FDE_CSSSyntaxStatus::DeclClose: + } + case FDE_CSSSyntaxStatus::DeclClose: { if (pStyleRule && pStyleRule->GetDeclaration()->empty()) { ruleArray->pop_back(); pStyleRule = nullptr; } return FDE_CSSSyntaxStatus::None; + } case FDE_CSSSyntaxStatus::EOS: return FDE_CSSSyntaxStatus::EOS; case FDE_CSSSyntaxStatus::Error: @@ -206,74 +124,8 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( } } -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadFontFaceRule( - CFDE_CSSSyntaxParser* pSyntax, - std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray) { - CFDE_CSSFontFaceRule* pFontFaceRule = nullptr; - const FX_WCHAR* pszValue = nullptr; - int32_t iValueLen = 0; - FDE_CSSPropertyArgs propertyArgs; - propertyArgs.pStringCache = &m_StringCache; - propertyArgs.pProperty = nullptr; - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::PropertyName: - pszValue = pSyntax->GetCurrentString(iValueLen); - propertyArgs.pProperty = - FDE_GetCSSPropertyByName(CFX_WideStringC(pszValue, iValueLen)); - break; - case FDE_CSSSyntaxStatus::PropertyValue: - if (propertyArgs.pProperty) { - pszValue = pSyntax->GetCurrentString(iValueLen); - if (iValueLen > 0) { - pFontFaceRule->GetDeclaration()->AddProperty(&propertyArgs, - pszValue, iValueLen); - } - } - break; - case FDE_CSSSyntaxStatus::DeclOpen: - if (!pFontFaceRule) { - auto rule = pdfium::MakeUnique<CFDE_CSSFontFaceRule>(); - pFontFaceRule = rule.get(); - ruleArray->push_back(std::move(rule)); - } - break; - case FDE_CSSSyntaxStatus::DeclClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadImportRule( - CFDE_CSSSyntaxParser* pSyntax) { - for (;;) { - switch (pSyntax->DoSyntaxParse()) { - case FDE_CSSSyntaxStatus::ImportClose: - return FDE_CSSSyntaxStatus::None; - case FDE_CSSSyntaxStatus::URI: - break; - case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; - case FDE_CSSSyntaxStatus::Error: - default: - return FDE_CSSSyntaxStatus::Error; - } - } -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadPageRule( - CFDE_CSSSyntaxParser* pSyntax) { - return SkipRuleSet(pSyntax); -} - -FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::SkipRuleSet( - CFDE_CSSSyntaxParser* pSyntax) { - for (;;) { +void CFDE_CSSStyleSheet::SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax) { + while (1) { switch (pSyntax->DoSyntaxParse()) { case FDE_CSSSyntaxStatus::Selector: case FDE_CSSSyntaxStatus::DeclOpen: @@ -281,12 +133,10 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::SkipRuleSet( case FDE_CSSSyntaxStatus::PropertyValue: break; case FDE_CSSSyntaxStatus::DeclClose: - return FDE_CSSSyntaxStatus::None; case FDE_CSSSyntaxStatus::EOS: - return FDE_CSSSyntaxStatus::EOS; case FDE_CSSSyntaxStatus::Error: default: - return FDE_CSSSyntaxStatus::Error; + return; } } } diff --git a/xfa/fde/css/cfde_cssstylesheet.h b/xfa/fde/css/cfde_cssstylesheet.h index 2268efa2e..4de377219 100644 --- a/xfa/fde/css/cfde_cssstylesheet.h +++ b/xfa/fde/css/cfde_cssstylesheet.h @@ -11,44 +11,29 @@ #include <unordered_map> #include <vector> -#include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_string.h" #include "xfa/fde/css/cfde_csssyntaxparser.h" -class CFDE_CSSRule; +class CFDE_CSSStyleRule; -class CFDE_CSSStyleSheet : public IFX_Retainable { +class CFDE_CSSStyleSheet { public: CFDE_CSSStyleSheet(); - ~CFDE_CSSStyleSheet() override; + ~CFDE_CSSStyleSheet(); - // IFX_Retainable: - uint32_t Retain() override; - uint32_t Release() override; + bool LoadBuffer(const FX_WCHAR* pBuffer, int32_t iBufSize); - bool LoadFromBuffer(const FX_WCHAR* pBuffer, int32_t iBufSize); - - uint32_t GetMediaList() const; int32_t CountRules() const; - CFDE_CSSRule* GetRule(int32_t index); + CFDE_CSSStyleRule* GetRule(int32_t index) const; private: void Reset(); - bool LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax); FDE_CSSSyntaxStatus LoadStyleRule( CFDE_CSSSyntaxParser* pSyntax, - std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray); - FDE_CSSSyntaxStatus LoadImportRule(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadPageRule(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadMediaRule(CFDE_CSSSyntaxParser* pSyntax); - FDE_CSSSyntaxStatus LoadFontFaceRule( - CFDE_CSSSyntaxParser* pSyntax, - std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray); - FDE_CSSSyntaxStatus SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax); + std::vector<std::unique_ptr<CFDE_CSSStyleRule>>* ruleArray); + void SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax); - uint16_t m_wRefCount; - uint32_t m_dwMediaList; - std::vector<std::unique_ptr<CFDE_CSSRule>> m_RuleArray; + std::vector<std::unique_ptr<CFDE_CSSStyleRule>> m_RuleArray; std::unordered_map<uint32_t, FX_WCHAR*> m_StringCache; }; diff --git a/xfa/fde/css/cfde_cssstylesheet_unittest.cpp b/xfa/fde/css/cfde_cssstylesheet_unittest.cpp index 080b45aa1..fa73a7a9b 100644 --- a/xfa/fde/css/cfde_cssstylesheet_unittest.cpp +++ b/xfa/fde/css/cfde_cssstylesheet_unittest.cpp @@ -15,7 +15,6 @@ #include "xfa/fde/css/cfde_cssdeclaration.h" #include "xfa/fde/css/cfde_cssenumvalue.h" #include "xfa/fde/css/cfde_cssnumbervalue.h" -#include "xfa/fde/css/cfde_cssrule.h" #include "xfa/fde/css/cfde_cssstylerule.h" #include "xfa/fde/css/cfde_cssvaluelist.h" @@ -33,13 +32,10 @@ class CFDE_CSSStyleSheetTest : public testing::Test { size_t decl_count) { ASSERT(sheet_); - EXPECT_TRUE(sheet_->LoadFromBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); EXPECT_EQ(sheet_->CountRules(), 1); - CFDE_CSSRule* rule = sheet_->GetRule(0); - EXPECT_EQ(rule->GetType(), FDE_CSSRuleType::Style); - - CFDE_CSSStyleRule* style = static_cast<CFDE_CSSStyleRule*>(rule); + CFDE_CSSStyleRule* style = sheet_->GetRule(0); EXPECT_EQ(selectors.size(), style->CountSelectorLists()); for (size_t i = 0; i < selectors.size(); i++) { @@ -55,19 +51,19 @@ class CFDE_CSSStyleSheetTest : public testing::Test { ASSERT(decl_); bool important; - CFDE_CSSValue* v = decl_->GetProperty(prop, important); + CFX_RetainPtr<CFDE_CSSValue> v = decl_->GetProperty(prop, &important); EXPECT_EQ(v->GetType(), FDE_CSSPrimitiveType::Number); - EXPECT_EQ(static_cast<CFDE_CSSNumberValue*>(v)->Kind(), type); - EXPECT_EQ(static_cast<CFDE_CSSNumberValue*>(v)->Value(), val); + EXPECT_EQ(v.As<CFDE_CSSNumberValue>()->Kind(), type); + EXPECT_EQ(v.As<CFDE_CSSNumberValue>()->Value(), val); } void VerifyEnum(FDE_CSSProperty prop, FDE_CSSPropertyValue val) { ASSERT(decl_); bool important; - CFDE_CSSValue* v = decl_->GetProperty(prop, important); + CFX_RetainPtr<CFDE_CSSValue> v = decl_->GetProperty(prop, &important); EXPECT_EQ(v->GetType(), FDE_CSSPrimitiveType::Enum); - EXPECT_EQ(static_cast<CFDE_CSSEnumValue*>(v)->Value(), val); + EXPECT_EQ(v.As<CFDE_CSSEnumValue>()->Value(), val); } void VerifyList(FDE_CSSProperty prop, @@ -75,14 +71,14 @@ class CFDE_CSSStyleSheetTest : public testing::Test { ASSERT(decl_); bool important; - CFDE_CSSValue* v = decl_->GetProperty(prop, important); - CFDE_CSSValueList* list = static_cast<CFDE_CSSValueList*>(v); + CFX_RetainPtr<CFDE_CSSValueList> list = + decl_->GetProperty(prop, &important).As<CFDE_CSSValueList>(); EXPECT_EQ(list->CountValues(), pdfium::CollectionSize<int32_t>(values)); for (size_t i = 0; i < values.size(); i++) { - CFDE_CSSValue* val = list->GetValue(i); + CFX_RetainPtr<CFDE_CSSValue> val = list->GetValue(i); EXPECT_EQ(val->GetType(), FDE_CSSPrimitiveType::Enum); - EXPECT_EQ(static_cast<CFDE_CSSEnumValue*>(val)->Value(), values[i]); + EXPECT_EQ(val.As<CFDE_CSSEnumValue>()->Value(), values[i]); } } @@ -93,13 +89,10 @@ class CFDE_CSSStyleSheetTest : public testing::Test { TEST_F(CFDE_CSSStyleSheetTest, ParseMultipleSelectors) { const FX_WCHAR* buf = L"a { border: 10px; }\nb { text-decoration: underline; }"; - EXPECT_TRUE(sheet_->LoadFromBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); EXPECT_EQ(2, sheet_->CountRules()); - CFDE_CSSRule* rule = sheet_->GetRule(0); - EXPECT_EQ(FDE_CSSRuleType::Style, rule->GetType()); - - CFDE_CSSStyleRule* style = static_cast<CFDE_CSSStyleRule*>(rule); + CFDE_CSSStyleRule* style = sheet_->GetRule(0); EXPECT_EQ(1UL, style->CountSelectorLists()); bool found_selector = false; @@ -123,10 +116,7 @@ TEST_F(CFDE_CSSStyleSheetTest, ParseMultipleSelectors) { VerifyFloat(FDE_CSSProperty::BorderBottomWidth, 10.0, FDE_CSSNumberType::Pixels); - rule = sheet_->GetRule(1); - EXPECT_EQ(FDE_CSSRuleType::Style, rule->GetType()); - - style = static_cast<CFDE_CSSStyleRule*>(rule); + style = sheet_->GetRule(1); EXPECT_EQ(1UL, style->CountSelectorLists()); found_selector = false; @@ -145,20 +135,61 @@ TEST_F(CFDE_CSSStyleSheetTest, ParseMultipleSelectors) { {FDE_CSSPropertyValue::Underline}); } -TEST_F(CFDE_CSSStyleSheetTest, ParseMultipleSelectorsCombined) { - LoadAndVerifyDecl(L"a, b, c { border: 5px; }", {L"a", L"b", L"c"}, 4); +TEST_F(CFDE_CSSStyleSheetTest, ParseChildSelectors) { + const FX_WCHAR* buf = L"a b c { border: 10px; }"; + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_EQ(1, sheet_->CountRules()); + + CFDE_CSSStyleRule* style = sheet_->GetRule(0); + EXPECT_EQ(1UL, style->CountSelectorLists()); + + auto sel = style->GetSelectorList(0); + EXPECT_TRUE(sel != nullptr); + EXPECT_EQ(FX_HashCode_GetW(L"c", true), sel->GetNameHash()); + + sel = sel->GetNextSelector(); + EXPECT_TRUE(sel != nullptr); + EXPECT_EQ(FX_HashCode_GetW(L"b", true), sel->GetNameHash()); + + sel = sel->GetNextSelector(); + EXPECT_TRUE(sel != nullptr); + EXPECT_EQ(FX_HashCode_GetW(L"a", true), sel->GetNameHash()); + + sel = sel->GetNextSelector(); + EXPECT_TRUE(sel == nullptr); + + decl_ = style->GetDeclaration(); + EXPECT_EQ(4UL, decl_->PropertyCountForTesting()); + + VerifyFloat(FDE_CSSProperty::BorderLeftWidth, 10.0, + FDE_CSSNumberType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderRightWidth, 10.0, + FDE_CSSNumberType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderTopWidth, 10.0, FDE_CSSNumberType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderBottomWidth, 10.0, + FDE_CSSNumberType::Pixels); } -TEST_F(CFDE_CSSStyleSheetTest, ParseWithPseudo) { - // TODO(dsinclair): I think this is wrong, as the selector just becomes - // :before and we lose the a? - LoadAndVerifyDecl(L"a:before { border: 10px; }", {L":before"}, 4); +TEST_F(CFDE_CSSStyleSheetTest, ParseUnhandledSelectors) { + const FX_WCHAR* buf = L"a > b { padding: 0; }"; + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_EQ(0, sheet_->CountRules()); + + buf = L"a[first] { padding: 0; }"; + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_EQ(0, sheet_->CountRules()); + + buf = L"a+b { padding: 0; }"; + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_EQ(0, sheet_->CountRules()); + + buf = L"a ^ b { padding: 0; }"; + EXPECT_TRUE(sheet_->LoadBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_EQ(0, sheet_->CountRules()); } -TEST_F(CFDE_CSSStyleSheetTest, ParseWithSelectorsAndPseudo) { - // TODO(dsinclair): I think this is wrong as we lose the b on the b:before - LoadAndVerifyDecl(L"a, b:before, c { border: 1px; }", - {L"a", L":before", L"c"}, 4); +TEST_F(CFDE_CSSStyleSheetTest, ParseMultipleSelectorsCombined) { + LoadAndVerifyDecl(L"a, b, c { border: 5px; }", {L"a", L"b", L"c"}, 4); } TEST_F(CFDE_CSSStyleSheetTest, ParseBorder) { diff --git a/xfa/fde/css/cfde_csssyntaxparser.cpp b/xfa/fde/css/cfde_csssyntaxparser.cpp index a24b4eee6..2f7bcce9d 100644 --- a/xfa/fde/css/cfde_csssyntaxparser.cpp +++ b/xfa/fde/css/cfde_csssyntaxparser.cpp @@ -19,24 +19,10 @@ bool IsSelectorStart(FX_WCHAR wch) { (wch >= 'A' && wch <= 'Z'); } -bool ParseCSSURI(const FX_WCHAR* pszValue, int32_t* iOffset, int32_t* iLength) { - ASSERT(pszValue && *iLength > 0); - if (*iLength < 6 || pszValue[*iLength - 1] != ')' || - FXSYS_wcsnicmp(L"url(", pszValue, 4)) { - return false; - } - if (CFDE_CSSDeclaration::ParseCSSString(pszValue + 4, *iLength - 5, iOffset, - iLength)) { - *iOffset += 4; - return true; - } - return false; -} - } // namespace CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser() - : m_iTextDatLen(0), + : m_iTextDataLen(0), m_dwCheck((uint32_t)-1), m_eMode(FDE_CSSSyntaxMode::RuleSet), m_eStatus(FDE_CSSSyntaxStatus::None) {} @@ -60,7 +46,7 @@ bool CFDE_CSSSyntaxParser::Init(const FX_WCHAR* pBuffer, void CFDE_CSSSyntaxParser::Reset(bool bOnlyDeclaration) { m_TextPlane.Reset(); m_TextData.Reset(); - m_iTextDatLen = 0; + m_iTextDataLen = 0; m_dwCheck = (uint32_t)-1; m_eStatus = FDE_CSSSyntaxStatus::None; m_eMode = bOnlyDeclaration ? FDE_CSSSyntaxMode::PropertyName @@ -85,10 +71,6 @@ FDE_CSSSyntaxStatus CFDE_CSSSyntaxParser::DoSyntaxParse() { switch (m_eMode) { case FDE_CSSSyntaxMode::RuleSet: switch (wch) { - case '@': - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::AtRule); - break; case '}': m_TextPlane.MoveNext(); if (RestoreMode()) @@ -120,7 +102,7 @@ FDE_CSSSyntaxStatus CFDE_CSSSyntaxParser::DoSyntaxParse() { case ',': m_TextPlane.MoveNext(); SwitchMode(FDE_CSSSyntaxMode::Selector); - if (m_iTextDatLen > 0) + if (m_iTextDataLen > 0) return FDE_CSSSyntaxStatus::Selector; break; case '{': @@ -194,128 +176,6 @@ FDE_CSSSyntaxStatus CFDE_CSSSyntaxParser::DoSyntaxParse() { } m_TextPlane.MoveNext(); break; - case FDE_CSSSyntaxMode::MediaType: - switch (wch) { - case ',': - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::MediaType); - if (m_iTextDatLen > 0) - return FDE_CSSSyntaxStatus::MediaType; - break; - case '{': { - if (m_ModeStack.empty() || - m_ModeStack.top() != FDE_CSSSyntaxMode::MediaRule) { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - - if (m_TextData.GetLength() > 0) { - SaveTextData(); - return FDE_CSSSyntaxStatus::MediaType; - } - m_TextPlane.MoveNext(); - - // Replace the MediaRule with a RuleSet rule. - m_ModeStack.top() = FDE_CSSSyntaxMode::RuleSet; - - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - return FDE_CSSSyntaxStatus::DeclOpen; - } - case ';': { - if (m_ModeStack.empty() || - m_ModeStack.top() != FDE_CSSSyntaxMode::Import) { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - - if (m_TextData.GetLength() > 0) { - SaveTextData(); - if (IsImportEnabled()) - return FDE_CSSSyntaxStatus::MediaType; - } else { - bool bEnabled = IsImportEnabled(); - m_TextPlane.MoveNext(); - m_ModeStack.pop(); - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - if (bEnabled) { - DisableImport(); - return FDE_CSSSyntaxStatus::ImportClose; - } - } - } break; - case '/': - if (m_TextPlane.GetNextChar() == '*') { - if (SwitchToComment() > 0) - return FDE_CSSSyntaxStatus::MediaType; - break; - } - default: - AppendChar(wch); - break; - } - break; - case FDE_CSSSyntaxMode::URI: { - if (m_ModeStack.empty() || - m_ModeStack.top() != FDE_CSSSyntaxMode::Import) { - m_eStatus = FDE_CSSSyntaxStatus::Error; - return m_eStatus; - } - - if (wch <= ' ' || wch == ';') { - int32_t iURIStart, iURILength = m_TextData.GetLength(); - if (iURILength > 0 && - ParseCSSURI(m_TextData.GetBuffer(), &iURIStart, &iURILength)) { - m_TextData.Subtract(iURIStart, iURILength); - SwitchMode(FDE_CSSSyntaxMode::MediaType); - if (IsImportEnabled()) - return FDE_CSSSyntaxStatus::URI; - break; - } - } - AppendChar(wch); - } break; - case FDE_CSSSyntaxMode::AtRule: - if (wch > ' ') { - AppendChar(wch); - } else { - int32_t iLen = m_TextData.GetLength(); - const FX_WCHAR* psz = m_TextData.GetBuffer(); - if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) { - SwitchMode(FDE_CSSSyntaxMode::Charset); - } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) { - m_ModeStack.push(FDE_CSSSyntaxMode::Import); - SwitchMode(FDE_CSSSyntaxMode::URI); - if (IsImportEnabled()) - return FDE_CSSSyntaxStatus::ImportRule; - break; - } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) { - m_ModeStack.push(FDE_CSSSyntaxMode::MediaRule); - SwitchMode(FDE_CSSSyntaxMode::MediaType); - return FDE_CSSSyntaxStatus::MediaRule; - } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) { - SwitchMode(FDE_CSSSyntaxMode::Selector); - return FDE_CSSSyntaxStatus::FontFaceRule; - } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) { - SwitchMode(FDE_CSSSyntaxMode::Selector); - return FDE_CSSSyntaxStatus::PageRule; - } else { - SwitchMode(FDE_CSSSyntaxMode::UnknownRule); - } - } - break; - case FDE_CSSSyntaxMode::Charset: - if (wch == ';') { - m_TextPlane.MoveNext(); - SwitchMode(FDE_CSSSyntaxMode::RuleSet); - if (IsCharsetEnabled()) { - DisableCharset(); - if (m_iTextDatLen > 0) - return FDE_CSSSyntaxStatus::Charset; - } - } else { - AppendChar(wch); - } - break; case FDE_CSSSyntaxMode::UnknownRule: if (wch == ';') SwitchMode(FDE_CSSSyntaxMode::RuleSet); @@ -348,9 +208,9 @@ bool CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch) { } int32_t CFDE_CSSSyntaxParser::SaveTextData() { - m_iTextDatLen = m_TextData.TrimEnd(); + m_iTextDataLen = m_TextData.TrimEnd(); m_TextData.Clear(); - return m_iTextDatLen; + return m_iTextDataLen; } void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSyntaxMode eMode) { @@ -374,7 +234,6 @@ bool CFDE_CSSSyntaxParser::RestoreMode() { return true; } -const FX_WCHAR* CFDE_CSSSyntaxParser::GetCurrentString(int32_t& iLength) const { - iLength = m_iTextDatLen; - return m_TextData.GetBuffer(); +CFX_WideStringC CFDE_CSSSyntaxParser::GetCurrentString() const { + return CFX_WideStringC(m_TextData.GetBuffer(), m_iTextDataLen); } diff --git a/xfa/fde/css/cfde_csssyntaxparser.h b/xfa/fde/css/cfde_csssyntaxparser.h index 131fe4bf2..b583b98b1 100644 --- a/xfa/fde/css/cfde_csssyntaxparser.h +++ b/xfa/fde/css/cfde_csssyntaxparser.h @@ -17,13 +17,7 @@ enum class FDE_CSSSyntaxMode { RuleSet, Comment, - AtRule, UnknownRule, - Charset, - Import, - MediaRule, - URI, - MediaType, Selector, PropertyName, PropertyValue, @@ -33,15 +27,7 @@ enum class FDE_CSSSyntaxStatus : uint8_t { Error, EOS, None, - Charset, - ImportRule, - ImportClose, - PageRule, StyleRule, - FontFaceRule, - MediaRule, - MediaType, - URI, Selector, DeclOpen, DeclClose, @@ -59,7 +45,7 @@ class CFDE_CSSSyntaxParser { int32_t iTextDatSize = 32, bool bOnlyDeclaration = false); FDE_CSSSyntaxStatus DoSyntaxParse(); - const FX_WCHAR* GetCurrentString(int32_t& iLength) const; + CFX_WideStringC GetCurrentString() const; protected: void Reset(bool bOnlyDeclaration); @@ -78,7 +64,7 @@ class CFDE_CSSSyntaxParser { CFDE_CSSTextBuf m_TextData; CFDE_CSSTextBuf m_TextPlane; - int32_t m_iTextDatLen; + int32_t m_iTextDataLen; uint32_t m_dwCheck; FDE_CSSSyntaxMode m_eMode; FDE_CSSSyntaxStatus m_eStatus; diff --git a/xfa/fde/css/cfde_csstagcache.cpp b/xfa/fde/css/cfde_csstagcache.cpp deleted file mode 100644 index 13e37982d..000000000 --- a/xfa/fde/css/cfde_csstagcache.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 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 "xfa/fde/css/cfde_csstagcache.h" - -#include <algorithm> - -#include "core/fxcrt/fx_ext.h" -#include "xfa/fxfa/app/cxfa_csstagprovider.h" - -CFDE_CSSTagCache::CFDE_CSSTagCache(CFDE_CSSTagCache* parent, - CXFA_CSSTagProvider* tag) - : pTag(tag), pParent(parent), dwIDHash(0), dwTagHash(0), iClassIndex(0) { - static const uint32_t s_dwIDHash = FX_HashCode_GetW(L"id", true); - static const uint32_t s_dwClassHash = FX_HashCode_GetW(L"class", true); - dwTagHash = FX_HashCode_GetW(pTag->GetTagName().AsStringC(), true); - - for (auto it : *pTag) { - CFX_WideString wsValue = it.first; - CFX_WideString wsName = it.second; - uint32_t dwNameHash = FX_HashCode_GetW(wsName.AsStringC(), true); - if (dwNameHash == s_dwClassHash) { - uint32_t dwHash = FX_HashCode_GetW(wsValue.AsStringC(), false); - dwClassHashes.push_back(dwHash); - } else if (dwNameHash == s_dwIDHash) { - dwIDHash = FX_HashCode_GetW(wsValue.AsStringC(), false); - } - } -} - -CFDE_CSSTagCache::CFDE_CSSTagCache(const CFDE_CSSTagCache& it) - : pTag(it.pTag), - pParent(it.pParent), - dwIDHash(it.dwIDHash), - dwTagHash(it.dwTagHash), - iClassIndex(0) { - std::copy(it.dwClassHashes.begin(), it.dwClassHashes.end(), - dwClassHashes.begin()); -} - -CFDE_CSSTagCache::~CFDE_CSSTagCache() {} diff --git a/xfa/fde/css/cfde_csstagcache.h b/xfa/fde/css/cfde_csstagcache.h deleted file mode 100644 index 6d9b4e705..000000000 --- a/xfa/fde/css/cfde_csstagcache.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2017 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 XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_ -#define XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_ - -#include <vector> - -#include "core/fxcrt/fx_system.h" -#include "third_party/base/stl_util.h" - -class CXFA_CSSTagProvider; - -class CFDE_CSSTagCache { - public: - CFDE_CSSTagCache(CFDE_CSSTagCache* parent, CXFA_CSSTagProvider* tag); - CFDE_CSSTagCache(const CFDE_CSSTagCache& it); - ~CFDE_CSSTagCache(); - - CFDE_CSSTagCache* GetParent() const { return pParent; } - CXFA_CSSTagProvider* GetTag() const { return pTag; } - uint32_t HashID() const { return dwIDHash; } - uint32_t HashTag() const { return dwTagHash; } - int32_t CountHashClass() const { - return pdfium::CollectionSize<int32_t>(dwClassHashes); - } - void SetClassIndex(int32_t index) { iClassIndex = index; } - uint32_t HashClass() const { - return iClassIndex < pdfium::CollectionSize<int32_t>(dwClassHashes) - ? dwClassHashes[iClassIndex] - : 0; - } - - private: - CXFA_CSSTagProvider* pTag; - CFDE_CSSTagCache* pParent; - uint32_t dwIDHash; - uint32_t dwTagHash; - int32_t iClassIndex; - std::vector<uint32_t> dwClassHashes; -}; - -#endif // XFA_FDE_CSS_CFDE_CSSTAGCACHE_H_ diff --git a/xfa/fde/css/cfde_cssvaluelist.cpp b/xfa/fde/css/cfde_cssvaluelist.cpp index 64ffb9a17..737ffcb04 100644 --- a/xfa/fde/css/cfde_cssvaluelist.cpp +++ b/xfa/fde/css/cfde_cssvaluelist.cpp @@ -20,6 +20,6 @@ int32_t CFDE_CSSValueList::CountValues() const { return m_ppList.size(); } -CFDE_CSSValue* CFDE_CSSValueList::GetValue(int32_t index) const { - return m_ppList[index].Get(); +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSValueList::GetValue(int32_t index) const { + return m_ppList[index]; } diff --git a/xfa/fde/css/cfde_cssvaluelist.h b/xfa/fde/css/cfde_cssvaluelist.h index 117b92567..a47f8a325 100644 --- a/xfa/fde/css/cfde_cssvaluelist.h +++ b/xfa/fde/css/cfde_cssvaluelist.h @@ -17,7 +17,7 @@ class CFDE_CSSValueList : public CFDE_CSSValue { ~CFDE_CSSValueList() override; int32_t CountValues() const; - CFDE_CSSValue* GetValue(int32_t index) const; + CFX_RetainPtr<CFDE_CSSValue> GetValue(int32_t index) const; protected: std::vector<CFX_RetainPtr<CFDE_CSSValue>> m_ppList; diff --git a/xfa/fde/css/cfde_cssvaluelistparser.cpp b/xfa/fde/css/cfde_cssvaluelistparser.cpp index 3c204b0d2..42c329686 100644 --- a/xfa/fde/css/cfde_cssvaluelistparser.cpp +++ b/xfa/fde/css/cfde_cssvaluelistparser.cpp @@ -16,50 +16,36 @@ CFDE_CSSValueListParser::CFDE_CSSValueListParser(const FX_WCHAR* psz, bool CFDE_CSSValueListParser::NextValue(FDE_CSSPrimitiveType& eType, const FX_WCHAR*& pStart, int32_t& iLength) { - while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator)) { + while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator)) ++m_pCur; - } - if (m_pCur >= m_pEnd) { + + if (m_pCur >= m_pEnd) return false; - } + eType = FDE_CSSPrimitiveType::Unknown; pStart = m_pCur; iLength = 0; FX_WCHAR wch = *m_pCur; if (wch == '#') { - iLength = SkipTo(' '); - if (iLength == 4 || iLength == 7) { + iLength = SkipTo(' ', false, false); + if (iLength == 4 || iLength == 7) eType = FDE_CSSPrimitiveType::RGB; - } } else if ((wch >= '0' && wch <= '9') || wch == '.' || wch == '-' || wch == '+') { - while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator)) { + while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator)) ++m_pCur; - } + iLength = m_pCur - pStart; - if (iLength > 0) { - eType = FDE_CSSPrimitiveType::Number; - } + eType = FDE_CSSPrimitiveType::Number; } else if (wch == '\"' || wch == '\'') { pStart++; - iLength = SkipTo(wch) - 1; + m_pCur++; + iLength = SkipTo(wch, false, false); m_pCur++; eType = FDE_CSSPrimitiveType::String; } else if (m_pEnd - m_pCur > 5 && m_pCur[3] == '(') { - if (FXSYS_wcsnicmp(L"url", m_pCur, 3) == 0) { - wch = m_pCur[4]; - if (wch == '\"' || wch == '\'') { - pStart += 5; - iLength = SkipTo(wch) - 6; - m_pCur += 2; - } else { - pStart += 4; - iLength = SkipTo(')') - 4; - m_pCur++; - } - eType = FDE_CSSPrimitiveType::String; - } else if (FXSYS_wcsnicmp(L"rgb", m_pCur, 3) == 0) { - iLength = SkipTo(')') + 1; + if (FXSYS_wcsnicmp(L"rgb", m_pCur, 3) == 0) { + iLength = SkipTo(')', false, false) + 1; m_pCur++; eType = FDE_CSSPrimitiveType::RGB; } @@ -69,48 +55,32 @@ bool CFDE_CSSValueListParser::NextValue(FDE_CSSPrimitiveType& eType, } return m_pCur <= m_pEnd && iLength > 0; } + int32_t CFDE_CSSValueListParser::SkipTo(FX_WCHAR wch, - bool bWSSeparator, - bool bBrContinue) { + bool breakOnSpace, + bool matchBrackets) { const FX_WCHAR* pStart = m_pCur; - if (!bBrContinue) { - if (bWSSeparator) { - while ((++m_pCur < m_pEnd) && (*m_pCur != wch) && (*m_pCur > ' ')) { - continue; - } - } else { - while (++m_pCur < m_pEnd && *m_pCur != wch) { - continue; - } - } - - } else { - int32_t iBracketCount = 0; - if (bWSSeparator) { - while ((m_pCur < m_pEnd) && (*m_pCur != wch) && (*m_pCur > ' ')) { - if (*m_pCur == '(') { - iBracketCount++; - } else if (*m_pCur == ')') { - iBracketCount--; - } - m_pCur++; - } - } else { - while (m_pCur < m_pEnd && *m_pCur != wch) { - if (*m_pCur == '(') { - iBracketCount++; - } else if (*m_pCur == ')') { - iBracketCount--; - } - m_pCur++; - } - } - while (iBracketCount > 0 && m_pCur < m_pEnd) { - if (*m_pCur == ')') { - iBracketCount--; - } + int32_t bracketCount = 0; + while (m_pCur < m_pEnd && *m_pCur != wch) { + if (breakOnSpace && *m_pCur <= ' ') + break; + if (!matchBrackets) { m_pCur++; + continue; } + + if (*m_pCur == '(') + bracketCount++; + else if (*m_pCur == ')') + bracketCount--; + + m_pCur++; + } + + while (bracketCount > 0 && m_pCur < m_pEnd) { + if (*m_pCur == ')') + bracketCount--; + m_pCur++; } return m_pCur - pStart; } diff --git a/xfa/fde/css/cfde_cssvaluelistparser.h b/xfa/fde/css/cfde_cssvaluelistparser.h index 731ac3c84..734aed8a5 100644 --- a/xfa/fde/css/cfde_cssvaluelistparser.h +++ b/xfa/fde/css/cfde_cssvaluelistparser.h @@ -19,12 +19,11 @@ class CFDE_CSSValueListParser { bool NextValue(FDE_CSSPrimitiveType& eType, const FX_WCHAR*& pStart, int32_t& iLength); + FX_WCHAR m_Separator; - protected: - int32_t SkipTo(FX_WCHAR wch, - bool bWSSeparator = false, - bool bBrContinue = false); + private: + int32_t SkipTo(FX_WCHAR wch, bool breakOnSpace, bool matchBrackets); const FX_WCHAR* m_pCur; const FX_WCHAR* m_pEnd; diff --git a/xfa/fde/css/cfde_cssvaluelistparser_unittest.cpp b/xfa/fde/css/cfde_cssvaluelistparser_unittest.cpp new file mode 100644 index 000000000..71bb807f3 --- /dev/null +++ b/xfa/fde/css/cfde_cssvaluelistparser_unittest.cpp @@ -0,0 +1,142 @@ +// Copyright 2017 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 "xfa/fde/css/cfde_cssvaluelistparser.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/base/ptr_util.h" + +TEST(CFDE_CSSValueListParser, rgb_short) { + FDE_CSSPrimitiveType type; + const FX_WCHAR* start; + int32_t len; + + auto parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"#abc", 4, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::RGB, type); + EXPECT_EQ(L"#abc", CFX_WideString(start, len)); + EXPECT_FALSE(parser->NextValue(type, start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"#abcdef", 7, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::RGB, type); + EXPECT_EQ(L"#abcdef", CFX_WideString(start, len)); + EXPECT_FALSE(parser->NextValue(type, start, len)); + + parser = + pdfium::MakeUnique<CFDE_CSSValueListParser>(L"rgb(1, 255, 4)", 14, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::RGB, type); + EXPECT_EQ(L"rgb(1, 255, 4)", CFX_WideString(start, len)); + + parser = + pdfium::MakeUnique<CFDE_CSSValueListParser>(L"#abcdefghij", 11, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Unknown, type); + EXPECT_EQ(L"#abcdefghij", CFX_WideString(start, len)); + EXPECT_FALSE(parser->NextValue(type, start, len)); +} + +TEST(CFDE_CSSValueListParser, number_parsing) { + FDE_CSSPrimitiveType type; + const FX_WCHAR* start; + int32_t len; + + auto parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"1234", 4, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"1234", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"-1234", 5, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"-1234", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"+1234", 5, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"+1234", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L".1234", 5, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L".1234", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"4321.1234", 9, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"4321.1234", CFX_WideString(start, len)); + + // TODO(dsinclair): These should probably fail but currently don't. + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"4321.12.34", 10, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"4321.12.34", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"43a1.12.34", 10, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"43a1.12.34", CFX_WideString(start, len)); +} + +TEST(CFDE_CSSValueListParser, string_parsing) { + FDE_CSSPrimitiveType type; + const FX_WCHAR* start; + int32_t len; + + auto parser = + pdfium::MakeUnique<CFDE_CSSValueListParser>(L"'string'", 8, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::String, type); + EXPECT_EQ(L"string", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"\"another string\"", + 16, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::String, type); + EXPECT_EQ(L"another string", CFX_WideString(start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>(L"standalone", 10, L' '); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::String, type); + EXPECT_EQ(L"standalone", CFX_WideString(start, len)); +} + +TEST(CFDE_CSSValueListParser, multiparsing) { + FDE_CSSPrimitiveType type; + const FX_WCHAR* start; + int32_t len; + + auto parser = + pdfium::MakeUnique<CFDE_CSSValueListParser>(L"1, 2, 3", 7, L','); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"1", CFX_WideString(start, len)); + + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"2", CFX_WideString(start, len)); + + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"3", CFX_WideString(start, len)); + + EXPECT_FALSE(parser->NextValue(type, start, len)); + + parser = pdfium::MakeUnique<CFDE_CSSValueListParser>( + L"'str', rgb(1, 2, 3), 4", 22, L','); + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::String, type); + EXPECT_EQ(L"str", CFX_WideString(start, len)); + + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::RGB, type); + EXPECT_EQ(L"rgb(1, 2, 3)", CFX_WideString(start, len)); + + EXPECT_TRUE(parser->NextValue(type, start, len)); + EXPECT_EQ(FDE_CSSPrimitiveType::Number, type); + EXPECT_EQ(L"4", CFX_WideString(start, len)); +} diff --git a/xfa/fde/css/fde_css.h b/xfa/fde/css/fde_css.h index 219465767..6c2629f5e 100644 --- a/xfa/fde/css/fde_css.h +++ b/xfa/fde/css/fde_css.h @@ -12,18 +12,6 @@ #include "xfa/fgas/crt/fgas_utils.h" #include "xfa/fgas/font/cfgas_fontmgr.h" -enum FDE_CSSMEDIATYPE { - FDE_CSSMEDIATYPE_Braille = 0x01, - FDE_CSSMEDIATYPE_Emboss = 0x02, - FDE_CSSMEDIATYPE_Handheld = 0x04, - FDE_CSSMEDIATYPE_Print = 0x08, - FDE_CSSMEDIATYPE_Projection = 0x10, - FDE_CSSMEDIATYPE_Screen = 0x20, - FDE_CSSMEDIATYPE_TTY = 0x40, - FDE_CSSMEDIATYPE_TV = 0x80, - FDE_CSSMEDIATYPE_ALL = 0xFF, -}; - enum FDE_CSSVALUETYPE { FDE_CSSVALUETYPE_Primitive = 1 << 0, FDE_CSSVALUETYPE_List = 1 << 1, @@ -137,17 +125,7 @@ enum class FDE_CSSProperty : uint8_t { LAST_MARKER }; -enum class FDE_CSSPseudo : uint8_t { After, Before, NONE }; - -enum class FDE_CSSSelectorType : uint8_t { - Element = 0, - Descendant, - Class, - Pseudo, - ID, -}; - -enum class FDE_CSSRuleType : uint8_t { Style, Media, FontFace }; +enum class FDE_CSSSelectorType : uint8_t { Element = 0, Descendant }; enum class FDE_CSSLengthUnit : uint8_t { Auto, @@ -205,18 +183,6 @@ enum FDE_CSSTEXTDECORATION { FDE_CSSTEXTDECORATION_Double = 1 << 4, }; -enum class FDE_CSSStyleSheetGroup : uint8_t { - UserAgent = 0, - User, - Author, -}; - -enum class FDE_CSSStyleSheetPriority : uint8_t { - High = 0, - Mid, - Low, -}; - class FDE_CSSLength { public: FDE_CSSLength() {} diff --git a/xfa/fde/css/fde_cssdatatable.cpp b/xfa/fde/css/fde_cssdatatable.cpp index fd4ef6bff..d61c610fe 100644 --- a/xfa/fde/css/fde_cssdatatable.cpp +++ b/xfa/fde/css/fde_cssdatatable.cpp @@ -173,14 +173,6 @@ static_assert(g_iCSSPropertyValueCount == static_cast<int32_t>(FDE_CSSPropertyValue::LAST_MARKER), "Property value table differs in size from property value enum"); -static const FDE_CSSMEDIATYPETABLE g_FDE_CSSMediaTypes[] = { - {0xF09, FDE_CSSMEDIATYPE_Emboss}, {FDE_CSSMEDIATYPE_Screen}, - {0x536A, FDE_CSSMEDIATYPE_TV}, {0x741D, FDE_CSSMEDIATYPE_Projection}, - {0x76ED, FDE_CSSMEDIATYPE_Print}, {0x7CFB, FDE_CSSMEDIATYPE_Braille}, - {0x9578, FDE_CSSMEDIATYPE_Handheld}, {0xC8E1, FDE_CSSMEDIATYPE_TTY}, - {0xD0F9, FDE_CSSMEDIATYPE_ALL}, -}; - static const FDE_CSSLengthUnitTable g_FDE_CSSLengthUnits[] = { {0x0672, FDE_CSSNumberType::EMS}, {0x067D, FDE_CSSNumberType::EXS}, @@ -204,15 +196,6 @@ static const FDE_CSSCOLORTABLE g_FDE_CSSColors[] = { {0xF6EFFF31, 0xff008000}, }; -static const FDE_CSSPseudoTable g_FDE_CSSPseudoType[] = { - {FDE_CSSPseudo::After, L":after", 0x16EE1FEC}, - {FDE_CSSPseudo::Before, L":before", 0x7DCDDE2D}, -}; - -const FDE_CSSPseudoTable* FDE_GetCSSPseudoByEnum(FDE_CSSPseudo ePseudo) { - return g_FDE_CSSPseudoType + static_cast<int>(ePseudo); -} - const FDE_CSSPropertyTable* FDE_GetCSSPropertyByName( const CFX_WideStringC& wsName) { ASSERT(!wsName.IsEmpty()); @@ -259,28 +242,6 @@ const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByName( return nullptr; } -const FDE_CSSMEDIATYPETABLE* FDE_GetCSSMediaTypeByName( - const CFX_WideStringC& wsName) { - ASSERT(!wsName.IsEmpty()); - uint16_t wHash = FX_HashCode_GetW(wsName, true); - int32_t iEnd = - sizeof(g_FDE_CSSMediaTypes) / sizeof(FDE_CSSMEDIATYPETABLE) - 1; - int32_t iMid, iStart = 0; - uint16_t uMid; - do { - iMid = (iStart + iEnd) / 2; - uMid = g_FDE_CSSMediaTypes[iMid].wHash; - if (wHash == uMid) { - return g_FDE_CSSMediaTypes + iMid; - } else if (wHash > uMid) { - iStart = iMid + 1; - } else { - iEnd = iMid - 1; - } - } while (iStart <= iEnd); - return nullptr; -} - const FDE_CSSLengthUnitTable* FDE_GetCSSLengthUnitByName( const CFX_WideStringC& wsName) { ASSERT(!wsName.IsEmpty()); diff --git a/xfa/fde/css/fde_cssdatatable.h b/xfa/fde/css/fde_cssdatatable.h index 4769f1665..afb0b8502 100644 --- a/xfa/fde/css/fde_cssdatatable.h +++ b/xfa/fde/css/fde_cssdatatable.h @@ -31,11 +31,6 @@ struct FDE_CSSPropertyValueTable { uint32_t dwHash; }; -struct FDE_CSSMEDIATYPETABLE { - uint16_t wHash; - uint16_t wValue; -}; - struct FDE_CSSLengthUnitTable { uint16_t wHash; FDE_CSSNumberType wValue; @@ -46,12 +41,6 @@ struct FDE_CSSCOLORTABLE { FX_ARGB dwValue; }; -struct FDE_CSSPseudoTable { - FDE_CSSPseudo eName; - const FX_WCHAR* pszName; - uint32_t dwHash; -}; - const FDE_CSSPropertyTable* FDE_GetCSSPropertyByName( const CFX_WideStringC& wsName); const FDE_CSSPropertyTable* FDE_GetCSSPropertyByEnum(FDE_CSSProperty eName); @@ -59,14 +48,9 @@ const FDE_CSSPropertyTable* FDE_GetCSSPropertyByEnum(FDE_CSSProperty eName); const FDE_CSSPropertyValueTable* FDE_GetCSSPropertyValueByName( const CFX_WideStringC& wsName); -const FDE_CSSMEDIATYPETABLE* FDE_GetCSSMediaTypeByName( - const CFX_WideStringC& wsName); - const FDE_CSSLengthUnitTable* FDE_GetCSSLengthUnitByName( const CFX_WideStringC& wsName); const FDE_CSSCOLORTABLE* FDE_GetCSSColorByName(const CFX_WideStringC& wsName); -const FDE_CSSPseudoTable* FDE_GetCSSPseudoByEnum(FDE_CSSPseudo ePseudo); - #endif // XFA_FDE_CSS_FDE_CSSDATATABLE_H_ diff --git a/xfa/fde/fde_gedevice.cpp b/xfa/fde/fde_gedevice.cpp index 081f00a03..db05f7624 100644 --- a/xfa/fde/fde_gedevice.cpp +++ b/xfa/fde/fde_gedevice.cpp @@ -24,29 +24,36 @@ CFDE_RenderDevice::CFDE_RenderDevice(CFX_RenderDevice* pDevice, ASSERT(pDevice); FX_RECT rt = m_pDevice->GetClipBox(); - m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(), - (FX_FLOAT)rt.Height()); + m_rtClip = CFX_RectF( + static_cast<FX_FLOAT>(rt.left), static_cast<FX_FLOAT>(rt.top), + static_cast<FX_FLOAT>(rt.Width()), static_cast<FX_FLOAT>(rt.Height())); } CFDE_RenderDevice::~CFDE_RenderDevice() { if (m_bOwnerDevice) delete m_pDevice; } + int32_t CFDE_RenderDevice::GetWidth() const { return m_pDevice->GetWidth(); } + int32_t CFDE_RenderDevice::GetHeight() const { return m_pDevice->GetHeight(); } + void CFDE_RenderDevice::SaveState() { m_pDevice->SaveState(); } + void CFDE_RenderDevice::RestoreState() { m_pDevice->RestoreState(false); const FX_RECT& rt = m_pDevice->GetClipBox(); - m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(), - (FX_FLOAT)rt.Height()); + m_rtClip = CFX_RectF( + static_cast<FX_FLOAT>(rt.left), static_cast<FX_FLOAT>(rt.top), + static_cast<FX_FLOAT>(rt.Width()), static_cast<FX_FLOAT>(rt.Height())); } + bool CFDE_RenderDevice::SetClipRect(const CFX_RectF& rtClip) { m_rtClip = rtClip; return m_pDevice->SetClip_Rect(FX_RECT((int32_t)FXSYS_floor(rtClip.left), @@ -54,21 +61,27 @@ bool CFDE_RenderDevice::SetClipRect(const CFX_RectF& rtClip) { (int32_t)FXSYS_ceil(rtClip.right()), (int32_t)FXSYS_ceil(rtClip.bottom()))); } + const CFX_RectF& CFDE_RenderDevice::GetClipRect() { return m_rtClip; } + bool CFDE_RenderDevice::SetClipPath(const CFDE_Path* pClip) { return false; } + CFDE_Path* CFDE_RenderDevice::GetClipPath() const { return nullptr; } + FX_FLOAT CFDE_RenderDevice::GetDpiX() const { return 96; } + FX_FLOAT CFDE_RenderDevice::GetDpiY() const { return 96; } + bool CFDE_RenderDevice::DrawImage(CFX_DIBSource* pDib, const CFX_RectF* pSrcRect, const CFX_RectF& dstRect, @@ -78,11 +91,13 @@ bool CFDE_RenderDevice::DrawImage(CFX_DIBSource* pDib, if (pSrcRect) { srcRect = *pSrcRect; } else { - srcRect.Set(0, 0, (FX_FLOAT)pDib->GetWidth(), (FX_FLOAT)pDib->GetHeight()); + srcRect = CFX_RectF(0, 0, static_cast<FX_FLOAT>(pDib->GetWidth()), + static_cast<FX_FLOAT>(pDib->GetHeight())); } - if (srcRect.IsEmpty()) { + + if (srcRect.IsEmpty()) return false; - } + CFX_Matrix dib2fxdev; if (pImgMatrix) { dib2fxdev = *pImgMatrix; @@ -104,6 +119,7 @@ bool CFDE_RenderDevice::DrawImage(CFX_DIBSource* pDib, m_pDevice->CancelDIBits(handle); return !!handle; } + bool CFDE_RenderDevice::DrawString(CFDE_Brush* pBrush, const CFX_RetainPtr<CFGAS_GEFont>& pFont, const FXTEXT_CHARPOS* pCharPos, @@ -152,12 +168,10 @@ bool CFDE_RenderDevice::DrawString(CFDE_Brush* pBrush, #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ FxFont.SetFace(pFxFont->GetFace()); m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, -fFontSize, - (const CFX_Matrix*)pMatrix, argb, - FXTEXT_CLEARTYPE); + pMatrix, argb, FXTEXT_CLEARTYPE); #else m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, -fFontSize, - (const CFX_Matrix*)pMatrix, argb, - FXTEXT_CLEARTYPE); + pMatrix, argb, FXTEXT_CLEARTYPE); #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ } pCurFont = pSTFont; @@ -172,15 +186,14 @@ bool CFDE_RenderDevice::DrawString(CFDE_Brush* pBrush, pFxFont = pCurFont->GetDevFont(); #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ FxFont.SetFace(pFxFont->GetFace()); - bool bRet = m_pDevice->DrawNormalText( - iCurCount, pCurCP, &FxFont, -fFontSize, (const CFX_Matrix*)pMatrix, - argb, FXTEXT_CLEARTYPE); + bool bRet = + m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, -fFontSize, + pMatrix, argb, FXTEXT_CLEARTYPE); FxFont.SetFace(nullptr); return bRet; #else return m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, -fFontSize, - (const CFX_Matrix*)pMatrix, argb, - FXTEXT_CLEARTYPE); + pMatrix, argb, FXTEXT_CLEARTYPE); #endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ } @@ -198,18 +211,19 @@ bool CFDE_RenderDevice::DrawBezier(CFDE_Pen* pPen, const CFX_PointF& pt3, const CFX_PointF& pt4, const CFX_Matrix* pMatrix) { - CFX_PointsF points; - points.Add(pt1); - points.Add(pt2); - points.Add(pt3); - points.Add(pt4); + std::vector<CFX_PointF> points; + points.push_back(pt1); + points.push_back(pt2); + points.push_back(pt3); + points.push_back(pt4); CFDE_Path path; path.AddBezier(points); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::DrawCurve(CFDE_Pen* pPen, FX_FLOAT fPenWidth, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, bool bClosed, FX_FLOAT fTension, const CFX_Matrix* pMatrix) { @@ -217,6 +231,7 @@ bool CFDE_RenderDevice::DrawCurve(CFDE_Pen* pPen, path.AddCurve(points, bClosed, fTension); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::DrawEllipse(CFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFX_RectF& rect, @@ -225,14 +240,16 @@ bool CFDE_RenderDevice::DrawEllipse(CFDE_Pen* pPen, path.AddEllipse(rect); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::DrawLines(CFDE_Pen* pPen, FX_FLOAT fPenWidth, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, const CFX_Matrix* pMatrix) { CFDE_Path path; path.AddLines(points); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::DrawLine(CFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFX_PointF& pt1, @@ -242,6 +259,7 @@ bool CFDE_RenderDevice::DrawLine(CFDE_Pen* pPen, path.AddLine(pt1, pt2); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::DrawPath(CFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFDE_Path* pPath, @@ -257,14 +275,16 @@ bool CFDE_RenderDevice::DrawPath(CFDE_Pen* pPen, return m_pDevice->DrawPath(&pGePath->m_Path, (const CFX_Matrix*)pMatrix, &graphState, 0, pPen->GetColor(), 0); } + bool CFDE_RenderDevice::DrawPolygon(CFDE_Pen* pPen, FX_FLOAT fPenWidth, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, const CFX_Matrix* pMatrix) { CFDE_Path path; path.AddPolygon(points); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::DrawRectangle(CFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFX_RectF& rect, @@ -273,14 +293,16 @@ bool CFDE_RenderDevice::DrawRectangle(CFDE_Pen* pPen, path.AddRectangle(rect); return DrawPath(pPen, fPenWidth, &path, pMatrix); } + bool CFDE_RenderDevice::FillClosedCurve(CFDE_Brush* pBrush, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, FX_FLOAT fTension, const CFX_Matrix* pMatrix) { CFDE_Path path; path.AddCurve(points, true, fTension); return FillPath(pBrush, &path, pMatrix); } + bool CFDE_RenderDevice::FillEllipse(CFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix* pMatrix) { @@ -288,13 +310,15 @@ bool CFDE_RenderDevice::FillEllipse(CFDE_Brush* pBrush, path.AddEllipse(rect); return FillPath(pBrush, &path, pMatrix); } + bool CFDE_RenderDevice::FillPolygon(CFDE_Brush* pBrush, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, const CFX_Matrix* pMatrix) { CFDE_Path path; path.AddPolygon(points); return FillPath(pBrush, &path, pMatrix); } + bool CFDE_RenderDevice::FillRectangle(CFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix* pMatrix) { @@ -302,6 +326,7 @@ bool CFDE_RenderDevice::FillRectangle(CFDE_Brush* pBrush, path.AddRectangle(rect); return FillPath(pBrush, &path, pMatrix); } + bool CFDE_RenderDevice::CreatePen(CFDE_Pen* pPen, FX_FLOAT fPenWidth, CFX_GraphStateData& graphState) { diff --git a/xfa/fde/fde_gedevice.h b/xfa/fde/fde_gedevice.h index 170bef595..7c772cfd0 100644 --- a/xfa/fde/fde_gedevice.h +++ b/xfa/fde/fde_gedevice.h @@ -7,6 +7,8 @@ #ifndef XFA_FDE_FDE_GEDEVICE_H_ #define XFA_FDE_FDE_GEDEVICE_H_ +#include <vector> + #include "core/fxge/cfx_renderdevice.h" #include "xfa/fgas/font/cfgas_gefont.h" @@ -52,7 +54,7 @@ class CFDE_RenderDevice { const CFX_Matrix* pMatrix = nullptr); bool DrawCurve(CFDE_Pen* pPen, FX_FLOAT fPenWidth, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, bool bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix* pMatrix = nullptr); @@ -62,7 +64,7 @@ class CFDE_RenderDevice { const CFX_Matrix* pMatrix = nullptr); bool DrawLines(CFDE_Pen* pPen, FX_FLOAT fPenWidth, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, const CFX_Matrix* pMatrix = nullptr); bool DrawLine(CFDE_Pen* pPen, FX_FLOAT fPenWidth, @@ -75,14 +77,14 @@ class CFDE_RenderDevice { const CFX_Matrix* pMatrix = nullptr); bool DrawPolygon(CFDE_Pen* pPen, FX_FLOAT fPenWidth, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, const CFX_Matrix* pMatrix = nullptr); bool DrawRectangle(CFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFX_RectF& rect, const CFX_Matrix* pMatrix = nullptr); bool FillClosedCurve(CFDE_Brush* pBrush, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, FX_FLOAT fTension = 0.5f, const CFX_Matrix* pMatrix = nullptr); bool FillEllipse(CFDE_Brush* pBrush, @@ -92,7 +94,7 @@ class CFDE_RenderDevice { const CFDE_Path* pPath, const CFX_Matrix* pMatrix = nullptr); bool FillPolygon(CFDE_Brush* pBrush, - const CFX_PointsF& points, + const std::vector<CFX_PointF>& points, const CFX_Matrix* pMatrix = nullptr); bool FillRectangle(CFDE_Brush* pBrush, const CFX_RectF& rect, diff --git a/xfa/fde/fde_render.cpp b/xfa/fde/fde_render.cpp index c0fb926c3..b6a8f7edd 100644 --- a/xfa/fde/fde_render.cpp +++ b/xfa/fde/fde_render.cpp @@ -61,7 +61,6 @@ FDE_RENDERSTATUS CFDE_RenderContext::DoRender(IFX_Pause* pPause) { rm.TransformRect(rtDocClip); IFDE_VisualSet* pVisualSet; FDE_TEXTEDITPIECE* pPiece; - CFX_RectF rtObj; int32_t iCount = 0; while (true) { pPiece = m_pIterator->GetNext(pVisualSet); @@ -69,9 +68,7 @@ FDE_RENDERSTATUS CFDE_RenderContext::DoRender(IFX_Pause* pPause) { eStatus = FDE_RENDERSTATUS_Done; break; } - rtObj.Empty(); - pVisualSet->GetRect(pPiece, rtObj); - if (!rtDocClip.IntersectWith(rtObj)) + if (!rtDocClip.IntersectWith(pVisualSet->GetRect(*pPiece))) continue; switch (pVisualSet->GetType()) { @@ -111,7 +108,7 @@ void CFDE_RenderContext::RenderText(IFDE_TextSet* pTextSet, if (!pFont) return; - int32_t iCount = pTextSet->GetDisplayPos(pText, nullptr, false); + int32_t iCount = pTextSet->GetDisplayPos(*pText, nullptr, false); if (iCount < 1) return; @@ -121,7 +118,7 @@ void CFDE_RenderContext::RenderText(IFDE_TextSet* pTextSet, if (m_CharPos.size() < static_cast<size_t>(iCount)) m_CharPos.resize(iCount, FXTEXT_CHARPOS()); - iCount = pTextSet->GetDisplayPos(pText, m_CharPos.data(), false); + iCount = pTextSet->GetDisplayPos(*pText, m_CharPos.data(), false); FX_FLOAT fFontSize = pTextSet->GetFontSize(); FX_ARGB dwColor = pTextSet->GetFontColor(); m_pBrush->SetColor(dwColor); diff --git a/xfa/fde/fde_visualset.h b/xfa/fde/fde_visualset.h index 8aef237ba..5cf02cde9 100644 --- a/xfa/fde/fde_visualset.h +++ b/xfa/fde/fde_visualset.h @@ -7,6 +7,8 @@ #ifndef XFA_FDE_FDE_VISUALSET_H_ #define XFA_FDE_FDE_VISUALSET_H_ +#include <vector> + #include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" @@ -15,7 +17,7 @@ #include "xfa/fde/fde_object.h" #include "xfa/fgas/font/cfgas_fontmgr.h" -struct FXTEXT_CHARPOS; +class FXTEXT_CHARPOS; enum FDE_VISUALOBJTYPE { FDE_VISUALOBJ_Canvas = 0x00, @@ -23,18 +25,26 @@ enum FDE_VISUALOBJTYPE { }; struct FDE_TEXTEDITPIECE { + FDE_TEXTEDITPIECE(); + FDE_TEXTEDITPIECE(const FDE_TEXTEDITPIECE& that); + ~FDE_TEXTEDITPIECE(); + int32_t nStart; int32_t nCount; int32_t nBidiLevel; CFX_RectF rtPiece; uint32_t dwCharStyles; }; +inline FDE_TEXTEDITPIECE::FDE_TEXTEDITPIECE() = default; +inline FDE_TEXTEDITPIECE::FDE_TEXTEDITPIECE(const FDE_TEXTEDITPIECE& that) = + default; +inline FDE_TEXTEDITPIECE::~FDE_TEXTEDITPIECE() = default; class IFDE_VisualSet { public: virtual ~IFDE_VisualSet() {} virtual FDE_VISUALOBJTYPE GetType() = 0; - virtual void GetRect(FDE_TEXTEDITPIECE* hVisualObj, CFX_RectF& rt) = 0; + virtual CFX_RectF GetRect(const FDE_TEXTEDITPIECE& hVisualObj) = 0; }; class IFDE_CanvasSet : public IFDE_VisualSet { @@ -51,13 +61,12 @@ class IFDE_TextSet : public IFDE_VisualSet { virtual CFX_RetainPtr<CFGAS_GEFont> GetFont() = 0; virtual FX_FLOAT GetFontSize() = 0; virtual FX_ARGB GetFontColor() = 0; - virtual int32_t GetDisplayPos(FDE_TEXTEDITPIECE* hText, + virtual int32_t GetDisplayPos(const FDE_TEXTEDITPIECE& hText, FXTEXT_CHARPOS* pCharPos, bool bCharCode = false, CFX_WideString* pWSForms = nullptr) = 0; - virtual int32_t GetCharRects(const FDE_TEXTEDITPIECE* hText, - CFX_RectFArray& rtArray, - bool bbox) = 0; + virtual std::vector<CFX_RectF> GetCharRects(const FDE_TEXTEDITPIECE* hText, + bool bbox) = 0; }; #endif // XFA_FDE_FDE_VISUALSET_H_ diff --git a/xfa/fde/ifde_txtedtpage.h b/xfa/fde/ifde_txtedtpage.h index ecc7d1699..0ab3897b3 100644 --- a/xfa/fde/ifde_txtedtpage.h +++ b/xfa/fde/ifde_txtedtpage.h @@ -7,6 +7,8 @@ #ifndef XFA_FDE_IFDE_TXTEDTPAGE_H_ #define XFA_FDE_IFDE_TXTEDTPAGE_H_ +#include <vector> + #include "xfa/fde/fde_visualset.h" #include "xfa/fgas/layout/fgas_textbreak.h" @@ -24,7 +26,7 @@ class IFDE_TxtEdtPage : public IFDE_CanvasSet, public IFX_TxtAccess { virtual int32_t GetCharIndex(const CFX_PointF& fPoint, bool& bBefore) = 0; virtual void CalcRangeRectArray(int32_t nStart, int32_t nCount, - CFX_RectFArray& RectFArr) const = 0; + std::vector<CFX_RectF>* RectFArr) const = 0; virtual int32_t SelectWord(const CFX_PointF& fPoint, int32_t& nCount) = 0; virtual int32_t GetCharStart() const = 0; virtual int32_t GetCharCount() const = 0; diff --git a/xfa/fde/tto/fde_textout.cpp b/xfa/fde/tto/fde_textout.cpp index 4d207fb73..421876b48 100644 --- a/xfa/fde/tto/fde_textout.cpp +++ b/xfa/fde/tto/fde_textout.cpp @@ -11,12 +11,17 @@ #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fde/cfde_path.h" #include "xfa/fde/fde_gedevice.h" #include "xfa/fde/fde_object.h" #include "xfa/fgas/crt/fgas_utils.h" #include "xfa/fgas/layout/fgas_textbreak.h" +FDE_TTOPIECE::FDE_TTOPIECE() = default; +FDE_TTOPIECE::FDE_TTOPIECE(const FDE_TTOPIECE& that) = default; +FDE_TTOPIECE::~FDE_TTOPIECE() = default; + CFDE_TextOut::CFDE_TextOut() : m_pTxtBreak(new CFX_TxtBreak(FX_TXTBREAKPOLICY_None)), m_pFont(nullptr), @@ -41,9 +46,7 @@ CFDE_TextOut::CFDE_TextOut() m_rtLogicClip.Reset(); } -CFDE_TextOut::~CFDE_TextOut() { - m_ttoLines.RemoveAll(false); -} +CFDE_TextOut::~CFDE_TextOut() {} void CFDE_TextOut::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { ASSERT(pFont); @@ -138,8 +141,7 @@ void CFDE_TextOut::SetRenderDevice(CFX_RenderDevice* pDevice) { } void CFDE_TextOut::SetClipRect(const CFX_Rect& rtClip) { - m_rtClip.Set((FX_FLOAT)rtClip.left, (FX_FLOAT)rtClip.top, - (FX_FLOAT)rtClip.Width(), (FX_FLOAT)rtClip.Height()); + m_rtClip = rtClip.As<FX_FLOAT>(); } void CFDE_TextOut::SetClipRect(const CFX_RectF& rtClip) { @@ -163,60 +165,12 @@ int32_t CFDE_TextOut::GetTotalLines() { return m_iTotalLines; } -void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr, - int32_t iLength, - CFX_Size& size) { - CFX_RectF rtText; - rtText.Set(0.0f, 0.0f, (FX_FLOAT)size.x, (FX_FLOAT)size.y); - CalcSize(pwsStr, iLength, rtText); - size.x = (int32_t)rtText.Width(); - size.y = (int32_t)rtText.Height(); -} - -void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr, - int32_t iLength, - CFX_SizeF& size) { - CFX_RectF rtText; - rtText.Set(0.0f, 0.0f, size.x, size.y); - CalcSize(pwsStr, iLength, rtText); - size.x = rtText.Width(); - size.y = rtText.Height(); -} - -void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr, - int32_t iLength, - CFX_Rect& rect) { - CFX_RectF rtText; - rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.Width(), - (FX_FLOAT)rect.Height()); - CalcSize(pwsStr, iLength, rtText); - rect.Set((int32_t)rtText.left, (int32_t)rtText.top, (int32_t)rtText.Width(), - (int32_t)rtText.Height()); -} - -void CFDE_TextOut::CalcSize(const FX_WCHAR* pwsStr, - int32_t iLength, - CFX_RectF& rect) { - if (!pwsStr || iLength < 1) { - rect.width = 0.0f; - rect.height = 0.0f; - } else { - CFX_Matrix rm; - rm.SetReverse(m_Matrix); - rm.TransformRect(rect); - CalcTextSize(pwsStr, iLength, rect); - m_Matrix.TransformRect(rect); - } -} - void CFDE_TextOut::CalcLogicSize(const FX_WCHAR* pwsStr, int32_t iLength, CFX_SizeF& size) { - CFX_RectF rtText; - rtText.Set(0.0f, 0.0f, size.x, size.y); + CFX_RectF rtText(0.0f, 0.0f, size.width, size.height); CalcLogicSize(pwsStr, iLength, rtText); - size.x = rtText.Width(); - size.y = rtText.Height(); + size = rtText.Size(); } void CFDE_TextOut::CalcLogicSize(const FX_WCHAR* pwsStr, @@ -346,9 +300,8 @@ void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr, int32_t iLength, int32_t x, int32_t y) { - CFX_RectF rtText; - rtText.Set((FX_FLOAT)x, (FX_FLOAT)y, m_fFontSize * 1000.0f, - m_fFontSize * 1000.0f); + CFX_RectF rtText(static_cast<FX_FLOAT>(x), static_cast<FX_FLOAT>(y), + m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); DrawText(pwsStr, iLength, rtText); } @@ -356,25 +309,20 @@ void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr, int32_t iLength, FX_FLOAT x, FX_FLOAT y) { - CFX_RectF rtText; - rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); - DrawText(pwsStr, iLength, rtText); + DrawText(pwsStr, iLength, + CFX_RectF(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f)); } void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr, int32_t iLength, const CFX_Rect& rect) { - CFX_RectF rtText; - rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.width, - (FX_FLOAT)rect.height); - DrawText(pwsStr, iLength, rtText); + DrawText(pwsStr, iLength, rect.As<FX_FLOAT>()); } void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr, int32_t iLength, const CFX_RectF& rect) { - CFX_RectF rtText; - rtText.Set(rect.left, rect.top, rect.width, rect.height); + CFX_RectF rtText(rect.left, rect.top, rect.width, rect.height); CFX_Matrix rm; rm.SetReverse(m_Matrix); rm.TransformRect(rtText); @@ -385,17 +333,15 @@ void CFDE_TextOut::DrawLogicText(const FX_WCHAR* pwsStr, int32_t iLength, FX_FLOAT x, FX_FLOAT y) { - CFX_RectF rtText; - rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); + CFX_RectF rtText(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f); DrawLogicText(pwsStr, iLength, rtText); } void CFDE_TextOut::DrawLogicText(const FX_WCHAR* pwsStr, int32_t iLength, const CFX_RectF& rect) { - CFX_RectF rtClip; - rtClip.Set(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width, - m_rtLogicClip.height); + CFX_RectF rtClip(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width, + m_rtLogicClip.height); m_Matrix.TransformRect(rtClip); DrawText(pwsStr, iLength, rect, rtClip); } @@ -416,7 +362,7 @@ void CFDE_TextOut::DrawText(const FX_WCHAR* pwsStr, fLineWidth = rect.height; } m_pTxtBreak->SetLineWidth(fLineWidth); - m_ttoLines.RemoveAll(true); + m_ttoLines.clear(); m_wsText.clear(); LoadText(pwsStr, iLength, rect); if (m_dwStyles & FDE_TTOSTYLE_Ellipsis) { @@ -532,12 +478,8 @@ void CFDE_TextOut::LoadText(const FX_WCHAR* pwsStr, } if ((bVertical && m_fLinePos + fLineStep < fLineStop) || (!bVertical && m_fLinePos + fLineStep > fLineStop)) { - int32_t iCurLine = m_iCurLine; - if (bEndofLine) { - iCurLine--; - } - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(iCurLine); - pLine->m_bNewReload = true; + int32_t iCurLine = bEndofLine ? m_iCurLine - 1 : m_iCurLine; + m_ttoLines[iCurLine].SetNewReload(true); bRet = true; break; } @@ -589,8 +531,7 @@ bool CFDE_TextOut::RetriecePieces(uint32_t dwBreakStatus, m_CharWidths[iChar++] = iCurCharWidth; } if (j == 0 && !bReload) { - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(m_iCurLine); - pLine->m_bNewReload = true; + m_ttoLines[m_iCurLine].SetNewReload(true); } else if (j > 0) { CFX_RectF rtPiece; if (bVertical) { @@ -626,14 +567,15 @@ bool CFDE_TextOut::RetriecePieces(uint32_t dwBreakStatus, void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE& ttoPiece, bool bNeedReload, bool bEnd) { - if (m_iCurLine >= m_ttoLines.GetSize()) { + if (m_iCurLine >= pdfium::CollectionSize<int32_t>(m_ttoLines)) { CFDE_TTOLine ttoLine; - ttoLine.m_bNewReload = bNeedReload; + ttoLine.SetNewReload(bNeedReload); m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece); - m_iCurLine = m_ttoLines.Add(ttoLine); + m_ttoLines.push_back(ttoLine); + m_iCurLine = pdfium::CollectionSize<int32_t>(m_ttoLines) - 1; } else { - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(m_iCurLine); - pLine->m_bNewReload = bNeedReload; + CFDE_TTOLine* pLine = &m_ttoLines[m_iCurLine]; + pLine->SetNewReload(bNeedReload); m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece); if (bEnd) { int32_t iPieces = pLine->GetSize(); @@ -642,36 +584,33 @@ void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE& ttoPiece, } } } - if (!bEnd && bNeedReload) { + if (!bEnd && bNeedReload) m_iCurPiece = 0; - } } void CFDE_TextOut::ReplaceWidthEllipsis() { LoadEllipsis(); int32_t iLength = m_wsEllipsis.GetLength(); - if (iLength < 1) { + if (iLength < 1) return; - } - int32_t iLines = m_ttoLines.GetSize(); - for (int32_t i = 0; i < iLines; i++) { - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i); - if (!pLine->m_bNewReload) { + + for (auto& line : m_ttoLines) { + if (!line.GetNewReload()) continue; - } + int32_t iEllipsisCharIndex = iLength - 1; int32_t iCharWidth = 0; int32_t iCharCount = 0; - int32_t iPiece = pLine->GetSize(); + int32_t iPiece = line.GetSize(); while (iPiece-- > 0) { - FDE_TTOPIECE* pPiece = pLine->GetPtrAt(iPiece); + FDE_TTOPIECE* pPiece = line.GetPtrAt(iPiece); if (!pPiece) break; for (int32_t j = pPiece->iChars - 1; j >= 0; j--) { - if (iEllipsisCharIndex < 0) { + if (iEllipsisCharIndex < 0) break; - } + int32_t index = pPiece->iStartChar + j; iCharWidth += m_CharWidths[index]; iCharCount++; @@ -684,23 +623,21 @@ void CFDE_TextOut::ReplaceWidthEllipsis() { } iEllipsisCharIndex--; } - if (iEllipsisCharIndex < 0) { + if (iEllipsisCharIndex < 0) break; - } } } } void CFDE_TextOut::Reload(const CFX_RectF& rect) { - int32_t iCount = m_ttoLines.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i); - if (!pLine || !pLine->m_bNewReload) - continue; - - m_iCurLine = i; - m_iCurPiece = 0; - ReloadLinePiece(pLine, rect); + int i = 0; + for (auto& line : m_ttoLines) { + if (line.GetNewReload()) { + m_iCurLine = i; + m_iCurPiece = 0; + ReloadLinePiece(&line, rect); + } + ++i; } } @@ -737,12 +674,12 @@ void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine* pLine, const CFX_RectF& rect) { } void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) { + if (m_ttoLines.empty()) + return; + bool bVertical = !!(m_dwStyles & FDE_TTOSTYLE_VerticalLayout); FX_FLOAT fLineStopS = bVertical ? rect.right() : rect.bottom(); - int32_t iLines = m_ttoLines.GetSize(); - if (iLines < 1) - return; - FDE_TTOPIECE* pFirstPiece = m_ttoLines.GetPtrAt(iLines - 1)->GetPtrAt(0); + FDE_TTOPIECE* pFirstPiece = m_ttoLines.back().GetPtrAt(0); if (!pFirstPiece) return; @@ -757,11 +694,10 @@ void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) { } if (fInc < 1.0f) return; - for (int32_t i = 0; i < iLines; i++) { - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i); - int32_t iPieces = pLine->GetSize(); + for (auto& line : m_ttoLines) { + int32_t iPieces = line.GetSize(); for (int32_t j = 0; j < iPieces; j++) { - FDE_TTOPIECE* pPiece = pLine->GetPtrAt(j); + FDE_TTOPIECE* pPiece = line.GetPtrAt(j); if (bVertical) pPiece->rtPiece.left += fInc; else @@ -771,39 +707,34 @@ void CFDE_TextOut::DoAlignment(const CFX_RectF& rect) { } void CFDE_TextOut::OnDraw(const CFX_RectF& rtClip) { - if (!m_pRenderDevice) - return; - - int32_t iLines = m_ttoLines.GetSize(); - if (iLines < 1) + if (!m_pRenderDevice || m_ttoLines.empty()) return; - CFDE_Brush* pBrush = new CFDE_Brush; + auto pBrush = pdfium::MakeUnique<CFDE_Brush>(); pBrush->SetColor(m_TxtColor); - CFDE_Pen* pPen = nullptr; m_pRenderDevice->SaveState(); - if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) { + if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) m_pRenderDevice->SetClipRect(rtClip); - } - for (int32_t i = 0; i < iLines; i++) { - CFDE_TTOLine* pLine = m_ttoLines.GetPtrAt(i); - int32_t iPieces = pLine->GetSize(); + + auto pPen = pdfium::MakeUnique<CFDE_Pen>(); + pPen->SetColor(m_TxtColor); + + for (auto& line : m_ttoLines) { + int32_t iPieces = line.GetSize(); for (int32_t j = 0; j < iPieces; j++) { - FDE_TTOPIECE* pPiece = pLine->GetPtrAt(j); + FDE_TTOPIECE* pPiece = line.GetPtrAt(j); if (!pPiece) continue; int32_t iCount = GetDisplayPos(pPiece); if (iCount > 0) { - m_pRenderDevice->DrawString(pBrush, m_pFont, m_CharPos.data(), iCount, - m_fFontSize, &m_Matrix); + m_pRenderDevice->DrawString(pBrush.get(), m_pFont, m_CharPos.data(), + iCount, m_fFontSize, &m_Matrix); } - DrawLine(pPiece, pPen); + DrawLine(pPiece, pPen.get()); } } m_pRenderDevice->RestoreState(); - delete pBrush; - delete pPen; } int32_t CFDE_TextOut::GetDisplayPos(FDE_TTOPIECE* pPiece) { @@ -814,8 +745,8 @@ int32_t CFDE_TextOut::GetDisplayPos(FDE_TTOPIECE* pPiece) { int32_t CFDE_TextOut::GetCharRects(const FDE_TTOPIECE* pPiece) { FX_TXTRUN tr = ToTextRun(pPiece); - m_rectArray.RemoveAll(); - return m_pTxtBreak->GetCharRects(&tr, m_rectArray); + m_rectArray = m_pTxtBreak->GetCharRects(&tr); + return pdfium::CollectionSize<int32_t>(m_rectArray); } FX_TXTRUN CFDE_TextOut::ToTextRun(const FDE_TTOPIECE* pPiece) { @@ -832,7 +763,7 @@ FX_TXTRUN CFDE_TextOut::ToTextRun(const FDE_TTOPIECE* pPiece) { return tr; } -void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen*& pPen) { +void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen* pPen) { bool bUnderLine = !!(m_dwStyles & FDE_TTOSTYLE_Underline); bool bStrikeOut = !!(m_dwStyles & FDE_TTOSTYLE_Strikeout); bool bHotKey = !!(m_dwStyles & FDE_TTOSTYLE_HotKey); @@ -840,10 +771,6 @@ void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen*& pPen) { if (!bUnderLine && !bStrikeOut && !bHotKey) return; - if (!pPen) { - pPen = new CFDE_Pen; - pPen->SetColor(m_TxtColor); - } std::unique_ptr<CFDE_Path> pPath(new CFDE_Path); int32_t iLineCount = 0; CFX_RectF rtText = pPiece->rtPiece; @@ -886,7 +813,7 @@ void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen*& pPen) { int32_t iCharIndex = m_hotKeys.GetAt(i); if (iCharIndex >= pPiece->iStartChar && iCharIndex < pPiece->iStartChar + pPiece->iChars) { - CFX_RectF rect = m_rectArray.GetAt(iCharIndex - pPiece->iStartChar); + CFX_RectF rect = m_rectArray[iCharIndex - pPiece->iStartChar]; if (bVertical) { pt1.x = rect.left; pt1.y = rect.top; @@ -908,43 +835,42 @@ void CFDE_TextOut::DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen*& pPen) { m_pRenderDevice->DrawPath(pPen, 1, pPath.get(), &m_Matrix); } -CFDE_TTOLine::CFDE_TTOLine() - : m_bNewReload(false), m_pieces(5), m_iPieceCount(0) {} +CFDE_TTOLine::CFDE_TTOLine() : m_bNewReload(false) {} CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine& ttoLine) : m_pieces(5) { m_bNewReload = ttoLine.m_bNewReload; - m_iPieceCount = ttoLine.m_iPieceCount; - m_pieces.Copy(ttoLine.m_pieces, 0, -1); + m_pieces = ttoLine.m_pieces; } CFDE_TTOLine::~CFDE_TTOLine() {} int32_t CFDE_TTOLine::AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece) { - if (index >= m_iPieceCount) { - index = m_pieces.Add(ttoPiece) + 1; - m_iPieceCount++; - } else { - FDE_TTOPIECE& piece = m_pieces.GetAt(index); - piece = ttoPiece; + if (index >= pdfium::CollectionSize<int32_t>(m_pieces)) { + m_pieces.push_back(ttoPiece); + return pdfium::CollectionSize<int32_t>(m_pieces); } + m_pieces[index] = ttoPiece; return index; } int32_t CFDE_TTOLine::GetSize() const { - return m_iPieceCount; + return pdfium::CollectionSize<int32_t>(m_pieces); } FDE_TTOPIECE* CFDE_TTOLine::GetPtrAt(int32_t index) { - if (index >= m_iPieceCount) { + if (index < 0 || index >= pdfium::CollectionSize<int32_t>(m_pieces)) return nullptr; - } - return m_pieces.GetPtrAt(index); + + return &m_pieces[index]; } -void CFDE_TTOLine::RemoveLast(int32_t iCount) { - m_pieces.RemoveLast(iCount); +void CFDE_TTOLine::RemoveLast(int32_t icount) { + if (icount < 0) + return; + icount = std::min(icount, pdfium::CollectionSize<int32_t>(m_pieces)); + m_pieces.erase(m_pieces.end() - icount, m_pieces.end()); } -void CFDE_TTOLine::RemoveAll(bool bLeaveMemory) { - m_pieces.RemoveAll(bLeaveMemory); +void CFDE_TTOLine::RemoveAll() { + m_pieces.clear(); } diff --git a/xfa/fde/tto/fde_textout.h b/xfa/fde/tto/fde_textout.h index 94b72f806..04d656776 100644 --- a/xfa/fde/tto/fde_textout.h +++ b/xfa/fde/tto/fde_textout.h @@ -7,6 +7,7 @@ #ifndef XFA_FDE_TTO_FDE_TEXTOUT_H_ #define XFA_FDE_TTO_FDE_TEXTOUT_H_ +#include <deque> #include <memory> #include <vector> @@ -47,12 +48,15 @@ class CFX_TxtBreak; struct FX_TXTRUN; struct FDE_TTOPIECE { + FDE_TTOPIECE(); + FDE_TTOPIECE(const FDE_TTOPIECE& that); + ~FDE_TTOPIECE(); + int32_t iStartChar; int32_t iChars; uint32_t dwCharStyles; CFX_RectF rtPiece; }; -typedef CFX_MassArrayTemplate<FDE_TTOPIECE> CFDE_TTOPieceArray; class CFDE_TTOLine { public: @@ -60,19 +64,18 @@ class CFDE_TTOLine { CFDE_TTOLine(const CFDE_TTOLine& ttoLine); ~CFDE_TTOLine(); + bool GetNewReload() const { return m_bNewReload; } + void SetNewReload(bool reload) { m_bNewReload = reload; } int32_t AddPiece(int32_t index, const FDE_TTOPIECE& ttoPiece); int32_t GetSize() const; FDE_TTOPIECE* GetPtrAt(int32_t index); void RemoveLast(int32_t iCount); - void RemoveAll(bool bLeaveMemory); + void RemoveAll(); + private: bool m_bNewReload; - CFDE_TTOPieceArray m_pieces; - - protected: - int32_t m_iPieceCount; + std::deque<FDE_TTOPIECE> m_pieces; }; -typedef CFX_ObjectMassArrayTemplate<CFDE_TTOLine> CFDE_TTOLineArray; class CFDE_TextOut { public: @@ -94,10 +97,6 @@ class CFDE_TextOut { void SetClipRect(const CFX_RectF& rtClip); void SetMatrix(const CFX_Matrix& matrix); void SetLineBreakTolerance(FX_FLOAT fTolerance); - void CalcSize(const FX_WCHAR* pwsStr, int32_t iLength, CFX_Size& size); - void CalcSize(const FX_WCHAR* pwsStr, int32_t iLength, CFX_SizeF& size); - void CalcSize(const FX_WCHAR* pwsStr, int32_t iLength, CFX_Rect& rect); - void CalcSize(const FX_WCHAR* pwsStr, int32_t iLength, CFX_RectF& rect); void DrawText(const FX_WCHAR* pwsStr, int32_t iLength, int32_t x, int32_t y); void DrawText(const FX_WCHAR* pwsStr, @@ -150,7 +149,7 @@ class CFDE_TextOut { int32_t GetCharRects(const FDE_TTOPIECE* pPiece); FX_TXTRUN ToTextRun(const FDE_TTOPIECE* pPiece); - void DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen*& pPen); + void DrawLine(const FDE_TTOPIECE* pPiece, CFDE_Pen* pPen); std::unique_ptr<CFX_TxtBreak> m_pTxtBreak; CFX_RetainPtr<CFGAS_GEFont> m_pFont; @@ -173,14 +172,14 @@ class CFDE_TextOut { CFX_RectF m_rtClip; CFX_RectF m_rtLogicClip; CFX_Matrix m_Matrix; - CFDE_TTOLineArray m_ttoLines; + std::deque<CFDE_TTOLine> m_ttoLines; int32_t m_iCurLine; int32_t m_iCurPiece; int32_t m_iTotalLines; std::vector<FXTEXT_CHARPOS> m_CharPos; std::unique_ptr<CFDE_RenderDevice> m_pRenderDevice; - CFX_Int32Array m_hotKeys; - CFX_RectFArray m_rectArray; + CFX_ArrayTemplate<int32_t> m_hotKeys; + std::vector<CFX_RectF> m_rectArray; }; #endif // XFA_FDE_TTO_FDE_TEXTOUT_H_ diff --git a/xfa/fde/xml/cfx_saxreader.h b/xfa/fde/xml/cfx_saxreader.h index 8e06d9bb4..129399d88 100644 --- a/xfa/fde/xml/cfx_saxreader.h +++ b/xfa/fde/xml/cfx_saxreader.h @@ -128,7 +128,7 @@ class CFX_SAXReader { bool m_bCharData; uint8_t m_CurByte; uint32_t m_dwDataOffset; - CFX_ByteArray m_SkipStack; + CFX_ArrayTemplate<uint8_t> m_SkipStack; uint8_t m_SkipChar; uint32_t m_dwNodePos; uint8_t* m_pszData; diff --git a/xfa/fde/xml/fde_xml_imp.cpp b/xfa/fde/xml/fde_xml_imp.cpp index 2bdaf5155..5ce274bbd 100644 --- a/xfa/fde/xml/fde_xml_imp.cpp +++ b/xfa/fde/xml/fde_xml_imp.cpp @@ -84,10 +84,6 @@ CFDE_XMLNode::CFDE_XMLNode() m_pPrior(nullptr), m_pNext(nullptr) {} -void CFDE_XMLNode::Release() { - delete this; -} - FDE_XMLNODETYPE CFDE_XMLNode::GetType() const { return FDE_XMLNODE_Unknown; } @@ -99,9 +95,9 @@ CFDE_XMLNode::~CFDE_XMLNode() { void CFDE_XMLNode::DeleteChildren() { CFDE_XMLNode* pChild = m_pChild; while (pChild) { - CFDE_XMLNode* pTemp = pChild->m_pNext; - pChild->Release(); - pChild = pTemp; + CFDE_XMLNode* pNext = pChild->m_pNext; + delete pChild; + pChild = pNext; } m_pChild = nullptr; } @@ -529,10 +525,6 @@ CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget) ASSERT(m_wsTarget.GetLength() > 0); } -void CFDE_XMLInstruction::Release() { - delete this; -} - FDE_XMLNODETYPE CFDE_XMLInstruction::GetType() const { return FDE_XMLNODE_Instruction; } @@ -687,10 +679,6 @@ CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString& wsTag) CFDE_XMLElement::~CFDE_XMLElement() {} -void CFDE_XMLElement::Release() { - delete this; -} - FDE_XMLNODETYPE CFDE_XMLElement::GetType() const { return FDE_XMLNODE_Element; } @@ -899,10 +887,6 @@ void CFDE_XMLElement::SetTextData(const CFX_WideString& wsText) { CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText) : CFDE_XMLNode(), m_wsText(wsText) {} -void CFDE_XMLText::Release() { - delete this; -} - FDE_XMLNODETYPE CFDE_XMLText::GetType() const { return FDE_XMLNODE_Text; } @@ -917,10 +901,6 @@ CFDE_XMLText::~CFDE_XMLText() {} CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData) : CFDE_XMLDeclaration(), m_wsCharData(wsCData) {} -void CFDE_XMLCharData::Release() { - delete this; -} - FDE_XMLNODETYPE CFDE_XMLCharData::GetType() const { return FDE_XMLNODE_CharData; } @@ -932,8 +912,7 @@ CFDE_XMLNode* CFDE_XMLCharData::Clone(bool bRecursive) { CFDE_XMLCharData::~CFDE_XMLCharData() {} -CFDE_XMLDoc::CFDE_XMLDoc() - : m_pRoot(nullptr), m_pSyntaxParser(nullptr), m_pXMLParser(nullptr) { +CFDE_XMLDoc::CFDE_XMLDoc() : m_pRoot(nullptr) { Reset(true); CFDE_XMLInstruction* pXML = new CFDE_XMLInstruction(L"xml"); m_pRoot->InsertChildNode(pXML); @@ -952,20 +931,14 @@ void CFDE_XMLDoc::Reset(bool bInitRoot) { else m_pRoot = new CFDE_XMLNode; } else { - if (m_pRoot) { - m_pRoot->Release(); - m_pRoot = nullptr; - } + delete m_pRoot; + m_pRoot = nullptr; } ReleaseParser(); } void CFDE_XMLDoc::ReleaseParser() { m_pXMLParser.reset(); - if (m_pSyntaxParser) { - m_pSyntaxParser->Release(); - m_pSyntaxParser = nullptr; - } } bool CFDE_XMLDoc::LoadXML(std::unique_ptr<IFDE_XMLParser> pXMLParser) { @@ -1314,7 +1287,8 @@ void CFDE_XMLSyntaxParser::Init(const CFX_RetainPtr<IFGAS_Stream>& pStream, return; } - m_pBuffer = FX_Alloc(FX_WCHAR, alloc_size_safe.ValueOrDie()); + m_pBuffer = FX_Alloc( + FX_WCHAR, pdfium::base::ValueOrDieForType<size_t>(alloc_size_safe)); m_pStart = m_pEnd = m_pBuffer; ASSERT(!m_BlockBuffer.IsInitialized()); m_BlockBuffer.InitBuffer(); diff --git a/xfa/fde/xml/fde_xml_imp.h b/xfa/fde/xml/fde_xml_imp.h index 49c5c51f7..41e84bad1 100644 --- a/xfa/fde/xml/fde_xml_imp.h +++ b/xfa/fde/xml/fde_xml_imp.h @@ -44,7 +44,6 @@ class CFDE_XMLNode { CFDE_XMLNode(); virtual ~CFDE_XMLNode(); - virtual void Release(); virtual FDE_XMLNODETYPE GetType() const; virtual CFDE_XMLNode* Clone(bool bRecursive); @@ -79,7 +78,6 @@ class CFDE_XMLInstruction : public CFDE_XMLNode { ~CFDE_XMLInstruction() override; // CFDE_XMLNode - void Release() override; FDE_XMLNODETYPE GetType() const override; CFDE_XMLNode* Clone(bool bRecursive) override; @@ -115,7 +113,6 @@ class CFDE_XMLElement : public CFDE_XMLNode { ~CFDE_XMLElement() override; // CFDE_XMLNode - void Release() override; FDE_XMLNODETYPE GetType() const override; CFDE_XMLNode* Clone(bool bRecursive) override; @@ -157,7 +154,6 @@ class CFDE_XMLText : public CFDE_XMLNode { ~CFDE_XMLText() override; // CFDE_XMLNode - void Release() override; FDE_XMLNODETYPE GetType() const override; CFDE_XMLNode* Clone(bool bRecursive) override; @@ -178,7 +174,6 @@ class CFDE_XMLCharData : public CFDE_XMLDeclaration { explicit CFDE_XMLCharData(const CFX_WideString& wsCData); ~CFDE_XMLCharData() override; - void Release() override; FDE_XMLNODETYPE GetType() const override; CFDE_XMLNode* Clone(bool bRecursive) override; @@ -210,7 +205,6 @@ class CFDE_XMLDoc { CFX_RetainPtr<IFGAS_Stream> m_pStream; int32_t m_iStatus; CFDE_XMLNode* m_pRoot; - CFDE_XMLSyntaxParser* m_pSyntaxParser; std::unique_ptr<IFDE_XMLParser> m_pXMLParser; }; @@ -227,7 +221,6 @@ class CFDE_BlockBuffer { bool InitBuffer(int32_t iBufferSize = 1024 * 1024); bool IsInitialized() { return m_iBufferSize / m_iAllocStep >= 1; } - void ReleaseBuffer() { delete this; } FX_WCHAR* GetAvailableBlock(int32_t& iIndexInBlock); inline int32_t GetAllocStep() const { return m_iAllocStep; } inline int32_t& GetDataLengthRef() { return m_iDataLength; } @@ -261,7 +254,6 @@ class CFDE_XMLSyntaxParser { CFDE_XMLSyntaxParser(); ~CFDE_XMLSyntaxParser(); - void Release() { delete this; } void Init(const CFX_RetainPtr<IFGAS_Stream>& pStream, int32_t iXMLPlaneSize, int32_t iTextDataSize = 256); diff --git a/xfa/fgas/crt/fgas_utils.cpp b/xfa/fgas/crt/fgas_utils.cpp index 1e86c6c16..c09198f6e 100644 --- a/xfa/fgas/crt/fgas_utils.cpp +++ b/xfa/fgas/crt/fgas_utils.cpp @@ -301,37 +301,6 @@ void CFX_BaseMassArrayImp::RemoveAll(bool bLeaveMemory) { m_iChunkCount = 0; m_iBlockCount = 0; } -CFX_BaseMassArray::CFX_BaseMassArray(int32_t iChunkSize, int32_t iBlockSize) { - m_pData = new CFX_BaseMassArrayImp(iChunkSize, iBlockSize); -} -CFX_BaseMassArray::~CFX_BaseMassArray() { - delete m_pData; -} -int32_t CFX_BaseMassArray::GetSize() const { - return m_pData->m_iBlockCount; -} -uint8_t* CFX_BaseMassArray::AddSpaceTo(int32_t index) { - return m_pData->AddSpaceTo(index); -} -uint8_t* CFX_BaseMassArray::GetAt(int32_t index) const { - return m_pData->GetAt(index); -} -int32_t CFX_BaseMassArray::Append(const CFX_BaseMassArray& src, - int32_t iStart, - int32_t iCount) { - return m_pData->Append(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount); -} -int32_t CFX_BaseMassArray::Copy(const CFX_BaseMassArray& src, - int32_t iStart, - int32_t iCount) { - return m_pData->Copy(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount); -} -int32_t CFX_BaseMassArray::RemoveLast(int32_t iCount) { - return m_pData->RemoveLast(iCount); -} -void CFX_BaseMassArray::RemoveAll(bool bLeaveMemory) { - m_pData->RemoveAll(bLeaveMemory); -} struct FX_BASEDISCRETEARRAYDATA { int32_t iBlockSize; diff --git a/xfa/fgas/crt/fgas_utils.h b/xfa/fgas/crt/fgas_utils.h index 465601149..105920dc5 100644 --- a/xfa/fgas/crt/fgas_utils.h +++ b/xfa/fgas/crt/fgas_utils.h @@ -104,152 +104,6 @@ class CFX_BaseMassArrayImp { int32_t iSrcCount); }; -class CFX_BaseMassArray { - protected: - CFX_BaseMassArray(int32_t iChunkSize, int32_t iBlockSize); - ~CFX_BaseMassArray(); - - int32_t GetSize() const; - uint8_t* AddSpaceTo(int32_t index); - uint8_t* GetAt(int32_t index) const; - int32_t Append(const CFX_BaseMassArray& src, int32_t iStart, int32_t iCount); - int32_t Copy(const CFX_BaseMassArray& src, int32_t iStart, int32_t iCount); - int32_t RemoveLast(int32_t iCount); - void RemoveAll(bool bLeaveMemory); - CFX_BaseMassArrayImp* m_pData; -}; - -template <class baseType> -class CFX_MassArrayTemplate : public CFX_BaseMassArray { - public: - explicit CFX_MassArrayTemplate(int32_t iChunkSize) - : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {} - CFX_MassArrayTemplate(int32_t iChunkSize, int32_t iBlockSize) - : CFX_BaseMassArray(iChunkSize, iBlockSize) {} - - int32_t GetSize() const { return CFX_BaseMassArray::GetSize(); } - baseType* AddSpace() { - return (baseType*)CFX_BaseMassArray::AddSpaceTo( - CFX_BaseMassArray::GetSize()); - } - int32_t Add(const baseType& element) { - int32_t index = CFX_BaseMassArray::GetSize(); - *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element; - return index; - } - baseType& GetAt(int32_t index) const { - return *(baseType*)CFX_BaseMassArray::GetAt(index); - } - baseType* GetPtrAt(int32_t index) const { - return (baseType*)CFX_BaseMassArray::GetAt(index); - } - void SetAt(int32_t index, const baseType& element) { - *(baseType*)CFX_BaseMassArray::GetAt(index) = element; - } - void SetAtGrow(int32_t index, const baseType& element) { - *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element; - } - int32_t Append(const CFX_MassArrayTemplate& src, - int32_t iStart, - int32_t iCount) { - return CFX_BaseMassArray::Append(src, iStart, iCount); - } - int32_t Copy(const CFX_MassArrayTemplate& src, - int32_t iStart, - int32_t iCount) { - return CFX_BaseMassArray::Copy(src, iStart, iCount); - } - int32_t RemoveLast(int32_t iCount) { - return CFX_BaseMassArray::RemoveLast(iCount); - } - void RemoveAll(bool bLeaveMemory) { - CFX_BaseMassArray::RemoveAll(bLeaveMemory); - } -}; - -template <class baseType> -class CFX_ObjectMassArrayTemplate : public CFX_BaseMassArray { - public: - explicit CFX_ObjectMassArrayTemplate(int32_t iChunkSize) - : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {} - ~CFX_ObjectMassArrayTemplate() { RemoveAll(false); } - - int32_t GetSize() const { return CFX_BaseMassArray::GetSize(); } - int32_t Add(const baseType& element) { - int32_t index = CFX_BaseMassArray::GetSize(); - baseType* p = (baseType*)CFX_BaseMassArray::AddSpaceTo(index); - new ((void*)p) baseType(element); - return index; - } - baseType& GetAt(int32_t index) const { - return *(baseType*)CFX_BaseMassArray::GetAt(index); - } - baseType* GetPtrAt(int32_t index) const { - return (baseType*)CFX_BaseMassArray::GetAt(index); - } - int32_t Append(const CFX_ObjectMassArrayTemplate& src, - int32_t iStart, - int32_t iCount) { - if (iCount == 0) { - return CFX_BaseMassArray::GetSize(); - } - int32_t iSize = src.GetSize(); - ASSERT(iStart > -1 && iStart < iSize); - if (iCount < 0) { - iCount = iSize; - } - int32_t iEnd = iStart + iCount; - if (iEnd > iSize) { - iEnd = iSize; - } - for (int32_t i = iStart; i < iEnd; i++) { - Add(src.GetAt(i)); - } - return CFX_BaseMassArray::GetSize(); - } - int32_t Copy(const CFX_ObjectMassArrayTemplate& src, - int32_t iStart, - int32_t iCount) { - if (iCount == 0) { - return CFX_BaseMassArray::GetSize(); - } - int32_t iSize = src.GetSize(); - ASSERT(iStart > -1 && iStart < iSize); - if (iCount < 0) { - iCount = iSize; - } - int32_t iEnd = iStart + iCount; - if (iEnd > iSize) { - iEnd = iSize; - } - RemoveAll(true); - for (int32_t i = iStart; i < iEnd; i++) { - Add(src.GetAt(i)); - } - return CFX_BaseMassArray::GetSize(); - } - int32_t RemoveLast(int32_t iCount) { - int32_t iSize = CFX_BaseMassArray::GetSize(); - if (iCount < 0 || iCount > iSize) { - iCount = iSize; - } - if (iCount == 0) { - return iSize; - } - for (int32_t i = iSize - iCount; i < iSize; i++) { - ((baseType*)GetPtrAt(i))->~baseType(); - } - return CFX_BaseMassArray::RemoveLast(iCount); - } - void RemoveAll(bool bLeaveMemory) { - int32_t iSize = CFX_BaseMassArray::GetSize(); - for (int32_t i = 0; i < iSize; i++) { - ((baseType*)GetPtrAt(i))->~baseType(); - } - CFX_BaseMassArray::RemoveAll(bLeaveMemory); - } -}; - class CFX_BaseDiscreteArray { protected: CFX_BaseDiscreteArray(int32_t iChunkSize, int32_t iBlockSize); @@ -316,61 +170,4 @@ class CFX_StackTemplate : public CFX_BaseStack { void RemoveAll(bool bLeaveMemory) { CFX_BaseStack::RemoveAll(bLeaveMemory); } }; -template <class baseType> -class CFX_ObjectStackTemplate : public CFX_BaseStack { - public: - explicit CFX_ObjectStackTemplate(int32_t iChunkSize) - : CFX_BaseStack(iChunkSize, sizeof(baseType)) {} - ~CFX_ObjectStackTemplate() { RemoveAll(false); } - - int32_t Push(const baseType& element) { - int32_t index = CFX_BaseStack::GetSize(); - baseType* p = (baseType*)CFX_BaseStack::Push(); - new ((void*)p) baseType(element); - return index; - } - void Pop() { - baseType* p = (baseType*)CFX_BaseStack::GetTopElement(); - if (p) { - p->~baseType(); - } - CFX_BaseStack::Pop(); - } - baseType* GetTopElement() const { - return (baseType*)CFX_BaseStack::GetTopElement(); - } - int32_t GetSize() const { return CFX_BaseStack::GetSize(); } - baseType* GetAt(int32_t index) const { - return (baseType*)CFX_BaseStack::GetAt(index); - } - void RemoveAll(bool bLeaveMemory) { - int32_t iSize = CFX_BaseStack::GetSize(); - for (int32_t i = 0; i < iSize; i++) { - ((baseType*)CFX_BaseStack::GetAt(i))->~baseType(); - } - CFX_BaseStack::RemoveAll(bLeaveMemory); - } - int32_t Copy(const CFX_ObjectStackTemplate& src, - int32_t iStart, - int32_t iCount) { - if (iCount == 0) { - return CFX_BaseStack::GetSize(); - } - int32_t iSize = src.GetSize(); - ASSERT(iStart > -1 && iStart < iSize); - if (iCount < 0) { - iCount = iSize; - } - int32_t iEnd = iStart + iCount; - if (iEnd > iSize) { - iEnd = iSize; - } - RemoveAll(true); - for (int32_t i = iStart; i < iEnd; i++) { - Push(*src.GetAt(i)); - } - return CFX_BaseStack::GetSize(); - } -}; - #endif // XFA_FGAS_CRT_FGAS_UTILS_H_ diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp index add66899a..aa41318f5 100644 --- a/xfa/fgas/font/cfgas_fontmgr.cpp +++ b/xfa/fgas/font/cfgas_fontmgr.cpp @@ -47,49 +47,49 @@ int32_t GetSimilarityScore(FX_FONTDESCRIPTOR const* pFont, return iValue; } -FX_FONTDESCRIPTOR const* MatchDefaultFont(FX_FONTMATCHPARAMS* pParams, - const CFX_FontDescriptors& fonts) { - FX_FONTDESCRIPTOR const* pBestFont = nullptr; +const FX_FONTDESCRIPTOR* MatchDefaultFont( + FX_FONTMATCHPARAMS* pParams, + const std::deque<FX_FONTDESCRIPTOR>& fonts) { + const FX_FONTDESCRIPTOR* pBestFont = nullptr; int32_t iBestSimilar = 0; bool bMatchStyle = (pParams->dwMatchFlags & FX_FONTMATCHPARA_MatchStyle) > 0; - for (int32_t i = 0; i < fonts.GetSize(); ++i) { - FX_FONTDESCRIPTOR const* pFont = fonts.GetPtrAt(i); - if ((pFont->dwFontStyles & FX_FONTSTYLE_BoldItalic) == + for (const auto& font : fonts) { + if ((font.dwFontStyles & FX_FONTSTYLE_BoldItalic) == FX_FONTSTYLE_BoldItalic) { continue; } if (pParams->pwsFamily) { - if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace)) + if (FXSYS_wcsicmp(pParams->pwsFamily, font.wsFontFace)) continue; - if (pFont->uCharSet == FX_CHARSET_Symbol) - return pFont; + if (font.uCharSet == FX_CHARSET_Symbol) + return &font; } - if (pFont->uCharSet == FX_CHARSET_Symbol) + if (font.uCharSet == FX_CHARSET_Symbol) continue; if (pParams->wCodePage != 0xFFFF) { - if (FX_GetCodePageFromCharset(pFont->uCharSet) != pParams->wCodePage) + if (FX_GetCodePageFromCharset(font.uCharSet) != pParams->wCodePage) continue; } else { if (pParams->dwUSB < 128) { uint32_t dwByte = pParams->dwUSB / 32; uint32_t dwUSB = 1 << (pParams->dwUSB % 32); - if ((pFont->FontSignature.fsUsb[dwByte] & dwUSB) == 0) + if ((font.FontSignature.fsUsb[dwByte] & dwUSB) == 0) continue; } } if (bMatchStyle) { - if ((pFont->dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F)) - return pFont; + if ((font.dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F)) + return &font; continue; } if (pParams->pwsFamily) { - if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace) == 0) - return pFont; + if (FXSYS_wcsicmp(pParams->pwsFamily, font.wsFontFace) == 0) + return &font; } - int32_t iSimilarValue = GetSimilarityScore(pFont, pParams->dwFontStyles); + int32_t iSimilarValue = GetSimilarityScore(&font, pParams->dwFontStyles); if (iBestSimilar < iSimilarValue) { iBestSimilar = iSimilarValue; - pBestFont = pFont; + pBestFont = &font; } } return iBestSimilar < 1 ? nullptr : pBestFont; @@ -105,12 +105,10 @@ std::unique_ptr<CFGAS_FontMgr> CFGAS_FontMgr::Create( CFGAS_FontMgr::CFGAS_FontMgr(FX_LPEnumAllFonts pEnumerator) : m_pEnumerator(pEnumerator), m_FontFaces(100) { if (m_pEnumerator) - m_pEnumerator(m_FontFaces, nullptr, 0xFEFF); + m_pEnumerator(&m_FontFaces, nullptr, 0xFEFF); } -CFGAS_FontMgr::~CFGAS_FontMgr() { - m_FontFaces.RemoveAll(false); -} +CFGAS_FontMgr::~CFGAS_FontMgr() {} CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage( uint16_t wCodePage, @@ -264,7 +262,7 @@ void CFGAS_FontMgr::RemoveFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { m_Fonts.erase(it); } -FX_FONTDESCRIPTOR const* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily, +const FX_FONTDESCRIPTOR* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily, uint32_t dwFontStyles, uint32_t dwMatchFlags, uint16_t wCodePage, @@ -278,25 +276,26 @@ FX_FONTDESCRIPTOR const* CFGAS_FontMgr::FindFont(const FX_WCHAR* pszFontFamily, params.pwsFamily = pszFontFamily; params.dwFontStyles = dwFontStyles; params.dwMatchFlags = dwMatchFlags; - FX_FONTDESCRIPTOR const* pDesc = MatchDefaultFont(¶ms, m_FontFaces); + const FX_FONTDESCRIPTOR* pDesc = MatchDefaultFont(¶ms, m_FontFaces); if (pDesc) return pDesc; + if (!pszFontFamily || !m_pEnumerator) return nullptr; - CFX_FontDescriptors namedFonts(100); - m_pEnumerator(namedFonts, pszFontFamily, wUnicode); + std::deque<FX_FONTDESCRIPTOR> namedFonts; + m_pEnumerator(&namedFonts, pszFontFamily, wUnicode); params.pwsFamily = nullptr; pDesc = MatchDefaultFont(¶ms, namedFonts); if (!pDesc) return nullptr; - for (int32_t i = m_FontFaces.GetSize() - 1; i >= 0; i--) { - FX_FONTDESCRIPTOR const* pMatch = m_FontFaces.GetPtrAt(i); - if (*pMatch == *pDesc) - return pMatch; - } - int index = m_FontFaces.Add(*pDesc); - return m_FontFaces.GetPtrAt(index); + + auto it = std::find(m_FontFaces.rbegin(), m_FontFaces.rend(), *pDesc); + if (it != m_FontFaces.rend()) + return &*it; + + m_FontFaces.push_back(*pDesc); + return &m_FontFaces.back(); } uint32_t FX_GetGdiFontStyles(const LOGFONTW& lf) { @@ -330,12 +329,12 @@ static int32_t CALLBACK FX_GdiFontEnumProc(ENUMLOGFONTEX* lpelfe, pFont->wsFontFace[31] = 0; FXSYS_memcpy(&pFont->FontSignature, &lpntme->ntmFontSig, sizeof(lpntme->ntmFontSig)); - ((CFX_FontDescriptors*)lParam)->Add(*pFont); + reinterpret_cast<std::deque<FX_FONTDESCRIPTOR>*>(lParam)->push_back(*pFont); FX_Free(pFont); return 1; } -static void FX_EnumGdiFonts(CFX_FontDescriptors& fonts, +static void FX_EnumGdiFonts(std::deque<FX_FONTDESCRIPTOR>* fonts, const FX_WCHAR* pwsFaceName, FX_WCHAR wUnicode) { HDC hDC = ::GetDC(nullptr); @@ -347,7 +346,7 @@ static void FX_EnumGdiFonts(CFX_FontDescriptors& fonts, lfFind.lfFaceName[31] = 0; } EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind, - (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)&fonts, 0); + (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)fonts, 0); ::ReleaseDC(nullptr, hDC); } @@ -516,7 +515,7 @@ CFX_ByteString CFX_FontSourceEnum_File::GetNextFile() { FX_CloseFolder(pCurHandle); if (!m_FolderQueue.empty()) m_FolderQueue.pop_back(); - if (!m_FolderQueue.empty()) { + if (m_FolderQueue.empty()) { if (!m_FolderPaths.empty()) m_FolderPaths.pop_back(); return !m_FolderPaths.empty() ? GetNextFile() : ""; @@ -629,7 +628,7 @@ CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByCodePage( const FX_WCHAR* pszFontFamily) { CFX_ByteString bsHash; bsHash.Format("%d, %d", wCodePage, dwFontStyles); - bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); + bsHash += FX_UTF8Encode(CFX_WideStringC(pszFontFamily)); uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFontArray = &m_Hash2Fonts[dwHash]; if (!pFontArray->empty()) @@ -673,7 +672,7 @@ CFX_RetainPtr<CFGAS_GEFont> CFGAS_FontMgr::GetFontByUnicode( bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles); else bsHash.Format("%d, %d", wCodePage, dwFontStyles); - bsHash += CFX_WideString(pszFontFamily).UTF8Encode(); + bsHash += FX_UTF8Encode(CFX_WideStringC(pszFontFamily)); uint32_t dwHash = FX_HashCode_GetA(bsHash.AsStringC(), false); std::vector<CFX_RetainPtr<CFGAS_GEFont>>* pFonts = &m_Hash2Fonts[dwHash]; for (size_t i = 0; i < pFonts->size(); ++i) { diff --git a/xfa/fgas/font/cfgas_fontmgr.h b/xfa/fgas/font/cfgas_fontmgr.h index 1dadfd347..dffdb8a66 100644 --- a/xfa/fgas/font/cfgas_fontmgr.h +++ b/xfa/fgas/font/cfgas_fontmgr.h @@ -7,6 +7,7 @@ #ifndef XFA_FGAS_FONT_CFGAS_FONTMGR_H_ #define XFA_FGAS_FONT_CFGAS_FONTMGR_H_ +#include <deque> #include <map> #include <memory> #include <set> @@ -70,8 +71,6 @@ struct FX_FONTDESCRIPTOR { FX_FONTSIGNATURE FontSignature; }; -typedef CFX_MassArrayTemplate<FX_FONTDESCRIPTOR> CFX_FontDescriptors; - inline bool operator==(const FX_FONTDESCRIPTOR& left, const FX_FONTDESCRIPTOR& right) { return left.uCharSet == right.uCharSet && @@ -80,7 +79,7 @@ inline bool operator==(const FX_FONTDESCRIPTOR& left, FXSYS_wcscmp(left.wsFontFace, right.wsFontFace) == 0; } -typedef void (*FX_LPEnumAllFonts)(CFX_FontDescriptors& fonts, +typedef void (*FX_LPEnumAllFonts)(std::deque<FX_FONTDESCRIPTOR>* fonts, const FX_WCHAR* pwsFaceName, FX_WCHAR wUnicode); @@ -119,7 +118,7 @@ class CFGAS_FontMgr { FX_WCHAR wUnicode = 0); FX_LPEnumAllFonts m_pEnumerator; - CFX_FontDescriptors m_FontFaces; + std::deque<FX_FONTDESCRIPTOR> m_FontFaces; std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_Fonts; std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_CPFonts; std::map<uint32_t, CFX_RetainPtr<CFGAS_GEFont>> m_FamilyFonts; diff --git a/xfa/fgas/font/cfgas_gefont.cpp b/xfa/fgas/font/cfgas_gefont.cpp index d0e7f13c3..a57962d08 100644 --- a/xfa/fgas/font/cfgas_gefont.cpp +++ b/xfa/fgas/font/cfgas_gefont.cpp @@ -220,8 +220,6 @@ bool CFGAS_GEFont::InitFont() { m_pCharWidthMap = pdfium::MakeUnique<CFX_DiscreteArrayTemplate<uint16_t>>(1024); } - if (!m_pRectArray) - m_pRectArray = pdfium::MakeUnique<CFX_MassArrayTemplate<CFX_Rect>>(16); return true; } @@ -315,33 +313,27 @@ bool CFGAS_GEFont::GetCharBBoxInternal(FX_WCHAR wUnicode, CFX_Rect* bbox, bool bRecursive, bool bCharCode) { - ASSERT(m_pRectArray); - CFX_Rect* pRect = nullptr; auto it = m_BBoxMap.find(wUnicode); - if (it == m_BBoxMap.end()) { - CFX_RetainPtr<CFGAS_GEFont> pFont; - int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); - if (iGlyph != 0xFFFF && pFont) { - if (pFont.Get() == this) { - FX_RECT rtBBox; - if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) { - CFX_Rect rt; - rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height()); - int32_t index = m_pRectArray->Add(rt); - pRect = m_pRectArray->GetPtrAt(index); - m_BBoxMap[wUnicode] = pRect; - } - } else if (pFont->GetCharBBoxInternal(wUnicode, bbox, false, bCharCode)) { - return true; - } - } - } else { - pRect = it->second; + if (it != m_BBoxMap.end()) { + *bbox = it->second; + return true; } - if (!pRect) + + CFX_RetainPtr<CFGAS_GEFont> pFont; + int32_t iGlyph = GetGlyphIndex(wUnicode, true, &pFont, bCharCode); + if (!pFont || iGlyph == 0xFFFF) + return false; + + if (pFont.Get() != this) + return pFont->GetCharBBoxInternal(wUnicode, bbox, false, bCharCode); + + FX_RECT rtBBox; + if (!m_pFont->GetGlyphBBox(iGlyph, rtBBox)) return false; - *bbox = *pRect; + CFX_Rect rt(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height()); + m_BBoxMap[wUnicode] = rt; + *bbox = rt; return true; } diff --git a/xfa/fgas/font/cfgas_gefont.h b/xfa/fgas/font/cfgas_gefont.h index 6c9d890df..2201721a9 100644 --- a/xfa/fgas/font/cfgas_gefont.h +++ b/xfa/fgas/font/cfgas_gefont.h @@ -109,8 +109,7 @@ class CFGAS_GEFont : public CFX_Retainable { CFX_RetainPtr<IFX_SeekableReadStream> m_pFileRead; std::unique_ptr<CFX_UnicodeEncoding> m_pFontEncoding; std::unique_ptr<CFX_DiscreteArrayTemplate<uint16_t>> m_pCharWidthMap; - std::unique_ptr<CFX_MassArrayTemplate<CFX_Rect>> m_pRectArray; - std::map<FX_WCHAR, CFX_Rect*> m_BBoxMap; // Rect owned by m_pRectArray. + std::map<FX_WCHAR, CFX_Rect> m_BBoxMap; CXFA_PDFFontMgr* m_pProvider; // not owned. std::vector<CFX_RetainPtr<CFGAS_GEFont>> m_SubstFonts; std::map<FX_WCHAR, CFX_RetainPtr<CFGAS_GEFont>> m_FontMapper; diff --git a/xfa/fgas/layout/fgas_rtfbreak.cpp b/xfa/fgas/layout/fgas_rtfbreak.cpp index f7ba0e72b..9a83be65a 100644 --- a/xfa/fgas/layout/fgas_rtfbreak.cpp +++ b/xfa/fgas/layout/fgas_rtfbreak.cpp @@ -13,36 +13,40 @@ #include "third_party/base/stl_util.h" #include "xfa/fgas/font/cfgas_gefont.h" #include "xfa/fgas/layout/fgas_linebreak.h" -#include "xfa/fgas/layout/fgas_unicode.h" -CFX_RTFBreak::CFX_RTFBreak(uint32_t dwPolicies) - : m_dwPolicies(dwPolicies), - m_iBoundaryStart(0), +namespace { + +typedef CFX_RTFBreakType (CFX_RTFBreak::*FX_RTFBreak_LPFAppendChar)( + CFX_RTFChar* pCurChar); +const FX_RTFBreak_LPFAppendChar g_FX_RTFBreak_lpfAppendChar[16] = { + &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Tab, + &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Control, + &CFX_RTFBreak::AppendChar_Combination, &CFX_RTFBreak::AppendChar_Others, + &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Arabic, + &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic, + &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic, + &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Others, + &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Others, +}; + +} // namespace + +CFX_RTFBreak::CFX_RTFBreak(uint32_t dwLayoutStyles) + : m_iBoundaryStart(0), m_iBoundaryEnd(2000000), - m_dwLayoutStyles(0), + m_dwLayoutStyles(dwLayoutStyles), m_bPagination(false), - m_bVertical(false), - m_bSingleLine(false), - m_bCharCode(false), m_pFont(nullptr), m_iFontHeight(240), m_iFontSize(240), m_iTabWidth(720000), - m_PositionedTabs(), - m_bOrphanLine(false), m_wDefChar(0xFEFF), m_iDefChar(0), m_wLineBreakChar(L'\n'), m_iHorizontalScale(100), m_iVerticalScale(100), - m_iLineRotation(0), - m_iCharRotation(0), - m_iRotation(0), m_iCharSpace(0), - m_bWordSpace(false), - m_iWordSpace(0), - m_bRTL(false), - m_iAlignment(FX_RTFLINEALIGNMENT_Left), + m_iAlignment(CFX_RTFLineAlignment::Left), m_pUserData(nullptr), m_eCharType(FX_CHARTYPE_Unknown), m_dwIdentity(0), @@ -52,13 +56,13 @@ CFX_RTFBreak::CFX_RTFBreak(uint32_t dwPolicies) m_iReady(0), m_iTolerance(0) { m_pCurLine = &m_RTFLine1; + + SetBreakStatus(); + m_bPagination = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_Pagination) != 0; } CFX_RTFBreak::~CFX_RTFBreak() { Reset(); - m_PositionedTabs.RemoveAll(); - if (m_pUserData) - m_pUserData->Release(); } void CFX_RTFBreak::SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) { @@ -78,443 +82,249 @@ void CFX_RTFBreak::SetLineStartPos(FX_FLOAT fLinePos) { m_pCurLine->m_iStart = iLinePos; } -void CFX_RTFBreak::SetLayoutStyles(uint32_t dwLayoutStyles) { - if (m_dwLayoutStyles == dwLayoutStyles) - return; - - SetBreakStatus(); - m_dwLayoutStyles = dwLayoutStyles; - m_bPagination = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_Pagination) != 0; - m_bVertical = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0; - m_bSingleLine = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0; - m_bCharCode = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0; - m_iLineRotation = GetLineRotation(m_dwLayoutStyles); - m_iRotation = m_iLineRotation + m_iCharRotation; - m_iRotation %= 4; -} - void CFX_RTFBreak::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { if (!pFont || pFont == m_pFont) return; SetBreakStatus(); m_pFont = pFont; - m_iDefChar = 0; - if (m_pFont) { - m_iFontHeight = m_iFontSize; - if (m_wDefChar != 0xFEFF) { - m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); - m_iDefChar *= m_iFontSize; - } - } + FontChanged(); } void CFX_RTFBreak::SetFontSize(FX_FLOAT fFontSize) { int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); - if (m_iFontSize == iFontSize) { + if (m_iFontSize == iFontSize) return; - } + SetBreakStatus(); m_iFontSize = iFontSize; + FontChanged(); +} + +void CFX_RTFBreak::FontChanged() { m_iDefChar = 0; - if (m_pFont) { - m_iFontHeight = m_iFontSize; - if (m_wDefChar != 0xFEFF) { - m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); - m_iDefChar *= m_iFontSize; - } - } + if (!m_pFont) + return; + + m_iFontHeight = m_iFontSize; + if (m_wDefChar == 0xFEFF) + return; + + m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); + m_iDefChar *= m_iFontSize; } + void CFX_RTFBreak::SetTabWidth(FX_FLOAT fTabWidth) { m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f); } + void CFX_RTFBreak::AddPositionedTab(FX_FLOAT fTabPos) { - int32_t iLineEnd = m_iBoundaryEnd; - int32_t iTabPos = FXSYS_round(fTabPos * 20000.0f) + m_iBoundaryStart; - if (iTabPos > iLineEnd) { - iTabPos = iLineEnd; - } - if (m_PositionedTabs.Find(iTabPos, 0) > -1) { + int32_t iTabPos = std::min(FXSYS_round(fTabPos * 20000.0f) + m_iBoundaryStart, + m_iBoundaryEnd); + auto it = std::lower_bound(m_PositionedTabs.begin(), m_PositionedTabs.end(), + iTabPos); + if (it != m_PositionedTabs.end() && *it == iTabPos) return; - } - int32_t iCount = m_PositionedTabs.GetSize(); - int32_t iFind = 0; - for (; iFind < iCount; iFind++) { - if (m_PositionedTabs[iFind] > iTabPos) { - break; - } - } - m_PositionedTabs.InsertAt(iFind, iTabPos); - if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) { - m_bOrphanLine = GetLastPositionedTab() >= iLineEnd; - } else { - m_bOrphanLine = false; - } -} -void CFX_RTFBreak::SetPositionedTabs(const std::vector<FX_FLOAT>& tabs) { - m_PositionedTabs.RemoveAll(); - int32_t iCount = pdfium::CollectionSize<int32_t>(tabs); - m_PositionedTabs.SetSize(iCount); - int32_t iLineEnd = m_iBoundaryEnd; - int32_t iTabPos; - for (int32_t i = 0; i < iCount; i++) { - iTabPos = FXSYS_round(tabs[i] * 20000.0f) + m_iBoundaryStart; - if (iTabPos > iLineEnd) { - iTabPos = iLineEnd; - } - m_PositionedTabs[i] = iTabPos; - } - if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) { - m_bOrphanLine = GetLastPositionedTab() >= iLineEnd; - } else { - m_bOrphanLine = false; - } -} -void CFX_RTFBreak::ClearPositionedTabs() { - m_PositionedTabs.RemoveAll(); - m_bOrphanLine = false; -} -void CFX_RTFBreak::SetDefaultChar(FX_WCHAR wch) { - m_wDefChar = wch; - m_iDefChar = 0; - if (m_wDefChar != 0xFEFF && m_pFont) { - m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); - if (m_iDefChar < 0) { - m_iDefChar = 0; - } else { - m_iDefChar *= m_iFontSize; - } - } -} -void CFX_RTFBreak::SetLineBreakChar(FX_WCHAR wch) { - if (wch != L'\r' && wch != L'\n') { - return; - } - m_wLineBreakChar = wch; + m_PositionedTabs.insert(it, iTabPos); } + void CFX_RTFBreak::SetLineBreakTolerance(FX_FLOAT fTolerance) { m_iTolerance = FXSYS_round(fTolerance * 20000.0f); } + void CFX_RTFBreak::SetHorizontalScale(int32_t iScale) { - if (iScale < 0) { + if (iScale < 0) iScale = 0; - } - if (m_iHorizontalScale == iScale) { + if (m_iHorizontalScale == iScale) return; - } + SetBreakStatus(); m_iHorizontalScale = iScale; } + void CFX_RTFBreak::SetVerticalScale(int32_t iScale) { - if (iScale < 0) { + if (iScale < 0) iScale = 0; - } - if (m_iVerticalScale == iScale) { + if (m_iVerticalScale == iScale) return; - } + SetBreakStatus(); m_iVerticalScale = iScale; } -void CFX_RTFBreak::SetCharRotation(int32_t iCharRotation) { - if (iCharRotation < 0) { - iCharRotation += (-iCharRotation / 4 + 1) * 4; - } else if (iCharRotation > 3) { - iCharRotation -= (iCharRotation / 4) * 4; - } - if (m_iCharRotation == iCharRotation) { - return; - } - SetBreakStatus(); - m_iCharRotation = iCharRotation; - m_iRotation = m_iLineRotation + m_iCharRotation; - m_iRotation %= 4; -} + void CFX_RTFBreak::SetCharSpace(FX_FLOAT fCharSpace) { m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f); } -void CFX_RTFBreak::SetWordSpace(bool bDefault, FX_FLOAT fWordSpace) { - m_bWordSpace = !bDefault; - m_iWordSpace = FXSYS_round(fWordSpace * 20000.0f); -} -void CFX_RTFBreak::SetReadingOrder(bool bRTL) { - m_bRTL = bRTL; -} -void CFX_RTFBreak::SetAlignment(int32_t iAlignment) { - ASSERT(iAlignment >= FX_RTFLINEALIGNMENT_Left && - iAlignment <= FX_RTFLINEALIGNMENT_Distributed); - m_iAlignment = iAlignment; -} -void CFX_RTFBreak::SetUserData(IFX_Retainable* pUserData) { - if (m_pUserData == pUserData) { + +void CFX_RTFBreak::SetUserData(const CFX_RetainPtr<CFX_Retainable>& pUserData) { + if (m_pUserData == pUserData) return; - } + SetBreakStatus(); - if (m_pUserData) { - m_pUserData->Release(); - } m_pUserData = pUserData; - if (m_pUserData) { - m_pUserData->Retain(); - } -} -static const int32_t gs_FX_RTFLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2}; -int32_t CFX_RTFBreak::GetLineRotation(uint32_t dwStyles) const { - return gs_FX_RTFLineRotations[(dwStyles & 0x0E) >> 1]; } + void CFX_RTFBreak::SetBreakStatus() { m_dwIdentity++; int32_t iCount = m_pCurLine->CountChars(); - if (iCount < 1) { + if (iCount < 1) return; - } + CFX_RTFChar& tc = m_pCurLine->GetChar(iCount - 1); - if (tc.m_dwStatus == 0) { - tc.m_dwStatus = FX_RTFBREAK_PieceBreak; - } + if (tc.m_dwStatus == CFX_RTFBreakType::None) + tc.m_dwStatus = CFX_RTFBreakType::Piece; } + CFX_RTFChar* CFX_RTFBreak::GetLastChar(int32_t index) const { - CFX_RTFCharArray& tca = m_pCurLine->m_LineChars; - int32_t iCount = tca.GetSize(); - if (index < 0 || index >= iCount) { + std::vector<CFX_RTFChar>& tca = m_pCurLine->m_LineChars; + int32_t iCount = pdfium::CollectionSize<int32_t>(tca); + if (index < 0 || index >= iCount) return nullptr; - } - CFX_RTFChar* pTC; + int32_t iStart = iCount - 1; while (iStart > -1) { - pTC = tca.GetDataPtr(iStart--); + CFX_RTFChar* pTC = &tca[iStart--]; if (pTC->m_iCharWidth >= 0 || pTC->GetCharType() != FX_CHARTYPE_Combination) { - if (--index < 0) { + if (--index < 0) return pTC; - } } } return nullptr; } -CFX_RTFLine* CFX_RTFBreak::GetRTFLine(bool bReady) const { - if (bReady) { - if (m_iReady == 1) { - return (CFX_RTFLine*)&m_RTFLine1; - } else if (m_iReady == 2) { - return (CFX_RTFLine*)&m_RTFLine2; - } else { - return nullptr; - } - } - ASSERT(m_pCurLine); - return m_pCurLine; + +const CFX_RTFLine* CFX_RTFBreak::GetRTFLine() const { + if (m_iReady == 1) + return &m_RTFLine1; + if (m_iReady == 2) + return &m_RTFLine2; + return nullptr; } -CFX_RTFPieceArray* CFX_RTFBreak::GetRTFPieces(bool bReady) const { - CFX_RTFLine* pRTFLine = GetRTFLine(bReady); + +const CFX_RTFPieceArray* CFX_RTFBreak::GetRTFPieces() const { + const CFX_RTFLine* pRTFLine = GetRTFLine(); return pRTFLine ? &pRTFLine->m_LinePieces : nullptr; } + inline FX_CHARTYPE CFX_RTFBreak::GetUnifiedCharType( FX_CHARTYPE chartype) const { return chartype >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : chartype; } + int32_t CFX_RTFBreak::GetLastPositionedTab() const { - int32_t iCount = m_PositionedTabs.GetSize(); - if (iCount < 1) { - return m_iBoundaryStart; - } - return m_PositionedTabs[iCount - 1]; + return m_PositionedTabs.empty() ? m_iBoundaryStart : m_PositionedTabs.back(); } -bool CFX_RTFBreak::GetPositionedTab(int32_t& iTabPos) const { - int32_t iCount = m_PositionedTabs.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - if (m_PositionedTabs[i] > iTabPos) { - iTabPos = m_PositionedTabs[i]; - return true; - } - } - return false; + +bool CFX_RTFBreak::GetPositionedTab(int32_t* iTabPos) const { + auto it = std::upper_bound(m_PositionedTabs.begin(), m_PositionedTabs.end(), + *iTabPos); + if (it == m_PositionedTabs.end()) + return false; + + *iTabPos = *it; + return true; } -typedef uint32_t (CFX_RTFBreak::*FX_RTFBreak_LPFAppendChar)( - CFX_RTFChar* pCurChar, - int32_t iRotation); -static const FX_RTFBreak_LPFAppendChar g_FX_RTFBreak_lpfAppendChar[16] = { - &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Tab, - &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Control, - &CFX_RTFBreak::AppendChar_Combination, &CFX_RTFBreak::AppendChar_Others, - &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Arabic, - &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic, - &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Arabic, - &CFX_RTFBreak::AppendChar_Arabic, &CFX_RTFBreak::AppendChar_Others, - &CFX_RTFBreak::AppendChar_Others, &CFX_RTFBreak::AppendChar_Others, -}; -uint32_t CFX_RTFBreak::AppendChar(FX_WCHAR wch) { + +CFX_RTFBreakType CFX_RTFBreak::AppendChar(FX_WCHAR wch) { ASSERT(m_pFont && m_pCurLine); - if (m_bCharCode) - return AppendChar_CharCode(wch); - uint32_t dwProps = kTextLayoutCodeProperties[(uint16_t)wch]; + uint32_t dwProps = kTextLayoutCodeProperties[static_cast<uint16_t>(wch)]; FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps); - CFX_RTFCharArray& tca = m_pCurLine->m_LineChars; - CFX_RTFChar* pCurChar = tca.AddSpace(); - pCurChar->m_dwStatus = 0; + m_pCurLine->m_LineChars.emplace_back(); + + CFX_RTFChar* pCurChar = &m_pCurLine->m_LineChars.back(); + pCurChar->m_dwStatus = CFX_RTFBreakType::None; pCurChar->m_wCharCode = wch; pCurChar->m_dwCharProps = dwProps; - pCurChar->m_dwCharStyles = 0; - pCurChar->m_dwLayoutStyles = 0; pCurChar->m_iFontSize = m_iFontSize; pCurChar->m_iFontHeight = m_iFontHeight; pCurChar->m_iHorizontalScale = m_iHorizontalScale; - pCurChar->m_iVertialScale = m_iVerticalScale; - pCurChar->m_nRotation = m_iCharRotation; + pCurChar->m_iVerticalScale = m_iVerticalScale; pCurChar->m_iCharWidth = 0; pCurChar->m_dwIdentity = m_dwIdentity; - if (m_pUserData) { - m_pUserData->Retain(); - } pCurChar->m_pUserData = m_pUserData; - uint32_t dwRet1 = FX_RTFBREAK_None; + + CFX_RTFBreakType dwRet1 = CFX_RTFBreakType::None; if (chartype != FX_CHARTYPE_Combination && - GetUnifiedCharType(m_eCharType) != GetUnifiedCharType(chartype)) { - if (!m_bSingleLine && !m_bOrphanLine && - m_eCharType != FX_CHARTYPE_Unknown && - m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) { - if (m_eCharType != FX_CHARTYPE_Space || chartype != FX_CHARTYPE_Control) { - dwRet1 = EndBreak(FX_RTFBREAK_LineBreak); - int32_t iCount = m_pCurLine->CountChars(); - if (iCount > 0) { - pCurChar = m_pCurLine->m_LineChars.GetDataPtr(iCount - 1); - } - } - } - } - int32_t iRotation = m_iRotation; - if (m_bVertical && (dwProps & 0x8000) != 0) { - iRotation = (iRotation + 1) % 4; + GetUnifiedCharType(m_eCharType) != GetUnifiedCharType(chartype) && + m_eCharType != FX_CHARTYPE_Unknown && + m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance && + (m_eCharType != FX_CHARTYPE_Space || chartype != FX_CHARTYPE_Control)) { + dwRet1 = EndBreak(CFX_RTFBreakType::Line); + int32_t iCount = m_pCurLine->CountChars(); + if (iCount > 0) + pCurChar = &m_pCurLine->m_LineChars[iCount - 1]; } - uint32_t dwRet2 = + + CFX_RTFBreakType dwRet2 = (this->*g_FX_RTFBreak_lpfAppendChar[chartype >> FX_CHARTYPEBITS])( - pCurChar, iRotation); + pCurChar); m_eCharType = chartype; return std::max(dwRet1, dwRet2); } -uint32_t CFX_RTFBreak::AppendChar_CharCode(FX_WCHAR wch) { - ASSERT(m_pFont && m_pCurLine); - ASSERT(m_bCharCode); - m_pCurLine->m_iMBCSChars++; - CFX_RTFCharArray& tca = m_pCurLine->m_LineChars; - CFX_RTFChar* pCurChar = tca.AddSpace(); - pCurChar->m_dwStatus = 0; - pCurChar->m_wCharCode = wch; - pCurChar->m_dwCharProps = 0; - pCurChar->m_dwCharStyles = 0; - pCurChar->m_dwLayoutStyles = m_dwLayoutStyles; - pCurChar->m_iFontSize = m_iFontSize; - pCurChar->m_iFontHeight = m_iFontHeight; - pCurChar->m_iHorizontalScale = m_iHorizontalScale; - pCurChar->m_iVertialScale = m_iVerticalScale; - pCurChar->m_nRotation = m_iCharRotation; - pCurChar->m_iCharWidth = 0; - pCurChar->m_dwIdentity = m_dwIdentity; - if (m_pUserData) - m_pUserData->Retain(); - - pCurChar->m_pUserData = m_pUserData; +CFX_RTFBreakType CFX_RTFBreak::AppendChar_Combination(CFX_RTFChar* pCurChar) { int32_t iCharWidth = 0; - if (m_bVertical != FX_IsOdd(m_iRotation)) { - iCharWidth = 1000; - } else { - if (!m_pFont->GetCharWidth(wch, iCharWidth, true)) { - iCharWidth = m_iDefChar; - } - } - iCharWidth *= m_iFontSize; - iCharWidth = iCharWidth * m_iHorizontalScale / 100; - iCharWidth += m_iCharSpace; - pCurChar->m_iCharWidth = iCharWidth; - m_pCurLine->m_iWidth += iCharWidth; - m_eCharType = FX_CHARTYPE_Unknown; - if (!m_bSingleLine && - m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) { - return EndBreak(FX_RTFBREAK_LineBreak); - } - return FX_RTFBREAK_None; -} + if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth, false)) + iCharWidth = 0; -uint32_t CFX_RTFBreak::AppendChar_Combination(CFX_RTFChar* pCurChar, - int32_t iRotation) { - int32_t iCharWidth = 0; - if (m_bVertical != FX_IsOdd(iRotation)) { - iCharWidth = 1000; - } else { - if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth, - m_bCharCode)) { - iCharWidth = 0; - } - } iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorizontalScale / 100; CFX_RTFChar* pLastChar = GetLastChar(0); - if (pLastChar && pLastChar->GetCharType() > FX_CHARTYPE_Combination) { + if (pLastChar && pLastChar->GetCharType() > FX_CHARTYPE_Combination) iCharWidth = -iCharWidth; - } else { + else m_eCharType = FX_CHARTYPE_Combination; - } + pCurChar->m_iCharWidth = iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) m_pCurLine->m_iWidth += iCharWidth; - } - return FX_RTFBREAK_None; + + return CFX_RTFBreakType::None; } -uint32_t CFX_RTFBreak::AppendChar_Tab(CFX_RTFChar* pCurChar, - int32_t iRotation) { - if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ExpandTab) { - bool bBreak = false; - if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) { - bBreak = (m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance); - } - int32_t& iLineWidth = m_pCurLine->m_iWidth; - int32_t iCharWidth = iLineWidth; - if (GetPositionedTab(iCharWidth)) { - iCharWidth -= iLineWidth; - } else { - iCharWidth = m_iTabWidth * (iLineWidth / m_iTabWidth + 1) - iLineWidth; - } - pCurChar->m_iCharWidth = iCharWidth; - iLineWidth += iCharWidth; - if (!m_bSingleLine && !m_bOrphanLine && bBreak) { - return EndBreak(FX_RTFBREAK_LineBreak); - } - } - return FX_RTFBREAK_None; + +CFX_RTFBreakType CFX_RTFBreak::AppendChar_Tab(CFX_RTFChar* pCurChar) { + if (!(m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ExpandTab)) + return CFX_RTFBreakType::None; + + int32_t& iLineWidth = m_pCurLine->m_iWidth; + int32_t iCharWidth = iLineWidth; + if (GetPositionedTab(&iCharWidth)) + iCharWidth -= iLineWidth; + else + iCharWidth = m_iTabWidth * (iLineWidth / m_iTabWidth + 1) - iLineWidth; + + pCurChar->m_iCharWidth = iCharWidth; + iLineWidth += iCharWidth; + return CFX_RTFBreakType::None; } -uint32_t CFX_RTFBreak::AppendChar_Control(CFX_RTFChar* pCurChar, - int32_t iRotation) { - uint32_t dwRet2 = FX_RTFBREAK_None; - if (!m_bSingleLine) { - switch (pCurChar->m_wCharCode) { - case L'\v': - case 0x2028: - dwRet2 = FX_RTFBREAK_LineBreak; - break; - case L'\f': - dwRet2 = FX_RTFBREAK_PageBreak; - break; - case 0x2029: - dwRet2 = FX_RTFBREAK_ParagraphBreak; - break; - default: - if (pCurChar->m_wCharCode == m_wLineBreakChar) { - dwRet2 = FX_RTFBREAK_ParagraphBreak; - } - break; - } - if (dwRet2 != FX_RTFBREAK_None) { - dwRet2 = EndBreak(dwRet2); - } + +CFX_RTFBreakType CFX_RTFBreak::AppendChar_Control(CFX_RTFChar* pCurChar) { + CFX_RTFBreakType dwRet2 = CFX_RTFBreakType::None; + switch (pCurChar->m_wCharCode) { + case L'\v': + case 0x2028: + dwRet2 = CFX_RTFBreakType::Line; + break; + case L'\f': + dwRet2 = CFX_RTFBreakType::Page; + break; + case 0x2029: + dwRet2 = CFX_RTFBreakType::Paragraph; + break; + default: + if (pCurChar->m_wCharCode == m_wLineBreakChar) + dwRet2 = CFX_RTFBreakType::Paragraph; + break; } + if (dwRet2 != CFX_RTFBreakType::None) + dwRet2 = EndBreak(dwRet2); + return dwRet2; } -uint32_t CFX_RTFBreak::AppendChar_Arabic(CFX_RTFChar* pCurChar, - int32_t iRotation) { +CFX_RTFBreakType CFX_RTFBreak::AppendChar_Arabic(CFX_RTFChar* pCurChar) { CFX_RTFChar* pLastChar = nullptr; - int32_t& iLineWidth = m_pCurLine->m_iWidth; int32_t iCharWidth = 0; FX_WCHAR wForm; bool bAlef = false; @@ -522,146 +332,116 @@ uint32_t CFX_RTFBreak::AppendChar_Arabic(CFX_RTFChar* pCurChar, m_eCharType <= FX_CHARTYPE_ArabicDistortion) { pLastChar = GetLastChar(1); if (pLastChar) { - iLineWidth -= pLastChar->m_iCharWidth; + m_pCurLine->m_iWidth -= pLastChar->m_iCharWidth; CFX_RTFChar* pPrevChar = GetLastChar(2); wForm = pdfium::arabic::GetFormChar(pLastChar, pPrevChar, pCurChar); bAlef = (wForm == 0xFEFF && pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef); - int32_t iLastRotation = pLastChar->m_nRotation + m_iLineRotation; - if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) { - iLastRotation++; - } - if (m_bVertical != FX_IsOdd(iLastRotation)) { - iCharWidth = 1000; - } else { - if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode)) { - if (!m_pFont->GetCharWidth(pLastChar->m_wCharCode, iCharWidth, - m_bCharCode)) { - iCharWidth = m_iDefChar; - } - } + if (!m_pFont->GetCharWidth(wForm, iCharWidth, false) && + !m_pFont->GetCharWidth(pLastChar->m_wCharCode, iCharWidth, false)) { + iCharWidth = m_iDefChar; } + iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorizontalScale / 100; pLastChar->m_iCharWidth = iCharWidth; - iLineWidth += iCharWidth; + m_pCurLine->m_iWidth += iCharWidth; iCharWidth = 0; } } + wForm = pdfium::arabic::GetFormChar(pCurChar, bAlef ? nullptr : pLastChar, nullptr); - if (m_bVertical != FX_IsOdd(iRotation)) { - iCharWidth = 1000; - } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode) && - !m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth, - m_bCharCode)) { + if (!m_pFont->GetCharWidth(wForm, iCharWidth, false) && + !m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth, false)) { iCharWidth = m_iDefChar; } iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorizontalScale / 100; pCurChar->m_iCharWidth = iCharWidth; - iLineWidth += iCharWidth; + m_pCurLine->m_iWidth += iCharWidth; m_pCurLine->m_iArabicChars++; - if (!m_bSingleLine && !m_bOrphanLine && - m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) { - return EndBreak(FX_RTFBREAK_LineBreak); - } - return FX_RTFBREAK_None; + + if (m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) + return EndBreak(CFX_RTFBreakType::Line); + return CFX_RTFBreakType::None; } -uint32_t CFX_RTFBreak::AppendChar_Others(CFX_RTFChar* pCurChar, - int32_t iRotation) { +CFX_RTFBreakType CFX_RTFBreak::AppendChar_Others(CFX_RTFChar* pCurChar) { FX_CHARTYPE chartype = pCurChar->GetCharType(); - FX_WCHAR wForm; - if (chartype == FX_CHARTYPE_Numeric) { - if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) - wForm = pCurChar->m_wCharCode + 0x0630; - else - wForm = pCurChar->m_wCharCode; - } else if (m_bRTL || m_bVertical) { - wForm = FX_GetMirrorChar(pCurChar->m_wCharCode, pCurChar->m_dwCharProps, - m_bRTL, m_bVertical); - } else { - wForm = pCurChar->m_wCharCode; - } + FX_WCHAR wForm = pCurChar->m_wCharCode; int32_t iCharWidth = 0; - if (m_bVertical == FX_IsOdd(iRotation)) { - if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode)) - iCharWidth = m_iDefChar; - } else { - iCharWidth = 1000; - } + if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) + iCharWidth = m_iDefChar; + iCharWidth *= m_iFontSize; iCharWidth *= m_iHorizontalScale / 100; iCharWidth += m_iCharSpace; - if (chartype == FX_CHARTYPE_Space && m_bWordSpace) - iCharWidth += m_iWordSpace; pCurChar->m_iCharWidth = iCharWidth; m_pCurLine->m_iWidth += iCharWidth; - bool bBreak = (chartype != FX_CHARTYPE_Space || - (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0); - if (!m_bSingleLine && !m_bOrphanLine && bBreak && + if (chartype != FX_CHARTYPE_Space && m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) { - return EndBreak(FX_RTFBREAK_LineBreak); + return EndBreak(CFX_RTFBreakType::Line); } - return FX_RTFBREAK_None; + return CFX_RTFBreakType::None; } -uint32_t CFX_RTFBreak::EndBreak(uint32_t dwStatus) { - ASSERT(dwStatus >= FX_RTFBREAK_PieceBreak && - dwStatus <= FX_RTFBREAK_PageBreak); +CFX_RTFBreakType CFX_RTFBreak::EndBreak(CFX_RTFBreakType dwStatus) { + ASSERT(dwStatus != CFX_RTFBreakType::None); + m_dwIdentity++; - CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces; + const CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces; int32_t iCount = pCurPieces->GetSize(); if (iCount > 0) { CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount); - if (dwStatus > FX_RTFBREAK_PieceBreak) + if (dwStatus != CFX_RTFBreakType::Piece) pLastPiece->m_dwStatus = dwStatus; else dwStatus = pLastPiece->m_dwStatus; return dwStatus; } - CFX_RTFLine* pLastLine = GetRTFLine(true); + const CFX_RTFLine* pLastLine = GetRTFLine(); if (pLastLine) { pCurPieces = &pLastLine->m_LinePieces; iCount = pCurPieces->GetSize(); if (iCount-- > 0) { CFX_RTFPiece* pLastPiece = pCurPieces->GetPtrAt(iCount); - if (dwStatus > FX_RTFBREAK_PieceBreak) + if (dwStatus != CFX_RTFBreakType::Piece) pLastPiece->m_dwStatus = dwStatus; else dwStatus = pLastPiece->m_dwStatus; return dwStatus; } - return FX_RTFBREAK_None; + return CFX_RTFBreakType::None; } + iCount = m_pCurLine->CountChars(); if (iCount < 1) - return FX_RTFBREAK_None; + return CFX_RTFBreakType::None; CFX_RTFChar& tc = m_pCurLine->GetChar(iCount - 1); tc.m_dwStatus = dwStatus; - if (dwStatus <= FX_RTFBREAK_PieceBreak) + if (dwStatus == CFX_RTFBreakType::Piece) return dwStatus; - m_iReady = (m_pCurLine == &m_RTFLine1) ? 1 : 2; + m_iReady = m_pCurLine == &m_RTFLine1 ? 1 : 2; CFX_RTFLine* pNextLine = - (m_pCurLine == &m_RTFLine1) ? &m_RTFLine2 : &m_RTFLine1; - bool bAllChars = (m_iAlignment > FX_RTFLINEALIGNMENT_Right); - CFX_TPOArray tpos(100); - if (!EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) { - if (!m_bCharCode) - EndBreak_BidiLine(tpos, dwStatus); + m_pCurLine == &m_RTFLine1 ? &m_RTFLine2 : &m_RTFLine1; + bool bAllChars = m_iAlignment == CFX_RTFLineAlignment::Justified || + m_iAlignment == CFX_RTFLineAlignment::Distributed; - if (!m_bPagination && m_iAlignment > FX_RTFLINEALIGNMENT_Left) + if (!EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) { + std::deque<FX_TPO> tpos; + EndBreak_BidiLine(&tpos, dwStatus); + if (!m_bPagination && m_iAlignment != CFX_RTFLineAlignment::Left) EndBreak_Alignment(tpos, bAllChars, dwStatus); } - m_pCurLine = pNextLine; m_pCurLine->m_iStart = m_iBoundaryStart; + CFX_RTFChar* pTC = GetLastChar(0); m_eCharType = pTC ? pTC->GetCharType() : FX_CHARTYPE_Unknown; return dwStatus; @@ -669,25 +449,14 @@ uint32_t CFX_RTFBreak::EndBreak(uint32_t dwStatus) { bool CFX_RTFBreak::EndBreak_SplitLine(CFX_RTFLine* pNextLine, bool bAllChars, - uint32_t dwStatus) { + CFX_RTFBreakType dwStatus) { bool bDone = false; - if (!m_bSingleLine && !m_bOrphanLine && - m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) { - CFX_RTFChar& tc = m_pCurLine->GetChar(m_pCurLine->CountChars() - 1); + if (m_pCurLine->GetLineEnd() > m_iBoundaryEnd + m_iTolerance) { + const CFX_RTFChar& tc = m_pCurLine->GetChar(m_pCurLine->CountChars() - 1); switch (tc.GetCharType()) { case FX_CHARTYPE_Tab: - if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) { - SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars); - bDone = true; - } - break; case FX_CHARTYPE_Control: - break; case FX_CHARTYPE_Space: - if ((m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0) { - SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars); - bDone = true; - } break; default: SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars); @@ -695,114 +464,115 @@ bool CFX_RTFBreak::EndBreak_SplitLine(CFX_RTFLine* pNextLine, break; } } - if (m_bPagination || m_pCurLine->m_iMBCSChars > 0) { - const CFX_RTFChar* pCurChars = m_pCurLine->m_LineChars.GetData(); - const CFX_RTFChar* pTC; - CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces; - CFX_RTFPiece tp; - tp.m_pChars = &m_pCurLine->m_LineChars; - bool bNew = true; - uint32_t dwIdentity = (uint32_t)-1; - int32_t iLast = m_pCurLine->CountChars() - 1, j = 0; - for (int32_t i = 0; i <= iLast;) { - pTC = pCurChars + i; - if (bNew) { - tp.m_iStartChar = i; - tp.m_iStartPos += tp.m_iWidth; - tp.m_iWidth = 0; + + if (!m_bPagination && m_pCurLine->m_iMBCSChars <= 0) { + if (bAllChars && !bDone) { + int32_t endPos = m_pCurLine->GetLineEnd(); + GetBreakPos(m_pCurLine->m_LineChars, endPos, bAllChars, true); + } + return false; + } + + const CFX_RTFChar* pCurChars = m_pCurLine->m_LineChars.data(); + const CFX_RTFChar* pTC; + CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces; + CFX_RTFPiece tp; + tp.m_pChars = &m_pCurLine->m_LineChars; + bool bNew = true; + uint32_t dwIdentity = static_cast<uint32_t>(-1); + int32_t iLast = m_pCurLine->CountChars() - 1; + int32_t j = 0; + for (int32_t i = 0; i <= iLast;) { + pTC = pCurChars + i; + if (bNew) { + tp.m_iStartChar = i; + tp.m_iStartPos += tp.m_iWidth; + tp.m_iWidth = 0; + tp.m_dwStatus = pTC->m_dwStatus; + tp.m_iFontSize = pTC->m_iFontSize; + tp.m_iFontHeight = pTC->m_iFontHeight; + tp.m_iHorizontalScale = pTC->m_iHorizontalScale; + tp.m_iVerticalScale = pTC->m_iVerticalScale; + dwIdentity = pTC->m_dwIdentity; + tp.m_dwIdentity = dwIdentity; + tp.m_pUserData = pTC->m_pUserData; + j = i; + bNew = false; + } + + if (i == iLast || pTC->m_dwStatus != CFX_RTFBreakType::None || + pTC->m_dwIdentity != dwIdentity) { + tp.m_iChars = i - j; + if (pTC->m_dwIdentity == dwIdentity) { tp.m_dwStatus = pTC->m_dwStatus; - tp.m_iFontSize = pTC->m_iFontSize; - tp.m_iFontHeight = pTC->m_iFontHeight; - tp.m_iHorizontalScale = pTC->m_iHorizontalScale; - tp.m_iVerticalScale = pTC->m_iVertialScale; - tp.m_dwLayoutStyles = pTC->m_dwLayoutStyles; - dwIdentity = pTC->m_dwIdentity; - tp.m_dwIdentity = dwIdentity; - tp.m_pUserData = pTC->m_pUserData; - j = i; - bNew = false; - } - if (i == iLast || pTC->m_dwStatus != FX_RTFBREAK_None || - pTC->m_dwIdentity != dwIdentity) { - tp.m_iChars = i - j; - if (pTC->m_dwIdentity == dwIdentity) { - tp.m_dwStatus = pTC->m_dwStatus; - tp.m_iWidth += pTC->m_iCharWidth; - tp.m_iChars += 1; - i++; - } - pCurPieces->Add(tp); - bNew = true; - } else { tp.m_iWidth += pTC->m_iCharWidth; + tp.m_iChars += 1; i++; } + pCurPieces->Add(tp); + bNew = true; + } else { + tp.m_iWidth += pTC->m_iCharWidth; + i++; } - return true; } - if (bAllChars && !bDone) { - int32_t iEndPos = m_pCurLine->GetLineEnd(); - GetBreakPos(m_pCurLine->m_LineChars, iEndPos, bAllChars, true); - } - return false; + return true; } -void CFX_RTFBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { + +void CFX_RTFBreak::EndBreak_BidiLine(std::deque<FX_TPO>* tpos, + CFX_RTFBreakType dwStatus) { FX_TPO tpo; CFX_RTFPiece tp; CFX_RTFChar* pTC; - int32_t i, j; - CFX_RTFCharArray& chars = m_pCurLine->m_LineChars; + int32_t i; + int32_t j; + std::vector<CFX_RTFChar>& chars = m_pCurLine->m_LineChars; int32_t iCount = m_pCurLine->CountChars(); - bool bDone = (!m_bPagination && !m_bCharCode && - (m_pCurLine->m_iArabicChars > 0 || m_bRTL)); - if (bDone) { + if (!m_bPagination && m_pCurLine->m_iArabicChars > 0) { int32_t iBidiNum = 0; for (i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; pTC->m_iBidiPos = i; - if (pTC->GetCharType() != FX_CHARTYPE_Control) { + if (pTC->GetCharType() != FX_CHARTYPE_Control) iBidiNum = i; - } - if (i == 0) { + if (i == 0) pTC->m_iBidiLevel = 1; - } } - FX_BidiLine(chars, iBidiNum + 1, m_bRTL ? 1 : 0); + FX_BidiLine(chars, iBidiNum + 1, 0); } else { for (i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; pTC->m_iBidiLevel = 0; pTC->m_iBidiPos = 0; pTC->m_iBidiOrder = 0; } } - tp.m_dwStatus = FX_RTFBREAK_PieceBreak; + + tp.m_dwStatus = CFX_RTFBreakType::Piece; tp.m_iStartPos = m_pCurLine->m_iStart; tp.m_pChars = &chars; CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces; - int32_t iBidiLevel = -1, iCharWidth; - uint32_t dwIdentity = (uint32_t)-1; - i = j = 0; + int32_t iBidiLevel = -1; + int32_t iCharWidth; + uint32_t dwIdentity = static_cast<uint32_t>(-1); + i = 0; + j = 0; while (i < iCount) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; if (iBidiLevel < 0) { iBidiLevel = pTC->m_iBidiLevel; iCharWidth = pTC->m_iCharWidth; - if (iCharWidth < 1) { - tp.m_iWidth = 0; - } else { - tp.m_iWidth = iCharWidth; - } + tp.m_iWidth = iCharWidth < 1 ? 0 : iCharWidth; tp.m_iBidiLevel = iBidiLevel; tp.m_iBidiPos = pTC->m_iBidiOrder; tp.m_iFontSize = pTC->m_iFontSize; tp.m_iFontHeight = pTC->m_iFontHeight; tp.m_iHorizontalScale = pTC->m_iHorizontalScale; - tp.m_iVerticalScale = pTC->m_iVertialScale; + tp.m_iVerticalScale = pTC->m_iVerticalScale; dwIdentity = pTC->m_dwIdentity; tp.m_dwIdentity = dwIdentity; tp.m_pUserData = pTC->m_pUserData; - tp.m_dwStatus = FX_RTFBREAK_PieceBreak; + tp.m_dwStatus = CFX_RTFBreakType::Piece; i++; } else if (iBidiLevel != pTC->m_iBidiLevel || pTC->m_dwIdentity != dwIdentity) { @@ -812,118 +582,113 @@ void CFX_RTFBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { tp.m_iStartChar = i; tpo.index = j++; tpo.pos = tp.m_iBidiPos; - tpos.Add(tpo); + tpos->push_back(tpo); iBidiLevel = -1; } else { iCharWidth = pTC->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) tp.m_iWidth += iCharWidth; - } i++; } } + if (i > tp.m_iStartChar) { tp.m_dwStatus = dwStatus; tp.m_iChars = i - tp.m_iStartChar; pCurPieces->Add(tp); tpo.index = j; tpo.pos = tp.m_iBidiPos; - tpos.Add(tpo); + tpos->push_back(tpo); } - if (!m_bCharCode) { - j = tpos.GetSize() - 1; - FX_TEXTLAYOUT_PieceSort(tpos, 0, j); - int32_t iStartPos = m_pCurLine->m_iStart; - for (i = 0; i <= j; i++) { - tpo = tpos.GetAt(i); - CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index); - ttp.m_iStartPos = iStartPos; - iStartPos += ttp.m_iWidth; - } + + std::sort(tpos->begin(), tpos->end()); + int32_t iStartPos = m_pCurLine->m_iStart; + for (const auto& it : *tpos) { + CFX_RTFPiece& ttp = pCurPieces->GetAt(it.index); + ttp.m_iStartPos = iStartPos; + iStartPos += ttp.m_iWidth; } } -void CFX_RTFBreak::EndBreak_Alignment(CFX_TPOArray& tpos, + +void CFX_RTFBreak::EndBreak_Alignment(const std::deque<FX_TPO>& tpos, bool bAllChars, - uint32_t dwStatus) { + CFX_RTFBreakType dwStatus) { CFX_RTFPieceArray* pCurPieces = &m_pCurLine->m_LinePieces; - int32_t iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth; + int32_t iNetWidth = m_pCurLine->m_iWidth; + int32_t iGapChars = 0; + int32_t iCharWidth; int32_t iCount = pCurPieces->GetSize(); bool bFind = false; uint32_t dwCharType; - int32_t i, j; + int32_t i; + int32_t j; FX_TPO tpo; for (i = iCount - 1; i > -1; i--) { - tpo = tpos.GetAt(i); + tpo = tpos[i]; CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index); - if (!bFind) { + if (!bFind) iNetWidth = ttp.GetEndPos(); - } + bool bArabic = FX_IsOdd(ttp.m_iBidiLevel); j = bArabic ? 0 : ttp.m_iChars - 1; while (j > -1 && j < ttp.m_iChars) { const CFX_RTFChar& tc = ttp.GetChar(j); - if (tc.m_nBreakType == FX_LBT_DIRECT_BRK) { + if (tc.m_nBreakType == FX_LBT_DIRECT_BRK) iGapChars++; - } + if (!bFind || !bAllChars) { dwCharType = tc.GetCharType(); if (dwCharType == FX_CHARTYPE_Space || dwCharType == FX_CHARTYPE_Control) { if (!bFind) { iCharWidth = tc.m_iCharWidth; - if (bAllChars && iCharWidth > 0) { + if (bAllChars && iCharWidth > 0) iNetWidth -= iCharWidth; - } } } else { bFind = true; - if (!bAllChars) { + if (!bAllChars) break; - } } } j += bArabic ? 1 : -1; } - if (!bAllChars && bFind) { + if (!bAllChars && bFind) break; - } } + int32_t iOffset = m_iBoundaryEnd - iNetWidth; - int32_t iLowerAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_LowerMask); - int32_t iHigherAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_HigherMask); - if (iGapChars > 0 && (iHigherAlignment == FX_RTFLINEALIGNMENT_Distributed || - (iHigherAlignment == FX_RTFLINEALIGNMENT_Justified && - dwStatus != FX_RTFBREAK_ParagraphBreak))) { + if (iGapChars > 0 && (m_iAlignment == CFX_RTFLineAlignment::Distributed || + (m_iAlignment == CFX_RTFLineAlignment::Justified && + dwStatus != CFX_RTFBreakType::Paragraph))) { int32_t iStart = -1; for (i = 0; i < iCount; i++) { - tpo = tpos.GetAt(i); + tpo = tpos[i]; CFX_RTFPiece& ttp = pCurPieces->GetAt(tpo.index); - if (iStart < 0) { + if (iStart < 0) iStart = ttp.m_iStartPos; - } else { + else ttp.m_iStartPos = iStart; - } - int32_t k; + for (j = 0; j < ttp.m_iChars; j++) { CFX_RTFChar& tc = ttp.GetChar(j); - if (tc.m_nBreakType != FX_LBT_DIRECT_BRK || tc.m_iCharWidth < 0) { + if (tc.m_nBreakType != FX_LBT_DIRECT_BRK || tc.m_iCharWidth < 0) continue; - } - k = iOffset / iGapChars; + + int32_t k = iOffset / iGapChars; tc.m_iCharWidth += k; ttp.m_iWidth += k; iOffset -= k; iGapChars--; - if (iGapChars < 1) { + if (iGapChars < 1) break; - } } iStart += ttp.m_iWidth; } - } else if (iLowerAlignment > FX_RTFLINEALIGNMENT_Left) { - if (iLowerAlignment == FX_RTFLINEALIGNMENT_Center) { + } else if (m_iAlignment == CFX_RTFLineAlignment::Right || + m_iAlignment == CFX_RTFLineAlignment::Center) { + if (m_iAlignment == CFX_RTFLineAlignment::Center) iOffset /= 2; - } if (iOffset > 0) { for (i = 0; i < iCount; i++) { CFX_RTFPiece& ttp = pCurPieces->GetAt(i); @@ -933,101 +698,68 @@ void CFX_RTFBreak::EndBreak_Alignment(CFX_TPOArray& tpos, } } -int32_t CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray& tca, +int32_t CFX_RTFBreak::GetBreakPos(std::vector<CFX_RTFChar>& tca, int32_t& iEndPos, bool bAllChars, bool bOnlyBrk) { - int32_t iLength = tca.GetSize() - 1; + int32_t iLength = pdfium::CollectionSize<int32_t>(tca) - 1; if (iLength < 1) return iLength; - int32_t iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1, - iLast = -1, iLastPos = -1; - if (m_bSingleLine || m_bOrphanLine || iEndPos <= m_iBoundaryEnd) { - if (!bAllChars || m_bCharCode) + int32_t iBreak = -1; + int32_t iBreakPos = -1; + int32_t iIndirect = -1; + int32_t iIndirectPos = -1; + int32_t iLast = -1; + int32_t iLastPos = -1; + if (iEndPos <= m_iBoundaryEnd) { + if (!bAllChars) return iLength; iBreak = iLength; iBreakPos = iEndPos; } - CFX_RTFChar* pCharArray = tca.GetData(); - if (m_bCharCode) { - const CFX_RTFChar* pChar; - int32_t iCharWidth; - while (iLength > 0) { - if (iEndPos <= m_iBoundaryEnd) - break; - pChar = pCharArray + iLength--; - iCharWidth = pChar->m_iCharWidth; - if (iCharWidth > 0) - iEndPos -= iCharWidth; - } - return iLength; - } - bool bSpaceBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0; - bool bTabBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0; - bool bNumberBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_NumberBreak) != 0; - bool bInfixBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_InfixBreak) != 0; - FX_LINEBREAKTYPE eType; - uint32_t nCodeProp, nCur, nNext; - CFX_RTFChar* pCur = pCharArray + iLength--; - if (bAllChars) { + CFX_RTFChar* pCharArray = tca.data(); + CFX_RTFChar* pCur = pCharArray + iLength; + --iLength; + if (bAllChars) pCur->m_nBreakType = FX_LBT_UNKNOWN; - } - nCodeProp = pCur->m_dwCharProps; - nNext = nCodeProp & 0x003F; + + uint32_t nCodeProp = pCur->m_dwCharProps; + uint32_t nNext = nCodeProp & 0x003F; int32_t iCharWidth = pCur->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) iEndPos -= iCharWidth; - } + while (iLength >= 0) { pCur = pCharArray + iLength; nCodeProp = pCur->m_dwCharProps; - nCur = nCodeProp & 0x003F; + uint32_t nCur = nCodeProp & 0x003F; bool bNeedBreak = false; - if (nCur == FX_CBP_SP) { - bNeedBreak = !bSpaceBreak; - if (nNext == FX_CBP_SP) { - eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK; - } else { - eType = gs_FX_LineBreak_PairTable[nCur][nNext]; - } - } else if (nCur == FX_CBP_TB) { - bNeedBreak = !bTabBreak; - if (nNext == FX_CBP_TB) { - eType = bTabBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK; - } else { - eType = gs_FX_LineBreak_PairTable[nCur][nNext]; - } - } else if ((bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) || - (bInfixBreak && nCur == FX_CBP_IS && nNext == FX_CBP_IS)) { - eType = FX_LBT_DIRECT_BRK; + FX_LINEBREAKTYPE eType; + if (nCur == FX_CBP_TB) { + bNeedBreak = true; + eType = nNext == FX_CBP_TB ? FX_LBT_PROHIBITED_BRK + : gs_FX_LineBreak_PairTable[nCur][nNext]; } else { - if (nNext == FX_CBP_SP) { - eType = FX_LBT_PROHIBITED_BRK; - } else { - eType = gs_FX_LineBreak_PairTable[nCur][nNext]; - } + if (nCur == FX_CBP_SP) + bNeedBreak = true; + + eType = nNext == FX_CBP_SP ? FX_LBT_PROHIBITED_BRK + : gs_FX_LineBreak_PairTable[nCur][nNext]; } - if (bAllChars) { + if (bAllChars) pCur->m_nBreakType = eType; - } + if (!bOnlyBrk) { iCharWidth = pCur->m_iCharWidth; - bool bBreak = false; - if (nCur == FX_CBP_TB && bTabBreak) { - bBreak = iCharWidth > 0 && iEndPos - iCharWidth <= m_iBoundaryEnd; - } else { - bBreak = iEndPos <= m_iBoundaryEnd; - } - if (m_bSingleLine || m_bOrphanLine || bBreak || bNeedBreak) { + if (iEndPos <= m_iBoundaryEnd || bNeedBreak) { if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) { iBreak = iLength; iBreakPos = iEndPos; - if (!bAllChars) { + if (!bAllChars) return iLength; - } } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) { iIndirect = iLength; iIndirectPos = iEndPos; @@ -1037,9 +769,8 @@ int32_t CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray& tca, iLastPos = iEndPos; } } - if (iCharWidth > 0) { + if (iCharWidth > 0) iEndPos -= iCharWidth; - } } nNext = nCodeProp & 0x003F; iLength--; @@ -1067,123 +798,76 @@ void CFX_RTFBreak::SplitTextLine(CFX_RTFLine* pCurLine, bool bAllChars) { ASSERT(pCurLine && pNextLine); int32_t iCount = pCurLine->CountChars(); - if (iCount < 2) { + if (iCount < 2) return; - } + int32_t iEndPos = pCurLine->GetLineEnd(); - CFX_RTFCharArray& curChars = pCurLine->m_LineChars; + std::vector<CFX_RTFChar>& curChars = pCurLine->m_LineChars; int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, false); - if (iCharPos < 0) { + if (iCharPos < 0) iCharPos = 0; - } + iCharPos++; if (iCharPos >= iCount) { pNextLine->RemoveAll(true); - CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1); + CFX_Char* pTC = &curChars[iCharPos - 1]; pTC->m_nBreakType = FX_LBT_UNKNOWN; return; } - CFX_RTFCharArray& nextChars = pNextLine->m_LineChars; - int cur_size = curChars.GetSize(); - nextChars.SetSize(cur_size - iCharPos); - FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos), - (cur_size - iCharPos) * sizeof(CFX_RTFChar)); - iCount -= iCharPos; - cur_size = curChars.GetSize(); - curChars.RemoveAt(cur_size - iCount, iCount); + + pNextLine->m_LineChars = + std::vector<CFX_RTFChar>(curChars.begin() + iCharPos, curChars.end()); + curChars.erase(curChars.begin() + iCharPos, curChars.end()); pNextLine->m_iStart = pCurLine->m_iStart; pNextLine->m_iWidth = pCurLine->GetLineEnd() - iEndPos; pCurLine->m_iWidth = iEndPos; - curChars.GetDataPtr(iCharPos - 1)->m_nBreakType = FX_LBT_UNKNOWN; - iCount = nextChars.GetSize(); - CFX_RTFChar* pNextChars = nextChars.GetData(); - for (int32_t i = 0; i < iCount; i++) { - CFX_RTFChar* tc = pNextChars + i; - if (tc->GetCharType() >= FX_CHARTYPE_ArabicAlef) { + curChars[iCharPos - 1].m_nBreakType = FX_LBT_UNKNOWN; + + for (size_t i = 0; i < pNextLine->m_LineChars.size(); i++) { + if (pNextLine->m_LineChars[i].GetCharType() >= FX_CHARTYPE_ArabicAlef) { pCurLine->m_iArabicChars--; pNextLine->m_iArabicChars++; } - if (tc->m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) { - pCurLine->m_iMBCSChars--; - pNextLine->m_iMBCSChars++; - } - tc->m_dwStatus = 0; + pNextLine->m_LineChars[i].m_dwStatus = CFX_RTFBreakType::None; } } int32_t CFX_RTFBreak::CountBreakPieces() const { - CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(true); + const CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(); return pRTFPieces ? pRTFPieces->GetSize() : 0; } const CFX_RTFPiece* CFX_RTFBreak::GetBreakPiece(int32_t index) const { - CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(true); + const CFX_RTFPieceArray* pRTFPieces = GetRTFPieces(); if (!pRTFPieces) return nullptr; - if (index < 0 || index >= pRTFPieces->GetSize()) return nullptr; - return pRTFPieces->GetPtrAt(index); } -void CFX_RTFBreak::GetLineRect(CFX_RectF& rect) const { - rect.top = 0; - CFX_RTFLine* pRTFLine = GetRTFLine(true); - if (!pRTFLine) { - rect.left = ((FX_FLOAT)m_iBoundaryStart) / 20000.0f; - rect.width = rect.height = 0; - return; - } - rect.left = ((FX_FLOAT)pRTFLine->m_iStart) / 20000.0f; - rect.width = ((FX_FLOAT)pRTFLine->m_iWidth) / 20000.0f; - CFX_RTFPieceArray& rtfPieces = pRTFLine->m_LinePieces; - int32_t iCount = rtfPieces.GetSize(); - if (iCount < 1) { - rect.width = 0; - return; - } - CFX_RTFPiece* pBreakPiece; - int32_t iLineHeight = 0, iMax; - for (int32_t i = 0; i < iCount; i++) { - pBreakPiece = rtfPieces.GetPtrAt(i); - int32_t iFontHeight = FXSYS_round(pBreakPiece->m_iFontHeight * - pBreakPiece->m_iVerticalScale / 100.0f); - iMax = std::max(pBreakPiece->m_iFontSize, iFontHeight); - if (i == 0) { - iLineHeight = iMax; - } else if (iLineHeight < iMax) { - iLineHeight = iMax; - } - } - rect.height = ((FX_FLOAT)iLineHeight) / 20.0f; -} void CFX_RTFBreak::ClearBreakPieces() { - CFX_RTFLine* pRTFLine = GetRTFLine(true); - if (pRTFLine) { - pRTFLine->RemoveAll(true); - } + const CFX_RTFLine* pRTFLine = GetRTFLine(); + if (pRTFLine) + const_cast<CFX_RTFLine*>(pRTFLine)->RemoveAll(true); m_iReady = 0; } + void CFX_RTFBreak::Reset() { m_eCharType = FX_CHARTYPE_Unknown; m_RTFLine1.RemoveAll(true); m_RTFLine2.RemoveAll(true); } + int32_t CFX_RTFBreak::GetDisplayPos(const FX_RTFTEXTOBJ* pText, FXTEXT_CHARPOS* pCharPos, - bool bCharCode, - CFX_WideString* pWSForms, - FX_AdjustCharDisplayPos pAdjustPos) const { - if (!pText || pText->iLength < 1) { + bool bCharCode) const { + if (!pText || pText->iLength < 1) return 0; - } - ASSERT(pText->pStr && pText->pWidths && pText->pFont && pText->pRect); - const FX_WCHAR* pStr = pText->pStr; - int32_t* pWidths = pText->pWidths; - int32_t iLength = pText->iLength - 1; + + ASSERT(pText->pFont && pText->pRect); + CFX_RetainPtr<CFGAS_GEFont> pFont = pText->pFont; - uint32_t dwStyles = pText->dwLayoutStyles; CFX_RectF rtText(*pText->pRect); bool bRTLPiece = FX_IsOdd(pText->iBidiLevel); FX_FLOAT fFontSize = pText->fFontSize; @@ -1192,335 +876,119 @@ int32_t CFX_RTFBreak::GetDisplayPos(const FX_RTFTEXTOBJ* pText, int32_t iDescent = pFont->GetDescent(); int32_t iMaxHeight = iAscent - iDescent; FX_FLOAT fFontHeight = fFontSize; - FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight; - FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight; - bool bVerticalDoc = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0; - bool bVerticalChar = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0; - bool bArabicNumber = (dwStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) != 0; - bool bMBCSCode = (dwStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0; - int32_t iRotation = GetLineRotation(dwStyles) + pText->iCharRotation; - int32_t iCharRotation; - FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm; - int32_t iWidth, iCharWidth, iCharHeight; - FX_FLOAT fX, fY, fCharWidth, fCharHeight; + FX_FLOAT fAscent = fFontHeight * static_cast<FX_FLOAT>(iAscent) / + static_cast<FX_FLOAT>(iMaxHeight); + FX_WCHAR wch; + FX_WCHAR wPrev = 0xFEFF; + FX_WCHAR wNext; + FX_WCHAR wForm; + int32_t iWidth; + int32_t iCharWidth; + int32_t iCharHeight; + FX_FLOAT fX = rtText.left; + FX_FLOAT fY = rtText.top; + FX_FLOAT fCharWidth; + FX_FLOAT fCharHeight; int32_t iHorScale = pText->iHorizontalScale; int32_t iVerScale = pText->iVerticalScale; bool bEmptyChar; - uint32_t dwProps, dwCharType; - fX = rtText.left; - fY = rtText.top; - if (bVerticalDoc) { - fX += (rtText.width - fFontSize) / 2.0f; - if (bRTLPiece) { - fY = rtText.bottom(); - } - } else { - if (bRTLPiece) { - fX = rtText.right(); - } - fY += fAscent; - } + uint32_t dwProps; + uint32_t dwCharType; + + if (bRTLPiece) + fX = rtText.right(); + + fY += fAscent; int32_t iCount = 0; - for (int32_t i = 0; i <= iLength; i++) { - wch = *pStr++; - iWidth = *pWidths++; - if (!bMBCSCode) { - dwProps = FX_GetUnicodeProperties(wch); - dwCharType = (dwProps & FX_CHARTYPEBITSMASK); - if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) { + for (int32_t i = 0; i < pText->iLength; i++) { + wch = pText->pStr[i]; + iWidth = pText->pWidths[i]; + dwProps = FX_GetUnicodeProperties(wch); + dwCharType = (dwProps & FX_CHARTYPEBITSMASK); + if (iWidth == 0) { + if (dwCharType == FX_CHARTYPE_ArabicAlef) wPrev = 0xFEFF; - continue; - } - } else { - dwProps = 0; - dwCharType = 0; + continue; } - if (iWidth != 0) { - iCharWidth = iWidth; - if (iCharWidth < 0) { - iCharWidth = -iCharWidth; - } - if (!bMBCSCode) { - bEmptyChar = (dwCharType >= FX_CHARTYPE_Tab && - dwCharType <= FX_CHARTYPE_Control); - } else { - bEmptyChar = false; + + iCharWidth = FXSYS_abs(iWidth); + bEmptyChar = + (dwCharType >= FX_CHARTYPE_Tab && dwCharType <= FX_CHARTYPE_Control); + if (!bEmptyChar) + iCount++; + + if (pCharPos) { + iCharWidth /= iFontSize; + wForm = wch; + if (dwCharType >= FX_CHARTYPE_ArabicAlef) { + if (i + 1 < pText->iLength) { + wNext = pText->pStr[i + 1]; + if (pText->pWidths[i + 1] < 0 && i + 2 < pText->iLength) + wNext = pText->pStr[i + 2]; + } else { + wNext = 0xFEFF; + } + wForm = pdfium::arabic::GetFormChar(wch, wPrev, wNext); + } else if (bRTLPiece) { + wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, false); } + dwProps = FX_GetUnicodeProperties(wForm); + if (!bEmptyChar) { - iCount++; - } - if (pCharPos) { - iCharWidth /= iFontSize; - wForm = wch; - if (!bMBCSCode) { - if (dwCharType >= FX_CHARTYPE_ArabicAlef) { - if (i < iLength) { - wNext = *pStr; - if (*pWidths < 0) { - if (i + 1 < iLength) { - wNext = pStr[1]; - } - } - } else { - wNext = 0xFEFF; - } - wForm = pdfium::arabic::GetFormChar(wch, wPrev, wNext); - } else if (bRTLPiece || bVerticalChar) { - wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar); - } else if (dwCharType == FX_CHARTYPE_Numeric && bArabicNumber) { - wForm = wch + 0x0630; - } - dwProps = FX_GetUnicodeProperties(wForm); - } - iCharRotation = iRotation; - if (!bMBCSCode && bVerticalChar && (dwProps & 0x8000) != 0) { - iCharRotation++; - iCharRotation %= 4; + if (bCharCode) { + pCharPos->m_GlyphIndex = wch; + } else { + pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm, false); + if (pCharPos->m_GlyphIndex == 0xFFFF) + pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wch, false); } - if (!bEmptyChar) { - if (bCharCode) { - pCharPos->m_GlyphIndex = wch; - } else { - pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm, bMBCSCode); - if (pCharPos->m_GlyphIndex == 0xFFFF) { - pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wch, bMBCSCode); - } - } #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - pCharPos->m_ExtGID = pCharPos->m_GlyphIndex; + pCharPos->m_ExtGID = pCharPos->m_GlyphIndex; #endif - pCharPos->m_FontCharWidth = iCharWidth; - if (pWSForms) { - *pWSForms += wForm; - } - } - if (bVerticalDoc) { - iCharHeight = iCharWidth; - iCharWidth = 1000; - } else { - iCharHeight = 1000; - } - fCharWidth = fFontSize * iCharWidth / 1000.0f; - fCharHeight = fFontSize * iCharHeight / 1000.0f; - if (!bMBCSCode && bRTLPiece && dwCharType != FX_CHARTYPE_Combination) { - if (bVerticalDoc) { - fY -= fCharHeight; - } else { - fX -= fCharWidth; - } - } - if (!bEmptyChar) { - CFX_PointF ptOffset; - bool bAdjusted = false; - if (pAdjustPos) { - bAdjusted = pAdjustPos(wForm, bMBCSCode, pFont, fFontSize, - bVerticalChar, ptOffset); - } - if (!bAdjusted && bVerticalChar && (dwProps & 0x00010000) != 0) { - CFX_Rect rtBBox; - rtBBox.Reset(); - if (pFont->GetCharBBox(wForm, &rtBBox, bMBCSCode)) { - ptOffset.x = fFontSize * (850 - rtBBox.right()) / 1000.0f; - ptOffset.y = fFontSize * (1000 - rtBBox.height) / 2000.0f; - } - } - pCharPos->m_OriginX = fX + ptOffset.x; - pCharPos->m_OriginY = fY - ptOffset.y; - } - if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) { - if (bVerticalDoc) { - fY += fCharHeight; - } else { - fX += fCharWidth; - } - } - if (!bEmptyChar) { - pCharPos->m_bGlyphAdjust = true; - if (bVerticalDoc) { - if (iCharRotation == 0) { - pCharPos->m_AdjustMatrix[0] = -1; - pCharPos->m_AdjustMatrix[1] = 0; - pCharPos->m_AdjustMatrix[2] = 0; - pCharPos->m_AdjustMatrix[3] = 1; - pCharPos->m_OriginY += fAscent * iVerScale / 100.0f; - } else if (iCharRotation == 1) { - pCharPos->m_AdjustMatrix[0] = 0; - pCharPos->m_AdjustMatrix[1] = -1; - pCharPos->m_AdjustMatrix[2] = -1; - pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX -= - fDescent + fAscent * iVerScale / 100.0f - fAscent; - } else if (iCharRotation == 2) { - pCharPos->m_AdjustMatrix[0] = 1; - pCharPos->m_AdjustMatrix[1] = 0; - pCharPos->m_AdjustMatrix[2] = 0; - pCharPos->m_AdjustMatrix[3] = -1; - pCharPos->m_OriginX += fCharWidth; - pCharPos->m_OriginY += fAscent; - } else { - pCharPos->m_AdjustMatrix[0] = 0; - pCharPos->m_AdjustMatrix[1] = 1; - pCharPos->m_AdjustMatrix[2] = 1; - pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX += fAscent; - pCharPos->m_OriginY += fCharWidth; - } - } else { - if (iCharRotation == 0) { - pCharPos->m_AdjustMatrix[0] = -1; - pCharPos->m_AdjustMatrix[1] = 0; - pCharPos->m_AdjustMatrix[2] = 0; - pCharPos->m_AdjustMatrix[3] = 1; - pCharPos->m_OriginY += fAscent * iVerScale / 100.0f - fAscent; - } else if (iCharRotation == 1) { - pCharPos->m_AdjustMatrix[0] = 0; - pCharPos->m_AdjustMatrix[1] = -1; - pCharPos->m_AdjustMatrix[2] = -1; - pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX -= fDescent; - pCharPos->m_OriginY -= fAscent + fDescent; - } else if (iCharRotation == 2) { - pCharPos->m_AdjustMatrix[0] = 1; - pCharPos->m_AdjustMatrix[1] = 0; - pCharPos->m_AdjustMatrix[2] = 0; - pCharPos->m_AdjustMatrix[3] = -1; - pCharPos->m_OriginX += fCharWidth; - pCharPos->m_OriginY -= fAscent; - } else { - pCharPos->m_AdjustMatrix[0] = 0; - pCharPos->m_AdjustMatrix[1] = 1; - pCharPos->m_AdjustMatrix[2] = 1; - pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX += fAscent * iVerScale / 100.0f; - } - } - if (iHorScale != 100 || iVerScale != 100) { - pCharPos->m_AdjustMatrix[0] = - pCharPos->m_AdjustMatrix[0] * iHorScale / 100.0f; - pCharPos->m_AdjustMatrix[1] = - pCharPos->m_AdjustMatrix[1] * iHorScale / 100.0f; - pCharPos->m_AdjustMatrix[2] = - pCharPos->m_AdjustMatrix[2] * iVerScale / 100.0f; - pCharPos->m_AdjustMatrix[3] = - pCharPos->m_AdjustMatrix[3] * iVerScale / 100.0f; - } - pCharPos++; - } + pCharPos->m_FontCharWidth = iCharWidth; } - } - if (iWidth > 0) { - wPrev = wch; - } - } - return iCount; -} -int32_t CFX_RTFBreak::GetCharRects(const FX_RTFTEXTOBJ* pText, - CFX_RectFArray& rtArray, - bool bCharBBox) const { - if (!pText || pText->iLength < 1) - return 0; + iCharHeight = 1000; - ASSERT(pText->pStr && pText->pWidths && pText->pFont && pText->pRect); - const FX_WCHAR* pStr = pText->pStr; - int32_t* pWidths = pText->pWidths; - int32_t iLength = pText->iLength; - CFX_RectF rect(*pText->pRect); - bool bRTLPiece = FX_IsOdd(pText->iBidiLevel); - FX_FLOAT fFontSize = pText->fFontSize; - int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); - FX_FLOAT fScale = fFontSize / 1000.0f; - CFX_RetainPtr<CFGAS_GEFont> pFont = pText->pFont; - if (!pFont) - bCharBBox = false; - - CFX_Rect bbox; - bbox.Set(0, 0, 0, 0); - if (bCharBBox) - bCharBBox = pFont->GetBBox(&bbox); - - FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale); - FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale); - rtArray.RemoveAll(); - rtArray.SetSize(iLength); - uint32_t dwStyles = pText->dwLayoutStyles; - bool bVertical = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0; - bool bSingleLine = (dwStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0; - bool bCombText = (dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0; - FX_WCHAR wch, wLineBreakChar = pText->wLineBreakChar; - int32_t iCharSize; - FX_FLOAT fCharSize, fStart; - if (bVertical) { - fStart = bRTLPiece ? rect.bottom() : rect.top; - } else { - fStart = bRTLPiece ? rect.right() : rect.left; - } - for (int32_t i = 0; i < iLength; i++) { - wch = *pStr++; - iCharSize = *pWidths++; - fCharSize = (FX_FLOAT)iCharSize / 20000.0f; - bool bRet = (!bSingleLine && FX_IsCtrlCode(wch)); - if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 || - (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) { - bRet = false; - } - if (bRet) { - iCharSize = iFontSize * 500; - fCharSize = fFontSize / 2.0f; - } - if (bVertical) { - rect.top = fStart; - if (bRTLPiece) { - rect.top -= fCharSize; - fStart -= fCharSize; - } else { - fStart += fCharSize; - } - rect.height = fCharSize; - } else { - rect.left = fStart; - if (bRTLPiece) { - rect.left -= fCharSize; - fStart -= fCharSize; - } else { - fStart += fCharSize; - } - rect.width = fCharSize; - } - if (bCharBBox && !bRet) { - int32_t iCharWidth = 1000; - pFont->GetCharWidth(wch, iCharWidth, false); - FX_FLOAT fRTLeft = 0, fCharWidth = 0; - if (iCharWidth > 0) { - fCharWidth = iCharWidth * fScale; - fRTLeft = fLeft; - if (bCombText) { - fRTLeft = (rect.width - fCharWidth) / 2.0f; + fCharWidth = fFontSize * iCharWidth / 1000.0f; + fCharHeight = fFontSize * iCharHeight / 1000.0f; + if (bRTLPiece && dwCharType != FX_CHARTYPE_Combination) + fX -= fCharWidth; + + if (!bEmptyChar) + pCharPos->m_Origin = CFX_PointF(fX, fY); + if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) + fX += fCharWidth; + + if (!bEmptyChar) { + pCharPos->m_bGlyphAdjust = true; + pCharPos->m_AdjustMatrix[0] = -1; + pCharPos->m_AdjustMatrix[1] = 0; + pCharPos->m_AdjustMatrix[2] = 0; + pCharPos->m_AdjustMatrix[3] = 1; + pCharPos->m_Origin.y += fAscent * iVerScale / 100.0f; + pCharPos->m_Origin.y -= fAscent; + + if (iHorScale != 100 || iVerScale != 100) { + pCharPos->m_AdjustMatrix[0] = + pCharPos->m_AdjustMatrix[0] * iHorScale / 100.0f; + pCharPos->m_AdjustMatrix[1] = + pCharPos->m_AdjustMatrix[1] * iHorScale / 100.0f; + pCharPos->m_AdjustMatrix[2] = + pCharPos->m_AdjustMatrix[2] * iVerScale / 100.0f; + pCharPos->m_AdjustMatrix[3] = + pCharPos->m_AdjustMatrix[3] * iVerScale / 100.0f; } + pCharPos++; } - CFX_RectF rtBBoxF; - if (bVertical) { - rtBBoxF.top = rect.left + fRTLeft; - rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f; - rtBBoxF.height = fCharWidth; - rtBBoxF.width = fHeight; - rtBBoxF.left = std::max(rtBBoxF.left, 0.0f); - } else { - rtBBoxF.left = rect.left + fRTLeft; - rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f; - rtBBoxF.width = fCharWidth; - rtBBoxF.height = fHeight; - rtBBoxF.top = std::max(rtBBoxF.top, 0.0f); - } - rtArray.SetAt(i, rtBBoxF); - continue; } - rtArray.SetAt(i, rect); + if (iWidth > 0) + wPrev = wch; } - return iLength; + return iCount; } CFX_RTFPiece::CFX_RTFPiece() - : m_dwStatus(FX_RTFBREAK_PieceBreak), + : m_dwStatus(CFX_RTFBreakType::Piece), m_iStartPos(0), m_iWidth(-1), m_iStartChar(0), @@ -1531,7 +999,6 @@ CFX_RTFPiece::CFX_RTFPiece() m_iFontHeight(0), m_iHorizontalScale(100), m_iVerticalScale(100), - m_dwLayoutStyles(0), m_dwIdentity(0), m_pChars(nullptr), m_pUserData(nullptr) {} @@ -1548,20 +1015,16 @@ CFX_RTFLine::CFX_RTFLine() m_iMBCSChars(0) {} CFX_RTFLine::~CFX_RTFLine() { - RemoveAll(); + RemoveAll(false); } FX_RTFTEXTOBJ::FX_RTFTEXTOBJ() - : pStr(nullptr), - pWidths(nullptr), - iLength(0), - pFont(nullptr), - fFontSize(12.0f), - dwLayoutStyles(0), - iCharRotation(0), - iBidiLevel(0), + : pFont(nullptr), pRect(nullptr), wLineBreakChar(L'\n'), + fFontSize(12.0f), + iLength(0), + iBidiLevel(0), iHorizontalScale(100), iVerticalScale(100) {} diff --git a/xfa/fgas/layout/fgas_rtfbreak.h b/xfa/fgas/layout/fgas_rtfbreak.h index 6edd86035..4d999ec68 100644 --- a/xfa/fgas/layout/fgas_rtfbreak.h +++ b/xfa/fgas/layout/fgas_rtfbreak.h @@ -7,77 +7,40 @@ #ifndef XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_ #define XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_ +#include <deque> #include <vector> +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_ucd.h" #include "xfa/fgas/crt/fgas_utils.h" #include "xfa/fgas/layout/fgas_textbreak.h" -#include "xfa/fgas/layout/fgas_unicode.h" class CFGAS_GEFont; -#define FX_RTFBREAKPOLICY_None 0x00 -#define FX_RTFBREAKPOLICY_SpaceBreak 0x01 -#define FX_RTFBREAKPOLICY_NumberBreak 0x02 -#define FX_RTFBREAKPOLICY_InfixBreak 0x04 -#define FX_RTFBREAKPOLICY_TabBreak 0x08 -#define FX_RTFBREAKPOLICY_OrphanPositionedTab 0x10 -#define FX_RTFBREAK_None 0x00 -#define FX_RTFBREAK_PieceBreak 0x01 -#define FX_RTFBREAK_LineBreak 0x02 -#define FX_RTFBREAK_ParagraphBreak 0x03 -#define FX_RTFBREAK_PageBreak 0x04 #define FX_RTFLAYOUTSTYLE_Pagination 0x01 -#define FX_RTFLAYOUTSTYLE_VerticalLayout 0x02 -#define FX_RTFLAYOUTSTYLE_VerticalChars 0x04 -#define FX_RTFLAYOUTSTYLE_LineDirection 0x08 #define FX_RTFLAYOUTSTYLE_ExpandTab 0x10 -#define FX_RTFLAYOUTSTYLE_ArabicNumber 0x20 -#define FX_RTFLAYOUTSTYLE_SingleLine 0x40 -#define FX_RTFLAYOUTSTYLE_MBCSCode 0x80 -#define FX_RTFCHARSTYLE_Alignment 0x000F -#define FX_RTFCHARSTYLE_ArabicNumber 0x0010 -#define FX_RTFCHARSTYLE_ArabicShadda 0x0020 -#define FX_RTFCHARSTYLE_OddBidiLevel 0x0040 -#define FX_RTFCHARSTYLE_RTLReadingOrder 0x0080 -#define FX_RTFCHARSTYLE_ArabicContext 0x0300 -#define FX_RTFCHARSTYLE_ArabicIndic 0x0400 -#define FX_RTFCHARSTYLE_ArabicComma 0x0800 -#define FX_RTFLINEALIGNMENT_Left 0 -#define FX_RTFLINEALIGNMENT_Center 1 -#define FX_RTFLINEALIGNMENT_Right 2 -#define FX_RTFLINEALIGNMENT_Justified (1 << 2) -#define FX_RTFLINEALIGNMENT_Distributed (2 << 2) -#define FX_RTFLINEALIGNMENT_JustifiedLeft \ - (FX_RTFLINEALIGNMENT_Left | FX_RTFLINEALIGNMENT_Justified) -#define FX_RTFLINEALIGNMENT_JustifiedCenter \ - (FX_RTFLINEALIGNMENT_Center | FX_RTFLINEALIGNMENT_Justified) -#define FX_RTFLINEALIGNMENT_JustifiedRight \ - (FX_RTFLINEALIGNMENT_Right | FX_RTFLINEALIGNMENT_Justified) -#define FX_RTFLINEALIGNMENT_DistributedLeft \ - (FX_RTFLINEALIGNMENT_Left | FX_RTFLINEALIGNMENT_Distributed) -#define FX_RTFLINEALIGNMENT_DistributedCenter \ - (FX_RTFLINEALIGNMENT_Center | FX_RTFLINEALIGNMENT_Distributed) -#define FX_RTFLINEALIGNMENT_DistributedRight \ - (FX_RTFLINEALIGNMENT_Right | FX_RTFLINEALIGNMENT_Distributed) -#define FX_RTFLINEALIGNMENT_LowerMask 0x03 -#define FX_RTFLINEALIGNMENT_HigherMask 0x0C + +enum class CFX_RTFLineAlignment { + Left = 0, + Center, + Right, + Justified, + Distributed +}; struct FX_RTFTEXTOBJ { FX_RTFTEXTOBJ(); ~FX_RTFTEXTOBJ(); - const FX_WCHAR* pStr; - int32_t* pWidths; - int32_t iLength; + CFX_WideString pStr; + std::vector<int32_t> pWidths; CFX_RetainPtr<CFGAS_GEFont> pFont; - FX_FLOAT fFontSize; - uint32_t dwLayoutStyles; - int32_t iCharRotation; - int32_t iBidiLevel; const CFX_RectF* pRect; FX_WCHAR wLineBreakChar; + FX_FLOAT fFontSize; + int32_t iLength; + int32_t iBidiLevel; int32_t iHorizontalScale; int32_t iVerticalScale; }; @@ -87,57 +50,36 @@ class CFX_RTFPiece { CFX_RTFPiece(); ~CFX_RTFPiece(); - void AppendChar(const CFX_RTFChar& tc) { - ASSERT(m_pChars); - m_pChars->Add(tc); - if (m_iWidth < 0) { - m_iWidth = tc.m_iCharWidth; - } else { - m_iWidth += tc.m_iCharWidth; - } - m_iChars++; - } int32_t GetEndPos() const { return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth; } - int32_t GetLength() const { return m_iChars; } - int32_t GetEndChar() const { return m_iStartChar + m_iChars; } + CFX_RTFChar& GetChar(int32_t index) { ASSERT(index > -1 && index < m_iChars && m_pChars); - return *m_pChars->GetDataPtr(m_iStartChar + index); - } - CFX_RTFChar* GetCharPtr(int32_t index) const { - ASSERT(index > -1 && index < m_iChars && m_pChars); - return m_pChars->GetDataPtr(m_iStartChar + index); + return (*m_pChars)[m_iStartChar + index]; } - void GetString(FX_WCHAR* pText) const { - ASSERT(pText); - int32_t iEndChar = m_iStartChar + m_iChars; - CFX_RTFChar* pChar; - for (int32_t i = m_iStartChar; i < iEndChar; i++) { - pChar = m_pChars->GetDataPtr(i); - *pText++ = (FX_WCHAR)pChar->m_wCharCode; - } - } - void GetString(CFX_WideString& wsText) const { - FX_WCHAR* pText = wsText.GetBuffer(m_iChars); - GetString(pText); - wsText.ReleaseBuffer(m_iChars); + + CFX_WideString GetString() const { + CFX_WideString ret; + ret.Reserve(m_iChars); + for (int32_t i = m_iStartChar; i < m_iStartChar + m_iChars; i++) + ret += static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode); + return ret; } - void GetWidths(int32_t* pWidths) const { - ASSERT(pWidths); - int32_t iEndChar = m_iStartChar + m_iChars; - CFX_RTFChar* pChar; - for (int32_t i = m_iStartChar; i < iEndChar; i++) { - pChar = m_pChars->GetDataPtr(i); - *pWidths++ = pChar->m_iCharWidth; - } + + std::vector<int32_t> GetWidths() const { + std::vector<int32_t> ret; + ret.reserve(m_iChars); + for (int32_t i = m_iStartChar; i < m_iStartChar + m_iChars; i++) + ret.push_back((*m_pChars)[i].m_iCharWidth); + return ret; } + void Reset() { - m_dwStatus = FX_RTFBREAK_PieceBreak; - if (m_iWidth > -1) { + m_dwStatus = CFX_RTFBreakType::Piece; + if (m_iWidth > -1) m_iStartPos += m_iWidth; - } + m_iWidth = -1; m_iStartChar += m_iChars; m_iChars = 0; @@ -147,7 +89,7 @@ class CFX_RTFPiece { m_iVerticalScale = 100; } - uint32_t m_dwStatus; + CFX_RTFBreakType m_dwStatus; int32_t m_iStartPos; int32_t m_iWidth; int32_t m_iStartChar; @@ -158,10 +100,9 @@ class CFX_RTFPiece { int32_t m_iFontHeight; int32_t m_iHorizontalScale; int32_t m_iVerticalScale; - uint32_t m_dwLayoutStyles; uint32_t m_dwIdentity; - CFX_RTFCharArray* m_pChars; - IFX_Retainable* m_pUserData; + std::vector<CFX_RTFChar>* m_pChars; // not owned. + CFX_RetainPtr<CFX_Retainable> m_pUserData; }; typedef CFX_BaseArrayTemplate<CFX_RTFPiece> CFX_RTFPieceArray; @@ -171,41 +112,25 @@ class CFX_RTFLine { CFX_RTFLine(); ~CFX_RTFLine(); - int32_t CountChars() const { return m_LineChars.GetSize(); } - CFX_RTFChar& GetChar(int32_t index) { - ASSERT(index > -1 && index < m_LineChars.GetSize()); - return *m_LineChars.GetDataPtr(index); - } - CFX_RTFChar* GetCharPtr(int32_t index) { - ASSERT(index > -1 && index < m_LineChars.GetSize()); - return m_LineChars.GetDataPtr(index); + int32_t CountChars() const { + return pdfium::CollectionSize<int32_t>(m_LineChars); } - int32_t CountPieces() const { return m_LinePieces.GetSize(); } - CFX_RTFPiece& GetPiece(int32_t index) const { - ASSERT(index > -1 && index < m_LinePieces.GetSize()); - return m_LinePieces.GetAt(index); - } - CFX_RTFPiece* GetPiecePtr(int32_t index) const { - ASSERT(index > -1 && index < m_LinePieces.GetSize()); - return m_LinePieces.GetPtrAt(index); + + CFX_RTFChar& GetChar(int32_t index) { + ASSERT(index >= 0 && index < pdfium::CollectionSize<int32_t>(m_LineChars)); + return m_LineChars[index]; } + int32_t GetLineEnd() const { return m_iStart + m_iWidth; } - void RemoveAll(bool bLeaveMemory = false) { - CFX_RTFChar* pChar; - int32_t iCount = m_LineChars.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - pChar = m_LineChars.GetDataPtr(i); - if (pChar->m_pUserData) - pChar->m_pUserData->Release(); - } - m_LineChars.RemoveAll(); + void RemoveAll(bool bLeaveMemory) { + m_LineChars.clear(); m_LinePieces.RemoveAll(bLeaveMemory); m_iWidth = 0; m_iArabicChars = 0; m_iMBCSChars = 0; } - CFX_RTFCharArray m_LineChars; + std::vector<CFX_RTFChar> m_LineChars; CFX_RTFPieceArray m_LinePieces; int32_t m_iStart; int32_t m_iWidth; @@ -215,105 +140,83 @@ class CFX_RTFLine { class CFX_RTFBreak { public: - explicit CFX_RTFBreak(uint32_t dwPolicies); + explicit CFX_RTFBreak(uint32_t dwLayoutStyles); ~CFX_RTFBreak(); void SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd); void SetLineStartPos(FX_FLOAT fLinePos); - uint32_t GetLayoutStyles() const { return m_dwLayoutStyles; } - void SetLayoutStyles(uint32_t dwLayoutStyles); void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont); void SetFontSize(FX_FLOAT fFontSize); void SetTabWidth(FX_FLOAT fTabWidth); - void AddPositionedTab(FX_FLOAT fTabPos); - void SetPositionedTabs(const std::vector<FX_FLOAT>& tabs); - void ClearPositionedTabs(); - void SetDefaultChar(FX_WCHAR wch); - void SetLineBreakChar(FX_WCHAR wch); void SetLineBreakTolerance(FX_FLOAT fTolerance); void SetHorizontalScale(int32_t iScale); void SetVerticalScale(int32_t iScale); - void SetCharRotation(int32_t iCharRotation); void SetCharSpace(FX_FLOAT fCharSpace); - void SetWordSpace(bool bDefault, FX_FLOAT fWordSpace); - void SetReadingOrder(bool bRTL = false); - void SetAlignment(int32_t iAlignment = FX_RTFLINEALIGNMENT_Left); - void SetUserData(IFX_Retainable* pUserData); - uint32_t AppendChar(FX_WCHAR wch); - uint32_t EndBreak(uint32_t dwStatus = FX_RTFBREAK_PieceBreak); + void SetAlignment(CFX_RTFLineAlignment align) { m_iAlignment = align; } + void SetUserData(const CFX_RetainPtr<CFX_Retainable>& pUserData); + + void AddPositionedTab(FX_FLOAT fTabPos); + + CFX_RTFBreakType EndBreak(CFX_RTFBreakType dwStatus); int32_t CountBreakPieces() const; const CFX_RTFPiece* GetBreakPiece(int32_t index) const; - void GetLineRect(CFX_RectF& rect) const; void ClearBreakPieces(); + void Reset(); + int32_t GetDisplayPos(const FX_RTFTEXTOBJ* pText, FXTEXT_CHARPOS* pCharPos, - bool bCharCode = false, - CFX_WideString* pWSForms = nullptr, - FX_AdjustCharDisplayPos pAdjustPos = nullptr) const; - int32_t GetCharRects(const FX_RTFTEXTOBJ* pText, - CFX_RectFArray& rtArray, - bool bCharBBox = false) const; - uint32_t AppendChar_CharCode(FX_WCHAR wch); - uint32_t AppendChar_Combination(CFX_RTFChar* pCurChar, int32_t iRotation); - uint32_t AppendChar_Tab(CFX_RTFChar* pCurChar, int32_t iRotation); - uint32_t AppendChar_Control(CFX_RTFChar* pCurChar, int32_t iRotation); - uint32_t AppendChar_Arabic(CFX_RTFChar* pCurChar, int32_t iRotation); - uint32_t AppendChar_Others(CFX_RTFChar* pCurChar, int32_t iRotation); - - protected: - int32_t GetLineRotation(uint32_t dwStyles) const; + bool bCharCode) const; + + CFX_RTFBreakType AppendChar(FX_WCHAR wch); + CFX_RTFBreakType AppendChar_Combination(CFX_RTFChar* pCurChar); + CFX_RTFBreakType AppendChar_Tab(CFX_RTFChar* pCurChar); + CFX_RTFBreakType AppendChar_Control(CFX_RTFChar* pCurChar); + CFX_RTFBreakType AppendChar_Arabic(CFX_RTFChar* pCurChar); + CFX_RTFBreakType AppendChar_Others(CFX_RTFChar* pCurChar); + + private: + void FontChanged(); void SetBreakStatus(); CFX_RTFChar* GetLastChar(int32_t index) const; - CFX_RTFLine* GetRTFLine(bool bReady) const; - CFX_RTFPieceArray* GetRTFPieces(bool bReady) const; + const CFX_RTFLine* GetRTFLine() const; + const CFX_RTFPieceArray* GetRTFPieces() const; FX_CHARTYPE GetUnifiedCharType(FX_CHARTYPE chartype) const; int32_t GetLastPositionedTab() const; - bool GetPositionedTab(int32_t& iTabPos) const; + bool GetPositionedTab(int32_t* iTabPos) const; - int32_t GetBreakPos(CFX_RTFCharArray& tca, + int32_t GetBreakPos(std::vector<CFX_RTFChar>& tca, int32_t& iEndPos, - bool bAllChars = false, - bool bOnlyBrk = false); + bool bAllChars, + bool bOnlyBrk); void SplitTextLine(CFX_RTFLine* pCurLine, CFX_RTFLine* pNextLine, - bool bAllChars = false); + bool bAllChars); bool EndBreak_SplitLine(CFX_RTFLine* pNextLine, bool bAllChars, - uint32_t dwStatus); - void EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus); - void EndBreak_Alignment(CFX_TPOArray& tpos, + CFX_RTFBreakType dwStatus); + void EndBreak_BidiLine(std::deque<FX_TPO>* tpos, CFX_RTFBreakType dwStatus); + void EndBreak_Alignment(const std::deque<FX_TPO>& tpos, bool bAllChars, - uint32_t dwStatus); + CFX_RTFBreakType dwStatus); - uint32_t m_dwPolicies; int32_t m_iBoundaryStart; int32_t m_iBoundaryEnd; uint32_t m_dwLayoutStyles; bool m_bPagination; - bool m_bVertical; - bool m_bSingleLine; - bool m_bCharCode; CFX_RetainPtr<CFGAS_GEFont> m_pFont; int32_t m_iFontHeight; int32_t m_iFontSize; int32_t m_iTabWidth; - CFX_Int32Array m_PositionedTabs; - bool m_bOrphanLine; + std::vector<int32_t> m_PositionedTabs; FX_WCHAR m_wDefChar; int32_t m_iDefChar; FX_WCHAR m_wLineBreakChar; int32_t m_iHorizontalScale; int32_t m_iVerticalScale; - int32_t m_iLineRotation; - int32_t m_iCharRotation; - int32_t m_iRotation; int32_t m_iCharSpace; - bool m_bWordSpace; - int32_t m_iWordSpace; - bool m_bRTL; - int32_t m_iAlignment; - IFX_Retainable* m_pUserData; + CFX_RTFLineAlignment m_iAlignment; + CFX_RetainPtr<CFX_Retainable> m_pUserData; FX_CHARTYPE m_eCharType; uint32_t m_dwIdentity; CFX_RTFLine m_RTFLine1; diff --git a/xfa/fgas/layout/fgas_textbreak.cpp b/xfa/fgas/layout/fgas_textbreak.cpp index 35984f501..8be72f2c7 100644 --- a/xfa/fgas/layout/fgas_textbreak.cpp +++ b/xfa/fgas/layout/fgas_textbreak.cpp @@ -14,7 +14,6 @@ #include "third_party/base/ptr_util.h" #include "xfa/fgas/font/cfgas_gefont.h" #include "xfa/fgas/layout/fgas_linebreak.h" -#include "xfa/fgas/layout/fgas_unicode.h" namespace { @@ -67,7 +66,6 @@ CFX_TxtBreak::CFX_TxtBreak(uint32_t dwPolicies) m_iReady(0), m_iTolerance(0), m_iHorScale(100), - m_iVerScale(100), m_iCharSpace(0) { m_bPagination = (m_dwPolicies & FX_TXTBREAKPOLICY_Pagination) != 0; int32_t iSize = m_bPagination ? sizeof(CFX_Char) : sizeof(CFX_TxtChar); @@ -87,13 +85,8 @@ void CFX_TxtBreak::SetLineWidth(FX_FLOAT fLineWidth) { } void CFX_TxtBreak::SetLinePos(FX_FLOAT fLinePos) { - int32_t iLinePos = FXSYS_round(fLinePos * 20000.0f); - if (iLinePos < 0) { - iLinePos = 0; - } - if (iLinePos > m_iLineWidth) { - iLinePos = m_iLineWidth; - } + int32_t iLinePos = + std::min(std::max(FXSYS_round(fLinePos * 20000.0f), 0), m_iLineWidth); m_pCurLine->m_iStart = iLinePos; m_pCurLine->m_iWidth += iLinePos; } @@ -118,52 +111,52 @@ void CFX_TxtBreak::SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont) { SetBreakStatus(); m_pFont = pFont; - m_iDefChar = 0; - if (m_wDefChar != 0xFEFF && m_pFont) { - m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); - m_iDefChar *= m_iFontSize; - } + FontChanged(); } void CFX_TxtBreak::SetFontSize(FX_FLOAT fFontSize) { int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); - if (m_iFontSize == iFontSize) { + if (m_iFontSize == iFontSize) return; - } + SetBreakStatus(); m_iFontSize = iFontSize; + FontChanged(); +} + +void CFX_TxtBreak::FontChanged() { m_iDefChar = 0; - if (m_wDefChar != 0xFEFF && m_pFont) { - m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); - m_iDefChar *= m_iFontSize; - } + if (m_wDefChar == 0xFEFF || !m_pFont) + return; + + m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); + m_iDefChar *= m_iFontSize; } void CFX_TxtBreak::SetTabWidth(FX_FLOAT fTabWidth, bool bEquidistant) { m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f); - if (m_iTabWidth < FX_TXTBREAK_MinimumTabWidth) { + if (m_iTabWidth < FX_TXTBREAK_MinimumTabWidth) m_iTabWidth = FX_TXTBREAK_MinimumTabWidth; - } + m_bEquidistant = bEquidistant; } void CFX_TxtBreak::SetDefaultChar(FX_WCHAR wch) { m_wDefChar = wch; m_iDefChar = 0; - if (m_wDefChar != 0xFEFF && m_pFont) { - m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); - if (m_iDefChar < 0) { - m_iDefChar = 0; - } else { - m_iDefChar *= m_iFontSize; - } - } + if (m_wDefChar == 0xFEFF || !m_pFont) + return; + + m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, false); + if (m_iDefChar < 0) + m_iDefChar = 0; + else + m_iDefChar *= m_iFontSize; } void CFX_TxtBreak::SetParagraphBreakChar(FX_WCHAR wch) { - if (wch != L'\r' && wch != L'\n') { + if (wch != L'\r' && wch != L'\n') return; - } m_wParagBreakChar = wch; } @@ -172,14 +165,14 @@ void CFX_TxtBreak::SetLineBreakTolerance(FX_FLOAT fTolerance) { } void CFX_TxtBreak::SetCharRotation(int32_t iCharRotation) { - if (iCharRotation < 0) { + if (iCharRotation < 0) iCharRotation += (-iCharRotation / 4 + 1) * 4; - } else if (iCharRotation > 3) { + else if (iCharRotation > 3) iCharRotation -= (iCharRotation / 4) * 4; - } - if (m_iCharRotation == iCharRotation) { + + if (m_iCharRotation == iCharRotation) return; - } + SetBreakStatus(); m_iCharRotation = iCharRotation; m_iRotation = m_iLineRotation + m_iCharRotation; @@ -195,77 +188,48 @@ void CFX_TxtBreak::SetAlignment(int32_t iAlignment) { void CFX_TxtBreak::ResetContextCharStyles() { m_dwContextCharStyles = m_bArabicContext ? m_iCurAlignment : m_iAlignment; - if (m_bArabicNumber) { + if (m_bArabicNumber) m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicNumber; - } - if (m_bArabicComma) { + if (m_bArabicComma) m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicComma; - } - if ((m_bArabicContext && m_bCurRTL) || (!m_bArabicContext && m_bRTL)) { + if ((m_bArabicContext && m_bCurRTL) || (!m_bArabicContext && m_bRTL)) m_dwContextCharStyles |= FX_TXTCHARSTYLE_RTLReadingOrder; - } m_dwContextCharStyles |= (m_iArabicContext << 8); } -uint32_t CFX_TxtBreak::GetContextCharStyles() const { - return m_dwContextCharStyles; -} - -void CFX_TxtBreak::SetContextCharStyles(uint32_t dwCharStyles) { - m_iCurAlignment = dwCharStyles & 0x0F; - m_bArabicNumber = (dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0; - m_bArabicComma = (dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0; - m_bCurRTL = (dwCharStyles & FX_TXTCHARSTYLE_RTLReadingOrder) != 0; - m_iCurArabicContext = m_iArabicContext = ((dwCharStyles & 0x0300) >> 8); - ResetContextCharStyles(); -} - void CFX_TxtBreak::SetCombWidth(FX_FLOAT fCombWidth) { m_iCombWidth = FXSYS_round(fCombWidth * 20000.0f); } void CFX_TxtBreak::SetUserData(void* pUserData) { - if (m_pUserData == pUserData) { + if (m_pUserData == pUserData) return; - } + SetBreakStatus(); m_pUserData = pUserData; } void CFX_TxtBreak::SetBreakStatus() { - if (m_bPagination) { + if (m_bPagination) return; - } + int32_t iCount = m_pCurLine->CountChars(); - if (iCount < 1) { + if (iCount < 1) return; - } + CFX_TxtChar* pTC = m_pCurLine->GetCharPtr(iCount - 1); - if (pTC->m_dwStatus == 0) { + if (pTC->m_dwStatus == 0) pTC->m_dwStatus = FX_TXTBREAK_PieceBreak; - } } void CFX_TxtBreak::SetHorizontalScale(int32_t iScale) { - if (iScale < 0) { + if (iScale < 0) iScale = 0; - } - if (iScale == m_iHorScale) { + if (iScale == m_iHorScale) return; - } - SetBreakStatus(); - m_iHorScale = iScale; -} -void CFX_TxtBreak::SetVerticalScale(int32_t iScale) { - if (iScale < 0) { - iScale = 0; - } - if (iScale == m_iHorScale) { - return; - } SetBreakStatus(); - m_iVerScale = iScale; + m_iHorScale = iScale; } void CFX_TxtBreak::SetCharSpace(FX_FLOAT fCharSpace) { @@ -273,33 +237,29 @@ void CFX_TxtBreak::SetCharSpace(FX_FLOAT fCharSpace) { } static const int32_t gs_FX_TxtLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2}; + int32_t CFX_TxtBreak::GetLineRotation(uint32_t dwStyles) const { return gs_FX_TxtLineRotations[(dwStyles & 0x0E) >> 1]; } CFX_TxtChar* CFX_TxtBreak::GetLastChar(int32_t index, bool bOmitChar) const { - CFX_TxtCharArray& ca = *m_pCurLine->m_pLineChars.get(); - int32_t iCount = ca.GetSize(); - if (index < 0 || index >= iCount) { + std::vector<CFX_TxtChar>& ca = *m_pCurLine->m_pLineChars.get(); + int32_t iCount = pdfium::CollectionSize<int32_t>(ca); + if (index < 0 || index >= iCount) return nullptr; - } - CFX_TxtChar* pTC; + int32_t iStart = iCount - 1; while (iStart > -1) { - pTC = ca.GetDataPtr(iStart--); - if (bOmitChar && pTC->GetCharType() == FX_CHARTYPE_Combination) { + CFX_TxtChar* pTC = &ca[iStart--]; + if (bOmitChar && pTC->GetCharType() == FX_CHARTYPE_Combination) continue; - } - if (--index < 0) { + if (--index < 0) return pTC; - } } return nullptr; } -CFX_TxtLine* CFX_TxtBreak::GetTxtLine(bool bReady) const { - if (!bReady) - return m_pCurLine; +CFX_TxtLine* CFX_TxtBreak::GetTxtLine() const { if (m_iReady == 1) return m_pTxtLine1.get(); if (m_iReady == 2) @@ -307,12 +267,9 @@ CFX_TxtLine* CFX_TxtBreak::GetTxtLine(bool bReady) const { return nullptr; } -CFX_TxtPieceArray* CFX_TxtBreak::GetTxtPieces(bool bReady) const { - CFX_TxtLine* pTxtLine = GetTxtLine(bReady); - if (!pTxtLine) { - return nullptr; - } - return pTxtLine->m_pLinePieces.get(); +CFX_TxtPieceArray* CFX_TxtBreak::GetTxtPieces() const { + CFX_TxtLine* pTxtLine = GetTxtLine(); + return pTxtLine ? pTxtLine->m_pLinePieces.get() : nullptr; } inline FX_CHARTYPE CFX_TxtBreak::GetUnifiedCharType( @@ -335,11 +292,10 @@ void CFX_TxtBreak::ResetArabicContext() { m_bCurRTL = m_bRTL; m_iCurAlignment = m_iAlignment; } - if (m_bRTL) { + if (m_bRTL) m_bArabicNumber = m_iArabicContext >= 1; - } else { + else m_bArabicNumber = m_iArabicContext > 1; - } m_bArabicNumber = m_bArabicNumber && m_bArabicShapes; } m_bArabicComma = m_bArabicNumber; @@ -361,15 +317,14 @@ void CFX_TxtBreak::AppendChar_PageLoad(CFX_TxtChar* pCurChar, : 1); if (iArabicContext != m_iArabicContext && iArabicContext != 1) { m_iArabicContext = iArabicContext; - if (m_iCurArabicContext == 1) { + if (m_iCurArabicContext == 1) m_iCurArabicContext = iArabicContext; - } + ResetArabicContext(); if (!m_bPagination) { CFX_TxtChar* pLastChar = GetLastChar(1, false); - if (pLastChar && pLastChar->m_dwStatus < 1) { + if (pLastChar && pLastChar->m_dwStatus < 1) pLastChar->m_dwStatus = FX_TXTBREAK_PieceBreak; - } } } } @@ -413,9 +368,8 @@ uint32_t CFX_TxtBreak::AppendChar_Combination(CFX_TxtChar* pCurChar, } } } - if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) { + if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) iCharWidth = 0; - } } iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorScale / 100; @@ -427,9 +381,9 @@ uint32_t CFX_TxtBreak::AppendChar_Combination(CFX_TxtChar* pCurChar, uint32_t CFX_TxtBreak::AppendChar_Tab(CFX_TxtChar* pCurChar, int32_t iRotation) { m_eCharType = FX_CHARTYPE_Tab; - if ((m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ExpandTab) == 0) { + if ((m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ExpandTab) == 0) return FX_TXTBREAK_None; - } + int32_t& iLineWidth = m_pCurLine->m_iWidth; int32_t iCharWidth; if (m_bCombText) { @@ -438,18 +392,18 @@ uint32_t CFX_TxtBreak::AppendChar_Tab(CFX_TxtChar* pCurChar, if (m_bEquidistant) { iCharWidth = iLineWidth; iCharWidth = m_iTabWidth * (iCharWidth / m_iTabWidth + 1) - iCharWidth; - if (iCharWidth < FX_TXTBREAK_MinimumTabWidth) { + if (iCharWidth < FX_TXTBREAK_MinimumTabWidth) iCharWidth += m_iTabWidth; - } } else { iCharWidth = m_iTabWidth; } } + pCurChar->m_iCharWidth = iCharWidth; iLineWidth += iCharWidth; - if (!m_bSingleLine && iLineWidth >= m_iLineWidth + m_iTolerance) { + if (!m_bSingleLine && iLineWidth >= m_iLineWidth + m_iTolerance) return EndBreak(FX_TXTBREAK_LineBreak); - } + return FX_TXTBREAK_None; } @@ -471,14 +425,12 @@ uint32_t CFX_TxtBreak::AppendChar_Control(CFX_TxtChar* pCurChar, dwRet = FX_TXTBREAK_ParagraphBreak; break; default: - if (wch == m_wParagBreakChar) { + if (wch == m_wParagBreakChar) dwRet = FX_TXTBREAK_ParagraphBreak; - } break; } - if (dwRet != FX_TXTBREAK_None) { + if (dwRet != FX_TXTBREAK_None) dwRet = EndBreak(dwRet); - } } return dwRet; } @@ -489,32 +441,31 @@ uint32_t CFX_TxtBreak::AppendChar_Arabic(CFX_TxtChar* pCurChar, int32_t& iLineWidth = m_pCurLine->m_iWidth; FX_WCHAR wForm; int32_t iCharWidth = 0; - CFX_Char* pLastChar = nullptr; + CFX_TxtChar* pLastChar = nullptr; bool bAlef = false; if (!m_bCombText && m_eCharType >= FX_CHARTYPE_ArabicAlef && m_eCharType <= FX_CHARTYPE_ArabicDistortion) { pLastChar = GetLastChar(1); if (pLastChar) { iCharWidth = pLastChar->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) iLineWidth -= iCharWidth; - } + CFX_Char* pPrevChar = GetLastChar(2); wForm = pdfium::arabic::GetFormChar(pLastChar, pPrevChar, pCurChar); bAlef = (wForm == 0xFEFF && pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef); int32_t iLastRotation = pLastChar->m_nRotation + m_iLineRotation; - if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) { + if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) iLastRotation++; - } - if (m_bVertical != FX_IsOdd(iLastRotation)) { + if (m_bVertical != FX_IsOdd(iLastRotation)) iCharWidth = 1000; - } else { + else m_pFont->GetCharWidth(wForm, iCharWidth, false); - } - if (wForm == 0xFEFF) { + + if (wForm == 0xFEFF) iCharWidth = m_iDefChar; - } + iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorScale / 100; pLastChar->m_iCharWidth = iCharWidth; @@ -522,29 +473,29 @@ uint32_t CFX_TxtBreak::AppendChar_Arabic(CFX_TxtChar* pCurChar, iCharWidth = 0; } } + m_eCharType = chartype; wForm = pdfium::arabic::GetFormChar(pCurChar, bAlef ? nullptr : pLastChar, nullptr); if (m_bCombText) { iCharWidth = m_iCombWidth; } else { - if (m_bVertical != FX_IsOdd(iRotation)) { + if (m_bVertical != FX_IsOdd(iRotation)) iCharWidth = 1000; - } else { + else m_pFont->GetCharWidth(wForm, iCharWidth, false); - } - if (wForm == 0xFEFF) { + + if (wForm == 0xFEFF) iCharWidth = m_iDefChar; - } + iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorScale / 100; } pCurChar->m_iCharWidth = iCharWidth; iLineWidth += iCharWidth; m_pCurLine->m_iArabicChars++; - if (!m_bSingleLine && iLineWidth > m_iLineWidth + m_iTolerance) { + if (!m_bSingleLine && iLineWidth > m_iLineWidth + m_iTolerance) return EndBreak(FX_TXTBREAK_LineBreak); - } return FX_TXTBREAK_None; } @@ -570,39 +521,43 @@ uint32_t CFX_TxtBreak::AppendChar_Others(CFX_TxtChar* pCurChar, } else if (m_bCurRTL || m_bVertical) { wForm = FX_GetMirrorChar(wch, dwProps, m_bCurRTL, m_bVertical); } + if (m_bCombText) { iCharWidth = m_iCombWidth; } else { - if (m_bVertical != FX_IsOdd(iRotation)) { + if (m_bVertical != FX_IsOdd(iRotation)) iCharWidth = 1000; - } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) { + else if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) iCharWidth = m_iDefChar; - } + iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorScale / 100; } + iCharWidth += m_iCharSpace; pCurChar->m_iCharWidth = iCharWidth; iLineWidth += iCharWidth; bool bBreak = (chartype != FX_CHARTYPE_Space || (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0); - if (!m_bSingleLine && bBreak && iLineWidth > m_iLineWidth + m_iTolerance) { + if (!m_bSingleLine && bBreak && iLineWidth > m_iLineWidth + m_iTolerance) return EndBreak(FX_TXTBREAK_LineBreak); - } + return FX_TXTBREAK_None; } uint32_t CFX_TxtBreak::AppendChar(FX_WCHAR wch) { - uint32_t dwProps = kTextLayoutCodeProperties[(uint16_t)wch]; + uint32_t dwProps = kTextLayoutCodeProperties[static_cast<uint16_t>(wch)]; FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps); - CFX_TxtChar* pCurChar = m_pCurLine->m_pLineChars->AddSpace(); - pCurChar->m_wCharCode = (uint16_t)wch; + m_pCurLine->m_pLineChars->emplace_back(); + + CFX_TxtChar* pCurChar = &m_pCurLine->m_pLineChars->back(); + pCurChar->m_wCharCode = static_cast<uint16_t>(wch); pCurChar->m_nRotation = m_iCharRotation; pCurChar->m_dwCharProps = dwProps; pCurChar->m_dwCharStyles = 0; pCurChar->m_iCharWidth = 0; pCurChar->m_iHorizontalScale = m_iHorScale; - pCurChar->m_iVertialScale = m_iVerScale; + pCurChar->m_iVerticalScale = 100; pCurChar->m_dwStatus = 0; pCurChar->m_iBidiClass = 0; pCurChar->m_iBidiLevel = 0; @@ -612,22 +567,20 @@ uint32_t CFX_TxtBreak::AppendChar(FX_WCHAR wch) { AppendChar_PageLoad(pCurChar, dwProps); uint32_t dwRet1 = FX_TXTBREAK_None; if (chartype != FX_CHARTYPE_Combination && - GetUnifiedCharType(m_eCharType) != GetUnifiedCharType(chartype)) { - if (m_eCharType != FX_CHARTYPE_Unknown && - m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance && !m_bSingleLine) { - if (m_eCharType != FX_CHARTYPE_Space || chartype != FX_CHARTYPE_Control) { - dwRet1 = EndBreak(FX_TXTBREAK_LineBreak); - int32_t iCount = m_pCurLine->CountChars(); - if (iCount > 0) { - pCurChar = m_pCurLine->m_pLineChars->GetDataPtr(iCount - 1); - } - } - } + GetUnifiedCharType(m_eCharType) != GetUnifiedCharType(chartype) && + m_eCharType != FX_CHARTYPE_Unknown && + m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance && !m_bSingleLine && + (m_eCharType != FX_CHARTYPE_Space || chartype != FX_CHARTYPE_Control)) { + dwRet1 = EndBreak(FX_TXTBREAK_LineBreak); + int32_t iCount = m_pCurLine->CountChars(); + if (iCount > 0) + pCurChar = &(*m_pCurLine->m_pLineChars)[iCount - 1]; } + int32_t iRotation = m_iRotation; - if (m_bVertical && (dwProps & 0x8000) != 0) { + if (m_bVertical && (dwProps & 0x8000) != 0) iRotation = (iRotation + 1) % 4; - } + uint32_t dwRet2 = (this->*g_FX_TxtBreak_lpfAppendChar[chartype >> FX_CHARTYPEBITS])( pCurChar, iRotation); @@ -637,11 +590,11 @@ uint32_t CFX_TxtBreak::AppendChar(FX_WCHAR wch) { void CFX_TxtBreak::EndBreak_UpdateArabicShapes() { ASSERT(m_bArabicShapes); int32_t iCount = m_pCurLine->CountChars(); - if (iCount < 2) { + if (iCount < 2) return; - } + int32_t& iLineWidth = m_pCurLine->m_iWidth; - CFX_Char* pCur = m_pCurLine->GetCharPtr(0); + CFX_TxtChar* pCur = m_pCurLine->GetCharPtr(0); bool bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0; pCur = m_pCurLine->GetCharPtr(1); FX_WCHAR wch, wForm; @@ -649,7 +602,7 @@ void CFX_TxtBreak::EndBreak_UpdateArabicShapes() { int32_t i = 1; int32_t iCharWidth; int32_t iRotation; - CFX_Char* pNext; + CFX_TxtChar* pNext; do { i++; if (i < iCount) { @@ -659,23 +612,24 @@ void CFX_TxtBreak::EndBreak_UpdateArabicShapes() { pNext = nullptr; bNextNum = false; } + wch = pCur->m_wCharCode; if (wch == L'.') { if (bPrevNum && bNextNum) { iRotation = m_iRotation; - if (m_bVertical && (pCur->m_dwCharProps & 0x8000) != 0) { + if (m_bVertical && (pCur->m_dwCharProps & 0x8000) != 0) iRotation = ((iRotation + 1) & 0x03); - } + wForm = wch == L'.' ? 0x066B : 0x066C; iLineWidth -= pCur->m_iCharWidth; if (m_bCombText) { iCharWidth = m_iCombWidth; } else { - if (m_bVertical != FX_IsOdd(iRotation)) { + if (m_bVertical != FX_IsOdd(iRotation)) iCharWidth = 1000; - } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) { + else if (!m_pFont->GetCharWidth(wForm, iCharWidth, false)) iCharWidth = m_iDefChar; - } + iCharWidth *= m_iFontSize; iCharWidth = iCharWidth * m_iHorScale / 100; } @@ -693,7 +647,7 @@ bool CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine* pNextLine, uint32_t dwStatus) { int32_t iCount = m_pCurLine->CountChars(); bool bDone = false; - CFX_Char* pTC; + CFX_TxtChar* pTC; if (!m_bSingleLine && m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance) { pTC = m_pCurLine->GetCharPtr(iCount - 1); switch (pTC->GetCharType()) { @@ -712,6 +666,7 @@ bool CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine* pNextLine, break; } } + iCount = m_pCurLine->CountChars(); CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces.get(); CFX_TxtPiece tp; @@ -726,7 +681,7 @@ bool CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine* pNextLine, pTC = m_pCurLine->GetCharPtr(0); tp.m_dwCharStyles = pTC->m_dwCharStyles; tp.m_iHorizontalScale = pTC->m_iHorizontalScale; - tp.m_iVerticalScale = pTC->m_iVertialScale; + tp.m_iVerticalScale = pTC->m_iVerticalScale; pCurPieces->Add(tp); m_pCurLine = pNextLine; m_eCharType = FX_CHARTYPE_Unknown; @@ -739,38 +694,41 @@ bool CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine* pNextLine, return false; } -void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { +void CFX_TxtBreak::EndBreak_BidiLine(std::deque<FX_TPO>* tpos, + uint32_t dwStatus) { CFX_TxtPiece tp; FX_TPO tpo; CFX_TxtChar* pTC; - int32_t i, j; - CFX_TxtCharArray& chars = *m_pCurLine->m_pLineChars.get(); + int32_t i; + int32_t j; + std::vector<CFX_TxtChar>& chars = *m_pCurLine->m_pLineChars.get(); int32_t iCount = m_pCurLine->CountChars(); bool bDone = (m_pCurLine->m_iArabicChars > 0 || m_bCurRTL); if (!m_bPagination && bDone) { int32_t iBidiNum = 0; for (i = 0; i < iCount; i++) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; pTC->m_iBidiPos = i; - if (pTC->GetCharType() != FX_CHARTYPE_Control) { + if (pTC->GetCharType() != FX_CHARTYPE_Control) iBidiNum = i; - } - if (i == 0) { + if (i == 0) pTC->m_iBidiLevel = 1; - } } FX_BidiLine(chars, iBidiNum + 1, m_bCurRTL ? 1 : 0); } + CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces.get(); if (!m_bPagination && (bDone || (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_MutipleFormat) != 0)) { tp.m_dwStatus = FX_TXTBREAK_PieceBreak; tp.m_iStartPos = m_pCurLine->m_iStart; tp.m_pChars = m_pCurLine->m_pLineChars.get(); - int32_t iBidiLevel = -1, iCharWidth; - i = 0, j = -1; + int32_t iBidiLevel = -1; + int32_t iCharWidth; + i = 0; + j = -1; while (i < iCount) { - pTC = chars.GetDataPtr(i); + pTC = &chars[i]; if (iBidiLevel < 0) { iBidiLevel = pTC->m_iBidiLevel; tp.m_iWidth = 0; @@ -779,16 +737,16 @@ void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { tp.m_dwCharStyles = pTC->m_dwCharStyles; tp.m_pUserData = pTC->m_pUserData; tp.m_iHorizontalScale = pTC->m_iHorizontalScale; - tp.m_iVerticalScale = pTC->m_iVertialScale; + tp.m_iVerticalScale = pTC->m_iVerticalScale; tp.m_dwStatus = FX_TXTBREAK_PieceBreak; } if (iBidiLevel != pTC->m_iBidiLevel || pTC->m_dwStatus != 0) { if (iBidiLevel == pTC->m_iBidiLevel) { tp.m_dwStatus = pTC->m_dwStatus; iCharWidth = pTC->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) tp.m_iWidth += iCharWidth; - } + i++; } tp.m_iChars = i - tp.m_iStartChar; @@ -797,13 +755,13 @@ void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { tp.m_iStartChar = i; tpo.index = ++j; tpo.pos = tp.m_iBidiPos; - tpos.Add(tpo); + tpos->push_back(tpo); iBidiLevel = -1; } else { iCharWidth = pTC->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) tp.m_iWidth += iCharWidth; - } + i++; } } @@ -813,14 +771,14 @@ void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { pCurPieces->Add(tp); tpo.index = ++j; tpo.pos = tp.m_iBidiPos; - tpos.Add(tpo); + tpos->push_back(tpo); } if (j > -1) { if (j > 0) { - FX_TEXTLAYOUT_PieceSort(tpos, 0, j); + std::sort(tpos->begin(), tpos->end()); int32_t iStartPos = 0; for (i = 0; i <= j; i++) { - tpo = tpos.GetAt(i); + tpo = (*tpos)[i]; CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index); ttp.m_iStartPos = iStartPos; iStartPos += ttp.m_iWidth; @@ -837,62 +795,61 @@ void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus) { tp.m_iChars = iCount; tp.m_pChars = m_pCurLine->m_pLineChars.get(); tp.m_pUserData = m_pUserData; - pTC = chars.GetDataPtr(0); + pTC = &chars[0]; tp.m_dwCharStyles = pTC->m_dwCharStyles; tp.m_iHorizontalScale = pTC->m_iHorizontalScale; - tp.m_iVerticalScale = pTC->m_iVertialScale; + tp.m_iVerticalScale = pTC->m_iVerticalScale; pCurPieces->Add(tp); - tpo.index = 0; - tpo.pos = 0; - tpos.Add(tpo); + tpos->push_back({0, 0}); } } -void CFX_TxtBreak::EndBreak_Alignment(CFX_TPOArray& tpos, +void CFX_TxtBreak::EndBreak_Alignment(const std::deque<FX_TPO>& tpos, bool bAllChars, uint32_t dwStatus) { - int32_t iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth; + int32_t iNetWidth = m_pCurLine->m_iWidth; + int32_t iGapChars = 0; + int32_t iCharWidth; CFX_TxtPieceArray* pCurPieces = m_pCurLine->m_pLinePieces.get(); - int32_t i, j, iCount = pCurPieces->GetSize(); + int32_t i; + int32_t j; + int32_t iCount = pCurPieces->GetSize(); bool bFind = false; FX_TPO tpo; CFX_TxtChar* pTC; FX_CHARTYPE chartype; for (i = iCount - 1; i > -1; i--) { - tpo = tpos.GetAt(i); + tpo = tpos[i]; CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index); - if (!bFind) { + if (!bFind) iNetWidth = ttp.GetEndPos(); - } + bool bArabic = FX_IsOdd(ttp.m_iBidiLevel); j = bArabic ? 0 : ttp.m_iChars - 1; while (j > -1 && j < ttp.m_iChars) { pTC = ttp.GetCharPtr(j); - if (pTC->m_nBreakType == FX_LBT_DIRECT_BRK) { + if (pTC->m_nBreakType == FX_LBT_DIRECT_BRK) iGapChars++; - } if (!bFind || !bAllChars) { chartype = pTC->GetCharType(); if (chartype == FX_CHARTYPE_Space || chartype == FX_CHARTYPE_Control) { if (!bFind) { iCharWidth = pTC->m_iCharWidth; - if (bAllChars && iCharWidth > 0) { + if (bAllChars && iCharWidth > 0) iNetWidth -= iCharWidth; - } } } else { bFind = true; - if (!bAllChars) { + if (!bAllChars) break; - } } } j += bArabic ? 1 : -1; } - if (!bAllChars && bFind) { + if (!bAllChars && bFind) break; - } } + int32_t iOffset = m_iLineWidth - iNetWidth; int32_t iLowerAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_LowerMask); int32_t iHigherAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_HigherMask); @@ -901,34 +858,31 @@ void CFX_TxtBreak::EndBreak_Alignment(CFX_TPOArray& tpos, dwStatus != FX_TXTBREAK_ParagraphBreak))) { int32_t iStart = -1; for (i = 0; i < iCount; i++) { - tpo = tpos.GetAt(i); + tpo = tpos[i]; CFX_TxtPiece& ttp = pCurPieces->GetAt(tpo.index); - if (iStart < -1) { + if (iStart < -1) iStart = ttp.m_iStartPos; - } else { + else ttp.m_iStartPos = iStart; - } - int32_t k; + for (j = 0; j < ttp.m_iChars; j++) { pTC = ttp.GetCharPtr(j); - if (pTC->m_nBreakType != FX_LBT_DIRECT_BRK || pTC->m_iCharWidth < 0) { + if (pTC->m_nBreakType != FX_LBT_DIRECT_BRK || pTC->m_iCharWidth < 0) continue; - } - k = iOffset / iGapChars; + + int32_t k = iOffset / iGapChars; pTC->m_iCharWidth += k; ttp.m_iWidth += k; iOffset -= k; iGapChars--; - if (iGapChars < 1) { + if (iGapChars < 1) break; - } } iStart += ttp.m_iWidth; } } else if (iLowerAlignment > FX_TXTLINEALIGNMENT_Left) { - if (iLowerAlignment == FX_TXTLINEALIGNMENT_Center) { + if (iLowerAlignment == FX_TXTLINEALIGNMENT_Center) iOffset /= 2; - } if (iOffset > 0) { for (i = 0; i < iCount; i++) { CFX_TxtPiece& ttp = pCurPieces->GetAt(i); @@ -945,59 +899,54 @@ uint32_t CFX_TxtBreak::EndBreak(uint32_t dwStatus) { int32_t iCount = pCurPieces->GetSize(); if (iCount > 0) { CFX_TxtPiece* pLastPiece = pCurPieces->GetPtrAt(--iCount); - if (dwStatus > FX_TXTBREAK_PieceBreak) { + if (dwStatus > FX_TXTBREAK_PieceBreak) pLastPiece->m_dwStatus = dwStatus; - } else { + else dwStatus = pLastPiece->m_dwStatus; - } return dwStatus; } else { - CFX_TxtLine* pLastLine = GetTxtLine(true); + CFX_TxtLine* pLastLine = GetTxtLine(); if (pLastLine) { pCurPieces = pLastLine->m_pLinePieces.get(); iCount = pCurPieces->GetSize(); if (iCount-- > 0) { CFX_TxtPiece* pLastPiece = pCurPieces->GetPtrAt(iCount); - if (dwStatus > FX_TXTBREAK_PieceBreak) { + if (dwStatus > FX_TXTBREAK_PieceBreak) pLastPiece->m_dwStatus = dwStatus; - } else { + else dwStatus = pLastPiece->m_dwStatus; - } return dwStatus; } return FX_TXTBREAK_None; } + iCount = m_pCurLine->CountChars(); - if (iCount < 1) { + if (iCount < 1) return FX_TXTBREAK_None; - } if (!m_bPagination) { CFX_TxtChar* pTC = m_pCurLine->GetCharPtr(iCount - 1); pTC->m_dwStatus = dwStatus; } - if (dwStatus <= FX_TXTBREAK_PieceBreak) { + if (dwStatus <= FX_TXTBREAK_PieceBreak) return dwStatus; - } } + m_iReady = (m_pCurLine == m_pTxtLine1.get()) ? 1 : 2; CFX_TxtLine* pNextLine = (m_pCurLine == m_pTxtLine1.get()) ? m_pTxtLine2.get() : m_pTxtLine1.get(); bool bAllChars = (m_iCurAlignment > FX_TXTLINEALIGNMENT_Right); - CFX_TPOArray tpos(100); - CFX_Char* pTC; - if (m_bArabicShapes) { + if (m_bArabicShapes) EndBreak_UpdateArabicShapes(); + + if (!EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) { + std::deque<FX_TPO> tpos; + EndBreak_BidiLine(&tpos, dwStatus); + if (!m_bPagination && m_iCurAlignment > FX_TXTLINEALIGNMENT_Left) + EndBreak_Alignment(tpos, bAllChars, dwStatus); } - if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) { - goto EndBreak_Ret; - } - EndBreak_BidiLine(tpos, dwStatus); - if (!m_bPagination && m_iCurAlignment > FX_TXTLINEALIGNMENT_Left) { - EndBreak_Alignment(tpos, bAllChars, dwStatus); - } -EndBreak_Ret: + m_pCurLine = pNextLine; - pTC = GetLastChar(0, false); + CFX_Char* pTC = GetLastChar(0, false); m_eCharType = pTC ? pTC->GetCharType() : FX_CHARTYPE_Unknown; if (dwStatus == FX_TXTBREAK_ParagraphBreak) { m_iArabicContext = m_iCurArabicContext = 1; @@ -1006,68 +955,71 @@ EndBreak_Ret: return dwStatus; } -int32_t CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray& ca, +int32_t CFX_TxtBreak::GetBreakPos(std::vector<CFX_TxtChar>& ca, int32_t& iEndPos, bool bAllChars, bool bOnlyBrk) { - int32_t iLength = ca.GetSize() - 1; - if (iLength < 1) { + int32_t iLength = pdfium::CollectionSize<int32_t>(ca) - 1; + if (iLength < 1) return iLength; - } - int32_t iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1, - iLast = -1, iLastPos = -1; + + int32_t iBreak = -1; + int32_t iBreakPos = -1; + int32_t iIndirect = -1; + int32_t iIndirectPos = -1; + int32_t iLast = -1; + int32_t iLastPos = -1; if (m_bSingleLine || iEndPos <= m_iLineWidth) { - if (!bAllChars) { + if (!bAllChars) return iLength; - } + iBreak = iLength; iBreakPos = iEndPos; } + bool bSpaceBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0; bool bNumberBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_NumberBreak) != 0; FX_LINEBREAKTYPE eType; - uint32_t nCodeProp, nCur, nNext; - CFX_Char* pCur = ca.GetDataPtr(iLength--); - if (bAllChars) { + uint32_t nCodeProp; + uint32_t nCur; + uint32_t nNext; + CFX_Char* pCur = &ca[iLength--]; + if (bAllChars) pCur->m_nBreakType = FX_LBT_UNKNOWN; - } + nCodeProp = pCur->m_dwCharProps; nNext = nCodeProp & 0x003F; int32_t iCharWidth = pCur->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) iEndPos -= iCharWidth; - } + while (iLength >= 0) { - pCur = ca.GetDataPtr(iLength); + pCur = &ca[iLength]; nCodeProp = pCur->m_dwCharProps; nCur = nCodeProp & 0x003F; if (nCur == FX_CBP_SP) { - if (nNext == FX_CBP_SP) { + if (nNext == FX_CBP_SP) eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK; - } else { + else eType = gs_FX_LineBreak_PairTable[nCur][nNext]; - } } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) { eType = FX_LBT_DIRECT_BRK; } else { - if (nNext == FX_CBP_SP) { + if (nNext == FX_CBP_SP) eType = FX_LBT_PROHIBITED_BRK; - } else { + else eType = gs_FX_LineBreak_PairTable[nCur][nNext]; - } - } - if (bAllChars) { - pCur->m_nBreakType = (uint8_t)eType; } + if (bAllChars) + pCur->m_nBreakType = static_cast<uint8_t>(eType); if (!bOnlyBrk) { if (m_bSingleLine || iEndPos <= m_iLineWidth || (nCur == FX_CBP_SP && !bSpaceBreak)) { if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) { iBreak = iLength; iBreakPos = iEndPos; - if (!bAllChars) { + if (!bAllChars) return iLength; - } } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) { iIndirect = iLength; iIndirectPos = iEndPos; @@ -1078,16 +1030,14 @@ int32_t CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray& ca, } } iCharWidth = pCur->m_iCharWidth; - if (iCharWidth > 0) { + if (iCharWidth > 0) iEndPos -= iCharWidth; - } } nNext = nCodeProp & 0x003F; iLength--; } - if (bOnlyBrk) { + if (bOnlyBrk) return 0; - } if (iBreak > -1) { iEndPos = iBreakPos; return iBreak; @@ -1108,85 +1058,75 @@ void CFX_TxtBreak::SplitTextLine(CFX_TxtLine* pCurLine, bool bAllChars) { ASSERT(pCurLine && pNextLine); int32_t iCount = pCurLine->CountChars(); - if (iCount < 2) { + if (iCount < 2) return; - } + int32_t iEndPos = pCurLine->m_iWidth; - CFX_TxtCharArray& curChars = *pCurLine->m_pLineChars.get(); + std::vector<CFX_TxtChar>& curChars = *pCurLine->m_pLineChars; int32_t iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, false); - if (iCharPos < 0) { + if (iCharPos < 0) iCharPos = 0; - } + iCharPos++; if (iCharPos >= iCount) { pNextLine->RemoveAll(true); - CFX_Char* pTC = curChars.GetDataPtr(iCharPos - 1); + CFX_Char* pTC = &curChars[iCharPos - 1]; pTC->m_nBreakType = FX_LBT_UNKNOWN; return; } - CFX_TxtCharArray& nextChars = *pNextLine->m_pLineChars.get(); - int cur_size = curChars.GetSize(); - nextChars.SetSize(cur_size - iCharPos); - FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos), - (cur_size - iCharPos) * sizeof(CFX_TxtChar)); - iCount -= iCharPos; - cur_size = curChars.GetSize(); - curChars.RemoveAt(cur_size - iCount, iCount); + + // m_pLineChars is a unique_ptr<vector>. Assign the ref into nextChars + // so we can change the m_pLineChars vector ... + std::vector<CFX_TxtChar>& nextChars = *pNextLine->m_pLineChars; + nextChars = + std::vector<CFX_TxtChar>(curChars.begin() + iCharPos, curChars.end()); + curChars.erase(curChars.begin() + iCharPos, curChars.end()); pCurLine->m_iWidth = iEndPos; - CFX_TxtChar* pTC = curChars.GetDataPtr(iCharPos - 1); + CFX_TxtChar* pTC = &curChars[iCharPos - 1]; pTC->m_nBreakType = FX_LBT_UNKNOWN; - iCount = nextChars.GetSize(); - int32_t iCharWidth, iWidth = 0; + iCount = pdfium::CollectionSize<int>(nextChars); + int32_t iWidth = 0; for (int32_t i = 0; i < iCount; i++) { - pTC = nextChars.GetDataPtr(i); - if (pTC->GetCharType() >= FX_CHARTYPE_ArabicAlef) { + if (nextChars[i].GetCharType() >= FX_CHARTYPE_ArabicAlef) { pCurLine->m_iArabicChars--; pNextLine->m_iArabicChars++; } - iCharWidth = pTC->m_iCharWidth; - if (iCharWidth > 0) { + int32_t iCharWidth = nextChars[i].m_iCharWidth; + if (iCharWidth > 0) iWidth += iCharWidth; - } - if (m_bPagination) { + if (m_bPagination) continue; - } - pTC->m_dwStatus = 0; + + nextChars[i].m_dwStatus = 0; } pNextLine->m_iWidth = iWidth; } -int32_t CFX_TxtBreak::CountBreakChars() const { - CFX_TxtLine* pTxtLine = GetTxtLine(true); - return pTxtLine ? pTxtLine->CountChars() : 0; -} - int32_t CFX_TxtBreak::CountBreakPieces() const { - CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(true); + CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(); return pTxtPieces ? pTxtPieces->GetSize() : 0; } const CFX_TxtPiece* CFX_TxtBreak::GetBreakPiece(int32_t index) const { - CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(true); - if (!pTxtPieces) { + CFX_TxtPieceArray* pTxtPieces = GetTxtPieces(); + if (!pTxtPieces) return nullptr; - } - if (index < 0 || index >= pTxtPieces->GetSize()) { + if (index < 0 || index >= pTxtPieces->GetSize()) return nullptr; - } return pTxtPieces->GetPtrAt(index); } void CFX_TxtBreak::ClearBreakPieces() { - CFX_TxtLine* pTxtLine = GetTxtLine(true); - if (pTxtLine) { + CFX_TxtLine* pTxtLine = GetTxtLine(); + if (pTxtLine) pTxtLine->RemoveAll(true); - } m_iReady = 0; } void CFX_TxtBreak::Reset() { m_eCharType = FX_CHARTYPE_Unknown; - m_iArabicContext = m_iCurArabicContext = 1; + m_iArabicContext = 1; + m_iCurArabicContext = 1; ResetArabicContext(); m_pTxtLine1->RemoveAll(true); m_pTxtLine2->RemoveAll(true); @@ -1201,11 +1141,10 @@ struct FX_FORMCHAR { int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, FXTEXT_CHARPOS* pCharPos, bool bCharCode, - CFX_WideString* pWSForms, - FX_AdjustCharDisplayPos pAdjustPos) const { - if (!pTxtRun || pTxtRun->iLength < 1) { + CFX_WideString* pWSForms) const { + if (!pTxtRun || pTxtRun->iLength < 1) return 0; - } + IFX_TxtAccess* pAccess = pTxtRun->pAccess; const FDE_TEXTEDITPIECE* pIdentity = pTxtRun->pIdentity; const FX_WCHAR* pStr = pTxtRun->wsStr.c_str(); @@ -1230,24 +1169,28 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, bool bVerticalDoc = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0; bool bVerticalChar = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0; int32_t iRotation = GetLineRotation(dwStyles) + pTxtRun->iCharRotation; - FX_FLOAT fX, fY, fCharWidth, fCharHeight; + FX_FLOAT fX = rtText.left; + FX_FLOAT fY; + FX_FLOAT fCharWidth; + FX_FLOAT fCharHeight; int32_t iHorScale = pTxtRun->iHorizontalScale; int32_t iVerScale = pTxtRun->iVerticalScale; bool bSkipSpace = pTxtRun->bSkipSpace; FX_FORMCHAR formChars[3]; FX_FLOAT fYBase; - fX = rtText.left; + if (bVerticalDoc) { fX += (rtText.width - fFontSize) / 2.0f; fYBase = bRTLPiece ? rtText.bottom() : rtText.top; fY = fYBase; } else { - if (bRTLPiece) { + if (bRTLPiece) fX = rtText.right(); - } + fYBase = rtText.top + (rtText.height - fFontSize) / 2.0f; fY = fYBase + fAscent; } + int32_t iCount = 0; int32_t iNext = 0; FX_WCHAR wPrev = 0xFEFF; @@ -1266,6 +1209,7 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, wch = *pStr++; iWidth = *pWidths++; } + uint32_t dwProps = FX_GetUnicodeProperties(wch); FX_CHARTYPE chartype = GetCharTypeFromProp(dwProps); if (chartype == FX_CHARTYPE_ArabicAlef && iWidth == 0) { @@ -1273,6 +1217,7 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, wLast = wch; continue; } + if (chartype >= FX_CHARTYPE_ArabicAlef) { if (i < iLength) { if (pAccess) { @@ -1280,31 +1225,30 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, while (iNext <= iLength) { wNext = pAccess->GetChar(pIdentity, iNext); dwProps = FX_GetUnicodeProperties(wNext); - if ((dwProps & FX_CHARTYPEBITSMASK) != FX_CHARTYPE_Combination) { + if ((dwProps & FX_CHARTYPEBITSMASK) != FX_CHARTYPE_Combination) break; - } + iNext++; } - if (iNext > iLength) { + if (iNext > iLength) wNext = 0xFEFF; - } } else { int32_t j = -1; do { j++; - if (i + j >= iLength) { + if (i + j >= iLength) break; - } + wNext = pStr[j]; dwProps = FX_GetUnicodeProperties(wNext); } while ((dwProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination); - if (i + j >= iLength) { + if (i + j >= iLength) wNext = 0xFEFF; - } } } else { wNext = 0xFEFF; } + wForm = pdfium::arabic::GetFormChar(wch, wPrev, wNext); bLam = (wPrev == 0x0644 && wch == 0x0644 && wNext == 0x0647); } else if (chartype == FX_CHARTYPE_Combination) { @@ -1317,13 +1261,11 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, wNext = 0xFEFF; if (pAccess) { iNext = i + 1; - if (iNext <= iLength) { + if (iNext <= iLength) wNext = pAccess->GetChar(pIdentity, iNext); - } } else { - if (i < iLength) { + if (i < iLength) wNext = *pStr; - } } if (wch == 0x0651) { if (wNext >= 0x064C && wNext <= 0x0650) { @@ -1342,67 +1284,61 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, } } else if (chartype == FX_CHARTYPE_Numeric) { wForm = wch; - if (bArabicNumber) { + if (bArabicNumber) wForm += 0x0630; - } } else if (wch == L'.') { wForm = wch; if (bArabicNumber) { wNext = 0xFEFF; if (pAccess) { iNext = i + 1; - if (iNext <= iLength) { + if (iNext <= iLength) wNext = pAccess->GetChar(pIdentity, iNext); - } } else { - if (i < iLength) { + if (i < iLength) wNext = *pStr; - } } - if (wNext >= L'0' && wNext <= L'9') { + if (wNext >= L'0' && wNext <= L'9') wForm = 0x066B; - } } } else if (wch == L',') { wForm = wch; - if (bArabicComma) { + if (bArabicComma) wForm = 0x060C; - } } else if (bRTLPiece || bVerticalChar) { wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar); } else { wForm = wch; } - if (chartype != FX_CHARTYPE_Combination) { + if (chartype != FX_CHARTYPE_Combination) bShadda = false; - } - if (chartype < FX_CHARTYPE_ArabicAlef) { + if (chartype < FX_CHARTYPE_ArabicAlef) bLam = false; - } + dwProps = FX_GetUnicodeProperties(wForm); int32_t iCharRotation = iRotation; - if (bVerticalChar && (dwProps & 0x8000) != 0) { + if (bVerticalChar && (dwProps & 0x8000) != 0) iCharRotation++; - } + iCharRotation %= 4; bool bEmptyChar = (chartype >= FX_CHARTYPE_Tab && chartype <= FX_CHARTYPE_Control); - if (wForm == 0xFEFF) { + if (wForm == 0xFEFF) bEmptyChar = true; - } + int32_t iForms = bLam ? 3 : 1; iCount += (bEmptyChar && bSkipSpace) ? 0 : iForms; if (!pCharPos) { - if (iWidth > 0) { + if (iWidth > 0) wPrev = wch; - } wLast = wch; continue; } + int32_t iCharWidth = iWidth; - if (iCharWidth < 0) { + if (iCharWidth < 0) iCharWidth = -iCharWidth; - } + iCharWidth /= iFontSize; formChars[0].wch = wch; formChars[0].wForm = wForm; @@ -1417,6 +1353,7 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, pFont->GetCharWidth(0x0670, iCharWidth, false); formChars[2].iWidth = iCharWidth; } + for (int32_t j = 0; j < iForms; j++) { wForm = (FX_WCHAR)formChars[j].wForm; iCharWidth = formChars[j].iWidth; @@ -1432,10 +1369,10 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, pCharPos->m_ExtGID = pCharPos->m_GlyphIndex; #endif pCharPos->m_FontCharWidth = iCharWidth; - if (pWSForms) { + if (pWSForms) *pWSForms += wForm; - } } + int32_t iCharHeight; if (bVerticalDoc) { iCharHeight = iCharWidth; @@ -1443,33 +1380,31 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, } else { iCharHeight = 1000; } + fCharWidth = fFontSize * iCharWidth / 1000.0f; fCharHeight = fFontSize * iCharHeight / 1000.0f; if (bRTLPiece && chartype != FX_CHARTYPE_Combination) { - if (bVerticalDoc) { + if (bVerticalDoc) fY -= fCharHeight; - } else { + else fX -= fCharWidth; - } } if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) { - pCharPos->m_OriginX = fX; - pCharPos->m_OriginY = fY; + pCharPos->m_Origin = CFX_PointF(fX, fY); if ((dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0) { int32_t iFormWidth = iCharWidth; pFont->GetCharWidth(wForm, iFormWidth, false); FX_FLOAT fOffset = fFontSize * (iCharWidth - iFormWidth) / 2000.0f; - if (bVerticalDoc) { - pCharPos->m_OriginY += fOffset; - } else { - pCharPos->m_OriginX += fOffset; - } + if (bVerticalDoc) + pCharPos->m_Origin.y += fOffset; + else + pCharPos->m_Origin.x += fOffset; } + if (chartype == FX_CHARTYPE_Combination) { CFX_Rect rtBBox; - rtBBox.Reset(); if (pFont->GetCharBBox(wForm, &rtBBox, false)) { - pCharPos->m_OriginY = + pCharPos->m_Origin.y = fYBase + fFontSize - fFontSize * (FX_FLOAT)rtBBox.height / (FX_FLOAT)iMaxHeight; } @@ -1478,37 +1413,29 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, if ((dwLastProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination) { CFX_Rect rtBox; - rtBox.Reset(); - if (pFont->GetCharBBox(wLast, &rtBox, false)) { - pCharPos->m_OriginY -= fFontSize * rtBox.height / iMaxHeight; - } + if (pFont->GetCharBBox(wLast, &rtBox, false)) + pCharPos->m_Origin.y -= fFontSize * rtBox.height / iMaxHeight; } } } CFX_PointF ptOffset; - bool bAdjusted = false; - if (pAdjustPos) { - bAdjusted = pAdjustPos(wForm, bCharCode, pFont, fFontSize, - bVerticalChar, ptOffset); - } - if (!bAdjusted && bVerticalChar && (dwProps & 0x00010000) != 0) { + if (bVerticalChar && (dwProps & 0x00010000) != 0) { CFX_Rect rtBBox; - rtBBox.Reset(); if (pFont->GetCharBBox(wForm, &rtBBox, false)) { ptOffset.x = fFontSize * (850 - rtBBox.right()) / iMaxHeight; ptOffset.y = fFontSize * (iAscent - rtBBox.top - 150) / iMaxHeight; } } - pCharPos->m_OriginX += ptOffset.x; - pCharPos->m_OriginY -= ptOffset.y; + pCharPos->m_Origin.x += ptOffset.x; + pCharPos->m_Origin.y -= ptOffset.y; } if (!bRTLPiece && chartype != FX_CHARTYPE_Combination) { - if (bVerticalDoc) { + if (bVerticalDoc) fY += fCharHeight; - } else { + else fX += fCharWidth; - } } + if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) { pCharPos->m_bGlyphAdjust = true; if (bVerticalDoc) { @@ -1517,26 +1444,26 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, pCharPos->m_AdjustMatrix[1] = 0; pCharPos->m_AdjustMatrix[2] = 0; pCharPos->m_AdjustMatrix[3] = 1; - pCharPos->m_OriginY += fAscent; + pCharPos->m_Origin.y += fAscent; } else if (iCharRotation == 1) { pCharPos->m_AdjustMatrix[0] = 0; pCharPos->m_AdjustMatrix[1] = -1; pCharPos->m_AdjustMatrix[2] = -1; pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX -= fDescent; + pCharPos->m_Origin.x -= fDescent; } else if (iCharRotation == 2) { pCharPos->m_AdjustMatrix[0] = 1; pCharPos->m_AdjustMatrix[1] = 0; pCharPos->m_AdjustMatrix[2] = 0; pCharPos->m_AdjustMatrix[3] = -1; - pCharPos->m_OriginX += fCharWidth; - pCharPos->m_OriginY += fAscent; + pCharPos->m_Origin.x += fCharWidth; + pCharPos->m_Origin.y += fAscent; } else { pCharPos->m_AdjustMatrix[0] = 0; pCharPos->m_AdjustMatrix[1] = 1; pCharPos->m_AdjustMatrix[2] = 1; pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX += fAscent; + pCharPos->m_Origin.x += fAscent; } } else { if (iCharRotation == 0) { @@ -1549,21 +1476,21 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, pCharPos->m_AdjustMatrix[1] = -1; pCharPos->m_AdjustMatrix[2] = -1; pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX -= fDescent; - pCharPos->m_OriginY -= fAscent + fDescent; + pCharPos->m_Origin.x -= fDescent; + pCharPos->m_Origin.y -= fAscent + fDescent; } else if (iCharRotation == 2) { pCharPos->m_AdjustMatrix[0] = 1; pCharPos->m_AdjustMatrix[1] = 0; pCharPos->m_AdjustMatrix[2] = 0; pCharPos->m_AdjustMatrix[3] = -1; - pCharPos->m_OriginX += fCharWidth; - pCharPos->m_OriginY -= fAscent; + pCharPos->m_Origin.x += fCharWidth; + pCharPos->m_Origin.y -= fAscent; } else { pCharPos->m_AdjustMatrix[0] = 0; pCharPos->m_AdjustMatrix[1] = 1; pCharPos->m_AdjustMatrix[2] = 1; pCharPos->m_AdjustMatrix[3] = 0; - pCharPos->m_OriginX += fAscent; + pCharPos->m_Origin.x += fAscent; } } if (iHorScale != 100 || iVerScale != 100) { @@ -1579,19 +1506,17 @@ int32_t CFX_TxtBreak::GetDisplayPos(const FX_TXTRUN* pTxtRun, pCharPos++; } } - if (iWidth > 0) { - wPrev = (FX_WCHAR)formChars[0].wch; - } + if (iWidth > 0) + wPrev = static_cast<FX_WCHAR>(formChars[0].wch); wLast = wch; } return iCount; } -int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, - CFX_RectFArray& rtArray, - bool bCharBBox) const { +std::vector<CFX_RectF> CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, + bool bCharBBox) const { if (!pTxtRun || pTxtRun->iLength < 1) - return 0; + return std::vector<CFX_RectF>(); IFX_TxtAccess* pAccess = pTxtRun->pAccess; const FDE_TEXTEDITPIECE* pIdentity = pTxtRun->pIdentity; @@ -1599,7 +1524,6 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, int32_t* pWidths = pTxtRun->pWidths; int32_t iLength = pTxtRun->iLength; CFX_RectF rect(*pTxtRun->pRect); - bool bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0; FX_FLOAT fFontSize = pTxtRun->fFontSize; int32_t iFontSize = FXSYS_round(fFontSize * 20.0f); FX_FLOAT fScale = fFontSize / 1000.0f; @@ -1608,25 +1532,26 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, bCharBBox = false; CFX_Rect bbox; - bbox.Set(0, 0, 0, 0); if (bCharBBox) bCharBBox = pFont->GetBBox(&bbox); FX_FLOAT fLeft = std::max(0.0f, bbox.left * fScale); FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale); - rtArray.RemoveAll(); - rtArray.SetSize(iLength); - bool bVertical = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0; - bool bSingleLine = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0; - bool bCombText = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0; - FX_WCHAR wch, wLineBreakChar = pTxtRun->wLineBreakChar; + bool bRTLPiece = !!(pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel); + bool bVertical = !!(pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout); + bool bSingleLine = !!(pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_SingleLine); + bool bCombText = !!(pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_CombText); + FX_WCHAR wch; + FX_WCHAR wLineBreakChar = pTxtRun->wLineBreakChar; int32_t iCharSize; - FX_FLOAT fCharSize, fStart; - if (bVertical) { + FX_FLOAT fCharSize; + FX_FLOAT fStart; + if (bVertical) fStart = bRTLPiece ? rect.bottom() : rect.top; - } else { + else fStart = bRTLPiece ? rect.right() : rect.left; - } + + std::vector<CFX_RectF> rtArray(iLength); for (int32_t i = 0; i < iLength; i++) { if (pAccess) { wch = pAccess->GetChar(pIdentity, i); @@ -1635,7 +1560,7 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, wch = *pStr++; iCharSize = *pWidths++; } - fCharSize = (FX_FLOAT)iCharSize / 20000.0f; + fCharSize = static_cast<FX_FLOAT>(iCharSize) / 20000.0f; bool bRet = (!bSingleLine && FX_IsCtrlCode(wch)); if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 || (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) { @@ -1664,6 +1589,7 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, } rect.width = fCharSize; } + if (bCharBBox && !bRet) { int32_t iCharWidth = 1000; pFont->GetCharWidth(wch, iCharWidth, false); @@ -1671,9 +1597,8 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, if (iCharWidth > 0) { fCharWidth = iCharWidth * fScale; fRTLeft = fLeft; - if (bCombText) { + if (bCombText) fRTLeft = (rect.width - fCharWidth) / 2.0f; - } } CFX_RectF rtBBoxF; if (bVertical) { @@ -1689,12 +1614,12 @@ int32_t CFX_TxtBreak::GetCharRects(const FX_TXTRUN* pTxtRun, rtBBoxF.height = fHeight; rtBBoxF.top = std::max(rtBBoxF.top, 0.0f); } - rtArray.SetAt(i, rtBBoxF); + rtArray[i] = rtBBoxF; continue; } - rtArray.SetAt(i, rect); + rtArray[i] = rect; } - return iLength; + return rtArray; } FX_TXTRUN::FX_TXTRUN() @@ -1732,7 +1657,7 @@ CFX_TxtPiece::CFX_TxtPiece() m_pUserData(nullptr) {} CFX_TxtLine::CFX_TxtLine(int32_t iBlockSize) - : m_pLineChars(new CFX_TxtCharArray), + : m_pLineChars(new std::vector<CFX_TxtChar>), m_pLinePieces(new CFX_TxtPieceArray(16)), m_iStart(0), m_iWidth(0), diff --git a/xfa/fgas/layout/fgas_textbreak.h b/xfa/fgas/layout/fgas_textbreak.h index 7359600c1..69ca835fa 100644 --- a/xfa/fgas/layout/fgas_textbreak.h +++ b/xfa/fgas/layout/fgas_textbreak.h @@ -7,18 +7,21 @@ #ifndef XFA_FGAS_LAYOUT_FGAS_TEXTBREAK_H_ #define XFA_FGAS_LAYOUT_FGAS_TEXTBREAK_H_ +#include <deque> #include <memory> +#include <vector> #include "core/fxcrt/fx_ucd.h" #include "core/fxge/cfx_renderdevice.h" +#include "third_party/base/stl_util.h" #include "xfa/fgas/crt/fgas_utils.h" -#include "xfa/fgas/layout/fgas_unicode.h" class CFX_Char; class CFGAS_GEFont; class CFX_TxtChar; class CFX_TxtPiece; class IFX_TxtAccess; +struct FDE_TEXTEDITPIECE; #define FX_TXTBREAKPOLICY_None 0x00 #define FX_TXTBREAKPOLICY_Pagination 0x01 @@ -72,7 +75,12 @@ class IFX_TxtAccess; #define FX_TXTLINEALIGNMENT_HigherMask 0x0C #define FX_TXTBREAK_MinimumTabWidth 160000 -struct FDE_TEXTEDITPIECE; +struct FX_TPO { + int32_t index; + int32_t pos; + + bool operator<(const FX_TPO& that) const { return pos < that.pos; } +}; class IFX_TxtAccess { public: @@ -116,16 +124,13 @@ class CFX_TxtPiece { int32_t GetEndChar() const { return m_iStartChar + m_iChars; } CFX_TxtChar* GetCharPtr(int32_t index) const { ASSERT(index > -1 && index < m_iChars && m_pChars); - return m_pChars->GetDataPtr(m_iStartChar + index); + return &(*m_pChars)[m_iStartChar + index]; } void GetString(FX_WCHAR* pText) const { ASSERT(pText); int32_t iEndChar = m_iStartChar + m_iChars; - CFX_Char* pChar; - for (int32_t i = m_iStartChar; i < iEndChar; i++) { - pChar = m_pChars->GetDataPtr(i); - *pText++ = (FX_WCHAR)pChar->m_wCharCode; - } + for (int32_t i = m_iStartChar; i < iEndChar; i++) + *pText++ = static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode); } void GetString(CFX_WideString& wsText) const { FX_WCHAR* pText = wsText.GetBuffer(m_iChars); @@ -135,11 +140,8 @@ class CFX_TxtPiece { void GetWidths(int32_t* pWidths) const { ASSERT(pWidths); int32_t iEndChar = m_iStartChar + m_iChars; - CFX_Char* pChar; - for (int32_t i = m_iStartChar; i < iEndChar; i++) { - pChar = m_pChars->GetDataPtr(i); - *pWidths++ = pChar->m_iCharWidth; - } + for (int32_t i = m_iStartChar; i < iEndChar; i++) + *pWidths++ = (*m_pChars)[i].m_iCharWidth; } uint32_t m_dwStatus; @@ -152,7 +154,7 @@ class CFX_TxtPiece { int32_t m_iHorizontalScale; int32_t m_iVerticalScale; uint32_t m_dwCharStyles; - CFX_TxtCharArray* m_pChars; + std::vector<CFX_TxtChar>* m_pChars; void* m_pUserData; }; @@ -163,34 +165,38 @@ class CFX_TxtLine { explicit CFX_TxtLine(int32_t iBlockSize); ~CFX_TxtLine(); - int32_t CountChars() const { return m_pLineChars->GetSize(); } + int32_t CountChars() const { + return pdfium::CollectionSize<int32_t>(*m_pLineChars); + } + CFX_TxtChar* GetCharPtr(int32_t index) const { - ASSERT(index > -1 && index < m_pLineChars->GetSize()); - return m_pLineChars->GetDataPtr(index); + ASSERT(index >= 0 && + index < pdfium::CollectionSize<int32_t>(*m_pLineChars)); + return &(*m_pLineChars)[index]; } + int32_t CountPieces() const { return m_pLinePieces->GetSize(); } CFX_TxtPiece* GetPiecePtr(int32_t index) const { ASSERT(index > -1 && index < m_pLinePieces->GetSize()); return m_pLinePieces->GetPtrAt(index); } + void GetString(CFX_WideString& wsStr) const { - int32_t iCount = m_pLineChars->GetSize(); + int32_t iCount = pdfium::CollectionSize<int32_t>(*m_pLineChars); FX_WCHAR* pBuf = wsStr.GetBuffer(iCount); - CFX_Char* pChar; - for (int32_t i = 0; i < iCount; i++) { - pChar = m_pLineChars->GetDataPtr(i); - *pBuf++ = (FX_WCHAR)pChar->m_wCharCode; - } + for (int32_t i = 0; i < iCount; i++) + *pBuf++ = static_cast<FX_WCHAR>((*m_pLineChars)[i].m_wCharCode); wsStr.ReleaseBuffer(iCount); } + void RemoveAll(bool bLeaveMemory = false) { - m_pLineChars->RemoveAll(); + m_pLineChars->clear(); m_pLinePieces->RemoveAll(bLeaveMemory); m_iWidth = 0; m_iArabicChars = 0; } - std::unique_ptr<CFX_TxtCharArray> m_pLineChars; + std::unique_ptr<std::vector<CFX_TxtChar>> m_pLineChars; std::unique_ptr<CFX_TxtPieceArray> m_pLinePieces; int32_t m_iStart; int32_t m_iWidth; @@ -213,17 +219,13 @@ class CFX_TxtBreak { void SetParagraphBreakChar(FX_WCHAR wch); void SetLineBreakTolerance(FX_FLOAT fTolerance); void SetHorizontalScale(int32_t iScale); - void SetVerticalScale(int32_t iScale); void SetCharRotation(int32_t iCharRotation); void SetCharSpace(FX_FLOAT fCharSpace); void SetAlignment(int32_t iAlignment); - uint32_t GetContextCharStyles() const; - void SetContextCharStyles(uint32_t dwCharStyles); void SetCombWidth(FX_FLOAT fCombWidth); void SetUserData(void* pUserData); uint32_t AppendChar(FX_WCHAR wch); uint32_t EndBreak(uint32_t dwStatus = FX_TXTBREAK_PieceBreak); - int32_t CountBreakChars() const; int32_t CountBreakPieces() const; const CFX_TxtPiece* GetBreakPiece(int32_t index) const; void ClearBreakPieces(); @@ -231,11 +233,9 @@ class CFX_TxtBreak { int32_t GetDisplayPos(const FX_TXTRUN* pTxtRun, FXTEXT_CHARPOS* pCharPos, bool bCharCode = false, - CFX_WideString* pWSForms = nullptr, - FX_AdjustCharDisplayPos pAdjustPos = nullptr) const; - int32_t GetCharRects(const FX_TXTRUN* pTxtRun, - CFX_RectFArray& rtArray, - bool bCharBBox = false) const; + CFX_WideString* pWSForms = nullptr) const; + std::vector<CFX_RectF> GetCharRects(const FX_TXTRUN* pTxtRun, + bool bCharBBox = false) const; void AppendChar_PageLoad(CFX_TxtChar* pCurChar, uint32_t dwProps); uint32_t AppendChar_Combination(CFX_TxtChar* pCurChar, int32_t iRotation); uint32_t AppendChar_Tab(CFX_TxtChar* pCurChar, int32_t iRotation); @@ -244,11 +244,12 @@ class CFX_TxtBreak { uint32_t AppendChar_Others(CFX_TxtChar* pCurChar, int32_t iRotation); private: + void FontChanged(); void SetBreakStatus(); int32_t GetLineRotation(uint32_t dwStyles) const; CFX_TxtChar* GetLastChar(int32_t index, bool bOmitChar = true) const; - CFX_TxtLine* GetTxtLine(bool bReady) const; - CFX_TxtPieceArray* GetTxtPieces(bool bReady) const; + CFX_TxtLine* GetTxtLine() const; + CFX_TxtPieceArray* GetTxtPieces() const; FX_CHARTYPE GetUnifiedCharType(FX_CHARTYPE dwType) const; void ResetArabicContext(); void ResetContextCharStyles(); @@ -256,11 +257,11 @@ class CFX_TxtBreak { bool EndBreak_SplitLine(CFX_TxtLine* pNextLine, bool bAllChars, uint32_t dwStatus); - void EndBreak_BidiLine(CFX_TPOArray& tpos, uint32_t dwStatus); - void EndBreak_Alignment(CFX_TPOArray& tpos, + void EndBreak_BidiLine(std::deque<FX_TPO>* tpos, uint32_t dwStatus); + void EndBreak_Alignment(const std::deque<FX_TPO>& tpos, bool bAllChars, uint32_t dwStatus); - int32_t GetBreakPos(CFX_TxtCharArray& ca, + int32_t GetBreakPos(std::vector<CFX_TxtChar>& ca, int32_t& iEndPos, bool bAllChars = false, bool bOnlyBrk = false); @@ -305,7 +306,6 @@ class CFX_TxtBreak { int32_t m_iReady; int32_t m_iTolerance; int32_t m_iHorScale; - int32_t m_iVerScale; int32_t m_iCharSpace; }; diff --git a/xfa/fgas/layout/fgas_unicode.cpp b/xfa/fgas/layout/fgas_unicode.cpp deleted file mode 100644 index 10fdbf081..000000000 --- a/xfa/fgas/layout/fgas_unicode.cpp +++ /dev/null @@ -1,49 +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 "xfa/fgas/layout/fgas_unicode.h" - -void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd) { - ASSERT(iStart > -1 && iStart < tpos.GetSize()); - ASSERT(iEnd > -1 && iEnd < tpos.GetSize()); - if (iStart >= iEnd) { - return; - } - int32_t i = iStart, j = iEnd; - FX_TPO *pCur = tpos.GetPtrAt(iStart), *pSort; - int32_t v = pCur->pos; - while (i < j) { - while (j > i) { - pSort = tpos.GetPtrAt(j); - if (pSort->pos < v) { - FX_TPO t = *pSort; - *pSort = *pCur; - *pCur = t; - pCur = pSort; - break; - } - j--; - } - while (i < j) { - pSort = tpos.GetPtrAt(i); - if (pSort->pos > v) { - FX_TPO t = *pSort; - *pSort = *pCur; - *pCur = t; - pCur = pSort; - break; - } - i++; - } - } - i--, j++; - if (iStart < i) { - FX_TEXTLAYOUT_PieceSort(tpos, iStart, i); - } - if (j < iEnd) { - FX_TEXTLAYOUT_PieceSort(tpos, j, iEnd); - } -} diff --git a/xfa/fgas/layout/fgas_unicode.h b/xfa/fgas/layout/fgas_unicode.h deleted file mode 100644 index b404d6728..000000000 --- a/xfa/fgas/layout/fgas_unicode.h +++ /dev/null @@ -1,29 +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 XFA_FGAS_LAYOUT_FGAS_UNICODE_H_ -#define XFA_FGAS_LAYOUT_FGAS_UNICODE_H_ - -#include "xfa/fgas/crt/fgas_utils.h" -#include "xfa/fgas/font/cfgas_fontmgr.h" - -struct FX_TPO { - int32_t index; - int32_t pos; -}; -typedef CFX_MassArrayTemplate<FX_TPO> CFX_TPOArray; - -void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray& tpos, int32_t iStart, int32_t iEnd); - -typedef bool (*FX_AdjustCharDisplayPos)( - FX_WCHAR wch, - bool bMBCSCode, - const CFX_RetainPtr<CFGAS_GEFont>& pFont, - FX_FLOAT fFontSize, - bool bVertical, - CFX_PointF& ptOffset); - -#endif // XFA_FGAS_LAYOUT_FGAS_UNICODE_H_ diff --git a/xfa/fgas/localization/fgas_locale.cpp b/xfa/fgas/localization/fgas_locale.cpp index d6ef62885..7d538411f 100644 --- a/xfa/fgas/localization/fgas_locale.cpp +++ b/xfa/fgas/localization/fgas_locale.cpp @@ -542,7 +542,7 @@ IFX_Locale* CFX_FormatString::GetNumericFormat(const CFX_WideString& wsPattern, wsCategory += pStr[ccf]; ccf++; } - if (wsCategory != FX_WSTRC(L"num")) { + if (wsCategory != L"num") { bBrackOpen = true; ccf = 0; continue; @@ -652,7 +652,7 @@ bool CFX_FormatString::ParseText(const CFX_WideString& wsSrcText, return false; } CFX_WideString wsTextFormat; - GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat); + GetTextFormat(wsPattern, L"text", wsTextFormat); if (wsTextFormat.IsEmpty()) { return false; } @@ -1942,16 +1942,16 @@ FX_DATETIMETYPE CFX_FormatString::GetDateTimeFormat( wsCategory += pStr[ccf]; ccf++; } - if (!(iFindCategory & 1) && wsCategory == FX_WSTRC(L"date")) { + if (!(iFindCategory & 1) && wsCategory == L"date") { iFindCategory |= 1; eCategory = FX_LOCALECATEGORY_Date; if (iFindCategory & 2) { iFindCategory = 4; } - } else if (!(iFindCategory & 2) && wsCategory == FX_WSTRC(L"time")) { + } else if (!(iFindCategory & 2) && wsCategory == L"time") { iFindCategory |= 2; eCategory = FX_LOCALECATEGORY_Time; - } else if (wsCategory == FX_WSTRC(L"datetime")) { + } else if (wsCategory == L"datetime") { iFindCategory = 3; eCategory = FX_LOCALECATEGORY_DateTime; } else { @@ -2506,7 +2506,7 @@ bool CFX_FormatString::ParseDateTime(const CFX_WideString& wsSrcDateTime, bool CFX_FormatString::ParseZero(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern) { CFX_WideString wsTextFormat; - GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat); + GetTextFormat(wsPattern, L"zero", wsTextFormat); int32_t iText = 0, iPattern = 0; const FX_WCHAR* pStrText = wsSrcText.c_str(); int32_t iLenText = wsSrcText.GetLength(); @@ -2536,7 +2536,7 @@ bool CFX_FormatString::ParseZero(const CFX_WideString& wsSrcText, bool CFX_FormatString::ParseNull(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern) { CFX_WideString wsTextFormat; - GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat); + GetTextFormat(wsPattern, L"null", wsTextFormat); int32_t iText = 0, iPattern = 0; const FX_WCHAR* pStrText = wsSrcText.c_str(); int32_t iLenText = wsSrcText.GetLength(); @@ -2574,7 +2574,7 @@ bool CFX_FormatString::FormatText(const CFX_WideString& wsSrcText, return false; } CFX_WideString wsTextFormat; - GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat); + GetTextFormat(wsPattern, L"text", wsTextFormat); int32_t iText = 0, iPattern = 0; const FX_WCHAR* pStrText = wsSrcText.c_str(); const FX_WCHAR* pStrPattern = wsTextFormat.c_str(); @@ -3926,14 +3926,14 @@ static bool FX_TimeFormat(const CFX_WideString& wsTimePattern, pLocale->GetMeridiemName(wsMeridiem, !bPM); wsResult += wsMeridiem; } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) { - wsResult += FX_WSTRC(L"GMT"); + wsResult += L"GMT"; FX_TIMEZONE tz; pLocale->GetTimeZone(&tz); if (!bGMT && (tz.tzHour != 0 || tz.tzMinute != 0)) { if (tz.tzHour < 0) { - wsResult += FX_WSTRC(L"-"); + wsResult += L"-"; } else { - wsResult += FX_WSTRC(L"+"); + wsResult += L"+"; } CFX_WideString wsTimezone; wsTimezone.Format(L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute); @@ -3944,9 +3944,9 @@ static bool FX_TimeFormat(const CFX_WideString& wsTimePattern, pLocale->GetTimeZone(&tz); if (!bGMT && tz.tzHour != 0 && tz.tzMinute != 0) { if (tz.tzHour < 0) { - wsResult += FX_WSTRC(L"-"); + wsResult += L"-"; } else { - wsResult += FX_WSTRC(L"+"); + wsResult += L"+"; } CFX_WideString wsTimezone; wsTimezone.Format(L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute); @@ -4079,7 +4079,7 @@ bool CFX_FormatString::FormatZero(const CFX_WideString& wsPattern, return false; } CFX_WideString wsTextFormat; - GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat); + GetTextFormat(wsPattern, L"zero", wsTextFormat); int32_t iPattern = 0; const FX_WCHAR* pStrPattern = wsTextFormat.c_str(); int32_t iLenPattern = wsTextFormat.GetLength(); @@ -4101,7 +4101,7 @@ bool CFX_FormatString::FormatNull(const CFX_WideString& wsPattern, return false; } CFX_WideString wsTextFormat; - GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat); + GetTextFormat(wsPattern, L"null", wsTextFormat); int32_t iPattern = 0; const FX_WCHAR* pStrPattern = wsTextFormat.c_str(); int32_t iLenPattern = wsTextFormat.GetLength(); diff --git a/xfa/fwl/cfwl_caret.cpp b/xfa/fwl/cfwl_caret.cpp index 4a95b0924..da57cb408 100644 --- a/xfa/fwl/cfwl_caret.cpp +++ b/xfa/fwl/cfwl_caret.cpp @@ -76,13 +76,10 @@ void CFWL_Caret::DrawCaretBK(CFX_Graphics* pGraphics, if (!(m_pProperties->m_dwStates & FWL_STATE_CAT_HightLight)) return; - CFX_RectF rect = GetWidgetRect(); - rect.Set(0, 0, rect.width, rect.height); - CFWL_ThemeBackground param; param.m_pWidget = this; param.m_pGraphics = pGraphics; - param.m_rtPart = rect; + param.m_rtPart = CFX_RectF(0, 0, GetWidgetRect().Size()); param.m_iPart = CFWL_Part::Background; param.m_dwStates = CFWL_PartState_HightLight; if (pMatrix) @@ -107,6 +104,5 @@ void CFWL_Caret::Timer::Run(CFWL_TimerInfo* pTimerInfo) { pCaret->RemoveStates(FWL_STATE_CAT_HightLight); CFX_RectF rt = pCaret->GetWidgetRect(); - rt.Set(0, 0, rt.width + 1, rt.height); - pCaret->RepaintRect(rt); + pCaret->RepaintRect(CFX_RectF(0, 0, rt.width + 1, rt.height)); } diff --git a/xfa/fwl/cfwl_checkbox.cpp b/xfa/fwl/cfwl_checkbox.cpp index 5d40d8f42..0102bc7cc 100644 --- a/xfa/fwl/cfwl_checkbox.cpp +++ b/xfa/fwl/cfwl_checkbox.cpp @@ -9,6 +9,7 @@ #include <algorithm> #include <memory> #include <utility> +#include <vector> #include "third_party/base/ptr_util.h" #include "xfa/fde/tto/fde_textout.h" @@ -128,27 +129,21 @@ void CFWL_CheckBox::Layout() { FXSYS_round(m_pProperties->m_rtWidget.height); m_rtClient = GetClientRect(); - FX_FLOAT fBoxTop = m_rtClient.top; - FX_FLOAT fBoxLeft = m_rtClient.left; - FX_FLOAT fTextLeft = fBoxLeft + m_fBoxHeight; - FX_FLOAT fTextRight = m_rtClient.right(); - m_rtBox.Set(fBoxLeft, fBoxTop, m_fBoxHeight, m_fBoxHeight); - m_rtCaption.Set(fTextLeft, m_rtClient.top, fTextRight - fTextLeft, - m_rtClient.height); + FX_FLOAT fTextLeft = m_rtClient.left + m_fBoxHeight; + m_rtBox = CFX_RectF(m_rtClient.TopLeft(), m_fBoxHeight, m_fBoxHeight); + m_rtCaption = CFX_RectF(fTextLeft, m_rtClient.top, + m_rtClient.right() - fTextLeft, m_rtClient.height); m_rtCaption.Inflate(-kCaptionMargin, -kCaptionMargin); - CFX_RectF rtFocus; - rtFocus.Set(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width, - m_rtCaption.height); + CFX_RectF rtFocus(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width, + m_rtCaption.height); CalcTextRect(L"Check box", m_pProperties->m_pThemeProvider, m_dwTTOStyles, m_iTTOAlign, rtFocus); - FX_FLOAT fWidth = std::max(m_rtCaption.width, rtFocus.width); - FX_FLOAT fHeight = std::min(m_rtCaption.height, rtFocus.height); - FX_FLOAT fLeft = m_rtCaption.left; - FX_FLOAT fTop = m_rtCaption.top; - m_rtFocus.Set(fLeft, fTop, fWidth, fHeight); + m_rtFocus = CFX_RectF(m_rtCaption.TopLeft(), + std::max(m_rtCaption.width, rtFocus.width), + std::min(m_rtCaption.height, rtFocus.height)); m_rtFocus.Inflate(1, 1); } @@ -187,18 +182,15 @@ void CFWL_CheckBox::NextStates() { FWL_STATE_CKB_Unchecked) { CFWL_WidgetMgr* pWidgetMgr = GetOwnerApp()->GetWidgetMgr(); if (!pWidgetMgr->IsFormDisabled()) { - CFX_ArrayTemplate<CFWL_Widget*> radioarr; - pWidgetMgr->GetSameGroupRadioButton(this, radioarr); - CFWL_CheckBox* pCheckBox = nullptr; - int32_t iCount = radioarr.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - pCheckBox = static_cast<CFWL_CheckBox*>(radioarr[i]); + std::vector<CFWL_Widget*> radioarr = + pWidgetMgr->GetSameGroupRadioButton(this); + for (const auto& pWidget : radioarr) { + CFWL_CheckBox* pCheckBox = static_cast<CFWL_CheckBox*>(pWidget); if (pCheckBox != this && pCheckBox->GetStates() & FWL_STATE_CKB_Checked) { pCheckBox->SetCheckState(0); - CFX_RectF rt = pCheckBox->GetWidgetRect(); - rt.left = rt.top = 0; - m_pWidgetMgr->RepaintWidget(pCheckBox, rt); + m_pWidgetMgr->RepaintWidget( + pCheckBox, CFX_RectF(0, 0, pCheckBox->GetWidgetRect().Size())); break; } } @@ -305,7 +297,7 @@ void CFWL_CheckBox::OnLButtonUp(CFWL_MessageMouse* pMsg) { return; m_bBtnDown = false; - if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) + if (!m_rtClient.Contains(pMsg->m_pos)) return; m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; @@ -319,7 +311,7 @@ void CFWL_CheckBox::OnMouseMove(CFWL_MessageMouse* pMsg) { bool bRepaint = false; if (m_bBtnDown) { - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtClient.Contains(pMsg->m_pos)) { if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) == 0) { bRepaint = true; m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed; @@ -339,7 +331,7 @@ void CFWL_CheckBox::OnMouseMove(CFWL_MessageMouse* pMsg) { } } } else { - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtClient.Contains(pMsg->m_pos)) { if ((m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) { bRepaint = true; m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered; diff --git a/xfa/fwl/cfwl_combobox.cpp b/xfa/fwl/cfwl_combobox.cpp index 03d2921e6..6083943f9 100644 --- a/xfa/fwl/cfwl_combobox.cpp +++ b/xfa/fwl/cfwl_combobox.cpp @@ -118,10 +118,10 @@ void CFWL_ComboBox::Update() { Layout(); } -FWL_WidgetHit CFWL_ComboBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) { +FWL_WidgetHit CFWL_ComboBox::HitTest(const CFX_PointF& point) { if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_HitTest(fx, fy); - return CFWL_Widget::HitTest(fx, fy); + return DisForm_HitTest(point); + return CFWL_Widget::HitTest(point); } void CFWL_ComboBox::DrawWidget(CFX_Graphics* pGraphics, @@ -326,9 +326,8 @@ void CFWL_ComboBox::ShowDropList(bool bActivate) { m_pListBox->ModifyStylesEx(dwStyleAdd, 0); m_rtList = m_pListBox->GetAutosizedWidgetRect(); - CFX_RectF rtAnchor; - rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); + CFX_RectF rtAnchor(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); m_rtList.width = std::max(m_rtList.width, m_rtClient.width); m_rtProxy = m_rtList; @@ -378,14 +377,13 @@ void CFWL_ComboBox::Layout() { return; FX_FLOAT fBtn = theme->GetScrollBarWidth(); - m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn, - m_rtClient.height); + m_rtBtn = CFX_RectF(m_rtClient.right() - fBtn, m_rtClient.top, fBtn, + m_rtClient.height); if (!IsDropDownStyle() || !m_pEdit) return; - CFX_RectF rtEdit; - rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, - m_rtClient.height); + CFX_RectF rtEdit(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, + m_rtClient.height); m_pEdit->SetWidgetRect(rtEdit); if (m_iCurSel >= 0) { @@ -552,11 +550,7 @@ void CFWL_ComboBox::DisForm_ShowDropList(bool bActivate) { fPopupMin = fItemHeight * 3 + fBorder * 2; FX_FLOAT fPopupMax = fItemHeight * iItems + fBorder * 2; - CFX_RectF rtList; - rtList.left = m_rtClient.left; - rtList.width = m_pProperties->m_rtWidget.width; - rtList.top = 0; - rtList.height = 0; + CFX_RectF rtList(m_rtClient.left, 0, m_pProperties->m_rtWidget.width, 0); GetPopupPos(fPopupMin, fPopupMax, m_pProperties->m_rtWidget, rtList); m_pListBox->SetWidgetRect(rtList); @@ -605,17 +599,16 @@ void CFWL_ComboBox::DisForm_Update() { Layout(); } -FWL_WidgetHit CFWL_ComboBox::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rect; - rect.Set(0, 0, m_pProperties->m_rtWidget.width - m_rtBtn.width, - m_pProperties->m_rtWidget.height); - if (rect.Contains(fx, fy)) +FWL_WidgetHit CFWL_ComboBox::DisForm_HitTest(const CFX_PointF& point) { + CFX_RectF rect(0, 0, m_pProperties->m_rtWidget.width - m_rtBtn.width, + m_pProperties->m_rtWidget.height); + if (rect.Contains(point)) return FWL_WidgetHit::Edit; - if (m_rtBtn.Contains(fx, fy)) + if (m_rtBtn.Contains(point)) return FWL_WidgetHit::Client; if (DisForm_IsDropListVisible()) { rect = m_pListBox->GetWidgetRect(); - if (rect.Contains(fx, fy)) + if (rect.Contains(point)) return FWL_WidgetHit::Client; } return FWL_WidgetHit::Unknown; @@ -624,8 +617,7 @@ FWL_WidgetHit CFWL_ComboBox::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) { void CFWL_ComboBox::DisForm_DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; - CFX_Matrix mtOrg; - mtOrg.Set(1, 0, 0, 1, 0, 0); + CFX_Matrix mtOrg(1, 0, 0, 1, 0, 0); if (pMatrix) mtOrg = *pMatrix; @@ -644,15 +636,13 @@ void CFWL_ComboBox::DisForm_DrawWidget(CFX_Graphics* pGraphics, if (m_pEdit) { CFX_RectF rtEdit = m_pEdit->GetWidgetRect(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top); + CFX_Matrix mt(1, 0, 0, 1, rtEdit.left, rtEdit.top); mt.Concat(mtOrg); m_pEdit->DrawWidget(pGraphics, &mt); } if (m_pListBox && DisForm_IsDropListVisible()) { CFX_RectF rtList = m_pListBox->GetWidgetRect(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtList.left, rtList.top); + CFX_Matrix mt(1, 0, 0, 1, rtList.left, rtList.top); mt.Concat(mtOrg); m_pListBox->DrawWidget(pGraphics, &mt); } @@ -679,8 +669,9 @@ void CFWL_ComboBox::DisForm_Layout() { FX_FLOAT borderWidth = 1; FX_FLOAT fBtn = theme->GetScrollBarWidth(); if (!(GetStylesEx() & FWL_STYLEEXT_CMB_ReadOnly)) { - m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth, - fBtn - borderWidth, m_rtClient.height - 2 * borderWidth); + m_rtBtn = + CFX_RectF(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth, + fBtn - borderWidth, m_rtClient.height - 2 * borderWidth); } CFWL_ThemePart part; @@ -692,9 +683,8 @@ void CFWL_ComboBox::DisForm_Layout() { if (!IsDropDownStyle() || !m_pEdit) return; - CFX_RectF rtEdit; - rtEdit.Set(m_rtContent.left, m_rtContent.top, m_rtContent.width - fBtn, - m_rtContent.height); + CFX_RectF rtEdit(m_rtContent.left, m_rtContent.top, m_rtContent.width - fBtn, + m_rtContent.height); m_pEdit->SetWidgetRect(rtEdit); if (m_iCurSel >= 0) { @@ -801,7 +791,7 @@ void CFWL_ComboBox::OnLButtonDown(CFWL_MessageMouse* pMsg) { return; CFX_RectF& rtBtn = IsDropDownStyle() ? m_rtBtn : m_rtClient; - if (!rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + if (!rtBtn.Contains(pMsg->m_pos)) return; if (IsDropDownStyle() && m_pEdit) @@ -818,7 +808,7 @@ void CFWL_ComboBox::OnLButtonDown(CFWL_MessageMouse* pMsg) { void CFWL_ComboBox::OnLButtonUp(CFWL_MessageMouse* pMsg) { m_bLButtonDown = false; - if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + if (m_rtBtn.Contains(pMsg->m_pos)) m_iBtnState = CFWL_PartState_Hovered; else m_iBtnState = CFWL_PartState_Normal; @@ -828,7 +818,7 @@ void CFWL_ComboBox::OnLButtonUp(CFWL_MessageMouse* pMsg) { void CFWL_ComboBox::OnMouseMove(CFWL_MessageMouse* pMsg) { int32_t iOldState = m_iBtnState; - if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtBtn.Contains(pMsg->m_pos)) { m_iBtnState = m_bLButtonDown ? CFWL_PartState_Pressed : CFWL_PartState_Hovered; } else { @@ -960,7 +950,7 @@ void CFWL_ComboBox::DisForm_OnProcessMessage(CFWL_Message* pMessage) { void CFWL_ComboBox::DisForm_OnLButtonDown(CFWL_MessageMouse* pMsg) { bool bDropDown = DisForm_IsDropListVisible(); CFX_RectF& rtBtn = bDropDown ? m_rtBtn : m_rtClient; - if (!rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + if (!rtBtn.Contains(pMsg->m_pos)) return; if (DisForm_IsDropListVisible()) { diff --git a/xfa/fwl/cfwl_combobox.h b/xfa/fwl/cfwl_combobox.h index d8db10dd2..168e20316 100644 --- a/xfa/fwl/cfwl_combobox.h +++ b/xfa/fwl/cfwl_combobox.h @@ -51,7 +51,7 @@ class CFWL_ComboBox : public CFWL_Widget { void SetStates(uint32_t dwStates) override; void RemoveStates(uint32_t dwStates) override; void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit HitTest(const CFX_PointF& point) override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; void OnProcessMessage(CFWL_Message* pMessage) override; @@ -135,7 +135,7 @@ class CFWL_ComboBox : public CFWL_Widget { void DisForm_ModifyStylesEx(uint32_t dwStylesExAdded, uint32_t dwStylesExRemoved); void DisForm_Update(); - FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy); + FWL_WidgetHit DisForm_HitTest(const CFX_PointF& point); void DisForm_DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix); CFX_RectF DisForm_GetBBox() const; void DisForm_Layout(); diff --git a/xfa/fwl/cfwl_comboboxproxy.cpp b/xfa/fwl/cfwl_comboboxproxy.cpp index 7bf311d19..0e2779b5c 100644 --- a/xfa/fwl/cfwl_comboboxproxy.cpp +++ b/xfa/fwl/cfwl_comboboxproxy.cpp @@ -70,11 +70,8 @@ void CFWL_ComboBoxProxy::OnLButtonDown(CFWL_Message* pMessage) { CFWL_NoteDriver* pDriver = static_cast<CFWL_NoteDriver*>(pApp->GetNoteDriver()); - CFX_RectF rtWidget = GetWidgetRect(); - rtWidget.left = rtWidget.top = 0; - CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); - if (rtWidget.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (CFX_RectF(0, 0, GetWidgetRect().Size()).Contains(pMsg->m_pos)) { m_bLButtonDown = true; pDriver->SetGrab(this, true); } else { @@ -99,9 +96,7 @@ void CFWL_ComboBoxProxy::OnLButtonUp(CFWL_Message* pMessage) { } CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); - CFX_RectF rect = GetWidgetRect(); - rect.left = rect.top = 0; - if (!rect.Contains(pMsg->m_fx, pMsg->m_fy) && + if (!CFX_RectF(0, 0, GetWidgetRect().Size()).Contains(pMsg->m_pos) && m_pComboBox->IsDropListVisible()) { m_pComboBox->ShowDropList(false); } diff --git a/xfa/fwl/cfwl_combolist.cpp b/xfa/fwl/cfwl_combolist.cpp index e78372cb2..5b700a90d 100644 --- a/xfa/fwl/cfwl_combolist.cpp +++ b/xfa/fwl/cfwl_combolist.cpp @@ -63,12 +63,11 @@ void CFWL_ComboList::ChangeSelected(int32_t iSel) { RepaintRect(rtInvalidate); } -void CFWL_ComboList::ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy) { - fx += m_pProperties->m_rtWidget.left, fy += m_pProperties->m_rtWidget.top; +CFX_PointF CFWL_ComboList::ClientToOuter(const CFX_PointF& point) { + CFX_PointF ret = point + CFX_PointF(m_pProperties->m_rtWidget.left, + m_pProperties->m_rtWidget.top); CFWL_Widget* pOwner = GetOwner(); - if (!pOwner) - return; - pOwner->TransformTo(m_pOuter, fx, fy); + return pOwner ? pOwner->TransformTo(m_pOuter, ret) : ret; } void CFWL_ComboList::OnProcessMessage(CFWL_Message* pMessage) { @@ -85,9 +84,8 @@ void CFWL_ComboList::OnProcessMessage(CFWL_Message* pMessage) { CFWL_ScrollBar* vertSB = GetVertScrollBar(); if (IsShowScrollBar(true) && vertSB) { CFX_RectF rect = vertSB->GetWidgetRect(); - if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) { - pMsg->m_fx -= rect.left; - pMsg->m_fy -= rect.top; + if (rect.Contains(pMsg->m_pos)) { + pMsg->m_pos -= rect.TopLeft(); vertSB->GetDelegate()->OnProcessMessage(pMsg); return; } @@ -131,31 +129,32 @@ void CFWL_ComboList::OnDropListFocusChanged(CFWL_Message* pMsg, bool bSet) { } void CFWL_ComboList::OnDropListMouseMove(CFWL_MessageMouse* pMsg) { - if (GetRTClient().Contains(pMsg->m_fx, pMsg->m_fy)) { + if (GetRTClient().Contains(pMsg->m_pos)) { if (m_bNotifyOwner) m_bNotifyOwner = false; CFWL_ScrollBar* vertSB = GetVertScrollBar(); if (IsShowScrollBar(true) && vertSB) { CFX_RectF rect = vertSB->GetWidgetRect(); - if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) + if (rect.Contains(pMsg->m_pos)) return; } - CFWL_ListItem* hItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); + CFWL_ListItem* hItem = GetItemAtPoint(pMsg->m_pos); if (!hItem) return; ChangeSelected(GetItemIndex(this, hItem)); } else if (m_bNotifyOwner) { - ClientToOuter(pMsg->m_fx, pMsg->m_fy); + pMsg->m_pos = ClientToOuter(pMsg->m_pos); + CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); pOuter->GetDelegate()->OnProcessMessage(pMsg); } } void CFWL_ComboList::OnDropListLButtonDown(CFWL_MessageMouse* pMsg) { - if (GetRTClient().Contains(pMsg->m_fx, pMsg->m_fy)) + if (GetRTClient().Contains(pMsg->m_pos)) return; CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); @@ -165,7 +164,7 @@ void CFWL_ComboList::OnDropListLButtonDown(CFWL_MessageMouse* pMsg) { void CFWL_ComboList::OnDropListLButtonUp(CFWL_MessageMouse* pMsg) { CFWL_ComboBox* pOuter = static_cast<CFWL_ComboBox*>(m_pOuter); if (m_bNotifyOwner) { - ClientToOuter(pMsg->m_fx, pMsg->m_fy); + pMsg->m_pos = ClientToOuter(pMsg->m_pos); pOuter->GetDelegate()->OnProcessMessage(pMsg); return; } @@ -173,12 +172,12 @@ void CFWL_ComboList::OnDropListLButtonUp(CFWL_MessageMouse* pMsg) { CFWL_ScrollBar* vertSB = GetVertScrollBar(); if (IsShowScrollBar(true) && vertSB) { CFX_RectF rect = vertSB->GetWidgetRect(); - if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) + if (rect.Contains(pMsg->m_pos)) return; } pOuter->ShowDropList(false); - CFWL_ListItem* hItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); + CFWL_ListItem* hItem = GetItemAtPoint(pMsg->m_pos); if (hItem) pOuter->ProcessSelChanged(true); } @@ -231,9 +230,8 @@ void CFWL_ComboList::OnDropListKeyDown(CFWL_MessageKey* pKey) { SetSelection(hItem, hItem, true); ScrollToVisible(hItem); - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); + CFX_RectF rtInvalidate(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); RepaintRect(rtInvalidate); break; } diff --git a/xfa/fwl/cfwl_combolist.h b/xfa/fwl/cfwl_combolist.h index e1d5fd9b2..b7ba6b578 100644 --- a/xfa/fwl/cfwl_combolist.h +++ b/xfa/fwl/cfwl_combolist.h @@ -29,7 +29,7 @@ class CFWL_ComboList : public CFWL_ListBox { void SetNotifyOwner(bool notify) { m_bNotifyOwner = notify; } private: - void ClientToOuter(FX_FLOAT& fx, FX_FLOAT& fy); + CFX_PointF ClientToOuter(const CFX_PointF& point); void OnDropListFocusChanged(CFWL_Message* pMsg, bool bSet); void OnDropListMouseMove(CFWL_MessageMouse* pMsg); void OnDropListLButtonDown(CFWL_MessageMouse* pMsg); diff --git a/xfa/fwl/cfwl_datetimeedit.h b/xfa/fwl/cfwl_datetimeedit.h index bde14ddf4..923ad05c9 100644 --- a/xfa/fwl/cfwl_datetimeedit.h +++ b/xfa/fwl/cfwl_datetimeedit.h @@ -12,7 +12,6 @@ #include "xfa/fwl/cfwl_edit.h" #include "xfa/fwl/cfwl_widget.h" #include "xfa/fwl/cfwl_widgetproperties.h" -#include "xfa/fwl/fwl_error.h" class CFWL_DateTimeEdit : public CFWL_Edit { public: diff --git a/xfa/fwl/cfwl_datetimepicker.cpp b/xfa/fwl/cfwl_datetimepicker.cpp index 861692f8e..a6ba65a3b 100644 --- a/xfa/fwl/cfwl_datetimepicker.cpp +++ b/xfa/fwl/cfwl_datetimepicker.cpp @@ -33,8 +33,6 @@ CFWL_DateTimePicker::CFWL_DateTimePicker(const CFWL_App* app) m_iMonth(-1), m_iDay(-1), m_bLBtnDown(false) { - m_rtBtn.Set(0, 0, 0, 0); - m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat; auto monthProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); @@ -45,9 +43,8 @@ CFWL_DateTimePicker::CFWL_DateTimePicker(const CFWL_App* app) m_pMonthCal.reset( new CFWL_MonthCalendar(m_pOwnerApp, std::move(monthProp), this)); - CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect(); - rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height); - m_pMonthCal->SetWidgetRect(rtMonthCal); + m_pMonthCal->SetWidgetRect( + CFX_RectF(0, 0, m_pMonthCal->GetAutosizedWidgetRect().Size())); auto editProp = pdfium::MakeUnique<CFWL_WidgetProperties>(); editProp->m_pParent = this; @@ -85,12 +82,11 @@ void CFWL_DateTimePicker::Update() { return; FX_FLOAT fBtn = theme->GetScrollBarWidth(); - m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1, - m_rtClient.height - 1); + m_rtBtn = CFX_RectF(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1, + m_rtClient.height - 1); - CFX_RectF rtEdit; - rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, - m_rtClient.height); + CFX_RectF rtEdit(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, + m_rtClient.height); m_pEdit->SetWidgetRect(rtEdit); ResetEditAlignment(); m_pEdit->Update(); @@ -98,22 +94,21 @@ void CFWL_DateTimePicker::Update() { m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider); CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect(); - CFX_RectF rtPopUp; - rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, - rtMonthCal.width, rtMonthCal.height); + CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, + rtMonthCal.width, rtMonthCal.height); m_pMonthCal->SetWidgetRect(rtPopUp); m_pMonthCal->Update(); return; } -FWL_WidgetHit CFWL_DateTimePicker::HitTest(FX_FLOAT fx, FX_FLOAT fy) { +FWL_WidgetHit CFWL_DateTimePicker::HitTest(const CFX_PointF& point) { if (m_pWidgetMgr->IsFormDisabled()) - return DisForm_HitTest(fx, fy); - if (m_rtClient.Contains(fx, fy)) + return DisForm_HitTest(point); + if (m_rtClient.Contains(point)) return FWL_WidgetHit::Client; if (IsMonthCalendarVisible()) { CFX_RectF rect = m_pMonthCal->GetWidgetRect(); - if (rect.Contains(fx, fy)) + if (rect.Contains(point)) return FWL_WidgetHit::Client; } return FWL_WidgetHit::Unknown; @@ -242,9 +237,8 @@ void CFWL_DateTimePicker::ShowMonthCalendar(bool bActivate) { CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect(); - CFX_RectF rtAnchor; - rtAnchor.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); + CFX_RectF rtAnchor(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth); m_pForm->SetWidgetRect(rtMonth); @@ -377,9 +371,8 @@ void CFWL_DateTimePicker::DisForm_ShowMonthCalendar(bool bActivate) { m_pEdit->GetDelegate()->OnProcessMessage(&msg); } - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); + CFX_RectF rtInvalidate(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); CFX_RectF rtCal = m_pMonthCal->GetWidgetRect(); rtInvalidate.Union(rtCal); @@ -387,19 +380,18 @@ void CFWL_DateTimePicker::DisForm_ShowMonthCalendar(bool bActivate) { RepaintRect(rtInvalidate); } -FWL_WidgetHit CFWL_DateTimePicker::DisForm_HitTest(FX_FLOAT fx, - FX_FLOAT fy) const { - CFX_RectF rect; - rect.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); - if (rect.Contains(fx, fy)) +FWL_WidgetHit CFWL_DateTimePicker::DisForm_HitTest( + const CFX_PointF& point) const { + CFX_RectF rect(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); + if (rect.Contains(point)) return FWL_WidgetHit::Edit; if (DisForm_IsNeedShowButton()) rect.width += m_fBtn; - if (rect.Contains(fx, fy)) + if (rect.Contains(point)) return FWL_WidgetHit::Client; if (IsMonthCalendarVisible()) { - if (m_pMonthCal->GetWidgetRect().Contains(fx, fy)) + if (m_pMonthCal->GetWidgetRect().Contains(point)) return FWL_WidgetHit::Client; } return FWL_WidgetHit::Unknown; @@ -432,9 +424,8 @@ void CFWL_DateTimePicker::DisForm_Update() { m_fBtn = theme->GetScrollBarWidth(); CFX_RectF rtMonthCal = m_pMonthCal->GetAutosizedWidgetRect(); - CFX_RectF rtPopUp; - rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, - rtMonthCal.width, rtMonthCal.height); + CFX_RectF rtPopUp(rtMonthCal.left, rtMonthCal.top + kDateTimePickerHeight, + rtMonthCal.width, rtMonthCal.height); m_pMonthCal->SetWidgetRect(rtPopUp); m_pMonthCal->Update(); } @@ -459,8 +450,7 @@ void CFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics, if (m_pEdit) { CFX_RectF rtEdit = m_pEdit->GetWidgetRect(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top); + CFX_Matrix mt(1, 0, 0, 1, rtEdit.left, rtEdit.top); if (pMatrix) mt.Concat(*pMatrix); m_pEdit->DrawWidget(pGraphics, &mt); @@ -469,8 +459,7 @@ void CFWL_DateTimePicker::DisForm_DrawWidget(CFX_Graphics* pGraphics, return; CFX_RectF rtMonth = m_pMonthCal->GetWidgetRect(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtMonth.left, rtMonth.top); + CFX_Matrix mt(1, 0, 0, 1, rtMonth.left, rtMonth.top); if (pMatrix) mt.Concat(*pMatrix); m_pMonthCal->DrawWidget(pGraphics, &mt); @@ -550,7 +539,7 @@ void CFWL_DateTimePicker::OnLButtonDown(CFWL_MessageMouse* pMsg) { return; if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) SetFocus(true); - if (!m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + if (!m_rtBtn.Contains(pMsg->m_pos)) return; if (IsMonthCalendarVisible()) { @@ -568,7 +557,7 @@ void CFWL_DateTimePicker::OnLButtonUp(CFWL_MessageMouse* pMsg) { return; m_bLBtnDown = false; - if (m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + if (m_rtBtn.Contains(pMsg->m_pos)) m_iBtnState = CFWL_PartState_Hovered; else m_iBtnState = CFWL_PartState_Normal; @@ -576,7 +565,7 @@ void CFWL_DateTimePicker::OnLButtonUp(CFWL_MessageMouse* pMsg) { } void CFWL_DateTimePicker::OnMouseMove(CFWL_MessageMouse* pMsg) { - if (!m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) + if (!m_rtBtn.Contains(pMsg->m_pos)) m_iBtnState = CFWL_PartState_Normal; RepaintRect(m_rtBtn); } @@ -594,15 +583,16 @@ void CFWL_DateTimePicker::DisForm_OnFocusChanged(CFWL_Message* pMsg, if (bSet) { m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; if (m_pEdit && !(m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) { - m_rtBtn.Set(m_pProperties->m_rtWidget.width, 0, m_fBtn, - m_pProperties->m_rtWidget.height - 1); + m_rtBtn = CFX_RectF(m_pProperties->m_rtWidget.width, 0, m_fBtn, + m_pProperties->m_rtWidget.height - 1); } rtInvalidate = m_rtBtn; pMsg->m_pDstTarget = m_pEdit.get(); m_pEdit->GetDelegate()->OnProcessMessage(pMsg); } else { m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; - m_rtBtn.Set(0, 0, 0, 0); + m_rtBtn.Reset(); + if (DisForm_IsMonthCalendarVisible()) ShowMonthCalendar(false); if (m_pEdit->GetStates() & FWL_WGTSTATE_Focused) { diff --git a/xfa/fwl/cfwl_datetimepicker.h b/xfa/fwl/cfwl_datetimepicker.h index 47d1c70fc..2935ee8b1 100644 --- a/xfa/fwl/cfwl_datetimepicker.h +++ b/xfa/fwl/cfwl_datetimepicker.h @@ -38,7 +38,7 @@ class CFWL_DateTimePicker : public CFWL_Widget { // CFWL_Widget FWL_Type GetClassID() const override; void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit HitTest(const CFX_PointF& point) override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; void SetThemeProvider(IFWL_ThemeProvider* pTP) override; void OnProcessMessage(CFWL_Message* pMessage) override; @@ -84,7 +84,7 @@ class CFWL_DateTimePicker : public CFWL_Widget { bool DisForm_IsMonthCalendarVisible() const; void DisForm_ShowMonthCalendar(bool bActivate); - FWL_WidgetHit DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy) const; + FWL_WidgetHit DisForm_HitTest(const CFX_PointF& point) const; bool DisForm_IsNeedShowButton() const; void DisForm_Update(); CFX_RectF DisForm_GetBBox() const; diff --git a/xfa/fwl/cfwl_edit.cpp b/xfa/fwl/cfwl_edit.cpp index acd567222..d36e28ab5 100644 --- a/xfa/fwl/cfwl_edit.cpp +++ b/xfa/fwl/cfwl_edit.cpp @@ -49,10 +49,10 @@ void AddSquigglyPath(CFX_Path* pPathData, FX_FLOAT fEndX, FX_FLOAT fY, FX_FLOAT fStep) { - pPathData->MoveTo(fStartX, fY); + pPathData->MoveTo(CFX_PointF(fStartX, fY)); int i = 1; for (FX_FLOAT fx = fStartX + fStep; fx < fEndX; fx += fStep, ++i) - pPathData->LineTo(fx, fY + (i & 1) * fStep); + pPathData->LineTo(CFX_PointF(fx, fY + (i & 1) * fStep)); } } // namespace @@ -112,7 +112,7 @@ CFX_RectF CFWL_Edit::GetAutosizedWidgetRect() { CFX_SizeF sz = CalcTextSize( m_EdtEngine.GetText(0, -1), m_pProperties->m_pThemeProvider, !!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine)); - rect.Set(0, 0, sz.x, sz.y); + rect = CFX_RectF(0, 0, sz); } InflateWidgetRect(rect); return rect; @@ -142,18 +142,18 @@ void CFWL_Edit::Update() { InitCaret(); } -FWL_WidgetHit CFWL_Edit::HitTest(FX_FLOAT fx, FX_FLOAT fy) { +FWL_WidgetHit CFWL_Edit::HitTest(const CFX_PointF& point) { if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { if (IsShowScrollBar(true)) { - if (m_pVertScrollBar->GetWidgetRect().Contains(fx, fy)) + if (m_pVertScrollBar->GetWidgetRect().Contains(point)) return FWL_WidgetHit::VScrollBar; } if (IsShowScrollBar(false)) { - if (m_pHorzScrollBar->GetWidgetRect().Contains(fx, fy)) + if (m_pHorzScrollBar->GetWidgetRect().Contains(point)) return FWL_WidgetHit::HScrollBar; } } - if (m_rtClient.Contains(fx, fy)) + if (m_rtClient.Contains(point)) return FWL_WidgetHit::Edit; return FWL_WidgetHit::Unknown; } @@ -168,15 +168,14 @@ void CFWL_Edit::AddSpellCheckObj(CFX_Path& PathData, FX_FLOAT fY = 0.0f; FX_FLOAT fStep = 0.0f; IFDE_TxtEdtPage* pPage = m_EdtEngine.GetPage(0); - CFX_RectFArray rectArray; - CFX_RectF rectText; const FDE_TXTEDTPARAMS* txtEdtParams = m_EdtEngine.GetEditParams(); FX_FLOAT fAsent = static_cast<FX_FLOAT>(txtEdtParams->pFont->GetAscent()) * txtEdtParams->fFontSize / 1000; - pPage->CalcRangeRectArray(nStart, nCount, rectArray); - for (int i = 0; i < rectArray.GetSize(); i++) { - rectText = rectArray.GetAt(i); + std::vector<CFX_RectF> rectArray; + pPage->CalcRangeRectArray(nStart, nCount, &rectArray); + + for (const auto& rectText : rectArray) { fY = rectText.top + fAsent + fOffSetY; fStep = txtEdtParams->fFontSize / 16.0f; fStartX = rectText.left + fOffSetX; @@ -193,15 +192,11 @@ void CFWL_Edit::DrawSpellCheck(CFX_Graphics* pGraphics, CFX_Color crLine(0xFFFF0000); CFWL_EventCheckWord checkWordEvent(this); - CFX_ByteString sLatinWord; CFX_Path pathSpell; - pathSpell.Create(); - int32_t nStart = 0; FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; - CFX_WideString wsSpell = GetText(); int32_t nContentLen = wsSpell.GetLength(); for (int i = 0; i < nContentLen; i++) { @@ -232,8 +227,7 @@ void CFWL_Edit::DrawSpellCheck(CFX_Graphics* pGraphics, } if (!pathSpell.IsEmpty()) { CFX_RectF rtClip = m_rtEngine; - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); + CFX_Matrix mt(1, 0, 0, 1, fOffSetX, fOffSetY); if (pMatrix) { pMatrix->TransformRect(rtClip); mt.Concat(*pMatrix); @@ -409,7 +403,6 @@ void CFWL_Edit::OnCaretChanged() { bool bRepaintContent = UpdateOffset(); UpdateCaret(); CFX_RectF rtInvalid; - rtInvalid.Set(0, 0, 0, 0); bool bRepaintScroll = false; if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { CFWL_ScrollBar* pScroll = UpdateScroll(); @@ -502,10 +495,9 @@ void CFWL_Edit::DrawTextBk(CFX_Graphics* pGraphics, CFX_RectF rtScroll = m_pHorzScrollBar->GetWidgetRect(); - CFX_RectF rtStatic; - rtStatic.Set(m_rtClient.right() - rtScroll.height, - m_rtClient.bottom() - rtScroll.height, rtScroll.height, - rtScroll.height); + CFX_RectF rtStatic(m_rtClient.right() - rtScroll.height, + m_rtClient.bottom() - rtScroll.height, rtScroll.height, + rtScroll.height); param.m_bStaticBackground = true; param.m_bMaximize = true; param.m_rtPart = rtStatic; @@ -526,8 +518,7 @@ void CFWL_Edit::DrawContent(CFX_Graphics* pGraphics, CFX_RectF rtClip = m_rtEngine; FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); + CFX_Matrix mt(1, 0, 0, 1, fOffSetX, fOffSetY); if (pMatrix) { pMatrix->TransformRect(rtClip); mt.Concat(*pMatrix); @@ -541,9 +532,8 @@ void CFWL_Edit::DrawContent(CFX_Graphics* pGraphics, int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1; int32_t nCharCount; int32_t nCharStart; - CFX_RectFArray rectArr; - int32_t i = 0; - for (i = 0; i < nSelCount; i++) { + std::vector<CFX_RectF> rectArr; + for (int32_t i = 0; i < nSelCount; i++) { nCharCount = m_EdtEngine.GetSelRange(i, &nCharStart); int32_t nCharEnd = nCharStart + nCharCount - 1; if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) @@ -552,17 +542,14 @@ void CFWL_Edit::DrawContent(CFX_Graphics* pGraphics, int32_t nBgn = std::max(nCharStart, nPageCharStart); int32_t nEnd = std::min(nCharEnd, nPageCharEnd); pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1, - rectArr); + &rectArr); } - int32_t nCount = rectArr.GetSize(); CFX_Path path; - path.Create(); - for (i = 0; i < nCount; i++) { - rectArr[i].left += fOffSetX; - rectArr[i].top += fOffSetY; - path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width, - rectArr[i].height); + for (auto& rect : rectArr) { + rect.left += fOffSetX; + rect.top += fOffSetY; + path.AddRectangle(rect.left, rect.top, rect.width, rect.height); } pGraphics->SetClipRect(rtClip); @@ -589,13 +576,13 @@ void CFWL_Edit::DrawContent(CFX_Graphics* pGraphics, if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) { pGraphics->RestoreGraphState(); CFX_Path path; - path.Create(); int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1; FX_FLOAT fStep = m_rtEngine.width / iLimit; FX_FLOAT fLeft = m_rtEngine.left + 1; for (int32_t i = 1; i < iLimit; i++) { fLeft += fStep; - path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom()); + path.AddLine(CFX_PointF(fLeft, m_rtClient.top), + CFX_PointF(fLeft, m_rtClient.bottom())); } CFWL_ThemeBackground param; @@ -786,8 +773,8 @@ void CFWL_Edit::UpdateVAlignment() { part.m_pWidget = this; CFX_SizeF pSpace = theme->GetSpaceAboveBelow(&part); - fSpaceAbove = pSpace.x; - fSpaceBelow = pSpace.y; + fSpaceAbove = pSpace.width; + fSpaceBelow = pSpace.height; } if (fSpaceAbove < 0.1f) fSpaceAbove = 0; @@ -816,8 +803,7 @@ void CFWL_Edit::UpdateCaret() { rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX, m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset); - CFX_RectF rtCaret; - rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height); + CFX_RectF rtCaret(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height); CFX_RectF rtClient = GetClientRect(); rtCaret.Intersect(rtClient); @@ -970,11 +956,11 @@ void CFWL_Edit::Layout() { CFX_RectF rtVertScr; if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtVertScr.Set(m_rtClient.right() + kEditMargin, m_rtClient.top, fWidth, - m_rtClient.height); + rtVertScr = CFX_RectF(m_rtClient.right() + kEditMargin, m_rtClient.top, + fWidth, m_rtClient.height); } else { - rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, - m_rtClient.height); + rtVertScr = CFX_RectF(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, + m_rtClient.height); if (bShowHorzScrollbar) rtVertScr.height -= fWidth; m_rtEngine.width -= fWidth; @@ -992,11 +978,11 @@ void CFWL_Edit::Layout() { CFX_RectF rtHoriScr; if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + kEditMargin, - m_rtClient.width, fWidth); + rtHoriScr = CFX_RectF(m_rtClient.left, m_rtClient.bottom() + kEditMargin, + m_rtClient.width, fWidth); } else { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, - m_rtClient.width, fWidth); + rtHoriScr = CFX_RectF(m_rtClient.left, m_rtClient.bottom() - fWidth, + m_rtClient.width, fWidth); if (bShowVertScrollbar) rtHoriScr.width -= fWidth; m_rtEngine.height -= fWidth; @@ -1025,11 +1011,11 @@ void CFWL_Edit::LayoutScrollBar() { InitVerticalScrollBar(); CFX_RectF rtVertScr; if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtVertScr.Set(m_rtClient.right() + kEditMargin, m_rtClient.top, fWidth, - m_rtClient.height); + rtVertScr = CFX_RectF(m_rtClient.right() + kEditMargin, m_rtClient.top, + fWidth, m_rtClient.height); } else { - rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, - m_rtClient.height); + rtVertScr = CFX_RectF(m_rtClient.right() - fWidth, m_rtClient.top, + fWidth, m_rtClient.height); if (bShowHorzScrollbar) rtVertScr.height -= fWidth; } @@ -1046,11 +1032,12 @@ void CFWL_Edit::LayoutScrollBar() { InitHorizontalScrollBar(); CFX_RectF rtHoriScr; if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + kEditMargin, + rtHoriScr = + CFX_RectF(m_rtClient.left, m_rtClient.bottom() + kEditMargin, m_rtClient.width, fWidth); } else { - rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, - m_rtClient.width, fWidth); + rtHoriScr = CFX_RectF(m_rtClient.left, m_rtClient.bottom() - fWidth, + m_rtClient.width, fWidth); if (bShowVertScrollbar) rtHoriScr.width -= (fWidth); } @@ -1065,9 +1052,9 @@ void CFWL_Edit::LayoutScrollBar() { UpdateScroll(); } -void CFWL_Edit::DeviceToEngine(CFX_PointF& pt) { - pt.x += m_fScrollOffsetX - m_rtEngine.left; - pt.y += m_fScrollOffsetY - m_rtEngine.top - m_fVAlignOffset; +CFX_PointF CFWL_Edit::DeviceToEngine(const CFX_PointF& pt) { + return pt + CFX_PointF(m_fScrollOffsetX - m_rtEngine.left, + m_fScrollOffsetY - m_rtEngine.top - m_fVAlignOffset); } void CFWL_Edit::InitVerticalScrollBar() { @@ -1123,11 +1110,8 @@ void CFWL_Edit::ShowCaret(CFX_RectF* pRect) { if (!pDocEnvironment) return; - CFX_Matrix mt; - pXFAWidget->GetRotateMatrix(mt); - CFX_RectF rt(*pRect); - mt.TransformRect(rt); + pXFAWidget->GetRotateMatrix().TransformRect(rt); pDocEnvironment->DisplayCaret(pXFAWidget, true, &rt); } @@ -1279,10 +1263,8 @@ void CFWL_Edit::DoButtonDown(CFWL_MessageMouse* pMsg) { if (!pPage) return; - CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); - DeviceToEngine(pt); bool bBefore = true; - int32_t nIndex = pPage->GetCharIndex(pt, bBefore); + int32_t nIndex = pPage->GetCharIndex(DeviceToEngine(pMsg->m_pos), bBefore); if (nIndex < 0) nIndex = 0; @@ -1316,9 +1298,8 @@ void CFWL_Edit::OnFocusChanged(CFWL_Message* pMsg, bool bSet) { if (!bRepaint) return; - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); + CFX_RectF rtInvalidate(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); RepaintRect(rtInvalidate); } @@ -1358,10 +1339,8 @@ void CFWL_Edit::OnButtonDblClk(CFWL_MessageMouse* pMsg) { if (!pPage) return; - CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); - DeviceToEngine(pt); int32_t nCount = 0; - int32_t nIndex = pPage->SelectWord(pt, nCount); + int32_t nIndex = pPage->SelectWord(DeviceToEngine(pMsg->m_pos), nCount); if (nIndex < 0) return; @@ -1378,10 +1357,8 @@ void CFWL_Edit::OnMouseMove(CFWL_MessageMouse* pMsg) { if (!pPage) return; - CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); - DeviceToEngine(pt); bool bBefore = true; - int32_t nIndex = pPage->GetCharIndex(pt, bBefore); + int32_t nIndex = pPage->GetCharIndex(DeviceToEngine(pMsg->m_pos), bBefore); m_EdtEngine.SetCaretPos(nIndex, bBefore); nIndex = m_EdtEngine.GetCaretPos(); m_EdtEngine.ClearSelection(); @@ -1509,43 +1486,43 @@ bool CFWL_Edit::OnScroll(CFWL_ScrollBar* pScrollBar, CFWL_EventScroll::Code dwCode, FX_FLOAT fPos) { CFX_SizeF fs; - pScrollBar->GetRange(&fs.x, &fs.y); + pScrollBar->GetRange(&fs.width, &fs.height); FX_FLOAT iCurPos = pScrollBar->GetPos(); FX_FLOAT fStep = pScrollBar->GetStepSize(); switch (dwCode) { case CFWL_EventScroll::Code::Min: { - fPos = fs.x; + fPos = fs.width; break; } case CFWL_EventScroll::Code::Max: { - fPos = fs.y; + fPos = fs.height; break; } case CFWL_EventScroll::Code::StepBackward: { fPos -= fStep; - if (fPos < fs.x + fStep / 2) { - fPos = fs.x; + if (fPos < fs.width + fStep / 2) { + fPos = fs.width; } break; } case CFWL_EventScroll::Code::StepForward: { fPos += fStep; - if (fPos > fs.y - fStep / 2) { - fPos = fs.y; + if (fPos > fs.height - fStep / 2) { + fPos = fs.height; } break; } case CFWL_EventScroll::Code::PageBackward: { fPos -= pScrollBar->GetPageSize(); - if (fPos < fs.x) { - fPos = fs.x; + if (fPos < fs.width) { + fPos = fs.width; } break; } case CFWL_EventScroll::Code::PageForward: { fPos += pScrollBar->GetPageSize(); - if (fPos > fs.y) { - fPos = fs.y; + if (fPos > fs.height) { + fPos = fs.height; } break; } @@ -1565,8 +1542,6 @@ bool CFWL_Edit::OnScroll(CFWL_ScrollBar* pScrollBar, UpdateCaret(); CFX_RectF rect = GetWidgetRect(); - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2); - RepaintRect(rtInvalidate); + RepaintRect(CFX_RectF(0, 0, rect.width + 2, rect.height + 2)); return true; } diff --git a/xfa/fwl/cfwl_edit.h b/xfa/fwl/cfwl_edit.h index 4193e735f..154e28633 100644 --- a/xfa/fwl/cfwl_edit.h +++ b/xfa/fwl/cfwl_edit.h @@ -59,7 +59,7 @@ class CFWL_Edit : public CFWL_Widget { CFX_RectF GetAutosizedWidgetRect() override; CFX_RectF GetWidgetRect() override; void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit HitTest(const CFX_PointF& point) override; void SetStates(uint32_t dwStates) override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; @@ -127,7 +127,7 @@ class CFWL_Edit : public CFWL_Widget { CFWL_ScrollBar* UpdateScroll(); void Layout(); void LayoutScrollBar(); - void DeviceToEngine(CFX_PointF& pt); + CFX_PointF DeviceToEngine(const CFX_PointF& pt); void InitVerticalScrollBar(); void InitHorizontalScrollBar(); void InitEngine(); diff --git a/xfa/fwl/cfwl_event.h b/xfa/fwl/cfwl_event.h index 9a9f30ab4..e326ab32c 100644 --- a/xfa/fwl/cfwl_event.h +++ b/xfa/fwl/cfwl_event.h @@ -12,7 +12,6 @@ #include "core/fxcrt/fx_system.h" #include "xfa/fwl/cfwl_messagekey.h" #include "xfa/fwl/cfwl_messagemouse.h" -#include "xfa/fwl/fwl_error.h" class CFX_Graphics; class CFWL_Widget; diff --git a/xfa/fwl/cfwl_form.cpp b/xfa/fwl/cfwl_form.cpp index d0d6ef211..5e956ade2 100644 --- a/xfa/fwl/cfwl_form.cpp +++ b/xfa/fwl/cfwl_form.cpp @@ -67,13 +67,12 @@ void CFWL_Form::Update() { Layout(); } -FWL_WidgetHit CFWL_Form::HitTest(FX_FLOAT fx, FX_FLOAT fy) { +FWL_WidgetHit CFWL_Form::HitTest(const CFX_PointF& point) { GetAvailableTheme(); - CFX_RectF rtCap; - rtCap.Set(m_fCYBorder, m_fCXBorder, -2 * m_fCYBorder, 0 - m_fCXBorder); - return rtCap.Contains(fx, fy) ? FWL_WidgetHit::Titlebar - : FWL_WidgetHit::Client; + CFX_RectF rtCap(m_fCYBorder, m_fCXBorder, -2 * m_fCYBorder, 0 - m_fCXBorder); + return rtCap.Contains(point) ? FWL_WidgetHit::Titlebar + : FWL_WidgetHit::Client; } void CFWL_Form::DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { diff --git a/xfa/fwl/cfwl_form.h b/xfa/fwl/cfwl_form.h index 4297fde86..7202cb279 100644 --- a/xfa/fwl/cfwl_form.h +++ b/xfa/fwl/cfwl_form.h @@ -37,7 +37,7 @@ class CFWL_Form : public CFWL_Widget { bool IsInstance(const CFX_WideStringC& wsClass) const override; CFX_RectF GetClientRect() override; void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit HitTest(const CFX_PointF& point) override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; void OnProcessMessage(CFWL_Message* pMessage) override; void OnDrawWidget(CFX_Graphics* pGraphics, diff --git a/xfa/fwl/cfwl_listbox.cpp b/xfa/fwl/cfwl_listbox.cpp index a7a568cd1..0b8270997 100644 --- a/xfa/fwl/cfwl_listbox.cpp +++ b/xfa/fwl/cfwl_listbox.cpp @@ -75,18 +75,18 @@ void CFWL_ListBox::Update() { CalcSize(false); } -FWL_WidgetHit CFWL_ListBox::HitTest(FX_FLOAT fx, FX_FLOAT fy) { +FWL_WidgetHit CFWL_ListBox::HitTest(const CFX_PointF& point) { if (IsShowScrollBar(false)) { CFX_RectF rect = m_pHorzScrollBar->GetWidgetRect(); - if (rect.Contains(fx, fy)) + if (rect.Contains(point)) return FWL_WidgetHit::HScrollBar; } if (IsShowScrollBar(true)) { CFX_RectF rect = m_pVertScrollBar->GetWidgetRect(); - if (rect.Contains(fx, fy)) + if (rect.Contains(point)) return FWL_WidgetHit::VScrollBar; } - if (m_rtClient.Contains(fx, fy)) + if (m_rtClient.Contains(point)) return FWL_WidgetHit::Client; return FWL_WidgetHit::Unknown; } @@ -304,8 +304,8 @@ void CFWL_ListBox::SetFocusItem(CFWL_ListItem* pItem) { } } -CFWL_ListItem* CFWL_ListBox::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy) { - fx -= m_rtConent.left, fy -= m_rtConent.top; +CFWL_ListItem* CFWL_ListBox::GetItemAtPoint(const CFX_PointF& point) { + CFX_PointF pos = point - m_rtConent.TopLeft(); FX_FLOAT fPosX = 0.0f; if (m_pHorzScrollBar) fPosX = m_pHorzScrollBar->GetPos(); @@ -322,7 +322,7 @@ CFWL_ListItem* CFWL_ListBox::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy) { CFX_RectF rtItem = pItem->GetRect(); rtItem.Offset(-fPosX, -fPosY); - if (rtItem.Contains(fx, fy)) + if (rtItem.Contains(pos)) return pItem; } return nullptr; @@ -475,7 +475,6 @@ CFX_SizeF CFWL_ListBox::CalcSize(bool bAutoSize) { m_rtClient = GetClientRect(); m_rtConent = m_rtClient; CFX_RectF rtUIMargin; - rtUIMargin.Set(0, 0, 0, 0); if (!m_pOuter) { CFWL_ThemePart part; part.m_pWidget = this; @@ -507,29 +506,29 @@ CFX_SizeF CFWL_ListBox::CalcSize(bool bAutoSize) { bool bShowVertScr = false; bool bShowHorzScr = false; if (!bShowVertScr && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll)) - bShowVertScr = (fs.y > iHeight); + bShowVertScr = (fs.height > iHeight); CFX_SizeF szRange; if (bShowVertScr) { if (!m_pVertScrollBar) InitVerticalScrollBar(); - CFX_RectF rtScrollBar; - rtScrollBar.Set(m_rtClient.right() - m_fScorllBarWidth, m_rtClient.top, - m_fScorllBarWidth, m_rtClient.height - 1); + CFX_RectF rtScrollBar(m_rtClient.right() - m_fScorllBarWidth, + m_rtClient.top, m_fScorllBarWidth, + m_rtClient.height - 1); if (bShowHorzScr) rtScrollBar.height -= m_fScorllBarWidth; m_pVertScrollBar->SetWidgetRect(rtScrollBar); - szRange.x = 0, szRange.y = fs.y - m_rtConent.height; - szRange.y = std::max(szRange.y, m_fItemHeight); + szRange.width = 0; + szRange.height = std::max(fs.height - m_rtConent.height, m_fItemHeight); - m_pVertScrollBar->SetRange(szRange.x, szRange.y); + m_pVertScrollBar->SetRange(szRange.width, szRange.height); m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10); m_pVertScrollBar->SetStepSize(m_fItemHeight); FX_FLOAT fPos = - std::min(std::max(m_pVertScrollBar->GetPos(), 0.f), szRange.y); + std::min(std::max(m_pVertScrollBar->GetPos(), 0.f), szRange.height); m_pVertScrollBar->SetPos(fPos); m_pVertScrollBar->SetTrackPos(fPos); if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == @@ -547,20 +546,21 @@ CFX_SizeF CFWL_ListBox::CalcSize(bool bAutoSize) { if (!m_pHorzScrollBar) InitHorizontalScrollBar(); - CFX_RectF rtScrollBar; - rtScrollBar.Set(m_rtClient.left, m_rtClient.bottom() - m_fScorllBarWidth, - m_rtClient.width, m_fScorllBarWidth); + CFX_RectF rtScrollBar(m_rtClient.left, + m_rtClient.bottom() - m_fScorllBarWidth, + m_rtClient.width, m_fScorllBarWidth); if (bShowVertScr) rtScrollBar.width -= m_fScorllBarWidth; m_pHorzScrollBar->SetWidgetRect(rtScrollBar); - szRange.x = 0, szRange.y = fs.x - rtScrollBar.width; - m_pHorzScrollBar->SetRange(szRange.x, szRange.y); + szRange.width = 0; + szRange.height = fs.width - rtScrollBar.width; + m_pHorzScrollBar->SetRange(szRange.width, szRange.height); m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10); m_pHorzScrollBar->SetStepSize(fWidth / 10); FX_FLOAT fPos = - std::min(std::max(m_pHorzScrollBar->GetPos(), 0.f), szRange.y); + std::min(std::max(m_pHorzScrollBar->GetPos(), 0.f), szRange.height); m_pHorzScrollBar->SetPos(fPos); m_pHorzScrollBar->SetTrackPos(fPos); if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == @@ -575,9 +575,9 @@ CFX_SizeF CFWL_ListBox::CalcSize(bool bAutoSize) { m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible); } if (bShowVertScr && bShowHorzScr) { - m_rtStatic.Set(m_rtClient.right() - m_fScorllBarWidth, - m_rtClient.bottom() - m_fScorllBarWidth, m_fScorllBarWidth, - m_fScorllBarWidth); + m_rtStatic = CFX_RectF(m_rtClient.right() - m_fScorllBarWidth, + m_rtClient.bottom() - m_fScorllBarWidth, + m_fScorllBarWidth, m_fScorllBarWidth); } return fs; } @@ -588,12 +588,11 @@ void CFWL_ListBox::UpdateItemSize(CFWL_ListItem* pItem, FX_FLOAT fItemHeight, bool bAutoSize) const { if (!bAutoSize && pItem) { - CFX_RectF rtItem; - rtItem.Set(0, size.y, fWidth, fItemHeight); + CFX_RectF rtItem(0, size.height, fWidth, fItemHeight); pItem->SetRect(rtItem); } - size.x = fWidth; - size.y += fItemHeight; + size.width = fWidth; + size.height += fItemHeight; } FX_FLOAT CFWL_ListBox::GetMaxTextWidth() { @@ -606,7 +605,7 @@ FX_FLOAT CFWL_ListBox::GetMaxTextWidth() { CFX_SizeF sz = CalcTextSize(pItem->GetText(), m_pProperties->m_pThemeProvider, false); - fRet = std::max(fRet, sz.x); + fRet = std::max(fRet, sz.width); } return fRet; } @@ -749,7 +748,7 @@ void CFWL_ListBox::OnLButtonDown(CFWL_MessageMouse* pMsg) { if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) SetFocus(true); - CFWL_ListItem* pItem = GetItemAtPoint(pMsg->m_fx, pMsg->m_fy); + CFWL_ListItem* pItem = GetItemAtPoint(pMsg->m_pos); if (!pItem) return; @@ -833,50 +832,48 @@ void CFWL_ListBox::OnVK(CFWL_ListItem* pItem, bool bShift, bool bCtrl) { SetFocusItem(pItem); ScrollToVisible(pItem); - CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, m_pProperties->m_rtWidget.width, - m_pProperties->m_rtWidget.height); - RepaintRect(rtInvalidate); + RepaintRect(CFX_RectF(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height)); } bool CFWL_ListBox::OnScroll(CFWL_ScrollBar* pScrollBar, CFWL_EventScroll::Code dwCode, FX_FLOAT fPos) { CFX_SizeF fs; - pScrollBar->GetRange(&fs.x, &fs.y); + pScrollBar->GetRange(&fs.width, &fs.height); FX_FLOAT iCurPos = pScrollBar->GetPos(); FX_FLOAT fStep = pScrollBar->GetStepSize(); switch (dwCode) { case CFWL_EventScroll::Code::Min: { - fPos = fs.x; + fPos = fs.width; break; } case CFWL_EventScroll::Code::Max: { - fPos = fs.y; + fPos = fs.height; break; } case CFWL_EventScroll::Code::StepBackward: { fPos -= fStep; - if (fPos < fs.x + fStep / 2) - fPos = fs.x; + if (fPos < fs.width + fStep / 2) + fPos = fs.width; break; } case CFWL_EventScroll::Code::StepForward: { fPos += fStep; - if (fPos > fs.y - fStep / 2) - fPos = fs.y; + if (fPos > fs.height - fStep / 2) + fPos = fs.height; break; } case CFWL_EventScroll::Code::PageBackward: { fPos -= pScrollBar->GetPageSize(); - if (fPos < fs.x) - fPos = fs.x; + if (fPos < fs.width) + fPos = fs.width; break; } case CFWL_EventScroll::Code::PageForward: { fPos += pScrollBar->GetPageSize(); - if (fPos > fs.y) - fPos = fs.y; + if (fPos > fs.height) + fPos = fs.height; break; } case CFWL_EventScroll::Code::Pos: diff --git a/xfa/fwl/cfwl_listbox.h b/xfa/fwl/cfwl_listbox.h index 95d8ad990..caa4f509f 100644 --- a/xfa/fwl/cfwl_listbox.h +++ b/xfa/fwl/cfwl_listbox.h @@ -41,7 +41,7 @@ class CFWL_ListBox : public CFWL_Widget { // CFWL_Widget FWL_Type GetClassID() const override; void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit HitTest(const CFX_PointF& point) override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) override; void OnProcessMessage(CFWL_Message* pMessage) override; @@ -69,7 +69,7 @@ class CFWL_ListBox : public CFWL_Widget { protected: CFWL_ListItem* GetListItem(CFWL_ListItem* hItem, uint32_t dwKeyCode); void SetSelection(CFWL_ListItem* hStart, CFWL_ListItem* hEnd, bool bSelected); - CFWL_ListItem* GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy); + CFWL_ListItem* GetItemAtPoint(const CFX_PointF& point); bool ScrollToVisible(CFWL_ListItem* hItem); void InitVerticalScrollBar(); void InitHorizontalScrollBar(); diff --git a/xfa/fwl/cfwl_message.h b/xfa/fwl/cfwl_message.h index 67e1f05cd..778e1e207 100644 --- a/xfa/fwl/cfwl_message.h +++ b/xfa/fwl/cfwl_message.h @@ -12,7 +12,6 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" -#include "xfa/fwl/fwl_error.h" class CFWL_Widget; diff --git a/xfa/fwl/cfwl_messagemouse.cpp b/xfa/fwl/cfwl_messagemouse.cpp index 110292a1d..1d56b0f17 100644 --- a/xfa/fwl/cfwl_messagemouse.cpp +++ b/xfa/fwl/cfwl_messagemouse.cpp @@ -14,6 +14,8 @@ CFWL_MessageMouse::CFWL_MessageMouse(CFWL_Widget* pSrcTarget, CFWL_Widget* pDstTarget) : CFWL_Message(CFWL_Message::Type::Mouse, pSrcTarget, pDstTarget) {} +CFWL_MessageMouse::CFWL_MessageMouse(const CFWL_MessageMouse& other) = default; + CFWL_MessageMouse::~CFWL_MessageMouse() {} std::unique_ptr<CFWL_Message> CFWL_MessageMouse::Clone() { diff --git a/xfa/fwl/cfwl_messagemouse.h b/xfa/fwl/cfwl_messagemouse.h index ac45745df..a2b0d39ae 100644 --- a/xfa/fwl/cfwl_messagemouse.h +++ b/xfa/fwl/cfwl_messagemouse.h @@ -9,6 +9,7 @@ #include <memory> +#include "core/fxcrt/fx_coordinates.h" #include "xfa/fwl/cfwl_message.h" enum class FWL_MouseCommand { @@ -27,13 +28,13 @@ enum class FWL_MouseCommand { class CFWL_MessageMouse : public CFWL_Message { public: CFWL_MessageMouse(CFWL_Widget* pSrcTarget, CFWL_Widget* pDstTarget); + CFWL_MessageMouse(const CFWL_MessageMouse& other); ~CFWL_MessageMouse() override; // CFWL_Message std::unique_ptr<CFWL_Message> Clone() override; - FX_FLOAT m_fx; - FX_FLOAT m_fy; + CFX_PointF m_pos; uint32_t m_dwFlags; FWL_MouseCommand m_dwCmd; }; diff --git a/xfa/fwl/cfwl_messagemousewheel.cpp b/xfa/fwl/cfwl_messagemousewheel.cpp index 3646b6c30..8996f650b 100644 --- a/xfa/fwl/cfwl_messagemousewheel.cpp +++ b/xfa/fwl/cfwl_messagemousewheel.cpp @@ -14,6 +14,9 @@ CFWL_MessageMouseWheel::CFWL_MessageMouseWheel(CFWL_Widget* pSrcTarget, CFWL_Widget* pDstTarget) : CFWL_Message(CFWL_Message::Type::MouseWheel, pSrcTarget, pDstTarget) {} +CFWL_MessageMouseWheel::CFWL_MessageMouseWheel(const CFWL_MessageMouseWheel&) = + default; + CFWL_MessageMouseWheel::~CFWL_MessageMouseWheel() {} std::unique_ptr<CFWL_Message> CFWL_MessageMouseWheel::Clone() { diff --git a/xfa/fwl/cfwl_messagemousewheel.h b/xfa/fwl/cfwl_messagemousewheel.h index 4d568c8e4..f969b9a8f 100644 --- a/xfa/fwl/cfwl_messagemousewheel.h +++ b/xfa/fwl/cfwl_messagemousewheel.h @@ -9,20 +9,20 @@ #include <memory> +#include "core/fxcrt/fx_coordinates.h" #include "xfa/fwl/cfwl_message.h" class CFWL_MessageMouseWheel : public CFWL_Message { public: CFWL_MessageMouseWheel(CFWL_Widget* pSrcTarget, CFWL_Widget* pDstTarget); + CFWL_MessageMouseWheel(const CFWL_MessageMouseWheel&); ~CFWL_MessageMouseWheel() override; // CFWL_Message std::unique_ptr<CFWL_Message> Clone() override; - FX_FLOAT m_fx; - FX_FLOAT m_fy; - FX_FLOAT m_fDeltaX; - FX_FLOAT m_fDeltaY; + CFX_PointF m_pos; + CFX_PointF m_delta; uint32_t m_dwFlags; }; diff --git a/xfa/fwl/cfwl_monthcalendar.cpp b/xfa/fwl/cfwl_monthcalendar.cpp index b79dc3ec6..6882d709b 100644 --- a/xfa/fwl/cfwl_monthcalendar.cpp +++ b/xfa/fwl/cfwl_monthcalendar.cpp @@ -11,6 +11,7 @@ #include <utility> #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fde/tto/fde_textout.h" #include "xfa/fwl/cfwl_datetimepicker.h" #include "xfa/fwl/cfwl_formproxy.h" @@ -115,7 +116,7 @@ CFWL_MonthCalendar::CFWL_MonthCalendar( CFWL_MonthCalendar::~CFWL_MonthCalendar() { ClearDateItem(); - m_arrSelDays.RemoveAll(); + m_arrSelDays.clear(); } FWL_Type CFWL_MonthCalendar::GetClassID() const { @@ -124,8 +125,7 @@ FWL_Type CFWL_MonthCalendar::GetClassID() const { CFX_RectF CFWL_MonthCalendar::GetAutosizedWidgetRect() { CFX_SizeF fs = CalcSize(); - CFX_RectF rect; - rect.Set(0, 0, fs.x, fs.y); + CFX_RectF rect(0, 0, fs.width, fs.height); InflateWidgetRect(rect); return rect; } @@ -279,9 +279,9 @@ void CFWL_MonthCalendar::DrawDatesInBK(CFX_Graphics* pGraphics, if (pMatrix) params.m_matrix.Concat(*pMatrix); - int32_t iCount = m_arrDates.GetSize(); + int32_t iCount = pdfium::CollectionSize<int32_t>(m_arrDates); for (int32_t j = 0; j < iCount; j++) { - DATEINFO* pDataInfo = m_arrDates.GetAt(j); + DATEINFO* pDataInfo = m_arrDates[j].get(); if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Selected) { params.m_dwStates |= CFWL_PartState_Selected; if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) { @@ -313,8 +313,10 @@ void CFWL_MonthCalendar::DrawWeek(CFX_Graphics* pGraphics, params.m_matrix.Concat(*pMatrix); for (int32_t i = 0; i < 7; i++) { - rtDayOfWeek.Set(m_rtWeek.left + i * (m_szCell.x + MONTHCAL_HMARGIN * 2), - m_rtWeek.top, m_szCell.x, m_szCell.y); + rtDayOfWeek = + CFX_RectF(m_rtWeek.left + i * (m_szCell.width + MONTHCAL_HMARGIN * 2), + m_rtWeek.top, m_szCell); + params.m_rtPart = rtDayOfWeek; params.m_wsText = GetCapacityForDay(pTheme, params, i); params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine; @@ -355,9 +357,9 @@ void CFWL_MonthCalendar::DrawDatesIn(CFX_Graphics* pGraphics, if (pMatrix) params.m_matrix.Concat(*pMatrix); - int32_t iCount = m_arrDates.GetSize(); + int32_t iCount = pdfium::CollectionSize<int32_t>(m_arrDates); for (int32_t j = 0; j < iCount; j++) { - DATEINFO* pDataInfo = m_arrDates.GetAt(j); + DATEINFO* pDataInfo = m_arrDates[j].get(); params.m_wsText = pDataInfo->wsDay; params.m_rtPart = pDataInfo->rect; params.m_dwStates = pDataInfo->dwStates; @@ -387,10 +389,11 @@ void CFWL_MonthCalendar::DrawDatesInCircle(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) { if (m_iMonth != m_iCurMonth || m_iYear != m_iCurYear) return; - if (m_iDay < 1 || m_iDay > m_arrDates.GetSize()) + + if (m_iDay < 1 || m_iDay > pdfium::CollectionSize<int32_t>(m_arrDates)) return; - DATEINFO* pDate = m_arrDates[m_iDay - 1]; + DATEINFO* pDate = m_arrDates[m_iDay - 1].get(); if (!pDate) return; @@ -409,7 +412,6 @@ CFX_SizeF CFWL_MonthCalendar::CalcSize() { if (!m_pProperties->m_pThemeProvider) return CFX_SizeF(); - CFX_SizeF fs; CFWL_ThemePart params; params.m_pWidget = this; IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; @@ -419,8 +421,8 @@ CFX_SizeF CFWL_MonthCalendar::CalcSize() { for (uint32_t i = 0; i < 7; ++i) { CFX_SizeF sz = CalcTextSize(GetCapacityForDay(pTheme, params, i), m_pProperties->m_pThemeProvider, false); - fMaxWeekW = (fMaxWeekW >= sz.x) ? fMaxWeekW : sz.x; - fMaxWeekH = (fMaxWeekH >= sz.y) ? fMaxWeekH : sz.y; + fMaxWeekW = (fMaxWeekW >= sz.width) ? fMaxWeekW : sz.width; + fMaxWeekH = (fMaxWeekH >= sz.height) ? fMaxWeekH : sz.height; } FX_FLOAT fDayMaxW = 0.0f; @@ -429,89 +431,95 @@ CFX_SizeF CFWL_MonthCalendar::CalcSize() { CFX_WideString wsDay; wsDay.Format(L"%d", day); CFX_SizeF sz = CalcTextSize(wsDay, m_pProperties->m_pThemeProvider, false); - fDayMaxW = (fDayMaxW >= sz.x) ? fDayMaxW : sz.x; - fDayMaxH = (fDayMaxH >= sz.y) ? fDayMaxH : sz.y; + fDayMaxW = (fDayMaxW >= sz.width) ? fDayMaxW : sz.width; + fDayMaxH = (fDayMaxH >= sz.height) ? fDayMaxH : sz.height; } - m_szCell.x = FX_FLOAT((fMaxWeekW >= fDayMaxW) ? (int)(fMaxWeekW + 0.5) - : (int)(fDayMaxW + 0.5)); - m_szCell.y = (fMaxWeekH >= fDayMaxH) ? fMaxWeekH : fDayMaxH; - fs.x = m_szCell.x * MONTHCAL_COLUMNS + - MONTHCAL_HMARGIN * MONTHCAL_COLUMNS * 2 + - MONTHCAL_HEADER_BTN_HMARGIN * 2; + m_szCell.width = FX_FLOAT((fMaxWeekW >= fDayMaxW) ? (int)(fMaxWeekW + 0.5) + : (int)(fDayMaxW + 0.5)); + m_szCell.height = (fMaxWeekH >= fDayMaxH) ? fMaxWeekH : fDayMaxH; + + CFX_SizeF fs; + fs.width = m_szCell.width * MONTHCAL_COLUMNS + + MONTHCAL_HMARGIN * MONTHCAL_COLUMNS * 2 + + MONTHCAL_HEADER_BTN_HMARGIN * 2; FX_FLOAT fMonthMaxW = 0.0f; FX_FLOAT fMonthMaxH = 0.0f; for (uint32_t i = 0; i < 12; ++i) { CFX_SizeF sz = CalcTextSize(GetCapacityForMonth(pTheme, params, i), m_pProperties->m_pThemeProvider, false); - fMonthMaxW = (fMonthMaxW >= sz.x) ? fMonthMaxW : sz.x; - fMonthMaxH = (fMonthMaxH >= sz.y) ? fMonthMaxH : sz.y; + fMonthMaxW = (fMonthMaxW >= sz.width) ? fMonthMaxW : sz.width; + fMonthMaxH = (fMonthMaxH >= sz.height) ? fMonthMaxH : sz.height; } CFX_SizeF szYear = CalcTextSize(GetHeadText(m_iYear, m_iMonth), m_pProperties->m_pThemeProvider, false); - fMonthMaxH = std::max(fMonthMaxH, szYear.y); - m_szHead = CFX_SizeF(fMonthMaxW + szYear.x, fMonthMaxH); - fMonthMaxW = m_szHead.x + MONTHCAL_HEADER_BTN_HMARGIN * 2 + m_szCell.x * 2; - fs.x = std::max(fs.x, fMonthMaxW); + fMonthMaxH = std::max(fMonthMaxH, szYear.height); + m_szHead = CFX_SizeF(fMonthMaxW + szYear.width, fMonthMaxH); + fMonthMaxW = + m_szHead.width + MONTHCAL_HEADER_BTN_HMARGIN * 2 + m_szCell.width * 2; + fs.width = std::max(fs.width, fMonthMaxW); CFX_WideString wsToday = GetTodayText(m_iYear, m_iMonth, m_iDay); m_wsToday = L"Today" + wsToday; m_szToday = CalcTextSize(wsToday, m_pProperties->m_pThemeProvider, false); - m_szToday.y = (m_szToday.y >= m_szCell.y) ? m_szToday.y : m_szCell.y; - fs.y = m_szCell.x + m_szCell.y * (MONTHCAL_ROWS - 2) + m_szToday.y + - MONTHCAL_VMARGIN * MONTHCAL_ROWS * 2 + MONTHCAL_HEADER_BTN_VMARGIN * 4; + m_szToday.height = (m_szToday.height >= m_szCell.height) ? m_szToday.height + : m_szCell.height; + fs.height = m_szCell.width + m_szCell.height * (MONTHCAL_ROWS - 2) + + m_szToday.height + MONTHCAL_VMARGIN * MONTHCAL_ROWS * 2 + + MONTHCAL_HEADER_BTN_VMARGIN * 4; return fs; } void CFWL_MonthCalendar::CalcHeadSize() { - FX_FLOAT fHeadHMargin = (m_rtClient.width - m_szHead.x) / 2; - FX_FLOAT fHeadVMargin = (m_szCell.x - m_szHead.y) / 2; - m_rtHeadText.Set(m_rtClient.left + fHeadHMargin, - m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN + - MONTHCAL_VMARGIN + fHeadVMargin, - m_szHead.x, m_szHead.y); + FX_FLOAT fHeadHMargin = (m_rtClient.width - m_szHead.width) / 2; + FX_FLOAT fHeadVMargin = (m_szCell.width - m_szHead.height) / 2; + m_rtHeadText = CFX_RectF(m_rtClient.left + fHeadHMargin, + m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN + + MONTHCAL_VMARGIN + fHeadVMargin, + m_szHead); } void CFWL_MonthCalendar::CalcTodaySize() { - m_rtTodayFlag.Set( + m_rtTodayFlag = CFX_RectF( m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN, m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN, - m_szCell.x, m_szToday.y); - m_rtToday.Set( - m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + m_szCell.x + + m_szCell.width, m_szToday.height); + m_rtToday = CFX_RectF( + m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + m_szCell.width + MONTHCAL_HMARGIN * 2, m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN, - m_szToday.x, m_szToday.y); + m_szToday); } void CFWL_MonthCalendar::Layout() { m_rtClient = GetClientRect(); - m_rtHead.Set( + m_rtHead = CFX_RectF( m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, m_rtClient.top, m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2, - m_szCell.x + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2); - m_rtWeek.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, m_rtHead.bottom(), - m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2, - m_szCell.y + MONTHCAL_VMARGIN * 2); - m_rtLBtn.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, - m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN, m_szCell.x, - m_szCell.x); - m_rtRBtn.Set(m_rtClient.left + m_rtClient.width - - MONTHCAL_HEADER_BTN_HMARGIN - m_szCell.x, - m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN, m_szCell.x, - m_szCell.x); - m_rtHSep.Set( + m_szCell.width + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2); + m_rtWeek = CFX_RectF(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, + m_rtHead.bottom(), + m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2, + m_szCell.height + MONTHCAL_VMARGIN * 2); + m_rtLBtn = CFX_RectF(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, + m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN, + m_szCell.width, m_szCell.width); + m_rtRBtn = CFX_RectF(m_rtClient.left + m_rtClient.width - + MONTHCAL_HEADER_BTN_HMARGIN - m_szCell.width, + m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN, + m_szCell.width, m_szCell.width); + m_rtHSep = CFX_RectF( m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN, m_rtWeek.bottom() - MONTHCAL_VMARGIN, m_rtClient.width - (MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN) * 2, MONTHCAL_HSEP_HEIGHT); - m_rtDates.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, - m_rtWeek.bottom(), - m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2, - m_szCell.y * (MONTHCAL_ROWS - 3) + - MONTHCAL_VMARGIN * (MONTHCAL_ROWS - 3) * 2); + m_rtDates = CFX_RectF(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, + m_rtWeek.bottom(), + m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2, + m_szCell.height * (MONTHCAL_ROWS - 3) + + MONTHCAL_VMARGIN * (MONTHCAL_ROWS - 3) * 2); CalDateItem(); } @@ -521,18 +529,17 @@ void CFWL_MonthCalendar::CalDateItem() { int32_t iWeekOfMonth = 0; FX_FLOAT fLeft = m_rtDates.left; FX_FLOAT fTop = m_rtDates.top; - int32_t iCount = m_arrDates.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - DATEINFO* pDateInfo = m_arrDates.GetAt(i); + for (const auto& pDateInfo : m_arrDates) { if (bNewWeek) { iWeekOfMonth++; bNewWeek = false; } - pDateInfo->rect.Set( - fLeft + pDateInfo->iDayOfWeek * (m_szCell.x + (MONTHCAL_HMARGIN * 2)), - fTop + iWeekOfMonth * (m_szCell.y + (MONTHCAL_VMARGIN * 2)), - m_szCell.x + (MONTHCAL_HMARGIN * 2), - m_szCell.y + (MONTHCAL_VMARGIN * 2)); + pDateInfo->rect = CFX_RectF( + fLeft + + pDateInfo->iDayOfWeek * (m_szCell.width + (MONTHCAL_HMARGIN * 2)), + fTop + iWeekOfMonth * (m_szCell.height + (MONTHCAL_VMARGIN * 2)), + m_szCell.width + (MONTHCAL_HMARGIN * 2), + m_szCell.height + (MONTHCAL_VMARGIN * 2)); if (pDateInfo->iDayOfWeek >= 6) bNewWeek = true; } @@ -559,9 +566,7 @@ void CFWL_MonthCalendar::InitDate() { } void CFWL_MonthCalendar::ClearDateItem() { - for (int32_t i = 0; i < m_arrDates.GetSize(); i++) - delete m_arrDates.GetAt(i); - m_arrDates.RemoveAll(); + m_arrDates.clear(); } void CFWL_MonthCalendar::ResetDateItem() { @@ -577,12 +582,12 @@ void CFWL_MonthCalendar::ResetDateItem() { uint32_t dwStates = 0; if (m_iYear == m_iCurYear && m_iMonth == m_iCurMonth && m_iDay == (i + 1)) dwStates |= FWL_ITEMSTATE_MCD_Flag; - if (m_arrSelDays.Find(i + 1) != -1) + if (pdfium::ContainsValue(m_arrSelDays, i + 1)) dwStates |= FWL_ITEMSTATE_MCD_Selected; CFX_RectF rtDate; - rtDate.Set(0, 0, 0, 0); - m_arrDates.Add(new DATEINFO(i + 1, iDayOfWeek, dwStates, rtDate, wsDay)); + m_arrDates.push_back(pdfium::MakeUnique<DATEINFO>(i + 1, iDayOfWeek, + dwStates, rtDate, wsDay)); iDayOfWeek++; } } @@ -634,30 +639,24 @@ void CFWL_MonthCalendar::ChangeToMonth(int32_t iYear, int32_t iMonth) { } void CFWL_MonthCalendar::RemoveSelDay() { - int32_t iCount = m_arrSelDays.GetSize(); - int32_t iDatesCount = m_arrDates.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - int32_t iSelDay = m_arrSelDays.GetAt(i); - if (iSelDay <= iDatesCount) { - DATEINFO* pDateInfo = m_arrDates.GetAt(iSelDay - 1); - pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected; - } + int32_t iDatesCount = pdfium::CollectionSize<int32_t>(m_arrDates); + for (int32_t iSelDay : m_arrSelDays) { + if (iSelDay <= iDatesCount) + m_arrDates[iSelDay - 1]->dwStates &= ~FWL_ITEMSTATE_MCD_Selected; } - m_arrSelDays.RemoveAll(); - return; + m_arrSelDays.clear(); } void CFWL_MonthCalendar::AddSelDay(int32_t iDay) { ASSERT(iDay > 0); - if (m_arrSelDays.Find(iDay) != -1) + if (!pdfium::ContainsValue(m_arrSelDays, iDay)) return; RemoveSelDay(); - if (iDay <= m_arrDates.GetSize()) { - DATEINFO* pDateInfo = m_arrDates.GetAt(iDay - 1); - pDateInfo->dwStates |= FWL_ITEMSTATE_MCD_Selected; - } - m_arrSelDays.Add(iDay); + if (iDay <= pdfium::CollectionSize<int32_t>(m_arrDates)) + m_arrDates[iDay - 1]->dwStates |= FWL_ITEMSTATE_MCD_Selected; + + m_arrSelDays.push_back(iDay); } void CFWL_MonthCalendar::JumpToToday() { @@ -669,7 +668,7 @@ void CFWL_MonthCalendar::JumpToToday() { return; } - if (m_arrSelDays.Find(m_iDay) == -1) + if (!pdfium::ContainsValue(m_arrSelDays, m_iDay)) AddSelDay(m_iDay); } @@ -692,24 +691,22 @@ CFX_WideString CFWL_MonthCalendar::GetTodayText(int32_t iYear, return wsToday; } -int32_t CFWL_MonthCalendar::GetDayAtPoint(FX_FLOAT x, FX_FLOAT y) { - int32_t iCount = m_arrDates.GetSize(); - for (int32_t i = 0; i < iCount; i++) { - DATEINFO* pDateInfo = m_arrDates.GetAt(i); - if (pDateInfo->rect.Contains(x, y)) - return ++i; +int32_t CFWL_MonthCalendar::GetDayAtPoint(const CFX_PointF& point) const { + int i = 1; // one-based day values. + for (const auto& pDateInfo : m_arrDates) { + if (pDateInfo->rect.Contains(point)) + return i; + ++i; } return -1; } CFX_RectF CFWL_MonthCalendar::GetDayRect(int32_t iDay) { - if (iDay <= 0 || iDay > m_arrDates.GetSize()) + if (iDay <= 0 || iDay > pdfium::CollectionSize<int32_t>(m_arrDates)) return CFX_RectF(); - DATEINFO* pDateInfo = m_arrDates[iDay - 1]; - if (!pDateInfo) - return CFX_RectF(); - return pDateInfo->rect; + DATEINFO* pDateInfo = m_arrDates[iDay - 1].get(); + return pDateInfo ? pDateInfo->rect : CFX_RectF(); } void CFWL_MonthCalendar::OnProcessMessage(CFWL_Message* pMessage) { @@ -755,15 +752,15 @@ void CFWL_MonthCalendar::OnDrawWidget(CFX_Graphics* pGraphics, } void CFWL_MonthCalendar::OnLButtonDown(CFWL_MessageMouse* pMsg) { - if (m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtLBtn.Contains(pMsg->m_pos)) { m_iLBtnPartStates = CFWL_PartState_Pressed; PrevMonth(); RepaintRect(m_rtClient); - } else if (m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + } else if (m_rtRBtn.Contains(pMsg->m_pos)) { m_iRBtnPartStates |= CFWL_PartState_Pressed; NextMonth(); RepaintRect(m_rtClient); - } else if (m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) { + } else if (m_rtToday.Contains(pMsg->m_pos)) { JumpToToday(); RepaintRect(m_rtClient); } else { @@ -777,32 +774,30 @@ void CFWL_MonthCalendar::OnLButtonUp(CFWL_MessageMouse* pMsg) { if (m_pWidgetMgr->IsFormDisabled()) return DisForm_OnLButtonUp(pMsg); - if (m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtLBtn.Contains(pMsg->m_pos)) { m_iLBtnPartStates = 0; RepaintRect(m_rtLBtn); return; } - if (m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtRBtn.Contains(pMsg->m_pos)) { m_iRBtnPartStates = 0; RepaintRect(m_rtRBtn); return; } - if (m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) + if (m_rtToday.Contains(pMsg->m_pos)) return; int32_t iOldSel = 0; - if (m_arrSelDays.GetSize() > 0) + if (!m_arrSelDays.empty()) iOldSel = m_arrSelDays[0]; - int32_t iCurSel = GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); + int32_t iCurSel = GetDayAtPoint(pMsg->m_pos); CFWL_DateTimePicker* pIPicker = static_cast<CFWL_DateTimePicker*>(m_pOuter); - CFX_RectF rt = pIPicker->GetFormProxy()->GetWidgetRect(); - rt.Set(0, 0, rt.width, rt.height); if (iCurSel > 0) { - DATEINFO* lpDatesInfo = m_arrDates.GetAt(iCurSel - 1); + DATEINFO* lpDatesInfo = m_arrDates[iCurSel - 1].get(); CFX_RectF rtInvalidate(lpDatesInfo->rect); - if (iOldSel > 0 && iOldSel <= m_arrDates.GetSize()) { - lpDatesInfo = m_arrDates.GetAt(iOldSel - 1); + if (iOldSel > 0 && iOldSel <= pdfium::CollectionSize<int32_t>(m_arrDates)) { + lpDatesInfo = m_arrDates[iOldSel - 1].get(); rtInvalidate.Union(lpDatesInfo->rect); } AddSelDay(iCurSel); @@ -811,36 +806,38 @@ void CFWL_MonthCalendar::OnLButtonUp(CFWL_MessageMouse* pMsg) { pIPicker->ProcessSelChanged(m_iCurYear, m_iCurMonth, iCurSel); pIPicker->ShowMonthCalendar(false); - } else if (m_bFlag && (!rt.Contains(pMsg->m_fx, pMsg->m_fy))) { + } else if (m_bFlag && + (!CFX_RectF(0, 0, pIPicker->GetFormProxy()->GetWidgetRect().Size()) + .Contains(pMsg->m_pos))) { pIPicker->ShowMonthCalendar(false); } m_bFlag = false; } void CFWL_MonthCalendar::DisForm_OnLButtonUp(CFWL_MessageMouse* pMsg) { - if (m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtLBtn.Contains(pMsg->m_pos)) { m_iLBtnPartStates = 0; RepaintRect(m_rtLBtn); return; } - if (m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtRBtn.Contains(pMsg->m_pos)) { m_iRBtnPartStates = 0; RepaintRect(m_rtRBtn); return; } - if (m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) + if (m_rtToday.Contains(pMsg->m_pos)) return; int32_t iOldSel = 0; - if (m_arrSelDays.GetSize() > 0) + if (!m_arrSelDays.empty()) iOldSel = m_arrSelDays[0]; - int32_t iCurSel = GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); + int32_t iCurSel = GetDayAtPoint(pMsg->m_pos); if (iCurSel > 0) { - DATEINFO* lpDatesInfo = m_arrDates.GetAt(iCurSel - 1); + DATEINFO* lpDatesInfo = m_arrDates[iCurSel - 1].get(); CFX_RectF rtInvalidate(lpDatesInfo->rect); - if (iOldSel > 0 && iOldSel <= m_arrDates.GetSize()) { - lpDatesInfo = m_arrDates.GetAt(iOldSel - 1); + if (iOldSel > 0 && iOldSel <= pdfium::CollectionSize<int32_t>(m_arrDates)) { + lpDatesInfo = m_arrDates[iOldSel - 1].get(); rtInvalidate.Union(lpDatesInfo->rect); } AddSelDay(iCurSel); @@ -854,9 +851,8 @@ void CFWL_MonthCalendar::DisForm_OnLButtonUp(CFWL_MessageMouse* pMsg) { void CFWL_MonthCalendar::OnMouseMove(CFWL_MessageMouse* pMsg) { bool bRepaint = false; CFX_RectF rtInvalidate; - rtInvalidate.Set(0, 0, 0, 0); - if (m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) { - int32_t iHover = GetDayAtPoint(pMsg->m_fx, pMsg->m_fy); + if (m_rtDates.Contains(pMsg->m_pos)) { + int32_t iHover = GetDayAtPoint(pMsg->m_pos); bRepaint = m_iHovered != iHover; if (bRepaint) { if (m_iHovered > 0) diff --git a/xfa/fwl/cfwl_monthcalendar.h b/xfa/fwl/cfwl_monthcalendar.h index 6c1d0d924..a110ee829 100644 --- a/xfa/fwl/cfwl_monthcalendar.h +++ b/xfa/fwl/cfwl_monthcalendar.h @@ -8,6 +8,7 @@ #define XFA_FWL_CFWL_MONTHCALENDAR_H_ #include <memory> +#include <vector> #include "xfa/fgas/localization/fgas_datetime.h" #include "xfa/fwl/cfwl_event.h" @@ -142,7 +143,7 @@ class CFWL_MonthCalendar : public CFWL_Widget { void JumpToToday(); CFX_WideString GetHeadText(int32_t iYear, int32_t iMonth); CFX_WideString GetTodayText(int32_t iYear, int32_t iMonth, int32_t iDay); - int32_t GetDayAtPoint(FX_FLOAT x, FX_FLOAT y); + int32_t GetDayAtPoint(const CFX_PointF& point) const; CFX_RectF GetDayRect(int32_t iDay); void OnLButtonDown(CFWL_MessageMouse* pMsg); void OnLButtonUp(CFWL_MessageMouse* pMsg); @@ -165,7 +166,7 @@ class CFWL_MonthCalendar : public CFWL_Widget { CFX_WideString m_wsHead; CFX_WideString m_wsToday; std::unique_ptr<CFX_DateTime> m_pDateTime; - CFX_ArrayTemplate<DATEINFO*> m_arrDates; + std::vector<std::unique_ptr<DATEINFO>> m_arrDates; int32_t m_iCurYear; int32_t m_iCurMonth; int32_t m_iYear; @@ -179,7 +180,7 @@ class CFWL_MonthCalendar : public CFWL_Widget { CFX_SizeF m_szHead; CFX_SizeF m_szCell; CFX_SizeF m_szToday; - CFX_ArrayTemplate<int32_t> m_arrSelDays; + std::vector<int32_t> m_arrSelDays; CFX_RectF m_rtClient; bool m_bFlag; }; diff --git a/xfa/fwl/cfwl_notedriver.cpp b/xfa/fwl/cfwl_notedriver.cpp index f4db9b14a..8feb0fb4e 100644 --- a/xfa/fwl/cfwl_notedriver.cpp +++ b/xfa/fwl/cfwl_notedriver.cpp @@ -342,7 +342,7 @@ bool CFWL_NoteDriver::DoMouse(CFWL_Message* pMessage, return !!pMsg->m_pDstTarget; } if (pMsg->m_pDstTarget != pMessageForm) - pMsg->m_pDstTarget->TransformTo(pMessageForm, pMsg->m_fx, pMsg->m_fy); + pMsg->m_pos = pMsg->m_pDstTarget->TransformTo(pMessageForm, pMsg->m_pos); if (!DoMouseEx(pMsg, pMessageForm)) pMsg->m_pDstTarget = pMessageForm; return true; @@ -355,12 +355,11 @@ bool CFWL_NoteDriver::DoWheel(CFWL_Message* pMessage, return false; CFWL_MessageMouseWheel* pMsg = static_cast<CFWL_MessageMouseWheel*>(pMessage); - CFWL_Widget* pDst = - pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy); + CFWL_Widget* pDst = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_pos); if (!pDst) return false; - pMessageForm->TransformTo(pDst, pMsg->m_fx, pMsg->m_fy); + pMsg->m_pos = pMessageForm->TransformTo(pDst, pMsg->m_pos); pMsg->m_pDstTarget = pDst; return true; } @@ -375,16 +374,12 @@ bool CFWL_NoteDriver::DoMouseEx(CFWL_Message* pMessage, pTarget = m_pGrab; CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); - if (!pTarget) { - pTarget = - pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy); - } - if (pTarget) { - if (pMessageForm != pTarget) - pMessageForm->TransformTo(pTarget, pMsg->m_fx, pMsg->m_fy); - } + if (!pTarget) + pTarget = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_pos); if (!pTarget) return false; + if (pTarget && pMessageForm != pTarget) + pMsg->m_pos = pMessageForm->TransformTo(pTarget, pMsg->m_pos); pMsg->m_pDstTarget = pTarget; return true; @@ -398,10 +393,7 @@ void CFWL_NoteDriver::MouseSecondary(CFWL_Message* pMessage) { CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); if (m_pHover) { CFWL_MessageMouse msLeave(nullptr, m_pHover); - msLeave.m_fx = pMsg->m_fx; - msLeave.m_fy = pMsg->m_fy; - pTarget->TransformTo(m_pHover, msLeave.m_fx, msLeave.m_fy); - + msLeave.m_pos = pTarget->TransformTo(m_pHover, pMsg->m_pos); msLeave.m_dwFlags = 0; msLeave.m_dwCmd = FWL_MouseCommand::Leave; DispatchMessage(&msLeave, nullptr); @@ -413,8 +405,7 @@ void CFWL_NoteDriver::MouseSecondary(CFWL_Message* pMessage) { m_pHover = pTarget; CFWL_MessageMouse msHover(nullptr, pTarget); - msHover.m_fx = pMsg->m_fx; - msHover.m_fy = pMsg->m_fy; + msHover.m_pos = pMsg->m_pos; msHover.m_dwFlags = 0; msHover.m_dwCmd = FWL_MouseCommand::Hover; DispatchMessage(&msHover, nullptr); diff --git a/xfa/fwl/cfwl_pushbutton.cpp b/xfa/fwl/cfwl_pushbutton.cpp index 3f0be45d1..fe4c3f621 100644 --- a/xfa/fwl/cfwl_pushbutton.cpp +++ b/xfa/fwl/cfwl_pushbutton.cpp @@ -24,10 +24,7 @@ CFWL_PushButton::CFWL_PushButton(const CFWL_App* app) : CFWL_Widget(app, pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr), m_bBtnDown(false), m_dwTTOStyles(FDE_TTOSTYLE_SingleLine), - m_iTTOAlign(FDE_TTOALIGNMENT_Center) { - m_rtClient.Set(0, 0, 0, 0); - m_rtCaption.Set(0, 0, 0, 0); -} + m_iTTOAlign(FDE_TTOALIGNMENT_Center) {} CFWL_PushButton::~CFWL_PushButton() {} @@ -173,14 +170,14 @@ void CFWL_PushButton::OnLButtonDown(CFWL_MessageMouse* pMsg) { void CFWL_PushButton::OnLButtonUp(CFWL_MessageMouse* pMsg) { m_bBtnDown = false; - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtClient.Contains(pMsg->m_pos)) { m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; } else { m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered; m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed; } - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtClient.Contains(pMsg->m_pos)) { CFWL_Event wmClick(CFWL_Event::Type::Click, this); DispatchEvent(&wmClick); } @@ -190,7 +187,7 @@ void CFWL_PushButton::OnLButtonUp(CFWL_MessageMouse* pMsg) { void CFWL_PushButton::OnMouseMove(CFWL_MessageMouse* pMsg) { bool bRepaint = false; if (m_bBtnDown) { - if (m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtClient.Contains(pMsg->m_pos)) { if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) == 0) { m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed; bRepaint = true; @@ -210,7 +207,7 @@ void CFWL_PushButton::OnMouseMove(CFWL_MessageMouse* pMsg) { } } } else { - if (!m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) + if (!m_rtClient.Contains(pMsg->m_pos)) return; if ((m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) { m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered; diff --git a/xfa/fwl/cfwl_scrollbar.cpp b/xfa/fwl/cfwl_scrollbar.cpp index d4dd8885e..1da267455 100644 --- a/xfa/fwl/cfwl_scrollbar.cpp +++ b/xfa/fwl/cfwl_scrollbar.cpp @@ -45,8 +45,6 @@ CFWL_ScrollBar::CFWL_ScrollBar( m_iMinTrackState(CFWL_PartState_Normal), m_iMaxTrackState(CFWL_PartState_Normal), m_fLastTrackPos(0), - m_cpTrackPointX(0), - m_cpTrackPointY(0), m_iMouseWheel(0), m_bMouseDown(false), m_fButtonLen(0), @@ -176,30 +174,22 @@ void CFWL_ScrollBar::CalcButtonLen() { } CFX_RectF CFWL_ScrollBar::CalcMinButtonRect() { - CFX_RectF rect; if (IsVertical()) - rect.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width, m_fButtonLen); - else - rect.Set(m_rtClient.left, m_rtClient.top, m_fButtonLen, m_rtClient.height); - return rect; + return CFX_RectF(m_rtClient.TopLeft(), m_rtClient.width, m_fButtonLen); + return CFX_RectF(m_rtClient.TopLeft(), m_fButtonLen, m_rtClient.height); } CFX_RectF CFWL_ScrollBar::CalcMaxButtonRect() { - CFX_RectF rect; if (IsVertical()) { - rect.Set(m_rtClient.left, m_rtClient.bottom() - m_fButtonLen, - m_rtClient.width, m_fButtonLen); - } else { - rect.Set(m_rtClient.right() - m_fButtonLen, m_rtClient.top, m_fButtonLen, - m_rtClient.height); + return CFX_RectF(m_rtClient.left, m_rtClient.bottom() - m_fButtonLen, + m_rtClient.width, m_fButtonLen); } - return rect; + return CFX_RectF(m_rtClient.right() - m_fButtonLen, m_rtClient.top, + m_fButtonLen, m_rtClient.height); } CFX_RectF CFWL_ScrollBar::CalcThumbButtonRect(const CFX_RectF& rtThumb) { CFX_RectF rect; - rect.Reset(); - if (!IsEnabled()) return rect; @@ -211,11 +201,11 @@ CFX_RectF CFWL_ScrollBar::CalcThumbButtonRect(const CFX_RectF& rtThumb) { FX_FLOAT fRange = m_fRangeMax - m_fRangeMin; if (fRange < 0) { - if (IsVertical()) - rect.Set(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width, 0); - else - rect.Set(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height); - return rect; + if (IsVertical()) { + return CFX_RectF(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width, + 0); + } + return CFX_RectF(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height); } CFX_RectF rtClient = m_rtClient; @@ -251,8 +241,6 @@ CFX_RectF CFWL_ScrollBar::CalcThumbButtonRect(const CFX_RectF& rtThumb) { CFX_RectF CFWL_ScrollBar::CalcMinTrackRect(const CFX_RectF& rtMinRect) { CFX_RectF rect; - rect.Reset(); - if (m_bMinSize) { rect.left = rtMinRect.left; rect.top = rtMinRect.top; @@ -272,33 +260,30 @@ CFX_RectF CFWL_ScrollBar::CalcMinTrackRect(const CFX_RectF& rtMinRect) { } CFX_RectF CFWL_ScrollBar::CalcMaxTrackRect(const CFX_RectF& rtMaxRect) { - CFX_RectF rect; - if (m_bMinSize) { - rect.Set(rtMaxRect.left, rtMaxRect.top, 0, 0); - return rect; - } + if (m_bMinSize) + return CFX_RectF(rtMaxRect.TopLeft(), 0, 0); if (IsVertical()) { FX_FLOAT iy = (m_rtThumb.top + m_rtThumb.bottom()) / 2; - rect.Set(m_rtClient.left, iy, m_rtClient.width, m_rtClient.bottom() - iy); - } else { - FX_FLOAT ix = (m_rtThumb.left + m_rtThumb.right()) / 2; - rect.Set(ix, m_rtClient.top, m_rtClient.height - ix, m_rtClient.height); + return CFX_RectF(m_rtClient.left, iy, m_rtClient.width, + m_rtClient.bottom() - iy); } - return rect; + + FX_FLOAT ix = (m_rtThumb.left + m_rtThumb.right()) / 2; + return CFX_RectF(ix, m_rtClient.top, m_rtClient.height - ix, + m_rtClient.height); } -FX_FLOAT CFWL_ScrollBar::GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy) { - FX_FLOAT fDiffX = fx - m_cpTrackPointX; - FX_FLOAT fDiffY = fy - m_cpTrackPointY; +FX_FLOAT CFWL_ScrollBar::GetTrackPointPos(const CFX_PointF& point) { + CFX_PointF diff = point - m_cpTrackPoint; FX_FLOAT fRange = m_fRangeMax - m_fRangeMin; FX_FLOAT fPos; if (IsVertical()) { - fPos = fRange * fDiffY / + fPos = fRange * diff.y / (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height); } else { - fPos = fRange * fDiffX / + fPos = fRange * diff.x / (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width); } @@ -317,11 +302,11 @@ bool CFWL_ScrollBar::SendEvent() { } if (m_iMinTrackState == CFWL_PartState_Pressed) { DoScroll(CFWL_EventScroll::Code::PageBackward, m_fTrackPos); - return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY); + return m_rtThumb.Contains(m_cpTrackPoint); } if (m_iMaxTrackState == CFWL_PartState_Pressed) { DoScroll(CFWL_EventScroll::Code::PageForward, m_fTrackPos); - return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY); + return m_rtThumb.Contains(m_cpTrackPoint); } if (m_iMouseWheel) { CFWL_EventScroll::Code dwCode = m_iMouseWheel < 0 @@ -349,13 +334,13 @@ void CFWL_ScrollBar::OnProcessMessage(CFWL_Message* pMessage) { CFWL_MessageMouse* pMsg = static_cast<CFWL_MessageMouse*>(pMessage); switch (pMsg->m_dwCmd) { case FWL_MouseCommand::LeftButtonDown: - OnLButtonDown(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy); + OnLButtonDown(pMsg->m_pos); break; case FWL_MouseCommand::LeftButtonUp: - OnLButtonUp(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy); + OnLButtonUp(pMsg->m_pos); break; case FWL_MouseCommand::Move: - OnMouseMove(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy); + OnMouseMove(pMsg->m_pos); break; case FWL_MouseCommand::Leave: OnMouseLeave(); @@ -366,8 +351,7 @@ void CFWL_ScrollBar::OnProcessMessage(CFWL_Message* pMessage) { } else if (type == CFWL_Message::Type::MouseWheel) { CFWL_MessageMouseWheel* pMsg = static_cast<CFWL_MessageMouseWheel*>(pMessage); - OnMouseWheel(pMsg->m_fx, pMsg->m_fy, pMsg->m_dwFlags, pMsg->m_fDeltaX, - pMsg->m_fDeltaY); + OnMouseWheel(pMsg->m_delta); } } @@ -376,47 +360,47 @@ void CFWL_ScrollBar::OnDrawWidget(CFX_Graphics* pGraphics, DrawWidget(pGraphics, pMatrix); } -void CFWL_ScrollBar::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { +void CFWL_ScrollBar::OnLButtonDown(const CFX_PointF& point) { if (!IsEnabled()) return; m_bMouseDown = true; SetGrab(true); - m_cpTrackPointX = fx; - m_cpTrackPointY = fy; + + m_cpTrackPoint = point; m_fLastTrackPos = m_fTrackPos; - if (m_rtMinBtn.Contains(fx, fy)) - DoMouseDown(0, m_rtMinBtn, m_iMinButtonState, fx, fy); - else if (m_rtThumb.Contains(fx, fy)) - DoMouseDown(1, m_rtThumb, m_iThumbButtonState, fx, fy); - else if (m_rtMaxBtn.Contains(fx, fy)) - DoMouseDown(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy); - else if (m_rtMinTrack.Contains(fx, fy)) - DoMouseDown(3, m_rtMinTrack, m_iMinTrackState, fx, fy); + if (m_rtMinBtn.Contains(point)) + DoMouseDown(0, m_rtMinBtn, m_iMinButtonState, point); + else if (m_rtThumb.Contains(point)) + DoMouseDown(1, m_rtThumb, m_iThumbButtonState, point); + else if (m_rtMaxBtn.Contains(point)) + DoMouseDown(2, m_rtMaxBtn, m_iMaxButtonState, point); + else if (m_rtMinTrack.Contains(point)) + DoMouseDown(3, m_rtMinTrack, m_iMinTrackState, point); else - DoMouseDown(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy); + DoMouseDown(4, m_rtMaxTrack, m_iMaxTrackState, point); if (!SendEvent()) m_pTimerInfo = m_Timer.StartTimer(FWL_SCROLLBAR_Elapse, true); } -void CFWL_ScrollBar::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { +void CFWL_ScrollBar::OnLButtonUp(const CFX_PointF& point) { m_pTimerInfo->StopTimer(); m_bMouseDown = false; - DoMouseUp(0, m_rtMinBtn, m_iMinButtonState, fx, fy); - DoMouseUp(1, m_rtThumb, m_iThumbButtonState, fx, fy); - DoMouseUp(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy); - DoMouseUp(3, m_rtMinTrack, m_iMinTrackState, fx, fy); - DoMouseUp(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy); + DoMouseUp(0, m_rtMinBtn, m_iMinButtonState, point); + DoMouseUp(1, m_rtThumb, m_iThumbButtonState, point); + DoMouseUp(2, m_rtMaxBtn, m_iMaxButtonState, point); + DoMouseUp(3, m_rtMinTrack, m_iMinTrackState, point); + DoMouseUp(4, m_rtMaxTrack, m_iMaxTrackState, point); SetGrab(false); } -void CFWL_ScrollBar::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - DoMouseMove(0, m_rtMinBtn, m_iMinButtonState, fx, fy); - DoMouseMove(1, m_rtThumb, m_iThumbButtonState, fx, fy); - DoMouseMove(2, m_rtMaxBtn, m_iMaxButtonState, fx, fy); - DoMouseMove(3, m_rtMinTrack, m_iMinTrackState, fx, fy); - DoMouseMove(4, m_rtMaxTrack, m_iMaxTrackState, fx, fy); +void CFWL_ScrollBar::OnMouseMove(const CFX_PointF& point) { + DoMouseMove(0, m_rtMinBtn, m_iMinButtonState, point); + DoMouseMove(1, m_rtThumb, m_iThumbButtonState, point); + DoMouseMove(2, m_rtMaxBtn, m_iMaxButtonState, point); + DoMouseMove(3, m_rtMinTrack, m_iMinTrackState, point); + DoMouseMove(4, m_rtMaxTrack, m_iMaxTrackState, point); } void CFWL_ScrollBar::OnMouseLeave() { @@ -427,12 +411,8 @@ void CFWL_ScrollBar::OnMouseLeave() { DoMouseLeave(4, m_rtMaxTrack, m_iMaxTrackState); } -void CFWL_ScrollBar::OnMouseWheel(FX_FLOAT fx, - FX_FLOAT fy, - uint32_t dwFlags, - FX_FLOAT fDeltaX, - FX_FLOAT fDeltaY) { - m_iMouseWheel = (int32_t)fDeltaX; +void CFWL_ScrollBar::OnMouseWheel(const CFX_PointF& delta) { + m_iMouseWheel = static_cast<int32_t>(delta.x); SendEvent(); m_iMouseWheel = 0; } @@ -440,9 +420,8 @@ void CFWL_ScrollBar::OnMouseWheel(FX_FLOAT fx, void CFWL_ScrollBar::DoMouseDown(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState, - FX_FLOAT fx, - FX_FLOAT fy) { - if (!rtItem.Contains(fx, fy)) + const CFX_PointF& point) { + if (!rtItem.Contains(point)) return; if (iState == CFWL_PartState_Pressed) return; @@ -454,10 +433,9 @@ void CFWL_ScrollBar::DoMouseDown(int32_t iItem, void CFWL_ScrollBar::DoMouseUp(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { int32_t iNewState = - rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered : CFWL_PartState_Normal; + rtItem.Contains(point) ? CFWL_PartState_Hovered : CFWL_PartState_Normal; if (iState == iNewState) return; @@ -469,20 +447,18 @@ void CFWL_ScrollBar::DoMouseUp(int32_t iItem, void CFWL_ScrollBar::DoMouseMove(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { if (!m_bMouseDown) { - int32_t iNewState = rtItem.Contains(fx, fy) ? CFWL_PartState_Hovered - : CFWL_PartState_Normal; + int32_t iNewState = + rtItem.Contains(point) ? CFWL_PartState_Hovered : CFWL_PartState_Normal; if (iState == iNewState) return; iState = iNewState; RepaintRect(rtItem); } else if ((2 == iItem) && (m_iThumbButtonState == CFWL_PartState_Pressed)) { - FX_FLOAT fPos = GetTrackPointPos(fx, fy); - m_fTrackPos = fPos; - OnScroll(CFWL_EventScroll::Code::TrackPos, fPos); + m_fTrackPos = GetTrackPointPos(point); + OnScroll(CFWL_EventScroll::Code::TrackPos, m_fTrackPos); } } diff --git a/xfa/fwl/cfwl_scrollbar.h b/xfa/fwl/cfwl_scrollbar.h index 62ce52364..6a67fa868 100644 --- a/xfa/fwl/cfwl_scrollbar.h +++ b/xfa/fwl/cfwl_scrollbar.h @@ -84,35 +84,28 @@ class CFWL_ScrollBar : public CFWL_Widget { CFX_RectF CalcThumbButtonRect(const CFX_RectF& rtThumbRect); CFX_RectF CalcMinTrackRect(const CFX_RectF& rtMinRect); CFX_RectF CalcMaxTrackRect(const CFX_RectF& rtMaxRect); - FX_FLOAT GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy); + FX_FLOAT GetTrackPointPos(const CFX_PointF& point); bool SendEvent(); bool OnScroll(CFWL_EventScroll::Code dwCode, FX_FLOAT fPos); - void OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - void OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - void OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); + void OnLButtonDown(const CFX_PointF& point); + void OnLButtonUp(const CFX_PointF& point); + void OnMouseMove(const CFX_PointF& point); void OnMouseLeave(); - void OnMouseWheel(FX_FLOAT fx, - FX_FLOAT fy, - uint32_t dwFlags, - FX_FLOAT fDeltaX, - FX_FLOAT fDeltaY); + void OnMouseWheel(const CFX_PointF& delta); bool DoScroll(CFWL_EventScroll::Code dwCode, FX_FLOAT fPos); void DoMouseDown(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); void DoMouseUp(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); void DoMouseMove(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); void DoMouseLeave(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState); void DoMouseHover(int32_t iItem, const CFX_RectF& rtItem, int32_t& iState); @@ -129,8 +122,7 @@ class CFWL_ScrollBar : public CFWL_Widget { int32_t m_iMinTrackState; int32_t m_iMaxTrackState; FX_FLOAT m_fLastTrackPos; - FX_FLOAT m_cpTrackPointX; - FX_FLOAT m_cpTrackPointY; + CFX_PointF m_cpTrackPoint; int32_t m_iMouseWheel; bool m_bMouseDown; FX_FLOAT m_fButtonLen; diff --git a/xfa/fwl/cfwl_spinbutton.cpp b/xfa/fwl/cfwl_spinbutton.cpp index 3748d36a3..6e58b69ba 100644 --- a/xfa/fwl/cfwl_spinbutton.cpp +++ b/xfa/fwl/cfwl_spinbutton.cpp @@ -52,26 +52,28 @@ void CFWL_SpinButton::Update() { m_rtClient = GetClientRect(); if (m_pProperties->m_dwStyleExes & FWL_STYLEEXE_SPB_Vert) { - m_rtUpButton.Set(m_rtClient.top, m_rtClient.left, m_rtClient.width, - m_rtClient.height / 2); - m_rtDnButton.Set(m_rtClient.left, m_rtClient.top + m_rtClient.height / 2, - m_rtClient.width, m_rtClient.height / 2); + m_rtUpButton = CFX_RectF(m_rtClient.top, m_rtClient.left, m_rtClient.width, + m_rtClient.height / 2); + m_rtDnButton = + CFX_RectF(m_rtClient.left, m_rtClient.top + m_rtClient.height / 2, + m_rtClient.width, m_rtClient.height / 2); } else { - m_rtUpButton.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width / 2, - m_rtClient.height); - m_rtDnButton.Set(m_rtClient.left + m_rtClient.width / 2, m_rtClient.top, - m_rtClient.width / 2, m_rtClient.height); + m_rtUpButton = CFX_RectF(m_rtClient.TopLeft(), m_rtClient.width / 2, + m_rtClient.height); + m_rtDnButton = + CFX_RectF(m_rtClient.left + m_rtClient.width / 2, m_rtClient.top, + m_rtClient.width / 2, m_rtClient.height); } } -FWL_WidgetHit CFWL_SpinButton::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (m_rtClient.Contains(fx, fy)) +FWL_WidgetHit CFWL_SpinButton::HitTest(const CFX_PointF& point) { + if (m_rtClient.Contains(point)) return FWL_WidgetHit::Client; - if (HasBorder() && (m_rtClient.Contains(fx, fy))) + if (HasBorder() && (m_rtClient.Contains(point))) return FWL_WidgetHit::Border; - if (m_rtUpButton.Contains(fx, fy)) + if (m_rtUpButton.Contains(point)) return FWL_WidgetHit::UpButton; - if (m_rtDnButton.Contains(fx, fy)) + if (m_rtDnButton.Contains(point)) return FWL_WidgetHit::DownButton; return FWL_WidgetHit::Unknown; } @@ -199,10 +201,8 @@ void CFWL_SpinButton::OnLButtonDown(CFWL_MessageMouse* pMsg) { SetGrab(true); SetFocus(true); - bool bUpPress = - (m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy) && IsUpButtonEnabled()); - bool bDnPress = - (m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy) && IsDownButtonEnabled()); + bool bUpPress = m_rtUpButton.Contains(pMsg->m_pos) && IsUpButtonEnabled(); + bool bDnPress = m_rtDnButton.Contains(pMsg->m_pos) && IsDownButtonEnabled(); if (!bUpPress && !bDnPress) return; if (bUpPress) { @@ -253,8 +253,7 @@ void CFWL_SpinButton::OnMouseMove(CFWL_MessageMouse* pMsg) { bool bRepaint = false; CFX_RectF rtInvlidate; - rtInvlidate.Reset(); - if (m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy)) { + if (m_rtUpButton.Contains(pMsg->m_pos)) { if (IsUpButtonEnabled()) { if (m_dwUpState == CFWL_PartState_Hovered) { m_dwUpState = CFWL_PartState_Hovered; @@ -274,7 +273,7 @@ void CFWL_SpinButton::OnMouseMove(CFWL_MessageMouse* pMsg) { if (!IsDownButtonEnabled()) DisableButton(); - } else if (m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy)) { + } else if (m_rtDnButton.Contains(pMsg->m_pos)) { if (IsDownButtonEnabled()) { if (m_dwDnState != CFWL_PartState_Hovered) { m_dwDnState = CFWL_PartState_Hovered; diff --git a/xfa/fwl/cfwl_spinbutton.h b/xfa/fwl/cfwl_spinbutton.h index 4794461fb..3cda761f9 100644 --- a/xfa/fwl/cfwl_spinbutton.h +++ b/xfa/fwl/cfwl_spinbutton.h @@ -27,7 +27,7 @@ class CFWL_SpinButton : public CFWL_Widget { // CFWL_Widget FWL_Type GetClassID() const override; void Update() override; - FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit HitTest(const CFX_PointF& point) override; void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) override; void OnProcessMessage(CFWL_Message* pMessage) override; void OnDrawWidget(CFX_Graphics* pGraphics, diff --git a/xfa/fwl/cfwl_widget.cpp b/xfa/fwl/cfwl_widget.cpp index 301ad5fc9..b5b8bf4c7 100644 --- a/xfa/fwl/cfwl_widget.cpp +++ b/xfa/fwl/cfwl_widget.cpp @@ -8,7 +8,9 @@ #include <algorithm> #include <utility> +#include <vector> +#include "third_party/base/stl_util.h" #include "xfa/fde/tto/fde_textout.h" #include "xfa/fwl/cfwl_app.h" #include "xfa/fwl/cfwl_combobox.h" @@ -149,70 +151,55 @@ void CFWL_Widget::RemoveStates(uint32_t dwStates) { m_pProperties->m_dwStates &= ~dwStates; } -FWL_WidgetHit CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (GetClientRect().Contains(fx, fy)) +FWL_WidgetHit CFWL_Widget::HitTest(const CFX_PointF& point) { + if (GetClientRect().Contains(point)) return FWL_WidgetHit::Client; - if (HasBorder() && GetRelativeRect().Contains(fx, fy)) + if (HasBorder() && GetRelativeRect().Contains(point)) return FWL_WidgetHit::Border; return FWL_WidgetHit::Unknown; } -void CFWL_Widget::TransformTo(CFWL_Widget* pWidget, - FX_FLOAT& fx, - FX_FLOAT& fy) { +CFX_PointF CFWL_Widget::TransformTo(CFWL_Widget* pWidget, + const CFX_PointF& point) { if (m_pWidgetMgr->IsFormDisabled()) { CFX_SizeF szOffset; if (IsParent(pWidget)) { szOffset = GetOffsetFromParent(pWidget); } else { szOffset = pWidget->GetOffsetFromParent(this); - szOffset.x = -szOffset.x; - szOffset.y = -szOffset.y; + szOffset.width = -szOffset.width; + szOffset.height = -szOffset.height; } - fx += szOffset.x; - fy += szOffset.y; - return; + return point + CFX_PointF(szOffset.width, szOffset.height); } - CFX_RectF r; - CFX_Matrix m; + + CFX_PointF ret = point; CFWL_Widget* parent = GetParent(); - if (parent) { - r = GetWidgetRect(); - fx += r.left; - fy += r.top; - m = GetMatrix(); - m.TransformPoint(fx, fy); - } + if (parent) + ret = GetMatrix().Transform(ret + GetWidgetRect().TopLeft()); + CFWL_Widget* form1 = m_pWidgetMgr->GetSystemFormWidget(this); if (!form1) - return; + return ret; + + if (!pWidget) + return ret + form1->GetWidgetRect().TopLeft(); - if (!pWidget) { - r = form1->GetWidgetRect(); - fx += r.left; - fy += r.top; - return; - } CFWL_Widget* form2 = m_pWidgetMgr->GetSystemFormWidget(pWidget); if (!form2) - return; + return ret; if (form1 != form2) { - r = form1->GetWidgetRect(); - fx += r.left; - fy += r.top; - r = form2->GetWidgetRect(); - fx -= r.left; - fy -= r.top; + ret += form1->GetWidgetRect().TopLeft(); + ret -= form2->GetWidgetRect().TopLeft(); } + parent = pWidget->GetParent(); - if (parent) { - CFX_Matrix m1; - m1.SetReverse(pWidget->GetMatrix()); - m1.TransformPoint(fx, fy); - r = pWidget->GetWidgetRect(); - fx -= r.left; - fy -= r.top; - } + if (!parent) + return ret; + + CFX_Matrix m; + m.SetReverse(pWidget->GetMatrix()); + return m.Transform(ret) - pWidget->GetWidgetRect().TopLeft(); } CFX_Matrix CFWL_Widget::GetMatrix() { @@ -220,19 +207,18 @@ CFX_Matrix CFWL_Widget::GetMatrix() { return CFX_Matrix(); CFWL_Widget* parent = GetParent(); - CFX_ArrayTemplate<CFWL_Widget*> parents; + std::vector<CFWL_Widget*> parents; while (parent) { - parents.Add(parent); + parents.push_back(parent); parent = parent->GetParent(); } CFX_Matrix matrix; CFX_Matrix ctmOnParent; CFX_RectF rect; - int32_t count = parents.GetSize(); + int32_t count = pdfium::CollectionSize<int32_t>(parents); for (int32_t i = count - 2; i >= 0; i--) { - parent = parents.GetAt(i); - + parent = parents[i]; if (parent->m_pProperties) ctmOnParent.SetIdentity(); rect = parent->GetWidgetRect(); @@ -242,8 +228,7 @@ CFX_Matrix CFWL_Widget::GetMatrix() { CFX_Matrix m; m.SetIdentity(); matrix.Concat(m, true); - parents.RemoveAll(); - + parents.clear(); return matrix; } @@ -281,8 +266,8 @@ bool CFWL_Widget::IsChild() const { } CFX_RectF CFWL_Widget::GetEdgeRect() { - CFX_RectF rtEdge = m_pProperties->m_rtWidget; - rtEdge.left = rtEdge.top = 0; + CFX_RectF rtEdge(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); if (HasBorder()) { FX_FLOAT fCX = GetBorderSize(true); FX_FLOAT fCY = GetBorderSize(false); @@ -299,10 +284,8 @@ FX_FLOAT CFWL_Widget::GetBorderSize(bool bCX) { } CFX_RectF CFWL_Widget::GetRelativeRect() { - CFX_RectF rect = m_pProperties->m_rtWidget; - rect.left = 0; - rect.top = 0; - return rect; + return CFX_RectF(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height); } IFWL_ThemeProvider* CFWL_Widget::GetAvailableTheme() { @@ -345,10 +328,9 @@ CFX_SizeF CFWL_Widget::CalcTextSize(const CFX_WideString& wsText, calPart.m_dwTTOStyles = bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine; calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft; - CFX_RectF rect; FX_FLOAT fWidth = bMultiLine ? FWL_WGT_CalcMultiLineDefWidth : FWL_WGT_CalcWidth; - rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight); + CFX_RectF rect(0, 0, fWidth, FWL_WGT_CalcHeight); pTheme->CalcTextRect(&calPart, rect); return CFX_SizeF(rect.width, rect.height); } @@ -422,32 +404,31 @@ bool CFWL_Widget::GetPopupPosMenu(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF& rtAnchor, CFX_RectF& rtPopup) { - FX_FLOAT fx = 0; - FX_FLOAT fy = 0; - if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) { bool bLeft = m_pProperties->m_rtWidget.left < 0; FX_FLOAT fRight = rtAnchor.right() + rtPopup.width; - TransformTo(nullptr, fx, fy); - if (fRight + fx > 0.0f || bLeft) { - rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width, - rtPopup.height); + CFX_PointF point = TransformTo(nullptr, CFX_PointF()); + if (fRight + point.x > 0.0f || bLeft) { + rtPopup = CFX_RectF(rtAnchor.left - rtPopup.width, rtAnchor.top, + rtPopup.width, rtPopup.height); } else { - rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width, - rtPopup.height); + rtPopup = CFX_RectF(rtAnchor.right(), rtAnchor.top, rtPopup.width, + rtPopup.height); } + rtPopup.Offset(point.x, point.y); + return true; + } + + FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height; + CFX_PointF point = TransformTo(nullptr, point); + if (fBottom + point.y > 0.0f) { + rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.top - rtPopup.height, + rtPopup.width, rtPopup.height); } else { - FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height; - TransformTo(nullptr, fx, fy); - if (fBottom + fy > 0.0f) { - rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, - rtPopup.height); - } else { - rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, - rtPopup.height); - } + rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, + rtPopup.height); } - rtPopup.Offset(fx, fy); + rtPopup.Offset(point.x, point.y); return true; } @@ -455,9 +436,6 @@ bool CFWL_Widget::GetPopupPosComboBox(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF& rtAnchor, CFX_RectF& rtPopup) { - FX_FLOAT fx = 0; - FX_FLOAT fy = 0; - FX_FLOAT fPopHeight = rtPopup.height; if (rtPopup.height > fMaxHeight) fPopHeight = fMaxHeight; @@ -466,13 +444,15 @@ bool CFWL_Widget::GetPopupPosComboBox(FX_FLOAT fMinHeight, FX_FLOAT fWidth = std::max(rtAnchor.width, rtPopup.width); FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight; - TransformTo(nullptr, fx, fy); - if (fBottom + fy > 0.0f) - rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight); - else - rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight); + CFX_PointF point = TransformTo(nullptr, CFX_PointF()); + if (fBottom + point.y > 0.0f) { + rtPopup = + CFX_RectF(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight); + } else { + rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight); + } - rtPopup.Offset(fx, fy); + rtPopup.Offset(point.x, point.y); return true; } @@ -480,18 +460,15 @@ bool CFWL_Widget::GetPopupPosGeneral(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF& rtAnchor, CFX_RectF& rtPopup) { - FX_FLOAT fx = 0; - FX_FLOAT fy = 0; - - TransformTo(nullptr, fx, fy); - if (rtAnchor.bottom() + fy > 0.0f) { - rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, - rtPopup.height); + CFX_PointF point = TransformTo(nullptr, CFX_PointF()); + if (rtAnchor.bottom() + point.y > 0.0f) { + rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.top - rtPopup.height, + rtPopup.width, rtPopup.height); } else { - rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, - rtPopup.height); + rtPopup = CFX_RectF(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, + rtPopup.height); } - rtPopup.Offset(fx, fy); + rtPopup.Offset(point.x, point.y); return true; } @@ -535,11 +512,8 @@ void CFWL_Widget::DispatchEvent(CFWL_Event* pEvent) { } void CFWL_Widget::Repaint() { - CFX_RectF rect; - rect = m_pProperties->m_rtWidget; - rect.left = 0; - rect.top = 0; - RepaintRect(rect); + RepaintRect(CFX_RectF(0, 0, m_pProperties->m_rtWidget.width, + m_pProperties->m_rtWidget.height)); } void CFWL_Widget::RepaintRect(const CFX_RectF& pRect) { diff --git a/xfa/fwl/cfwl_widget.h b/xfa/fwl/cfwl_widget.h index 74fa314bf..2387b753e 100644 --- a/xfa/fwl/cfwl_widget.h +++ b/xfa/fwl/cfwl_widget.h @@ -60,7 +60,7 @@ class CFWL_Widget : public IFWL_WidgetDelegate { virtual void SetStates(uint32_t dwStates); virtual void RemoveStates(uint32_t dwStates); virtual void Update() = 0; - virtual FWL_WidgetHit HitTest(FX_FLOAT fx, FX_FLOAT fy); + virtual FWL_WidgetHit HitTest(const CFX_PointF& point); virtual void DrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix) = 0; virtual void SetThemeProvider(IFWL_ThemeProvider* pThemeProvider); @@ -90,7 +90,7 @@ class CFWL_Widget : public IFWL_WidgetDelegate { m_iLock--; } - void TransformTo(CFWL_Widget* pWidget, FX_FLOAT& fx, FX_FLOAT& fy); + CFX_PointF TransformTo(CFWL_Widget* pWidget, const CFX_PointF& point); CFX_Matrix GetMatrix(); IFWL_ThemeProvider* GetThemeProvider() const; @@ -173,7 +173,6 @@ class CFWL_Widget : public IFWL_WidgetDelegate { FX_FLOAT fMaxHeight, const CFX_RectF& rtAnchor, CFX_RectF& rtPopup); - bool GetScreenSize(FX_FLOAT& fx, FX_FLOAT& fy); void DrawBackground(CFX_Graphics* pGraphics, CFWL_Part iPartBk, IFWL_ThemeProvider* pTheme, diff --git a/xfa/fwl/cfwl_widgetmgr.cpp b/xfa/fwl/cfwl_widgetmgr.cpp index dc3b38346..7c0fddd41 100644 --- a/xfa/fwl/cfwl_widgetmgr.cpp +++ b/xfa/fwl/cfwl_widgetmgr.cpp @@ -160,7 +160,10 @@ void CFWL_WidgetMgr::RepaintWidget(CFWL_Widget* pWidget, if (!pNative) return; - pWidget->TransformTo(pNative, transformedRect.left, transformedRect.top); + CFX_PointF pos = pWidget->TransformTo( + pNative, CFX_PointF(transformedRect.left, transformedRect.top)); + transformedRect.left = pos.x; + transformedRect.top = pos.y; } AddRedrawCounts(pNative); m_pAdapter->RepaintWidget(pNative); @@ -255,28 +258,25 @@ void CFWL_WidgetMgr::SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild) { } CFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(CFWL_Widget* parent, - FX_FLOAT x, - FX_FLOAT y) { + const CFX_PointF& point) const { if (!parent) return nullptr; - FX_FLOAT x1; - FX_FLOAT y1; + CFX_PointF pos; CFWL_Widget* child = GetLastChildWidget(parent); while (child) { if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) { - x1 = x; - y1 = y; - CFX_Matrix matrixOnParent; CFX_Matrix m; m.SetIdentity(); + + CFX_Matrix matrixOnParent; m.SetReverse(matrixOnParent); - m.TransformPoint(x1, y1); + pos = m.Transform(point); + CFX_RectF bounds = child->GetWidgetRect(); - if (bounds.Contains(x1, y1)) { - x1 -= bounds.left; - y1 -= bounds.top; - return GetWidgetAtPoint(child, x1, y1); + if (bounds.Contains(pos)) { + pos -= bounds.TopLeft(); + return GetWidgetAtPoint(child, pos); } } child = GetPriorSiblingWidget(child); @@ -320,17 +320,18 @@ CFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader( return nullptr; } -void CFWL_WidgetMgr::GetSameGroupRadioButton( - CFWL_Widget* pRadioButton, - CFX_ArrayTemplate<CFWL_Widget*>& group) const { +std::vector<CFWL_Widget*> CFWL_WidgetMgr::GetSameGroupRadioButton( + CFWL_Widget* pRadioButton) const { CFWL_Widget* pFirst = GetFirstSiblingWidget(pRadioButton); if (!pFirst) pFirst = pRadioButton; - int32_t iGroup = CountRadioButtonGroup(pFirst); - if (iGroup < 2) - return; - group.Add(GetRadioButtonGroupHeader(pRadioButton)); + if (CountRadioButtonGroup(pFirst) < 2) + return std::vector<CFWL_Widget*>(); + + std::vector<CFWL_Widget*> group; + group.push_back(GetRadioButtonGroupHeader(pRadioButton)); + return group; } CFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(CFWL_Widget* pParent) const { @@ -372,7 +373,7 @@ CFWL_WidgetMgr::Item* CFWL_WidgetMgr::GetWidgetMgrItem( bool CFWL_WidgetMgr::IsAbleNative(CFWL_Widget* pWidget) const { if (!pWidget) return false; - if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) + if (!pWidget->IsInstance(FWL_CLASS_Form)) return false; uint32_t dwStyles = pWidget->GetStyles(); @@ -427,23 +428,20 @@ void CFWL_WidgetMgr::OnDrawWidget(CFWL_Widget* pWidget, if (!pWidget || !pGraphics) return; - CFX_RectF clipCopy = pWidget->GetWidgetRect(); - clipCopy.left = clipCopy.top = 0; - + CFX_RectF clipCopy(0, 0, pWidget->GetWidgetRect().Size()); CFX_RectF clipBounds; -#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ || \ - _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_ - pWidget->GetDelegate()->OnDrawWidget(pGraphics, pMatrix); - pGraphics->GetClipRect(clipBounds); - clipCopy = clipBounds; -#elif _FX_OS_ == _FX_MACOSX_ +#if _FX_OS_ == _FX_MACOSX_ if (IsFormDisabled()) { +#endif // _FX_OS_ == _FX_MACOSX_ + pWidget->GetDelegate()->OnDrawWidget(pGraphics, pMatrix); - pGraphics->GetClipRect(clipBounds); + clipBounds = pGraphics->GetClipRect(); clipCopy = clipBounds; + +#if _FX_OS_ == _FX_MACOSX_ } else { - clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d); + clipBounds = CFX_RectF(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d); const_cast<CFX_Matrix*>(pMatrix)->SetIdentity(); // FIXME: const cast. pWidget->GetDelegate()->OnDrawWidget(pGraphics, pMatrix); } @@ -485,7 +483,9 @@ void CFWL_WidgetMgr::DrawChild(CFWL_Widget* parent, widgetMatrix.Concat(*pMatrix); if (!bFormDisable) { - widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top); + CFX_PointF pos = widgetMatrix.Transform(clipBounds.TopLeft()); + clipBounds.left = pos.x; + clipBounds.top = pos.y; clipBounds.Intersect(rtClip); if (clipBounds.IsEmpty()) continue; @@ -517,8 +517,7 @@ bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget, return true; } - CFX_RectF rtWidget = pWidget->GetWidgetRect(); - rtWidget.left = rtWidget.top = 0; + CFX_RectF rtWidget(0, 0, pWidget->GetWidgetRect().Size()); pMatrix->TransformRect(rtWidget); if (!rtWidget.IntersectWith(rtDirty)) return false; @@ -529,11 +528,9 @@ bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget, return true; CFX_RectF rtChilds; - rtChilds.Empty(); bool bChildIntersectWithDirty = false; bool bOrginPtIntersectWidthChild = false; - bool bOrginPtIntersectWidthDirty = - rtDirty.Contains(rtWidget.left, rtWidget.top); + bool bOrginPtIntersectWidthDirty = rtDirty.Contains(rtWidget.TopLeft()); static FWL_NEEDREPAINTHITDATA hitPoint[kNeedRepaintHitPoints]; FXSYS_memset(hitPoint, 0, sizeof(hitPoint)); FX_FLOAT fxPiece = rtWidget.width / kNeedRepaintHitPiece; @@ -554,9 +551,8 @@ bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget, rtWidget.height + rtWidget.top; do { CFX_RectF rect = pChild->GetWidgetRect(); - CFX_RectF r = rect; - r.left += rtWidget.left; - r.top += rtWidget.top; + CFX_RectF r(rect.left + rtWidget.left, rect.top + rtWidget.top, rect.width, + rect.height); if (r.IsEmpty()) continue; if (r.Contains(rtDirty)) @@ -564,7 +560,7 @@ bool CFWL_WidgetMgr::IsNeedRepaint(CFWL_Widget* pWidget, if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) bChildIntersectWithDirty = true; if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) - bOrginPtIntersectWidthChild = rect.Contains(0, 0); + bOrginPtIntersectWidthChild = rect.Contains(CFX_PointF(0, 0)); if (rtChilds.IsEmpty()) rtChilds = rect; diff --git a/xfa/fwl/cfwl_widgetmgr.h b/xfa/fwl/cfwl_widgetmgr.h index 62ea60a18..2d436bd8e 100644 --- a/xfa/fwl/cfwl_widgetmgr.h +++ b/xfa/fwl/cfwl_widgetmgr.h @@ -9,9 +9,9 @@ #include <map> #include <memory> +#include <vector> #include "core/fxcrt/fx_system.h" -#include "xfa/fwl/fwl_error.h" #include "xfa/fwl/ifwl_widgetmgrdelegate.h" #include "xfa/fxgraphics/cfx_graphics.h" @@ -49,12 +49,13 @@ class CFWL_WidgetMgr : public CFWL_WidgetMgrDelegate { void SetOwner(CFWL_Widget* pOwner, CFWL_Widget* pOwned); void SetParent(CFWL_Widget* pParent, CFWL_Widget* pChild); - CFWL_Widget* GetWidgetAtPoint(CFWL_Widget* pParent, FX_FLOAT fx, FX_FLOAT fy); - + CFWL_Widget* GetWidgetAtPoint(CFWL_Widget* pParent, + const CFX_PointF& point) const; CFWL_Widget* NextTab(CFWL_Widget* parent, CFWL_Widget* focus, bool& bFind); - void GetSameGroupRadioButton(CFWL_Widget* pRadioButton, - CFX_ArrayTemplate<CFWL_Widget*>& group) const; + std::vector<CFWL_Widget*> GetSameGroupRadioButton( + CFWL_Widget* pRadioButton) const; + CFWL_Widget* GetDefaultButton(CFWL_Widget* pParent) const; void AddRedrawCounts(CFWL_Widget* pWidget); diff --git a/xfa/fwl/cfwl_widgetproperties.cpp b/xfa/fwl/cfwl_widgetproperties.cpp index 1b41105ef..fee957aec 100644 --- a/xfa/fwl/cfwl_widgetproperties.cpp +++ b/xfa/fwl/cfwl_widgetproperties.cpp @@ -12,8 +12,6 @@ CFWL_WidgetProperties::CFWL_WidgetProperties() m_dwStates(0), m_pThemeProvider(nullptr), m_pParent(nullptr), - m_pOwner(nullptr) { - m_rtWidget.Set(0, 0, 0, 0); -} + m_pOwner(nullptr) {} CFWL_WidgetProperties::~CFWL_WidgetProperties() {} diff --git a/xfa/fwl/fwl_error.h b/xfa/fwl/fwl_error.h deleted file mode 100644 index 8ef56d969..000000000 --- a/xfa/fwl/fwl_error.h +++ /dev/null @@ -1,19 +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 XFA_FWL_FWL_ERROR_H_ -#define XFA_FWL_FWL_ERROR_H_ - -enum class FWL_Error { - Succeeded = 0, - Indefinite, - ParameterInvalid, - PropertyInvalid, - IntermediateValueInvalid, - MethodNotSupported -}; - -#endif // XFA_FWL_FWL_ERROR_H_ diff --git a/xfa/fwl/theme/cfwl_carettp.cpp b/xfa/fwl/theme/cfwl_carettp.cpp index 06df3f51e..4a04f869f 100644 --- a/xfa/fwl/theme/cfwl_carettp.cpp +++ b/xfa/fwl/theme/cfwl_carettp.cpp @@ -40,7 +40,6 @@ void CFWL_CaretTP::DrawCaretBK(CFX_Graphics* pGraphics, CFX_Color* crFill, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); CFX_RectF rect = *pRect; path.AddRectangle(rect.left, rect.top, rect.width, rect.height); if (crFill) { diff --git a/xfa/fwl/theme/cfwl_checkboxtp.cpp b/xfa/fwl/theme/cfwl_checkboxtp.cpp index 0bc75ec66..1d185b4c3 100644 --- a/xfa/fwl/theme/cfwl_checkboxtp.cpp +++ b/xfa/fwl/theme/cfwl_checkboxtp.cpp @@ -79,7 +79,6 @@ void CFWL_CheckBoxTP::DrawSignCircle(CFX_Graphics* pGraphics, FX_ARGB argbFill, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); path.AddEllipse(*pRtSign); CFX_Color crFill(argbFill); pGraphics->SaveGraphState(); @@ -93,11 +92,12 @@ void CFWL_CheckBoxTP::DrawSignCross(CFX_Graphics* pGraphics, FX_ARGB argbFill, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); FX_FLOAT fRight = pRtSign->right(); FX_FLOAT fBottom = pRtSign->bottom(); - path.AddLine(pRtSign->left, pRtSign->top, fRight, fBottom); - path.AddLine(pRtSign->left, fBottom, fRight, pRtSign->top); + path.AddLine(pRtSign->TopLeft(), CFX_PointF(fRight, fBottom)); + path.AddLine(CFX_PointF(pRtSign->left, fBottom), + CFX_PointF(fRight, pRtSign->top)); + CFX_Color crFill(argbFill); pGraphics->SaveGraphState(); pGraphics->SetStrokeColor(&crFill); @@ -111,15 +111,15 @@ void CFWL_CheckBoxTP::DrawSignDiamond(CFX_Graphics* pGraphics, FX_ARGB argbFill, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); FX_FLOAT fWidth = pRtSign->width; FX_FLOAT fHeight = pRtSign->height; FX_FLOAT fBottom = pRtSign->bottom(); - path.MoveTo(pRtSign->left + fWidth / 2, pRtSign->top); - path.LineTo(pRtSign->left, pRtSign->top + fHeight / 2); - path.LineTo(pRtSign->left + fWidth / 2, fBottom); - path.LineTo(pRtSign->right(), pRtSign->top + fHeight / 2); - path.LineTo(pRtSign->left + fWidth / 2, pRtSign->top); + path.MoveTo(CFX_PointF(pRtSign->left + fWidth / 2, pRtSign->top)); + path.LineTo(CFX_PointF(pRtSign->left, pRtSign->top + fHeight / 2)); + path.LineTo(CFX_PointF(pRtSign->left + fWidth / 2, fBottom)); + path.LineTo(CFX_PointF(pRtSign->right(), pRtSign->top + fHeight / 2)); + path.LineTo(CFX_PointF(pRtSign->left + fWidth / 2, pRtSign->top)); + CFX_Color crFill(argbFill); pGraphics->SaveGraphState(); pGraphics->SetFillColor(&crFill); @@ -132,7 +132,6 @@ void CFWL_CheckBoxTP::DrawSignSquare(CFX_Graphics* pGraphics, FX_ARGB argbFill, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); path.AddRectangle(pRtSign->left, pRtSign->top, pRtSign->width, pRtSign->height); CFX_Color crFill(argbFill); @@ -147,28 +146,31 @@ void CFWL_CheckBoxTP::DrawSignStar(CFX_Graphics* pGraphics, FX_ARGB argbFill, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); FX_FLOAT fBottom = pRtSign->bottom(); FX_FLOAT fRadius = - (pRtSign->top - fBottom) / (1 + (FX_FLOAT)cos(FX_PI / 5.0f)); + (pRtSign->top - fBottom) / (1 + static_cast<FX_FLOAT>(cos(FX_PI / 5.0f))); CFX_PointF ptCenter((pRtSign->left + pRtSign->right()) / 2.0f, (pRtSign->top + fBottom) / 2.0f); - FX_FLOAT px[5], py[5]; + + CFX_PointF points[5]; FX_FLOAT fAngel = FX_PI / 10.0f; for (int32_t i = 0; i < 5; i++) { - px[i] = ptCenter.x + fRadius * (FX_FLOAT)cos(fAngel); - py[i] = ptCenter.y + fRadius * (FX_FLOAT)sin(fAngel); + points[i] = + ptCenter + CFX_PointF(fRadius * static_cast<FX_FLOAT>(cos(fAngel)), + fRadius * static_cast<FX_FLOAT>(sin(fAngel))); fAngel += FX_PI * 2 / 5.0f; } - path.MoveTo(px[0], py[0]); + + path.MoveTo(points[0]); int32_t nNext = 0; for (int32_t j = 0; j < 5; j++) { nNext += 2; - if (nNext >= 5) { + if (nNext >= 5) nNext -= 5; - } - path.LineTo(px[nNext], py[nNext]); + + path.LineTo(points[nNext]); } + CFX_Color crFill(argbFill); pGraphics->SaveGraphState(); pGraphics->SetFillColor(&crFill); @@ -217,7 +219,7 @@ void CFWL_CheckBoxTP::SetThemeData() { void CFWL_CheckBoxTP::InitCheckPath(FX_FLOAT fCheckLen) { if (!m_pCheckPath) { m_pCheckPath = pdfium::MakeUnique<CFX_Path>(); - m_pCheckPath->Create(); + FX_FLOAT fWidth = kSignPath; FX_FLOAT fHeight = -kSignPath; FX_FLOAT fBottom = kSignPath; @@ -238,48 +240,33 @@ void CFWL_CheckBoxTP::InitCheckPath(FX_FLOAT fCheckLen) { CFX_PointF pt54(fWidth / 3.4f, fBottom + fHeight / 3.5f); CFX_PointF pt51(fWidth / 3.6f, fBottom + fHeight / 4.0f); CFX_PointF pt15(fWidth / 3.5f, fBottom + fHeight * 3.5f / 5.0f); - m_pCheckPath->MoveTo(pt1.x, pt1.y); - FX_FLOAT px1 = pt12.x - pt1.x; - FX_FLOAT py1 = pt12.y - pt1.y; - FX_FLOAT px2 = pt21.x - pt2.x; - FX_FLOAT py2 = pt21.y - pt2.y; - m_pCheckPath->BezierTo(pt1.x + px1 * FX_BEZIER, pt1.y + py1 * FX_BEZIER, - pt2.x + px2 * FX_BEZIER, pt2.y + py2 * FX_BEZIER, - pt2.x, pt2.y); - px1 = pt23.x - pt2.x; - py1 = pt23.y - pt2.y; - px2 = pt32.x - pt3.x; - py2 = pt32.y - pt3.y; - m_pCheckPath->BezierTo(pt2.x + px1 * FX_BEZIER, pt2.y + py1 * FX_BEZIER, - pt3.x + px2 * FX_BEZIER, pt3.y + py2 * FX_BEZIER, - pt3.x, pt3.y); - px1 = pt34.x - pt3.x; - py1 = pt34.y - pt3.y; - px2 = pt43.x - pt4.x; - py2 = pt43.y - pt4.y; - m_pCheckPath->BezierTo(pt3.x + px1 * FX_BEZIER, pt3.y + py1 * FX_BEZIER, - pt4.x + px2 * FX_BEZIER, pt4.y + py2 * FX_BEZIER, - pt4.x, pt4.y); - px1 = pt45.x - pt4.x; - py1 = pt45.y - pt4.y; - px2 = pt54.x - pt5.x; - py2 = pt54.y - pt5.y; - m_pCheckPath->BezierTo(pt4.x + px1 * FX_BEZIER, pt4.y + py1 * FX_BEZIER, - pt5.x + px2 * FX_BEZIER, pt5.y + py2 * FX_BEZIER, - pt5.x, pt5.y); - px1 = pt51.x - pt5.x; - py1 = pt51.y - pt5.y; - px2 = pt15.x - pt1.x; - py2 = pt15.y - pt1.y; - m_pCheckPath->BezierTo(pt5.x + px1 * FX_BEZIER, pt5.y + py1 * FX_BEZIER, - pt1.x + px2 * FX_BEZIER, pt1.y + py2 * FX_BEZIER, - pt1.x, pt1.y); + m_pCheckPath->MoveTo(pt1); + + CFX_PointF p1 = CFX_PointF(pt12.x - pt1.x, pt12.y - pt1.y) * FX_BEZIER; + CFX_PointF p2 = CFX_PointF(pt21.x - pt2.x, pt21.y - pt2.y) * FX_BEZIER; + m_pCheckPath->BezierTo(pt1 + p1, pt2 + p2, pt2); + + p1 = CFX_PointF(pt23.x - pt2.x, pt23.y - pt2.y) * FX_BEZIER; + p2 = CFX_PointF(pt32.x - pt3.x, pt32.y - pt3.y) * FX_BEZIER; + m_pCheckPath->BezierTo(pt2 + p1, pt3 + p2, pt3); + + p1 = CFX_PointF(pt34.x - pt3.x, pt34.y - pt3.y) * FX_BEZIER; + p2 = CFX_PointF(pt43.x - pt4.x, pt43.y - pt4.y) * FX_BEZIER; + m_pCheckPath->BezierTo(pt3 + p1, pt4 + p2, pt4); + + p1 = CFX_PointF(pt45.x - pt4.x, pt45.y - pt4.y) * FX_BEZIER; + p2 = CFX_PointF(pt54.x - pt5.x, pt54.y - pt5.y) * FX_BEZIER; + m_pCheckPath->BezierTo(pt4 + p1, pt5 + p2, pt5); + + p1 = CFX_PointF(pt51.x - pt5.x, pt51.y - pt5.y) * FX_BEZIER; + p2 = CFX_PointF(pt15.x - pt1.x, pt15.y - pt1.y) * FX_BEZIER; + m_pCheckPath->BezierTo(pt5 + p1, pt1 + p2, pt1); + FX_FLOAT fScale = fCheckLen / kSignPath; - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, 0, 0); + CFX_Matrix mt(1, 0, 0, 1, 0, 0); mt.Scale(fScale, fScale); - CFX_PathData* pData = m_pCheckPath->GetPathData(); - pData->Transform(&mt); + + m_pCheckPath->TransformBy(mt); } } diff --git a/xfa/fwl/theme/cfwl_comboboxtp.cpp b/xfa/fwl/theme/cfwl_comboboxtp.cpp index 567cb2ec2..53a6eae72 100644 --- a/xfa/fwl/theme/cfwl_comboboxtp.cpp +++ b/xfa/fwl/theme/cfwl_comboboxtp.cpp @@ -28,7 +28,6 @@ void CFWL_ComboBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) { } case CFWL_Part::Background: { CFX_Path path; - path.Create(); CFX_RectF& rect = pParams->m_rtPart; path.AddRectangle(rect.left, rect.top, rect.width, rect.height); FX_ARGB argb_color; @@ -66,7 +65,6 @@ void CFWL_ComboBoxTP::DrawStrethHandler(CFWL_ThemeBackground* pParams, uint32_t dwStates, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); path.AddRectangle(pParams->m_rtPart.left, pParams->m_rtPart.top, pParams->m_rtPart.width - 1, pParams->m_rtPart.height); CFX_Color cr(ArgbEncode(0xff, 0xff, 0, 0)); diff --git a/xfa/fwl/theme/cfwl_edittp.cpp b/xfa/fwl/theme/cfwl_edittp.cpp index eee542320..43160177d 100644 --- a/xfa/fwl/theme/cfwl_edittp.cpp +++ b/xfa/fwl/theme/cfwl_edittp.cpp @@ -53,7 +53,6 @@ void CFWL_EditTP::DrawBackground(CFWL_ThemeBackground* pParams) { pGraphics->RestoreGraphState(); } else { CFX_Path path; - path.Create(); path.AddRectangle(pParams->m_rtPart.left, pParams->m_rtPart.top, pParams->m_rtPart.width, pParams->m_rtPart.height); CFX_Color cr(FWLTHEME_COLOR_Background); diff --git a/xfa/fwl/theme/cfwl_listboxtp.cpp b/xfa/fwl/theme/cfwl_listboxtp.cpp index 7a9ba92be..4e00420df 100644 --- a/xfa/fwl/theme/cfwl_listboxtp.cpp +++ b/xfa/fwl/theme/cfwl_listboxtp.cpp @@ -70,7 +70,6 @@ void CFWL_ListBoxTP::DrawListBoxItem(CFX_Graphics* pGraphics, pGraphics->SetFillColor(&crFill); CFX_RectF rt(*prtItem); CFX_Path path; - path.Create(); #if (_FX_OS_ == _FX_MACOSX_) path.AddRectangle(rt.left, rt.top, rt.width - 1, rt.height - 1); #else diff --git a/xfa/fwl/theme/cfwl_monthcalendartp.cpp b/xfa/fwl/theme/cfwl_monthcalendartp.cpp index d98cf24f8..b14109d01 100644 --- a/xfa/fwl/theme/cfwl_monthcalendartp.cpp +++ b/xfa/fwl/theme/cfwl_monthcalendartp.cpp @@ -105,10 +105,10 @@ void CFWL_MonthCalendarTP::DrawText(CFWL_ThemeText* pParams) { void CFWL_MonthCalendarTP::DrawTotalBK(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); CFX_RectF rtTotal(pParams->m_rtPart); path.AddRectangle(rtTotal.left, rtTotal.top, rtTotal.width, rtTotal.height); pParams->m_pGraphics->SaveGraphState(); + CFX_Color clrBK(m_pThemeData->clrBK); pParams->m_pGraphics->SetFillColor(&clrBK); pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); @@ -118,10 +118,10 @@ void CFWL_MonthCalendarTP::DrawTotalBK(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawHeadBk(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); CFX_RectF rtHead = pParams->m_rtPart; path.AddRectangle(rtHead.left, rtHead.top, rtHead.width, rtHead.height); pParams->m_pGraphics->SaveGraphState(); + CFX_Color clrHeadBK(m_pThemeData->clrBK); pParams->m_pGraphics->SetFillColor(&clrHeadBK); pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); @@ -131,11 +131,10 @@ void CFWL_MonthCalendarTP::DrawHeadBk(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawLButton(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - CFX_RectF rtLBtn; - rtLBtn = pParams->m_rtPart; + CFX_RectF rtLBtn = pParams->m_rtPart; path.AddRectangle(rtLBtn.left, rtLBtn.top, rtLBtn.width, rtLBtn.height); pParams->m_pGraphics->SaveGraphState(); + CFX_Color clrLBtnEdge(ArgbEncode(0xff, 205, 219, 243)); pParams->m_pGraphics->SetStrokeColor(&clrLBtnEdge); pParams->m_pGraphics->StrokePath(&path, pMatrix); @@ -148,12 +147,15 @@ void CFWL_MonthCalendarTP::DrawLButton(CFWL_ThemeBackground* pParams, pParams->m_pGraphics->SetFillColor(&clrLBtnFill); pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); } + path.Clear(); - path.MoveTo(rtLBtn.left + rtLBtn.Width() / 3 * 2, - rtLBtn.top + rtLBtn.height / 4); - path.LineTo(rtLBtn.left + rtLBtn.Width() / 3, rtLBtn.top + rtLBtn.height / 2); - path.LineTo(rtLBtn.left + rtLBtn.Width() / 3 * 2, - rtLBtn.bottom() - rtLBtn.height / 4); + path.MoveTo(CFX_PointF(rtLBtn.left + rtLBtn.Width() / 3 * 2, + rtLBtn.top + rtLBtn.height / 4)); + path.LineTo(CFX_PointF(rtLBtn.left + rtLBtn.Width() / 3, + rtLBtn.top + rtLBtn.height / 2)); + path.LineTo(CFX_PointF(rtLBtn.left + rtLBtn.Width() / 3 * 2, + rtLBtn.bottom() - rtLBtn.height / 4)); + CFX_Color clrFlag(ArgbEncode(0xff, 50, 104, 205)); pParams->m_pGraphics->SetStrokeColor(&clrFlag); pParams->m_pGraphics->StrokePath(&path, pMatrix); @@ -163,11 +165,10 @@ void CFWL_MonthCalendarTP::DrawLButton(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawRButton(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - CFX_RectF rtRBtn; - rtRBtn = pParams->m_rtPart; + CFX_RectF rtRBtn = pParams->m_rtPart; path.AddRectangle(rtRBtn.left, rtRBtn.top, rtRBtn.width, rtRBtn.height); pParams->m_pGraphics->SaveGraphState(); + CFX_Color clrRBtnEdge(ArgbEncode(0xff, 205, 219, 243)); pParams->m_pGraphics->SetStrokeColor(&clrRBtnEdge); pParams->m_pGraphics->StrokePath(&path, pMatrix); @@ -180,12 +181,15 @@ void CFWL_MonthCalendarTP::DrawRButton(CFWL_ThemeBackground* pParams, pParams->m_pGraphics->SetFillColor(&clrRBtnFill); pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); } + path.Clear(); - path.MoveTo(rtRBtn.left + rtRBtn.Width() / 3, rtRBtn.top + rtRBtn.height / 4); - path.LineTo(rtRBtn.left + rtRBtn.Width() / 3 * 2, - rtRBtn.top + rtRBtn.height / 2); - path.LineTo(rtRBtn.left + rtRBtn.Width() / 3, - rtRBtn.bottom() - rtRBtn.height / 4); + path.MoveTo(CFX_PointF(rtRBtn.left + rtRBtn.Width() / 3, + rtRBtn.top + rtRBtn.height / 4)); + path.LineTo(CFX_PointF(rtRBtn.left + rtRBtn.Width() / 3 * 2, + rtRBtn.top + rtRBtn.height / 2)); + path.LineTo(CFX_PointF(rtRBtn.left + rtRBtn.Width() / 3, + rtRBtn.bottom() - rtRBtn.height / 4)); + CFX_Color clrFlag(ArgbEncode(0xff, 50, 104, 205)); pParams->m_pGraphics->SetStrokeColor(&clrFlag); pParams->m_pGraphics->StrokePath(&path, pMatrix); @@ -195,12 +199,11 @@ void CFWL_MonthCalendarTP::DrawRButton(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawHSeperator(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - CFX_RectF rtHSep; - rtHSep = pParams->m_rtPart; - path.MoveTo(rtHSep.left, rtHSep.top + rtHSep.height / 2); - path.LineTo(rtHSep.right(), rtHSep.top + rtHSep.height / 2); + CFX_RectF rtHSep = pParams->m_rtPart; + path.MoveTo(CFX_PointF(rtHSep.left, rtHSep.top + rtHSep.height / 2)); + path.LineTo(CFX_PointF(rtHSep.right(), rtHSep.top + rtHSep.height / 2)); pParams->m_pGraphics->SaveGraphState(); + CFX_Color clrHSep(m_pThemeData->clrSeperator); pParams->m_pGraphics->SetStrokeColor(&clrHSep); pParams->m_pGraphics->StrokePath(&path, pMatrix); @@ -210,12 +213,11 @@ void CFWL_MonthCalendarTP::DrawHSeperator(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawWeekNumSep(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - CFX_RectF rtWeekSep; - rtWeekSep = pParams->m_rtPart; - path.MoveTo(rtWeekSep.left, rtWeekSep.top); - path.LineTo(rtWeekSep.left, rtWeekSep.bottom()); + CFX_RectF rtWeekSep = pParams->m_rtPart; + path.MoveTo(rtWeekSep.TopLeft()); + path.LineTo(rtWeekSep.BottomLeft()); pParams->m_pGraphics->SaveGraphState(); + CFX_Color clrHSep(m_pThemeData->clrSeperator); pParams->m_pGraphics->SetStrokeColor(&clrHSep); pParams->m_pGraphics->StrokePath(&path, pMatrix); @@ -227,9 +229,7 @@ void CFWL_MonthCalendarTP::DrawDatesInBK(CFWL_ThemeBackground* pParams, pParams->m_pGraphics->SaveGraphState(); if (pParams->m_dwStates & CFWL_PartState_Selected) { CFX_Path path; - path.Create(); - CFX_RectF rtSelDay; - rtSelDay = pParams->m_rtPart; + CFX_RectF rtSelDay = pParams->m_rtPart; path.AddRectangle(rtSelDay.left, rtSelDay.top, rtSelDay.width, rtSelDay.height); CFX_Color clrSelDayBK(m_pThemeData->clrDatesSelectedBK); @@ -237,9 +237,7 @@ void CFWL_MonthCalendarTP::DrawDatesInBK(CFWL_ThemeBackground* pParams, pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); } else if (pParams->m_dwStates & CFWL_PartState_Hovered) { CFX_Path path; - path.Create(); - CFX_RectF rtSelDay; - rtSelDay = pParams->m_rtPart; + CFX_RectF rtSelDay = pParams->m_rtPart; path.AddRectangle(rtSelDay.left, rtSelDay.top, rtSelDay.width, rtSelDay.height); CFX_Color clrSelDayBK(m_pThemeData->clrDatesHoverBK); @@ -252,9 +250,7 @@ void CFWL_MonthCalendarTP::DrawDatesInBK(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawDatesInCircle(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - CFX_RectF rtSelDay; - rtSelDay = pParams->m_rtPart; + CFX_RectF rtSelDay = pParams->m_rtPart; path.AddRectangle(rtSelDay.left, rtSelDay.top, rtSelDay.width, rtSelDay.height); pParams->m_pGraphics->SaveGraphState(); @@ -267,9 +263,7 @@ void CFWL_MonthCalendarTP::DrawDatesInCircle(CFWL_ThemeBackground* pParams, void CFWL_MonthCalendarTP::DrawTodayCircle(CFWL_ThemeBackground* pParams, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - CFX_RectF rtTodayCircle; - rtTodayCircle = pParams->m_rtPart; + CFX_RectF rtTodayCircle = pParams->m_rtPart; path.AddRectangle(rtTodayCircle.left, rtTodayCircle.top, rtTodayCircle.width, rtTodayCircle.height); pParams->m_pGraphics->SaveGraphState(); diff --git a/xfa/fwl/theme/cfwl_pushbuttontp.cpp b/xfa/fwl/theme/cfwl_pushbuttontp.cpp index a1e57836f..56268a850 100644 --- a/xfa/fwl/theme/cfwl_pushbuttontp.cpp +++ b/xfa/fwl/theme/cfwl_pushbuttontp.cpp @@ -31,39 +31,50 @@ void CFWL_PushButtonTP::DrawBackground(CFWL_ThemeBackground* pParams) { CFX_RectF& rect = pParams->m_rtPart; FX_FLOAT fRight = rect.right(); FX_FLOAT fBottom = rect.bottom(); + CFX_Path strokePath; - strokePath.Create(); - strokePath.MoveTo(rect.left + PUSHBUTTON_SIZE_Corner, rect.top); - strokePath.LineTo(fRight - PUSHBUTTON_SIZE_Corner, rect.top); - strokePath.LineTo(fRight, rect.top + PUSHBUTTON_SIZE_Corner); - strokePath.LineTo(fRight, fBottom - PUSHBUTTON_SIZE_Corner); - strokePath.LineTo(fRight - PUSHBUTTON_SIZE_Corner, fBottom); - strokePath.LineTo(rect.left + PUSHBUTTON_SIZE_Corner, fBottom); - strokePath.LineTo(rect.left, fBottom - PUSHBUTTON_SIZE_Corner); - strokePath.LineTo(rect.left, rect.top + PUSHBUTTON_SIZE_Corner); - strokePath.LineTo(rect.left + PUSHBUTTON_SIZE_Corner, rect.top); + strokePath.MoveTo( + CFX_PointF(rect.left + PUSHBUTTON_SIZE_Corner, rect.top)); + strokePath.LineTo(CFX_PointF(fRight - PUSHBUTTON_SIZE_Corner, rect.top)); + strokePath.LineTo(CFX_PointF(fRight, rect.top + PUSHBUTTON_SIZE_Corner)); + strokePath.LineTo(CFX_PointF(fRight, fBottom - PUSHBUTTON_SIZE_Corner)); + strokePath.LineTo(CFX_PointF(fRight - PUSHBUTTON_SIZE_Corner, fBottom)); + strokePath.LineTo( + CFX_PointF(rect.left + PUSHBUTTON_SIZE_Corner, fBottom)); + strokePath.LineTo( + CFX_PointF(rect.left, fBottom - PUSHBUTTON_SIZE_Corner)); + strokePath.LineTo( + CFX_PointF(rect.left, rect.top + PUSHBUTTON_SIZE_Corner)); + strokePath.LineTo( + CFX_PointF(rect.left + PUSHBUTTON_SIZE_Corner, rect.top)); + CFX_Path fillPath; - fillPath.Create(); fillPath.AddSubpath(&strokePath); + CFX_Graphics* pGraphics = pParams->m_pGraphics; pGraphics->SaveGraphState(); + CFX_RectF rtInner(rect); rtInner.Deflate(PUSHBUTTON_SIZE_Corner + 1, PUSHBUTTON_SIZE_Corner + 1, PUSHBUTTON_SIZE_Corner, PUSHBUTTON_SIZE_Corner); fillPath.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); + int32_t iColor = GetColorID(pParams->m_dwStates); DrawAxialShading(pGraphics, rect.left + PUSHBUTTON_SIZE_Corner, rect.top, rect.left + PUSHBUTTON_SIZE_Corner, rect.bottom(), m_pThemeData->clrStart[iColor], m_pThemeData->clrEnd[iColor], &fillPath, FXFILL_ALTERNATE, &pParams->m_matrix); + CFX_Color crStroke(m_pThemeData->clrBorder[iColor]); pGraphics->SetStrokeColor(&crStroke); pGraphics->StrokePath(&strokePath, &pParams->m_matrix); + fillPath.Clear(); fillPath.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); + CFX_Color crFill(m_pThemeData->clrFill[iColor]); pGraphics->SetFillColor(&crFill); pGraphics->FillPath(&fillPath, FXFILL_WINDING, &pParams->m_matrix); diff --git a/xfa/fwl/theme/cfwl_scrollbartp.cpp b/xfa/fwl/theme/cfwl_scrollbartp.cpp index 4cd2fb376..121d4dea3 100644 --- a/xfa/fwl/theme/cfwl_scrollbartp.cpp +++ b/xfa/fwl/theme/cfwl_scrollbartp.cpp @@ -81,7 +81,6 @@ void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics* pGraphics, return; CFX_Path path; - path.Create(); CFX_RectF rect(*pRect); if (bVert) { rect.Deflate(1, 0); @@ -124,36 +123,39 @@ void CFWL_ScrollBarTP::DrawPaw(CFX_Graphics* pGraphics, FWLTHEME_STATE eState, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); if (bVert) { FX_FLOAT fPawLen = kPawLength; if (pRect->width / 2 <= fPawLen) { fPawLen = (pRect->width - 6) / 2; } + FX_FLOAT fX = pRect->left + pRect->width / 4; FX_FLOAT fY = pRect->top + pRect->height / 2; - path.MoveTo(fX, fY - 4); - path.LineTo(fX + fPawLen, fY - 4); - path.MoveTo(fX, fY - 2); - path.LineTo(fX + fPawLen, fY - 2); - path.MoveTo(fX, fY); - path.LineTo(fX + fPawLen, fY); - path.MoveTo(fX, fY + 2); - path.LineTo(fX + fPawLen, fY + 2); + path.MoveTo(CFX_PointF(fX, fY - 4)); + path.LineTo(CFX_PointF(fX + fPawLen, fY - 4)); + path.MoveTo(CFX_PointF(fX, fY - 2)); + path.LineTo(CFX_PointF(fX + fPawLen, fY - 2)); + path.MoveTo(CFX_PointF(fX, fY)); + path.LineTo(CFX_PointF(fX + fPawLen, fY)); + path.MoveTo(CFX_PointF(fX, fY + 2)); + path.LineTo(CFX_PointF(fX + fPawLen, fY + 2)); + CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]); pGraphics->SetLineWidth(1); pGraphics->SetStrokeColor(&clrLight); pGraphics->StrokePath(&path); fX++; + path.Clear(); - path.MoveTo(fX, fY - 3); - path.LineTo(fX + fPawLen, fY - 3); - path.MoveTo(fX, fY - 1); - path.LineTo(fX + fPawLen, fY - 1); - path.MoveTo(fX, fY + 1); - path.LineTo(fX + fPawLen, fY + 1); - path.MoveTo(fX, fY + 3); - path.LineTo(fX + fPawLen, fY + 3); + path.MoveTo(CFX_PointF(fX, fY - 3)); + path.LineTo(CFX_PointF(fX + fPawLen, fY - 3)); + path.MoveTo(CFX_PointF(fX, fY - 1)); + path.LineTo(CFX_PointF(fX + fPawLen, fY - 1)); + path.MoveTo(CFX_PointF(fX, fY + 1)); + path.LineTo(CFX_PointF(fX + fPawLen, fY + 1)); + path.MoveTo(CFX_PointF(fX, fY + 3)); + path.LineTo(CFX_PointF(fX + fPawLen, fY + 3)); + CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]); pGraphics->SetLineWidth(1); pGraphics->SetStrokeColor(&clrDark); @@ -163,30 +165,34 @@ void CFWL_ScrollBarTP::DrawPaw(CFX_Graphics* pGraphics, if (pRect->height / 2 <= fPawLen) { fPawLen = (pRect->height - 6) / 2; } + FX_FLOAT fX = pRect->left + pRect->width / 2; FX_FLOAT fY = pRect->top + pRect->height / 4; - path.MoveTo(fX - 4, fY); - path.LineTo(fX - 4, fY + fPawLen); - path.MoveTo(fX - 2, fY); - path.LineTo(fX - 2, fY + fPawLen); - path.MoveTo(fX, fY); - path.LineTo(fX, fY + fPawLen); - path.MoveTo(fX + 2, fY); - path.LineTo(fX + 2, fY + fPawLen); + path.MoveTo(CFX_PointF(fX - 4, fY)); + path.LineTo(CFX_PointF(fX - 4, fY + fPawLen)); + path.MoveTo(CFX_PointF(fX - 2, fY)); + path.LineTo(CFX_PointF(fX - 2, fY + fPawLen)); + path.MoveTo(CFX_PointF(fX, fY)); + path.LineTo(CFX_PointF(fX, fY + fPawLen)); + path.MoveTo(CFX_PointF(fX + 2, fY)); + path.LineTo(CFX_PointF(fX + 2, fY + fPawLen)); + CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]); pGraphics->SetLineWidth(1); pGraphics->SetStrokeColor(&clrLight); pGraphics->StrokePath(&path, pMatrix); fY++; + path.Clear(); - path.MoveTo(fX - 3, fY); - path.LineTo(fX - 3, fY + fPawLen); - path.MoveTo(fX - 1, fY); - path.LineTo(fX - 1, fY + fPawLen); - path.MoveTo(fX + 1, fY); - path.LineTo(fX + 1, fY + fPawLen); - path.MoveTo(fX + 3, fY); - path.LineTo(fX + 3, fY + fPawLen); + path.MoveTo(CFX_PointF(fX - 3, fY)); + path.LineTo(CFX_PointF(fX - 3, fY + fPawLen)); + path.MoveTo(CFX_PointF(fX - 1, fY)); + path.LineTo(CFX_PointF(fX - 1, fY + fPawLen)); + path.MoveTo(CFX_PointF(fX + 1, fY)); + path.LineTo(CFX_PointF(fX + 1, fY + fPawLen)); + path.MoveTo(CFX_PointF(fX + 3, fY)); + path.LineTo(CFX_PointF(fX + 3, fY + fPawLen)); + CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]); pGraphics->SetLineWidth(1); pGraphics->SetStrokeColor(&clrDark); @@ -206,7 +212,6 @@ void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics* pGraphics, pGraphics->SaveGraphState(); CFX_Color colorLine(ArgbEncode(255, 238, 237, 229)); CFX_Path path; - path.Create(); FX_FLOAT fRight = pRect->right(); FX_FLOAT fBottom = pRect->bottom(); if (bVert) { diff --git a/xfa/fwl/theme/cfwl_widgettp.cpp b/xfa/fwl/theme/cfwl_widgettp.cpp index a0d6b4c54..fbcbcffb8 100644 --- a/xfa/fwl/theme/cfwl_widgettp.cpp +++ b/xfa/fwl/theme/cfwl_widgettp.cpp @@ -84,8 +84,7 @@ void CFWL_WidgetTP::InitTTO() { if (m_pTextOut) return; - m_pFDEFont = - CFWL_FontManager::GetInstance()->FindFont(FX_WSTRC(L"Helvetica"), 0, 0); + m_pFDEFont = CFWL_FontManager::GetInstance()->FindFont(L"Helvetica", 0, 0); m_pTextOut = pdfium::MakeUnique<CFDE_TextOut>(); m_pTextOut->SetFont(m_pFDEFont); m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize); @@ -105,7 +104,6 @@ void CFWL_WidgetTP::DrawBorder(CFX_Graphics* pGraphics, if (!pRect) return; CFX_Path path; - path.Create(); path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2, pRect->height - 2); @@ -134,7 +132,6 @@ void CFWL_WidgetTP::FillSoildRect(CFX_Graphics* pGraphics, CFX_Color crFill(fillColor); pGraphics->SetFillColor(&crFill); CFX_Path path; - path.Create(); path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix); pGraphics->RestoreGraphState(); @@ -176,7 +173,6 @@ void CFWL_WidgetTP::DrawFocus(CFX_Graphics* pGraphics, FX_FLOAT DashPattern[2] = {1, 1}; pGraphics->SetLineDash(0.0f, DashPattern, 2); CFX_Path path; - path.Create(); path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height); pGraphics->StrokePath(&path, pMatrix); pGraphics->RestoreGraphState(); @@ -194,42 +190,41 @@ void CFWL_WidgetTP::DrawArrow(CFX_Graphics* pGraphics, FX_FLOAT fTop = (FX_FLOAT)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5); CFX_Path path; - path.Create(); switch (eDict) { case FWLTHEME_DIRECTION_Down: { - path.MoveTo(fLeft, fTop + 1); - path.LineTo(fLeft + 4, fTop + 5); - path.LineTo(fLeft + 8, fTop + 1); - path.LineTo(fLeft + 7, fTop); - path.LineTo(fLeft + 4, fTop + 3); - path.LineTo(fLeft + 1, fTop); + path.MoveTo(CFX_PointF(fLeft, fTop + 1)); + path.LineTo(CFX_PointF(fLeft + 4, fTop + 5)); + path.LineTo(CFX_PointF(fLeft + 8, fTop + 1)); + path.LineTo(CFX_PointF(fLeft + 7, fTop)); + path.LineTo(CFX_PointF(fLeft + 4, fTop + 3)); + path.LineTo(CFX_PointF(fLeft + 1, fTop)); break; } case FWLTHEME_DIRECTION_Up: { - path.MoveTo(fLeft, fTop + 4); - path.LineTo(fLeft + 4, fTop); - path.LineTo(fLeft + 8, fTop + 4); - path.LineTo(fLeft + 7, fTop + 5); - path.LineTo(fLeft + 4, fTop + 2); - path.LineTo(fLeft + 1, fTop + 5); + path.MoveTo(CFX_PointF(fLeft, fTop + 4)); + path.LineTo(CFX_PointF(fLeft + 4, fTop)); + path.LineTo(CFX_PointF(fLeft + 8, fTop + 4)); + path.LineTo(CFX_PointF(fLeft + 7, fTop + 5)); + path.LineTo(CFX_PointF(fLeft + 4, fTop + 2)); + path.LineTo(CFX_PointF(fLeft + 1, fTop + 5)); break; } case FWLTHEME_DIRECTION_Right: { - path.MoveTo(fLeft + 1, fTop); - path.LineTo(fLeft + 5, fTop + 4); - path.LineTo(fLeft + 1, fTop + 8); - path.LineTo(fLeft, fTop + 7); - path.LineTo(fLeft + 3, fTop + 4); - path.LineTo(fLeft, fTop + 1); + path.MoveTo(CFX_PointF(fLeft + 1, fTop)); + path.LineTo(CFX_PointF(fLeft + 5, fTop + 4)); + path.LineTo(CFX_PointF(fLeft + 1, fTop + 8)); + path.LineTo(CFX_PointF(fLeft, fTop + 7)); + path.LineTo(CFX_PointF(fLeft + 3, fTop + 4)); + path.LineTo(CFX_PointF(fLeft, fTop + 1)); break; } case FWLTHEME_DIRECTION_Left: { - path.MoveTo(fLeft, fTop + 4); - path.LineTo(fLeft + 4, fTop); - path.LineTo(fLeft + 5, fTop + 1); - path.LineTo(fLeft + 2, fTop + 4); - path.LineTo(fLeft + 5, fTop + 7); - path.LineTo(fLeft + 4, fTop + 8); + path.MoveTo(CFX_PointF(fLeft, fTop + 4)); + path.LineTo(CFX_PointF(fLeft + 4, fTop)); + path.LineTo(CFX_PointF(fLeft + 5, fTop + 1)); + path.LineTo(CFX_PointF(fLeft + 2, fTop + 4)); + path.LineTo(CFX_PointF(fLeft + 5, fTop + 7)); + path.LineTo(CFX_PointF(fLeft + 4, fTop + 8)); break; } } @@ -243,8 +238,6 @@ void CFWL_WidgetTP::DrawBtn(CFX_Graphics* pGraphics, FWLTHEME_STATE eState, CFX_Matrix* pMatrix) { CFX_Path path; - path.Create(); - InitializeArrowColorData(); FX_FLOAT fRight = pRect->right(); diff --git a/xfa/fwl/theme/cfwl_widgettp.h b/xfa/fwl/theme/cfwl_widgettp.h index 794c67be8..c81950793 100644 --- a/xfa/fwl/theme/cfwl_widgettp.h +++ b/xfa/fwl/theme/cfwl_widgettp.h @@ -14,7 +14,6 @@ #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" #include "xfa/fgas/font/cfgas_gefont.h" -#include "xfa/fwl/fwl_error.h" #include "xfa/fwl/theme/cfwl_utils.h" #include "xfa/fxgraphics/cfx_graphics.h" diff --git a/xfa/fxbarcode/BC_TwoDimWriter.cpp b/xfa/fxbarcode/BC_TwoDimWriter.cpp index 84678a81d..b9aae361d 100644 --- a/xfa/fxbarcode/BC_TwoDimWriter.cpp +++ b/xfa/fxbarcode/BC_TwoDimWriter.cpp @@ -145,7 +145,8 @@ void CBC_TwoDimWriter::RenderResult(uint8_t* code, inputX++, outputX += multiX) { if (code[inputX + inputY * inputWidth] == 1) { m_output->SetRegion(outputX, outputY, multiX, multiY, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } } diff --git a/xfa/fxbarcode/BC_UtilCodingConvert.cpp b/xfa/fxbarcode/BC_UtilCodingConvert.cpp index 73475751f..c06cffc21 100644 --- a/xfa/fxbarcode/BC_UtilCodingConvert.cpp +++ b/xfa/fxbarcode/BC_UtilCodingConvert.cpp @@ -22,7 +22,7 @@ void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString& src, } void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString& src, - CFX_ByteArray& dst) { + CFX_ArrayTemplate<uint8_t>& dst) { CFX_WideString unicode = CFX_WideString::FromLocal(src.AsStringC()); CFX_ByteString utf8 = unicode.UTF8Encode(); for (int32_t i = 0; i < utf8.GetLength(); i++) { @@ -30,7 +30,7 @@ void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString& src, } } -void CBC_UtilCodingConvert::Utf8ToLocale(const CFX_ByteArray& src, +void CBC_UtilCodingConvert::Utf8ToLocale(const CFX_ArrayTemplate<uint8_t>& src, CFX_ByteString& dst) { CFX_ByteString utf8; for (int32_t i = 0; i < src.GetSize(); i++) { diff --git a/xfa/fxbarcode/BC_UtilCodingConvert.h b/xfa/fxbarcode/BC_UtilCodingConvert.h index 698cd857d..859eeea1e 100644 --- a/xfa/fxbarcode/BC_UtilCodingConvert.h +++ b/xfa/fxbarcode/BC_UtilCodingConvert.h @@ -17,8 +17,10 @@ class CBC_UtilCodingConvert { CFX_ByteString& result); static void LocaleToUtf8(const CFX_ByteString& source, CFX_ByteString& result); - static void LocaleToUtf8(const CFX_ByteString& source, CFX_ByteArray& result); - static void Utf8ToLocale(const CFX_ByteArray& source, CFX_ByteString& result); + static void LocaleToUtf8(const CFX_ByteString& source, + CFX_ArrayTemplate<uint8_t>& result); + static void Utf8ToLocale(const CFX_ArrayTemplate<uint8_t>& source, + CFX_ByteString& result); static void Utf8ToLocale(const uint8_t* source, int32_t count, CFX_ByteString& result); diff --git a/xfa/fxbarcode/BC_Utils.cpp b/xfa/fxbarcode/BC_Utils.cpp index 807b04861..5d881c7be 100644 --- a/xfa/fxbarcode/BC_Utils.cpp +++ b/xfa/fxbarcode/BC_Utils.cpp @@ -26,7 +26,8 @@ void BC_FX_ByteString_Append(CFX_ByteString& dst, int32_t count, FX_CHAR c) { dst += c; } } -void BC_FX_ByteString_Append(CFX_ByteString& dst, const CFX_ByteArray& ba) { +void BC_FX_ByteString_Append(CFX_ByteString& dst, + const CFX_ArrayTemplate<uint8_t>& ba) { for (int32_t i = 0; i < ba.GetSize(); i++) { dst += ba[i]; } diff --git a/xfa/fxbarcode/cbc_codabar.cpp b/xfa/fxbarcode/cbc_codabar.cpp index e8e8cdc99..6f6ab4a96 100644 --- a/xfa/fxbarcode/cbc_codabar.cpp +++ b/xfa/fxbarcode/cbc_codabar.cpp @@ -70,11 +70,13 @@ bool CBC_Codabar::Encode(const CFX_WideStringC& contents, m_renderContents = filtercontents; uint8_t* data = static_cast<CBC_OnedCodaBarWriter*>(m_pBCWriter.get()) ->Encode(byteString, format, outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderResult(filtercontents.AsStringC(), data, outWidth, isDevice, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -86,7 +88,8 @@ bool CBC_Codabar::RenderDevice(CFX_RenderDevice* device, ->encodedContents(m_renderContents.AsStringC()); static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderDeviceResult(device, matrix, renderCon.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -96,7 +99,8 @@ bool CBC_Codabar::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { ->encodedContents(m_renderContents.AsStringC()); static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, renderCon.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_code128.cpp b/xfa/fxbarcode/cbc_code128.cpp index 99c3c21e0..35bd136fd 100644 --- a/xfa/fxbarcode/cbc_code128.cpp +++ b/xfa/fxbarcode/cbc_code128.cpp @@ -58,11 +58,13 @@ bool CBC_Code128::Encode(const CFX_WideStringC& contents, CFX_ByteString byteString = encodeContents.UTF8Encode(); uint8_t* data = static_cast<CBC_OnedCode128Writer*>(m_pBCWriter.get()) ->Encode(byteString, format, outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderResult(encodeContents.AsStringC(), data, outWidth, isDevice, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -71,14 +73,16 @@ bool CBC_Code128::RenderDevice(CFX_RenderDevice* device, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderDeviceResult(device, matrix, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } bool CBC_Code128::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_code39.cpp b/xfa/fxbarcode/cbc_code39.cpp index e90abb9d7..af45ad406 100644 --- a/xfa/fxbarcode/cbc_code39.cpp +++ b/xfa/fxbarcode/cbc_code39.cpp @@ -47,11 +47,13 @@ bool CBC_Code39::Encode(const CFX_WideStringC& contents, CFX_ByteString byteString = filtercontents.UTF8Encode(); uint8_t* data = static_cast<CBC_OnedCode39Writer*>(m_pBCWriter.get()) ->Encode(byteString, format, outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderResult(renderContents.AsStringC(), data, outWidth, isDevice, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -63,7 +65,8 @@ bool CBC_Code39::RenderDevice(CFX_RenderDevice* device, ->encodedContents(m_renderContents.AsStringC(), e); static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderDeviceResult(device, matrix, renderCon.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -73,7 +76,8 @@ bool CBC_Code39::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { ->encodedContents(m_renderContents.AsStringC(), e); static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, renderCon.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_datamatrix.cpp b/xfa/fxbarcode/cbc_datamatrix.cpp index 86ca75d04..6122368e8 100644 --- a/xfa/fxbarcode/cbc_datamatrix.cpp +++ b/xfa/fxbarcode/cbc_datamatrix.cpp @@ -35,11 +35,13 @@ bool CBC_DataMatrix::Encode(const CFX_WideStringC& contents, uint8_t* data = static_cast<CBC_DataMatrixWriter*>(m_pBCWriter.get()) ->Encode(CFX_WideString(contents), outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_TwoDimWriter*>(m_pBCWriter.get()) ->RenderResult(data, outWidth, outHeight, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -54,7 +56,8 @@ bool CBC_DataMatrix::RenderDevice(CFX_RenderDevice* device, bool CBC_DataMatrix::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_TwoDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_ean13.cpp b/xfa/fxbarcode/cbc_ean13.cpp index d69689716..450fba04c 100644 --- a/xfa/fxbarcode/cbc_ean13.cpp +++ b/xfa/fxbarcode/cbc_ean13.cpp @@ -63,11 +63,13 @@ bool CBC_EAN13::Encode(const CFX_WideStringC& contents, m_renderContents = encodeContents; uint8_t* data = static_cast<CBC_OnedEAN13Writer*>(m_pBCWriter.get()) ->Encode(byteString, format, outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderResult(encodeContents.AsStringC(), data, outWidth, isDevice, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -76,14 +78,16 @@ bool CBC_EAN13::RenderDevice(CFX_RenderDevice* device, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderDeviceResult(device, matrix, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } bool CBC_EAN13::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_ean8.cpp b/xfa/fxbarcode/cbc_ean8.cpp index 2c1ce24b5..64ba61733 100644 --- a/xfa/fxbarcode/cbc_ean8.cpp +++ b/xfa/fxbarcode/cbc_ean8.cpp @@ -62,11 +62,13 @@ bool CBC_EAN8::Encode(const CFX_WideStringC& contents, m_renderContents = encodeContents; uint8_t* data = static_cast<CBC_OnedEAN8Writer*>(m_pBCWriter.get()) ->Encode(byteString, format, outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderResult(encodeContents.AsStringC(), data, outWidth, isDevice, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -75,14 +77,16 @@ bool CBC_EAN8::RenderDevice(CFX_RenderDevice* device, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderDeviceResult(device, matrix, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } bool CBC_EAN8::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_pdf417i.cpp b/xfa/fxbarcode/cbc_pdf417i.cpp index 1e147d944..1c5547d44 100644 --- a/xfa/fxbarcode/cbc_pdf417i.cpp +++ b/xfa/fxbarcode/cbc_pdf417i.cpp @@ -45,11 +45,13 @@ bool CBC_PDF417I::Encode(const CFX_WideStringC& contents, uint8_t* data = static_cast<CBC_PDF417Writer*>(m_pBCWriter.get()) ->Encode(CFX_WideString(contents), outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; static_cast<CBC_TwoDimWriter*>(m_pBCWriter.get()) ->RenderResult(data, outWidth, outHeight, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -64,7 +66,8 @@ bool CBC_PDF417I::RenderDevice(CFX_RenderDevice* device, bool CBC_PDF417I::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_TwoDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_qrcode.cpp b/xfa/fxbarcode/cbc_qrcode.cpp index 507b8f9ff..26b74ca40 100644 --- a/xfa/fxbarcode/cbc_qrcode.cpp +++ b/xfa/fxbarcode/cbc_qrcode.cpp @@ -52,10 +52,12 @@ bool CBC_QRCode::Encode(const CFX_WideStringC& contents, uint8_t* data = pWriter->Encode(CFX_WideString(contents), pWriter->GetErrorCorrectionLevel(), outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; pWriter->RenderResult(data, outWidth, outHeight, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -70,7 +72,8 @@ bool CBC_QRCode::RenderDevice(CFX_RenderDevice* device, bool CBC_QRCode::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_TwoDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/cbc_upca.cpp b/xfa/fxbarcode/cbc_upca.cpp index db8f72282..b282d5cd7 100644 --- a/xfa/fxbarcode/cbc_upca.cpp +++ b/xfa/fxbarcode/cbc_upca.cpp @@ -66,11 +66,13 @@ bool CBC_UPCA::Encode(const CFX_WideStringC& contents, pWriter->Init(); uint8_t* data = pWriter->Encode(byteString, format, outWidth, outHeight, e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; pWriter->RenderResult(encodeContents.AsStringC(), data, outWidth, isDevice, e); FX_Free(data); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } @@ -79,14 +81,16 @@ bool CBC_UPCA::RenderDevice(CFX_RenderDevice* device, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderDeviceResult(device, matrix, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } bool CBC_UPCA::RenderBitmap(CFX_DIBitmap*& pOutBitmap, int32_t& e) { static_cast<CBC_OneDimWriter*>(m_pBCWriter.get()) ->RenderBitmapResult(pOutBitmap, m_renderContents.AsStringC(), e); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + if (e != BCExceptionNO) + return false; return true; } diff --git a/xfa/fxbarcode/common/BC_CommonBitArray.cpp b/xfa/fxbarcode/common/BC_CommonBitArray.cpp index 722bbc501..0371837fd 100644 --- a/xfa/fxbarcode/common/BC_CommonBitArray.cpp +++ b/xfa/fxbarcode/common/BC_CommonBitArray.cpp @@ -41,7 +41,7 @@ CBC_CommonBitArray::~CBC_CommonBitArray() { int32_t CBC_CommonBitArray::GetSize() { return m_size; } -CFX_Int32Array& CBC_CommonBitArray::GetBits() { +CFX_ArrayTemplate<int32_t>& CBC_CommonBitArray::GetBits() { return m_bits; } int32_t CBC_CommonBitArray::GetSizeInBytes() { diff --git a/xfa/fxbarcode/common/BC_CommonBitArray.h b/xfa/fxbarcode/common/BC_CommonBitArray.h index 80a56d1b5..6ad8ab321 100644 --- a/xfa/fxbarcode/common/BC_CommonBitArray.h +++ b/xfa/fxbarcode/common/BC_CommonBitArray.h @@ -17,7 +17,7 @@ class CBC_CommonBitArray { virtual ~CBC_CommonBitArray(); int32_t GetSize(); - CFX_Int32Array& GetBits(); + CFX_ArrayTemplate<int32_t>& GetBits(); int32_t GetSizeInBytes(); bool Get(int32_t i); void Set(int32_t i); @@ -30,7 +30,7 @@ class CBC_CommonBitArray { private: int32_t m_size; - CFX_Int32Array m_bits; + CFX_ArrayTemplate<int32_t> m_bits; }; #endif // XFA_FXBARCODE_COMMON_BC_COMMONBITARRAY_H_ diff --git a/xfa/fxbarcode/common/BC_CommonByteArray.cpp b/xfa/fxbarcode/common/BC_CommonByteArray.cpp index 71fa85f0c..050ecb0bf 100644 --- a/xfa/fxbarcode/common/BC_CommonByteArray.cpp +++ b/xfa/fxbarcode/common/BC_CommonByteArray.cpp @@ -85,7 +85,7 @@ void CBC_CommonByteArray::Set(uint8_t* source, int32_t offset, int32_t count) { FXSYS_memcpy(m_bytes, source + offset, count); m_index = count; } -void CBC_CommonByteArray::Set(CFX_ByteArray* source, +void CBC_CommonByteArray::Set(CFX_ArrayTemplate<uint8_t>* source, int32_t offset, int32_t count) { FX_Free(m_bytes); diff --git a/xfa/fxbarcode/common/BC_CommonByteArray.h b/xfa/fxbarcode/common/BC_CommonByteArray.h index dd6ee581e..009f625a8 100644 --- a/xfa/fxbarcode/common/BC_CommonByteArray.h +++ b/xfa/fxbarcode/common/BC_CommonByteArray.h @@ -25,7 +25,7 @@ class CBC_CommonByteArray { void AppendByte(int32_t value); void Reserve(int32_t capacity); void Set(uint8_t* source, int32_t offset, int32_t count); - void Set(CFX_ByteArray* source, int32_t offset, int32_t count); + void Set(CFX_ArrayTemplate<uint8_t>* source, int32_t offset, int32_t count); private: int32_t m_size; diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp index 352dc3dab..769889036 100644 --- a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.cpp @@ -39,51 +39,57 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonEncoder::BuildGenerator(int32_t degree, CBC_ReedSolomonGF256Poly* lastGenerator = m_cachedGenerators[m_cachedGenerators.GetSize() - 1]; for (int32_t d = m_cachedGenerators.GetSize(); d <= degree; d++) { - CFX_Int32Array temp; + CFX_ArrayTemplate<int32_t> temp; temp.Add(1); temp.Add(m_field->Exp(d - 1)); CBC_ReedSolomonGF256Poly temp_poly; temp_poly.Init(m_field, &temp, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; CBC_ReedSolomonGF256Poly* nextGenerator = lastGenerator->Multiply(&temp_poly, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; m_cachedGenerators.Add(nextGenerator); lastGenerator = nextGenerator; } } return m_cachedGenerators[degree]; } -void CBC_ReedSolomonEncoder::Encode(CFX_Int32Array* toEncode, +void CBC_ReedSolomonEncoder::Encode(CFX_ArrayTemplate<int32_t>* toEncode, int32_t ecBytes, int32_t& e) { if (ecBytes == 0) { e = BCExceptionNoCorrectionBytes; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t dataBytes = toEncode->GetSize() - ecBytes; if (dataBytes <= 0) { e = BCExceptionNoDataBytesProvided; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } CBC_ReedSolomonGF256Poly* generator = BuildGenerator(ecBytes, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - CFX_Int32Array infoCoefficients; + if (e != BCExceptionNO) + return; + CFX_ArrayTemplate<int32_t> infoCoefficients; infoCoefficients.SetSize(dataBytes); for (int32_t x = 0; x < dataBytes; x++) { infoCoefficients[x] = toEncode->operator[](x); } CBC_ReedSolomonGF256Poly info; info.Init(m_field, &infoCoefficients, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; std::unique_ptr<CBC_ReedSolomonGF256Poly> infoTemp( info.MultiplyByMonomial(ecBytes, 1, e)); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; std::unique_ptr<CFX_ArrayTemplate<CBC_ReedSolomonGF256Poly*>> temp( infoTemp->Divide(generator, e)); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CBC_ReedSolomonGF256Poly* remainder = (*temp)[1]; - CFX_Int32Array* coefficients = remainder->GetCoefficients(); + CFX_ArrayTemplate<int32_t>* coefficients = remainder->GetCoefficients(); int32_t numZeroCoefficients = ecBytes - coefficients->GetSize(); for (int32_t i = 0; i < numZeroCoefficients; i++) { (*toEncode)[dataBytes + i] = 0; diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h index b71cfb4c0..95828f1a0 100644 --- a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomon.h @@ -17,7 +17,9 @@ class CBC_ReedSolomonEncoder { explicit CBC_ReedSolomonEncoder(CBC_ReedSolomonGF256* field); virtual ~CBC_ReedSolomonEncoder(); - void Encode(CFX_Int32Array* toEncode, int32_t ecBytes, int32_t& e); + void Encode(CFX_ArrayTemplate<int32_t>* toEncode, + int32_t ecBytes, + int32_t& e); virtual void Init(); private: diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp index 33b828cc1..ce84d8e08 100644 --- a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.cpp @@ -78,19 +78,21 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::BuildMonomial( int32_t& e) { if (degree < 0) { e = BCExceptionDegreeIsNegative; - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + return nullptr; } if (coefficient == 0) { CBC_ReedSolomonGF256Poly* temp = m_zero->Clone(e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } - CFX_Int32Array coefficients; + CFX_ArrayTemplate<int32_t> coefficients; coefficients.SetSize(degree + 1); coefficients[0] = coefficient; CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(this, &coefficients, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } @@ -105,7 +107,7 @@ int32_t CBC_ReedSolomonGF256::Exp(int32_t a) { int32_t CBC_ReedSolomonGF256::Log(int32_t a, int32_t& e) { if (a == 0) { e = BCExceptionAIsZero; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return 0; } return m_logTable[a]; } @@ -113,7 +115,7 @@ int32_t CBC_ReedSolomonGF256::Log(int32_t a, int32_t& e) { int32_t CBC_ReedSolomonGF256::Inverse(int32_t a, int32_t& e) { if (a == 0) { e = BCExceptionAIsZero; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return 0; } return m_expTable[255 - m_logTable[a]]; } diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp index 60f1f1bbe..a0bbc025c 100644 --- a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.cpp @@ -38,11 +38,11 @@ CBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly() { m_field = nullptr; } void CBC_ReedSolomonGF256Poly::Init(CBC_ReedSolomonGF256* field, - CFX_Int32Array* coefficients, + CFX_ArrayTemplate<int32_t>* coefficients, int32_t& e) { if (!coefficients || coefficients->GetSize() == 0) { e = BCExceptionCoefficientsSizeIsNull; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } m_field = field; int32_t coefficientsLength = coefficients->GetSize(); @@ -64,7 +64,7 @@ void CBC_ReedSolomonGF256Poly::Init(CBC_ReedSolomonGF256* field, m_coefficients.Copy(*coefficients); } } -CFX_Int32Array* CBC_ReedSolomonGF256Poly::GetCoefficients() { +CFX_ArrayTemplate<int32_t>* CBC_ReedSolomonGF256Poly::GetCoefficients() { return &m_coefficients; } int32_t CBC_ReedSolomonGF256Poly::GetDegree() { @@ -98,7 +98,8 @@ int32_t CBC_ReedSolomonGF256Poly::EvaluateAt(int32_t a) { CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Clone(int32_t& e) { CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &m_coefficients, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract( @@ -109,17 +110,17 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract( if (other->IsZero()) return Clone(e); - CFX_Int32Array smallerCoefficients; + CFX_ArrayTemplate<int32_t> smallerCoefficients; smallerCoefficients.Copy(m_coefficients); - CFX_Int32Array largerCoefficients; + CFX_ArrayTemplate<int32_t> largerCoefficients; largerCoefficients.Copy(*(other->GetCoefficients())); if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) { - CFX_Int32Array temp; + CFX_ArrayTemplate<int32_t> temp; temp.Copy(smallerCoefficients); smallerCoefficients.Copy(largerCoefficients); largerCoefficients.Copy(temp); } - CFX_Int32Array sumDiff; + CFX_ArrayTemplate<int32_t> sumDiff; sumDiff.SetSize(largerCoefficients.GetSize()); int32_t lengthDiff = largerCoefficients.GetSize() - smallerCoefficients.GetSize(); @@ -132,7 +133,8 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract( } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &sumDiff, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply( @@ -141,13 +143,13 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply( if (IsZero() || other->IsZero()) return m_field->GetZero()->Clone(e); - CFX_Int32Array aCoefficients; + CFX_ArrayTemplate<int32_t> aCoefficients; aCoefficients.Copy(m_coefficients); int32_t aLength = m_coefficients.GetSize(); - CFX_Int32Array bCoefficients; + CFX_ArrayTemplate<int32_t> bCoefficients; bCoefficients.Copy(*(other->GetCoefficients())); int32_t bLength = other->GetCoefficients()->GetSize(); - CFX_Int32Array product; + CFX_ArrayTemplate<int32_t> product; product.SetSize(aLength + bLength - 1); for (int32_t i = 0; i < aLength; i++) { int32_t aCoeff = m_coefficients[i]; @@ -159,7 +161,8 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply( } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &product, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(int32_t scalar, @@ -170,14 +173,15 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(int32_t scalar, return Clone(e); int32_t size = m_coefficients.GetSize(); - CFX_Int32Array product; + CFX_ArrayTemplate<int32_t> product; product.SetSize(size); for (int32_t i = 0; i < size; i++) { product[i] = m_field->Multiply(m_coefficients[i], scalar); } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &product, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::MultiplyByMonomial( @@ -192,14 +196,15 @@ CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::MultiplyByMonomial( return m_field->GetZero()->Clone(e); int32_t size = m_coefficients.GetSize(); - CFX_Int32Array product; + CFX_ArrayTemplate<int32_t> product; product.SetSize(size + degree); for (int32_t i = 0; i < size; i++) { product[i] = (m_field->Multiply(m_coefficients[i], coefficient)); } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &product, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return temp; } @@ -212,13 +217,16 @@ CFX_ArrayTemplate<CBC_ReedSolomonGF256Poly*>* CBC_ReedSolomonGF256Poly::Divide( } std::unique_ptr<CBC_ReedSolomonGF256Poly> quotient( m_field->GetZero()->Clone(e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; std::unique_ptr<CBC_ReedSolomonGF256Poly> remainder(Clone(e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; int32_t denominatorLeadingTerm = other->GetCoefficients(other->GetDegree()); int32_t inverseDenominatorLeadingTeam = m_field->Inverse(denominatorLeadingTerm, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; while (remainder->GetDegree() >= other->GetDegree() && !remainder->IsZero()) { int32_t degreeDifference = remainder->GetDegree() - other->GetDegree(); int32_t scale = @@ -226,14 +234,18 @@ CFX_ArrayTemplate<CBC_ReedSolomonGF256Poly*>* CBC_ReedSolomonGF256Poly::Divide( inverseDenominatorLeadingTeam); std::unique_ptr<CBC_ReedSolomonGF256Poly> term( other->MultiplyByMonomial(degreeDifference, scale, e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; std::unique_ptr<CBC_ReedSolomonGF256Poly> iteratorQuotient( m_field->BuildMonomial(degreeDifference, scale, e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; quotient.reset(quotient->AddOrSubtract(iteratorQuotient.get(), e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; remainder.reset(remainder->AddOrSubtract(term.get(), e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; } CFX_ArrayTemplate<CBC_ReedSolomonGF256Poly*>* tempPtrA = new CFX_ArrayTemplate<CBC_ReedSolomonGF256Poly*>(); diff --git a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h index 3eff31b62..ff93264e0 100644 --- a/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h +++ b/xfa/fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h @@ -17,11 +17,11 @@ class CBC_ReedSolomonGF256Poly final { CBC_ReedSolomonGF256Poly(); ~CBC_ReedSolomonGF256Poly(); void Init(CBC_ReedSolomonGF256* field, - CFX_Int32Array* coefficients, + CFX_ArrayTemplate<int32_t>* coefficients, int32_t& e); int32_t GetCoefficients(int32_t degree); - CFX_Int32Array* GetCoefficients(); + CFX_ArrayTemplate<int32_t>* GetCoefficients(); int32_t GetDegree(); bool IsZero(); int32_t EvaluateAt(int32_t a); @@ -41,7 +41,7 @@ class CBC_ReedSolomonGF256Poly final { private: CBC_ReedSolomonGF256* m_field; - CFX_Int32Array m_coefficients; + CFX_ArrayTemplate<int32_t> m_coefficients; }; #endif // XFA_FXBARCODE_COMMON_REEDSOLOMON_BC_REEDSOLOMONGF256POLY_H_ diff --git a/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp b/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp index 8858f6001..50f02ca52 100644 --- a/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp +++ b/xfa/fxbarcode/datamatrix/BC_C40Encoder.cpp @@ -163,7 +163,8 @@ int32_t CBC_C40Encoder::encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e) { sb += (FX_WCHAR)0x001e; int32_t len = 2; len += encodeChar((c - 128), sb, e); - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + if (e != BCExceptionNO) + return 0; return len; } else { e = BCExceptionIllegalArgument; @@ -180,7 +181,8 @@ int32_t CBC_C40Encoder::backtrackOneCharacter(CBC_EncoderContext& context, context.m_pos--; FX_WCHAR c = context.getCurrentChar(); lastCharSize = encodeChar(c, removed, e); - BC_EXCEPTION_CHECK_ReturnValue(e, -1); + if (e != BCExceptionNO) + return -1; context.resetSymbolInfo(); return lastCharSize; } diff --git a/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp b/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp index 1fe801863..f1ce798af 100644 --- a/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp +++ b/xfa/fxbarcode/datamatrix/BC_DataMatrixWriter.cpp @@ -54,7 +54,7 @@ uint8_t* CBC_DataMatrixWriter::Encode(const CFX_WideString& contents, int32_t& e) { if (outWidth < 0 || outHeight < 0) { e = BCExceptionHeightAndWidthMustBeAtLeast1; - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + return nullptr; } CBC_SymbolShapeHint::SymbolShapeHint shape = CBC_SymbolShapeHint::FORCE_SQUARE; @@ -63,20 +63,25 @@ uint8_t* CBC_DataMatrixWriter::Encode(const CFX_WideString& contents, CFX_WideString ecLevel; CFX_WideString encoded = CBC_HighLevelEncoder::encodeHighLevel( contents, ecLevel, shape, minSize, maxSize, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; CBC_SymbolInfo* symbolInfo = CBC_SymbolInfo::lookup( encoded.GetLength(), shape, minSize, maxSize, true, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; CFX_WideString codewords = CBC_ErrorCorrection::encodeECC200(encoded, symbolInfo, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; CBC_DefaultPlacement* placement = new CBC_DefaultPlacement(codewords, symbolInfo->getSymbolDataWidth(e), symbolInfo->getSymbolDataHeight(e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; placement->place(); CBC_CommonByteMatrix* bytematrix = encodeLowLevel(placement, symbolInfo, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; outWidth = bytematrix->GetWidth(); outHeight = bytematrix->GetHeight(); uint8_t* result = FX_Alloc2D(uint8_t, outWidth, outHeight); @@ -90,12 +95,15 @@ CBC_CommonByteMatrix* CBC_DataMatrixWriter::encodeLowLevel( CBC_SymbolInfo* symbolInfo, int32_t& e) { int32_t symbolWidth = symbolInfo->getSymbolDataWidth(e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; int32_t symbolHeight = symbolInfo->getSymbolDataHeight(e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; CBC_CommonByteMatrix* matrix = new CBC_CommonByteMatrix( symbolInfo->getSymbolWidth(e), symbolInfo->getSymbolHeight(e)); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; matrix->Init(); int32_t matrixY = 0; for (int32_t y = 0; y < symbolHeight; y++) { diff --git a/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp index bc0aa72b4..e7eef07b4 100644 --- a/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp +++ b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.cpp @@ -43,7 +43,7 @@ int32_t CBC_DefaultPlacement::getNumrows() { int32_t CBC_DefaultPlacement::getNumcols() { return m_numcols; } -CFX_ByteArray& CBC_DefaultPlacement::getBits() { +CFX_ArrayTemplate<uint8_t>& CBC_DefaultPlacement::getBits() { return m_bits; } bool CBC_DefaultPlacement::getBit(int32_t col, int32_t row) { diff --git a/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h index 64d02886f..36a7ab261 100644 --- a/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h +++ b/xfa/fxbarcode/datamatrix/BC_DefaultPlacement.h @@ -18,7 +18,7 @@ class CBC_DefaultPlacement { int32_t getNumrows(); int32_t getNumcols(); - CFX_ByteArray& getBits(); + CFX_ArrayTemplate<uint8_t>& getBits(); bool getBit(int32_t col, int32_t row); void setBit(int32_t col, int32_t row, bool bit); bool hasBit(int32_t col, int32_t row); @@ -28,7 +28,7 @@ class CBC_DefaultPlacement { CFX_WideString m_codewords; int32_t m_numrows; int32_t m_numcols; - CFX_ByteArray m_bits; + CFX_ArrayTemplate<uint8_t> m_bits; void module(int32_t row, int32_t col, int32_t pos, int32_t bit); void utah(int32_t row, int32_t col, int32_t pos); void corner1(int32_t pos); diff --git a/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp b/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp index c395f3a91..b01b3120e 100644 --- a/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp +++ b/xfa/fxbarcode/datamatrix/BC_EncoderContext.cpp @@ -100,7 +100,8 @@ void CBC_EncoderContext::updateSymbolInfo(int32_t len, int32_t& e) { if (!m_symbolInfo || len > m_symbolInfo->m_dataCapacity) { m_symbolInfo = CBC_SymbolInfo::lookup(len, m_shape, m_minSize, m_maxSize, true, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } void CBC_EncoderContext::resetSymbolInfo() { diff --git a/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp b/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp index f52f0ff0c..17eec1ee4 100644 --- a/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp +++ b/xfa/fxbarcode/datamatrix/BC_ErrorCorrection.cpp @@ -129,14 +129,15 @@ CFX_WideString CBC_ErrorCorrection::encodeECC200(CFX_WideString codewords, if (blockCount == 1) { CFX_WideString ecc = createECCBlock(codewords, symbolInfo->m_errorCodewords, e); - BC_EXCEPTION_CHECK_ReturnValue(e, CFX_WideString()); + if (e != BCExceptionNO) + return CFX_WideString(); sb += ecc; } else { - CFX_Int32Array dataSizes; + CFX_ArrayTemplate<int32_t> dataSizes; dataSizes.SetSize(blockCount); - CFX_Int32Array errorSizes; + CFX_ArrayTemplate<int32_t> errorSizes; errorSizes.SetSize(blockCount); - CFX_Int32Array startPos; + CFX_ArrayTemplate<int32_t> startPos; startPos.SetSize(blockCount); for (int32_t i = 0; i < blockCount; i++) { dataSizes[i] = symbolInfo->getDataLengthForInterleavedBlock(i + 1); @@ -152,7 +153,8 @@ CFX_WideString CBC_ErrorCorrection::encodeECC200(CFX_WideString codewords, temp += (FX_WCHAR)codewords.GetAt(d); } CFX_WideString ecc = createECCBlock(temp, errorSizes[block], e); - BC_EXCEPTION_CHECK_ReturnValue(e, CFX_WideString()); + if (e != BCExceptionNO) + return CFX_WideString(); int32_t pos = 0; for (int32_t l = block; l < errorSizes[block] * blockCount; l += blockCount) { diff --git a/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp index fcd668af6..abd358476 100644 --- a/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp +++ b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.cpp @@ -58,7 +58,8 @@ const wchar_t CBC_HighLevelEncoder::MACRO_TRAILER = 0x0004; CBC_HighLevelEncoder::CBC_HighLevelEncoder() {} CBC_HighLevelEncoder::~CBC_HighLevelEncoder() {} -CFX_ByteArray& CBC_HighLevelEncoder::getBytesForMessage(CFX_WideString msg) { +CFX_ArrayTemplate<uint8_t>& CBC_HighLevelEncoder::getBytesForMessage( + CFX_WideString msg) { CFX_ByteString bytestr; CBC_UtilCodingConvert::UnicodeToUTF8(msg, bytestr); for (int32_t i = 0; i < bytestr.GetLength(); i++) { @@ -78,7 +79,8 @@ CFX_WideString CBC_HighLevelEncoder::encodeHighLevel(CFX_WideString msg, CBC_Dimension* maxSize, int32_t& e) { CBC_EncoderContext context(msg, ecLevel, e); - BC_EXCEPTION_CHECK_ReturnValue(e, CFX_WideString()); + if (e != BCExceptionNO) + return CFX_WideString(); context.setSymbolShape(shape); context.setSizeConstraints(minSize, maxSize); if ((msg.Mid(0, 6) == MACRO_05_HEADER) && @@ -159,9 +161,9 @@ int32_t CBC_HighLevelEncoder::lookAheadTest(CFX_WideString msg, while (true) { if ((startpos + charsProcessed) == msg.GetLength()) { int32_t min = std::numeric_limits<int32_t>::max(); - CFX_ByteArray mins; + CFX_ArrayTemplate<uint8_t> mins; mins.SetSize(6); - CFX_Int32Array intCharCounts; + CFX_ArrayTemplate<int32_t> intCharCounts; intCharCounts.SetSize(6); min = findMinimums(charCounts, intCharCounts, min, mins); int32_t minCount = getMinimumCount(mins); @@ -229,9 +231,9 @@ int32_t CBC_HighLevelEncoder::lookAheadTest(CFX_WideString msg, charCounts[BASE256_ENCODATION]++; } if (charsProcessed >= 4) { - CFX_Int32Array intCharCounts; + CFX_ArrayTemplate<int32_t> intCharCounts; intCharCounts.SetSize(6); - CFX_ByteArray mins; + CFX_ArrayTemplate<uint8_t> mins; mins.SetSize(6); findMinimums(charCounts, intCharCounts, std::numeric_limits<int32_t>::max(), mins); @@ -317,10 +319,11 @@ FX_WCHAR CBC_HighLevelEncoder::randomize253State(FX_WCHAR ch, return tempVariable <= 254 ? (FX_WCHAR)tempVariable : (FX_WCHAR)(tempVariable - 254); } -int32_t CBC_HighLevelEncoder::findMinimums(std::vector<FX_FLOAT>& charCounts, - CFX_Int32Array& intCharCounts, - int32_t min, - CFX_ByteArray& mins) { +int32_t CBC_HighLevelEncoder::findMinimums( + std::vector<FX_FLOAT>& charCounts, + CFX_ArrayTemplate<int32_t>& intCharCounts, + int32_t min, + CFX_ArrayTemplate<uint8_t>& mins) { for (int32_t l = 0; l < mins.GetSize(); l++) { mins[l] = (uint8_t)0; } @@ -339,7 +342,8 @@ int32_t CBC_HighLevelEncoder::findMinimums(std::vector<FX_FLOAT>& charCounts, } return min; } -int32_t CBC_HighLevelEncoder::getMinimumCount(CFX_ByteArray& mins) { +int32_t CBC_HighLevelEncoder::getMinimumCount( + CFX_ArrayTemplate<uint8_t>& mins) { int32_t minCount = 0; for (int32_t i = 0; i < 6; i++) { minCount += mins[i]; diff --git a/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h index 3b88f888f..5d72f1074 100644 --- a/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h +++ b/xfa/fxbarcode/datamatrix/BC_HighLevelEncoder.h @@ -23,7 +23,7 @@ class CBC_HighLevelEncoder : public CBC_SymbolShapeHint { CBC_HighLevelEncoder(); ~CBC_HighLevelEncoder() override; - CFX_ByteArray& getBytesForMessage(CFX_WideString msg); + CFX_ArrayTemplate<uint8_t>& getBytesForMessage(CFX_WideString msg); static CFX_WideString encodeHighLevel(CFX_WideString msg, CFX_WideString ecLevel, int32_t& e); @@ -59,15 +59,15 @@ class CBC_HighLevelEncoder : public CBC_SymbolShapeHint { static const wchar_t* MACRO_05_HEADER; static const wchar_t* MACRO_06_HEADER; static const wchar_t MACRO_TRAILER; - CFX_ByteArray m_bytearray; + CFX_ArrayTemplate<uint8_t> m_bytearray; private: static FX_WCHAR randomize253State(FX_WCHAR ch, int32_t codewordPosition); static int32_t findMinimums(std::vector<FX_FLOAT>& charCounts, - CFX_Int32Array& intCharCounts, + CFX_ArrayTemplate<int32_t>& intCharCounts, int32_t min, - CFX_ByteArray& mins); - static int32_t getMinimumCount(CFX_ByteArray& mins); + CFX_ArrayTemplate<uint8_t>& mins); + static int32_t getMinimumCount(CFX_ArrayTemplate<uint8_t>& mins); static bool isNativeC40(FX_WCHAR ch); static bool isNativeText(FX_WCHAR ch); static bool isNativeX12(FX_WCHAR ch); diff --git a/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp b/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp index 77a809a51..ae74b8b2d 100644 --- a/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp +++ b/xfa/fxbarcode/datamatrix/BC_SymbolInfo.cpp @@ -151,12 +151,14 @@ CBC_SymbolInfo* CBC_SymbolInfo::lookup(int32_t dataCodewords, } if (minSize && (symbol->getSymbolWidth(e) < minSize->getWidth() || symbol->getSymbolHeight(e) < minSize->getHeight())) { - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; continue; } if (maxSize && (symbol->getSymbolWidth(e) > maxSize->getWidth() || symbol->getSymbolHeight(e) > maxSize->getHeight())) { - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; continue; } if (dataCodewords <= symbol->m_dataCapacity) { diff --git a/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp b/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp index c8b37e9c8..e3eb4a8c4 100644 --- a/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp +++ b/xfa/fxbarcode/datamatrix/BC_TextEncoder.cpp @@ -90,7 +90,8 @@ int32_t CBC_TextEncoder::encodeChar(FX_WCHAR c, sb += (FX_WCHAR)0x001e; int32_t len = 2; len += encodeChar((FX_WCHAR)(c - 128), sb, e); - BC_EXCEPTION_CHECK_ReturnValue(e, -1); + if (e != BCExceptionNO) + return -1; return len; } CBC_HighLevelEncoder::illegalCharacter(c, e); diff --git a/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp b/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp index 9ebfc4670..d77af9318 100644 --- a/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp +++ b/xfa/fxbarcode/datamatrix/BC_X12Encoder.cpp @@ -94,7 +94,8 @@ int32_t CBC_X12Encoder::encodeChar(FX_WCHAR c, CFX_WideString& sb, int32_t& e) { sb += (FX_WCHAR)(c - 65 + 14); } else { CBC_HighLevelEncoder::illegalCharacter(c, e); - BC_EXCEPTION_CHECK_ReturnValue(e, -1); + if (e != BCExceptionNO) + return -1; } return 1; } diff --git a/xfa/fxbarcode/oned/BC_OneDimWriter.cpp b/xfa/fxbarcode/oned/BC_OneDimWriter.cpp index 24d257a63..bc0d61fd2 100644 --- a/xfa/fxbarcode/oned/BC_OneDimWriter.cpp +++ b/xfa/fxbarcode/oned/BC_OneDimWriter.cpp @@ -103,7 +103,8 @@ uint8_t* CBC_OneDimWriter::Encode(const CFX_ByteString& contents, } else { ret = Encode(contents, outWidth, e); } - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } @@ -113,7 +114,8 @@ uint8_t* CBC_OneDimWriter::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } @@ -175,8 +177,7 @@ void CBC_OneDimWriter::CalcTextInfo(const CFX_ByteString& text, (FX_FLOAT)FXSYS_abs(cFont->GetDescent()) * (FX_FLOAT)fontSize / 1000.0f; FX_FLOAT left = leftPositon; FX_FLOAT top = 0.0; - charPos[0].m_OriginX = penX + left; - charPos[0].m_OriginY = penY + top; + charPos[0].m_Origin = CFX_PointF(penX + left, penY + top); charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(pCharCode[0]); charPos[0].m_FontCharWidth = cFont->GetGlyphWidth(charPos[0].m_GlyphIndex); #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ @@ -184,8 +185,7 @@ void CBC_OneDimWriter::CalcTextInfo(const CFX_ByteString& text, #endif penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * (FX_FLOAT)fontSize / 1000.0f; for (int32_t i = 1; i < length; i++) { - charPos[i].m_OriginX = penX + left; - charPos[i].m_OriginY = penY + top; + charPos[i].m_Origin = CFX_PointF(penX + left, penY + top); charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(pCharCode[i]); charPos[i].m_FontCharWidth = cFont->GetGlyphWidth(charPos[i].m_GlyphIndex); #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ @@ -221,8 +221,8 @@ void CBC_OneDimWriter::ShowDeviceChars(CFX_RenderDevice* device, affine_matrix.Concat(*matrix); } device->DrawNormalText(str.GetLength(), pCharPos, m_pFont, - (FX_FLOAT)iFontSize, &affine_matrix, m_fontColor, - FXTEXT_CLEARTYPE); + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); } void CBC_OneDimWriter::ShowBitmapChars(CFX_DIBitmap* pOutBitmap, @@ -238,9 +238,11 @@ void CBC_OneDimWriter::ShowBitmapChars(CFX_DIBitmap* pOutBitmap, ge.Create((int)geWidth, iTextHeight, m_colorSpace, nullptr); FX_RECT geRect(0, 0, (int)geWidth, iTextHeight); ge.FillRect(&geRect, m_backgroundColor); - CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize); - ge.DrawNormalText(str.GetLength(), pCharPos, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, + static_cast<FX_FLOAT>(iFontSize)); + ge.DrawNormalText(str.GetLength(), pCharPos, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); CFX_FxgeDevice geBitmap; geBitmap.Attach(pOutBitmap, false, nullptr, false); geBitmap.SetDIBits(ge.GetBitmap(), (int)locX, (int)locY); @@ -319,7 +321,8 @@ void CBC_OneDimWriter::RenderBitmapResult(CFX_DIBitmap*& pOutBitmap, const CFX_WideStringC& contents, int32_t& e) { if (!m_output) - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; pOutBitmap = CreateDIBitmap(m_output->GetWidth(), m_output->GetHeight()); pOutBitmap->Clear(m_backgroundColor); @@ -342,7 +345,8 @@ void CBC_OneDimWriter::RenderBitmapResult(CFX_DIBitmap*& pOutBitmap, if (m_locTextLoc != BC_TEXT_LOC_NONE && i < contents.GetLength()) { ShowChars(contents, pOutBitmap, nullptr, nullptr, m_barWidth, m_multiple, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } std::unique_ptr<CFX_DIBitmap> pStretchBitmap = pOutBitmap->StretchTo(m_Width, m_Height); @@ -355,7 +359,8 @@ void CBC_OneDimWriter::RenderDeviceResult(CFX_RenderDevice* device, const CFX_WideStringC& contents, int32_t& e) { if (!m_output) - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CFX_GraphStateData stateData; CFX_PathData path; @@ -382,7 +387,8 @@ void CBC_OneDimWriter::RenderDeviceResult(CFX_RenderDevice* device, } if (m_locTextLoc != BC_TEXT_LOC_NONE && i < contents.GetLength()) { ShowChars(contents, nullptr, device, matrix, m_barWidth, m_multiple, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } @@ -392,7 +398,8 @@ void CBC_OneDimWriter::RenderResult(const CFX_WideStringC& contents, bool isDevice, int32_t& e) { if (codeLength < 1) { - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } if (m_ModuleHeight < 20.0) { m_ModuleHeight = 20; @@ -456,7 +463,8 @@ void CBC_OneDimWriter::RenderResult(const CFX_WideStringC& contents, break; } m_output->SetRegion(outputX, 0, m_multiple, outputHeight, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } outputX += m_multiple; } diff --git a/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp b/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp index fb0d7dcd7..399e5e7d4 100644 --- a/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp +++ b/xfa/fxbarcode/oned/BC_OnedCodaBarWriter.cpp @@ -144,7 +144,8 @@ uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, @@ -159,7 +160,8 @@ uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, } uint8_t* ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString& contents, diff --git a/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp b/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp index ed2d2c1b2..f163b1866 100644 --- a/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp +++ b/xfa/fxbarcode/oned/BC_OnedCode128Writer.cpp @@ -154,7 +154,8 @@ uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents, } uint8_t* ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents, @@ -163,7 +164,8 @@ uint8_t* CBC_OnedCode128Writer::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } bool CBC_OnedCode128Writer::IsDigits(const CFX_ByteString& contents, diff --git a/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp b/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp index 9d5fdda96..a1ba5c808 100644 --- a/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp +++ b/xfa/fxbarcode/oned/BC_OnedCode39Writer.cpp @@ -130,7 +130,8 @@ uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, @@ -145,7 +146,8 @@ uint8_t* CBC_OnedCode39Writer::Encode(const CFX_ByteString& contents, } uint8_t* ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } void CBC_OnedCode39Writer::ToIntArray(int32_t a, int32_t* toReturn) { @@ -263,7 +265,8 @@ CFX_WideString CBC_OnedCode39Writer::encodedContents( CFX_ByteString str = checksumContent.UTF8Encode(); FX_CHAR checksum; checksum = CalcCheckSum(str, e); - BC_EXCEPTION_CHECK_ReturnValue(e, CFX_WideString()); + if (e != BCExceptionNO) + return CFX_WideString(); str += checksum; encodedContents += checksum; } @@ -275,7 +278,8 @@ void CBC_OnedCode39Writer::RenderResult(const CFX_WideStringC& contents, bool isDevice, int32_t& e) { CFX_WideString encodedCon = encodedContents(contents, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CBC_OneDimWriter::RenderResult(encodedCon.AsStringC(), code, codeLength, isDevice, e); } diff --git a/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp b/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp index 71d9ac650..bcbc80a61 100644 --- a/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp +++ b/xfa/fxbarcode/oned/BC_OnedEAN13Writer.cpp @@ -97,7 +97,8 @@ uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, @@ -111,7 +112,8 @@ uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, } uint8_t* ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedEAN13Writer::Encode(const CFX_ByteString& contents, @@ -231,8 +233,9 @@ void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, ge.Create(strWidth, iTextHeight, FXDIB_Argb, nullptr); FX_RECT rect(0, 0, strWidth, iTextHeight); ge.FillRect(&rect, m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos + 1, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + ge.DrawNormalText(iLen, pCharPos + 1, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight); } else { CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, @@ -241,8 +244,9 @@ void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos + 1, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos + 1, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } tempStr = str.Mid(7, 6); iLen = tempStr.GetLength(); @@ -251,8 +255,9 @@ void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, if (pOutBitmap) { FX_RECT rect1(0, 0, strWidth, iTextHeight); ge.FillRect(&rect1, m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos + 7, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + ge.DrawNormalText(iLen, pCharPos + 7, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 47 * multiple, m_Height - iTextHeight); } else { @@ -263,8 +268,9 @@ void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos + 7, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos + 7, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } tempStr = str.Mid(0, 1); iLen = tempStr.GetLength(); @@ -278,7 +284,7 @@ void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, delete ge.GetBitmap(); ge.Create(strWidth, iTextHeight, FXDIB_Argb, nullptr); ge.GetBitmap()->Clear(m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos, m_pFont, (FX_FLOAT)iFontSize, + ge.DrawNormalText(iLen, pCharPos, m_pFont, static_cast<FX_FLOAT>(iFontSize), &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight); } else { @@ -287,8 +293,9 @@ void CBC_OnedEAN13Writer::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } FX_Free(pCharPos); } diff --git a/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp b/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp index ad3ee6160..c40223818 100644 --- a/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp +++ b/xfa/fxbarcode/oned/BC_OnedEAN8Writer.cpp @@ -100,7 +100,8 @@ uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, @@ -115,7 +116,8 @@ uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, } uint8_t* ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } uint8_t* CBC_OnedEAN8Writer::Encode(const CFX_ByteString& contents, @@ -221,7 +223,7 @@ void CBC_OnedEAN8Writer::ShowChars(const CFX_WideStringC& contents, delete ge.GetBitmap(); ge.Create(strWidth, iTextHeight, FXDIB_Argb, nullptr); ge.GetBitmap()->Clear(m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos, m_pFont, (FX_FLOAT)iFontSize, + ge.DrawNormalText(iLen, pCharPos, m_pFont, static_cast<FX_FLOAT>(iFontSize), &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight); } else { @@ -229,8 +231,9 @@ void CBC_OnedEAN8Writer::ShowChars(const CFX_WideStringC& contents, (FX_FLOAT)leftPosition * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize)); affine_matrix1.Concat(*matrix); - device->DrawNormalText(iLen, pCharPos, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } tempStr = str.Mid(4, 4); iLen = tempStr.GetLength(); @@ -240,8 +243,9 @@ void CBC_OnedEAN8Writer::ShowChars(const CFX_WideStringC& contents, delete ge.GetBitmap(); ge.Create(strWidth, iTextHeight, FXDIB_Argb, nullptr); ge.GetBitmap()->Clear(m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos + 4, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + ge.DrawNormalText(iLen, pCharPos + 4, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 33 * multiple, m_Height - iTextHeight); } else { @@ -252,8 +256,9 @@ void CBC_OnedEAN8Writer::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos + 4, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos + 4, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } FX_Free(pCharPos); } diff --git a/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp b/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp index 42e84b711..6d6e79637 100644 --- a/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp +++ b/xfa/fxbarcode/oned/BC_OnedUPCAWriter.cpp @@ -87,7 +87,8 @@ uint8_t* CBC_OnedUPCAWriter::Encode(const CFX_ByteString& contents, int32_t& outHeight, int32_t& e) { uint8_t* ret = Encode(contents, format, outWidth, outHeight, 0, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } @@ -105,7 +106,8 @@ uint8_t* CBC_OnedUPCAWriter::Encode(const CFX_ByteString& contents, m_iDataLenth = 13; uint8_t* ret = m_subWriter->Encode(toEAN13String, BCFORMAT_EAN_13, outWidth, outHeight, hints, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return ret; } @@ -190,8 +192,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, if (pOutBitmap) { ge.Create((int)strWidth, iTextHeight, FXDIB_Argb, nullptr); ge.GetBitmap()->Clear(m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos + 1, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + ge.DrawNormalText(iLen, pCharPos + 1, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight); } else { CFX_Matrix affine_matrix1(1.0, 0.0, 0.0, -1.0, @@ -200,8 +203,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos + 1, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos + 1, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } tempStr = str.Mid(6, 5); iLen = tempStr.GetLength(); @@ -209,8 +213,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, if (pOutBitmap) { FX_RECT rect2(0, 0, (int)strWidth, iTextHeight); ge.FillRect(&rect2, m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos + 6, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + ge.DrawNormalText(iLen, pCharPos + 6, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 40 * multiple, m_Height - iTextHeight); } else { @@ -221,8 +226,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos + 6, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos + 6, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } tempStr = str.Mid(0, 1); iLen = tempStr.GetLength(); @@ -235,7 +241,7 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, delete ge.GetBitmap(); ge.Create((int)strWidth, iTextHeight, FXDIB_Argb, nullptr); ge.GetBitmap()->Clear(m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos, m_pFont, (FX_FLOAT)iFontSize, + ge.DrawNormalText(iLen, pCharPos, m_pFont, static_cast<FX_FLOAT>(iFontSize), &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight); } else { @@ -244,8 +250,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } tempStr = str.Mid(11, 1); iLen = tempStr.GetLength(); @@ -254,8 +261,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, delete ge.GetBitmap(); ge.Create((int)strWidth, iTextHeight, FXDIB_Argb, nullptr); ge.GetBitmap()->Clear(m_backgroundColor); - ge.DrawNormalText(iLen, pCharPos + 11, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix, m_fontColor, FXTEXT_CLEARTYPE); + ge.DrawNormalText(iLen, pCharPos + 11, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix, + m_fontColor, FXTEXT_CLEARTYPE); geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 85 * multiple, m_Height - iTextHeight); } else { @@ -266,8 +274,9 @@ void CBC_OnedUPCAWriter::ShowChars(const CFX_WideStringC& contents, if (matrix) { affine_matrix1.Concat(*matrix); } - device->DrawNormalText(iLen, pCharPos + 11, m_pFont, (FX_FLOAT)iFontSize, - &affine_matrix1, m_fontColor, FXTEXT_CLEARTYPE); + device->DrawNormalText(iLen, pCharPos + 11, m_pFont, + static_cast<FX_FLOAT>(iFontSize), &affine_matrix1, + m_fontColor, FXTEXT_CLEARTYPE); } FX_Free(pCharPos); } diff --git a/xfa/fxbarcode/pdf417/BC_PDF417.cpp b/xfa/fxbarcode/pdf417/BC_PDF417.cpp index 9b8d0c149..2f01564b1 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417.cpp @@ -405,14 +405,17 @@ void CBC_PDF417::generateBarcodeLogic(CFX_WideString msg, int32_t errorCorrectionCodeWords = CBC_PDF417ErrorCorrection::getErrorCorrectionCodewordCount( errorCorrectionLevel, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CFX_WideString highLevel = CBC_PDF417HighLevelEncoder::encodeHighLevel(msg, m_compaction, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t sourceCodeWords = highLevel.GetLength(); - CFX_Int32Array* dimension = + CFX_ArrayTemplate<int32_t>* dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t cols = dimension->GetAt(0); int32_t rows = dimension->GetAt(1); delete dimension; @@ -432,7 +435,8 @@ void CBC_PDF417::generateBarcodeLogic(CFX_WideString msg, CFX_WideString dataCodewords(sb); CFX_WideString ec = CBC_PDF417ErrorCorrection::generateErrorCorrection( dataCodewords, errorCorrectionLevel, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CFX_WideString fullCodewords = dataCodewords + ec; m_barcodeMatrix = pdfium::MakeUnique<CBC_BarcodeMatrix>(rows, cols); encodeLowLevel(fullCodewords, cols, rows, errorCorrectionLevel, @@ -532,12 +536,12 @@ void CBC_PDF417::encodeLowLevel(CFX_WideString fullCodewords, } } -CFX_Int32Array* CBC_PDF417::determineDimensions( +CFX_ArrayTemplate<int32_t>* CBC_PDF417::determineDimensions( int32_t sourceCodeWords, int32_t errorCorrectionCodeWords, int32_t& e) { FX_FLOAT ratio = 0.0f; - CFX_Int32Array* dimension = nullptr; + CFX_ArrayTemplate<int32_t>* dimension = nullptr; for (int32_t cols = m_minCols; cols <= m_maxCols; cols++) { int32_t rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols); @@ -555,7 +559,7 @@ CFX_Int32Array* CBC_PDF417::determineDimensions( } ratio = newRatio; delete dimension; - dimension = new CFX_Int32Array; + dimension = new CFX_ArrayTemplate<int32_t>; dimension->Add(cols); dimension->Add(rows); } @@ -563,11 +567,11 @@ CFX_Int32Array* CBC_PDF417::determineDimensions( int32_t rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, m_minCols); if (rows < m_minRows) { - dimension = new CFX_Int32Array; + dimension = new CFX_ArrayTemplate<int32_t>; dimension->Add(m_minCols); dimension->Add(m_minRows); } else if (rows >= 3 && rows <= 90) { - dimension = new CFX_Int32Array; + dimension = new CFX_ArrayTemplate<int32_t>; dimension->Add(m_minCols); dimension->Add(rows); } diff --git a/xfa/fxbarcode/pdf417/BC_PDF417.h b/xfa/fxbarcode/pdf417/BC_PDF417.h index 5f7c2d49b..3ba5aa2f0 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417.h +++ b/xfa/fxbarcode/pdf417/BC_PDF417.h @@ -51,9 +51,10 @@ class CBC_PDF417 { int32_t r, int32_t errorCorrectionLevel, CBC_BarcodeMatrix* logic); - CFX_Int32Array* determineDimensions(int32_t sourceCodeWords, - int32_t errorCorrectionCodeWords, - int32_t& e); + CFX_ArrayTemplate<int32_t>* determineDimensions( + int32_t sourceCodeWords, + int32_t errorCorrectionCodeWords, + int32_t& e); std::unique_ptr<CBC_BarcodeMatrix> m_barcodeMatrix; bool m_compact; diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp index f348d2c93..c1f4da1e3 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.cpp @@ -59,16 +59,16 @@ int32_t CBC_BarcodeMatrix::getWidth() { int32_t CBC_BarcodeMatrix::getHeight() { return m_outHeight; } -CFX_ByteArray& CBC_BarcodeMatrix::getMatrix() { +CFX_ArrayTemplate<uint8_t>& CBC_BarcodeMatrix::getMatrix() { return getScaledMatrix(1, 1); } -CFX_ByteArray& CBC_BarcodeMatrix::getScaledMatrix(int32_t scale) { +CFX_ArrayTemplate<uint8_t>& CBC_BarcodeMatrix::getScaledMatrix(int32_t scale) { return getScaledMatrix(scale, scale); } -CFX_ByteArray& CBC_BarcodeMatrix::getScaledMatrix(int32_t xScale, - int32_t yScale) { +CFX_ArrayTemplate<uint8_t>& CBC_BarcodeMatrix::getScaledMatrix(int32_t xScale, + int32_t yScale) { int32_t yMax = m_height * yScale; - CFX_ByteArray bytearray; + CFX_ArrayTemplate<uint8_t> bytearray; bytearray.Copy(m_matrix[0]->getScaledRow(xScale)); int32_t xMax = bytearray.GetSize(); m_matrixOut.SetSize(xMax * yMax); diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h index 0f6922233..95ab547c9 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeMatrix.h @@ -21,15 +21,15 @@ class CBC_BarcodeMatrix { void setMatrix(int32_t x, int32_t y, bool black); void startRow(); CBC_BarcodeRow* getCurrentRow(); - CFX_ByteArray& getMatrix(); - CFX_ByteArray& getScaledMatrix(int32_t scale); - CFX_ByteArray& getScaledMatrix(int32_t xScale, int32_t yScale); + CFX_ArrayTemplate<uint8_t>& getMatrix(); + CFX_ArrayTemplate<uint8_t>& getScaledMatrix(int32_t scale); + CFX_ArrayTemplate<uint8_t>& getScaledMatrix(int32_t xScale, int32_t yScale); int32_t getWidth(); int32_t getHeight(); private: CFX_ArrayTemplate<CBC_BarcodeRow*> m_matrix; - CFX_ByteArray m_matrixOut; + CFX_ArrayTemplate<uint8_t> m_matrixOut; int32_t m_currentRow; int32_t m_height; int32_t m_width; diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp index b721ffc3e..243af70d9 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.cpp @@ -41,10 +41,10 @@ void CBC_BarcodeRow::addBar(bool black, int32_t width) { set(m_currentLocation++, black); } } -CFX_ByteArray& CBC_BarcodeRow::getRow() { +CFX_ArrayTemplate<uint8_t>& CBC_BarcodeRow::getRow() { return m_row; } -CFX_ByteArray& CBC_BarcodeRow::getScaledRow(int32_t scale) { +CFX_ArrayTemplate<uint8_t>& CBC_BarcodeRow::getScaledRow(int32_t scale) { m_output.SetSize(m_row.GetSize() * scale); for (int32_t i = 0; i < m_output.GetSize(); i++) { m_output[i] = (m_row[i / scale]); diff --git a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h index 90e76ac50..7d9d19cb5 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h +++ b/xfa/fxbarcode/pdf417/BC_PDF417BarcodeRow.h @@ -17,12 +17,12 @@ class CBC_BarcodeRow { void set(int32_t x, uint8_t value); void set(int32_t x, bool black); void addBar(bool black, int32_t width); - CFX_ByteArray& getRow(); - CFX_ByteArray& getScaledRow(int32_t scale); + CFX_ArrayTemplate<uint8_t>& getRow(); + CFX_ArrayTemplate<uint8_t>& getScaledRow(int32_t scale); private: - CFX_ByteArray m_row; - CFX_ByteArray m_output; + CFX_ArrayTemplate<uint8_t> m_row; + CFX_ArrayTemplate<uint8_t> m_output; int32_t m_currentLocation; }; diff --git a/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp b/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp index cbdfffac6..bdec40397 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417ErrorCorrection.cpp @@ -161,7 +161,8 @@ CFX_WideString CBC_PDF417ErrorCorrection::generateErrorCorrection( int32_t errorCorrectionLevel, int32_t& e) { int32_t k = getErrorCorrectionCodewordCount(errorCorrectionLevel, e); - BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' '); + if (e != BCExceptionNO) + return L" "; FX_WCHAR* ech = FX_Alloc(FX_WCHAR, k); FXSYS_memset(ech, 0, k * sizeof(FX_WCHAR)); int32_t sld = dataCodewords.GetLength(); diff --git a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp index fa0e9bc67..08a40c51b 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.cpp @@ -71,7 +71,7 @@ CFX_WideString CBC_PDF417HighLevelEncoder::encodeHighLevel( } msg += ch; } - CFX_ByteArray byteArr; + CFX_ArrayTemplate<uint8_t> byteArr; for (int32_t k = 0; k < bytes.GetLength(); k++) { byteArr.Add(bytes.GetAt(k)); } @@ -108,7 +108,8 @@ CFX_WideString CBC_PDF417HighLevelEncoder::encodeHighLevel( p += t; } else { int32_t b = determineConsecutiveBinaryCount(msg, &byteArr, p, e); - BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' '); + if (e != BCExceptionNO) + return L" "; if (b == 0) { b = 1; } @@ -260,7 +261,7 @@ int32_t CBC_PDF417HighLevelEncoder::encodeText(CFX_WideString msg, } return submode; } -void CBC_PDF417HighLevelEncoder::encodeBinary(CFX_ByteArray* bytes, +void CBC_PDF417HighLevelEncoder::encodeBinary(CFX_ArrayTemplate<uint8_t>* bytes, int32_t startpos, int32_t count, int32_t startmode, @@ -387,7 +388,7 @@ int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount( } int32_t CBC_PDF417HighLevelEncoder::determineConsecutiveBinaryCount( CFX_WideString msg, - CFX_ByteArray* bytes, + CFX_ArrayTemplate<uint8_t>* bytes, int32_t startpos, int32_t& e) { int32_t len = msg.GetLength(); diff --git a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h index 39abe0f1d..38382c891 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h +++ b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder.h @@ -39,7 +39,7 @@ class CBC_PDF417HighLevelEncoder { int32_t count, CFX_WideString& sb, int32_t initialSubmode); - static void encodeBinary(CFX_ByteArray* bytes, + static void encodeBinary(CFX_ArrayTemplate<uint8_t>* bytes, int32_t startpos, int32_t count, int32_t startmode, @@ -58,10 +58,11 @@ class CBC_PDF417HighLevelEncoder { int32_t startpos); static int32_t determineConsecutiveTextCount(CFX_WideString msg, int32_t startpos); - static int32_t determineConsecutiveBinaryCount(CFX_WideString msg, - CFX_ByteArray* bytes, - int32_t startpos, - int32_t& e); + static int32_t determineConsecutiveBinaryCount( + CFX_WideString msg, + CFX_ArrayTemplate<uint8_t>* bytes, + int32_t startpos, + int32_t& e); friend class PDF417HighLevelEncoder_EncodeNumeric_Test; friend class PDF417HighLevelEncoder_EncodeBinary_Test; diff --git a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp index a1b753e3e..2cd60fef4 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417HighLevelEncoder_unittest.cpp @@ -43,7 +43,7 @@ TEST(PDF417HighLevelEncoder, EncodeBinary) { CBC_PDF417HighLevelEncoder::Initialize(); for (size_t i = 0; i < FX_ArraySize(encode_binary_cases); ++i) { EncodeBinaryCase* ptr = &encode_binary_cases[i]; - CFX_ByteArray input_array; + CFX_ArrayTemplate<uint8_t> input_array; size_t input_length = strlen(ptr->input); input_array.SetSize(input_length); for (size_t j = 0; j < input_length; ++j) { diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp b/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp index 4c9b5cb15..2c75a14a8 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp +++ b/xfa/fxbarcode/pdf417/BC_PDF417Writer.cpp @@ -59,11 +59,12 @@ uint8_t* CBC_PDF417Writer::Encode(const CFX_WideString& contents, encoder.setDimensions(30, 1, row, row); } encoder.generateBarcodeLogic(contents, m_iCorrectLevel, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; int32_t lineThickness = 2; int32_t aspectRatio = 4; CBC_BarcodeMatrix* barcodeMatrix = encoder.getBarcodeMatrix(); - CFX_ByteArray originalScale; + CFX_ArrayTemplate<uint8_t> originalScale; originalScale.Copy(barcodeMatrix->getScaledMatrix( lineThickness, aspectRatio * lineThickness)); int32_t width = outWidth; @@ -101,10 +102,10 @@ uint8_t* CBC_PDF417Writer::Encode(const CFX_WideString& contents, FXSYS_memcpy(result, originalScale.GetData(), outHeight * outWidth); return result; } -void CBC_PDF417Writer::rotateArray(CFX_ByteArray& bitarray, +void CBC_PDF417Writer::rotateArray(CFX_ArrayTemplate<uint8_t>& bitarray, int32_t height, int32_t width) { - CFX_ByteArray temp; + CFX_ArrayTemplate<uint8_t> temp; temp.Copy(bitarray); for (int32_t ii = 0; ii < height; ii++) { int32_t inverseii = height - ii - 1; diff --git a/xfa/fxbarcode/pdf417/BC_PDF417Writer.h b/xfa/fxbarcode/pdf417/BC_PDF417Writer.h index 178d251bf..420c441bc 100644 --- a/xfa/fxbarcode/pdf417/BC_PDF417Writer.h +++ b/xfa/fxbarcode/pdf417/BC_PDF417Writer.h @@ -27,7 +27,9 @@ class CBC_PDF417Writer : public CBC_TwoDimWriter { void SetTruncated(bool truncated); private: - void rotateArray(CFX_ByteArray& bitarray, int32_t width, int32_t height); + void rotateArray(CFX_ArrayTemplate<uint8_t>& bitarray, + int32_t width, + int32_t height); bool m_bTruncated; }; diff --git a/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp index adb12f25b..8a6499cbb 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCodeWriter.cpp @@ -85,7 +85,7 @@ uint8_t* CBC_QRCodeWriter::Encode(const CFX_WideString& contents, break; default: { e = BCExceptionUnSupportEclevel; - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + return nullptr; } } CBC_QRCoder qr; @@ -95,7 +95,8 @@ uint8_t* CBC_QRCodeWriter::Encode(const CFX_WideString& contents, } else { CBC_QRCoderEncoder::Encode(contents, ec, &qr, e); } - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; outWidth = qr.GetMatrixWidth(); outHeight = qr.GetMatrixWidth(); uint8_t* result = FX_Alloc2D(uint8_t, outWidth, outHeight); diff --git a/xfa/fxbarcode/qrcode/BC_QRCoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoder.cpp index c47374935..a5c849780 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoder.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoder.cpp @@ -85,7 +85,7 @@ int32_t CBC_QRCoder::At(int32_t x, int32_t y, int32_t& e) { int32_t value = m_matrix->Get(x, y); if (!(value == 0 || value == 1)) { e = BCExceptionValueMustBeEither0or1; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return 0; } return value; } diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp index c770c1539..e4140a87a 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoderBitVector.cpp @@ -43,7 +43,7 @@ void CBC_QRCoderBitVector::Clear() { int32_t CBC_QRCoderBitVector::At(int32_t index, int32_t& e) { if (index < 0 || index >= m_sizeInBits) { e = BCExceptionBadIndexException; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return 0; } int32_t value = m_array[index >> 3] & 0xff; return (value >> (7 - (index & 0x7))) & 1; @@ -57,7 +57,7 @@ int32_t CBC_QRCoderBitVector::Size() { void CBC_QRCoderBitVector::AppendBit(int32_t bit, int32_t& e) { if (!(bit == 0 || bit == 1)) { e = BCExceptionBadValueException; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t numBitsInLastByte = m_sizeInBits & 0x7; if (numBitsInLastByte == 0) { @@ -72,7 +72,7 @@ void CBC_QRCoderBitVector::AppendBits(int32_t value, int32_t& e) { if (numBits < 0 || numBits > 32) { e = BCExceptionBadNumBitsException; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t numBitsLeft = numBits; while (numBitsLeft > 0) { @@ -83,7 +83,8 @@ void CBC_QRCoderBitVector::AppendBits(int32_t value, } else { int32_t bit = (value >> (numBitsLeft - 1)) & 1; AppendBit(bit, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; --numBitsLeft; } } @@ -93,15 +94,17 @@ void CBC_QRCoderBitVector::AppendBitVector(CBC_QRCoderBitVector* bits, int32_t size = bits->Size(); for (int32_t i = 0; i < size; i++) { int32_t num = bits->At(i, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendBit(num, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) + if (e != BCExceptionNO) + return; } } void CBC_QRCoderBitVector::XOR(CBC_QRCoderBitVector* other, int32_t& e) { if (m_sizeInBits != other->Size()) { e = BCExceptioncanNotOperatexorOperator; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t sizeInBytes = (m_sizeInBits + 7) >> 3; for (int32_t i = 0; i < sizeInBytes; ++i) { diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp index 332f1de9c..2c262f006 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.cpp @@ -63,13 +63,16 @@ void CBC_QRCoderEncoder::Encode(const CFX_ByteString& content, int32_t versionSpecify) { if (versionSpecify == 0) { EncodeWithAutoVersion(content, ecLevel, qrCode, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) + if (e != BCExceptionNO) + return; } else if (versionSpecify > 0 && versionSpecify <= 40) { EncodeWithSpecifyVersion(content, ecLevel, qrCode, versionSpecify, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } else { e = BCExceptionVersionMust1_40; - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } @@ -87,44 +90,56 @@ void CBC_QRCoderEncoder::AppendDataModeLenghInfo( tempMode = splitResult.first; if (tempMode == CBC_QRCoderMode::sGBK) { AppendModeInfo(tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendLengthInfo(splitResult.second.GetLength(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendBytes(splitResult.second, tempMode, &headerAndDataBits, encoding, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } else if (tempMode == CBC_QRCoderMode::sBYTE) { - CFX_ByteArray bytes; + CFX_ArrayTemplate<uint8_t> bytes; CBC_UtilCodingConvert::LocaleToUtf8(splitResult.second, bytes); AppendModeInfo(tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendLengthInfo(bytes.GetSize(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; Append8BitBytes(bytes, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } else if (tempMode == CBC_QRCoderMode::sALPHANUMERIC) { AppendModeInfo(tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendLengthInfo(splitResult.second.GetLength(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendBytes(splitResult.second, tempMode, &headerAndDataBits, encoding, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } else if (tempMode == CBC_QRCoderMode::sNUMERIC) { AppendModeInfo(tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendLengthInfo(splitResult.second.GetLength(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; AppendBytes(splitResult.second, tempMode, &headerAndDataBits, encoding, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } else { e = BCExceptionUnknown; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } } } @@ -199,45 +214,41 @@ int32_t CBC_QRCoderEncoder::GetSpanByVersion(CBC_QRCoderMode* modeFirst, CBC_QRCoderMode* modeSecond, int32_t versionNum, int32_t& e) { - if (versionNum == 0) { + if (versionNum == 0) return 0; - } - if ((modeFirst == CBC_QRCoderMode::sALPHANUMERIC) && - (modeSecond == CBC_QRCoderMode::sBYTE)) { - if (versionNum >= 1 && versionNum <= 9) { + + if (modeFirst == CBC_QRCoderMode::sALPHANUMERIC && + modeSecond == CBC_QRCoderMode::sBYTE) { + if (versionNum >= 1 && versionNum <= 9) return 11; - } else if (versionNum >= 10 && versionNum <= 26) { + if (versionNum >= 10 && versionNum <= 26) return 15; - } else if (versionNum >= 27 && versionNum <= 40) { + if (versionNum >= 27 && versionNum <= 40) return 16; - } else { - e = BCExceptionNoSuchVersion; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); - } - } else if ((modeSecond == CBC_QRCoderMode::sALPHANUMERIC) && - (modeFirst == CBC_QRCoderMode::sNUMERIC)) { - if (versionNum >= 1 && versionNum <= 9) { + e = BCExceptionNoSuchVersion; + return 0; + } + if (modeSecond == CBC_QRCoderMode::sALPHANUMERIC && + modeFirst == CBC_QRCoderMode::sNUMERIC) { + if (versionNum >= 1 && versionNum <= 9) return 13; - } else if (versionNum >= 10 && versionNum <= 26) { + if (versionNum >= 10 && versionNum <= 26) return 15; - } else if (versionNum >= 27 && versionNum <= 40) { + if (versionNum >= 27 && versionNum <= 40) return 17; - } else { - e = BCExceptionNoSuchVersion; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); - } - } else if ((modeSecond == CBC_QRCoderMode::sBYTE) && - (modeFirst == CBC_QRCoderMode::sNUMERIC)) { - if (versionNum >= 1 && versionNum <= 9) { + e = BCExceptionNoSuchVersion; + return 0; + } + if (modeSecond == CBC_QRCoderMode::sBYTE && + modeFirst == CBC_QRCoderMode::sNUMERIC) { + if (versionNum >= 1 && versionNum <= 9) return 6; - } else if (versionNum >= 10 && versionNum <= 26) { + if (versionNum >= 10 && versionNum <= 26) return 8; - } else if (versionNum >= 27 && versionNum <= 40) { + if (versionNum >= 27 && versionNum <= 40) return 9; - } else { - e = BCExceptionNoSuchVersion; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); - } + e = BCExceptionNoSuchVersion; + return 0; } return -1; } @@ -253,7 +264,8 @@ void CBC_QRCoderEncoder::MergeString( if (element1->first == CBC_QRCoderMode::sALPHANUMERIC) { int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sALPHANUMERIC, CBC_QRCoderMode::sBYTE, versionNum, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; if (element2->first == CBC_QRCoderMode::sBYTE && element1->second.GetLength() < tmp) { element2->second = element1->second + element2->second; @@ -271,7 +283,8 @@ void CBC_QRCoderEncoder::MergeString( } else if (element1->first == CBC_QRCoderMode::sNUMERIC) { int32_t tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC, CBC_QRCoderMode::sBYTE, versionNum, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; if (element2->first == CBC_QRCoderMode::sBYTE && element1->second.GetLength() < tmp) { element2->second = element1->second + element2->second; @@ -281,7 +294,8 @@ void CBC_QRCoderEncoder::MergeString( } tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC, CBC_QRCoderMode::sALPHANUMERIC, versionNum, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; if (element2->first == CBC_QRCoderMode::sALPHANUMERIC && element1->second.GetLength() < tmp) { element2->second = element1->second + element2->second; @@ -295,7 +309,8 @@ void CBC_QRCoderEncoder::MergeString( return; } MergeString(result, versionNum, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes, @@ -308,23 +323,23 @@ void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes, qrCode->SetMode(mode); CBC_QRCoderVersion* version = CBC_QRCoderVersion::GetVersionForNumber(versionNumber, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t numBytes = version->GetTotalCodeWords(); CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel); int32_t numEcBytes = ecBlocks->GetTotalECCodeWords(); int32_t numRSBlocks = ecBlocks->GetNumBlocks(); int32_t numDataBytes = numBytes - numEcBytes; - if (numDataBytes >= numInputBytes + 3) { - qrCode->SetVersion(versionNumber); - qrCode->SetNumTotalBytes(numBytes); - qrCode->SetNumDataBytes(numDataBytes); - qrCode->SetNumRSBlocks(numRSBlocks); - qrCode->SetNumECBytes(numEcBytes); - qrCode->SetMatrixWidth(version->GetDimensionForVersion()); + if (numDataBytes < numInputBytes + 3) { + e = BCExceptionCannotFindBlockInfo; return; } - e = BCExceptionCannotFindBlockInfo; - BC_EXCEPTION_CHECK_ReturnVoid(e); + qrCode->SetVersion(versionNumber); + qrCode->SetNumTotalBytes(numBytes); + qrCode->SetNumDataBytes(numDataBytes); + qrCode->SetNumRSBlocks(numRSBlocks); + qrCode->SetNumECBytes(numEcBytes); + qrCode->SetMatrixWidth(version->GetDimensionForVersion()); } void CBC_QRCoderEncoder::EncodeWithSpecifyVersion( @@ -340,7 +355,9 @@ void CBC_QRCoderEncoder::EncodeWithSpecifyVersion( dataBits.Init(); SplitString(content, &splitResult); MergeString(&splitResult, versionSpecify, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderMode* tempMode = nullptr; + if (e != BCExceptionNO) + return; + CBC_QRCoderMode* tempMode = nullptr; for (const auto& result : splitResult) { AppendBytes(result.second, result.first, &dataBits, encoding, e); if (e != BCExceptionNO) @@ -368,23 +385,27 @@ void CBC_QRCoderEncoder::EncodeWithSpecifyVersion( InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(), &finalBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix( qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth())); matrix->Init(); int32_t maskPattern = ChooseMaskPattern( &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + qrCode->SetMaskPattern(maskPattern); CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), qrCode->GetMaskPattern(), matrix.get(), e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + qrCode->SetMatrix(std::move(matrix)); - if (!qrCode->IsValid()) { + if (!qrCode->IsValid()) e = BCExceptionInvalidQRCode; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } void CBC_QRCoderEncoder::EncodeWithAutoVersion( @@ -399,7 +420,8 @@ void CBC_QRCoderEncoder::EncodeWithAutoVersion( dataBits.Init(); SplitString(content, &splitResult); MergeString(&splitResult, 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CBC_QRCoderMode* tempMode = nullptr; for (const auto& result : splitResult) { AppendBytes(result.second, result.first, &dataBits, encoding, e); @@ -408,7 +430,9 @@ void CBC_QRCoderEncoder::EncodeWithAutoVersion( } int32_t numInputBytes = dataBits.sizeInBytes(); InitQRCode(numInputBytes, ecLevel, mode, qrCode, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) CBC_QRCoderBitVector headerAndDataBits; + if (e != BCExceptionNO) + return; + CBC_QRCoderBitVector headerAndDataBits; headerAndDataBits.Init(); tempMode = nullptr; int32_t versionNum = qrCode->GetVersion(); @@ -446,22 +470,26 @@ catchException: InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(), &finalBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix( qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth())); matrix->Init(); int32_t maskPattern = ChooseMaskPattern( &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + qrCode->SetMaskPattern(maskPattern); CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), qrCode->GetMaskPattern(), matrix.get(), e); - BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(std::move(matrix)); - if (!qrCode->IsValid()) { + if (e != BCExceptionNO) + return qrCode->SetMatrix(std::move(matrix)); + + if (!qrCode->IsValid()) e = BCExceptionInvalidQRCode; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } void CBC_QRCoderEncoder::Encode(const CFX_WideString& content, @@ -475,44 +503,53 @@ void CBC_QRCoderEncoder::Encode(const CFX_WideString& content, CBC_QRCoderBitVector dataBits; dataBits.Init(); AppendBytes(utf8Data, mode, &dataBits, encoding, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t numInputBytes = dataBits.sizeInBytes(); InitQRCode(numInputBytes, ecLevel, mode, qrCode, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; CBC_QRCoderBitVector headerAndDataBits; headerAndDataBits.Init(); AppendModeInfo(mode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes() : content.GetLength(); AppendLengthInfo(numLetters, qrCode->GetVersion(), mode, &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; headerAndDataBits.AppendBitVector(&dataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) - TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e); + if (e != BCExceptionNO) + return; CBC_QRCoderBitVector finalBits; finalBits.Init(); InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), qrCode->GetNumDataBytes(), qrCode->GetNumRSBlocks(), &finalBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + std::unique_ptr<CBC_CommonByteMatrix> matrix(new CBC_CommonByteMatrix( qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth())); matrix->Init(); int32_t maskPattern = ChooseMaskPattern( &finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + qrCode->SetMaskPattern(maskPattern); CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), qrCode->GetMaskPattern(), matrix.get(), e); - BC_EXCEPTION_CHECK_ReturnVoid(e) qrCode->SetMatrix(std::move(matrix)); - if (!qrCode->IsValid()) { + if (e != BCExceptionNO) + return qrCode->SetMatrix(std::move(matrix)); + + if (!qrCode->IsValid()) e = BCExceptionInvalidQRCode; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } void CBC_QRCoderEncoder::TerminateBits(int32_t numDataBytes, @@ -521,38 +558,40 @@ void CBC_QRCoderEncoder::TerminateBits(int32_t numDataBytes, int32_t capacity = numDataBytes << 3; if (bits->Size() > capacity) { e = BCExceptionDataTooMany; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } for (int32_t i = 0; i < 4 && bits->Size() < capacity; ++i) { bits->AppendBit(0, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } int32_t numBitsInLastByte = bits->Size() % 8; if (numBitsInLastByte > 0) { int32_t numPaddingBits = 8 - numBitsInLastByte; for (int32_t j = 0; j < numPaddingBits; ++j) { bits->AppendBit(0, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) + if (e != BCExceptionNO) + return; } } if (bits->Size() % 8 != 0) { e = BCExceptionDigitLengthMustBe8; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t numPaddingBytes = numDataBytes - bits->sizeInBytes(); for (int32_t k = 0; k < numPaddingBytes; ++k) { if (k % 2 == 0) { bits->AppendBits(0xec, 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } else { bits->AppendBits(0x11, 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } - if (bits->Size() != capacity) { + if (bits->Size() != capacity) e = BCExceptionBitsNotEqualCacity; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } int32_t CBC_QRCoderEncoder::ChooseMaskPattern( @@ -567,7 +606,8 @@ int32_t CBC_QRCoderEncoder::ChooseMaskPattern( maskPattern++) { CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern, matrix, e); - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + if (e != BCExceptionNO) + return 0; int32_t penalty = CalculateMaskPenalty(matrix); if (penalty < minPenalty) { minPenalty = penalty; @@ -619,25 +659,18 @@ void CBC_QRCoderEncoder::AppendBytes(const CFX_ByteString& content, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, int32_t& e) { - if (mode == CBC_QRCoderMode::sNUMERIC) { + if (mode == CBC_QRCoderMode::sNUMERIC) AppendNumericBytes(content, bits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - } else if (mode == CBC_QRCoderMode::sALPHANUMERIC) { + else if (mode == CBC_QRCoderMode::sALPHANUMERIC) AppendAlphaNumericBytes(content, bits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - } else if (mode == CBC_QRCoderMode::sBYTE) { + else if (mode == CBC_QRCoderMode::sBYTE) Append8BitBytes(content, bits, encoding, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - } else if (mode == CBC_QRCoderMode::sKANJI) { + else if (mode == CBC_QRCoderMode::sKANJI) AppendKanjiBytes(content, bits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - } else if (mode == CBC_QRCoderMode::sGBK) { + else if (mode == CBC_QRCoderMode::sGBK) AppendGBKBytes(content, bits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - } else { + else e = BCExceptionUnsupportedMode; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } void CBC_QRCoderEncoder::AppendNumericBytes(const CFX_ByteString& content, @@ -651,14 +684,19 @@ void CBC_QRCoderEncoder::AppendNumericBytes(const CFX_ByteString& content, int32_t num2 = content[i + 1] - '0'; int32_t num3 = content[i + 2] - '0'; bits->AppendBits(num1 * 100 + num2 * 10 + num3, 10, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) i += 3; + if (e != BCExceptionNO) + return; + i += 3; } else if (i + 1 < length) { int32_t num2 = content[i + 1] - '0'; bits->AppendBits(num1 * 10 + num2, 7, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) i += 2; + if (e != BCExceptionNO) + return; + i += 2; } else { bits->AppendBits(num1, 4, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; i++; } } @@ -673,20 +711,23 @@ void CBC_QRCoderEncoder::AppendAlphaNumericBytes(const CFX_ByteString& content, int32_t code1 = GetAlphaNumericCode(content[i]); if (code1 == -1) { e = BCExceptionInvalidateCharacter; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (i + 1 < length) { int32_t code2 = GetAlphaNumericCode(content[i + 1]); if (code2 == -1) { e = BCExceptionInvalidateCharacter; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } bits->AppendBits(code1 * 45 + code2, 11, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; i += 2; } else { bits->AppendBits(code1, 6, e); - BC_EXCEPTION_CHECK_ReturnVoid(e) i++; + if (e != BCExceptionNO) + return; + i++; } } } @@ -704,11 +745,12 @@ void CBC_QRCoderEncoder::AppendGBKBytes(const CFX_ByteString& content, value -= 0xA6A1; } else { e = BCExceptionInvalidateCharacter; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } value = (uint32_t)((value >> 8) * 0x60) + (uint32_t)(value & 0xff); bits->AppendBits(value, 13, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } @@ -718,23 +760,25 @@ void CBC_QRCoderEncoder::Append8BitBytes(const CFX_ByteString& content, int32_t& e) { for (int32_t i = 0; i < content.GetLength(); i++) { bits->AppendBits(content[i], 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } -void CBC_QRCoderEncoder::Append8BitBytes(CFX_ByteArray& bytes, +void CBC_QRCoderEncoder::Append8BitBytes(CFX_ArrayTemplate<uint8_t>& bytes, CBC_QRCoderBitVector* bits, int32_t& e) { for (int32_t i = 0; i < bytes.GetSize(); i++) { bits->AppendBits(bytes[i], 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } void CBC_QRCoderEncoder::AppendKanjiBytes(const CFX_ByteString& content, CBC_QRCoderBitVector* bits, int32_t& e) { - CFX_ByteArray bytes; + CFX_ArrayTemplate<uint8_t> bytes; uint32_t value = 0; for (int32_t i = 0; i < bytes.GetSize(); i += 2) { value = (uint32_t)((uint8_t)(content[i] << 8) | (uint8_t)content[i + 1]); @@ -744,11 +788,12 @@ void CBC_QRCoderEncoder::AppendKanjiBytes(const CFX_ByteString& content, value -= 0xc140; } else { e = BCExceptionInvalidateCharacter; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } value = (uint32_t)((value >> 8) * 0xc0) + (uint32_t)(value & 0xff); bits->AppendBits(value, 13, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } @@ -762,7 +807,8 @@ void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes, for (int32_t versionNum = 1; versionNum <= 40; versionNum++) { CBC_QRCoderVersion* version = CBC_QRCoderVersion::GetVersionForNumber(versionNum, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t numBytes = version->GetTotalCodeWords(); CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel); int32_t numEcBytes = ecBlocks->GetTotalECCodeWords(); @@ -779,17 +825,14 @@ void CBC_QRCoderEncoder::InitQRCode(int32_t numInputBytes, } } e = BCExceptionCannotFindBlockInfo; - BC_EXCEPTION_CHECK_ReturnVoid(e); } void CBC_QRCoderEncoder::AppendModeInfo(CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, int32_t& e) { bits->AppendBits(mode->GetBits(), 4, e); - if (mode == CBC_QRCoderMode::sGBK) { + if (mode == CBC_QRCoderMode::sGBK) bits->AppendBits(1, 4, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } void CBC_QRCoderEncoder::AppendLengthInfo(int32_t numLetters, @@ -798,18 +841,20 @@ void CBC_QRCoderEncoder::AppendLengthInfo(int32_t numLetters, CBC_QRCoderBitVector* bits, int32_t& e) { CBC_QRCoderVersion* qcv = CBC_QRCoderVersion::GetVersionForNumber(version, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t numBits = mode->GetCharacterCountBits(qcv, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; if (numBits > ((1 << numBits) - 1)) { return; } if (mode == CBC_QRCoderMode::sGBK) { bits->AppendBits(numLetters / 2, numBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } bits->AppendBits(numLetters, numBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); } void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, @@ -820,7 +865,7 @@ void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, int32_t& e) { if (bits->sizeInBytes() != numDataBytes) { e = BCExceptionBitsBytesNotMatch; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t dataBytesOffset = 0; int32_t maxNumDataBytes = 0; @@ -837,7 +882,8 @@ void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock); std::unique_ptr<CBC_CommonByteArray> ecBytes( GenerateECBytes(dataBytes.get(), numEcBytesInBlosk, e)); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; maxNumDataBytes = std::max(maxNumDataBytes, dataBytes->Size()); maxNumEcBytes = std::max(maxNumEcBytes, ecBytes->Size()); blocks.Add( @@ -846,14 +892,15 @@ void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, } if (numDataBytes != dataBytesOffset) { e = BCExceptionBytesNotMatchOffset; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } for (int32_t x = 0; x < maxNumDataBytes; x++) { for (int32_t j = 0; j < blocks.GetSize(); j++) { const CBC_CommonByteArray* dataBytes = blocks[j]->GetDataBytes(); if (x < dataBytes->Size()) { result->AppendBits(dataBytes->At(x), 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } } @@ -862,17 +909,16 @@ void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, const CBC_CommonByteArray* ecBytes = blocks[l]->GetErrorCorrectionBytes(); if (y < ecBytes->Size()) { result->AppendBits(ecBytes->At(y), 8, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } } for (int32_t k = 0; k < blocks.GetSize(); k++) { delete blocks[k]; } - if (numTotalBytes != result->sizeInBytes()) { + if (numTotalBytes != result->sizeInBytes()) e = BCExceptionSizeInBytesDiffer; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } void CBC_QRCoderEncoder::GetNumDataBytesAndNumECBytesForBlockID( @@ -907,7 +953,7 @@ CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes( int32_t numEcBytesInBlock, int32_t& e) { int32_t numDataBytes = dataBytes->Size(); - CFX_Int32Array toEncode; + CFX_ArrayTemplate<int32_t> toEncode; toEncode.SetSize(numDataBytes + numEcBytesInBlock); for (int32_t i = 0; i < numDataBytes; i++) { toEncode[i] = (dataBytes->At(i)); @@ -915,7 +961,8 @@ CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes( CBC_ReedSolomonEncoder encode(CBC_ReedSolomonGF256::QRCodeField); encode.Init(); encode.Encode(&toEncode, numEcBytesInBlock, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; CBC_CommonByteArray* ecBytes = new CBC_CommonByteArray(numEcBytesInBlock); for (int32_t j = 0; j < numEcBytesInBlock; j++) { ecBytes->Set(j, toEncode[numDataBytes + j]); diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h index 649938a06..a1b078f24 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h +++ b/xfa/fxbarcode/qrcode/BC_QRCoderEncoder.h @@ -62,7 +62,7 @@ class CBC_QRCoderEncoder { CBC_QRCoderBitVector* bits, CFX_ByteString encoding, int32_t& e); - static void Append8BitBytes(CFX_ByteArray& bytes, + static void Append8BitBytes(CFX_ArrayTemplate<uint8_t>& bytes, CBC_QRCoderBitVector* bits, int32_t& e); static void AppendKanjiBytes(const CFX_ByteString& content, diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp index 8342b9b6d..7953701bb 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.cpp @@ -128,7 +128,7 @@ bool CBC_QRCoderMaskUtil::GetDataMaskBit(int32_t maskPattern, int32_t& e) { if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) { e = (BCExceptionInvalidateMaskPattern); - BC_EXCEPTION_CHECK_ReturnValue(e, false); + return false; } int32_t intermediate = 0, temp = 0; switch (maskPattern) { @@ -161,7 +161,7 @@ bool CBC_QRCoderMaskUtil::GetDataMaskBit(int32_t maskPattern, break; default: { e = BCExceptionInvalidateMaskPattern; - BC_EXCEPTION_CHECK_ReturnValue(e, false); + return false; } } return intermediate == 0; diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp index ca44e0129..d48d81c09 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMatrixUtil.cpp @@ -79,7 +79,7 @@ void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix, int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } matrix->clear((uint8_t)-1); } @@ -92,34 +92,43 @@ void CBC_QRCoderMatrixUtil::BuildMatrix( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } ClearMatrix(matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedBasicPatterns(version, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedTypeInfo(ecLevel, maskPattern, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; MaybeEmbedVersionInfo(version, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedDataBits(dataBits, maskPattern, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(int32_t version, CBC_CommonByteMatrix* matrix, int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } EmbedPositionDetectionPatternsAndSeparators(matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedDarkDotAtLeftBottomCorner(matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; MaybeEmbedPositionAdjustmentPatterns(version, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedTimingPatterns(matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } void CBC_QRCoderMatrixUtil::EmbedTypeInfo( CBC_QRCoderErrorCorrectionLevel* ecLevel, @@ -128,15 +137,17 @@ void CBC_QRCoderMatrixUtil::EmbedTypeInfo( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } CBC_QRCoderBitVector typeInfoBits; typeInfoBits.Init(); MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; for (int32_t i = 0; i < typeInfoBits.Size(); i++) { int32_t bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t x1 = TYPE_INFO_COORDINATES[i][0]; int32_t y1 = TYPE_INFO_COORDINATES[i][1]; matrix->Set(x1, y1, bit); @@ -156,7 +167,7 @@ void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(int32_t version, int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (version < 7) { return; @@ -164,12 +175,14 @@ void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(int32_t version, CBC_QRCoderBitVector versionInfoBits; versionInfoBits.Init(); MakeVersionInfoBits(version, &versionInfoBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t bitIndex = 6 * 3 - 1; for (int32_t i = 0; i < 6; i++) { for (int32_t j = 0; j < 3; j++) { int32_t bit = versionInfoBits.At(bitIndex, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; bitIndex--; matrix->Set(i, matrix->GetHeight() - 11 + j, bit); matrix->Set(matrix->GetHeight() - 11 + j, i, bit); @@ -182,7 +195,7 @@ void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits, int32_t& e) { if (!matrix || !dataBits) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t bitIndex = 0; int32_t direction = -1; @@ -205,14 +218,16 @@ void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits, int32_t bit; if (bitIndex < dataBits->Size()) { bit = dataBits->At(bitIndex, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; bitIndex++; } else { bit = 0; } if (maskPattern != -1) { bool bol = CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; if (bol) { bit ^= 0x01; } @@ -244,46 +259,52 @@ void CBC_QRCoderMatrixUtil::MakeTypeInfoBits( int32_t& e) { if (!bits) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) { e = BCExceptionBadMask; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t typeInfo = (ecLevel->GetBits() << 3) | maskPattern; - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; bits->AppendBits(typeInfo, 5, e); int32_t bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; bits->AppendBits(bchCode, 10, e); CBC_QRCoderBitVector maskBits; maskBits.Init(); maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; bits->XOR(&maskBits, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - if (bits->Size() != 15) { + if (e != BCExceptionNO) + return; + if (bits->Size() != 15) e = BCExceptionBitSizeNot15; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } + void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(int32_t version, CBC_QRCoderBitVector* bits, int32_t& e) { if (!bits) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } bits->AppendBits(version, 6, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; + int32_t bchCode = CalculateBCHCode(version, VERSION_INFO_POLY); bits->AppendBits(bchCode, 12, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); - if (bits->Size() != 18) { + if (e != BCExceptionNO) + return; + + if (bits->Size() != 18) e = BCExceptionBitSizeNot18; - BC_EXCEPTION_CHECK_ReturnVoid(e); - } } + bool CBC_QRCoderMatrixUtil::IsEmpty(int32_t value) { return (uint8_t)value == 0xff; } @@ -291,24 +312,25 @@ bool CBC_QRCoderMatrixUtil::IsValidValue(int32_t value) { return ((uint8_t)value == 0xff || (uint8_t)value == 0x00 || (uint8_t)value == 0x01); } + void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } for (int32_t i = 8; i < matrix->GetWidth() - 8; i++) { int32_t bit = (i + 1) % 2; if (!IsValidValue(matrix->Get(i, 6))) { e = BCExceptionInvalidateImageData; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (IsEmpty(matrix->Get(i, 6))) { matrix->Set(i, 6, bit); } if (!IsValidValue(matrix->Get(6, i))) { e = BCExceptionInvalidateImageData; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (IsEmpty(matrix->Get(6, i))) { matrix->Set(6, i, bit); @@ -320,11 +342,11 @@ void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (matrix->Get(8, matrix->GetHeight() - 8) == 0) { e = BCExceptionHeight_8BeZero; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } matrix->Set(8, matrix->GetHeight() - 8, 1); } @@ -335,12 +357,12 @@ void CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } for (int32_t x = 0; x < 8; x++) { if (!IsEmpty(matrix->Get(xStart + x, yStart))) { e = BCExceptionInvalidateData; - BC_EXCEPTION_CHECK_ReturnVoid(e) + return; } matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]); } @@ -352,12 +374,12 @@ void CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } for (int32_t y = 0; y < 7; y++) { if (!IsEmpty(matrix->Get(xStart, yStart + y))) { e = BCExceptionInvalidateData; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]); } @@ -369,13 +391,14 @@ void CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } for (int32_t y = 0; y < 5; y++) { for (int32_t x = 0; x < 5; x++) { if (!IsEmpty(matrix->Get(xStart + x, y + yStart))) { e = BCExceptionInvalidateData; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]); } @@ -388,13 +411,13 @@ void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } for (int32_t y = 0; y < 7; y++) { for (int32_t x = 0; x < 7; x++) { if (!IsEmpty(matrix->Get(xStart + x, yStart + y))) { e = BCExceptionInvalidateData; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]); } @@ -405,32 +428,41 @@ void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } int32_t pdpWidth = 7; EmbedPositionDetectionPattern(0, 0, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t hspWidth = 8; EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; int32_t vspSize = 7; EmbedVerticalSeparationPattern(vspSize, 0, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns( int32_t version, @@ -438,7 +470,7 @@ void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns( int32_t& e) { if (!matrix) { e = BCExceptionNullPointer; - BC_EXCEPTION_CHECK_ReturnVoid(e); + return; } if (version < 2) { return; @@ -456,7 +488,8 @@ void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns( } if (IsEmpty(matrix->Get(x, y))) { EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e); - BC_EXCEPTION_CHECK_ReturnVoid(e); + if (e != BCExceptionNO) + return; } } } diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp index 74c556392..a1283dda9 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoderMode.cpp @@ -98,12 +98,10 @@ CBC_QRCoderMode* CBC_QRCoderMode::ForBits(int32_t bits, int32_t& e) { return sFNC1_SECOND_POSITION; case 0x0D: return sGBK; - default: { + default: e = BCExceptionUnsupportedMode; - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); - } + return nullptr; } - return nullptr; } int32_t CBC_QRCoderMode::GetBits() const { @@ -118,7 +116,7 @@ int32_t CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version, int32_t& e) const { if (m_characterCountBitsForVersions.empty()) { e = BCExceptionCharacterNotThisMode; - BC_EXCEPTION_CHECK_ReturnValue(e, 0); + return 0; } int32_t number = version->GetVersionNumber(); int32_t offset; diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp index b0b445bed..befdc17a9 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp +++ b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.cpp @@ -354,7 +354,7 @@ CBC_QRCoderVersion::~CBC_QRCoderVersion() { int32_t CBC_QRCoderVersion::GetVersionNumber() { return m_versionNumber; } -CFX_Int32Array* CBC_QRCoderVersion::GetAlignmentPatternCenters() { +CFX_ArrayTemplate<int32_t>* CBC_QRCoderVersion::GetAlignmentPatternCenters() { return &m_alignmentPatternCenters; } int32_t CBC_QRCoderVersion::GetTotalCodeWords() { @@ -372,10 +372,11 @@ CBC_QRCoderVersion* CBC_QRCoderVersion::GetProvisionalVersionForDimension( int32_t& e) { if ((dimension % 4) != 1) { e = BCExceptionRead; - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + return nullptr; } CBC_QRCoderVersion* qcv = GetVersionForNumber((dimension - 17) >> 2, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return qcv; } CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation( @@ -387,7 +388,8 @@ CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation( int32_t targetVersion = VERSION_DECODE_INFO[i]; if (targetVersion == versionBits) { CBC_QRCoderVersion* qcv = GetVersionForNumber(i + 7, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return qcv; } int32_t bitsDifference = NumBitsDiffering(versionBits, targetVersion); @@ -398,7 +400,8 @@ CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation( } if (bestDifference <= 3) { CBC_QRCoderVersion* qcv = GetVersionForNumber(bestVersion, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; return qcv; } return nullptr; @@ -408,11 +411,14 @@ CBC_CommonBitMatrix* CBC_QRCoderVersion::BuildFunctionPattern(int32_t& e) { CBC_CommonBitMatrix* bitMatrix = new CBC_CommonBitMatrix(); bitMatrix->Init(dimension); bitMatrix->SetRegion(0, 0, 9, 9, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; bitMatrix->SetRegion(dimension - 8, 0, 8, 9, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; bitMatrix->SetRegion(0, dimension - 8, 9, 8, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; int32_t max = m_alignmentPatternCenters.GetSize(); for (int32_t x = 0; x < max; x++) { int32_t i = m_alignmentPatternCenters[x] - 2; @@ -421,18 +427,23 @@ CBC_CommonBitMatrix* CBC_QRCoderVersion::BuildFunctionPattern(int32_t& e) { continue; } bitMatrix->SetRegion(m_alignmentPatternCenters[y] - 2, i, 5, 5, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; } } bitMatrix->SetRegion(6, 9, 1, dimension - 17, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; bitMatrix->SetRegion(9, 6, dimension - 17, 1, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; if (m_versionNumber > 6) { bitMatrix->SetRegion(dimension - 11, 0, 3, 6, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; bitMatrix->SetRegion(0, dimension - 11, 6, 3, e); - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + if (e != BCExceptionNO) + return nullptr; } return bitMatrix; } @@ -771,7 +782,7 @@ CBC_QRCoderVersion* CBC_QRCoderVersion::GetVersionForNumber( } if (versionNumber < 1 || versionNumber > 40) { e = BCExceptionIllegalArgument; - BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); + return nullptr; } return (*VERSION)[versionNumber - 1]; } diff --git a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h index 43b4b6062..030dd512a 100644 --- a/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h +++ b/xfa/fxbarcode/qrcode/BC_QRCoderVersion.h @@ -23,7 +23,7 @@ class CBC_QRCoderVersion { int32_t GetTotalCodeWords(); int32_t GetDimensionForVersion(); CBC_CommonBitMatrix* BuildFunctionPattern(int32_t& e); - CFX_Int32Array* GetAlignmentPatternCenters(); + CFX_ArrayTemplate<int32_t>* GetAlignmentPatternCenters(); CBC_QRCoderECBlocks* GetECBlocksForLevel( CBC_QRCoderErrorCorrectionLevel* ecLevel); static CBC_QRCoderVersion* GetVersionForNumber(int32_t versionNumber, @@ -48,7 +48,7 @@ class CBC_QRCoderVersion { int32_t m_versionNumber; int32_t m_totalCodeWords; - CFX_Int32Array m_alignmentPatternCenters; + CFX_ArrayTemplate<int32_t> m_alignmentPatternCenters; CFX_ArrayTemplate<CBC_QRCoderECBlocks*> m_ecBlocksArray; }; diff --git a/xfa/fxbarcode/utils.h b/xfa/fxbarcode/utils.h index 7473d4196..1cb8d8501 100644 --- a/xfa/fxbarcode/utils.h +++ b/xfa/fxbarcode/utils.h @@ -15,7 +15,8 @@ bool BC_FX_ByteString_Replace(CFX_ByteString& dst, int32_t count, FX_CHAR c); void BC_FX_ByteString_Append(CFX_ByteString& dst, int32_t count, FX_CHAR c); -void BC_FX_ByteString_Append(CFX_ByteString& dst, const CFX_ByteArray& ba); +void BC_FX_ByteString_Append(CFX_ByteString& dst, + const CFX_ArrayTemplate<uint8_t>& ba); #if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_) #include <limits> @@ -164,15 +165,5 @@ enum BCFORMAT { #define BCExceptiontNotFoundInstance 104 #define BCExceptionNotFoundInstance 105 #define BCExceptionCannotMetadata 106 -#define TWO_DIGIT_DATA_LENGTH_SIZE 24 -#define THREE_DIGIT_DATA_LENGTH_SIZE 23 -#define THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH_SIZE 57 -#define FOUR_DIGIT_DATA_LENGTH_SIZE 17 -#define BC_EXCEPTION_CHECK_ReturnVoid(e) \ - if (e != BCExceptionNO) \ - return; -#define BC_EXCEPTION_CHECK_ReturnValue(e, v) \ - if (e != BCExceptionNO) \ - return v; #endif // XFA_FXBARCODE_UTILS_H_ diff --git a/xfa/fxfa/app/cxfa_csstagprovider.h b/xfa/fxfa/app/cxfa_csstagprovider.h index 3c2378440..f5db86739 100644 --- a/xfa/fxfa/app/cxfa_csstagprovider.h +++ b/xfa/fxfa/app/cxfa_csstagprovider.h @@ -13,30 +13,27 @@ class CXFA_CSSTagProvider { public: - using AttributeMap = std::map<CFX_WideString, CFX_WideString>; - CXFA_CSSTagProvider(); ~CXFA_CSSTagProvider(); CFX_WideString GetTagName() { return m_wsTagName; } - AttributeMap::iterator begin() { return m_Attributes.begin(); } - AttributeMap::iterator end() { return m_Attributes.end(); } - - bool empty() const { return m_Attributes.empty(); } - - void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; } + void SetTagName(const CFX_WideString& wsName) { m_wsTagName = wsName; } void SetAttribute(const CFX_WideString& wsAttr, const CFX_WideString& wsValue) { m_Attributes.insert({wsAttr, wsValue}); } + CFX_WideString GetAttribute(const CFX_WideString& wsAttr) { + return m_Attributes[wsAttr]; + } + bool m_bTagAvailable; bool m_bContent; - protected: + private: CFX_WideString m_wsTagName; - AttributeMap m_Attributes; + std::map<CFX_WideString, CFX_WideString> m_Attributes; }; #endif // XFA_FXFA_APP_CXFA_CSSTAGPROVIDER_H_ diff --git a/xfa/fxfa/app/cxfa_linkuserdata.cpp b/xfa/fxfa/app/cxfa_linkuserdata.cpp index f1e15f406..4128cd882 100644 --- a/xfa/fxfa/app/cxfa_linkuserdata.cpp +++ b/xfa/fxfa/app/cxfa_linkuserdata.cpp @@ -7,21 +7,6 @@ #include "xfa/fxfa/app/cxfa_linkuserdata.h" CXFA_LinkUserData::CXFA_LinkUserData(FX_WCHAR* pszText) - : m_dwRefCount(1), m_wsURLContent(pszText) {} + : m_wsURLContent(pszText) {} CXFA_LinkUserData::~CXFA_LinkUserData() {} - -uint32_t CXFA_LinkUserData::Retain() { - return ++m_dwRefCount; -} - -uint32_t CXFA_LinkUserData::Release() { - uint32_t dwRefCount = --m_dwRefCount; - if (dwRefCount <= 0) - delete this; - return dwRefCount; -} - -const FX_WCHAR* CXFA_LinkUserData::GetLinkURL() { - return m_wsURLContent.c_str(); -} diff --git a/xfa/fxfa/app/cxfa_linkuserdata.h b/xfa/fxfa/app/cxfa_linkuserdata.h index 621398ecb..852b46764 100644 --- a/xfa/fxfa/app/cxfa_linkuserdata.h +++ b/xfa/fxfa/app/cxfa_linkuserdata.h @@ -7,23 +7,22 @@ #ifndef XFA_FXFA_APP_CXFA_LINKUSERDATA_H_ #define XFA_FXFA_APP_CXFA_LINKUSERDATA_H_ +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" -class CXFA_LinkUserData : public IFX_Retainable { +class CXFA_LinkUserData : public CFX_Retainable { public: - explicit CXFA_LinkUserData(FX_WCHAR* pszText); - ~CXFA_LinkUserData() override; - - // IFX_Retainable: - uint32_t Retain() override; - uint32_t Release() override; + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); - const FX_WCHAR* GetLinkURL(); + const FX_WCHAR* GetLinkURL() const { return m_wsURLContent.c_str(); } protected: - uint32_t m_dwRefCount; + explicit CXFA_LinkUserData(FX_WCHAR* pszText); + ~CXFA_LinkUserData() override; + CFX_WideString m_wsURLContent; }; diff --git a/xfa/fxfa/app/cxfa_loadercontext.cpp b/xfa/fxfa/app/cxfa_loadercontext.cpp index 56ac71bfb..0733c52df 100644 --- a/xfa/fxfa/app/cxfa_loadercontext.cpp +++ b/xfa/fxfa/app/cxfa_loadercontext.cpp @@ -16,7 +16,6 @@ CXFA_LoaderContext::CXFA_LoaderContext() m_iTotalLines(-1), m_pXMLNode(nullptr), m_pNode(nullptr), - m_pParentStyle(nullptr), m_dwFlags(0) {} CXFA_LoaderContext::~CXFA_LoaderContext() {} diff --git a/xfa/fxfa/app/cxfa_loadercontext.h b/xfa/fxfa/app/cxfa_loadercontext.h index c647f62a3..d8ccdbe7e 100644 --- a/xfa/fxfa/app/cxfa_loadercontext.h +++ b/xfa/fxfa/app/cxfa_loadercontext.h @@ -11,10 +11,10 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_system.h" +#include "xfa/fde/css/cfde_csscomputedstyle.h" class CFDE_XMLNode; class CXFA_Node; -class CFDE_CSSComputedStyle; class CXFA_LoaderContext { public: @@ -31,7 +31,7 @@ class CXFA_LoaderContext { int32_t m_iTotalLines; CFDE_XMLNode* m_pXMLNode; CXFA_Node* m_pNode; - CFDE_CSSComputedStyle* m_pParentStyle; + CFX_RetainPtr<CFDE_CSSComputedStyle> m_pParentStyle; CFX_ArrayTemplate<FX_FLOAT> m_lineHeights; uint32_t m_dwFlags; std::vector<FX_FLOAT> m_BlocksHeight; diff --git a/xfa/fxfa/app/cxfa_textlayout.cpp b/xfa/fxfa/app/cxfa_textlayout.cpp index 788fea2e7..06cbfe0c7 100644 --- a/xfa/fxfa/app/cxfa_textlayout.cpp +++ b/xfa/fxfa/app/cxfa_textlayout.cpp @@ -80,7 +80,7 @@ CFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() { CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLChild); CFX_WideString wsTag; pXMLElement->GetLocalTagName(wsTag); - if (wsTag == FX_WSTRC(L"body") || wsTag == FX_WSTRC(L"html")) { + if (wsTag == L"body" || wsTag == L"html") { pXMLContainer = pXMLChild; break; } @@ -89,14 +89,12 @@ CFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode() { return pXMLContainer; } -CFX_RTFBreak* CXFA_TextLayout::CreateBreak(bool bDefault) { +std::unique_ptr<CFX_RTFBreak> CXFA_TextLayout::CreateBreak(bool bDefault) { uint32_t dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab; if (!bDefault) dwStyle |= FX_RTFLAYOUTSTYLE_Pagination; - CFX_RTFBreak* pBreak = new CFX_RTFBreak(0); - pBreak->SetLayoutStyles(dwStyle); - pBreak->SetLineBreakChar(L'\n'); + auto pBreak = pdfium::MakeUnique<CFX_RTFBreak>(dwStyle); pBreak->SetLineBreakTolerance(1); pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, nullptr)); pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, nullptr)); @@ -109,26 +107,26 @@ void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth) { FX_FLOAT fStart = 0; FX_FLOAT fStartPos = 0; if (para) { - int32_t iAlign = FX_RTFLINEALIGNMENT_Left; + CFX_RTFLineAlignment iAlign = CFX_RTFLineAlignment::Left; switch (para.GetHorizontalAlign()) { case XFA_ATTRIBUTEENUM_Center: - iAlign = FX_RTFLINEALIGNMENT_Center; + iAlign = CFX_RTFLineAlignment::Center; break; case XFA_ATTRIBUTEENUM_Right: - iAlign = FX_RTFLINEALIGNMENT_Right; + iAlign = CFX_RTFLineAlignment::Right; break; case XFA_ATTRIBUTEENUM_Justify: - iAlign = FX_RTFLINEALIGNMENT_Justified; + iAlign = CFX_RTFLineAlignment::Justified; break; case XFA_ATTRIBUTEENUM_JustifyAll: - iAlign = FX_RTFLINEALIGNMENT_Distributed; + iAlign = CFX_RTFLineAlignment::Distributed; break; } m_pBreak->SetAlignment(iAlign); fStart = para.GetMarginLeft(); if (m_pTextProvider->IsCheckButtonAndAutoWidth()) { - if (iAlign != FX_RTFLINEALIGNMENT_Left) + if (iAlign != CFX_RTFLineAlignment::Left) fLineWidth -= para.GetMarginRight(); } else { fLineWidth -= para.GetMarginRight(); @@ -168,24 +166,25 @@ void CXFA_TextLayout::InitBreak(CFDE_CSSComputedStyle* pStyle, if (eDisplay == FDE_CSSDisplay::Block || eDisplay == FDE_CSSDisplay::ListItem) { - int32_t iAlign = FX_RTFLINEALIGNMENT_Left; + CFX_RTFLineAlignment iAlign = CFX_RTFLineAlignment::Left; switch (pStyle->GetTextAlign()) { case FDE_CSSTextAlign::Right: - iAlign = FX_RTFLINEALIGNMENT_Right; + iAlign = CFX_RTFLineAlignment::Right; break; case FDE_CSSTextAlign::Center: - iAlign = FX_RTFLINEALIGNMENT_Center; + iAlign = CFX_RTFLineAlignment::Center; break; case FDE_CSSTextAlign::Justify: - iAlign = FX_RTFLINEALIGNMENT_Justified; + iAlign = CFX_RTFLineAlignment::Justified; break; case FDE_CSSTextAlign::JustifyAll: - iAlign = FX_RTFLINEALIGNMENT_Distributed; + iAlign = CFX_RTFLineAlignment::Distributed; break; default: break; } m_pBreak->SetAlignment(iAlign); + FX_FLOAT fStart = 0; const FDE_CSSRect* pRect = pStyle->GetMarginWidth(); const FDE_CSSRect* pPaddingRect = pStyle->GetPaddingWidth(); @@ -261,7 +260,7 @@ FX_FLOAT CXFA_TextLayout::GetLayoutHeight() { m_pLoader->m_fLastPos = 0; CalcSize(szMax, szMax, szDef); m_pLoader->m_bSaveLineHeight = false; - return szDef.y; + return szDef.height; } FX_FLOAT fHeight = m_pLoader->m_fHeight; @@ -293,7 +292,7 @@ FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth) { m_pLoader->m_fLastPos = 0; CalcSize(szMax, szMax, szDef); m_pLoader->m_bSaveLineHeight = false; - fWidth = szDef.x; + fWidth = szDef.width; } return fWidth; } @@ -388,11 +387,11 @@ int32_t CXFA_TextLayout::CountBlocks() const { bool CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize, const CFX_SizeF& maxSize, CFX_SizeF& defaultSize) { - defaultSize.x = maxSize.x; - if (defaultSize.x < 1) - defaultSize.x = 0xFFFF; + defaultSize.width = maxSize.width; + if (defaultSize.width < 1) + defaultSize.width = 0xFFFF; - m_pBreak.reset(CreateBreak(false)); + m_pBreak = CreateBreak(false); FX_FLOAT fLinePos = 0; m_iLines = 0; m_fMaxWidth = 0; @@ -406,11 +405,11 @@ bool CXFA_TextLayout::CalcSize(const CFX_SizeF& minSize, } bool CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) { - if (size.x < 1) + if (size.width < 1) return false; Unload(); - m_pBreak.reset(CreateBreak(true)); + m_pBreak = CreateBreak(true); if (m_pLoader) { m_pLoader->m_iTotalLines = -1; m_pLoader->m_iChar = 0; @@ -419,7 +418,7 @@ bool CXFA_TextLayout::Layout(const CFX_SizeF& size, FX_FLOAT* fHeight) { m_iLines = 0; FX_FLOAT fLinePos = 0; Loader(size, fLinePos, true); - UpdateAlign(size.y, fLinePos); + UpdateAlign(size.height, fLinePos); m_pTabstopContext.reset(); if (fHeight) *fHeight = fLinePos; @@ -445,7 +444,7 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) { return true; if (iBlock == iBlocksHeightCount) { Unload(); - m_pBreak.reset(CreateBreak(true)); + m_pBreak = CreateBreak(true); fLinePos = m_pLoader->m_fStartLineOffset; for (int32_t i = 0; i < iBlocksHeightCount; i++) fLinePos -= m_pLoader->m_BlocksHeight[i * 2 + 1]; @@ -456,7 +455,7 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) { Loader(szText, fLinePos, true); if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f) - UpdateAlign(szText.y, fLinePos); + UpdateAlign(szText.height, fLinePos); } else if (m_pTextDataNode) { iBlock *= 2; if (iBlock < iCount - 2) @@ -476,7 +475,7 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) { for (; pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) { if (!LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, - true)) { + true, nullptr)) { break; } } @@ -495,7 +494,7 @@ bool CXFA_TextLayout::Layout(int32_t iBlock) { for (; pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling)) { if (!LoadRichText(pXMLNode, szText, fLinePos, - m_pLoader->m_pParentStyle, true)) { + m_pLoader->m_pParentStyle, true, nullptr)) { break; } } @@ -654,10 +653,9 @@ bool CXFA_TextLayout::Loader(const CFX_SizeF& szText, if (!m_textParser.IsParsed()) m_textParser.DoParse(pXMLContainer, m_pTextProvider); - CFDE_CSSComputedStyle* pRootStyle = - m_textParser.CreateRootStyle(m_pTextProvider); - LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces); - pRootStyle->Release(); + auto pRootStyle = m_textParser.CreateRootStyle(m_pTextProvider); + LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces, + nullptr); } } else { LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces); @@ -669,7 +667,7 @@ void CXFA_TextLayout::LoadText(CXFA_Node* pNode, const CFX_SizeF& szText, FX_FLOAT& fLinePos, bool bSavePieces) { - InitBreak(szText.x); + InitBreak(szText.width); CXFA_Para para = m_pTextProvider->GetParaNode(); FX_FLOAT fSpaceAbove = 0; @@ -695,18 +693,19 @@ void CXFA_TextLayout::LoadText(CXFA_Node* pNode, if (bRet && m_pLoader) m_pLoader->m_pNode = pNode; else - EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces); + EndBreak(CFX_RTFBreakType::Paragraph, fLinePos, bSavePieces); } -bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, - const CFX_SizeF& szText, - FX_FLOAT& fLinePos, - CFDE_CSSComputedStyle* pParentStyle, - bool bSavePieces, - CXFA_LinkUserData* pLinkData, - bool bEndBreak, - bool bIsOl, - int32_t iLiCount) { +bool CXFA_TextLayout::LoadRichText( + CFDE_XMLNode* pXMLNode, + const CFX_SizeF& szText, + FX_FLOAT& fLinePos, + const CFX_RetainPtr<CFDE_CSSComputedStyle>& pParentStyle, + bool bSavePieces, + CFX_RetainPtr<CXFA_LinkUserData> pLinkData, + bool bEndBreak, + bool bIsOl, + int32_t iLiCount) { if (!pXMLNode) return false; @@ -715,7 +714,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, FDE_CSSDisplay eDisplay = FDE_CSSDisplay::None; bool bContentNode = false; FX_FLOAT fSpaceBelow = 0; - CFDE_CSSComputedStyle* pStyle = nullptr; + CFX_RetainPtr<CFDE_CSSComputedStyle> pStyle; CFX_WideString wsName; if (bEndBreak) { bool bCurOl = false; @@ -732,7 +731,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, pElement = static_cast<CFDE_XMLElement*>(pXMLNode); pElement->GetLocalTagName(wsName); } - if (wsName == FX_WSTRC(L"ol")) { + if (wsName == L"ol") { bIsOl = true; bCurOl = true; } @@ -744,15 +743,14 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, return true; } - pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle); - InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x, - pXMLNode, pParentStyle); + pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle.Get()); + InitBreak(bContentNode ? pParentStyle.Get() : pStyle.Get(), eDisplay, + szText.width, pXMLNode, pParentStyle.Get()); if ((eDisplay == FDE_CSSDisplay::Block || eDisplay == FDE_CSSDisplay::ListItem) && pStyle && - (wsName.IsEmpty() || - (wsName != FX_WSTRC(L"body") && wsName != FX_WSTRC(L"html") && - wsName != FX_WSTRC(L"ol") && wsName != FX_WSTRC(L"ul")))) { + (wsName.IsEmpty() || (wsName != L"body" && wsName != L"html" && + wsName != L"ol" && wsName != L"ul"))) { const FDE_CSSRect* pRect = pStyle->GetMarginWidth(); if (pRect) { fLinePos += pRect->top.GetValue(); @@ -760,32 +758,32 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, } } - if (wsName == FX_WSTRC(L"a")) { + if (wsName == L"a") { CFX_WideString wsLinkContent; ASSERT(pElement); pElement->GetString(L"href", wsLinkContent); if (!wsLinkContent.IsEmpty()) { - pLinkData = new CXFA_LinkUserData( + pLinkData = pdfium::MakeRetain<CXFA_LinkUserData>( wsLinkContent.GetBuffer(wsLinkContent.GetLength())); wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength()); } } - int32_t iTabCount = - m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle); - bool bSpaceRun = - m_textParser.IsSpaceRun(bContentNode ? pParentStyle : pStyle); + int32_t iTabCount = m_textParser.CountTabs( + bContentNode ? pParentStyle.Get() : pStyle.Get()); + bool bSpaceRun = m_textParser.IsSpaceRun( + bContentNode ? pParentStyle.Get() : pStyle.Get()); CFX_WideString wsText; if (bContentNode && iTabCount == 0) { static_cast<CFDE_XMLText*>(pXMLNode)->GetText(wsText); - } else if (wsName == FX_WSTRC(L"br")) { + } else if (wsName == L"br") { wsText = L'\n'; - } else if (wsName == FX_WSTRC(L"li")) { + } else if (wsName == L"li") { bCurLi = true; if (bIsOl) wsText.Format(L"%d. ", iLiCount); else - wsText = 0x00B7 + FX_WSTRC(L" "); + wsText = 0x00B7 + CFX_WideStringC(L" ", 1); } else if (!bContentNode) { if (iTabCount > 0) { while (iTabCount-- > 0) @@ -819,10 +817,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, if (wsText.GetLength() > 0) { if (!m_pLoader || m_pLoader->m_iChar == 0) { - if (pLinkData) - pLinkData->Retain(); - - CXFA_TextUserData* pUserData = new CXFA_TextUserData( + auto pUserData = pdfium::MakeRetain<CXFA_TextUserData>( bContentNode ? pParentStyle : pStyle, pLinkData); m_pBreak->SetUserData(pUserData); } @@ -835,8 +830,6 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, m_pLoader->m_pXMLNode = pXMLNode; m_pLoader->m_pParentStyle = pParentStyle; } - if (pStyle) - pStyle->Release(); return false; } return true; @@ -863,7 +856,7 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE; } if (bCurLi) - EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces); + EndBreak(CFX_RTFBreakType::Line, fLinePos, bSavePieces); } else { if (pContext) eDisplay = pContext->GetDisplay(); @@ -871,25 +864,16 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, if (m_bBlockContinue) { if (pContext && !bContentNode) { - uint32_t dwStatus = (eDisplay == FDE_CSSDisplay::Block) - ? FX_RTFBREAK_ParagraphBreak - : FX_RTFBREAK_PieceBreak; + CFX_RTFBreakType dwStatus = (eDisplay == FDE_CSSDisplay::Block) + ? CFX_RTFBreakType::Paragraph + : CFX_RTFBreakType::Piece; EndBreak(dwStatus, fLinePos, bSavePieces); if (eDisplay == FDE_CSSDisplay::Block) { fLinePos += fSpaceBelow; if (m_pTabstopContext) m_pTabstopContext->RemoveAll(); } - if (wsName == FX_WSTRC(L"a")) { - if (pLinkData) { - pLinkData->Release(); - pLinkData = nullptr; - } - } if (IsEnd(bSavePieces)) { - if (pStyle) - pStyle->Release(); - if (m_pLoader && m_pLoader->m_iTotalLines > -1) { m_pLoader->m_pXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::NextSibling); @@ -899,9 +883,6 @@ bool CXFA_TextLayout::LoadRichText(CFDE_XMLNode* pXMLNode, } } } - if (pStyle) - pStyle->Release(); - return true; } @@ -909,7 +890,7 @@ bool CXFA_TextLayout::AppendChar(const CFX_WideString& wsText, FX_FLOAT& fLinePos, FX_FLOAT fSpaceAbove, bool bSavePieces) { - uint32_t dwStatus = 0; + CFX_RTFBreakType dwStatus = CFX_RTFBreakType::None; int32_t iChar = 0; if (m_pLoader) iChar = m_pLoader->m_iChar; @@ -920,14 +901,16 @@ bool CXFA_TextLayout::AppendChar(const CFX_WideString& wsText, if (wch == 0xA0) wch = 0x20; - if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) { + dwStatus = m_pBreak->AppendChar(wch); + if (dwStatus != CFX_RTFBreakType::None && + dwStatus != CFX_RTFBreakType::Piece) { AppendTextLine(dwStatus, fLinePos, bSavePieces); if (IsEnd(bSavePieces)) { if (m_pLoader) m_pLoader->m_iChar = i; return true; } - if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) + if (dwStatus == CFX_RTFBreakType::Paragraph && m_bRichText) fLinePos += fSpaceAbove; } } @@ -967,11 +950,11 @@ void CXFA_TextLayout::ProcessText(CFX_WideString& wsText) { wsText = wsText.Left(iTrimLeft); } -void CXFA_TextLayout::EndBreak(uint32_t dwStatus, +void CXFA_TextLayout::EndBreak(CFX_RTFBreakType dwStatus, FX_FLOAT& fLinePos, bool bSavePieces) { dwStatus = m_pBreak->EndBreak(dwStatus); - if (dwStatus > FX_RTFBREAK_PieceBreak) + if (dwStatus != CFX_RTFBreakType::None && dwStatus != CFX_RTFBreakType::Piece) AppendTextLine(dwStatus, fLinePos, bSavePieces, true); } @@ -1016,10 +999,10 @@ void CXFA_TextLayout::DoTabstops(CFDE_CSSComputedStyle* pStyle, } else if (dwAlign == FX_HashCode_GetW(L"decimal", false)) { int32_t iChars = pPiece->iChars; for (int32_t i = 0; i < iChars; i++) { - if (pPiece->pszText[i] == L'.') + if (pPiece->szText[i] == L'.') break; - fLeft += pPiece->pWidths[i] / 20000.0f; + fLeft += pPiece->Widths[i] / 20000.0f; } } m_pTabstopContext->m_fLeft = @@ -1031,7 +1014,7 @@ void CXFA_TextLayout::DoTabstops(CFDE_CSSComputedStyle* pStyle, } } -void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, +void CXFA_TextLayout::AppendTextLine(CFX_RTFBreakType dwStatus, FX_FLOAT& fLinePos, bool bSavePieces, bool bEndBreak) { @@ -1039,7 +1022,7 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, if (iPieces < 1) return; - CFDE_CSSComputedStyle* pStyle = nullptr; + CFX_RetainPtr<CFDE_CSSComputedStyle> pStyle; if (bSavePieces) { auto pNew = pdfium::MakeUnique<CXFA_PieceLine>(); CXFA_PieceLine* pPieceLine = pNew.get(); @@ -1051,35 +1034,35 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, int32_t i = 0; for (i = 0; i < iPieces; i++) { const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i); - CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData; + CXFA_TextUserData* pUserData = + static_cast<CXFA_TextUserData*>(pPiece->m_pUserData.Get()); if (pUserData) pStyle = pUserData->m_pStyle; FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f; auto pTP = pdfium::MakeUnique<XFA_TextPiece>(); - pTP->pszText = FX_Alloc(FX_WCHAR, pPiece->m_iChars); - pTP->pWidths = FX_Alloc(int32_t, pPiece->m_iChars); pTP->iChars = pPiece->m_iChars; - pPiece->GetString(pTP->pszText); - pPiece->GetWidths(pTP->pWidths); + pTP->szText = pPiece->GetString(); + pTP->Widths = pPiece->GetWidths(); pTP->iBidiLevel = pPiece->m_iBidiLevel; pTP->iHorScale = pPiece->m_iHorizontalScale; pTP->iVerScale = pPiece->m_iVerticalScale; - m_textParser.GetUnderline(m_pTextProvider, pStyle, pTP->iUnderline, + m_textParser.GetUnderline(m_pTextProvider, pStyle.Get(), pTP->iUnderline, pTP->iPeriod); - m_textParser.GetLinethrough(m_pTextProvider, pStyle, pTP->iLineThrough); - pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle); - pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle); - pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle); + m_textParser.GetLinethrough(m_pTextProvider, pStyle.Get(), + pTP->iLineThrough); + pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle.Get()); + pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle.Get()); + pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle.Get()); pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f; pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f; pTP->rtPiece.height = (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f; FX_FLOAT fBaseLineTemp = - m_textParser.GetBaseline(m_pTextProvider, pStyle); + m_textParser.GetBaseline(m_pTextProvider, pStyle.Get()); pTP->rtPiece.top = fBaseLineTemp; FX_FLOAT fLineHeight = m_textParser.GetLineHeight( - m_pTextProvider, pStyle, m_iLines == 0, fVerScale); + m_pTextProvider, pStyle.Get(), m_iLines == 0, fVerScale); if (fBaseLineTemp > 0) { FX_FLOAT fLineHeightTmp = fBaseLineTemp + pTP->rtPiece.height; if (fLineHeight < fLineHeightTmp) @@ -1090,14 +1073,9 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, fBaseLine = -fBaseLineTemp; } fLineStep = std::max(fLineStep, fLineHeight); - if (pUserData && pUserData->m_pLinkData) { - pUserData->m_pLinkData->Retain(); - pTP->pLinkData = pUserData->m_pLinkData; - } else { - pTP->pLinkData = nullptr; - } + pTP->pLinkData = pUserData ? pUserData->m_pLinkData : nullptr; pPieceLine->m_textPieces.push_back(std::move(pTP)); - DoTabstops(pStyle, pPieceLine); + DoTabstops(pStyle.Get(), pPieceLine); } for (const auto& pTP : pPieceLine->m_textPieces) { FX_FLOAT& fTop = pTP->rtPiece.top; @@ -1111,13 +1089,15 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, FX_FLOAT fLineWidth = 0; for (int32_t i = 0; i < iPieces; i++) { const CFX_RTFPiece* pPiece = m_pBreak->GetBreakPiece(i); - CXFA_TextUserData* pUserData = (CXFA_TextUserData*)pPiece->m_pUserData; + CXFA_TextUserData* pUserData = + static_cast<CXFA_TextUserData*>(pPiece->m_pUserData.Get()); if (pUserData) pStyle = pUserData->m_pStyle; FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f; - FX_FLOAT fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle); + FX_FLOAT fBaseLine = + m_textParser.GetBaseline(m_pTextProvider, pStyle.Get()); FX_FLOAT fLineHeight = m_textParser.GetLineHeight( - m_pTextProvider, pStyle, m_iLines == 0, fVerScale); + m_pTextProvider, pStyle.Get(), m_iLines == 0, fVerScale); if (fBaseLine > 0) { FX_FLOAT fLineHeightTmp = fBaseLine + (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f; @@ -1136,11 +1116,9 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, m_pLoader->m_lineHeights.Add(fHeight); } } - if (pStyle) - pStyle->Retain(); m_pBreak->ClearBreakPieces(); - if (dwStatus == FX_RTFBREAK_ParagraphBreak) { + if (dwStatus == CFX_RTFBreakType::Paragraph) { m_pBreak->Reset(); if (!pStyle && bEndBreak) { CXFA_Para para = m_pTextProvider->GetParaNode(); @@ -1171,7 +1149,6 @@ void CXFA_TextLayout::AppendTextLine(uint32_t dwStatus, fStart -= fTextIndent; m_pBreak->SetLineStartPos(fStart); - pStyle->Release(); } m_iLines++; } @@ -1209,11 +1186,11 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, int32_t iChars = GetDisplayPos(pPiece, pCharPos); if (iChars > 0) { CFX_PointF pt1, pt2; - FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f; + FX_FLOAT fEndY = pCharPos[0].m_Origin.y + 1.05f; if (pPiece->iPeriod == XFA_ATTRIBUTEENUM_Word) { for (int32_t i = 0; i < pPiece->iUnderline; i++) { for (int32_t j = 0; j < iChars; j++) { - pt1.x = pCharPos[j].m_OriginX; + pt1.x = pCharPos[j].m_Origin.x; pt2.x = pt1.x + pCharPos[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f; pt1.y = pt2.y = fEndY; @@ -1222,9 +1199,9 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, fEndY += 2.0f; } } else { - pt1.x = pCharPos[0].m_OriginX; + pt1.x = pCharPos[0].m_Origin.x; pt2.x = - pCharPos[iChars - 1].m_OriginX + + pCharPos[iChars - 1].m_Origin.x + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; for (int32_t i = 0; i < pPiece->iUnderline; i++) { pt1.y = pt2.y = fEndY; @@ -1232,9 +1209,9 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, fEndY += 2.0f; } } - fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f; - pt1.x = pCharPos[0].m_OriginX; - pt2.x = pCharPos[iChars - 1].m_OriginX + + fEndY = pCharPos[0].m_Origin.y - pPiece->rtPiece.height * 0.25f; + pt1.x = pCharPos[0].m_Origin.x; + pt2.x = pCharPos[iChars - 1].m_Origin.x + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; for (int32_t i = 0; i < pPiece->iLineThrough; i++) { pt1.y = pt2.y = fEndY; @@ -1275,25 +1252,29 @@ void CXFA_TextLayout::RenderPath(CFDE_RenderDevice* pDevice, if (iChars < 1) return; - fOrgX = pCharPos[iChars - 1].m_OriginX + + fOrgX = pCharPos[iChars - 1].m_Origin.x + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f; pPiece = pPieceLine->m_textPieces[iPieceNext].get(); iChars = GetDisplayPos(pPiece, pCharPos); if (iChars < 1) return; - fEndX = pCharPos[0].m_OriginX; - CFX_PointF pt1, pt2; - pt1.x = fOrgX, pt2.x = fEndX; - FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f; + fEndX = pCharPos[0].m_Origin.x; + CFX_PointF pt1; + CFX_PointF pt2; + pt1.x = fOrgX; + pt2.x = fEndX; + FX_FLOAT fEndY = pCharPos[0].m_Origin.y + 1.05f; for (int32_t i = 0; i < pPiece->iUnderline; i++) { - pt1.y = pt2.y = fEndY; + pt1.y = fEndY; + pt2.y = fEndY; pPath->AddLine(pt1, pt2); fEndY += 2.0f; } - fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f; + fEndY = pCharPos[0].m_Origin.y - pPiece->rtPiece.height * 0.25f; for (int32_t i = 0; i < pPiece->iLineThrough; i++) { - pt1.y = pt2.y = fEndY; + pt1.y = fEndY; + pt2.y = fEndY; pPath->AddLine(pt1, pt2); fEndY += 2.0f; } @@ -1318,17 +1299,15 @@ bool CXFA_TextLayout::ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ* tr) { if (iLength < 1) return false; - tr->pStr = pPiece->pszText; + tr->pStr = pPiece->szText; tr->pFont = pPiece->pFont; tr->pRect = &pPiece->rtPiece; - tr->pWidths = pPiece->pWidths; + tr->pWidths = pPiece->Widths; tr->iLength = iLength; tr->fFontSize = pPiece->fFontSize; tr->iBidiLevel = pPiece->iBidiLevel; - tr->iCharRotation = 0; tr->wLineBreakChar = L'\n'; tr->iVerticalScale = pPiece->iVerScale; - tr->dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab; tr->iHorizontalScale = pPiece->iHorScale; return true; } diff --git a/xfa/fxfa/app/cxfa_textlayout.h b/xfa/fxfa/app/cxfa_textlayout.h index 4de53d1eb..d4d60cf81 100644 --- a/xfa/fxfa/app/cxfa_textlayout.h +++ b/xfa/fxfa/app/cxfa_textlayout.h @@ -60,12 +60,12 @@ class CXFA_TextLayout { } bool m_bHasBlock; - CFX_Int32Array m_Blocks; + CFX_ArrayTemplate<int32_t> m_Blocks; private: void GetTextDataNode(); CFDE_XMLNode* GetXMLContainerNode(); - CFX_RTFBreak* CreateBreak(bool bDefault); + std::unique_ptr<CFX_RTFBreak> CreateBreak(bool bDefault); void InitBreak(FX_FLOAT fLineWidth); void InitBreak(CFDE_CSSComputedStyle* pStyle, FDE_CSSDisplay eDisplay, @@ -82,9 +82,9 @@ class CXFA_TextLayout { bool LoadRichText(CFDE_XMLNode* pXMLNode, const CFX_SizeF& szText, FX_FLOAT& fLinePos, - CFDE_CSSComputedStyle* pParentStyle, + const CFX_RetainPtr<CFDE_CSSComputedStyle>& pParentStyle, bool bSavePieces, - CXFA_LinkUserData* pLinkData = nullptr, + CFX_RetainPtr<CXFA_LinkUserData> pLinkData, bool bEndBreak = true, bool bIsOl = false, int32_t iLiCount = 0); @@ -92,11 +92,11 @@ class CXFA_TextLayout { FX_FLOAT& fLinePos, FX_FLOAT fSpaceAbove, bool bSavePieces); - void AppendTextLine(uint32_t dwStatus, + void AppendTextLine(CFX_RTFBreakType dwStatus, FX_FLOAT& fLinePos, bool bSavePieces, bool bEndBreak = false); - void EndBreak(uint32_t dwStatus, FX_FLOAT& fLinePos, bool bDefault); + void EndBreak(CFX_RTFBreakType dwStatus, FX_FLOAT& fLinePos, bool bDefault); bool IsEnd(bool bSavePieces); void ProcessText(CFX_WideString& wsText); void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom); diff --git a/xfa/fxfa/app/cxfa_textparsecontext.cpp b/xfa/fxfa/app/cxfa_textparsecontext.cpp index c0c226c4a..851d84456 100644 --- a/xfa/fxfa/app/cxfa_textparsecontext.cpp +++ b/xfa/fxfa/app/cxfa_textparsecontext.cpp @@ -12,23 +12,6 @@ CXFA_TextParseContext::CXFA_TextParseContext() : m_pParentStyle(nullptr), - m_ppMatchedDecls(nullptr), - m_dwMatchedDecls(0), m_eDisplay(FDE_CSSDisplay::None) {} -CXFA_TextParseContext::~CXFA_TextParseContext() { - if (m_pParentStyle) - m_pParentStyle->Release(); - FX_Free(m_ppMatchedDecls); -} - -void CXFA_TextParseContext::SetDecls(const CFDE_CSSDeclaration** ppDeclArray, - int32_t iDeclCount) { - if (iDeclCount <= 0 || !ppDeclArray) - return; - - m_dwMatchedDecls = iDeclCount; - m_ppMatchedDecls = FX_Alloc(CFDE_CSSDeclaration*, iDeclCount); - FXSYS_memcpy(m_ppMatchedDecls, ppDeclArray, - iDeclCount * sizeof(CFDE_CSSDeclaration*)); -} +CXFA_TextParseContext::~CXFA_TextParseContext() {} diff --git a/xfa/fxfa/app/cxfa_textparsecontext.h b/xfa/fxfa/app/cxfa_textparsecontext.h index 2faaadb44..5ea68e947 100644 --- a/xfa/fxfa/app/cxfa_textparsecontext.h +++ b/xfa/fxfa/app/cxfa_textparsecontext.h @@ -7,9 +7,13 @@ #ifndef XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_ #define XFA_FXFA_APP_CXFA_TEXTPARSECONTEXT_H_ +#include <utility> +#include <vector> + +#include "third_party/base/stl_util.h" +#include "xfa/fde/css/cfde_cssdeclaration.h" #include "xfa/fde/css/fde_css.h" -class CFDE_CSSDeclaration; class CFDE_CSSComputedStyle; class CXFA_TextParseContext { @@ -20,17 +24,15 @@ class CXFA_TextParseContext { void SetDisplay(FDE_CSSDisplay eDisplay) { m_eDisplay = eDisplay; } FDE_CSSDisplay GetDisplay() const { return m_eDisplay; } - void SetDecls(const CFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount); - const CFDE_CSSDeclaration** GetDecls() { - return const_cast<const CFDE_CSSDeclaration**>(m_ppMatchedDecls); + void SetDecls(std::vector<const CFDE_CSSDeclaration*>&& decl) { + decls_ = std::move(decl); } - uint32_t CountDecls() const { return m_dwMatchedDecls; } + const std::vector<const CFDE_CSSDeclaration*>& GetDecls() { return decls_; } - CFDE_CSSComputedStyle* m_pParentStyle; + CFX_RetainPtr<CFDE_CSSComputedStyle> m_pParentStyle; protected: - CFDE_CSSDeclaration** m_ppMatchedDecls; - uint32_t m_dwMatchedDecls; + std::vector<const CFDE_CSSDeclaration*> decls_; FDE_CSSDisplay m_eDisplay; }; diff --git a/xfa/fxfa/app/cxfa_textparser.cpp b/xfa/fxfa/app/cxfa_textparser.cpp index 9920f6e72..9759cb219 100644 --- a/xfa/fxfa/app/cxfa_textparser.cpp +++ b/xfa/fxfa/app/cxfa_textparser.cpp @@ -7,9 +7,10 @@ #include "xfa/fxfa/app/cxfa_textparser.h" #include <algorithm> +#include <utility> +#include <vector> #include "third_party/base/ptr_util.h" -#include "xfa/fde/css/cfde_cssaccelerator.h" #include "xfa/fde/css/cfde_csscomputedstyle.h" #include "xfa/fde/css/cfde_cssstyleselector.h" #include "xfa/fde/css/cfde_cssstylesheet.h" @@ -39,12 +40,10 @@ enum class TabStopStatus { } // namespace -CXFA_TextParser::CXFA_TextParser() : m_pUASheet(nullptr), m_bParsed(false) {} +CXFA_TextParser::CXFA_TextParser() + : m_bParsed(false), m_cssInitialized(false) {} CXFA_TextParser::~CXFA_TextParser() { - if (m_pUASheet) - m_pUASheet->Release(); - for (auto& pair : m_mapXMLNodeToParseContext) { if (pair.second) delete pair.second; @@ -76,37 +75,37 @@ void CXFA_TextParser::InitCSSData(CXFA_TextProvider* pTextProvider) { m_pSelector->SetDefFontSize(fFontSize); } - if (!m_pUASheet) { - m_pUASheet = LoadDefaultSheetStyle(); - m_pSelector->SetStyleSheet(FDE_CSSStyleSheetGroup::UserAgent, m_pUASheet); - m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL); - } + if (m_cssInitialized) + return; + + m_cssInitialized = true; + auto uaSheet = LoadDefaultSheetStyle(); + m_pSelector->SetUAStyleSheet(std::move(uaSheet)); + m_pSelector->UpdateStyleIndex(); } -CFDE_CSSStyleSheet* CXFA_TextParser::LoadDefaultSheetStyle() { +std::unique_ptr<CFDE_CSSStyleSheet> CXFA_TextParser::LoadDefaultSheetStyle() { static const FX_WCHAR s_pStyle[] = L"html,body,ol,p,ul{display:block}" L"li{display:list-item}" - L"ol,ul{padding-left:33px}ol{list-style-type:decimal}ol,ul{margin-top:0;" - L"margin-bottom:0}ul,ol{margin:1.12em 0}" - L"a{color:#0000ff;text-decoration:underline}b{font-weight:bolder}i{font-" - L"style:italic}" - L"sup{vertical-align:+15em;font-size:.66em}sub{vertical-align:-15em;font-" - L"size:.66em}"; - - CFDE_CSSStyleSheet* pStyleSheet = new CFDE_CSSStyleSheet(); - if (!pStyleSheet->LoadFromBuffer(s_pStyle, FXSYS_wcslen(s_pStyle))) { - pStyleSheet->Release(); - pStyleSheet = nullptr; - } - return pStyleSheet; + L"ol,ul{padding-left:33px;margin:1.12em 0}" + L"ol{list-style-type:decimal}" + L"a{color:#0000ff;text-decoration:underline}" + L"b{font-weight:bolder}" + L"i{font-style:italic}" + L"sup{vertical-align:+15em;font-size:.66em}" + L"sub{vertical-align:-15em;font-size:.66em}"; + + auto sheet = pdfium::MakeUnique<CFDE_CSSStyleSheet>(); + return sheet->LoadBuffer(s_pStyle, FXSYS_wcslen(s_pStyle)) ? std::move(sheet) + : nullptr; } -CFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle( +CFX_RetainPtr<CFDE_CSSComputedStyle> CXFA_TextParser::CreateRootStyle( CXFA_TextProvider* pTextProvider) { CXFA_Font font = pTextProvider->GetFontNode(); CXFA_Para para = pTextProvider->GetParaNode(); - CFDE_CSSComputedStyle* pStyle = m_pSelector->CreateComputedStyle(nullptr); + auto pStyle = m_pSelector->CreateComputedStyle(nullptr); FX_FLOAT fLineHeight = 0; FX_FLOAT fFontSize = 10; @@ -164,10 +163,9 @@ CFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle( return pStyle; } -CFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle( +CFX_RetainPtr<CFDE_CSSComputedStyle> CXFA_TextParser::CreateStyle( CFDE_CSSComputedStyle* pParentStyle) { - CFDE_CSSComputedStyle* pNewStyle = - m_pSelector->CreateComputedStyle(pParentStyle); + auto pNewStyle = m_pSelector->CreateComputedStyle(pParentStyle); ASSERT(pNewStyle); if (!pParentStyle) return pNewStyle; @@ -186,7 +184,7 @@ CFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle( return pNewStyle; } -CFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle( +CFX_RetainPtr<CFDE_CSSComputedStyle> CXFA_TextParser::ComputeStyle( CFDE_XMLNode* pXMLNode, CFDE_CSSComputedStyle* pParentStyle) { auto it = m_mapXMLNodeToParseContext.find(pXMLNode); @@ -197,20 +195,16 @@ CFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle( if (!pContext) return nullptr; - pContext->m_pParentStyle = pParentStyle; - pParentStyle->Retain(); + pContext->m_pParentStyle.Reset(pParentStyle); - CXFA_CSSTagProvider tagProvider; - ParseTagInfo(pXMLNode, tagProvider); - if (tagProvider.m_bContent) + auto tagProvider = ParseTagInfo(pXMLNode); + if (tagProvider->m_bContent) return nullptr; - CFDE_CSSComputedStyle* pStyle = CreateStyle(pParentStyle); - CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator(); - pCSSAccel->OnEnterTag(&tagProvider); - m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(), - pContext->CountDecls(), pStyle); - pCSSAccel->OnLeaveTag(&tagProvider); + auto pStyle = CreateStyle(pParentStyle); + m_pSelector->ComputeStyle(pContext->GetDecls(), + tagProvider->GetAttribute(L"style"), + tagProvider->GetAttribute(L"align"), pStyle.Get()); return pStyle; } @@ -221,9 +215,8 @@ void CXFA_TextParser::DoParse(CFDE_XMLNode* pXMLContainer, m_bParsed = true; InitCSSData(pTextProvider); - CFDE_CSSComputedStyle* pRootStyle = CreateRootStyle(pTextProvider); - ParseRichText(pXMLContainer, pRootStyle); - pRootStyle->Release(); + auto pRootStyle = CreateRootStyle(pTextProvider); + ParseRichText(pXMLContainer, pRootStyle.Get()); } void CXFA_TextParser::ParseRichText(CFDE_XMLNode* pXMLNode, @@ -231,30 +224,25 @@ void CXFA_TextParser::ParseRichText(CFDE_XMLNode* pXMLNode, if (!pXMLNode) return; - CXFA_CSSTagProvider tagProvider; - ParseTagInfo(pXMLNode, tagProvider); - if (!tagProvider.m_bTagAvailable) + auto tagProvider = ParseTagInfo(pXMLNode); + if (!tagProvider->m_bTagAvailable) return; - CFDE_CSSComputedStyle* pNewStyle = nullptr; - if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) || - (tagProvider.GetTagName() != FX_WSTRC(L"html"))) { + CFX_RetainPtr<CFDE_CSSComputedStyle> pNewStyle; + if ((tagProvider->GetTagName() != L"body") || + (tagProvider->GetTagName() != L"html")) { CXFA_TextParseContext* pTextContext = new CXFA_TextParseContext; FDE_CSSDisplay eDisplay = FDE_CSSDisplay::Inline; - if (!tagProvider.m_bContent) { + if (!tagProvider->m_bContent) { + auto declArray = + m_pSelector->MatchDeclarations(tagProvider->GetTagName()); pNewStyle = CreateStyle(pParentStyle); - CFDE_CSSAccelerator* pCSSAccel = m_pSelector->InitAccelerator(); - pCSSAccel->OnEnterTag(&tagProvider); - CFX_ArrayTemplate<CFDE_CSSDeclaration*> DeclArray; - int32_t iMatchedDecls = - m_pSelector->MatchDeclarations(&tagProvider, DeclArray); - const CFDE_CSSDeclaration** ppMatchDecls = - const_cast<const CFDE_CSSDeclaration**>(DeclArray.GetData()); - m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls, - pNewStyle); - pCSSAccel->OnLeaveTag(&tagProvider); - if (iMatchedDecls > 0) - pTextContext->SetDecls(ppMatchDecls, iMatchedDecls); + m_pSelector->ComputeStyle(declArray, tagProvider->GetAttribute(L"style"), + tagProvider->GetAttribute(L"align"), + pNewStyle.Get()); + + if (!declArray.empty()) + pTextContext->SetDecls(std::move(declArray)); eDisplay = pNewStyle->GetDisplay(); } @@ -266,10 +254,8 @@ void CXFA_TextParser::ParseRichText(CFDE_XMLNode* pXMLNode, pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(CFDE_XMLNode::NextSibling)) { - ParseRichText(pXMLChild, pNewStyle); + ParseRichText(pXMLChild, pNewStyle.Get()); } - if (pNewStyle) - pNewStyle->Release(); } bool CXFA_TextParser::TagValidate(const CFX_WideString& wsName) const { @@ -294,23 +280,26 @@ bool CXFA_TextParser::TagValidate(const CFX_WideString& wsName) const { FX_HashCode_GetW(wsName.AsStringC(), true)); } -void CXFA_TextParser::ParseTagInfo(CFDE_XMLNode* pXMLNode, - CXFA_CSSTagProvider& tagProvider) { +std::unique_ptr<CXFA_CSSTagProvider> CXFA_TextParser::ParseTagInfo( + CFDE_XMLNode* pXMLNode) { + auto tagProvider = pdfium::MakeUnique<CXFA_CSSTagProvider>(); + CFX_WideString wsName; if (pXMLNode->GetType() == FDE_XMLNODE_Element) { CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode); pXMLElement->GetLocalTagName(wsName); - tagProvider.SetTagNameObj(wsName); - tagProvider.m_bTagAvailable = TagValidate(wsName); + tagProvider->SetTagName(wsName); + tagProvider->m_bTagAvailable = TagValidate(wsName); CFX_WideString wsValue; pXMLElement->GetString(L"style", wsValue); if (!wsValue.IsEmpty()) - tagProvider.SetAttribute(L"style", wsValue); + tagProvider->SetAttribute(L"style", wsValue); } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) { - tagProvider.m_bTagAvailable = true; - tagProvider.m_bContent = true; + tagProvider->m_bTagAvailable = true; + tagProvider->m_bContent = true; } + return tagProvider; } int32_t CXFA_TextParser::GetVAlign(CXFA_TextProvider* pTextProvider) const { @@ -320,23 +309,23 @@ int32_t CXFA_TextParser::GetVAlign(CXFA_TextProvider* pTextProvider) const { FX_FLOAT CXFA_TextParser::GetTabInterval(CFDE_CSSComputedStyle* pStyle) const { CFX_WideString wsValue; - if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue)) + if (pStyle && pStyle->GetCustomStyle(L"tab-interval", wsValue)) return CXFA_Measurement(wsValue.AsStringC()).ToUnit(XFA_UNIT_Pt); return 36; } int32_t CXFA_TextParser::CountTabs(CFDE_CSSComputedStyle* pStyle) const { CFX_WideString wsValue; - if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue)) + if (pStyle && pStyle->GetCustomStyle(L"xfa-tab-count", wsValue)) return wsValue.GetInteger(); return 0; } bool CXFA_TextParser::IsSpaceRun(CFDE_CSSComputedStyle* pStyle) const { CFX_WideString wsValue; - if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) { + if (pStyle && pStyle->GetCustomStyle(L"xfa-spacerun", wsValue)) { wsValue.MakeLower(); - return wsValue == FX_WSTRC(L"yes"); + return wsValue == L"yes"; } return false; } @@ -414,7 +403,7 @@ int32_t CXFA_TextParser::GetVerScale(CXFA_TextProvider* pTextProvider, CFDE_CSSComputedStyle* pStyle) const { if (pStyle) { CFX_WideString wsValue; - if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue)) + if (pStyle->GetCustomStyle(L"xfa-font-vertical-scale", wsValue)) return wsValue.GetInteger(); } @@ -445,8 +434,8 @@ void CXFA_TextParser::GetUnderline(CXFA_TextProvider* pTextProvider, iUnderline = 1; CFX_WideString wsValue; - if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) { - if (wsValue == FX_WSTRC(L"word")) + if (pStyle->GetCustomStyle(L"underlinePeriod", wsValue)) { + if (wsValue == L"word") iPeriod = XFA_ATTRIBUTEENUM_Word; } else if (CXFA_Font font = pTextProvider->GetFontNode()) { iPeriod = font.GetUnderlinePeriod(); @@ -535,8 +524,8 @@ bool CXFA_TextParser::GetEmbbedObj(CXFA_TextProvider* pTextProvider, else ws.MakeLower(); - bool bURI = (ws == FX_WSTRC(L"uri")); - if (!bURI && ws != FX_WSTRC(L"som")) + bool bURI = (ws == L"uri"); + if (!bURI && ws != L"som") return false; ws.clear(); @@ -546,8 +535,8 @@ bool CXFA_TextParser::GetEmbbedObj(CXFA_TextProvider* pTextProvider, else ws.MakeLower(); - bool bRaw = (ws == FX_WSTRC(L"raw")); - if (!bRaw && ws != FX_WSTRC(L"formatted")) + bool bRaw = (ws == L"raw"); + if (!bRaw && ws != L"formatted") return false; bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue); @@ -567,8 +556,8 @@ bool CXFA_TextParser::GetTabstops(CFDE_CSSComputedStyle* pStyle, return false; CFX_WideString wsValue; - if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue) && - !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) { + if (!pStyle->GetCustomStyle(L"xfa-tab-stops", wsValue) && + !pStyle->GetCustomStyle(L"tab-stops", wsValue)) { return false; } diff --git a/xfa/fxfa/app/cxfa_textparser.h b/xfa/fxfa/app/cxfa_textparser.h index a0b5ab1f2..86da502db 100644 --- a/xfa/fxfa/app/cxfa_textparser.h +++ b/xfa/fxfa/app/cxfa_textparser.h @@ -33,9 +33,11 @@ class CXFA_TextParser { void Reset(); void DoParse(CFDE_XMLNode* pXMLContainer, CXFA_TextProvider* pTextProvider); - CFDE_CSSComputedStyle* CreateRootStyle(CXFA_TextProvider* pTextProvider); - CFDE_CSSComputedStyle* ComputeStyle(CFDE_XMLNode* pXMLNode, - CFDE_CSSComputedStyle* pParentStyle); + CFX_RetainPtr<CFDE_CSSComputedStyle> CreateRootStyle( + CXFA_TextProvider* pTextProvider); + CFX_RetainPtr<CFDE_CSSComputedStyle> ComputeStyle( + CFDE_XMLNode* pXMLNode, + CFDE_CSSComputedStyle* pParentStyle); bool IsParsed() const { return m_bParsed; } @@ -87,14 +89,15 @@ class CXFA_TextParser { void InitCSSData(CXFA_TextProvider* pTextProvider); void ParseRichText(CFDE_XMLNode* pXMLNode, CFDE_CSSComputedStyle* pParentStyle); - void ParseTagInfo(CFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider); - CFDE_CSSStyleSheet* LoadDefaultSheetStyle(); - CFDE_CSSComputedStyle* CreateStyle(CFDE_CSSComputedStyle* pParentStyle); + std::unique_ptr<CXFA_CSSTagProvider> ParseTagInfo(CFDE_XMLNode* pXMLNode); + std::unique_ptr<CFDE_CSSStyleSheet> LoadDefaultSheetStyle(); + CFX_RetainPtr<CFDE_CSSComputedStyle> CreateStyle( + CFDE_CSSComputedStyle* pParentStyle); std::unique_ptr<CFDE_CSSStyleSelector> m_pSelector; - CFDE_CSSStyleSheet* m_pUASheet; std::map<CFDE_XMLNode*, CXFA_TextParseContext*> m_mapXMLNodeToParseContext; bool m_bParsed; + bool m_cssInitialized; }; #endif // XFA_FXFA_APP_CXFA_TEXTPARSER_H_ diff --git a/xfa/fxfa/app/cxfa_textuserdata.cpp b/xfa/fxfa/app/cxfa_textuserdata.cpp index 4fdabd6bb..e4e549316 100644 --- a/xfa/fxfa/app/cxfa_textuserdata.cpp +++ b/xfa/fxfa/app/cxfa_textuserdata.cpp @@ -11,33 +11,13 @@ #include "xfa/fde/css/fde_css.h" #include "xfa/fxfa/app/cxfa_linkuserdata.h" -CXFA_TextUserData::CXFA_TextUserData(CFDE_CSSComputedStyle* pStyle) - : m_pStyle(pStyle), m_pLinkData(nullptr), m_dwRefCount(0) { - if (m_pStyle) - m_pStyle->Retain(); -} +CXFA_TextUserData::CXFA_TextUserData( + const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle) + : m_pStyle(pStyle) {} -CXFA_TextUserData::CXFA_TextUserData(CFDE_CSSComputedStyle* pStyle, - CXFA_LinkUserData* pLinkData) - : m_pStyle(pStyle), m_pLinkData(pLinkData), m_dwRefCount(0) { - if (m_pStyle) - m_pStyle->Retain(); -} +CXFA_TextUserData::CXFA_TextUserData( + const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle, + const CFX_RetainPtr<CXFA_LinkUserData>& pLinkData) + : m_pStyle(pStyle), m_pLinkData(pLinkData) {} -CXFA_TextUserData::~CXFA_TextUserData() { - if (m_pStyle) - m_pStyle->Release(); - if (m_pLinkData) - m_pLinkData->Release(); -} - -uint32_t CXFA_TextUserData::Retain() { - return ++m_dwRefCount; -} - -uint32_t CXFA_TextUserData::Release() { - uint32_t dwRefCount = --m_dwRefCount; - if (dwRefCount == 0) - delete this; - return dwRefCount; -} +CXFA_TextUserData::~CXFA_TextUserData() {} diff --git a/xfa/fxfa/app/cxfa_textuserdata.h b/xfa/fxfa/app/cxfa_textuserdata.h index 83f762ddb..b0eff73f2 100644 --- a/xfa/fxfa/app/cxfa_textuserdata.h +++ b/xfa/fxfa/app/cxfa_textuserdata.h @@ -7,27 +7,26 @@ #ifndef XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_ #define XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_ +#include "core/fxcrt/cfx_retain_ptr.h" #include "core/fxcrt/fx_basic.h" class CFDE_CSSComputedStyle; class CXFA_LinkUserData; -class CXFA_TextUserData : public IFX_Retainable { +class CXFA_TextUserData : public CFX_Retainable { public: - explicit CXFA_TextUserData(CFDE_CSSComputedStyle* pStyle); - CXFA_TextUserData(CFDE_CSSComputedStyle* pStyle, - CXFA_LinkUserData* pLinkData); - ~CXFA_TextUserData() override; - - // IFX_Retainable: - uint32_t Retain() override; - uint32_t Release() override; + template <typename T, typename... Args> + friend CFX_RetainPtr<T> pdfium::MakeRetain(Args&&... args); - CFDE_CSSComputedStyle* m_pStyle; - CXFA_LinkUserData* m_pLinkData; + CFX_RetainPtr<CFDE_CSSComputedStyle> m_pStyle; + CFX_RetainPtr<CXFA_LinkUserData> m_pLinkData; protected: - uint32_t m_dwRefCount; + explicit CXFA_TextUserData( + const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle); + CXFA_TextUserData(const CFX_RetainPtr<CFDE_CSSComputedStyle>& pStyle, + const CFX_RetainPtr<CXFA_LinkUserData>& pLinkData); + ~CXFA_TextUserData() override; }; #endif // XFA_FXFA_APP_CXFA_TEXTUSERDATA_H_ diff --git a/xfa/fxfa/app/xfa_ffbarcode.cpp b/xfa/fxfa/app/xfa_ffbarcode.cpp index 822029df3..b136b8da5 100644 --- a/xfa/fxfa/app/xfa_ffbarcode.cpp +++ b/xfa/fxfa/app/xfa_ffbarcode.cpp @@ -116,9 +116,8 @@ const XFA_BARCODETYPEENUMINFO* XFA_GetBarcodeTypeByName( } // namespace. -CXFA_FFBarcode::CXFA_FFBarcode(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFTextEdit(pPageView, pDataAcc) {} +CXFA_FFBarcode::CXFA_FFBarcode(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFTextEdit(pDataAcc) {} CXFA_FFBarcode::~CXFA_FFBarcode() {} @@ -145,21 +144,20 @@ bool CXFA_FFBarcode::LoadWidget() { void CXFA_FFBarcode::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); DrawBorder(pGS, borderUI, m_rtUI, &mtRotate); RenderCaption(pGS, &mtRotate); CFX_RectF rtWidget = m_pNormalWidget->GetWidgetRect(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top); + + CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top); mt.Concat(mtRotate); m_pNormalWidget->DrawWidget(pGS, &mt); } @@ -223,20 +221,18 @@ void CXFA_FFBarcode::UpdateWidgetProperty() { } } -bool CXFA_FFBarcode::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { +bool CXFA_FFBarcode::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) { CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget; - if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) { + if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) return false; - } - if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) { + if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) return false; - } - return CXFA_FFTextEdit::OnLButtonDown(dwFlags, fx, fy); + return CXFA_FFTextEdit::OnLButtonDown(dwFlags, point); } -bool CXFA_FFBarcode::OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFBarcode::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) { CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget; - if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) { + if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) return false; - } - return CXFA_FFTextEdit::OnRButtonDown(dwFlags, fx, fy); + return CXFA_FFTextEdit::OnRButtonDown(dwFlags, point); } diff --git a/xfa/fxfa/app/xfa_ffbarcode.h b/xfa/fxfa/app/xfa_ffbarcode.h index 4690b3d61..c20feb516 100644 --- a/xfa/fxfa/app/xfa_ffbarcode.h +++ b/xfa/fxfa/app/xfa_ffbarcode.h @@ -13,7 +13,7 @@ class CXFA_FFBarcode : public CXFA_FFTextEdit { public: - CXFA_FFBarcode(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFBarcode(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFBarcode() override; // CXFA_FFTextEdit @@ -22,8 +22,8 @@ class CXFA_FFBarcode : public CXFA_FFTextEdit { CFX_Matrix* pMatrix, uint32_t dwStatus) override; void UpdateWidgetProperty() override; - bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; }; enum XFA_BARCODETYPEENUM { diff --git a/xfa/fxfa/app/xfa_ffcheckbutton.cpp b/xfa/fxfa/app/xfa_ffcheckbutton.cpp index e8a422ebd..f088b5d4d 100644 --- a/xfa/fxfa/app/xfa_ffcheckbutton.cpp +++ b/xfa/fxfa/app/xfa_ffcheckbutton.cpp @@ -18,11 +18,8 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) { - m_rtCheckBox.Set(0, 0, 0, 0); -} +CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} CXFA_FFCheckButton::~CXFA_FFCheckButton() {} @@ -91,8 +88,7 @@ bool CXFA_FFCheckButton::PerformLayout() { CXFA_FFWidget::PerformLayout(); FX_FLOAT fCheckSize = m_pDataAcc->GetCheckButtonSize(); CXFA_Margin mgWidget = m_pDataAcc->GetMargin(); - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); + CFX_RectF rtWidget = GetRectWithoutRotate(); if (mgWidget) { XFA_RectWidthoutMargin(rtWidget, mgWidget); } @@ -100,8 +96,7 @@ bool CXFA_FFCheckButton::PerformLayout() { FX_FLOAT fCapReserve = 0; CXFA_Caption caption = m_pDataAcc->GetCaption(); if (caption && caption.GetPresence()) { - m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, - rtWidget.height); + m_rtCaption = rtWidget; iCapPlacement = caption.GetPlacementType(); fCapReserve = caption.GetReserve(); if (fCapReserve <= 0) { @@ -216,14 +211,13 @@ void CXFA_FFCheckButton::AddUIMargin(int32_t iCapPlacement) { void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); DrawBorder(pGS, borderUI, m_rtUI, &mtRotate, @@ -233,14 +227,12 @@ void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS, RenderCaption(pGS, &mtRotate); DrawHighlight(pGS, &mtRotate, dwStatus, m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top); + CFX_Matrix mt(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top); mt.Concat(mtRotate); GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget, pGS, &mt); } bool CXFA_FFCheckButton::OnLButtonUp(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { if (!m_pNormalWidget || !IsButtonDown()) return false; @@ -248,9 +240,7 @@ bool CXFA_FFCheckButton::OnLButtonUp(uint32_t dwFlags, CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::LeftButtonUp; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } diff --git a/xfa/fxfa/app/xfa_ffcheckbutton.h b/xfa/fxfa/app/xfa_ffcheckbutton.h index dcd68935a..2c0acd6e3 100644 --- a/xfa/fxfa/app/xfa_ffcheckbutton.h +++ b/xfa/fxfa/app/xfa_ffcheckbutton.h @@ -12,7 +12,7 @@ class CXFA_FFCheckButton : public CXFA_FFField { public: - CXFA_FFCheckButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFCheckButton(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFCheckButton() override; // CXFA_FFField @@ -24,7 +24,7 @@ class CXFA_FFCheckButton : public CXFA_FFField { bool PerformLayout() override; bool UpdateFWLData() override; void UpdateWidgetProperty() override; - bool OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; void OnProcessMessage(CFWL_Message* pMessage) override; void OnProcessEvent(CFWL_Event* pEvent) override; void OnDrawWidget(CFX_Graphics* pGraphics, diff --git a/xfa/fxfa/app/xfa_ffchoicelist.cpp b/xfa/fxfa/app/xfa_ffchoicelist.cpp index 2764d725a..3aabde870 100644 --- a/xfa/fxfa/app/xfa_ffchoicelist.cpp +++ b/xfa/fxfa/app/xfa_ffchoicelist.cpp @@ -25,9 +25,8 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFListBox::CXFA_FFListBox(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) {} +CXFA_FFListBox::CXFA_FFListBox(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} CXFA_FFListBox::~CXFA_FFListBox() { if (m_pNormalWidget) { @@ -65,7 +64,7 @@ bool CXFA_FFListBox::LoadWidget() { } dwExtendedStyle |= GetAlignment(); m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; m_pDataAcc->GetSelectedItems(iSelArray); int32_t iSelCount = iSelArray.GetSize(); for (int32_t j = 0; j < iSelCount; j++) { @@ -86,7 +85,7 @@ bool CXFA_FFListBox::OnKillFocus(CXFA_FFWidget* pNewFocus) { bool CXFA_FFListBox::CommitData() { CFWL_ListBox* pListBox = static_cast<CFWL_ListBox*>(m_pNormalWidget); int32_t iSels = pListBox->CountSelItems(); - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; for (int32_t i = 0; i < iSels; ++i) iSelArray.Add(pListBox->GetSelIndex(i)); m_pDataAcc->SetSelectedItems(iSelArray, true, false, true); @@ -94,7 +93,7 @@ bool CXFA_FFListBox::CommitData() { } bool CXFA_FFListBox::IsDataChanged() { - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; m_pDataAcc->GetSelectedItems(iSelArray); int32_t iOldSels = iSelArray.GetSize(); CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget; @@ -140,7 +139,7 @@ bool CXFA_FFListBox::UpdateFWLData() { } CFWL_ListBox* pListBox = ((CFWL_ListBox*)m_pNormalWidget); CFX_ArrayTemplate<CFWL_ListItem*> selItemArray; - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; m_pDataAcc->GetSelectedItems(iSelArray); int32_t iSelCount = iSelArray.GetSize(); for (int32_t j = 0; j < iSelCount; j++) { @@ -154,8 +153,9 @@ bool CXFA_FFListBox::UpdateFWLData() { m_pNormalWidget->Update(); return true; } -void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget, - const CFX_Int32Array& arrSels) { +void CXFA_FFListBox::OnSelectChanged( + CFWL_Widget* pWidget, + const CFX_ArrayTemplate<int32_t>& arrSels) { CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_Change; eParam.m_pTarget = m_pDataAcc; @@ -201,7 +201,7 @@ void CXFA_FFListBox::OnProcessEvent(CFWL_Event* pEvent) { CXFA_FFField::OnProcessEvent(pEvent); switch (pEvent->GetType()) { case CFWL_Event::Type::SelectChanged: { - CFX_Int32Array arrSels; + CFX_ArrayTemplate<int32_t> arrSels; OnSelectChanged(m_pNormalWidget, arrSels); break; } @@ -215,26 +215,20 @@ void CXFA_FFListBox::OnDrawWidget(CFX_Graphics* pGraphics, m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix); } -CXFA_FFComboBox::CXFA_FFComboBox(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) {} +CXFA_FFComboBox::CXFA_FFComboBox(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} CXFA_FFComboBox::~CXFA_FFComboBox() {} -bool CXFA_FFComboBox::GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus) { +CFX_RectF CXFA_FFComboBox::GetBBox(uint32_t dwStatus, bool bDrawFocus) { if (bDrawFocus) - return false; - return CXFA_FFWidget::GetBBox(rtBox, dwStatus); + return CFX_RectF(); + return CXFA_FFWidget::GetBBox(dwStatus); } -bool CXFA_FFComboBox::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) - return false; - return static_cast<CFWL_ComboBox*>(m_pNormalWidget) - ->GetBBox() - .Contains(fx, fy); +bool CXFA_FFComboBox::PtInActiveRect(const CFX_PointF& point) { + auto pComboBox = static_cast<CFWL_ComboBox*>(m_pNormalWidget); + return pComboBox && pComboBox->GetBBox().Contains(point); } bool CXFA_FFComboBox::LoadWidget() { @@ -256,7 +250,7 @@ bool CXFA_FFComboBox::LoadWidget() { for (int32_t i = 0; i < iItems; i++) { pComboBox->AddString(wsLabelArray[i].AsStringC()); } - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; m_pDataAcc->GetSelectedItems(iSelArray); int32_t iSelCount = iSelArray.GetSize(); if (iSelCount > 0) { @@ -295,13 +289,15 @@ void CXFA_FFComboBox::UpdateWidgetProperty() { } pComboBox->EditModifyStylesEx(dwEditStyles, 0xFFFFFFFF); } -bool CXFA_FFComboBox::OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy)) + +bool CXFA_FFComboBox::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) { + if (!CXFA_FFField::OnRButtonUp(dwFlags, point)) return false; - GetDoc()->GetDocEnvironment()->PopupMenu(this, CFX_PointF(fx, fy)); + GetDoc()->GetDocEnvironment()->PopupMenu(this, point); return true; } + bool CXFA_FFComboBox::OnKillFocus(CXFA_FFWidget* pNewWidget) { bool flag = ProcessCommittedData(); if (!flag) { @@ -383,7 +379,7 @@ bool CXFA_FFComboBox::UpdateFWLData() { if (!m_pNormalWidget) { return false; } - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; m_pDataAcc->GetSelectedItems(iSelArray); int32_t iSelCount = iSelArray.GetSize(); if (iSelCount > 0) { diff --git a/xfa/fxfa/app/xfa_ffchoicelist.h b/xfa/fxfa/app/xfa_ffchoicelist.h index e9bee6f71..e89366ad1 100644 --- a/xfa/fxfa/app/xfa_ffchoicelist.h +++ b/xfa/fxfa/app/xfa_ffchoicelist.h @@ -12,7 +12,7 @@ class CXFA_FFListBox : public CXFA_FFField { public: - CXFA_FFListBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFListBox(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFListBox() override; // CXFA_FFField @@ -23,7 +23,8 @@ class CXFA_FFListBox : public CXFA_FFField { void OnDrawWidget(CFX_Graphics* pGraphics, const CFX_Matrix* pMatrix = nullptr) override; - void OnSelectChanged(CFWL_Widget* pWidget, const CFX_Int32Array& arrSels); + void OnSelectChanged(CFWL_Widget* pWidget, + const CFX_ArrayTemplate<int32_t>& arrSels); void SetItemState(int32_t nIndex, bool bSelected); void InsertItem(const CFX_WideStringC& wsLabel, int32_t nIndex = -1); void DeleteItem(int32_t nIndex); @@ -40,16 +41,14 @@ class CXFA_FFListBox : public CXFA_FFField { class CXFA_FFComboBox : public CXFA_FFField { public: - CXFA_FFComboBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFComboBox(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFComboBox() override; // CXFA_FFField - bool GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus = false) override; + CFX_RectF GetBBox(uint32_t dwStatus, bool bDrawFocus = false) override; bool LoadWidget() override; void UpdateWidgetProperty() override; - bool OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; bool OnKillFocus(CXFA_FFWidget* pNewWidget) override; bool CanUndo() override; bool CanRedo() override; @@ -85,7 +84,7 @@ class CXFA_FFComboBox : public CXFA_FFField { protected: // CXFA_FFField - bool PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) override; + bool PtInActiveRect(const CFX_PointF& point) override; bool CommitData() override; bool UpdateFWLData() override; bool IsDataChanged() override; diff --git a/xfa/fxfa/app/xfa_ffdoc.cpp b/xfa/fxfa/app/xfa_ffdoc.cpp index c34213c17..911bdf840 100644 --- a/xfa/fxfa/app/xfa_ffdoc.cpp +++ b/xfa/fxfa/app/xfa_ffdoc.cpp @@ -183,7 +183,7 @@ bool XFA_GetPDFContentsFromPDFXML(CFDE_XMLNode* pPDFElement, CFX_WideString wsTagName; CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode); pXMLElement->GetTagName(wsTagName); - if (wsTagName == FX_WSTRC(L"document")) { + if (wsTagName == L"document") { pDocumentElement = pXMLElement; break; } @@ -200,7 +200,7 @@ bool XFA_GetPDFContentsFromPDFXML(CFDE_XMLNode* pPDFElement, CFX_WideString wsTagName; CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode); pXMLElement->GetTagName(wsTagName); - if (wsTagName == FX_WSTRC(L"chunk")) { + if (wsTagName == L"chunk") { pChunkElement = pXMLElement; break; } @@ -265,7 +265,7 @@ void CXFA_FFDoc::StopLoad() { return; } CFX_WideString wsType; - if (pDynamicRender->TryContent(wsType) && wsType == FX_WSTRC(L"required")) { + if (pDynamicRender->TryContent(wsType) && wsType == L"required") { m_dwDocType = XFA_DOCTYPE_Dynamic; } } diff --git a/xfa/fxfa/app/xfa_ffdocview.cpp b/xfa/fxfa/app/xfa_ffdocview.cpp index bf91baf08..87441814e 100644 --- a/xfa/fxfa/app/xfa_ffdocview.cpp +++ b/xfa/fxfa/app/xfa_ffdocview.cpp @@ -155,7 +155,7 @@ void CXFA_FFDocView::ShowNullTestMsg() { iCount -= iRemain; CFX_WideString wsMsg; for (int32_t i = 0; i < iCount; i++) { - wsMsg += m_arrNullTestMsg[i] + FX_WSTRC(L"\n"); + wsMsg += m_arrNullTestMsg[i] + L"\n"; } if (iRemain > 0) { CFX_WideString wsTemp; @@ -163,7 +163,7 @@ void CXFA_FFDocView::ShowNullTestMsg() { L"Message limit exceeded. Remaining %d " L"validation errors not reported.", iRemain); - wsMsg += FX_WSTRC(L"\n") + wsTemp; + wsMsg += L"\n" + wsTemp; } pAppProvider->MsgBox(wsMsg, pAppProvider->GetAppTitle(), XFA_MBICON_Status, XFA_MB_OK); @@ -551,10 +551,7 @@ void CXFA_FFDocView::AddInvalidateRect(CXFA_FFPageView* pPageView, m_mapPageInvalidate[pPageView]->Union(rtInvalidate); return; } - CFX_RectF* pRect = new CFX_RectF; - pRect->Set(rtInvalidate.left, rtInvalidate.top, rtInvalidate.width, - rtInvalidate.height); - m_mapPageInvalidate[pPageView].reset(pRect); + m_mapPageInvalidate[pPageView] = pdfium::MakeUnique<CFX_RectF>(rtInvalidate); } void CXFA_FFDocView::RunInvalidate() { @@ -636,11 +633,12 @@ void CXFA_FFDocView::AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc) { } void CXFA_FFDocView::AddCalculateNodeNotify(CXFA_Node* pNodeChange) { - CXFA_CalcData* pGlobalData = - (CXFA_CalcData*)pNodeChange->GetUserData(XFA_CalcData); - int32_t iCount = pGlobalData ? pGlobalData->m_Globals.GetSize() : 0; - for (int32_t i = 0; i < iCount; i++) { - CXFA_WidgetAcc* pResultAcc = pGlobalData->m_Globals[i]; + auto pGlobalData = + static_cast<CXFA_CalcData*>(pNodeChange->GetUserData(XFA_CalcData)); + if (!pGlobalData) + return; + + for (const auto& pResultAcc : pGlobalData->m_Globals) { if (!pResultAcc->GetNode()->HasRemovedChildren()) AddCalculateWidgetAcc(pResultAcc); } @@ -754,10 +752,8 @@ void CXFA_FFDocView::RunBindItems() { binditems.GetValueRef(wsValueRef); binditems.GetLabelRef(wsLabelRef); const bool bUseValue = wsLabelRef.IsEmpty() || wsLabelRef == wsValueRef; - const bool bLabelUseContent = - wsLabelRef.IsEmpty() || wsLabelRef == FX_WSTRC(L"$"); - const bool bValueUseContent = - wsValueRef.IsEmpty() || wsValueRef == FX_WSTRC(L"$"); + const bool bLabelUseContent = wsLabelRef.IsEmpty() || wsLabelRef == L"$"; + const bool bValueUseContent = wsValueRef.IsEmpty() || wsValueRef == L"$"; CFX_WideString wsValue; CFX_WideString wsLabel; uint32_t uValueHash = FX_HashCode_GetW(wsValueRef, false); diff --git a/xfa/fxfa/app/xfa_ffdraw.cpp b/xfa/fxfa/app/xfa_ffdraw.cpp index da1ae65ba..37095ddb4 100644 --- a/xfa/fxfa/app/xfa_ffdraw.cpp +++ b/xfa/fxfa/app/xfa_ffdraw.cpp @@ -11,6 +11,6 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFDraw::CXFA_FFDraw(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) - : CXFA_FFWidget(pPageView, pDataAcc) {} +CXFA_FFDraw::CXFA_FFDraw(CXFA_WidgetAcc* pDataAcc) : CXFA_FFWidget(pDataAcc) {} + CXFA_FFDraw::~CXFA_FFDraw() {} diff --git a/xfa/fxfa/app/xfa_ffdraw.h b/xfa/fxfa/app/xfa_ffdraw.h index bf9fd84a1..0212dcca0 100644 --- a/xfa/fxfa/app/xfa_ffdraw.h +++ b/xfa/fxfa/app/xfa_ffdraw.h @@ -12,7 +12,7 @@ class CXFA_FFDraw : public CXFA_FFWidget { public: - CXFA_FFDraw(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFDraw(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFDraw() override; }; diff --git a/xfa/fxfa/app/xfa_ffexclgroup.cpp b/xfa/fxfa/app/xfa_ffexclgroup.cpp index a6b94475a..7d63daddb 100644 --- a/xfa/fxfa/app/xfa_ffexclgroup.cpp +++ b/xfa/fxfa/app/xfa_ffexclgroup.cpp @@ -11,20 +11,20 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFExclGroup::CXFA_FFExclGroup(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFWidget(pPageView, pDataAcc) {} +CXFA_FFExclGroup::CXFA_FFExclGroup(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFWidget(pDataAcc) {} + CXFA_FFExclGroup::~CXFA_FFExclGroup() {} + void CXFA_FFExclGroup::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); } diff --git a/xfa/fxfa/app/xfa_ffexclgroup.h b/xfa/fxfa/app/xfa_ffexclgroup.h index 90e82510a..12a13aea9 100644 --- a/xfa/fxfa/app/xfa_ffexclgroup.h +++ b/xfa/fxfa/app/xfa_ffexclgroup.h @@ -12,7 +12,7 @@ class CXFA_FFExclGroup : public CXFA_FFWidget { public: - CXFA_FFExclGroup(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFExclGroup(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFExclGroup() override; // CXFA_FFWidget diff --git a/xfa/fxfa/app/xfa_fffield.cpp b/xfa/fxfa/app/xfa_fffield.cpp index aa8abbde8..630d04311 100644 --- a/xfa/fxfa/app/xfa_fffield.cpp +++ b/xfa/fxfa/app/xfa_fffield.cpp @@ -25,45 +25,39 @@ #include "xfa/fxgraphics/cfx_color.h" #include "xfa/fxgraphics/cfx_path.h" -CXFA_FFField::CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) - : CXFA_FFWidget(pPageView, pDataAcc), m_pNormalWidget(nullptr) { - m_rtUI.Set(0, 0, 0, 0); - m_rtCaption.Set(0, 0, 0, 0); -} +CXFA_FFField::CXFA_FFField(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFWidget(pDataAcc), m_pNormalWidget(nullptr) {} + CXFA_FFField::~CXFA_FFField() { CXFA_FFField::UnloadWidget(); } -bool CXFA_FFField::GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus) { +CFX_RectF CXFA_FFField::GetBBox(uint32_t dwStatus, bool bDrawFocus) { if (!bDrawFocus) - return CXFA_FFWidget::GetBBox(rtBox, dwStatus); + return CXFA_FFWidget::GetBBox(dwStatus); XFA_Element type = m_pDataAcc->GetUIType(); - if (type == XFA_Element::Button || type == XFA_Element::CheckButton || - type == XFA_Element::ImageEdit || type == XFA_Element::Signature || - type == XFA_Element::ChoiceList) { - rtBox = m_rtUI; - CFX_Matrix mt; - GetRotateMatrix(mt); - mt.TransformRect(rtBox); - return true; + if (type != XFA_Element::Button && type != XFA_Element::CheckButton && + type != XFA_Element::ImageEdit && type != XFA_Element::Signature && + type != XFA_Element::ChoiceList) { + return CFX_RectF(); } - return false; + + CFX_RectF rtBox = m_rtUI; + GetRotateMatrix().TransformRect(rtBox); + return rtBox; } void CXFA_FFField::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); DrawBorder(pGS, borderUI, m_rtUI, &mtRotate); @@ -71,8 +65,7 @@ void CXFA_FFField::RenderWidget(CFX_Graphics* pGS, DrawHighlight(pGS, &mtRotate, dwStatus, false); CFX_RectF rtWidget = m_pNormalWidget->GetWidgetRect(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top); + CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top); mt.Concat(mtRotate); GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget, pGS, &mt); } @@ -89,12 +82,11 @@ void CXFA_FFField::DrawHighlight(CFX_Graphics* pGS, CFX_Color crHighlight(pDoc->GetDocEnvironment()->GetHighlightColor(pDoc)); pGS->SetFillColor(&crHighlight); CFX_Path path; - path.Create(); - if (bEllipse) { + if (bEllipse) path.AddEllipse(m_rtUI); - } else { + else path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height); - } + pGS->FillPath(&path, FXFILL_WINDING, pMatrix); } } @@ -105,8 +97,8 @@ void CXFA_FFField::DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix) { FX_FLOAT DashPattern[2] = {1, 1}; pGS->SetLineDash(0.0f, DashPattern, 2); pGS->SetLineWidth(0, false); + CFX_Path path; - path.Create(); path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height); pGS->StrokePath(&path, pMatrix); } @@ -157,8 +149,7 @@ bool CXFA_FFField::PerformLayout() { return true; } void CXFA_FFField::CapPlacement() { - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); + CFX_RectF rtWidget = GetRectWithoutRotate(); CXFA_Margin mgWidget = m_pDataAcc->GetMargin(); if (mgWidget) { CXFA_LayoutItem* pItem = this; @@ -170,38 +161,35 @@ void CXFA_FFField::CapPlacement() { if (!pItem->GetPrev() && !pItem->GetNext()) { rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset); } else { - if (!pItem->GetPrev()) { + if (!pItem->GetPrev()) rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, 0); - } else if (!pItem->GetNext()) { + else if (!pItem->GetNext()) rtWidget.Deflate(fLeftInset, 0, fRightInset, fBottomInset); - } else { + else rtWidget.Deflate(fLeftInset, 0, fRightInset, 0); - } } } + XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown; FX_FLOAT fCapReserve = 0; CXFA_Caption caption = m_pDataAcc->GetCaption(); if (caption && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) { iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType(); if (iCapPlacement == XFA_ATTRIBUTEENUM_Top && GetPrev()) { - m_rtCaption.Set(0, 0, 0, 0); + m_rtCaption.Reset(); } else if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom && GetNext()) { - m_rtCaption.Set(0, 0, 0, 0); + m_rtCaption.Reset(); } else { fCapReserve = caption.GetReserve(); CXFA_LayoutItem* pItem = this; if (!pItem->GetPrev() && !pItem->GetNext()) { - m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, - rtWidget.height); + m_rtCaption = rtWidget; } else { pItem = pItem->GetFirst(); - pItem->GetRect(m_rtCaption); + m_rtCaption = pItem->GetRect(false); pItem = pItem->GetNext(); while (pItem) { - CFX_RectF rtRect; - pItem->GetRect(rtRect); - m_rtCaption.height += rtRect.Height(); + m_rtCaption.height += pItem->GetRect(false).Height(); pItem = pItem->GetNext(); } XFA_RectWidthoutMargin(m_rtCaption, mgWidget); @@ -214,9 +202,9 @@ void CXFA_FFField::CapPlacement() { pCapTextLayout->CalcSize(minSize, maxSize, size); if (iCapPlacement == XFA_ATTRIBUTEENUM_Top || iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) { - fCapReserve = size.y; + fCapReserve = size.height; } else { - fCapReserve = size.x; + fCapReserve = size.width; } } } @@ -361,145 +349,126 @@ bool CXFA_FFField::OnMouseExit() { return true; } -void CXFA_FFField::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) { - if (!m_pNormalWidget) - return; - - CFX_RectF rtWidget = m_pNormalWidget->GetWidgetRect(); - fx -= rtWidget.left; - fy -= rtWidget.top; +CFX_PointF CXFA_FFField::FWLToClient(const CFX_PointF& point) { + return m_pNormalWidget ? point - m_pNormalWidget->GetWidgetRect().TopLeft() + : point; } -bool CXFA_FFField::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { +bool CXFA_FFField::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { return false; } - if (!PtInActiveRect(fx, fy)) { + if (!PtInActiveRect(point)) return false; - } + SetButtonDown(true); CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFField::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { + +bool CXFA_FFField::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } - if (!IsButtonDown()) { + if (!IsButtonDown()) return false; - } + SetButtonDown(false); CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::LeftButtonUp; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFField::OnLButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { + +bool CXFA_FFField::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } + CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::LeftButtonDblClk; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFField::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { + +bool CXFA_FFField::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } + CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::Move; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } + bool CXFA_FFField::OnMouseWheel(uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy) { - if (!m_pNormalWidget) { + const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } + CFWL_MessageMouseWheel ms(nullptr, m_pNormalWidget); ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); - ms.m_fDeltaX = zDelta; - ms.m_fDeltaY = 0; + ms.m_pos = FWLToClient(point); + ms.m_delta = CFX_PointF(zDelta, 0); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFField::OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { + +bool CXFA_FFField::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) { return false; } - if (!PtInActiveRect(fx, fy)) { + if (!PtInActiveRect(point)) return false; - } + SetButtonDown(true); CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::RightButtonDown; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFField::OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { + +bool CXFA_FFField::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } - if (!IsButtonDown()) { + if (!IsButtonDown()) return false; - } + SetButtonDown(false); CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::RightButtonUp; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFField::OnRButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!m_pNormalWidget) { + +bool CXFA_FFField::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) { + if (!m_pNormalWidget) return false; - } + CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::RightButtonDblClk; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } @@ -568,28 +537,25 @@ bool CXFA_FFField::OnChar(uint32_t dwChar, uint32_t dwFlags) { TranslateFWLMessage(&ms); return true; } -FWL_WidgetHit CXFA_FFField::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (m_pNormalWidget) { - FX_FLOAT ffx = fx, ffy = fy; - FWLToClient(ffx, ffy); - if (m_pNormalWidget->HitTest(ffx, ffy) != FWL_WidgetHit::Unknown) - return FWL_WidgetHit::Client; - } - CFX_RectF rtBox; - GetRectWithoutRotate(rtBox); - if (!rtBox.Contains(fx, fy)) +FWL_WidgetHit CXFA_FFField::OnHitTest(const CFX_PointF& point) { + if (m_pNormalWidget && + m_pNormalWidget->HitTest(FWLToClient(point)) != FWL_WidgetHit::Unknown) { + return FWL_WidgetHit::Client; + } + + if (!GetRectWithoutRotate().Contains(point)) return FWL_WidgetHit::Unknown; - if (m_rtCaption.Contains(fx, fy)) + if (m_rtCaption.Contains(point)) return FWL_WidgetHit::Titlebar; return FWL_WidgetHit::Border; } -bool CXFA_FFField::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) { +bool CXFA_FFField::OnSetCursor(const CFX_PointF& point) { return true; } -bool CXFA_FFField::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) { - return m_pNormalWidget && m_pNormalWidget->GetWidgetRect().Contains(fx, fy); +bool CXFA_FFField::PtInActiveRect(const CFX_PointF& point) { + return m_pNormalWidget && m_pNormalWidget->GetWidgetRect().Contains(point); } void CXFA_FFField::LayoutCaption() { @@ -603,47 +569,45 @@ void CXFA_FFField::LayoutCaption() { if (m_rtCaption.height < fHeight) m_rtCaption.height = fHeight; } + void CXFA_FFField::RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix) { CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout(); - if (!pCapTextLayout) { + if (!pCapTextLayout) return; - } + CXFA_Caption caption = m_pDataAcc->GetCaption(); - if (caption && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) { - if (!pCapTextLayout->IsLoaded()) { - pCapTextLayout->Layout(CFX_SizeF(m_rtCaption.width, m_rtCaption.height)); - } - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); - CFX_RectF rtClip = m_rtCaption; - rtClip.Intersect(rtWidget); - CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top); - if (pMatrix) { - pMatrix->TransformRect(rtClip); - mt.Concat(*pMatrix); - } - pCapTextLayout->DrawString(pRenderDevice, mt, rtClip); + if (!caption || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) + return; + + if (!pCapTextLayout->IsLoaded()) + pCapTextLayout->Layout(CFX_SizeF(m_rtCaption.width, m_rtCaption.height)); + + CFX_RectF rtClip = m_rtCaption; + rtClip.Intersect(GetRectWithoutRotate()); + CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); + CFX_Matrix mt(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top); + if (pMatrix) { + pMatrix->TransformRect(rtClip); + mt.Concat(*pMatrix); } + pCapTextLayout->DrawString(pRenderDevice, mt, rtClip); } + bool CXFA_FFField::ProcessCommittedData() { - if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) { + if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) return false; - } - if (!IsDataChanged()) { + if (!IsDataChanged()) return false; - } - if (CalculateOverride() != 1) { + if (CalculateOverride() != 1) return false; - } - if (!CommitData()) { + if (!CommitData()) return false; - } + m_pDocView->SetChangeMark(); m_pDocView->AddValidateWidget(m_pDataAcc); return true; } + int32_t CXFA_FFField::CalculateOverride() { CXFA_WidgetAcc* pAcc = m_pDataAcc->GetExclGroup(); if (!pAcc) { diff --git a/xfa/fxfa/app/xfa_fffield.h b/xfa/fxfa/app/xfa_fffield.h index 6b4c92ae1..f10ce6173 100644 --- a/xfa/fxfa/app/xfa_fffield.h +++ b/xfa/fxfa/app/xfa_fffield.h @@ -17,13 +17,11 @@ class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate { public: - CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFField(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFField() override; // CXFA_FFWidget - bool GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus = false) override; + CFX_RectF GetBBox(uint32_t dwStatus, bool bDrawFocus = false) override; void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) override; @@ -33,25 +31,24 @@ class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate { bool PerformLayout() override; bool OnMouseEnter() override; bool OnMouseExit() override; - bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnLButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) override; bool OnMouseWheel(uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy) override; - bool OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + const CFX_PointF& point) override; + bool OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) override; bool OnSetFocus(CXFA_FFWidget* pOldWidget) override; bool OnKillFocus(CXFA_FFWidget* pNewWidget) override; bool OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) override; bool OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) override; bool OnChar(uint32_t dwChar, uint32_t dwFlags) override; - FWL_WidgetHit OnHitTest(FX_FLOAT fx, FX_FLOAT fy) override; - bool OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit OnHitTest(const CFX_PointF& point) override; + bool OnSetCursor(const CFX_PointF& point) override; // IFWL_WidgetDelegate void OnProcessMessage(CFWL_Message* pMessage) override; @@ -63,12 +60,12 @@ class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate { uint32_t UpdateUIProperty(); protected: - bool PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) override; + bool PtInActiveRect(const CFX_PointF& point) override; virtual void SetFWLRect(); void SetFWLThemeProvider(); CFWL_Widget* GetNormalWidget() { return m_pNormalWidget; } - void FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy); + CFX_PointF FWLToClient(const CFX_PointF& point); void LayoutCaption(); void RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix = nullptr); diff --git a/xfa/fxfa/app/xfa_ffimage.cpp b/xfa/fxfa/app/xfa_ffimage.cpp index c387cc269..a613221ea 100644 --- a/xfa/fxfa/app/xfa_ffimage.cpp +++ b/xfa/fxfa/app/xfa_ffimage.cpp @@ -12,11 +12,12 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFImage::CXFA_FFImage(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) - : CXFA_FFDraw(pPageView, pDataAcc) {} +CXFA_FFImage::CXFA_FFImage(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {} + CXFA_FFImage::~CXFA_FFImage() { CXFA_FFImage::UnloadWidget(); } + bool CXFA_FFImage::IsLoaded() { return !!GetDataAcc()->GetImageImage(); } @@ -33,34 +34,36 @@ void CXFA_FFImage::UnloadWidget() { void CXFA_FFImage::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); - if (CFX_DIBitmap* pDIBitmap = GetDataAcc()->GetImageImage()) { - CFX_RectF rtImage; - GetRectWithoutRotate(rtImage); - if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { - XFA_RectWidthoutMargin(rtImage, mgWidget); - } - int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left; - int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top; - if (CXFA_Para para = m_pDataAcc->GetPara()) { - iHorzAlign = para.GetHorizontalAlign(); - iVertAlign = para.GetVerticalAlign(); - } - CXFA_Value value = m_pDataAcc->GetFormValue(); - CXFA_Image imageObj = value.GetImage(); - int32_t iAspect = imageObj.GetAspect(); - int32_t iImageXDpi = 0; - int32_t iImageYDpi = 0; - m_pDataAcc->GetImageDpi(iImageXDpi, iImageYDpi); - XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi, - iImageYDpi, iHorzAlign, iVertAlign); + + CFX_DIBitmap* pDIBitmap = GetDataAcc()->GetImageImage(); + if (!pDIBitmap) + return; + + CFX_RectF rtImage = GetRectWithoutRotate(); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) + XFA_RectWidthoutMargin(rtImage, mgWidget); + + int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left; + int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top; + if (CXFA_Para para = m_pDataAcc->GetPara()) { + iHorzAlign = para.GetHorizontalAlign(); + iVertAlign = para.GetVerticalAlign(); } + + CXFA_Value value = m_pDataAcc->GetFormValue(); + CXFA_Image imageObj = value.GetImage(); + int32_t iAspect = imageObj.GetAspect(); + int32_t iImageXDpi = 0; + int32_t iImageYDpi = 0; + m_pDataAcc->GetImageDpi(iImageXDpi, iImageYDpi); + XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi, + iImageYDpi, iHorzAlign, iVertAlign); } diff --git a/xfa/fxfa/app/xfa_ffimage.h b/xfa/fxfa/app/xfa_ffimage.h index cc5320eb3..2c4279187 100644 --- a/xfa/fxfa/app/xfa_ffimage.h +++ b/xfa/fxfa/app/xfa_ffimage.h @@ -11,7 +11,7 @@ class CXFA_FFImage : public CXFA_FFDraw { public: - CXFA_FFImage(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFImage(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFImage() override; // CXFA_FFWidget diff --git a/xfa/fxfa/app/xfa_ffimageedit.cpp b/xfa/fxfa/app/xfa_ffimageedit.cpp index 3b063d6e9..01d29eed4 100644 --- a/xfa/fxfa/app/xfa_ffimageedit.cpp +++ b/xfa/fxfa/app/xfa_ffimageedit.cpp @@ -16,12 +16,13 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFImageEdit::CXFA_FFImageEdit(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) {} +CXFA_FFImageEdit::CXFA_FFImageEdit(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} + CXFA_FFImageEdit::~CXFA_FFImageEdit() { CXFA_FFImageEdit::UnloadWidget(); } + bool CXFA_FFImageEdit::LoadWidget() { CFWL_PictureBox* pPictureBox = new CFWL_PictureBox(GetFWLApp()); m_pNormalWidget = pPictureBox; @@ -48,47 +49,47 @@ void CXFA_FFImageEdit::UnloadWidget() { void CXFA_FFImageEdit::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); DrawBorder(pGS, borderUI, m_rtUI, &mtRotate); RenderCaption(pGS, &mtRotate); - if (CFX_DIBitmap* pDIBitmap = m_pDataAcc->GetImageEditImage()) { - CFX_RectF rtImage = m_pNormalWidget->GetWidgetRect(); - int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left; - int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top; - if (CXFA_Para para = m_pDataAcc->GetPara()) { - iHorzAlign = para.GetHorizontalAlign(); - iVertAlign = para.GetVerticalAlign(); - } - int32_t iAspect = XFA_ATTRIBUTEENUM_Fit; - if (CXFA_Value value = m_pDataAcc->GetFormValue()) { - if (CXFA_Image imageObj = value.GetImage()) { - iAspect = imageObj.GetAspect(); - } - } - int32_t iImageXDpi = 0; - int32_t iImageYDpi = 0; - m_pDataAcc->GetImageEditDpi(iImageXDpi, iImageYDpi); - XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi, - iImageYDpi, iHorzAlign, iVertAlign); + CFX_DIBitmap* pDIBitmap = m_pDataAcc->GetImageEditImage(); + if (!pDIBitmap) + return; + + CFX_RectF rtImage = m_pNormalWidget->GetWidgetRect(); + int32_t iHorzAlign = XFA_ATTRIBUTEENUM_Left; + int32_t iVertAlign = XFA_ATTRIBUTEENUM_Top; + if (CXFA_Para para = m_pDataAcc->GetPara()) { + iHorzAlign = para.GetHorizontalAlign(); + iVertAlign = para.GetVerticalAlign(); + } + + int32_t iAspect = XFA_ATTRIBUTEENUM_Fit; + if (CXFA_Value value = m_pDataAcc->GetFormValue()) { + if (CXFA_Image imageObj = value.GetImage()) + iAspect = imageObj.GetAspect(); } + + int32_t iImageXDpi = 0; + int32_t iImageYDpi = 0; + m_pDataAcc->GetImageEditDpi(iImageXDpi, iImageYDpi); + XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi, + iImageYDpi, iHorzAlign, iVertAlign); } bool CXFA_FFImageEdit::OnLButtonDown(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) return false; - - if (!PtInActiveRect(fx, fy)) + if (!PtInActiveRect(point)) return false; SetButtonDown(true); @@ -96,9 +97,7 @@ bool CXFA_FFImageEdit::OnLButtonDown(uint32_t dwFlags, CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } diff --git a/xfa/fxfa/app/xfa_ffimageedit.h b/xfa/fxfa/app/xfa_ffimageedit.h index b6f6ae1ff..73032b981 100644 --- a/xfa/fxfa/app/xfa_ffimageedit.h +++ b/xfa/fxfa/app/xfa_ffimageedit.h @@ -11,7 +11,7 @@ class CXFA_FFImageEdit : public CXFA_FFField { public: - CXFA_FFImageEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFImageEdit(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFImageEdit() override; // CXFA_FFField @@ -20,7 +20,7 @@ class CXFA_FFImageEdit : public CXFA_FFField { uint32_t dwStatus) override; bool LoadWidget() override; void UnloadWidget() override; - bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; void OnProcessMessage(CFWL_Message* pMessage) override; void OnProcessEvent(CFWL_Event* pEvent) override; void OnDrawWidget(CFX_Graphics* pGraphics, diff --git a/xfa/fxfa/app/xfa_ffnotify.cpp b/xfa/fxfa/app/xfa_ffnotify.cpp index 3aef5fcbf..951b4fd3f 100644 --- a/xfa/fxfa/app/xfa_ffnotify.cpp +++ b/xfa/fxfa/app/xfa_ffnotify.cpp @@ -102,62 +102,62 @@ CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode) { CXFA_FFWidget* pWidget; switch (pAcc->GetUIType()) { case XFA_Element::Barcode: - pWidget = new CXFA_FFBarcode(nullptr, pAcc); + pWidget = new CXFA_FFBarcode(pAcc); break; case XFA_Element::Button: - pWidget = new CXFA_FFPushButton(nullptr, pAcc); + pWidget = new CXFA_FFPushButton(pAcc); break; case XFA_Element::CheckButton: - pWidget = new CXFA_FFCheckButton(nullptr, pAcc); + pWidget = new CXFA_FFCheckButton(pAcc); break; case XFA_Element::ChoiceList: { if (pAcc->IsListBox()) { - pWidget = new CXFA_FFListBox(nullptr, pAcc); + pWidget = new CXFA_FFListBox(pAcc); } else { - pWidget = new CXFA_FFComboBox(nullptr, pAcc); + pWidget = new CXFA_FFComboBox(pAcc); } } break; case XFA_Element::DateTimeEdit: - pWidget = new CXFA_FFDateTimeEdit(nullptr, pAcc); + pWidget = new CXFA_FFDateTimeEdit(pAcc); break; case XFA_Element::ImageEdit: - pWidget = new CXFA_FFImageEdit(nullptr, pAcc); + pWidget = new CXFA_FFImageEdit(pAcc); break; case XFA_Element::NumericEdit: - pWidget = new CXFA_FFNumericEdit(nullptr, pAcc); + pWidget = new CXFA_FFNumericEdit(pAcc); break; case XFA_Element::PasswordEdit: - pWidget = new CXFA_FFPasswordEdit(nullptr, pAcc); + pWidget = new CXFA_FFPasswordEdit(pAcc); break; case XFA_Element::Signature: - pWidget = new CXFA_FFSignature(nullptr, pAcc); + pWidget = new CXFA_FFSignature(pAcc); break; case XFA_Element::TextEdit: - pWidget = new CXFA_FFTextEdit(nullptr, pAcc); + pWidget = new CXFA_FFTextEdit(pAcc); break; case XFA_Element::Arc: - pWidget = new CXFA_FFArc(nullptr, pAcc); + pWidget = new CXFA_FFArc(pAcc); break; case XFA_Element::Line: - pWidget = new CXFA_FFLine(nullptr, pAcc); + pWidget = new CXFA_FFLine(pAcc); break; case XFA_Element::Rectangle: - pWidget = new CXFA_FFRectangle(nullptr, pAcc); + pWidget = new CXFA_FFRectangle(pAcc); break; case XFA_Element::Text: - pWidget = new CXFA_FFText(nullptr, pAcc); + pWidget = new CXFA_FFText(pAcc); break; case XFA_Element::Image: - pWidget = new CXFA_FFImage(nullptr, pAcc); + pWidget = new CXFA_FFImage(pAcc); break; case XFA_Element::Draw: - pWidget = new CXFA_FFDraw(nullptr, pAcc); + pWidget = new CXFA_FFDraw(pAcc); break; case XFA_Element::Subform: - pWidget = new CXFA_FFSubForm(nullptr, pAcc); + pWidget = new CXFA_FFSubForm(pAcc); break; case XFA_Element::ExclGroup: - pWidget = new CXFA_FFExclGroup(nullptr, pAcc); + pWidget = new CXFA_FFExclGroup(pAcc); break; case XFA_Element::DefaultUi: default: @@ -487,9 +487,7 @@ void CXFA_FFNotify::OnLayoutItemAdded(CXFA_LayoutProcessor* pLayout, return; } if (pWidget->IsLoaded()) { - CFX_RectF rtOld; - pWidget->GetWidgetRect(rtOld); - if (rtOld != pWidget->ReCacheWidgetRect()) + if (pWidget->GetWidgetRect() != pWidget->RecacheWidgetRect()) pWidget->PerformLayout(); } else { pWidget->LoadWidget(); diff --git a/xfa/fxfa/app/xfa_ffpageview.cpp b/xfa/fxfa/app/xfa_ffpageview.cpp index 5ef108693..7ae5493ba 100644 --- a/xfa/fxfa/app/xfa_ffpageview.cpp +++ b/xfa/fxfa/app/xfa_ffpageview.cpp @@ -6,6 +6,11 @@ #include "xfa/fxfa/xfa_ffpageview.h" +#include <memory> +#include <vector> + +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fde/fde_render.h" #include "xfa/fxfa/app/xfa_ffcheckbutton.h" #include "xfa/fxfa/app/xfa_ffchoicelist.h" @@ -20,16 +25,15 @@ namespace { -void GetPageMatrix(CFX_Matrix& pageMatrix, - const CFX_RectF& docPageRect, - const CFX_Rect& devicePageRect, - int32_t iRotate, - uint32_t dwCoordinatesType) { +CFX_Matrix GetPageMatrix(const CFX_RectF& docPageRect, + const CFX_Rect& devicePageRect, + int32_t iRotate, + uint32_t dwCoordinatesType) { ASSERT(iRotate >= 0 && iRotate <= 3); + bool bFlipX = (dwCoordinatesType & 0x01) != 0; bool bFlipY = (dwCoordinatesType & 0x02) != 0; - CFX_Matrix m; - m.Set((bFlipX ? -1.0f : 1.0f), 0, 0, (bFlipY ? -1.0f : 1.0f), 0, 0); + CFX_Matrix m((bFlipX ? -1.0f : 1.0f), 0, 0, (bFlipY ? -1.0f : 1.0f), 0, 0); if (iRotate == 0 || iRotate == 2) { m.a *= (FX_FLOAT)devicePageRect.width / docPageRect.width; m.d *= (FX_FLOAT)devicePageRect.height / docPageRect.height; @@ -66,7 +70,7 @@ void GetPageMatrix(CFX_Matrix& pageMatrix, default: break; } - pageMatrix = m; + return m; } bool PageWidgetFilter(CXFA_FFWidget* pWidget, @@ -120,17 +124,13 @@ CXFA_FFDocView* CXFA_FFPageView::GetDocView() const { return m_pDocView; } -void CXFA_FFPageView::GetPageViewRect(CFX_RectF& rtPage) const { - rtPage.Set(0, 0, GetPageSize()); +CFX_RectF CXFA_FFPageView::GetPageViewRect() const { + return CFX_RectF(0, 0, GetPageSize()); } -void CXFA_FFPageView::GetDisplayMatrix(CFX_Matrix& mt, - const CFX_Rect& rtDisp, - int32_t iRotate) const { - CFX_SizeF sz = GetPageSize(); - CFX_RectF fdePage; - fdePage.Set(0, 0, sz.x, sz.y); - GetPageMatrix(mt, fdePage, rtDisp, iRotate, 0); +CFX_Matrix CXFA_FFPageView::GetDisplayMatrix(const CFX_Rect& rtDisp, + int32_t iRotate) const { + return GetPageMatrix(CFX_RectF(0, 0, GetPageSize()), rtDisp, iRotate, 0); } IXFA_WidgetIterator* CXFA_FFPageView::CreateWidgetIterator( @@ -228,32 +228,34 @@ void CXFA_FFTabOrderPageWidgetIterator::Reset() { CreateTabOrderWidgetArray(); m_iCurWidget = -1; } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToFirst() { - if (m_TabOrderWidgetArray.GetSize() > 0) { - for (int32_t i = 0; i < m_TabOrderWidgetArray.GetSize(); i++) { - if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true, - m_bIgnorerelevant)) { - m_iCurWidget = i; - return m_TabOrderWidgetArray[m_iCurWidget]; - } + for (int32_t i = 0; + i < pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray); i++) { + if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true, + m_bIgnorerelevant)) { + m_iCurWidget = i; + return m_TabOrderWidgetArray[m_iCurWidget]; } } return nullptr; } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToLast() { - if (m_TabOrderWidgetArray.GetSize() > 0) { - for (int32_t i = m_TabOrderWidgetArray.GetSize() - 1; i >= 0; i--) { - if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true, - m_bIgnorerelevant)) { - m_iCurWidget = i; - return m_TabOrderWidgetArray[m_iCurWidget]; - } + for (int32_t i = pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray) - 1; + i >= 0; i--) { + if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true, + m_bIgnorerelevant)) { + m_iCurWidget = i; + return m_TabOrderWidgetArray[m_iCurWidget]; } } return nullptr; } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToNext() { - for (int32_t i = m_iCurWidget + 1; i < m_TabOrderWidgetArray.GetSize(); i++) { + for (int32_t i = m_iCurWidget + 1; + i < pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray); i++) { if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true, m_bIgnorerelevant)) { m_iCurWidget = i; @@ -263,6 +265,7 @@ CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToNext() { m_iCurWidget = -1; return nullptr; } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious() { for (int32_t i = m_iCurWidget - 1; i >= 0; i--) { if (PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, true, @@ -274,21 +277,22 @@ CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious() { m_iCurWidget = -1; return nullptr; } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget() { - if (m_iCurWidget >= 0) { - return m_TabOrderWidgetArray[m_iCurWidget]; - } - return nullptr; + return m_iCurWidget >= 0 ? m_TabOrderWidgetArray[m_iCurWidget] : nullptr; } + bool CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget( CXFA_FFWidget* hWidget) { - int32_t iWidgetIndex = m_TabOrderWidgetArray.Find(hWidget); - if (iWidgetIndex >= 0) { - m_iCurWidget = iWidgetIndex; - return true; - } - return false; + auto it = std::find(m_TabOrderWidgetArray.begin(), + m_TabOrderWidgetArray.end(), hWidget); + if (it == m_TabOrderWidgetArray.end()) + return false; + + m_iCurWidget = it - m_TabOrderWidgetArray.begin(); + return true; } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget( CXFA_FFWidget* pWidget) { CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc(); @@ -309,29 +313,36 @@ CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName( CXFA_FFWidget* pRefWidget) { return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget); } + void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() { - m_TabOrderWidgetArray.RemoveAll(); - CXFA_WidgetArray SpaceOrderWidgetArray; - CreateSpaceOrderWidgetArray(SpaceOrderWidgetArray); - int32_t nWidgetCount = SpaceOrderWidgetArray.GetSize(); - if (nWidgetCount < 1) { + m_TabOrderWidgetArray.clear(); + + std::vector<CXFA_FFWidget*> SpaceOrderWidgetArray; + CreateSpaceOrderWidgetArray(&SpaceOrderWidgetArray); + if (SpaceOrderWidgetArray.empty()) return; - } + + int32_t nWidgetCount = pdfium::CollectionSize<int32_t>(SpaceOrderWidgetArray); CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0]; - for (; m_TabOrderWidgetArray.GetSize() < nWidgetCount;) { - if (m_TabOrderWidgetArray.Find(hWidget) < 0) { - m_TabOrderWidgetArray.Add(hWidget); + while (pdfium::CollectionSize<int32_t>(m_TabOrderWidgetArray) < + nWidgetCount) { + if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) { + m_TabOrderWidgetArray.push_back(hWidget); CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc(); if (pWidgetAcc->GetUIType() == XFA_Element::ExclGroup) { - int32_t iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget) + 1; + auto it = std::find(SpaceOrderWidgetArray.begin(), + SpaceOrderWidgetArray.end(), hWidget); + int32_t iWidgetIndex = it != SpaceOrderWidgetArray.end() + ? it - SpaceOrderWidgetArray.begin() + 1 + : 0; while (true) { CXFA_FFWidget* pRadio = - SpaceOrderWidgetArray[(iWidgetIndex) % nWidgetCount]; + SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount]; if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) { break; } - if (m_TabOrderWidgetArray.Find(hWidget) < 0) { - m_TabOrderWidgetArray.Add(pRadio); + if (!pdfium::ContainsValue(m_TabOrderWidgetArray, hWidget)) { + m_TabOrderWidgetArray.push_back(pRadio); } iWidgetIndex++; } @@ -341,23 +352,27 @@ void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray() { continue; } } - int32_t iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget); - hWidget = SpaceOrderWidgetArray[(iWidgetIndex + 1) % nWidgetCount]; + auto it = std::find(SpaceOrderWidgetArray.begin(), + SpaceOrderWidgetArray.end(), hWidget); + int32_t iWidgetIndex = it != SpaceOrderWidgetArray.end() + ? it - SpaceOrderWidgetArray.begin() + 1 + : 0; + hWidget = SpaceOrderWidgetArray[iWidgetIndex % nWidgetCount]; } } + static int32_t XFA_TabOrderWidgetComparator(const void* phWidget1, const void* phWidget2) { - CXFA_FFWidget* pWidget1 = (*(CXFA_TabParam**)phWidget1)->m_pWidget; - CXFA_FFWidget* pWidget2 = (*(CXFA_TabParam**)phWidget2)->m_pWidget; - CFX_RectF rt1, rt2; - pWidget1->GetWidgetRect(rt1); - pWidget2->GetWidgetRect(rt2); + auto param1 = *static_cast<CXFA_TabParam**>(const_cast<void*>(phWidget1)); + auto param2 = *static_cast<CXFA_TabParam**>(const_cast<void*>(phWidget2)); + CFX_RectF rt1 = param1->m_pWidget->GetWidgetRect(); + CFX_RectF rt2 = param2->m_pWidget->GetWidgetRect(); FX_FLOAT x1 = rt1.left, y1 = rt1.top, x2 = rt2.left, y2 = rt2.top; - if (y1 < y2 || (y1 - y2 < XFA_FLOAT_PERCISION && x1 < x2)) { + if (y1 < y2 || (y1 - y2 < XFA_FLOAT_PERCISION && x1 < x2)) return -1; - } return 1; } + void CXFA_FFTabOrderPageWidgetIterator::OrderContainer( CXFA_LayoutItemIterator* sIterator, CXFA_LayoutItem* pContainerItem, @@ -407,36 +422,35 @@ void CXFA_FFTabOrderPageWidgetIterator::OrderContainer( XFA_TabOrderWidgetComparator); } for (int32_t iStart = 0; iStart < iChildren; iStart++) { - CXFA_TabParam* pParam = tabParams[iStart]; - pContainer->m_Children.Add(pParam->m_pWidget); - if (pParam->m_Children.GetSize() > 0) { - pContainer->m_Children.Append(pParam->m_Children); - } - delete pParam; + std::unique_ptr<CXFA_TabParam> pParam(tabParams[iStart]); + pContainer->m_Children.push_back(pParam->m_pWidget); + pContainer->m_Children.insert(pContainer->m_Children.end(), + pParam->m_Children.begin(), + pParam->m_Children.end()); } tabParams.RemoveAll(); } void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray( - CXFA_WidgetArray& WidgetArray) { + std::vector<CXFA_FFWidget*>* WidgetArray) { CXFA_LayoutItemIterator sIterator; sIterator.Init(m_pPageView); - CXFA_TabParam* pParam = new CXFA_TabParam; + auto pParam = pdfium::MakeUnique<CXFA_TabParam>(); bool bCurrentItem = false; bool bContentArea = false; - OrderContainer(&sIterator, nullptr, pParam, bCurrentItem, bContentArea); - if (pParam->m_Children.GetSize() > 0) { - WidgetArray.Append(pParam->m_Children); - } + OrderContainer(&sIterator, nullptr, pParam.get(), bCurrentItem, bContentArea); + WidgetArray->insert(WidgetArray->end(), pParam->m_Children.begin(), + pParam->m_Children.end()); + sIterator.Reset(); bCurrentItem = false; bContentArea = false; - pParam->m_Children.RemoveAll(); - OrderContainer(&sIterator, nullptr, pParam, bCurrentItem, bContentArea, true); - if (pParam->m_Children.GetSize() > 0) { - WidgetArray.Append(pParam->m_Children); - } - delete pParam; + pParam->m_Children.clear(); + OrderContainer(&sIterator, nullptr, pParam.get(), bCurrentItem, bContentArea, + true); + WidgetArray->insert(WidgetArray->end(), pParam->m_Children.begin(), + pParam->m_Children.end()); } + CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget( CXFA_LayoutItem* pLayoutItem) { if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) { diff --git a/xfa/fxfa/app/xfa_ffpath.cpp b/xfa/fxfa/app/xfa_ffpath.cpp index c5c91a459..43016fe5c 100644 --- a/xfa/fxfa/app/xfa_ffpath.cpp +++ b/xfa/fxfa/app/xfa_ffpath.cpp @@ -14,9 +14,10 @@ #include "xfa/fxgraphics/cfx_color.h" #include "xfa/fxgraphics/cfx_path.h" -CXFA_FFLine::CXFA_FFLine(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) - : CXFA_FFDraw(pPageView, pDataAcc) {} +CXFA_FFLine::CXFA_FFLine(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {} + CXFA_FFLine::~CXFA_FFLine() {} + void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect, int32_t iHand, FX_FLOAT fLineWidth) { @@ -49,50 +50,48 @@ void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect, } } } + void CXFA_FFLine::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } + CXFA_Value value = m_pDataAcc->GetFormValue(); - if (!value) { + if (!value) return; - } + CXFA_Line lineObj = value.GetLine(); FX_ARGB lineColor = 0xFF000000; int32_t iStrokeType = 0; FX_FLOAT fLineWidth = 1.0f; - bool bSlope = lineObj.GetSlop(); int32_t iCap = 0; CXFA_Edge edge = lineObj.GetEdge(); if (edge) { - if (edge.GetPresence() != XFA_ATTRIBUTEENUM_Visible) { + if (edge.GetPresence() != XFA_ATTRIBUTEENUM_Visible) return; - } + lineColor = edge.GetColor(); iStrokeType = edge.GetStrokeType(); fLineWidth = edge.GetThickness(); iCap = edge.GetCapType(); } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } - CFX_RectF rtLine; - GetRectWithoutRotate(rtLine); - if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + + CFX_RectF rtLine = GetRectWithoutRotate(); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) XFA_RectWidthoutMargin(rtLine, mgWidget); - } + GetRectFromHand(rtLine, lineObj.GetHand(), fLineWidth); CFX_Path linePath; - linePath.Create(); - if (bSlope && rtLine.right() > 0.0f && rtLine.bottom() > 0.0f) { - linePath.AddLine(rtLine.right(), rtLine.top, rtLine.left, rtLine.bottom()); - } else { - linePath.AddLine(rtLine.left, rtLine.top, rtLine.right(), rtLine.bottom()); - } + if (lineObj.GetSlope() && rtLine.right() > 0.0f && rtLine.bottom() > 0.0f) + linePath.AddLine(rtLine.TopRight(), rtLine.BottomLeft()); + else + linePath.AddLine(rtLine.TopLeft(), rtLine.BottomRight()); + CFX_Color color(lineColor); pGS->SaveGraphState(); pGS->SetLineWidth(fLineWidth, true); @@ -102,56 +101,56 @@ void CXFA_FFLine::RenderWidget(CFX_Graphics* pGS, pGS->StrokePath(&linePath, &mtRotate); pGS->RestoreGraphState(); } -CXFA_FFArc::CXFA_FFArc(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) - : CXFA_FFDraw(pPageView, pDataAcc) {} + +CXFA_FFArc::CXFA_FFArc(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {} + CXFA_FFArc::~CXFA_FFArc() {} + void CXFA_FFArc::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } + CXFA_Value value = m_pDataAcc->GetFormValue(); - if (!value) { + if (!value) return; - } + CXFA_Arc arcObj = value.GetArc(); - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } - CFX_RectF rtArc; - GetRectWithoutRotate(rtArc); - if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + + CFX_RectF rtArc = GetRectWithoutRotate(); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) XFA_RectWidthoutMargin(rtArc, mgWidget); - } + DrawBorder(pGS, arcObj, rtArc, &mtRotate); } -CXFA_FFRectangle::CXFA_FFRectangle(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFDraw(pPageView, pDataAcc) {} + +CXFA_FFRectangle::CXFA_FFRectangle(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFDraw(pDataAcc) {} + CXFA_FFRectangle::~CXFA_FFRectangle() {} + void CXFA_FFRectangle::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } + CXFA_Value value = m_pDataAcc->GetFormValue(); - if (!value) { + if (!value) return; - } + CXFA_Rectangle rtObj = value.GetRectangle(); - CFX_RectF rect; - GetRectWithoutRotate(rect); - if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + CFX_RectF rect = GetRectWithoutRotate(); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) XFA_RectWidthoutMargin(rect, mgWidget); - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + DrawBorder(pGS, rtObj, rect, &mtRotate); } diff --git a/xfa/fxfa/app/xfa_ffpath.h b/xfa/fxfa/app/xfa_ffpath.h index 71c45e323..002f75d26 100644 --- a/xfa/fxfa/app/xfa_ffpath.h +++ b/xfa/fxfa/app/xfa_ffpath.h @@ -11,7 +11,7 @@ class CXFA_FFLine : public CXFA_FFDraw { public: - CXFA_FFLine(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFLine(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFLine() override; // CXFA_FFWidget @@ -22,9 +22,10 @@ class CXFA_FFLine : public CXFA_FFDraw { private: void GetRectFromHand(CFX_RectF& rect, int32_t iHand, FX_FLOAT fLineWidth); }; + class CXFA_FFArc : public CXFA_FFDraw { public: - CXFA_FFArc(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFArc(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFArc() override; // CXFA_FFWidget @@ -35,7 +36,7 @@ class CXFA_FFArc : public CXFA_FFDraw { class CXFA_FFRectangle : public CXFA_FFDraw { public: - CXFA_FFRectangle(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFRectangle(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFRectangle() override; // CXFA_FFWidget diff --git a/xfa/fxfa/app/xfa_ffpushbutton.cpp b/xfa/fxfa/app/xfa_ffpushbutton.cpp index 4d4d1aad2..7b6be8203 100644 --- a/xfa/fxfa/app/xfa_ffpushbutton.cpp +++ b/xfa/fxfa/app/xfa_ffpushbutton.cpp @@ -18,37 +18,37 @@ #include "xfa/fxgraphics/cfx_color.h" #include "xfa/fxgraphics/cfx_path.h" -CXFA_FFPushButton::CXFA_FFPushButton(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc), +CXFA_FFPushButton::CXFA_FFPushButton(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pRolloverTextLayout(nullptr), m_pDownTextLayout(nullptr), m_pDownProvider(nullptr), m_pRollProvider(nullptr), m_pOldDelegate(nullptr) {} + CXFA_FFPushButton::~CXFA_FFPushButton() { CXFA_FFPushButton::UnloadWidget(); } + void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); RenderHighlightCaption(pGS, &mtRotate); - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top); + + CFX_RectF rtWidget = GetRectWithoutRotate(); + CFX_Matrix mt(1, 0, 0, 1, rtWidget.left, rtWidget.top); mt.Concat(mtRotate); GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget, pGS, &mt); } + bool CXFA_FFPushButton::LoadWidget() { ASSERT(!m_pNormalWidget); CFWL_PushButton* pPushButton = new CFWL_PushButton(GetFWLApp()); @@ -99,22 +99,22 @@ void CXFA_FFPushButton::UnloadWidget() { bool CXFA_FFPushButton::PerformLayout() { CXFA_FFWidget::PerformLayout(); - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); + CFX_RectF rtWidget = GetRectWithoutRotate(); + m_rtUI = rtWidget; - if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) XFA_RectWidthoutMargin(rtWidget, mgWidget); - } + CXFA_Caption caption = m_pDataAcc->GetCaption(); - m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height); - if (CXFA_Margin mgCap = caption.GetMargin()) { + m_rtCaption = rtWidget; + if (CXFA_Margin mgCap = caption.GetMargin()) XFA_RectWidthoutMargin(m_rtCaption, mgCap); - } + LayoutHighlightCaption(); SetFWLRect(); - if (m_pNormalWidget) { + if (m_pNormalWidget) m_pNormalWidget->Update(); - } + return true; } FX_FLOAT CXFA_FFPushButton::GetLineWidth() { @@ -169,35 +169,30 @@ void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix) { CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout(); CXFA_Caption caption = m_pDataAcc->GetCaption(); - if (caption && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) { - CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); - CFX_RectF rtClip = m_rtCaption; - rtClip.Intersect(rtWidget); - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top); - if (pMatrix) { - pMatrix->TransformRect(rtClip); - mt.Concat(*pMatrix); - } - { - uint32_t dwState = m_pNormalWidget->GetStates(); - if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) && - (dwState & FWL_STATE_PSB_Hovered)) { - if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) { - return; - } - } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) { - if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) { - return; - } - } - } - if (pCapTextLayout) { - pCapTextLayout->DrawString(pRenderDevice, mt, rtClip); - } + if (!caption || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) + return; + + CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); + CFX_RectF rtClip = m_rtCaption; + rtClip.Intersect(GetRectWithoutRotate()); + CFX_Matrix mt(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top); + if (pMatrix) { + pMatrix->TransformRect(rtClip); + mt.Concat(*pMatrix); + } + + uint32_t dwState = m_pNormalWidget->GetStates(); + if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) && + (dwState & FWL_STATE_PSB_Hovered)) { + if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) + return; + } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) { + if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) + return; } + + if (pCapTextLayout) + pCapTextLayout->DrawString(pRenderDevice, mt, rtClip); } void CXFA_FFPushButton::OnProcessMessage(CFWL_Message* pMessage) { @@ -214,14 +209,13 @@ void CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics, if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) { if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) { - CFX_RectF rtFill = m_pNormalWidget->GetWidgetRect(); - rtFill.left = rtFill.top = 0; + CFX_RectF rtFill(0, 0, m_pNormalWidget->GetWidgetRect().Size()); FX_FLOAT fLineWith = GetLineWidth(); rtFill.Deflate(fLineWith, fLineWith); CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255)); pGraphics->SetFillColor(&cr); + CFX_Path path; - path.Create(); path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height); pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix); } @@ -233,9 +227,8 @@ void CXFA_FFPushButton::OnDrawWidget(CFX_Graphics* pGraphics, CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255)); pGraphics->SetStrokeColor(&cr); pGraphics->SetLineWidth(fLineWidth); - CFX_Path path; - path.Create(); + CFX_Path path; CFX_RectF rect = m_pNormalWidget->GetWidgetRect(); path.AddRectangle(0, 0, rect.width, rect.height); pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix); diff --git a/xfa/fxfa/app/xfa_ffpushbutton.h b/xfa/fxfa/app/xfa_ffpushbutton.h index d5fe0b279..eb18ccb11 100644 --- a/xfa/fxfa/app/xfa_ffpushbutton.h +++ b/xfa/fxfa/app/xfa_ffpushbutton.h @@ -18,7 +18,7 @@ class CXFA_TextProvider; class CXFA_FFPushButton : public CXFA_FFField { public: - CXFA_FFPushButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFPushButton(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFPushButton() override; // CXFA_FFField diff --git a/xfa/fxfa/app/xfa_ffsignature.cpp b/xfa/fxfa/app/xfa_ffsignature.cpp index 7b8da0cea..bf2bba3ad 100644 --- a/xfa/fxfa/app/xfa_ffsignature.cpp +++ b/xfa/fxfa/app/xfa_ffsignature.cpp @@ -11,25 +11,27 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFSignature::CXFA_FFSignature(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc) {} +CXFA_FFSignature::CXFA_FFSignature(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc) {} + CXFA_FFSignature::~CXFA_FFSignature() {} + bool CXFA_FFSignature::LoadWidget() { return CXFA_FFField::LoadWidget(); } + void CXFA_FFSignature::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) mtRotate.Concat(*pMatrix); - } + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); + CXFA_Border borderUI = m_pDataAcc->GetUIBorder(); DrawBorder(pGS, borderUI, m_rtUI, &mtRotate); RenderCaption(pGS, &mtRotate); @@ -39,68 +41,74 @@ void CXFA_FFSignature::RenderWidget(CFX_Graphics* pGS, bool CXFA_FFSignature::OnMouseEnter() { return false; } + bool CXFA_FFSignature::OnMouseExit() { return false; } + bool CXFA_FFSignature::OnLButtonDown(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { return false; } -bool CXFA_FFSignature::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFSignature::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) { return false; } + bool CXFA_FFSignature::OnLButtonDblClk(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { return false; } -bool CXFA_FFSignature::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFSignature::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) { return false; } + bool CXFA_FFSignature::OnMouseWheel(uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { return false; } + bool CXFA_FFSignature::OnRButtonDown(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { return false; } -bool CXFA_FFSignature::OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFSignature::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) { return false; } + bool CXFA_FFSignature::OnRButtonDblClk(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { return false; } + bool CXFA_FFSignature::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) { return false; } + bool CXFA_FFSignature::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) { return false; } + bool CXFA_FFSignature::OnChar(uint32_t dwChar, uint32_t dwFlags) { return false; } -FWL_WidgetHit CXFA_FFSignature::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) { - if (m_pNormalWidget) { - FX_FLOAT ffx = fx, ffy = fy; - FWLToClient(ffx, ffy); - if (m_pNormalWidget->HitTest(ffx, ffy) != FWL_WidgetHit::Unknown) - return FWL_WidgetHit::Client; + +FWL_WidgetHit CXFA_FFSignature::OnHitTest(const CFX_PointF& point) { + if (m_pNormalWidget && + m_pNormalWidget->HitTest(FWLToClient(point)) != FWL_WidgetHit::Unknown) { + return FWL_WidgetHit::Client; } - CFX_RectF rtBox; - GetRectWithoutRotate(rtBox); - if (!rtBox.Contains(fx, fy)) + + if (!GetRectWithoutRotate().Contains(point)) return FWL_WidgetHit::Unknown; - if (m_rtCaption.Contains(fx, fy)) + if (m_rtCaption.Contains(point)) return FWL_WidgetHit::Titlebar; return FWL_WidgetHit::Client; } -bool CXFA_FFSignature::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFSignature::OnSetCursor(const CFX_PointF& point) { return false; } diff --git a/xfa/fxfa/app/xfa_ffsignature.h b/xfa/fxfa/app/xfa_ffsignature.h index 28053b758..934323f43 100644 --- a/xfa/fxfa/app/xfa_ffsignature.h +++ b/xfa/fxfa/app/xfa_ffsignature.h @@ -11,7 +11,7 @@ class CXFA_FFSignature final : public CXFA_FFField { public: - CXFA_FFSignature(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFSignature(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFSignature() override; // CXFA_FFField @@ -21,23 +21,22 @@ class CXFA_FFSignature final : public CXFA_FFField { bool LoadWidget() override; bool OnMouseEnter() override; bool OnMouseExit() override; - bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnLButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) override; bool OnMouseWheel(uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy) override; - bool OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + const CFX_PointF& pointy) override; + bool OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) override; bool OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) override; bool OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) override; bool OnChar(uint32_t dwChar, uint32_t dwFlags) override; - FWL_WidgetHit OnHitTest(FX_FLOAT fx, FX_FLOAT fy) override; - bool OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) override; + FWL_WidgetHit OnHitTest(const CFX_PointF& point) override; + bool OnSetCursor(const CFX_PointF& point) override; }; #endif // XFA_FXFA_APP_XFA_FFSIGNATURE_H_ diff --git a/xfa/fxfa/app/xfa_ffsubform.cpp b/xfa/fxfa/app/xfa_ffsubform.cpp index 38c21fbb6..0b479f4d4 100644 --- a/xfa/fxfa/app/xfa_ffsubform.cpp +++ b/xfa/fxfa/app/xfa_ffsubform.cpp @@ -11,7 +11,7 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFSubForm::CXFA_FFSubForm(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFWidget(pPageView, pDataAcc) {} +CXFA_FFSubForm::CXFA_FFSubForm(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFWidget(pDataAcc) {} + CXFA_FFSubForm::~CXFA_FFSubForm() {} diff --git a/xfa/fxfa/app/xfa_ffsubform.h b/xfa/fxfa/app/xfa_ffsubform.h index 98ce739b1..e6b77a8b3 100644 --- a/xfa/fxfa/app/xfa_ffsubform.h +++ b/xfa/fxfa/app/xfa_ffsubform.h @@ -12,7 +12,7 @@ class CXFA_FFSubForm : public CXFA_FFWidget { public: - CXFA_FFSubForm(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFSubForm(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFSubForm() override; }; diff --git a/xfa/fxfa/app/xfa_fftext.cpp b/xfa/fxfa/app/xfa_fftext.cpp index 3d2c9a6ea..e8d7aa32d 100644 --- a/xfa/fxfa/app/xfa_fftext.cpp +++ b/xfa/fxfa/app/xfa_fftext.cpp @@ -19,52 +19,55 @@ #include "xfa/fxfa/xfa_ffwidget.h" #include "xfa/fxgraphics/cfx_graphics.h" -CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc) - : CXFA_FFDraw(pPageView, pDataAcc) {} +CXFA_FFText::CXFA_FFText(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {} + CXFA_FFText::~CXFA_FFText() {} + void CXFA_FFText::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } - { - CFX_Matrix mtRotate; - GetRotateMatrix(mtRotate); - if (pMatrix) { - mtRotate.Concat(*pMatrix); - } - CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); - CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); - if (pTextLayout) { - CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); - CFX_RectF rtText; - GetRectWithoutRotate(rtText); - if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { - CXFA_LayoutItem* pItem = this; - if (!pItem->GetPrev() && !pItem->GetNext()) { - XFA_RectWidthoutMargin(rtText, mgWidget); - } else { - FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0; - mgWidget.GetLeftInset(fLeftInset); - mgWidget.GetRightInset(fRightInset); - if (!pItem->GetPrev()) { - mgWidget.GetTopInset(fTopInset); - } else if (!pItem->GetNext()) { - mgWidget.GetBottomInset(fBottomInset); - } - rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset); - } - } - CFX_Matrix mt; - mt.Set(1, 0, 0, 1, rtText.left, rtText.top); - CFX_RectF rtClip = rtText; - mtRotate.TransformRect(rtClip); - mt.Concat(mtRotate); - pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex()); + + CFX_Matrix mtRotate = GetRotateMatrix(); + if (pMatrix) + mtRotate.Concat(*pMatrix); + + CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus); + + CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); + if (!pTextLayout) + return; + + CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); + CFX_RectF rtText = GetRectWithoutRotate(); + if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { + CXFA_LayoutItem* pItem = this; + if (!pItem->GetPrev() && !pItem->GetNext()) { + XFA_RectWidthoutMargin(rtText, mgWidget); + } else { + FX_FLOAT fLeftInset; + FX_FLOAT fRightInset; + FX_FLOAT fTopInset = 0; + FX_FLOAT fBottomInset = 0; + mgWidget.GetLeftInset(fLeftInset); + mgWidget.GetRightInset(fRightInset); + if (!pItem->GetPrev()) + mgWidget.GetTopInset(fTopInset); + else if (!pItem->GetNext()) + mgWidget.GetBottomInset(fBottomInset); + + rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset); } } + + CFX_Matrix mt(1, 0, 0, 1, rtText.left, rtText.top); + CFX_RectF rtClip = rtText; + mtRotate.TransformRect(rtClip); + mt.Concat(mtRotate); + pTextLayout->DrawString(pRenderDevice, mt, rtClip, GetIndex()); } + bool CXFA_FFText::IsLoaded() { CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); return pTextLayout && !pTextLayout->m_bHasBlock; @@ -85,8 +88,7 @@ bool CXFA_FFText::PerformLayout() { } pItem = pItem->GetFirst(); while (pItem) { - CFX_RectF rtText; - pItem->GetRect(rtText); + CFX_RectF rtText = pItem->GetRect(false); if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) { if (!pItem->GetPrev()) { FX_FLOAT fTopInset; @@ -104,73 +106,58 @@ bool CXFA_FFText::PerformLayout() { pTextLayout->m_bHasBlock = false; return true; } -bool CXFA_FFText::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rtBox; - GetRectWithoutRotate(rtBox); - if (!rtBox.Contains(fx, fy)) { + +bool CXFA_FFText::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) { + if (!GetRectWithoutRotate().Contains(point)) return false; - } - const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy); - if (!wsURLContent) { + + const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(point); + if (!wsURLContent) return false; - } + SetButtonDown(true); return true; } -bool CXFA_FFText::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rtBox; - GetRectWithoutRotate(rtBox); - if (!rtBox.Contains(fx, fy)) { - return false; - } - const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy); - if (!wsURLContent) { - return false; - } - return true; + +bool CXFA_FFText::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) { + return GetRectWithoutRotate().Contains(point) && !!GetLinkURLAtPoint(point); } -bool CXFA_FFText::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!IsButtonDown()) { + +bool CXFA_FFText::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) { + if (!IsButtonDown()) return false; - } + SetButtonDown(false); - const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(fx, fy); - if (!wsURLContent) { + const FX_WCHAR* wsURLContent = GetLinkURLAtPoint(point); + if (!wsURLContent) return false; - } + CXFA_FFDoc* pDoc = GetDoc(); pDoc->GetDocEnvironment()->GotoURL(pDoc, wsURLContent); return true; } -FWL_WidgetHit CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rtBox; - GetRectWithoutRotate(rtBox); - if (!rtBox.Contains(fx, fy)) + +FWL_WidgetHit CXFA_FFText::OnHitTest(const CFX_PointF& point) { + if (!GetRectWithoutRotate().Contains(point)) return FWL_WidgetHit::Unknown; - if (!GetLinkURLAtPoint(fx, fy)) + if (!GetLinkURLAtPoint(point)) return FWL_WidgetHit::Unknown; return FWL_WidgetHit::HyperLink; } -const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy) { + +const FX_WCHAR* CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) { CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout(); if (!pTextLayout) return nullptr; - FX_FLOAT x(fx); - FX_FLOAT y(fy); - FWLToClient(x, y); - + CFX_RectF rect = GetRectWithoutRotate(); for (const auto& pPieceLine : *pTextLayout->GetPieceLines()) { for (const auto& pPiece : pPieceLine->m_textPieces) { - if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) + if (pPiece->pLinkData && + pPiece->rtPiece.Contains(point - rect.TopLeft())) { return pPiece->pLinkData->GetLinkURL(); + } } } return nullptr; } -void CXFA_FFText::FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy) { - CFX_RectF rtWidget; - GetRectWithoutRotate(rtWidget); - fx -= rtWidget.left; - fy -= rtWidget.top; -} diff --git a/xfa/fxfa/app/xfa_fftext.h b/xfa/fxfa/app/xfa_fftext.h index 71f36e276..c55382179 100644 --- a/xfa/fxfa/app/xfa_fftext.h +++ b/xfa/fxfa/app/xfa_fftext.h @@ -11,14 +11,14 @@ class CXFA_FFText : public CXFA_FFDraw { public: - CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFText(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFText() override; // CXFA_FFWidget - bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - FWL_WidgetHit OnHitTest(FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) override; + FWL_WidgetHit OnHitTest(const CFX_PointF& point) override; void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) override; @@ -26,8 +26,7 @@ class CXFA_FFText : public CXFA_FFDraw { bool PerformLayout() override; private: - const FX_WCHAR* GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy); - void FWLToClient(FX_FLOAT& fx, FX_FLOAT& fy); + const FX_WCHAR* GetLinkURLAtPoint(const CFX_PointF& point); }; #endif // XFA_FXFA_APP_XFA_FFTEXT_H_ diff --git a/xfa/fxfa/app/xfa_fftextedit.cpp b/xfa/fxfa/app/xfa_fftextedit.cpp index 1088afdb6..094839f48 100644 --- a/xfa/fxfa/app/xfa_fftextedit.cpp +++ b/xfa/fxfa/app/xfa_fftextedit.cpp @@ -28,9 +28,8 @@ #include "xfa/fxfa/xfa_ffpageview.h" #include "xfa/fxfa/xfa_ffwidget.h" -CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFField(pPageView, pDataAcc), m_pOldDelegate(nullptr) {} +CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFField(pDataAcc), m_pOldDelegate(nullptr) {} CXFA_FFTextEdit::~CXFA_FFTextEdit() { if (m_pNormalWidget) { @@ -104,58 +103,53 @@ void CXFA_FFTextEdit::UpdateWidgetProperty() { m_pNormalWidget->ModifyStyles(dwStyle, 0xFFFFFFFF); m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); } -bool CXFA_FFTextEdit::OnLButtonDown(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - if (!PtInActiveRect(fx, fy)) { + +bool CXFA_FFTextEdit::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) { + if (!PtInActiveRect(point)) return false; - } if (!IsFocused()) { m_dwStatus |= XFA_WidgetStatus_Focused; UpdateFWLData(); AddInvalidateRect(); } + SetButtonDown(true); CFWL_MessageMouse ms(nullptr, m_pNormalWidget); ms.m_dwCmd = FWL_MouseCommand::LeftButtonDown; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFTextEdit::OnRButtonDown(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) { + +bool CXFA_FFTextEdit::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) { + if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) return false; - } - if (!PtInActiveRect(fx, fy)) { + if (!PtInActiveRect(point)) return false; - } if (!IsFocused()) { m_dwStatus |= XFA_WidgetStatus_Focused; UpdateFWLData(); AddInvalidateRect(); } + SetButtonDown(true); CFWL_MessageMouse ms(nullptr, nullptr); ms.m_dwCmd = FWL_MouseCommand::RightButtonDown; ms.m_dwFlags = dwFlags; - ms.m_fx = fx; - ms.m_fy = fy; - FWLToClient(ms.m_fx, ms.m_fy); + ms.m_pos = FWLToClient(point); TranslateFWLMessage(&ms); return true; } -bool CXFA_FFTextEdit::OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { - if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy)) + +bool CXFA_FFTextEdit::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) { + if (!CXFA_FFField::OnRButtonUp(dwFlags, point)) return false; - GetDoc()->GetDocEnvironment()->PopupMenu(this, CFX_PointF(fx, fy)); + GetDoc()->GetDocEnvironment()->PopupMenu(this, point); return true; } + bool CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget) { m_dwStatus &= ~XFA_WidgetStatus_TextEditValueChanged; if (!IsFocused()) { @@ -360,10 +354,11 @@ void CXFA_FFTextEdit::OnDrawWidget(CFX_Graphics* pGraphics, m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix); } -CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFTextEdit(pPageView, pDataAcc) {} +CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFTextEdit(pDataAcc) {} + CXFA_FFNumericEdit::~CXFA_FFNumericEdit() {} + bool CXFA_FFNumericEdit::LoadWidget() { CFWL_Edit* pWidget = new CFWL_Edit( GetFWLApp(), pdfium::MakeUnique<CFWL_WidgetProperties>(), nullptr); @@ -437,9 +432,9 @@ bool CXFA_FFNumericEdit::OnValidate(CFWL_Widget* pWidget, return widgetValue.ValidateNumericTemp(wsText, wsFormat, m_pDataAcc->GetLocal()); } -CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFTextEdit(pPageView, pDataAcc) {} + +CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFTextEdit(pDataAcc) {} CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit() {} @@ -488,25 +483,22 @@ void CXFA_FFPasswordEdit::UpdateWidgetProperty() { dwExtendedStyle |= GetAlignment(); m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF); } -CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) - : CXFA_FFTextEdit(pPageView, pDataAcc) {} +CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_WidgetAcc* pDataAcc) + : CXFA_FFTextEdit(pDataAcc) {} CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit() {} -bool CXFA_FFDateTimeEdit::GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus) { +CFX_RectF CXFA_FFDateTimeEdit::GetBBox(uint32_t dwStatus, bool bDrawFocus) { if (bDrawFocus) - return false; - return CXFA_FFWidget::GetBBox(rtBox, dwStatus); + return CFX_RectF(); + return CXFA_FFWidget::GetBBox(dwStatus); } -bool CXFA_FFDateTimeEdit::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) { +bool CXFA_FFDateTimeEdit::PtInActiveRect(const CFX_PointF& point) { return m_pNormalWidget && static_cast<CFWL_DateTimePicker*>(m_pNormalWidget) ->GetBBox() - .Contains(fx, fy); + .Contains(point); } bool CXFA_FFDateTimeEdit::LoadWidget() { diff --git a/xfa/fxfa/app/xfa_fftextedit.h b/xfa/fxfa/app/xfa_fftextedit.h index 88622e3c5..1e0562a75 100644 --- a/xfa/fxfa/app/xfa_fftextedit.h +++ b/xfa/fxfa/app/xfa_fftextedit.h @@ -13,15 +13,15 @@ class CXFA_FFTextEdit : public CXFA_FFField { public: - CXFA_FFTextEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFTextEdit(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFTextEdit() override; // CXFA_FFField bool LoadWidget() override; void UpdateWidgetProperty() override; - bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; - bool OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) override; + bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) override; + bool OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) override; bool OnSetFocus(CXFA_FFWidget* pOldWidget) override; bool OnKillFocus(CXFA_FFWidget* pNewWidget) override; void OnProcessMessage(CFWL_Message* pMessage) override; @@ -48,7 +48,7 @@ class CXFA_FFTextEdit : public CXFA_FFField { class CXFA_FFNumericEdit : public CXFA_FFTextEdit { public: - CXFA_FFNumericEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFNumericEdit(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFNumericEdit() override; // CXFA_FFTextEdit @@ -62,7 +62,7 @@ class CXFA_FFNumericEdit : public CXFA_FFTextEdit { class CXFA_FFPasswordEdit : public CXFA_FFTextEdit { public: - CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFPasswordEdit(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFPasswordEdit() override; // CXFA_FFTextEdit @@ -80,13 +80,11 @@ enum XFA_DATETIMETYPE { class CXFA_FFDateTimeEdit : public CXFA_FFTextEdit { public: - CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFDateTimeEdit(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFDateTimeEdit() override; // CXFA_FFTextEdit - bool GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus = false) override; + CFX_RectF GetBBox(uint32_t dwStatus, bool bDrawFocus = false) override; bool LoadWidget() override; void UpdateWidgetProperty() override; void OnProcessEvent(CFWL_Event* pEvent) override; @@ -97,7 +95,7 @@ class CXFA_FFDateTimeEdit : public CXFA_FFTextEdit { int32_t iDay); protected: - bool PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) override; + bool PtInActiveRect(const CFX_PointF& point) override; bool CommitData() override; bool UpdateFWLData() override; bool IsDataChanged() override; diff --git a/xfa/fxfa/app/xfa_ffwidget.cpp b/xfa/fxfa/app/xfa_ffwidget.cpp index 64aed4f32..9995fd11b 100644 --- a/xfa/fxfa/app/xfa_ffwidget.cpp +++ b/xfa/fxfa/app/xfa_ffwidget.cpp @@ -32,39 +32,31 @@ #include "xfa/fxgraphics/cfx_pattern.h" #include "xfa/fxgraphics/cfx_shading.h" -CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView, - CXFA_WidgetAcc* pDataAcc) +CXFA_FFWidget::CXFA_FFWidget(CXFA_WidgetAcc* pDataAcc) : CXFA_ContentLayoutItem(pDataAcc->GetNode()), - m_pPageView(pPageView), - m_pDataAcc(pDataAcc) { - m_rtWidget.Set(0, 0, 0, 0); -} + m_pPageView(nullptr), + m_pDataAcc(pDataAcc) {} + CXFA_FFWidget::~CXFA_FFWidget() {} -CXFA_FFPageView* CXFA_FFWidget::GetPageView() { - return m_pPageView; -} -void CXFA_FFWidget::SetPageView(CXFA_FFPageView* pPageView) { - m_pPageView = pPageView; -} const CFWL_App* CXFA_FFWidget::GetFWLApp() { return GetPageView()->GetDocView()->GetDoc()->GetApp()->GetFWLApp(); } -void CXFA_FFWidget::GetWidgetRect(CFX_RectF& rtWidget) { - if ((m_dwStatus & XFA_WidgetStatus_RectCached) == 0) { - m_dwStatus |= XFA_WidgetStatus_RectCached; - GetRect(m_rtWidget); - } - rtWidget = m_rtWidget; +CFX_RectF CXFA_FFWidget::GetWidgetRect() { + if ((m_dwStatus & XFA_WidgetStatus_RectCached) == 0) + RecacheWidgetRect(); + return m_rtWidget; } -CFX_RectF CXFA_FFWidget::ReCacheWidgetRect() { + +CFX_RectF CXFA_FFWidget::RecacheWidgetRect() { m_dwStatus |= XFA_WidgetStatus_RectCached; - GetRect(m_rtWidget); + m_rtWidget = GetRect(false); return m_rtWidget; } -void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) { - GetWidgetRect(rtWidget); + +CFX_RectF CXFA_FFWidget::GetRectWithoutRotate() { + CFX_RectF rtWidget = GetWidgetRect(); FX_FLOAT fValue = 0; switch (m_pDataAcc->GetRotate()) { case 90: @@ -84,7 +76,9 @@ void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) { rtWidget.height = fValue; break; } + return rtWidget; } + uint32_t CXFA_FFWidget::GetStatus() { return m_dwStatus; } @@ -93,14 +87,10 @@ void CXFA_FFWidget::ModifyStatus(uint32_t dwAdded, uint32_t dwRemoved) { m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded; } -bool CXFA_FFWidget::GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus) { - if (bDrawFocus) - return false; - if (m_pPageView) - m_pPageView->GetPageViewRect(rtBox); - return true; +CFX_RectF CXFA_FFWidget::GetBBox(uint32_t dwStatus, bool bDrawFocus) { + if (bDrawFocus || !m_pPageView) + return CFX_RectF(); + return m_pPageView->GetPageViewRect(); } CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc() { @@ -115,24 +105,26 @@ bool CXFA_FFWidget::GetToolTip(CFX_WideString& wsToolTip) { } return GetCaptionText(wsToolTip); } + void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus) { - if (!IsMatchVisibleStatus(dwStatus)) { + if (!IsMatchVisibleStatus(dwStatus)) return; - } + CXFA_Border border = m_pDataAcc->GetBorder(); - if (border) { - CFX_RectF rtBorder; - GetRectWithoutRotate(rtBorder); - CXFA_Margin margin = border.GetMargin(); - if (margin) { - XFA_RectWidthoutMargin(rtBorder, margin); - } - rtBorder.Normalize(); - DrawBorder(pGS, border, rtBorder, pMatrix); - } + if (!border) + return; + + CFX_RectF rtBorder = GetRectWithoutRotate(); + CXFA_Margin margin = border.GetMargin(); + if (margin) + XFA_RectWidthoutMargin(rtBorder, margin); + + rtBorder.Normalize(); + DrawBorder(pGS, border, rtBorder, pMatrix); } + bool CXFA_FFWidget::IsLoaded() { return !!m_pPageView; } @@ -142,7 +134,7 @@ bool CXFA_FFWidget::LoadWidget() { } void CXFA_FFWidget::UnloadWidget() {} bool CXFA_FFWidget::PerformLayout() { - ReCacheWidgetRect(); + RecacheWidgetRect(); return true; } bool CXFA_FFWidget::UpdateFWLData() { @@ -156,28 +148,31 @@ void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS, uint32_t dwFlags) { XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags); } + void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect) { - if (!pRect) { - CFX_RectF rtWidget; - GetBBox(rtWidget, XFA_WidgetStatus_Focused); - rtWidget.Inflate(2, 2); - GetDoc()->GetDocEnvironment()->InvalidateRect(m_pPageView, rtWidget, - XFA_INVALIDATE_CurrentPage); - } else { + if (pRect) { GetDoc()->GetDocEnvironment()->InvalidateRect(m_pPageView, *pRect, XFA_INVALIDATE_CurrentPage); + return; } + + CFX_RectF rtWidget = GetBBox(XFA_WidgetStatus_Focused); + rtWidget.Inflate(2, 2); + GetDoc()->GetDocEnvironment()->InvalidateRect(m_pPageView, rtWidget, + XFA_INVALIDATE_CurrentPage); } + void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect) { CFX_RectF rtWidget; if (pRect) { rtWidget = *pRect; } else { - GetBBox(rtWidget, XFA_WidgetStatus_Focused); + rtWidget = GetBBox(XFA_WidgetStatus_Focused); rtWidget.Inflate(2, 2); } m_pDocView->AddInvalidateRect(m_pPageView, rtWidget); } + bool CXFA_FFWidget::GetCaptionText(CFX_WideString& wsCap) { CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout(); if (!pCapTextlayout) { @@ -194,38 +189,42 @@ bool CXFA_FFWidget::IsFocused() { bool CXFA_FFWidget::OnMouseEnter() { return false; } + bool CXFA_FFWidget::OnMouseExit() { return false; } -bool CXFA_FFWidget::OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFWidget::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) { return false; } -bool CXFA_FFWidget::OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFWidget::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) { return false; } -bool CXFA_FFWidget::OnLButtonDblClk(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + +bool CXFA_FFWidget::OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) { return false; } -bool CXFA_FFWidget::OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFWidget::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) { return false; } + bool CXFA_FFWidget::OnMouseWheel(uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { return false; } -bool CXFA_FFWidget::OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFWidget::OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point) { return false; } -bool CXFA_FFWidget::OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFWidget::OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point) { return false; } -bool CXFA_FFWidget::OnRButtonDblClk(uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + +bool CXFA_FFWidget::OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point) { return false; } @@ -241,6 +240,7 @@ bool CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) { m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam); return true; } + bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) { m_dwStatus &= ~XFA_WidgetStatus_Focused; EventKillFocus(); @@ -252,57 +252,75 @@ bool CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) { } return true; } + bool CXFA_FFWidget::OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags) { return false; } + bool CXFA_FFWidget::OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags) { return false; } + bool CXFA_FFWidget::OnChar(uint32_t dwChar, uint32_t dwFlags) { return false; } -FWL_WidgetHit CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) { + +FWL_WidgetHit CXFA_FFWidget::OnHitTest(const CFX_PointF& point) { return FWL_WidgetHit::Unknown; } -bool CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) { + +bool CXFA_FFWidget::OnSetCursor(const CFX_PointF& point) { return false; } + bool CXFA_FFWidget::CanUndo() { return false; } + bool CXFA_FFWidget::CanRedo() { return false; } + bool CXFA_FFWidget::Undo() { return false; } + bool CXFA_FFWidget::Redo() { return false; } + bool CXFA_FFWidget::CanCopy() { return false; } + bool CXFA_FFWidget::CanCut() { return false; } + bool CXFA_FFWidget::CanPaste() { return false; } + bool CXFA_FFWidget::CanSelectAll() { return false; } + bool CXFA_FFWidget::CanDelete() { return CanCut(); } + bool CXFA_FFWidget::CanDeSelect() { return CanCopy(); } + bool CXFA_FFWidget::Copy(CFX_WideString& wsCopy) { return false; } + bool CXFA_FFWidget::Cut(CFX_WideString& wsCut) { return false; } + bool CXFA_FFWidget::Paste(const CFX_WideString& wsPaste) { return false; } @@ -321,16 +339,17 @@ bool CXFA_FFWidget::ReplaceSpellCheckWord(CFX_PointF pointf, const CFX_ByteStringC& bsReplace) { return false; } -void CXFA_FFWidget::Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy) { - CFX_Matrix mt; - GetRotateMatrix(mt); - if (mt.IsIdentity()) { - return; - } + +CFX_PointF CXFA_FFWidget::Rotate2Normal(const CFX_PointF& point) { + CFX_Matrix mt = GetRotateMatrix(); + if (mt.IsIdentity()) + return point; + CFX_Matrix mtReverse; mtReverse.SetReverse(mt); - mtReverse.TransformPoint(fx, fy); + return mtReverse.Transform(point); } + static void XFA_GetMatrix(CFX_Matrix& m, int32_t iRotate, XFA_ATTRIBUTEENUM at, @@ -387,20 +406,22 @@ static void XFA_GetMatrix(CFX_Matrix& m, break; } } -void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix& mt) { - mt.Set(1, 0, 0, 1, 0, 0); + +CFX_Matrix CXFA_FFWidget::GetRotateMatrix() { + CFX_Matrix mt; int32_t iRotate = m_pDataAcc->GetRotate(); - if (!iRotate) { - return; - } - CFX_RectF rcWidget; - GetRectWithoutRotate(rcWidget); + if (!iRotate) + return mt; + + CFX_RectF rcWidget = GetRectWithoutRotate(); XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft; XFA_GetMatrix(mt, iRotate, at, rcWidget); + + return mt; } + bool CXFA_FFWidget::IsLayoutRectEmpty() { - CFX_RectF rtLayout; - GetRectWithoutRotate(rtLayout); + CFX_RectF rtLayout = GetRectWithoutRotate(); return rtLayout.width < 0.1f && rtLayout.height < 0.1f; } CXFA_FFWidget* CXFA_FFWidget::GetParent() { @@ -415,63 +436,45 @@ CXFA_FFWidget* CXFA_FFWidget::GetParent() { } return nullptr; } + bool CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) { - if (!pWidget) { + if (!pWidget) return false; - } + CXFA_Node* pNode = m_pDataAcc->GetNode(); CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode(); while (pChildNode) { - if (pChildNode == pNode) { + if (pChildNode == pNode) return true; - } + pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent); } return false; } -bool CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) { - CFX_RectF rtWidget; - GetWidgetRect(rtWidget); - if (rtWidget.Contains(fx, fy)) { - return true; - } - return false; + +bool CXFA_FFWidget::PtInActiveRect(const CFX_PointF& point) { + return GetWidgetRect().Contains(point); } + CXFA_FFDocView* CXFA_FFWidget::GetDocView() { return m_pDocView; } + void CXFA_FFWidget::SetDocView(CXFA_FFDocView* pDocView) { m_pDocView = pDocView; } + CXFA_FFDoc* CXFA_FFWidget::GetDoc() { return m_pDocView->GetDoc(); } + CXFA_FFApp* CXFA_FFWidget::GetApp() { return GetDoc()->GetApp(); } + IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() { return GetApp()->GetAppProvider(); } -void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth) { - fMinWidth = fMaxWidth = 0; - FX_FLOAT fWidth = 0; - if (m_pDataAcc->GetWidth(fWidth)) { - fMinWidth = fMaxWidth = fWidth; - } else { - m_pDataAcc->GetMinWidth(fMinWidth); - m_pDataAcc->GetMaxWidth(fMaxWidth); - } -} -void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight) { - fMinHeight = fMaxHeight = 0; - FX_FLOAT fHeight = 0; - if (m_pDataAcc->GetHeight(fHeight)) { - fMinHeight = fMaxHeight = fHeight; - } else { - m_pDataAcc->GetMinHeight(fMinHeight); - m_pDataAcc->GetMaxHeight(fMaxHeight); - } -} bool CXFA_FFWidget::IsMatchVisibleStatus(uint32_t dwStatus) { return !!(m_dwStatus & XFA_WidgetStatus_Visible); @@ -839,18 +842,15 @@ void XFA_DrawImage(CFX_Graphics* pGS, int32_t iImageYDpi, int32_t iHorzAlign, int32_t iVertAlign) { - if (rtImage.IsEmpty()) { + if (rtImage.IsEmpty()) return; - } - if (!pDIBitmap || !pDIBitmap->GetBuffer()) { + if (!pDIBitmap || !pDIBitmap->GetBuffer()) return; - } - FX_FLOAT fWidth = - XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi); - FX_FLOAT fHeight = - XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi); - CFX_RectF rtFit; - rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight); + + CFX_RectF rtFit( + rtImage.TopLeft(), + XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi), + XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi)); switch (iAspect) { case XFA_ATTRIBUTEENUM_Fit: { FX_FLOAT f1 = rtImage.height / rtFit.height; @@ -888,18 +888,22 @@ void XFA_DrawImage(CFX_Graphics* pGS, } CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice(); pRenderDevice->SaveState(); + CFX_PathData path; path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top); pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING); + CFX_Matrix mtImage(1, 0, 0, -1, 0, 1); - mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top); + mtImage.Concat( + CFX_Matrix(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top)); mtImage.Concat(*pMatrix); + CXFA_ImageRenderer imageRender; bool bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage, FXDIB_INTERPOL); - while (bRet) { + while (bRet) bRet = imageRender.Continue(nullptr); - } + pRenderDevice->RestoreState(false); } @@ -1020,21 +1024,16 @@ FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len) { FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideString& wsType) { CFX_WideString wsContentType(wsType); wsContentType.MakeLower(); - if (wsContentType == FX_WSTRC(L"image/jpg")) { + if (wsContentType == L"image/jpg") return FXCODEC_IMAGE_JPG; - } - if (wsContentType == FX_WSTRC(L"image/png")) { + if (wsContentType == L"image/png") return FXCODEC_IMAGE_PNG; - } - if (wsContentType == FX_WSTRC(L"image/gif")) { + if (wsContentType == L"image/gif") return FXCODEC_IMAGE_GIF; - } - if (wsContentType == FX_WSTRC(L"image/bmp")) { + if (wsContentType == L"image/bmp") return FXCODEC_IMAGE_BMP; - } - if (wsContentType == FX_WSTRC(L"image/tif")) { + if (wsContentType == L"image/tif") return FXCODEC_IMAGE_TIF; - } return FXCODEC_IMAGE_UNKNOWN; } CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc, @@ -1073,8 +1072,7 @@ CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc, } } else { CFX_WideString wsURL = wsHref; - if (wsURL.Left(7) != FX_WSTRC(L"http://") && - wsURL.Left(6) != FX_WSTRC(L"ftp://")) { + if (wsURL.Left(7) != L"http://" && wsURL.Left(6) != L"ftp://") { CFX_DIBitmap* pBitmap = pDoc->GetPDFNamedImage(wsURL.AsStringC(), iImageXDpi, iImageYDpi); if (pBitmap) { @@ -1130,7 +1128,7 @@ CFX_DIBitmap* XFA_LoadImageFromBuffer( CFX_DIBAttribute dibAttr; CFX_DIBitmap* pBitmap = nullptr; - CCodec_ProgressiveDecoder* pProgressiveDecoder = + std::unique_ptr<CCodec_ProgressiveDecoder> pProgressiveDecoder = pCodecMgr->CreateProgressiveDecoder(); pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr, false); switch (dibAttr.m_wDPIUnit) { @@ -1166,9 +1164,9 @@ CFX_DIBitmap* XFA_LoadImageFromBuffer( pProgressiveDecoder->ContinueDecode(); } } - delete pProgressiveDecoder; return pBitmap; } + void XFA_RectWidthoutMargin(CFX_RectF& rt, const CXFA_Margin& mg, bool bUI) { if (!mg) { return; @@ -1213,11 +1211,11 @@ static void XFA_BOX_GetPath_Arc(CXFA_Box box, } startAngle = -startAngle * FX_PI / 180.0f; sweepAngle = -sweepAngle * FX_PI / 180.0f; - fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height, - startAngle, sweepAngle); + fillPath.AddArc(rtDraw.TopLeft(), rtDraw.Size(), startAngle, sweepAngle); } + static void XFA_BOX_GetPath(CXFA_Box box, - const CXFA_StrokeArray& strokes, + const std::vector<CXFA_Stroke>& strokes, CFX_RectF rtWidget, CFX_Path& path, int32_t nIndex, @@ -1338,54 +1336,55 @@ static void XFA_BOX_GetPath(CXFA_Box box, cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore, offsetEY = -halfAfter; } - vx = 1, vy = -1; - nx = 0, ny = 1; + vx = 1; + vy = -1; + nx = 0; + ny = 1; if (bRound) { sx = bInverted ? 0 : FX_PI / 2; } else { - sx = 0, sy = -1; + sx = 0; + sy = -1; } break; } if (bStart) { - path.MoveTo(cpStart.x, cpStart.y); + path.MoveTo(cpStart); } if (nIndex & 1) { - path.LineTo(cp2.x + fRadius2 * nx + offsetEX, - cp2.y + fRadius2 * ny + offsetEY); + path.LineTo(CFX_PointF(cp2.x + fRadius2 * nx + offsetEX, + cp2.y + fRadius2 * ny + offsetEY)); return; } if (bRound) { - if (fRadius1 < 0) { + if (fRadius1 < 0) sx -= FX_PI; - } - if (bInverted) { + if (bInverted) sy *= -1; - } - CFX_RectF rtRadius; - rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2, - fRadius1 * 2 * vx - offsetX * 2, - fRadius1 * 2 * vy - offsetY * 2); + + CFX_RectF rtRadius(cp1.x + offsetX * 2, cp1.y + offsetY * 2, + fRadius1 * 2 * vx - offsetX * 2, + fRadius1 * 2 * vy - offsetY * 2); rtRadius.Normalize(); - if (bInverted) { + if (bInverted) rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy); - } - path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx, - sy); + + path.ArcTo(rtRadius.TopLeft(), rtRadius.Size(), sx, sy); } else { CFX_PointF cp; if (bInverted) { - cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy; + cp.x = cp1.x + fRadius1 * vx; + cp.y = cp1.y + fRadius1 * vy; } else { cp = cp1; } - path.LineTo(cp.x, cp.y); - path.LineTo(cp1.x + fRadius1 * sx + offsetX, - cp1.y + fRadius1 * sy + offsetY); + path.LineTo(cp); + path.LineTo(CFX_PointF(cp1.x + fRadius1 * sx + offsetX, + cp1.y + fRadius1 * sy + offsetY)); } } static void XFA_BOX_GetFillPath(CXFA_Box box, - const CXFA_StrokeArray& strokes, + const std::vector<CXFA_Stroke>& strokes, CFX_RectF rtWidget, CFX_Path& fillPath, uint16_t dwFlags) { @@ -1501,39 +1500,38 @@ static void XFA_BOX_GetFillPath(CXFA_Box box, if (bRound) { sx = bInverted ? 0 : FX_PI / 2; } else { - sx = 0, sy = -1; + sx = 0; + sy = -1; } break; } - if (i == 0) { - fillPath.MoveTo(cp1.x, cp1.y + fRadius1); - } + if (i == 0) + fillPath.MoveTo(CFX_PointF(cp1.x, cp1.y + fRadius1)); + if (bRound) { - if (fRadius1 < 0) { + if (fRadius1 < 0) sx -= FX_PI; - } - if (bInverted) { + if (bInverted) sy *= -1; - } - CFX_RectF rtRadius; - rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy); + + CFX_RectF rtRadius(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy); rtRadius.Normalize(); - if (bInverted) { + if (bInverted) rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy); - } - fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, - rtRadius.height, sx, sy); + + fillPath.ArcTo(rtRadius.TopLeft(), rtRadius.Size(), sx, sy); } else { CFX_PointF cp; if (bInverted) { - cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy; + cp.x = cp1.x + fRadius1 * vx; + cp.y = cp1.y + fRadius1 * vy; } else { cp = cp1; } - fillPath.LineTo(cp.x, cp.y); - fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy); + fillPath.LineTo(cp); + fillPath.LineTo(CFX_PointF(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy)); } - fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny); + fillPath.LineTo(CFX_PointF(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny)); } } static void XFA_BOX_Fill_Radial(CXFA_Box box, @@ -1568,22 +1566,22 @@ static void XFA_BOX_Fill_Pattern(CXFA_Box box, FX_ARGB crStart, crEnd; crStart = fill.GetColor(); int32_t iType = fill.GetPattern(crEnd); - FX_HatchStyle iHatch = FX_HATCHSTYLE_Cross; + FX_HatchStyle iHatch = FX_HatchStyle::Cross; switch (iType) { case XFA_ATTRIBUTEENUM_CrossDiagonal: - iHatch = FX_HATCHSTYLE_DiagonalCross; + iHatch = FX_HatchStyle::DiagonalCross; break; case XFA_ATTRIBUTEENUM_DiagonalLeft: - iHatch = FX_HATCHSTYLE_ForwardDiagonal; + iHatch = FX_HatchStyle::ForwardDiagonal; break; case XFA_ATTRIBUTEENUM_DiagonalRight: - iHatch = FX_HATCHSTYLE_BackwardDiagonal; + iHatch = FX_HatchStyle::BackwardDiagonal; break; case XFA_ATTRIBUTEENUM_Horizontal: - iHatch = FX_HATCHSTYLE_Horizontal; + iHatch = FX_HatchStyle::Horizontal; break; case XFA_ATTRIBUTEENUM_Vertical: - iHatch = FX_HATCHSTYLE_Vertical; + iHatch = FX_HatchStyle::Vertical; break; default: break; @@ -1631,18 +1629,17 @@ static void XFA_BOX_Fill_Linear(CXFA_Box box, pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix); } static void XFA_BOX_Fill(CXFA_Box box, - const CXFA_StrokeArray& strokes, + const std::vector<CXFA_Stroke>& strokes, CFX_Graphics* pGS, const CFX_RectF& rtWidget, CFX_Matrix* pMatrix, uint32_t dwFlags) { CXFA_Fill fill = box.GetFill(); - if (!fill || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) { + if (!fill || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) return; - } + pGS->SaveGraphState(); CFX_Path fillPath; - fillPath.Create(); XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath, (dwFlags & XFA_DRAWBOX_ForceRound) != 0); fillPath.Close(); @@ -1731,54 +1728,61 @@ static void XFA_BOX_StrokeArc(CXFA_Box box, } if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 || (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) { - if (fHalf < 0.001f) { + if (fHalf < 0.001f) return; - } + CFX_Path arcPath; - arcPath.Create(); XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags); XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix); return; } pGS->SaveGraphState(); pGS->SetLineWidth(fHalf); + FX_FLOAT a, b; a = rtWidget.width / 2.0f; b = rtWidget.height / 2.0f; if (dwFlags & XFA_DRAWBOX_ForceRound) { - a = b = std::min(a, b); + a = std::min(a, b); + b = a; } + CFX_PointF center = rtWidget.Center(); rtWidget.left = center.x - a; rtWidget.top = center.y - b; rtWidget.width = a + a; rtWidget.height = b + b; + FX_FLOAT startAngle = 0, sweepAngle = 360; startAngle = startAngle * FX_PI / 180.0f; sweepAngle = -sweepAngle * FX_PI / 180.0f; + CFX_Path arcPath; - arcPath.Create(); - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, - 3.0f * FX_PI / 4.0f, FX_PI); + arcPath.AddArc(rtWidget.TopLeft(), rtWidget.Size(), 3.0f * FX_PI / 4.0f, + FX_PI); + CFX_Color cr(0xFF808080); pGS->SetStrokeColor(&cr); pGS->StrokePath(&arcPath, pMatrix); arcPath.Clear(); - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, - -1.0f * FX_PI / 4.0f, FX_PI); + arcPath.AddArc(rtWidget.TopLeft(), rtWidget.Size(), -1.0f * FX_PI / 4.0f, + FX_PI); + cr.Set(0xFFFFFFFF); pGS->SetStrokeColor(&cr); pGS->StrokePath(&arcPath, pMatrix); rtWidget.Deflate(fHalf, fHalf); arcPath.Clear(); - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, - 3.0f * FX_PI / 4.0f, FX_PI); + arcPath.AddArc(rtWidget.TopLeft(), rtWidget.Size(), 3.0f * FX_PI / 4.0f, + FX_PI); + cr.Set(0xFF404040); pGS->SetStrokeColor(&cr); pGS->StrokePath(&arcPath, pMatrix); arcPath.Clear(); - arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, - -1.0f * FX_PI / 4.0f, FX_PI); + arcPath.AddArc(rtWidget.TopLeft(), rtWidget.Size(), -1.0f * FX_PI / 4.0f, + FX_PI); + cr.Set(0xFFC0C0C0); pGS->SetStrokeColor(&cr); pGS->StrokePath(&arcPath, pMatrix); @@ -1795,26 +1799,26 @@ static void XFA_Draw3DRect(CFX_Graphics* pGraphic, FX_FLOAT fBottom = rt.bottom(); FX_FLOAT fRight = rt.right(); CFX_Path pathLT; - pathLT.Create(); - pathLT.MoveTo(rt.left, fBottom); - pathLT.LineTo(rt.left, rt.top); - pathLT.LineTo(fRight, rt.top); - pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth); - pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth); - pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth); - pathLT.LineTo(rt.left, fBottom); + pathLT.MoveTo(CFX_PointF(rt.left, fBottom)); + pathLT.LineTo(CFX_PointF(rt.left, rt.top)); + pathLT.LineTo(CFX_PointF(fRight, rt.top)); + pathLT.LineTo(CFX_PointF(fRight - fLineWidth, rt.top + fLineWidth)); + pathLT.LineTo(CFX_PointF(rt.left + fLineWidth, rt.top + fLineWidth)); + pathLT.LineTo(CFX_PointF(rt.left + fLineWidth, fBottom - fLineWidth)); + pathLT.LineTo(CFX_PointF(rt.left, fBottom)); pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix); + CFX_Color crRB(argbBottomRight); pGraphic->SetFillColor(&crRB); + CFX_Path pathRB; - pathRB.Create(); - pathRB.MoveTo(fRight, rt.top); - pathRB.LineTo(fRight, fBottom); - pathRB.LineTo(rt.left, fBottom); - pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth); - pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth); - pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth); - pathRB.LineTo(fRight, rt.top); + pathRB.MoveTo(CFX_PointF(fRight, rt.top)); + pathRB.LineTo(CFX_PointF(fRight, fBottom)); + pathRB.LineTo(CFX_PointF(rt.left, fBottom)); + pathRB.LineTo(CFX_PointF(rt.left + fLineWidth, fBottom - fLineWidth)); + pathRB.LineTo(CFX_PointF(fRight - fLineWidth, fBottom - fLineWidth)); + pathRB.LineTo(CFX_PointF(fRight - fLineWidth, rt.top + fLineWidth)); + pathRB.LineTo(CFX_PointF(fRight, rt.top)); pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix); } static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS, @@ -1827,7 +1831,6 @@ static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS, CFX_Color cr(0xFF000000); pGS->SetFillColor(&cr); CFX_Path path; - path.Create(); path.AddRectangle(rt.left, rt.top, rt.width, rt.height); path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix); @@ -1843,7 +1846,6 @@ static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS, CFX_Color cr(0xFF000000); pGS->SetFillColor(&cr); CFX_Path path; - path.Create(); path.AddRectangle(rt.left, rt.top, rt.width, rt.height); path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height); pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix); @@ -1870,7 +1872,7 @@ static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS, XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080); } static void XFA_BOX_Stroke_Rect(CXFA_Box box, - const CXFA_StrokeArray& strokes, + const std::vector<CXFA_Stroke>& strokes, CFX_Graphics* pGS, CFX_RectF rtWidget, CFX_Matrix* pMatrix) { @@ -1922,17 +1924,14 @@ static void XFA_BOX_Stroke_Rect(CXFA_Box box, } if (bSameStyles) { stroke1 = strokes[0]; - if (stroke1.IsInverted()) { + if (stroke1.IsInverted()) bSameStyles = false; - } - if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) { + if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) bSameStyles = false; - } } } bool bStart = true; CFX_Path path; - path.Create(); for (int32_t i = 0; i < 8; i++) { CXFA_Stroke stroke = strokes[i]; if ((i % 1) == 0 && stroke.GetRadius() < 0) { @@ -1961,7 +1960,7 @@ static void XFA_BOX_Stroke_Rect(CXFA_Box box, } } static void XFA_BOX_Stroke(CXFA_Box box, - const CXFA_StrokeArray& strokes, + const std::vector<CXFA_Stroke>& strokes, CFX_Graphics* pGS, CFX_RectF rtWidget, CFX_Matrix* pMatrix, @@ -2038,16 +2037,14 @@ void XFA_DrawBox(CXFA_Box box, eType != XFA_Element::Rectangle) { return; } - CXFA_StrokeArray strokes; - if (!(dwFlags & XFA_DRAWBOX_ForceRound) && eType != XFA_Element::Arc) { - box.GetStrokes(strokes); - } + std::vector<CXFA_Stroke> strokes; + if (!(dwFlags & XFA_DRAWBOX_ForceRound) && eType != XFA_Element::Arc) + box.GetStrokes(&strokes); + XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags); XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags); } CXFA_CalcData::CXFA_CalcData() : m_iRefCount(0) {} -CXFA_CalcData::~CXFA_CalcData() { - m_Globals.RemoveAll(); -} +CXFA_CalcData::~CXFA_CalcData() {} diff --git a/xfa/fxfa/app/xfa_ffwidgetacc.cpp b/xfa/fxfa/app/xfa_ffwidgetacc.cpp index d4d9949c3..adc5c31cc 100644 --- a/xfa/fxfa/app/xfa_ffwidgetacc.cpp +++ b/xfa/fxfa/app/xfa_ffwidgetacc.cpp @@ -183,7 +183,7 @@ bool CXFA_WidgetAcc::GetName(CFX_WideString& wsName, int32_t iNameType) { } m_pNode->GetSOMExpression(wsName); if (iNameType == 2 && wsName.GetLength() >= 15) { - CFX_WideStringC wsPre = FX_WSTRC(L"xfa[0].form[0]."); + CFX_WideStringC wsPre = L"xfa[0].form[0]."; if (wsPre == CFX_WideStringC(wsName.c_str(), wsPre.GetLength())) { wsName.Delete(0, wsPre.GetLength()); } @@ -678,9 +678,8 @@ int32_t CXFA_WidgetAcc::ExecuteScript(CXFA_Script script, pRefNode->SetUserData(XFA_CalcData, pGlobalData, &gs_XFADeleteCalcData); } - if (pGlobalData->m_Globals.Find(this) < 0) { - pGlobalData->m_Globals.Add(this); - } + if (!pdfium::ContainsValue(pGlobalData->m_Globals, this)) + pGlobalData->m_Globals.push_back(this); } } } @@ -728,12 +727,12 @@ void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) { ->m_pCapTextLayout.get(); if (pCapTextLayout) { if (!bVert && eUIType != XFA_Element::Button) { - szCap.x = fCapReserve; + szCap.width = fCapReserve; } CFX_SizeF minSize; pCapTextLayout->CalcSize(minSize, szCap, szCap); if (bReserveExit) { - bVert ? szCap.y = fCapReserve : szCap.x = fCapReserve; + bVert ? szCap.height = fCapReserve : szCap.width = fCapReserve; } } else { FX_FLOAT fFontSize = 10.0f; @@ -743,10 +742,10 @@ void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) { fFontSize = widgetfont.GetFontSize(); } if (bVert) { - szCap.y = fCapReserve > 0 ? fCapReserve : fFontSize; + szCap.height = fCapReserve > 0 ? fCapReserve : fFontSize; } else { - szCap.x = fCapReserve > 0 ? fCapReserve : 0; - szCap.y = fFontSize; + szCap.width = fCapReserve > 0 ? fCapReserve : 0; + szCap.height = fFontSize; } } if (CXFA_Margin mgCap = caption.GetMargin()) { @@ -756,11 +755,11 @@ void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF& szCap) { mgCap.GetRightInset(fRightInset); mgCap.GetBottomInset(fBottomInset); if (bReserveExit) { - bVert ? (szCap.x += fLeftInset + fRightInset) - : (szCap.y += fTopInset + fBottomInset); + bVert ? (szCap.width += fLeftInset + fRightInset) + : (szCap.height += fTopInset + fBottomInset); } else { - szCap.x += fLeftInset + fRightInset; - szCap.y += fTopInset + fBottomInset; + szCap.width += fLeftInset + fRightInset; + szCap.height += fTopInset + fBottomInset; } } } @@ -768,21 +767,21 @@ bool CXFA_WidgetAcc::CalculateFieldAutoSize(CFX_SizeF& size) { CFX_SizeF szCap; CalcCaptionSize(szCap); CFX_RectF rtUIMargin = GetUIMargin(); - size.x += rtUIMargin.left + rtUIMargin.width; - size.y += rtUIMargin.top + rtUIMargin.height; - if (szCap.x > 0 && szCap.y > 0) { + size.width += rtUIMargin.left + rtUIMargin.width; + size.height += rtUIMargin.top + rtUIMargin.height; + if (szCap.width > 0 && szCap.height > 0) { int32_t iCapPlacement = GetCaption().GetPlacementType(); switch (iCapPlacement) { case XFA_ATTRIBUTEENUM_Left: case XFA_ATTRIBUTEENUM_Right: case XFA_ATTRIBUTEENUM_Inline: { - size.x += szCap.x; - size.y = std::max(size.y, szCap.y); + size.width += szCap.width; + size.height = std::max(size.height, szCap.height); } break; case XFA_ATTRIBUTEENUM_Top: case XFA_ATTRIBUTEENUM_Bottom: { - size.y += szCap.y; - size.x = std::max(size.x, szCap.x); + size.height += szCap.height; + size.width = std::max(size.width, szCap.width); } default: break; @@ -798,46 +797,47 @@ bool CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF& size) { mgWidget.GetTopInset(fTopInset); mgWidget.GetRightInset(fRightInset); mgWidget.GetBottomInset(fBottomInset); - size.x += fLeftInset + fRightInset; - size.y += fTopInset + fBottomInset; + size.width += fLeftInset + fRightInset; + size.height += fTopInset + fBottomInset; } CXFA_Para para = GetPara(); - if (para) { - size.x += para.GetMarginLeft(); - size.x += para.GetTextIndent(); - } - FX_FLOAT fVal = 0, fMin = 0, fMax = 0; + if (para) + size.width += para.GetMarginLeft() + para.GetTextIndent(); + + FX_FLOAT fVal = 0; + FX_FLOAT fMin = 0; + FX_FLOAT fMax = 0; if (GetWidth(fVal)) { - size.x = fVal; + size.width = fVal; } else { - if (GetMinWidth(fMin)) { - size.x = std::max(size.x, fMin); - } - if (GetMaxWidth(fMax) && fMax > 0) { - size.x = std::min(size.x, fMax); - } - } - fVal = 0, fMin = 0, fMax = 0; + if (GetMinWidth(fMin)) + size.width = std::max(size.width, fMin); + if (GetMaxWidth(fMax) && fMax > 0) + size.width = std::min(size.width, fMax); + } + fVal = 0; + fMin = 0; + fMax = 0; if (GetHeight(fVal)) { - size.y = fVal; + size.height = fVal; } else { - if (GetMinHeight(fMin)) { - size.y = std::max(size.y, fMin); - } - if (GetMaxHeight(fMax) && fMax > 0) { - size.y = std::min(size.y, fMax); - } + if (GetMinHeight(fMin)) + size.height = std::max(size.height, fMin); + if (GetMaxHeight(fMax) && fMax > 0) + size.height = std::min(size.height, fMax); } return true; } + void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF& size) { FX_FLOAT fFontSize = GetFontSize(); CFX_WideString wsText; GetValue(wsText, XFA_VALUEPICTURE_Display); if (wsText.IsEmpty()) { - size.y += fFontSize; + size.height += fFontSize; return; } + FX_WCHAR wcEnter = '\n'; FX_WCHAR wsLast = wsText.GetAt(wsText.GetLength() - 1); if (wsLast == wcEnter) { @@ -863,11 +863,11 @@ void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF& size) { size); } bool CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) { - if (size.x > 0) { + if (size.width > 0) { CFX_SizeF szOrz = size; CFX_SizeF szCap; CalcCaptionSize(szCap); - bool bCapExit = szCap.x > 0.01 && szCap.y > 0.01; + bool bCapExit = szCap.width > 0.01 && szCap.height > 0.01; int32_t iCapPlacement = XFA_ATTRIBUTEENUM_Unknown; if (bCapExit) { iCapPlacement = GetCaption().GetPlacementType(); @@ -875,39 +875,39 @@ bool CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) { case XFA_ATTRIBUTEENUM_Left: case XFA_ATTRIBUTEENUM_Right: case XFA_ATTRIBUTEENUM_Inline: { - size.x -= szCap.x; + size.width -= szCap.width; } default: break; } } CFX_RectF rtUIMargin = GetUIMargin(); - size.x -= rtUIMargin.left + rtUIMargin.width; + size.width -= rtUIMargin.left + rtUIMargin.width; CXFA_Margin mgWidget = GetMargin(); if (mgWidget) { FX_FLOAT fLeftInset, fRightInset; mgWidget.GetLeftInset(fLeftInset); mgWidget.GetRightInset(fRightInset); - size.x -= fLeftInset + fRightInset; + size.width -= fLeftInset + fRightInset; } CalculateTextContentSize(size); - size.y += rtUIMargin.top + rtUIMargin.height; + size.height += rtUIMargin.top + rtUIMargin.height; if (bCapExit) { switch (iCapPlacement) { case XFA_ATTRIBUTEENUM_Left: case XFA_ATTRIBUTEENUM_Right: case XFA_ATTRIBUTEENUM_Inline: { - size.y = std::max(size.y, szCap.y); + size.height = std::max(size.height, szCap.height); } break; case XFA_ATTRIBUTEENUM_Top: case XFA_ATTRIBUTEENUM_Bottom: { - size.y += szCap.y; + size.height += szCap.height; } default: break; } } - size.x = szOrz.x; + size.width = szOrz.width; return CalculateWidgetAutoSize(size); } CalculateTextContentSize(size); @@ -915,7 +915,7 @@ bool CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF& size) { } bool CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF& size) { FX_FLOAT fCheckSize = GetCheckButtonSize(); - size.x = size.y = fCheckSize; + size = CFX_SizeF(fCheckSize, fCheckSize); return CalculateFieldAutoSize(size); } bool CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF& size) { @@ -928,16 +928,15 @@ bool CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF& size) { } size.clear(); if (CFX_DIBitmap* pBitmap = GetImageImage()) { - CFX_RectF rtImage, rtFit; - rtImage.Set(0, 0, 0, 0); - rtFit.Set(0, 0, 0, 0); int32_t iImageXDpi = 0; int32_t iImageYDpi = 0; GetImageDpi(iImageXDpi, iImageYDpi); - rtImage.width = - XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi); - rtImage.height = - XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi); + CFX_RectF rtImage( + 0, 0, + XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi), + XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi)); + + CFX_RectF rtFit; if (GetWidth(rtFit.width)) { GetWidthWithoutMargin(rtFit.width); } else { @@ -948,8 +947,7 @@ bool CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF& size) { } else { rtFit.height = rtImage.height; } - size.x = rtFit.width; - size.y = rtFit.height; + size = rtFit.Size(); } return CalculateWidgetAutoSize(size); } @@ -959,16 +957,15 @@ bool CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF& size) { } size.clear(); if (CFX_DIBitmap* pBitmap = GetImageEditImage()) { - CFX_RectF rtImage, rtFit; - rtImage.Set(0, 0, 0, 0); - rtFit.Set(0, 0, 0, 0); int32_t iImageXDpi = 0; int32_t iImageYDpi = 0; GetImageEditDpi(iImageXDpi, iImageYDpi); - rtImage.width = - XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi); - rtImage.height = - XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi); + CFX_RectF rtImage( + 0, 0, + XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi), + XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi)); + + CFX_RectF rtFit; if (GetWidth(rtFit.width)) { GetWidthWithoutMargin(rtFit.width); } else { @@ -979,8 +976,8 @@ bool CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF& size) { } else { rtFit.height = rtImage.height; } - size.x = rtFit.width; - size.y = rtFit.height; + size.width = rtFit.width; + size.height = rtFit.height; } return CalculateFieldAutoSize(size); } @@ -1011,8 +1008,8 @@ bool CXFA_WidgetAcc::CalculateTextAutoSize(CFX_SizeF& size) { CXFA_TextLayout* pTextLayout = static_cast<CXFA_TextLayoutData*>(m_pLayoutData.get())->GetTextLayout(); if (pTextLayout) { - size.x = pTextLayout->StartLayout(size.x); - size.y = pTextLayout->GetLayoutHeight(); + size.width = pTextLayout->StartLayout(size.width); + size.height = pTextLayout->GetLayoutHeight(); } return CalculateWidgetAutoSize(size); } @@ -1142,9 +1139,9 @@ void CXFA_WidgetAcc::CalculateAccWidthAndHeight(XFA_Element eUIType, default: break; } - fWidth = sz.x; - m_pLayoutData->m_fWidgetHeight = sz.y; - fCalcHeight = sz.y; + fWidth = sz.width; + m_pLayoutData->m_fWidgetHeight = sz.height; + fCalcHeight = sz.height; } bool CXFA_WidgetAcc::FindSplitPos(int32_t iBlockIndex, FX_FLOAT& fCalcHeight) { XFA_Element eUIType = GetUIType(); @@ -1498,7 +1495,7 @@ CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData() { } CFX_RetainPtr<CFGAS_GEFont> CXFA_WidgetAcc::GetFDEFont() { - CFX_WideStringC wsFontName = FX_WSTRC(L"Courier"); + CFX_WideStringC wsFontName = L"Courier"; uint32_t dwFontStyle = 0; if (CXFA_Font font = GetFont()) { if (font.IsBold()) @@ -1542,7 +1539,7 @@ CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) { CFX_WideString wsContentType; m_pTextNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); - if (wsContentType == FX_WSTRC(L"text/html")) { + if (wsContentType == L"text/html") { bRichText = true; } } @@ -1558,7 +1555,7 @@ CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) { if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) { CFX_WideString wsContentType; pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); - if (wsContentType == FX_WSTRC(L"text/html")) { + if (wsContentType == L"text/html") { bRichText = true; } } @@ -1593,7 +1590,7 @@ CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) { if (pChildNode && pChildNode->GetElementType() == XFA_Element::ExData) { CFX_WideString wsContentType; pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); - if (wsContentType == FX_WSTRC(L"text/html")) { + if (wsContentType == L"text/html") { bRichText = true; } } @@ -1608,11 +1605,10 @@ CXFA_Node* CXFA_TextProvider::GetTextNode(bool& bRichText) { while (pNode) { CFX_WideStringC wsName; pNode->TryCData(XFA_ATTRIBUTE_Name, wsName); - if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover && - wsName == FX_WSTRC(L"rollover")) { + if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover && wsName == L"rollover") { return pNode; } - if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == FX_WSTRC(L"down")) { + if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == L"down") { return pNode; } pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling); diff --git a/xfa/fxfa/app/xfa_ffwidgethandler.cpp b/xfa/fxfa/app/xfa_ffwidgethandler.cpp index 551d8f659..2fddfb615 100644 --- a/xfa/fxfa/app/xfa_ffwidgethandler.cpp +++ b/xfa/fxfa/app/xfa_ffwidgethandler.cpp @@ -40,11 +40,9 @@ bool CXFA_FFWidgetHandler::OnMouseExit(CXFA_FFWidget* hWidget) { bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { m_pDocView->LockUpdate(); - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnLButtonDown(dwFlags, fx, fy); + bool bRet = hWidget->OnLButtonDown(dwFlags, hWidget->Rotate2Normal(point)); if (bRet && m_pDocView->SetFocus(hWidget)) { m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget( m_pDocView->GetDoc(), hWidget); @@ -56,12 +54,10 @@ bool CXFA_FFWidgetHandler::OnLButtonDown(CXFA_FFWidget* hWidget, bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { m_pDocView->LockUpdate(); - hWidget->Rotate2Normal(fx, fy); m_pDocView->m_bLayoutEvent = true; - bool bRet = hWidget->OnLButtonUp(dwFlags, fx, fy); + bool bRet = hWidget->OnLButtonUp(dwFlags, hWidget->Rotate2Normal(point)); m_pDocView->UnlockUpdate(); m_pDocView->UpdateDocView(); return bRet; @@ -69,20 +65,16 @@ bool CXFA_FFWidgetHandler::OnLButtonUp(CXFA_FFWidget* hWidget, bool CXFA_FFWidgetHandler::OnLButtonDblClk(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnLButtonDblClk(dwFlags, fx, fy); + const CFX_PointF& point) { + bool bRet = hWidget->OnLButtonDblClk(dwFlags, hWidget->Rotate2Normal(point)); m_pDocView->RunInvalidate(); return bRet; } bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnMouseMove(dwFlags, fx, fy); + const CFX_PointF& point) { + bool bRet = hWidget->OnMouseMove(dwFlags, hWidget->Rotate2Normal(point)); m_pDocView->RunInvalidate(); return bRet; } @@ -90,20 +82,17 @@ bool CXFA_FFWidgetHandler::OnMouseMove(CXFA_FFWidget* hWidget, bool CXFA_FFWidgetHandler::OnMouseWheel(CXFA_FFWidget* hWidget, uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnMouseWheel(dwFlags, zDelta, fx, fy); + const CFX_PointF& point) { + bool bRet = + hWidget->OnMouseWheel(dwFlags, zDelta, hWidget->Rotate2Normal(point)); m_pDocView->RunInvalidate(); return bRet; } bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnRButtonDown(dwFlags, fx, fy); + const CFX_PointF& point) { + bool bRet = hWidget->OnRButtonDown(dwFlags, hWidget->Rotate2Normal(point)); if (bRet && m_pDocView->SetFocus(hWidget)) { m_pDocView->GetDoc()->GetDocEnvironment()->SetFocusWidget( m_pDocView->GetDoc(), hWidget); @@ -114,20 +103,16 @@ bool CXFA_FFWidgetHandler::OnRButtonDown(CXFA_FFWidget* hWidget, bool CXFA_FFWidgetHandler::OnRButtonUp(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnRButtonUp(dwFlags, fx, fy); + const CFX_PointF& point) { + bool bRet = hWidget->OnRButtonUp(dwFlags, hWidget->Rotate2Normal(point)); m_pDocView->RunInvalidate(); return bRet; } bool CXFA_FFWidgetHandler::OnRButtonDblClk(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - bool bRet = hWidget->OnRButtonDblClk(dwFlags, fx, fy); + const CFX_PointF& point) { + bool bRet = hWidget->OnRButtonDblClk(dwFlags, hWidget->Rotate2Normal(point)); m_pDocView->RunInvalidate(); return bRet; } @@ -158,20 +143,15 @@ bool CXFA_FFWidgetHandler::OnChar(CXFA_FFWidget* hWidget, } FWL_WidgetHit CXFA_FFWidgetHandler::OnHitTest(CXFA_FFWidget* hWidget, - FX_FLOAT fx, - FX_FLOAT fy) { + const CFX_PointF& point) { if (!(hWidget->GetStatus() & XFA_WidgetStatus_Visible)) return FWL_WidgetHit::Unknown; - - hWidget->Rotate2Normal(fx, fy); - return hWidget->OnHitTest(fx, fy); + return hWidget->OnHitTest(hWidget->Rotate2Normal(point)); } bool CXFA_FFWidgetHandler::OnSetCursor(CXFA_FFWidget* hWidget, - FX_FLOAT fx, - FX_FLOAT fy) { - hWidget->Rotate2Normal(fx, fy); - return hWidget->OnSetCursor(fx, fy); + const CFX_PointF& point) { + return hWidget->OnSetCursor(hWidget->Rotate2Normal(point)); } void CXFA_FFWidgetHandler::RenderWidget(CXFA_FFWidget* hWidget, diff --git a/xfa/fxfa/app/xfa_fwladapter.cpp b/xfa/fxfa/app/xfa_fwladapter.cpp index 3dfa679c4..e1f3e202e 100644 --- a/xfa/fxfa/app/xfa_fwladapter.cpp +++ b/xfa/fxfa/app/xfa_fwladapter.cpp @@ -30,10 +30,8 @@ bool CXFA_FWLAdapterWidgetMgr::GetPopupPos(CFWL_Widget* pWidget, const CFX_RectF& rtAnchor, CFX_RectF& rtPopup) { CXFA_FFWidget* pFFWidget = pWidget->GetLayoutItem(); - CFX_Matrix mt; - pFFWidget->GetRotateMatrix(mt); CFX_RectF rtRotateAnchor(rtAnchor); - mt.TransformRect(rtRotateAnchor); + pFFWidget->GetRotateMatrix().TransformRect(rtRotateAnchor); pFFWidget->GetDoc()->GetDocEnvironment()->GetPopupPos( pFFWidget, fMinHeight, fMaxHeight, rtRotateAnchor, rtPopup); return true; diff --git a/xfa/fxfa/app/xfa_fwladapter.h b/xfa/fxfa/app/xfa_fwladapter.h index 406709bbf..c68fb7015 100644 --- a/xfa/fxfa/app/xfa_fwladapter.h +++ b/xfa/fxfa/app/xfa_fwladapter.h @@ -9,7 +9,6 @@ #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_system.h" -#include "xfa/fwl/fwl_error.h" class CFWL_Widget; diff --git a/xfa/fxfa/app/xfa_fwltheme.cpp b/xfa/fxfa/app/xfa_fwltheme.cpp index 1de302e99..73abaecbc 100644 --- a/xfa/fxfa/app/xfa_fwltheme.cpp +++ b/xfa/fxfa/app/xfa_fwltheme.cpp @@ -149,8 +149,6 @@ void CXFA_FWLTheme::DrawText(CFWL_ThemeText* pParams) { CFX_RectF CXFA_FWLTheme::GetUIMargin(CFWL_ThemePart* pThemePart) const { CFX_RectF rect; - rect.Reset(); - CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget); if (!pWidget) return rect; @@ -217,8 +215,8 @@ CFX_SizeF CXFA_FWLTheme::GetSpaceAboveBelow(CFWL_ThemePart* pThemePart) const { if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) { CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc(); if (CXFA_Para para = pWidgetAcc->GetPara()) { - sizeAboveBelow.x = para.GetSpaceAbove(); - sizeAboveBelow.y = para.GetSpaceBelow(); + sizeAboveBelow.width = para.GetSpaceAbove(); + sizeAboveBelow.height = para.GetSpaceBelow(); } } return sizeAboveBelow; diff --git a/xfa/fxfa/app/xfa_rendercontext.cpp b/xfa/fxfa/app/xfa_rendercontext.cpp index 75e7e7d84..a855105e3 100644 --- a/xfa/fxfa/app/xfa_rendercontext.cpp +++ b/xfa/fxfa/app/xfa_rendercontext.cpp @@ -32,11 +32,10 @@ int32_t CXFA_RenderContext::StartRender(CXFA_FFPageView* pPageView, m_pGS = pGS; m_matrix = matrix; m_options = options; - CFX_RectF rtPage; - pGS->GetClipRect(rtPage); + CFX_Matrix mtRes; mtRes.SetReverse(matrix); - m_rtClipRect.Set(rtPage.left, rtPage.top, rtPage.width, rtPage.height); + m_rtClipRect = pGS->GetClipRect(); mtRes.TransformRect(m_rtClipRect); m_dwStatus = m_options.m_bHighlight ? XFA_WidgetStatus_Highlight : 0; uint32_t dwFilterType = XFA_WidgetStatus_Visible | @@ -52,12 +51,12 @@ int32_t CXFA_RenderContext::DoRender(IFX_Pause* pPause) { int32_t iCount = 0; while (m_pWidget) { CXFA_FFWidget* pWidget = m_pWidget; - CFX_RectF rtWidgetBox; - pWidget->GetBBox(rtWidgetBox, XFA_WidgetStatus_Visible); + CFX_RectF rtWidgetBox = pWidget->GetBBox(XFA_WidgetStatus_Visible); rtWidgetBox.width += 1; rtWidgetBox.height += 1; if (rtWidgetBox.IntersectWith(m_rtClipRect)) pWidget->RenderWidget(m_pGS, &m_matrix, m_dwStatus); + m_pWidget = m_pWidgetIterator->MoveToNext(); iCount++; if (iCount > kMaxCount && pPause && pPause->NeedToPauseNow()) diff --git a/xfa/fxfa/app/xfa_textpiece.cpp b/xfa/fxfa/app/xfa_textpiece.cpp index 933af6c92..c53e45f91 100644 --- a/xfa/fxfa/app/xfa_textpiece.cpp +++ b/xfa/fxfa/app/xfa_textpiece.cpp @@ -8,13 +8,6 @@ #include "xfa/fxfa/app/cxfa_linkuserdata.h" -XFA_TextPiece::XFA_TextPiece() - : pszText(nullptr), pWidths(nullptr), pFont(nullptr), pLinkData(nullptr) {} +XFA_TextPiece::XFA_TextPiece() {} -XFA_TextPiece::~XFA_TextPiece() { - if (pLinkData) - pLinkData->Release(); - - FX_Free(pszText); - FX_Free(pWidths); -} +XFA_TextPiece::~XFA_TextPiece() {} diff --git a/xfa/fxfa/app/xfa_textpiece.h b/xfa/fxfa/app/xfa_textpiece.h index 2b74155af..6802df556 100644 --- a/xfa/fxfa/app/xfa_textpiece.h +++ b/xfa/fxfa/app/xfa_textpiece.h @@ -7,6 +7,8 @@ #ifndef XFA_FXFA_APP_XFA_TEXTPIECE_H_ #define XFA_FXFA_APP_XFA_TEXTPIECE_H_ +#include <vector> + #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_coordinates.h" #include "core/fxcrt/fx_string.h" @@ -20,20 +22,20 @@ class XFA_TextPiece { XFA_TextPiece(); ~XFA_TextPiece(); - FX_WCHAR* pszText; + CFX_WideString szText; + std::vector<int32_t> Widths; int32_t iChars; - int32_t* pWidths; int32_t iHorScale; int32_t iVerScale; int32_t iBidiLevel; int32_t iUnderline; int32_t iPeriod; int32_t iLineThrough; - CFX_RetainPtr<CFGAS_GEFont> pFont; FX_ARGB dwColor; FX_FLOAT fFontSize; CFX_RectF rtPiece; - CXFA_LinkUserData* pLinkData; + CFX_RetainPtr<CFGAS_GEFont> pFont; + CFX_RetainPtr<CXFA_LinkUserData> pLinkData; }; #endif // XFA_FXFA_APP_XFA_TEXTPIECE_H_ diff --git a/xfa/fxfa/fm2js/xfa_expression.cpp b/xfa/fxfa/fm2js/xfa_expression.cpp index a4d119593..32db6d24d 100644 --- a/xfa/fxfa/fm2js/xfa_expression.cpp +++ b/xfa/fxfa/fm2js/xfa_expression.cpp @@ -46,24 +46,24 @@ CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition() {} void CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript) { if (m_isGlobal && m_pExpressions.empty()) { - javascript << FX_WSTRC(L"// comments only"); + javascript << L"// comments only"; return; } if (m_isGlobal) { - javascript << FX_WSTRC(L"(\n"); + javascript << L"(\n"; } - javascript << FX_WSTRC(L"function "); + javascript << L"function "; if (m_wsName.GetAt(0) == L'!') { CFX_WideString tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1); javascript << tempName; } else { javascript << m_wsName; } - javascript << FX_WSTRC(L"("); + javascript << L"("; bool bNeedComma = false; for (const auto& identifier : m_pArguments) { if (bNeedComma) - javascript << FX_WSTRC(L", "); + javascript << L", "; if (identifier.GetAt(0) == L'!') { CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + identifier.Mid(1); @@ -73,28 +73,28 @@ void CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript) { } bNeedComma = true; } - javascript << FX_WSTRC(L")\n{\n"); - javascript << FX_WSTRC(L"var "); + javascript << L")\n{\n"; + javascript << L"var "; javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = null;\n"); + javascript << L" = null;\n"; for (const auto& expr : m_pExpressions) { if (expr == m_pExpressions.back()) expr->ToImpliedReturnJS(javascript); else expr->ToJavaScript(javascript); } - javascript << FX_WSTRC(L"return "); + javascript << L"return "; if (m_isGlobal) { javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L")"); + javascript << L")"; } else { javascript << RUNTIMEFUNCTIONRETURNVALUE; } - javascript << FX_WSTRC(L";\n}\n"); + javascript << L";\n}\n"; if (m_isGlobal) { - javascript << FX_WSTRC(L").call(this);\n"); + javascript << L").call(this);\n"; } } @@ -111,49 +111,49 @@ CXFA_FMVarExpression::CXFA_FMVarExpression( CXFA_FMVarExpression::~CXFA_FMVarExpression() {} void CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"var "); + javascript << L"var "; CFX_WideString tempName(m_wsName); if (m_wsName.GetAt(0) == L'!') { tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1); } javascript << tempName; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; if (m_pInit) { m_pInit->ToJavaScript(javascript); javascript << tempName; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(VARFILTER); - javascript << FX_WSTRC(L"("); + javascript << L"("; javascript << tempName; - javascript << FX_WSTRC(L");\n"); + javascript << L");\n"; } else { - javascript << FX_WSTRC(L"\"\";\n"); + javascript << L"\"\";\n"; } } void CXFA_FMVarExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"var "); + javascript << L"var "; CFX_WideString tempName(m_wsName); if (m_wsName.GetAt(0) == L'!') { tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1); } javascript << tempName; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; if (m_pInit) { m_pInit->ToJavaScript(javascript); javascript << tempName; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(VARFILTER); - javascript << FX_WSTRC(L"("); + javascript << L"("; javascript << tempName; - javascript << FX_WSTRC(L");\n"); + javascript << L");\n"; } else { - javascript << FX_WSTRC(L"\"\";\n"); + javascript << L"\"\";\n"; } javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << tempName; - javascript << FX_WSTRC(L";\n"); + javascript << L";\n"; } CXFA_FMExpExpression::CXFA_FMExpExpression( @@ -169,7 +169,7 @@ void CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& javascript) { m_pExpression->ToJavaScript(javascript); } else { m_pExpression->ToJavaScript(javascript); - javascript << FX_WSTRC(L";\n"); + javascript << L";\n"; } } @@ -183,16 +183,16 @@ void CXFA_FMExpExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { m_pExpression->GetOperatorToken() == TOKdotdot || m_pExpression->GetOperatorToken() == TOKdot) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExpression->ToJavaScript(javascript); - javascript << FX_WSTRC(L");\n"); + javascript << L");\n"; } else { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; m_pExpression->ToJavaScript(javascript); - javascript << FX_WSTRC(L";\n"); + javascript << L";\n"; } } } @@ -206,21 +206,21 @@ CXFA_FMBlockExpression::CXFA_FMBlockExpression( CXFA_FMBlockExpression::~CXFA_FMBlockExpression() {} void CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"{\n"); + javascript << L"{\n"; for (const auto& expr : m_ExpressionList) expr->ToJavaScript(javascript); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; } void CXFA_FMBlockExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"{\n"); + javascript << L"{\n"; for (const auto& expr : m_ExpressionList) { if (expr == m_ExpressionList.back()) expr->ToImpliedReturnJS(javascript); else expr->ToJavaScript(javascript); } - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; } CXFA_FMDoExpression::CXFA_FMDoExpression( @@ -251,25 +251,25 @@ CXFA_FMIfExpression::CXFA_FMIfExpression( CXFA_FMIfExpression::~CXFA_FMIfExpression() {} void CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"if ("); + javascript << L"if ("; if (m_pExpression) { javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExpression->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } - javascript << FX_WSTRC(L")\n"); + javascript << L")\n"; if (m_pIfExpression) { m_pIfExpression->ToJavaScript(javascript); } if (m_pElseExpression) { if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) { - javascript << FX_WSTRC(L"else\n"); - javascript << FX_WSTRC(L"{\n"); + javascript << L"else\n"; + javascript << L"{\n"; m_pElseExpression->ToJavaScript(javascript); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; } else { - javascript << FX_WSTRC(L"else\n"); + javascript << L"else\n"; m_pElseExpression->ToJavaScript(javascript); } } @@ -277,26 +277,26 @@ void CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript) { void CXFA_FMIfExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"if ("); + javascript << L" = 0;\n"; + javascript << L"if ("; if (m_pExpression) { javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExpression->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } - javascript << FX_WSTRC(L")\n"); + javascript << L")\n"; if (m_pIfExpression) { m_pIfExpression->ToImpliedReturnJS(javascript); } if (m_pElseExpression) { if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) { - javascript << FX_WSTRC(L"else\n"); - javascript << FX_WSTRC(L"{\n"); + javascript << L"else\n"; + javascript << L"{\n"; m_pElseExpression->ToImpliedReturnJS(javascript); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; } else { - javascript << FX_WSTRC(L"else\n"); + javascript << L"else\n"; m_pElseExpression->ToImpliedReturnJS(javascript); } } @@ -319,18 +319,18 @@ CXFA_FMWhileExpression::CXFA_FMWhileExpression( CXFA_FMWhileExpression::~CXFA_FMWhileExpression() {} void CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"while ("); + javascript << L"while ("; m_pCondition->ToJavaScript(javascript); - javascript << FX_WSTRC(L")\n"); + javascript << L")\n"; m_pExpression->ToJavaScript(javascript); } void CXFA_FMWhileExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"while ("); + javascript << L" = 0;\n"; + javascript << L"while ("; m_pCondition->ToJavaScript(javascript); - javascript << FX_WSTRC(L")\n"); + javascript << L")\n"; m_pExpression->ToImpliedReturnJS(javascript); } @@ -341,14 +341,14 @@ CXFA_FMBreakExpression::~CXFA_FMBreakExpression() {} void CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"break;\n"); + javascript << L" = 0;\n"; + javascript << L"break;\n"; } void CXFA_FMBreakExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"break;\n"); + javascript << L" = 0;\n"; + javascript << L"break;\n"; } CXFA_FMContinueExpression::CXFA_FMContinueExpression(uint32_t line) @@ -358,14 +358,14 @@ CXFA_FMContinueExpression::~CXFA_FMContinueExpression() {} void CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"continue;\n"); + javascript << L" = 0;\n"; + javascript << L"continue;\n"; } void CXFA_FMContinueExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"continue;\n"); + javascript << L" = 0;\n"; + javascript << L"continue;\n"; } CXFA_FMForExpression::CXFA_FMForExpression( @@ -387,7 +387,7 @@ CXFA_FMForExpression::CXFA_FMForExpression( CXFA_FMForExpression::~CXFA_FMForExpression() {} void CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"{\nvar "); + javascript << L"{\nvar "; CFX_WideString tempVariant; if (m_wsVariant.GetAt(0) == L'!') { tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1); @@ -396,49 +396,49 @@ void CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript) { tempVariant = m_wsVariant; javascript << m_wsVariant; } - javascript << FX_WSTRC(L" = null;\n"); - javascript << FX_WSTRC(L"for ("); + javascript << L" = null;\n"; + javascript << L"for ("; javascript << tempVariant; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pAssignment->ToJavaScript(javascript); - javascript << FX_WSTRC(L"); "); + javascript << L"); "; javascript << tempVariant; if (m_iDirection == 1) { - javascript << FX_WSTRC(L" <= "); + javascript << L" <= "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pAccessor->ToJavaScript(javascript); - javascript << FX_WSTRC(L"); "); + javascript << L"); "; javascript << tempVariant; - javascript << FX_WSTRC(L" += "); + javascript << L" += "; } else { - javascript << FX_WSTRC(L" >= "); + javascript << L" >= "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pAccessor->ToJavaScript(javascript); - javascript << FX_WSTRC(L"); "); + javascript << L"); "; javascript << tempVariant; - javascript << FX_WSTRC(L" -= "); + javascript << L" -= "; } if (m_pStep) { javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pStep->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } else { - javascript << FX_WSTRC(L"1"); + javascript << L"1"; } - javascript << FX_WSTRC(L")\n"); + javascript << L")\n"; m_pList->ToJavaScript(javascript); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; } void CXFA_FMForExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"{\nvar "); + javascript << L" = 0;\n"; + javascript << L"{\nvar "; CFX_WideString tempVariant; if (m_wsVariant.GetAt(0) == L'!') { tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1); @@ -447,43 +447,43 @@ void CXFA_FMForExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { tempVariant = m_wsVariant; javascript << m_wsVariant; } - javascript << FX_WSTRC(L" = null;\n"); - javascript << FX_WSTRC(L"for ("); + javascript << L" = null;\n"; + javascript << L"for ("; javascript << tempVariant; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pAssignment->ToJavaScript(javascript); - javascript << FX_WSTRC(L"); "); + javascript << L"); "; javascript << tempVariant; if (m_iDirection == 1) { - javascript << FX_WSTRC(L" <= "); + javascript << L" <= "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pAccessor->ToJavaScript(javascript); - javascript << FX_WSTRC(L"); "); + javascript << L"); "; javascript << tempVariant; - javascript << FX_WSTRC(L" += "); + javascript << L" += "; } else { - javascript << FX_WSTRC(L" >= "); + javascript << L" >= "; javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pAccessor->ToJavaScript(javascript); - javascript << FX_WSTRC(L"); "); + javascript << L"); "; javascript << tempVariant; - javascript << FX_WSTRC(L" -= "); + javascript << L" -= "; } if (m_pStep) { javascript << XFA_FM_EXPTypeToString(GETFMVALUE); - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pStep->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } else { - javascript << FX_WSTRC(L"1"); + javascript << L"1"; } - javascript << FX_WSTRC(L")\n"); + javascript << L")\n"; m_pList->ToImpliedReturnJS(javascript); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; } CXFA_FMForeachExpression::CXFA_FMForeachExpression( @@ -499,8 +499,8 @@ CXFA_FMForeachExpression::CXFA_FMForeachExpression( CXFA_FMForeachExpression::~CXFA_FMForeachExpression() {} void CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"{\n"); - javascript << FX_WSTRC(L"var "); + javascript << L"{\n"; + javascript << L"var "; if (m_wsIdentifier.GetAt(0) == L'!') { CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1); @@ -508,27 +508,27 @@ void CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } else { javascript << m_wsIdentifier; } - javascript << FX_WSTRC(L" = null;\n"); - javascript << FX_WSTRC(L"var "); + javascript << L" = null;\n"; + javascript << L"var "; javascript << RUNTIMEBLOCKTEMPARRAY; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT); - javascript << FX_WSTRC(L"("); + javascript << L"("; for (const auto& expr : m_pAccessors) { expr->ToJavaScript(javascript); if (expr != m_pAccessors.back()) javascript << L", "; } - javascript << FX_WSTRC(L");\n"); - javascript << FX_WSTRC(L"var "); + javascript << L");\n"; + javascript << L"var "; javascript << RUNTIMEBLOCKTEMPARRAYINDEX; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"while("); + javascript << (L" = 0;\n"); + javascript << L"while("; javascript << RUNTIMEBLOCKTEMPARRAYINDEX; - javascript << FX_WSTRC(L" < "); + javascript << L" < "; javascript << RUNTIMEBLOCKTEMPARRAY; - javascript << FX_WSTRC(L".length)\n{\n"); + javascript << L".length)\n{\n"; if (m_wsIdentifier.GetAt(0) == L'!') { CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1); @@ -536,21 +536,21 @@ void CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } else { javascript << m_wsIdentifier; } - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << RUNTIMEBLOCKTEMPARRAY; - javascript << FX_WSTRC(L"["); + javascript << L"["; javascript << RUNTIMEBLOCKTEMPARRAYINDEX; - javascript << FX_WSTRC(L"++];\n"); + javascript << L"++];\n"; m_pList->ToJavaScript(javascript); - javascript << FX_WSTRC(L"}\n"); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; + javascript << L"}\n"; } void CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"{\n"); - javascript << FX_WSTRC(L"var "); + javascript << L" = 0;\n"; + javascript << L"{\n"; + javascript << L"var "; if (m_wsIdentifier.GetAt(0) == L'!') { CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1); @@ -558,26 +558,26 @@ void CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { } else { javascript << m_wsIdentifier; } - javascript << FX_WSTRC(L" = null;\n"); - javascript << FX_WSTRC(L"var "); + javascript << L" = null;\n"; + javascript << L"var "; javascript << RUNTIMEBLOCKTEMPARRAY; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT); - javascript << FX_WSTRC(L"("); + javascript << L"("; for (const auto& expr : m_pAccessors) { expr->ToJavaScript(javascript); if (expr != m_pAccessors.back()) javascript << L", "; } - javascript << FX_WSTRC(L");\n"); - javascript << FX_WSTRC(L"var "); + javascript << L");\n"; + javascript << L"var "; javascript << RUNTIMEBLOCKTEMPARRAYINDEX; - javascript << FX_WSTRC(L" = 0;\n"); - javascript << FX_WSTRC(L"while("); + javascript << L" = 0;\n"; + javascript << L"while("; javascript << RUNTIMEBLOCKTEMPARRAYINDEX; - javascript << FX_WSTRC(L" < "); + javascript << L" < "; javascript << RUNTIMEBLOCKTEMPARRAY; - javascript << FX_WSTRC(L".length)\n{\n"); + javascript << L".length)\n{\n"; if (m_wsIdentifier.GetAt(0) == L'!') { CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1); @@ -585,12 +585,12 @@ void CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { } else { javascript << m_wsIdentifier; } - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << RUNTIMEBLOCKTEMPARRAY; - javascript << FX_WSTRC(L"["); + javascript << L"["; javascript << RUNTIMEBLOCKTEMPARRAYINDEX; - javascript << FX_WSTRC(L"++];\n"); + javascript << L"++];\n"; m_pList->ToImpliedReturnJS(javascript); - javascript << FX_WSTRC(L"}\n"); - javascript << FX_WSTRC(L"}\n"); + javascript << L"}\n"; + javascript << L"}\n"; } diff --git a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp index b307687f9..e8cb2d027 100644 --- a/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp +++ b/xfa/fxfa/fm2js/xfa_fm2jscontext.cpp @@ -409,30 +409,30 @@ void AlternateDateTimeSymbols(CFX_WideString& wsPattern, bool PatternStringType(const CFX_ByteStringC& szPattern, uint32_t& patternType) { CFX_WideString wsPattern = CFX_WideString::FromUTF8(szPattern); - if (FX_WSTRC(L"datetime") == wsPattern.Left(8)) { + if (L"datetime" == wsPattern.Left(8)) { patternType = XFA_VT_DATETIME; return true; } - if (FX_WSTRC(L"date") == wsPattern.Left(4)) { + if (L"date" == wsPattern.Left(4)) { patternType = wsPattern.Find(L"time") > 0 ? XFA_VT_DATETIME : XFA_VT_DATE; return true; } - if (FX_WSTRC(L"time") == wsPattern.Left(4)) { + if (L"time" == wsPattern.Left(4)) { patternType = XFA_VT_TIME; return true; } - if (FX_WSTRC(L"text") == wsPattern.Left(4)) { + if (L"text" == wsPattern.Left(4)) { patternType = XFA_VT_TEXT; return true; } - if (FX_WSTRC(L"num") == wsPattern.Left(3)) { - if (FX_WSTRC(L"integer") == wsPattern.Mid(4, 7)) { + if (L"num" == wsPattern.Left(3)) { + if (L"integer" == wsPattern.Mid(4, 7)) { patternType = XFA_VT_INTEGER; - } else if (FX_WSTRC(L"decimal") == wsPattern.Mid(4, 7)) { + } else if (L"decimal" == wsPattern.Mid(4, 7)) { patternType = XFA_VT_DECIMAL; - } else if (FX_WSTRC(L"currency") == wsPattern.Mid(4, 8)) { + } else if (L"currency" == wsPattern.Mid(4, 8)) { patternType = XFA_VT_FLOAT; - } else if (FX_WSTRC(L"percent") == wsPattern.Mid(4, 7)) { + } else if (L"percent" == wsPattern.Mid(4, 7)) { patternType = XFA_VT_FLOAT; } else { patternType = XFA_VT_FLOAT; @@ -2026,7 +2026,7 @@ bool CXFA_FM2JSContext::IsoDate2Local(CFXJSE_Value* pThis, CFX_WideString wsRet; widgetValue.FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display); - strLocalDate = FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength()); + strLocalDate = wsRet.UTF8Encode(); return true; } @@ -2065,7 +2065,7 @@ bool CXFA_FM2JSContext::IsoTime2Local(CFXJSE_Value* pThis, CFX_WideString wsRet; widgetValue.FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display); - strLocalTime = FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength()); + strLocalTime = wsRet.UTF8Encode(); return true; } @@ -2104,7 +2104,7 @@ bool CXFA_FM2JSContext::GetGMTTime(CFXJSE_Value* pThis, CFX_WideString wsRet; widgetValue.FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display); - strGMTTime = FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength()); + strGMTTime = wsRet.UTF8Encode(); return true; } @@ -2213,7 +2213,7 @@ void CXFA_FM2JSContext::GetLocalDateFormat(CFXJSE_Value* pThis, pLocale->GetDateTimeSymbols(wsSymbols); AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Date); } - strFormat = FX_UTF8Encode(strRet.c_str(), strRet.GetLength()); + strFormat = strRet.UTF8Encode(); } // static @@ -2264,7 +2264,7 @@ void CXFA_FM2JSContext::GetLocalTimeFormat(CFXJSE_Value* pThis, pLocale->GetDateTimeSymbols(wsSymbols); AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Time); } - strFormat = FX_UTF8Encode(strRet.c_str(), strRet.GetLength()); + strFormat = strRet.UTF8Encode(); } // static @@ -2959,10 +2959,8 @@ void CXFA_FM2JSContext::Eval(CFXJSE_Value* pThis, CFXJSE_Context::Create(pIsolate, nullptr, nullptr)); auto returnValue = pdfium::MakeUnique<CFXJSE_Value>(pIsolate); - CFX_WideString javaScript(wsJavaScriptBuf.AsStringC()); - pNewContext->ExecuteScript( - FX_UTF8Encode(javaScript.c_str(), javaScript.GetLength()).c_str(), - returnValue.get()); + pNewContext->ExecuteScript(FX_UTF8Encode(wsJavaScriptBuf.AsStringC()).c_str(), + returnValue.get()); args.GetReturnValue()->Assign(returnValue.get()); } @@ -3428,11 +3426,8 @@ void CXFA_FM2JSContext::DecodeURL(const CFX_ByteStringC& szURLString, ++i; } wsResultBuf.AppendChar(0); - szResultString.Clear(); - szResultString << FX_UTF8Encode(wsResultBuf.GetBuffer(), - wsResultBuf.GetLength()) - .AsStringC(); + szResultString << FX_UTF8Encode(wsResultBuf.AsStringC()); } // static @@ -3508,9 +3503,7 @@ void CXFA_FM2JSContext::DecodeHTML(const CFX_ByteStringC& szHTMLString, wsResultBuf.AppendChar(0); szResultString.Clear(); - szResultString << FX_UTF8Encode(wsResultBuf.GetBuffer(), - wsResultBuf.GetLength()) - .AsStringC(); + szResultString << FX_UTF8Encode(wsResultBuf.AsStringC()); } // static @@ -3610,10 +3603,8 @@ void CXFA_FM2JSContext::DecodeXML(const CFX_ByteStringC& szXMLString, iCode = 0; } wsXMLBuf.AppendChar(0); - szResultString.Clear(); - szResultString << FX_UTF8Encode(wsXMLBuf.GetBuffer(), wsXMLBuf.GetLength()) - .AsStringC(); + szResultString << FX_UTF8Encode(wsXMLBuf.AsStringC()); } // static @@ -3685,7 +3676,7 @@ void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString, int32_t iIndex = ch / 16; strEncode[1] = strCode[iIndex]; strEncode[2] = strCode[ch - iIndex * 16]; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; break; } ++i; @@ -3700,7 +3691,7 @@ void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString, int32_t iIndex = ch / 16; strEncode[1] = strCode[iIndex]; strEncode[2] = strCode[ch - iIndex * 16]; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; break; } ++i; @@ -3724,7 +3715,7 @@ void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString, int32_t iIndex = ch / 16; strEncode[1] = strCode[iIndex]; strEncode[2] = strCode[ch - iIndex * 16]; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; } else if (ch >= 0x20 && ch <= 0x7e) { wsResultBuf.AppendChar(ch); } else { @@ -3750,20 +3741,18 @@ void CXFA_FM2JSContext::EncodeURL(const CFX_ByteStringC& szURLString, strEncode[2] = strTmp.GetAt(iLen - 2); iIndex = iLen - 3; } - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; while (iIndex > 0) { strEncode[1] = strTmp.GetAt(iIndex); strEncode[2] = strTmp.GetAt(iIndex - 1); iIndex -= 2; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; } } } wsResultBuf.AppendChar(0); szResultBuf.Clear(); - - szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength()) - .AsStringC(); + szResultBuf << FX_UTF8Encode(wsResultBuf.AsStringC()); } // static @@ -3799,7 +3788,7 @@ void CXFA_FM2JSContext::EncodeHTML(const CFX_ByteStringC& szHTMLString, strEncode[4] = strCode[ch - iIndex * 16]; strEncode[5] = ';'; strEncode[6] = 0; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; } else { int32_t iBigByte = ch / 256; int32_t iLittleByte = ch % 256; @@ -3807,15 +3796,13 @@ void CXFA_FM2JSContext::EncodeHTML(const CFX_ByteStringC& szHTMLString, strEncode[4] = strCode[iBigByte % 16]; strEncode[5] = strCode[iLittleByte / 16]; strEncode[6] = strCode[iLittleByte % 16]; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; } ++i; } wsResultBuf.AppendChar(0); szResultBuf.Clear(); - - szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength()) - .AsStringC(); + szResultBuf << FX_UTF8Encode(wsResultBuf.AsStringC()); } // static @@ -3870,7 +3857,7 @@ void CXFA_FM2JSContext::EncodeXML(const CFX_ByteStringC& szXMLString, strEncode[4] = strCode[ch - iIndex * 16]; strEncode[5] = ';'; strEncode[6] = 0; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; } else { int32_t iBigByte = ch / 256; int32_t iLittleByte = ch % 256; @@ -3878,7 +3865,7 @@ void CXFA_FM2JSContext::EncodeXML(const CFX_ByteStringC& szXMLString, strEncode[4] = strCode[iBigByte % 16]; strEncode[5] = strCode[iLittleByte / 16]; strEncode[6] = strCode[iLittleByte % 16]; - wsResultBuf << FX_WSTRC(strEncode); + wsResultBuf << strEncode; } break; } @@ -3886,9 +3873,7 @@ void CXFA_FM2JSContext::EncodeXML(const CFX_ByteStringC& szXMLString, } wsResultBuf.AppendChar(0); szResultBuf.Clear(); - - szResultBuf << FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength()) - .AsStringC(); + szResultBuf << FX_UTF8Encode(wsResultBuf.AsStringC()); } // static @@ -4009,8 +3994,7 @@ void CXFA_FM2JSContext::Format(CFXJSE_Value* pThis, return; } - args.GetReturnValue()->SetString( - FX_UTF8Encode(wsRet.c_str(), wsRet.GetLength()).AsStringC()); + args.GetReturnValue()->SetString(wsRet.UTF8Encode().AsStringC()); } // static @@ -4091,8 +4075,7 @@ void CXFA_FM2JSContext::Lower(CFXJSE_Value* pThis, lowStringBuf.AppendChar(0); args.GetReturnValue()->SetString( - FX_UTF8Encode(lowStringBuf.GetBuffer(), lowStringBuf.GetLength()) - .AsStringC()); + FX_UTF8Encode(lowStringBuf.AsStringC()).AsStringC()); } // static @@ -4156,7 +4139,7 @@ void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis, return; } args.GetReturnValue()->SetString( - FX_UTF8Encode(localeValue.GetValue()).AsStringC()); + localeValue.GetValue().UTF8Encode().AsStringC()); return; } @@ -4173,7 +4156,7 @@ void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis, return; } args.GetReturnValue()->SetString( - FX_UTF8Encode(localeValue.GetValue()).AsStringC()); + localeValue.GetValue().UTF8Encode().AsStringC()); return; } case XFA_VT_DATE: { @@ -4185,7 +4168,7 @@ void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis, return; } args.GetReturnValue()->SetString( - FX_UTF8Encode(localeValue.GetValue()).AsStringC()); + localeValue.GetValue().UTF8Encode().AsStringC()); return; } case XFA_VT_TIME: { @@ -4197,7 +4180,7 @@ void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis, return; } args.GetReturnValue()->SetString( - FX_UTF8Encode(localeValue.GetValue()).AsStringC()); + localeValue.GetValue().UTF8Encode().AsStringC()); return; } case XFA_VT_TEXT: { @@ -4209,7 +4192,7 @@ void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis, return; } args.GetReturnValue()->SetString( - FX_UTF8Encode(localeValue.GetValue()).AsStringC()); + localeValue.GetValue().UTF8Encode().AsStringC()); return; } case XFA_VT_FLOAT: { @@ -4241,7 +4224,7 @@ void CXFA_FM2JSContext::Parse(CFXJSE_Value* pThis, return; } args.GetReturnValue()->SetString( - FX_UTF8Encode(localeValue2.GetValue()).AsStringC()); + localeValue2.GetValue().UTF8Encode().AsStringC()); return; } } @@ -4640,8 +4623,7 @@ void CXFA_FM2JSContext::Upper(CFXJSE_Value* pThis, upperStringBuf.AppendChar(0); args.GetReturnValue()->SetString( - FX_UTF8Encode(upperStringBuf.GetBuffer(), upperStringBuf.GetLength()) - .AsStringC()); + FX_UTF8Encode(upperStringBuf.AsStringC()).AsStringC()); } // static @@ -4931,10 +4913,7 @@ void CXFA_FM2JSContext::Post(CFXJSE_Value* pThis, pContext->ThrowServerDeniedException(); return; } - - args.GetReturnValue()->SetString( - FX_UTF8Encode(decodedResponse.c_str(), decodedResponse.GetLength()) - .AsStringC()); + args.GetReturnValue()->SetString(decodedResponse.UTF8Encode().AsStringC()); } // static @@ -5680,9 +5659,8 @@ void CXFA_FM2JSContext::eval_translation(CFXJSE_Value* pThis, return; } - CFX_WideString javaScript = wsJavaScriptBuf.MakeString(); args.GetReturnValue()->SetString( - FX_UTF8Encode(javaScript.c_str(), javaScript.GetLength()).AsStringC()); + FX_UTF8Encode(wsJavaScriptBuf.AsStringC()).AsStringC()); } // static @@ -6149,7 +6127,7 @@ int32_t CXFA_FM2JSContext::ResolveObjects(CFXJSE_Value* pThis, if (CXFA_Node* pXFANode = pNode->AsNode()) pXFANode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, false); if (wsName.IsEmpty()) - wsName = FX_WSTRC(L"#") + pNode->GetClassName(); + wsName = L"#" + pNode->GetClassName(); wsSomExpression = wsName + wsSomExpression; dFlags = XFA_RESOLVENODE_Siblings; @@ -6439,6 +6417,5 @@ void CXFA_FM2JSContext::ThrowException(const FX_WCHAR* str, ...) const { va_start(arg_ptr, str); wsMessage.FormatV(str, arg_ptr); va_end(arg_ptr); - FXJSE_ThrowMessage( - FX_UTF8Encode(wsMessage.c_str(), wsMessage.GetLength()).AsStringC()); + FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC()); } diff --git a/xfa/fxfa/fm2js/xfa_fmparse.cpp b/xfa/fxfa/fm2js/xfa_fmparse.cpp index 2dfdfdb4d..52161e8c0 100644 --- a/xfa/fxfa/fm2js/xfa_fmparse.cpp +++ b/xfa/fxfa/fm2js/xfa_fmparse.cpp @@ -847,7 +847,7 @@ std::unique_ptr<CXFA_FMExpression> CXFA_FMParse::ParseIfExpression() { m_lexer->SetCurrentLine(line); m_pToken = new CXFA_FMToken(line); m_pToken->m_type = TOKidentifier; - m_pToken->m_wstring = FX_WSTRC(L"if"); + m_pToken->m_wstring = L"if"; m_lexer->SetToken(m_pToken); m_lexer->RestorePos(pStartPos); return ParseExpExpression(); diff --git a/xfa/fxfa/fm2js/xfa_simpleexpression.cpp b/xfa/fxfa/fm2js/xfa_simpleexpression.cpp index 342fe9f06..686ddaa17 100644 --- a/xfa/fxfa/fm2js/xfa_simpleexpression.cpp +++ b/xfa/fxfa/fm2js/xfa_simpleexpression.cpp @@ -132,7 +132,7 @@ CXFA_FMNullExpression::CXFA_FMNullExpression(uint32_t line) : CXFA_FMSimpleExpression(line, TOKnull) {} void CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"null"); + javascript << L"null"; } CXFA_FMNumberExpression::CXFA_FMNumberExpression(uint32_t line, @@ -161,12 +161,12 @@ void CXFA_FMStringExpression::ToJavaScript(CFX_WideTextBuf& javascript) { switch (oneChar) { case L'\"': { i++; - javascript << FX_WSTRC(L"\\\""); + javascript << L"\\\""; } break; case 0x0d: break; case 0x0a: { - javascript << FX_WSTRC(L"\\n"); + javascript << L"\\n"; } break; default: { javascript.AppendChar(oneChar); } break; } @@ -187,22 +187,22 @@ CXFA_FMIdentifierExpression::~CXFA_FMIdentifierExpression() {} void CXFA_FMIdentifierExpression::ToJavaScript(CFX_WideTextBuf& javascript) { CFX_WideString tempStr(m_wsIdentifier); - if (tempStr == FX_WSTRC(L"$")) { - tempStr = FX_WSTRC(L"this"); - } else if (tempStr == FX_WSTRC(L"!")) { - tempStr = FX_WSTRC(L"xfa.datasets"); - } else if (tempStr == FX_WSTRC(L"$data")) { - tempStr = FX_WSTRC(L"xfa.datasets.data"); - } else if (tempStr == FX_WSTRC(L"$event")) { - tempStr = FX_WSTRC(L"xfa.event"); - } else if (tempStr == FX_WSTRC(L"$form")) { - tempStr = FX_WSTRC(L"xfa.form"); - } else if (tempStr == FX_WSTRC(L"$host")) { - tempStr = FX_WSTRC(L"xfa.host"); - } else if (tempStr == FX_WSTRC(L"$layout")) { - tempStr = FX_WSTRC(L"xfa.layout"); - } else if (tempStr == FX_WSTRC(L"$template")) { - tempStr = FX_WSTRC(L"xfa.template"); + if (tempStr == L"$") { + tempStr = L"this"; + } else if (tempStr == L"!") { + tempStr = L"xfa.datasets"; + } else if (tempStr == L"$data") { + tempStr = L"xfa.datasets.data"; + } else if (tempStr == L"$event") { + tempStr = L"xfa.event"; + } else if (tempStr == L"$form") { + tempStr = L"xfa.form"; + } else if (tempStr == L"$host") { + tempStr = L"xfa.host"; + } else if (tempStr == L"$layout") { + tempStr = L"xfa.layout"; + } else if (tempStr == L"$template") { + tempStr = L"xfa.template"; } else if (tempStr[0] == L'!') { tempStr = EXCLAMATION_IN_IDENTIFIER + tempStr.Mid(1); } @@ -240,62 +240,62 @@ CXFA_FMAssignExpression::CXFA_FMAssignExpression( : CXFA_FMBinExpression(line, op, std::move(pExp1), std::move(pExp2)) {} void CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"if ("); + javascript << L"if ("; javascript << gs_lpStrExpFuncName[ISFMOBJECT]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L"))\n{\n"); + javascript << L"))\n{\n"; javascript << gs_lpStrExpFuncName[ASSIGN]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L");\n}\n"); + javascript << L");\n}\n"; CFX_WideTextBuf tempExp1; m_pExp1->ToJavaScript(tempExp1); if (m_pExp1->GetOperatorToken() == TOKidentifier && - tempExp1.AsStringC() != FX_WSTRC(L"this")) { - javascript << FX_WSTRC(L"else\n{\n"); + tempExp1.AsStringC() != L"this") { + javascript << L"else\n{\n"; javascript << tempExp1; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << gs_lpStrExpFuncName[ASSIGN]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L");\n}\n"); + javascript << L");\n}\n"; } } void CXFA_FMAssignExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"if ("); + javascript << L"if ("; javascript << gs_lpStrExpFuncName[ISFMOBJECT]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L"))\n{\n"); + javascript << L"))\n{\n"; javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << gs_lpStrExpFuncName[ASSIGN]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L");\n}\n"); + javascript << L");\n}\n"; CFX_WideTextBuf tempExp1; m_pExp1->ToJavaScript(tempExp1); if (m_pExp1->GetOperatorToken() == TOKidentifier && - tempExp1.AsStringC() != FX_WSTRC(L"this")) { - javascript << FX_WSTRC(L"else\n{\n"); + tempExp1.AsStringC() != L"this") { + javascript << L"else\n{\n"; javascript << RUNTIMEFUNCTIONRETURNVALUE; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << tempExp1; - javascript << FX_WSTRC(L" = "); + javascript << L" = "; javascript << gs_lpStrExpFuncName[ASSIGN]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L");\n}\n"); + javascript << L");\n}\n"; } } @@ -308,11 +308,11 @@ CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression( void CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[LOGICALOR]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression( @@ -324,11 +324,11 @@ CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression( void CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[LOGICALAND]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMEqualityExpression::CXFA_FMEqualityExpression( @@ -352,11 +352,11 @@ void CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& javascript) { ASSERT(false); break; } - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMRelationalExpression::CXFA_FMRelationalExpression( @@ -388,11 +388,11 @@ void CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& javascript) { ASSERT(false); break; } - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression( @@ -414,11 +414,11 @@ void CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& javascript) { ASSERT(false); break; } - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression( @@ -441,11 +441,11 @@ void CXFA_FMMultiplicativeExpression::ToJavaScript( ASSERT(false); break; } - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); + javascript << L", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMPosExpression::CXFA_FMPosExpression( @@ -455,9 +455,9 @@ CXFA_FMPosExpression::CXFA_FMPosExpression( void CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[POSITIVE]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMNegExpression::CXFA_FMNegExpression( @@ -467,9 +467,9 @@ CXFA_FMNegExpression::CXFA_FMNegExpression( void CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[NEGATIVE]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMNotExpression::CXFA_FMNotExpression( @@ -479,9 +479,9 @@ CXFA_FMNotExpression::CXFA_FMNotExpression( void CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[NOT]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMCallExpression::CXFA_FMCallExpression( @@ -574,12 +574,12 @@ void CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { bool isEvalFunc = false; bool isExistsFunc = false; if (IsBuildInFunc(&funcName)) { - if (funcName.AsStringC() == FX_WSTRC(L"Eval")) { + if (funcName.AsStringC() == L"Eval") { isEvalFunc = true; - javascript << FX_WSTRC(L"eval.call(this, "); + javascript << L"eval.call(this, "; javascript << gs_lpStrExpFuncName[CALL]; - javascript << FX_WSTRC(L"Translate"); - } else if (funcName.AsStringC() == FX_WSTRC(L"Exists")) { + javascript << L"Translate"; + } else if (funcName.AsStringC() == L"Exists") { isExistsFunc = true; javascript << gs_lpStrExpFuncName[CALL]; javascript << funcName; @@ -590,19 +590,19 @@ void CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { } else { javascript << funcName; } - javascript << FX_WSTRC(L"("); + javascript << L"("; if (isExistsFunc) { - javascript << FX_WSTRC(L"\n(\nfunction ()\n{\ntry\n{\n"); + javascript << L"\n(\nfunction ()\n{\ntry\n{\n"; if (!m_Arguments.empty()) { const auto& expr = m_Arguments[0]; - javascript << FX_WSTRC(L"return "); + javascript << L"return "; expr->ToJavaScript(javascript); - javascript << FX_WSTRC(L";\n}\n"); + javascript << L";\n}\n"; } else { - javascript << FX_WSTRC(L"return 0;\n}\n"); + javascript << L"return 0;\n}\n"; } - javascript << FX_WSTRC( - L"catch(accessExceptions)\n{\nreturn 0;\n}\n}\n).call(this)\n"); + javascript + << L"catch(accessExceptions)\n{\nreturn 0;\n}\n}\n).call(this)\n"; } else { for (const auto& expr : m_Arguments) { expr->ToJavaScript(javascript); @@ -633,33 +633,33 @@ CXFA_FMDotAccessorExpression::~CXFA_FMDotAccessorExpression() {} void CXFA_FMDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[DOT]; - javascript << FX_WSTRC(L"("); + javascript << L"("; if (m_pExp1) { m_pExp1->ToJavaScript(javascript); } else { - javascript << FX_WSTRC(L"null"); + javascript << L"null"; } - javascript << FX_WSTRC(L", "); - javascript << FX_WSTRC(L"\""); + javascript << L", "; + javascript << L"\""; if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) { m_pExp1->ToJavaScript(javascript); } - javascript << FX_WSTRC(L"\", "); + javascript << L"\", "; if (m_op == TOKdotscream) { - javascript << FX_WSTRC(L"\"#"); + javascript << L"\"#"; javascript << m_wsIdentifier; - javascript << FX_WSTRC(L"\", "); + javascript << L"\", "; } else if (m_op == TOKdotstar) { - javascript << FX_WSTRC(L"\"*\", "); + javascript << L"\"*\", "; } else if (m_op == TOKcall) { - javascript << FX_WSTRC(L"\"\", "); + javascript << L"\"\", "; } else { - javascript << FX_WSTRC(L"\""); + javascript << L"\""; javascript << m_wsIdentifier; - javascript << FX_WSTRC(L"\", "); + javascript << L"\", "; } m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMIndexExpression::CXFA_FMIndexExpression( @@ -674,26 +674,26 @@ CXFA_FMIndexExpression::CXFA_FMIndexExpression( void CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& javascript) { switch (m_accessorIndex) { case ACCESSOR_NO_INDEX: - javascript << FX_WSTRC(L"0"); + javascript << L"0"; break; case ACCESSOR_NO_RELATIVEINDEX: - javascript << FX_WSTRC(L"1"); + javascript << L"1"; break; case ACCESSOR_POSITIVE_INDEX: - javascript << FX_WSTRC(L"2"); + javascript << L"2"; break; case ACCESSOR_NEGATIVE_INDEX: - javascript << FX_WSTRC(L"3"); + javascript << L"3"; break; default: - javascript << FX_WSTRC(L"0"); + javascript << L"0"; } if (!m_bIsStarIndex) { - javascript << FX_WSTRC(L", "); + javascript << L", "; if (m_pExp) { m_pExp->ToJavaScript(javascript); } else { - javascript << FX_WSTRC(L"0"); + javascript << L"0"; } } } @@ -715,19 +715,19 @@ CXFA_FMDotDotAccessorExpression::~CXFA_FMDotDotAccessorExpression() {} void CXFA_FMDotDotAccessorExpression::ToJavaScript( CFX_WideTextBuf& javascript) { javascript << gs_lpStrExpFuncName[DOTDOT]; - javascript << FX_WSTRC(L"("); + javascript << L"("; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L", "); - javascript << FX_WSTRC(L"\""); + javascript << L", "; + javascript << L"\""; if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) { m_pExp1->ToJavaScript(javascript); } - javascript << FX_WSTRC(L"\", "); - javascript << FX_WSTRC(L"\""); + javascript << L"\", "; + javascript << L"\""; javascript << m_wsIdentifier; - javascript << FX_WSTRC(L"\", "); + javascript << L"\", "; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L")"); + javascript << L")"; } CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression( @@ -740,22 +740,22 @@ CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression( std::move(pCallExp)) {} void CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& javascript) { - javascript << FX_WSTRC(L"(\nfunction ()\n{\n"); - javascript << FX_WSTRC(L"var method_return_value = null;\n"); - javascript << FX_WSTRC(L"var accessor_object = "); + javascript << L"(\nfunction ()\n{\n"; + javascript << L"var method_return_value = null;\n"; + javascript << L"var accessor_object = "; m_pExp1->ToJavaScript(javascript); - javascript << FX_WSTRC(L";\n"); - javascript << FX_WSTRC(L"if ("); + javascript << L";\n"; + javascript << L"if ("; javascript << gs_lpStrExpFuncName[ISFMARRAY]; - javascript << FX_WSTRC(L"(accessor_object))\n{\n"); - javascript << FX_WSTRC( - L"for(var index = accessor_object.length - 1; index > 1; index--)\n{\n"); - javascript << FX_WSTRC(L"method_return_value = accessor_object[index]."); + javascript << L"(accessor_object))\n{\n"; + javascript << L"for(var index = accessor_object.length - 1; index > 1; " + L"index--)\n{\n"; + javascript << L"method_return_value = accessor_object[index]."; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L";\n}\n}\n"); - javascript << FX_WSTRC(L"else\n{\nmethod_return_value = accessor_object."); + javascript << L";\n}\n}\n"; + javascript << L"else\n{\nmethod_return_value = accessor_object."; m_pExp2->ToJavaScript(javascript); - javascript << FX_WSTRC(L";\n}\n"); - javascript << FX_WSTRC(L"return method_return_value;\n"); - javascript << FX_WSTRC(L"}\n).call(this)"); + javascript << L";\n}\n"; + javascript << L"return method_return_value;\n"; + javascript << L"}\n).call(this)"; } diff --git a/xfa/fxfa/fm2js/xfa_simpleexpression.h b/xfa/fxfa/fm2js/xfa_simpleexpression.h index 28c37edfb..af1d02eea 100644 --- a/xfa/fxfa/fm2js/xfa_simpleexpression.h +++ b/xfa/fxfa/fm2js/xfa_simpleexpression.h @@ -14,9 +14,8 @@ #include "xfa/fxfa/fm2js/xfa_lexer.h" #define RUNTIMEFUNCTIONRETURNVALUE \ - (FX_WSTRC(L"foxit_xfa_formcalc_runtime_func_return_value")) -#define EXCLAMATION_IN_IDENTIFIER \ - (FX_WSTRC(L"foxit_xfa_formcalc__exclamation__")) + (L"foxit_xfa_formcalc_runtime_func_return_value") +#define EXCLAMATION_IN_IDENTIFIER (L"foxit_xfa_formcalc__exclamation__") enum XFA_FM_SimpleExpressionType { ASSIGN, diff --git a/xfa/fxfa/parser/cscript_eventpseudomodel.cpp b/xfa/fxfa/parser/cscript_eventpseudomodel.cpp index 8a7d80b5d..8cfedd299 100644 --- a/xfa/fxfa/parser/cscript_eventpseudomodel.cpp +++ b/xfa/fxfa/parser/cscript_eventpseudomodel.cpp @@ -25,7 +25,7 @@ void StringProperty(CFXJSE_Value* pValue, wsValue = pValue->ToWideString(); return; } - pValue->SetString(FX_UTF8Encode(wsValue).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } void InterProperty(CFXJSE_Value* pValue, int32_t& iValue, bool bSetting) { diff --git a/xfa/fxfa/parser/cscript_hostpseudomodel.cpp b/xfa/fxfa/parser/cscript_hostpseudomodel.cpp index 97f16f01e..a06e02f56 100644 --- a/xfa/fxfa/parser/cscript_hostpseudomodel.cpp +++ b/xfa/fxfa/parser/cscript_hostpseudomodel.cpp @@ -89,7 +89,7 @@ void CScript_HostPseudoModel::Language(CFXJSE_Value* pValue, return; } pValue->SetString( - FX_UTF8Encode(pNotify->GetAppProvider()->GetLanguage()).AsStringC()); + pNotify->GetAppProvider()->GetLanguage().UTF8Encode().AsStringC()); } void CScript_HostPseudoModel::NumPages(CFXJSE_Value* pValue, @@ -118,8 +118,9 @@ void CScript_HostPseudoModel::Platform(CFXJSE_Value* pValue, return; } pValue->SetString( - FX_UTF8Encode(pNotify->GetAppProvider()->GetPlatform()).AsStringC()); + pNotify->GetAppProvider()->GetPlatform().UTF8Encode().AsStringC()); } + void CScript_HostPseudoModel::Title(CFXJSE_Value* pValue, bool bSetting, XFA_ATTRIBUTE eAttribute) { @@ -137,7 +138,7 @@ void CScript_HostPseudoModel::Title(CFXJSE_Value* pValue, } CFX_WideString wsTitle; pNotify->GetDocEnvironment()->GetTitle(hDoc, wsTitle); - pValue->SetString(FX_UTF8Encode(wsTitle).AsStringC()); + pValue->SetString(wsTitle.UTF8Encode().AsStringC()); } void CScript_HostPseudoModel::ValidationsEnabled(CFXJSE_Value* pValue, @@ -199,7 +200,7 @@ void CScript_HostPseudoModel::Name(CFXJSE_Value* pValue, return; } pValue->SetString( - FX_UTF8Encode(pNotify->GetAppProvider()->GetAppName()).AsStringC()); + pNotify->GetAppProvider()->GetAppName().UTF8Encode().AsStringC()); } void CScript_HostPseudoModel::GotoURL(CFXJSE_Arguments* pArguments) { @@ -306,7 +307,7 @@ void CScript_HostPseudoModel::Response(CFXJSE_Arguments* pArguments) { wsQuestion, wsTitle, wsDefaultAnswer, bMark); CFXJSE_Value* pValue = pArguments->GetReturnValue(); if (pValue) - pValue->SetString(FX_UTF8Encode(wsAnswer).AsStringC()); + pValue->SetString(wsAnswer.UTF8Encode().AsStringC()); } void CScript_HostPseudoModel::DocumentInBatch(CFXJSE_Arguments* pArguments) { @@ -519,7 +520,7 @@ bool CScript_HostPseudoModel::ValidateArgsForMsg(CFXJSE_Arguments* pArguments, return false; } if (pValueArg->IsNull()) { - wsValue = FX_WSTRC(L""); + wsValue = L""; } else { wsValue = pValueArg->ToWideString(); } @@ -674,7 +675,7 @@ void CScript_HostPseudoModel::CurrentDateTime(CFXJSE_Arguments* pArguments) { CFX_WideString wsDataTime = pNotify->GetCurrentDateTime(); CFXJSE_Value* pValue = pArguments->GetReturnValue(); if (pValue) - pValue->SetString(FX_UTF8Encode(wsDataTime).AsStringC()); + pValue->SetString(wsDataTime.UTF8Encode().AsStringC()); } void CScript_HostPseudoModel::ThrowSetLanguageException() const { diff --git a/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp b/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp index a1d1ca578..152b56861 100644 --- a/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp +++ b/xfa/fxfa/parser/cscript_layoutpseudomodel.cpp @@ -90,7 +90,7 @@ void CScript_LayoutPseudoModel::HWXY(CFXJSE_Arguments* pArguments, if (!pDocLayout) { return; } - CFX_RectF rtRect; + CXFA_Measurement measure; CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode); if (!pLayoutItem) { @@ -105,7 +105,8 @@ void CScript_LayoutPseudoModel::HWXY(CFXJSE_Arguments* pArguments, pValue->SetFloat(0); return; } - pLayoutItem->GetRect(rtRect, true); + + CFX_RectF rtRect = pLayoutItem->GetRect(true); switch (layoutModel) { case XFA_LAYOUTMODEL_H: measure.Set(rtRect.height, XFA_UNIT_Pt); @@ -217,13 +218,13 @@ void CScript_LayoutPseudoModel::GetObjArray(CXFA_LayoutProcessor* pDocLayout, if (!pLayoutPage) { return; } - if (wsType == FX_WSTRC(L"pageArea")) { + if (wsType == L"pageArea") { if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) { retArray.Add(pMasterPage); } return; } - if (wsType == FX_WSTRC(L"contentArea")) { + if (wsType == L"contentArea") { for (CXFA_LayoutItem* pItem = pLayoutPage->m_pFirstChild; pItem; pItem = pItem->m_pNextSibling) { if (pItem->m_pFormNode->GetElementType() == XFA_Element::ContentArea) { @@ -288,13 +289,13 @@ void CScript_LayoutPseudoModel::GetObjArray(CXFA_LayoutProcessor* pDocLayout, return; } XFA_Element eType = XFA_Element::Unknown; - if (wsType == FX_WSTRC(L"field")) { + if (wsType == L"field") { eType = XFA_Element::Field; - } else if (wsType == FX_WSTRC(L"draw")) { + } else if (wsType == L"draw") { eType = XFA_Element::Draw; - } else if (wsType == FX_WSTRC(L"subform")) { + } else if (wsType == L"subform") { eType = XFA_Element::Subform; - } else if (wsType == FX_WSTRC(L"area")) { + } else if (wsType == L"area") { eType = XFA_Element::Area; } if (eType != XFA_Element::Unknown) { diff --git a/xfa/fxfa/parser/cxfa_box.cpp b/xfa/fxfa/parser/cxfa_box.cpp index 9d9b4b47a..552c98031 100644 --- a/xfa/fxfa/parser/cxfa_box.cpp +++ b/xfa/fxfa/parser/cxfa_box.cpp @@ -13,53 +13,47 @@ namespace { void GetStrokesInternal(CXFA_Node* pNode, - CXFA_StrokeArray& strokes, + std::vector<CXFA_Stroke>* strokes, bool bNull) { - strokes.RemoveAll(); + strokes->clear(); if (!pNode) return; - strokes.SetSize(8); + strokes->resize(8); int32_t i, j; for (i = 0, j = 0; i < 4; i++) { CXFA_Corner corner = CXFA_Corner(pNode->GetProperty(i, XFA_Element::Corner, i == 0)); - if (corner || i == 0) - strokes.SetAt(j, corner); - else if (bNull) - strokes.SetAt(j, CXFA_Stroke(nullptr)); - else if (i == 1) - strokes.SetAt(j, strokes[0]); - else if (i == 2) - strokes.SetAt(j, strokes[0]); - else - strokes.SetAt(j, strokes[2]); - + if (corner || i == 0) { + (*strokes)[j] = corner; + } else if (!bNull) { + if (i == 1 || i == 2) + (*strokes)[j] = (*strokes)[0]; + else + (*strokes)[j] = (*strokes)[2]; + } j++; CXFA_Edge edge = CXFA_Edge(pNode->GetProperty(i, XFA_Element::Edge, i == 0)); - if (edge || i == 0) - strokes.SetAt(j, edge); - else if (bNull) - strokes.SetAt(j, CXFA_Stroke(nullptr)); - else if (i == 1) - strokes.SetAt(j, strokes[1]); - else if (i == 2) - strokes.SetAt(j, strokes[1]); - else - strokes.SetAt(j, strokes[3]); - + if (edge || i == 0) { + (*strokes)[j] = edge; + } else if (!bNull) { + if (i == 1 || i == 2) + (*strokes)[j] = (*strokes)[1]; + else + (*strokes)[j] = (*strokes)[3]; + } j++; } } -static int32_t Style3D(const CXFA_StrokeArray& strokes, CXFA_Stroke& stroke) { - int32_t iCount = strokes.GetSize(); - if (iCount < 1) +static int32_t Style3D(const std::vector<CXFA_Stroke>& strokes, + CXFA_Stroke& stroke) { + if (strokes.empty()) return 0; stroke = strokes[0]; - for (int32_t i = 1; i < iCount; i++) { + for (size_t i = 1; i < strokes.size(); i++) { CXFA_Stroke find = strokes[i]; if (!find) continue; @@ -105,7 +99,7 @@ CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const { : nullptr); } -void CXFA_Box::GetStrokes(CXFA_StrokeArray& strokes) const { +void CXFA_Box::GetStrokes(std::vector<CXFA_Stroke>* strokes) const { GetStrokesInternal(m_pNode, strokes, false); } @@ -158,8 +152,8 @@ int32_t CXFA_Box::Get3DStyle(bool& bVisible, FX_FLOAT& fThickness) const { if (IsArc()) return 0; - CXFA_StrokeArray strokes; - GetStrokesInternal(m_pNode, strokes, true); + std::vector<CXFA_Stroke> strokes; + GetStrokesInternal(m_pNode, &strokes, true); CXFA_Stroke stroke(nullptr); int32_t iType = Style3D(strokes, stroke); if (iType) { diff --git a/xfa/fxfa/parser/cxfa_box.h b/xfa/fxfa/parser/cxfa_box.h index 014155ceb..a0af2f449 100644 --- a/xfa/fxfa/parser/cxfa_box.h +++ b/xfa/fxfa/parser/cxfa_box.h @@ -7,6 +7,8 @@ #ifndef XFA_FXFA_PARSER_CXFA_BOX_H_ #define XFA_FXFA_PARSER_CXFA_BOX_H_ +#include <vector> + #include "core/fxcrt/fx_system.h" #include "xfa/fxfa/parser/cxfa_data.h" #include "xfa/fxfa/parser/cxfa_edge.h" @@ -28,7 +30,7 @@ class CXFA_Box : public CXFA_Data { int32_t GetPresence() const; int32_t CountEdges() const; CXFA_Edge GetEdge(int32_t nIndex = 0) const; - void GetStrokes(CXFA_StrokeArray& strokes) const; + void GetStrokes(std::vector<CXFA_Stroke>* strokes) const; bool IsCircular() const; bool GetStartAngle(FX_FLOAT& fStartAngle) const; FX_FLOAT GetStartAngle() const { diff --git a/xfa/fxfa/parser/cxfa_containerlayoutitem.cpp b/xfa/fxfa/parser/cxfa_containerlayoutitem.cpp index dd759b699..5ef29f14c 100644 --- a/xfa/fxfa/parser/cxfa_containerlayoutitem.cpp +++ b/xfa/fxfa/parser/cxfa_containerlayoutitem.cpp @@ -34,7 +34,7 @@ CFX_SizeF CXFA_ContainerLayoutItem::GetPageSize() const { pMedium->GetMeasure(XFA_ATTRIBUTE_Long).ToUnit(XFA_UNIT_Pt)); if (pMedium->GetEnum(XFA_ATTRIBUTE_Orientation) == XFA_ATTRIBUTEENUM_Landscape) { - size = CFX_SizeF(size.y, size.x); + size = CFX_SizeF(size.height, size.width); } return size; } diff --git a/xfa/fxfa/parser/cxfa_dataexporter.cpp b/xfa/fxfa/parser/cxfa_dataexporter.cpp index 72d1fa76b..fe9947527 100644 --- a/xfa/fxfa/parser/cxfa_dataexporter.cpp +++ b/xfa/fxfa/parser/cxfa_dataexporter.cpp @@ -24,19 +24,19 @@ CFX_WideString ExportEncodeAttribute(const CFX_WideString& str) { for (int32_t i = 0; i < iLen; i++) { switch (str[i]) { case '&': - textBuf << FX_WSTRC(L"&"); + textBuf << L"&"; break; case '<': - textBuf << FX_WSTRC(L"<"); + textBuf << L"<"; break; case '>': - textBuf << FX_WSTRC(L">"); + textBuf << L">"; break; case '\'': - textBuf << FX_WSTRC(L"'"); + textBuf << L"'"; break; case '\"': - textBuf << FX_WSTRC(L"""); + textBuf << L"""; break; default: textBuf.AppendChar(str[i]); @@ -54,20 +54,20 @@ CFX_WideString ExportEncodeContent(const CFX_WideStringC& str) { continue; if (ch == '&') { - textBuf << FX_WSTRC(L"&"); + textBuf << L"&"; } else if (ch == '<') { - textBuf << FX_WSTRC(L"<"); + textBuf << L"<"; } else if (ch == '>') { - textBuf << FX_WSTRC(L">"); + textBuf << L">"; } else if (ch == '\'') { - textBuf << FX_WSTRC(L"'"); + textBuf << L"'"; } else if (ch == '\"') { - textBuf << FX_WSTRC(L"""); + textBuf << L"""; } else if (ch == ' ') { if (i && str.GetAt(i - 1) != ' ') { textBuf.AppendChar(' '); } else { - textBuf << FX_WSTRC(L" "); + textBuf << L" "; } } else { textBuf.AppendChar(str.GetAt(i)); @@ -87,11 +87,11 @@ void SaveAttribute(CXFA_Node* pNode, return; } wsValue = ExportEncodeAttribute(wsValue); - wsOutput += FX_WSTRC(L" "); + wsOutput += L" "; wsOutput += wsName; - wsOutput += FX_WSTRC(L"=\""); + wsOutput += L"=\""; wsOutput += wsValue; - wsOutput += FX_WSTRC(L"\""); + wsOutput += L"\""; } bool AttributeSaveInDataModel(CXFA_Node* pNode, XFA_ATTRIBUTE eAttribute) { @@ -190,7 +190,7 @@ void RegenerateFormFile_Changed(CXFA_Node* pNode, CFX_WideString wsContentType; pNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); if (pRawValueNode->GetElementType() == XFA_Element::SharpxHTML && - wsContentType == FX_WSTRC(L"text/html")) { + wsContentType == L"text/html") { CFDE_XMLNode* pExDataXML = pNode->GetXMLMappingNode(); if (!pExDataXML) break; @@ -214,7 +214,7 @@ void RegenerateFormFile_Changed(CXFA_Node* pNode, wsChildren += CFX_WideString::FromUTF8( CFX_ByteStringC(pMemStream->GetBuffer(), pMemStream->GetSize())); } else if (pRawValueNode->GetElementType() == XFA_Element::Sharpxml && - wsContentType == FX_WSTRC(L"text/xml")) { + wsContentType == L"text/xml") { CFX_WideString wsRawValue; pRawValueNode->GetAttribute(XFA_ATTRIBUTE_Value, wsRawValue, false); if (wsRawValue.IsEmpty()) @@ -240,20 +240,20 @@ void RegenerateFormFile_Changed(CXFA_Node* pNode, CFX_WideString bodyTagName; bodyTagName = pGrandparentNode->GetCData(XFA_ATTRIBUTE_Name); if (bodyTagName.IsEmpty()) - bodyTagName = FX_WSTRC(L"ListBox1"); + bodyTagName = L"ListBox1"; - buf << FX_WSTRC(L"<"); + buf << L"<"; buf << bodyTagName; - buf << FX_WSTRC(L" xmlns=\"\"\n>"); + buf << L" xmlns=\"\"\n>"; for (int32_t i = 0; i < pdfium::CollectionSize<int32_t>(wsSelTextArray); i++) { - buf << FX_WSTRC(L"<value\n>"); + buf << L"<value\n>"; buf << ExportEncodeContent(wsSelTextArray[i].AsStringC()); - buf << FX_WSTRC(L"</value\n>"); + buf << L"</value\n>"; } - buf << FX_WSTRC(L"</"); + buf << L"</"; buf << bodyTagName; - buf << FX_WSTRC(L"\n>"); + buf << L"\n>"; wsChildren += buf.AsStringC(); buf.Clear(); } else { @@ -305,19 +305,19 @@ void RegenerateFormFile_Changed(CXFA_Node* pNode, pNode->HasAttribute(XFA_ATTRIBUTE_Name)) { CFX_WideStringC wsElement = pNode->GetClassName(); CFX_WideString wsName; - SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), true, wsName); - buf << FX_WSTRC(L"<"); + SaveAttribute(pNode, XFA_ATTRIBUTE_Name, L"name", true, wsName); + buf << L"<"; buf << wsElement; buf << wsName; buf << wsAttrs; if (wsChildren.IsEmpty()) { - buf << FX_WSTRC(L"\n/>"); + buf << L"\n/>"; } else { - buf << FX_WSTRC(L"\n>"); + buf << L"\n>"; buf << wsChildren; - buf << FX_WSTRC(L"</"); + buf << L"</"; buf << wsElement; - buf << FX_WSTRC(L"\n>"); + buf << L"\n>"; } } } @@ -340,7 +340,7 @@ void RegenerateFormFile_Container(CXFA_Node* pNode, pStream->WriteString(L"<", 1); pStream->WriteString(wsElement.c_str(), wsElement.GetLength()); CFX_WideString wsOutput; - SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), true, wsOutput); + SaveAttribute(pNode, XFA_ATTRIBUTE_Name, L"name", true, wsOutput); CFX_WideString wsAttrs; int32_t iAttrs = 0; const uint8_t* pAttrs = @@ -399,10 +399,10 @@ void XFA_DataExporter_RegenerateFormFile( RecognizeXFAVersionNumber( ToNode(pNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Template)), wsVersionNumber); - if (wsVersionNumber.IsEmpty()) { - wsVersionNumber = FX_WSTRC(L"2.8"); - } - wsVersionNumber += FX_WSTRC(L"/\"\n>"); + if (wsVersionNumber.IsEmpty()) + wsVersionNumber = L"2.8"; + + wsVersionNumber += L"/\"\n>"; pStream->WriteString(wsVersionNumber.c_str(), wsVersionNumber.GetLength()); CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); while (pChildNode) { diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp index 374fb98c5..adb8eb2e0 100644 --- a/xfa/fxfa/parser/cxfa_document.cpp +++ b/xfa/fxfa/parser/cxfa_document.cpp @@ -105,6 +105,16 @@ CXFA_Document::~CXFA_Document() { PurgeNodes(); } +CXFA_LayoutProcessor* CXFA_Document::GetLayoutProcessor() { + if (!m_pLayoutProcessor) + m_pLayoutProcessor = new CXFA_LayoutProcessor(this); + return m_pLayoutProcessor; +} + +CXFA_LayoutProcessor* CXFA_Document::GetDocLayout() { + return GetLayoutProcessor(); +} + void CXFA_Document::ClearLayoutData() { delete m_pLayoutProcessor; m_pLayoutProcessor = nullptr; @@ -272,8 +282,7 @@ bool CXFA_Document::IsInteractive() { CXFA_Node* pFormFiller = pPDF->GetChild(0, XFA_Element::Interactive); if (pFormFiller) { m_dwDocFlags |= XFA_DOCFLAG_HasInteractive; - if (pFormFiller->TryContent(wsInteractive) && - wsInteractive == FX_WSTRC(L"1")) { + if (pFormFiller->TryContent(wsInteractive) && wsInteractive == L"1") { m_dwDocFlags |= XFA_DOCFLAG_Interactive; return true; } @@ -381,8 +390,7 @@ void CXFA_Document::DoProtoMerge() { wsURI = CFX_WideStringC(wsUseVal.c_str(), uSharpPos); FX_STRSIZE uLen = wsUseVal.GetLength(); if (uLen >= uSharpPos + 5 && - CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) == - FX_WSTRC(L"#som(") && + CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) == L"#som(" && wsUseVal[uLen - 1] == ')') { wsSOM = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 5, uLen - 1 - uSharpPos - 5); @@ -399,7 +407,7 @@ void CXFA_Document::DoProtoMerge() { wsSOM = CFX_WideStringC(wsUseVal.c_str(), wsUseVal.GetLength()); } - if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) + if (!wsURI.IsEmpty() && wsURI != L".") continue; CXFA_Node* pProtoNode = nullptr; diff --git a/xfa/fxfa/parser/cxfa_image.cpp b/xfa/fxfa/parser/cxfa_image.cpp index 806101847..8cf7fc1e2 100644 --- a/xfa/fxfa/parser/cxfa_image.cpp +++ b/xfa/fxfa/parser/cxfa_image.cpp @@ -22,7 +22,7 @@ bool CXFA_Image::GetContentType(CFX_WideString& wsContentType) { bool CXFA_Image::GetHref(CFX_WideString& wsHref) { if (m_bDefValue) return m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref); - return m_pNode->GetAttribute(FX_WSTRC(L"href"), wsHref); + return m_pNode->GetAttribute(L"href", wsHref); } int32_t CXFA_Image::GetTransferEncoding() { diff --git a/xfa/fxfa/parser/cxfa_layoutitem.cpp b/xfa/fxfa/parser/cxfa_layoutitem.cpp index 264fe4e1b..476d6118a 100644 --- a/xfa/fxfa/parser/cxfa_layoutitem.cpp +++ b/xfa/fxfa/parser/cxfa_layoutitem.cpp @@ -9,6 +9,7 @@ #include "xfa/fxfa/app/xfa_ffnotify.h" #include "xfa/fxfa/parser/cxfa_containerlayoutitem.h" #include "xfa/fxfa/parser/cxfa_contentlayoutitem.h" +#include "xfa/fxfa/parser/cxfa_measurement.h" void XFA_ReleaseLayoutItem(CXFA_LayoutItem* pLayoutItem) { CXFA_LayoutItem* pNode = pLayoutItem->m_pFirstChild; @@ -45,7 +46,175 @@ CXFA_ContainerLayoutItem* CXFA_LayoutItem::AsContainerLayoutItem() { return IsContainerLayoutItem() ? static_cast<CXFA_ContainerLayoutItem*>(this) : nullptr; } + CXFA_ContentLayoutItem* CXFA_LayoutItem::AsContentLayoutItem() { return IsContentLayoutItem() ? static_cast<CXFA_ContentLayoutItem*>(this) : nullptr; } + +CXFA_ContainerLayoutItem* CXFA_LayoutItem::GetPage() const { + for (CXFA_LayoutItem* pCurNode = const_cast<CXFA_LayoutItem*>(this); pCurNode; + pCurNode = pCurNode->m_pParent) { + if (pCurNode->m_pFormNode->GetElementType() == XFA_Element::PageArea) + return static_cast<CXFA_ContainerLayoutItem*>(pCurNode); + } + return nullptr; +} + +CFX_RectF CXFA_LayoutItem::GetRect(bool bRelative) const { + ASSERT(m_bIsContentLayoutItem); + + auto pThis = static_cast<const CXFA_ContentLayoutItem*>(this); + CFX_PointF sPos = pThis->m_sPos; + CFX_SizeF sSize = pThis->m_sSize; + if (bRelative) + return CFX_RectF(sPos, sSize); + + for (CXFA_LayoutItem* pLayoutItem = pThis->m_pParent; pLayoutItem; + pLayoutItem = pLayoutItem->m_pParent) { + if (CXFA_ContentLayoutItem* pContent = pLayoutItem->AsContentLayoutItem()) { + sPos += pContent->m_sPos; + CXFA_Node* pMarginNode = + pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); + if (pMarginNode) { + sPos += CFX_PointF(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset) + .ToUnit(XFA_UNIT_Pt), + pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset) + .ToUnit(XFA_UNIT_Pt)); + } + continue; + } + + if (pLayoutItem->m_pFormNode->GetElementType() == + XFA_Element::ContentArea) { + sPos += CFX_PointF(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X) + .ToUnit(XFA_UNIT_Pt), + pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y) + .ToUnit(XFA_UNIT_Pt)); + break; + } + if (pLayoutItem->m_pFormNode->GetElementType() == XFA_Element::PageArea) + break; + } + return CFX_RectF(sPos, sSize); +} + +CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() { + ASSERT(m_bIsContentLayoutItem); + CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this); + while (pCurNode->m_pPrev) + pCurNode = pCurNode->m_pPrev; + + return pCurNode; +} + +const CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const { + ASSERT(m_bIsContentLayoutItem); + const CXFA_ContentLayoutItem* pCurNode = + static_cast<const CXFA_ContentLayoutItem*>(this); + while (pCurNode->m_pNext) + pCurNode = pCurNode->m_pNext; + + return pCurNode; +} + +CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const { + ASSERT(m_bIsContentLayoutItem); + + return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pPrev; +} + +CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const { + ASSERT(m_bIsContentLayoutItem); + return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pNext; +} + +int32_t CXFA_LayoutItem::GetIndex() const { + ASSERT(m_bIsContentLayoutItem); + int32_t iIndex = 0; + const CXFA_ContentLayoutItem* pCurNode = + static_cast<const CXFA_ContentLayoutItem*>(this); + while (pCurNode->m_pPrev) { + pCurNode = pCurNode->m_pPrev; + ++iIndex; + } + return iIndex; +} + +int32_t CXFA_LayoutItem::GetCount() const { + ASSERT(m_bIsContentLayoutItem); + + int32_t iCount = GetIndex() + 1; + const CXFA_ContentLayoutItem* pCurNode = + static_cast<const CXFA_ContentLayoutItem*>(this); + while (pCurNode->m_pNext) { + pCurNode = pCurNode->m_pNext; + iCount++; + } + return iCount; +} + +void CXFA_LayoutItem::AddChild(CXFA_LayoutItem* pChildItem) { + if (pChildItem->m_pParent) + pChildItem->m_pParent->RemoveChild(pChildItem); + + pChildItem->m_pParent = this; + if (!m_pFirstChild) { + m_pFirstChild = pChildItem; + return; + } + + CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; + while (pExistingChildItem->m_pNextSibling) + pExistingChildItem = pExistingChildItem->m_pNextSibling; + + pExistingChildItem->m_pNextSibling = pChildItem; +} + +void CXFA_LayoutItem::AddHeadChild(CXFA_LayoutItem* pChildItem) { + if (pChildItem->m_pParent) + pChildItem->m_pParent->RemoveChild(pChildItem); + + pChildItem->m_pParent = this; + if (!m_pFirstChild) { + m_pFirstChild = pChildItem; + return; + } + + CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; + m_pFirstChild = pChildItem; + m_pFirstChild->m_pNextSibling = pExistingChildItem; +} + +void CXFA_LayoutItem::InsertChild(CXFA_LayoutItem* pBeforeItem, + CXFA_LayoutItem* pChildItem) { + if (pBeforeItem->m_pParent != this) + return; + if (pChildItem->m_pParent) + pChildItem->m_pParent = nullptr; + + pChildItem->m_pParent = this; + + CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling; + pBeforeItem->m_pNextSibling = pChildItem; + pChildItem->m_pNextSibling = pExistingChildItem; +} + +void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) { + if (pChildItem->m_pParent != this) + return; + + if (m_pFirstChild == pChildItem) { + m_pFirstChild = pChildItem->m_pNextSibling; + } else { + CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; + while (pExistingChildItem && + pExistingChildItem->m_pNextSibling != pChildItem) { + pExistingChildItem = pExistingChildItem->m_pNextSibling; + } + if (pExistingChildItem) + pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling; + } + pChildItem->m_pNextSibling = nullptr; + pChildItem->m_pParent = nullptr; +} diff --git a/xfa/fxfa/parser/cxfa_layoutitem.h b/xfa/fxfa/parser/cxfa_layoutitem.h index 5991cd6f3..9c088601e 100644 --- a/xfa/fxfa/parser/cxfa_layoutitem.h +++ b/xfa/fxfa/parser/cxfa_layoutitem.h @@ -25,15 +25,15 @@ class CXFA_LayoutItem { CXFA_ContentLayoutItem* AsContentLayoutItem(); CXFA_ContainerLayoutItem* GetPage() const; - CXFA_Node* GetFormNode() const; - void GetRect(CFX_RectF& rtLayout, bool bRelative = false) const; + CXFA_Node* GetFormNode() const { return m_pFormNode; } + CFX_RectF GetRect(bool bRelative) const; + int32_t GetIndex() const; int32_t GetCount() const; - CXFA_LayoutItem* GetParent() const; - const CXFA_LayoutItem* GetFirst() const; + + CXFA_LayoutItem* GetParent() const { return m_pParent; } CXFA_LayoutItem* GetFirst(); const CXFA_LayoutItem* GetLast() const; - CXFA_LayoutItem* GetLast(); CXFA_LayoutItem* GetPrev() const; CXFA_LayoutItem* GetNext() const; diff --git a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp index 0a057f543..f38ef0ebf 100644 --- a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp +++ b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp @@ -63,9 +63,9 @@ uint32_t GetRelevant(CXFA_Node* pFormItem, uint32_t dwParentRelvant) { uint32_t dwRelevant = XFA_WidgetStatus_Viewable | XFA_WidgetStatus_Printable; CFX_WideStringC wsRelevant; if (pFormItem->TryCData(XFA_ATTRIBUTE_Relevant, wsRelevant)) { - if (wsRelevant == FX_WSTRC(L"+print") || wsRelevant == FX_WSTRC(L"print")) + if (wsRelevant == L"+print" || wsRelevant == L"print") dwRelevant &= ~XFA_WidgetStatus_Viewable; - else if (wsRelevant == FX_WSTRC(L"-print")) + else if (wsRelevant == L"-print") dwRelevant &= ~XFA_WidgetStatus_Printable; } @@ -140,14 +140,14 @@ CXFA_Node* ResolveBreakTarget(CXFA_Node* pPageSetRoot, CFX_WideString wsTargetAll(wsTargetExpr); wsTargetAll.TrimLeft(); wsTargetAll.TrimRight(); - int32_t iSpliteIndex = 0; + int32_t iSplitIndex = 0; bool bTargetAllFind = true; - while (iSpliteIndex != -1) { + while (iSplitIndex != -1) { CFX_WideString wsExpr; - int32_t iSpliteNextIndex = 0; + int32_t iSplitNextIndex = 0; if (!bTargetAllFind) { - iSpliteNextIndex = wsTargetAll.Find(' ', iSpliteIndex); - wsExpr = wsTargetAll.Mid(iSpliteIndex, iSpliteNextIndex - iSpliteIndex); + iSplitNextIndex = wsTargetAll.Find(' ', iSplitIndex); + wsExpr = wsTargetAll.Mid(iSplitIndex, iSplitNextIndex - iSplitIndex); } else { wsExpr = wsTargetAll; } @@ -163,8 +163,7 @@ CXFA_Node* ResolveBreakTarget(CXFA_Node* pPageSetRoot, return pNode; } else if (bNewExprStyle) { CFX_WideString wsProcessedTarget = wsExpr; - if (wsExpr.Left(4) == FX_WSTRC(L"som(") && - wsExpr.Right(1) == FX_WSTRC(L")")) { + if (wsExpr.Left(4) == L"som(" && wsExpr.Right(1) == L")") { wsProcessedTarget = wsExpr.Mid(4, wsExpr.GetLength() - 5); } XFA_RESOLVENODE_RS rs; @@ -176,7 +175,7 @@ CXFA_Node* ResolveBreakTarget(CXFA_Node* pPageSetRoot, if (iCount > 0 && rs.nodes[0]->IsNode()) return rs.nodes[0]->AsNode(); } - iSpliteIndex = iSpliteNextIndex; + iSplitIndex = iSplitNextIndex; } return nullptr; } @@ -445,8 +444,8 @@ void CXFA_LayoutPageMgr::SubmitContentItem( m_bCreateOverFlowPage = false; } - if (eStatus != XFA_ItemLayoutProcessorResult_Done) { - if (eStatus == XFA_ItemLayoutProcessorResult_PageFullBreak && + if (eStatus != XFA_ItemLayoutProcessorResult::Done) { + if (eStatus == XFA_ItemLayoutProcessorResult::PageFullBreak && m_CurrentContainerRecordIter == GetTailPosition()) { AppendNewPage(); } @@ -467,7 +466,7 @@ FX_FLOAT CXFA_LayoutPageMgr::GetAvailHeight() { return fAvailHeight; if (m_CurrentContainerRecordIter == m_ProposedContainerRecords.begin()) return 0.0f; - return XFA_LAYOUT_FLOAT_MAX; + return FLT_MAX; } bool XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node* pTestScript) { @@ -665,7 +664,7 @@ void CXFA_LayoutPageMgr::FinishPaginatedPageSets() { pContentChildLayoutItem->m_pNextSibling) { if (CXFA_ContentLayoutItem* pContent = pContentChildLayoutItem->AsContentLayoutItem()) { - fUsedHeight += pContent->m_sSize.y; + fUsedHeight += pContent->m_sSize.height; } } rgUsedHeights.Add(fUsedHeight); @@ -1588,11 +1587,6 @@ void CXFA_LayoutPageMgr::ClearData() { m_pPageSetMap.clear(); } -CXFA_LayoutItem* CXFA_LayoutPageMgr::FindOrCreateLayoutItem( - CXFA_Node* pFormNode) { - return pFormNode->GetDocument()->GetNotify()->OnCreateLayoutItem(pFormNode); -} - void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItem* pParentLayoutItem) { CXFA_LayoutItem* pNextLayoutItem; CXFA_LayoutItem* pCurLayoutItem = pParentLayoutItem->m_pFirstChild; diff --git a/xfa/fxfa/parser/cxfa_layoutpagemgr.h b/xfa/fxfa/parser/cxfa_layoutpagemgr.h index 1133e1778..3c8e7f9d1 100644 --- a/xfa/fxfa/parser/cxfa_layoutpagemgr.h +++ b/xfa/fxfa/parser/cxfa_layoutpagemgr.h @@ -50,7 +50,6 @@ class CXFA_LayoutPageMgr { bool ProcessBookendLeaderOrTrailer(CXFA_Node* pBookendNode, bool bLeader, CXFA_Node*& pBookendAppendNode); - CXFA_LayoutItem* FindOrCreateLayoutItem(CXFA_Node* pFormNode); protected: bool AppendNewPage(bool bFirstTemPage = false); diff --git a/xfa/fxfa/parser/cxfa_layoutprocessor.cpp b/xfa/fxfa/parser/cxfa_layoutprocessor.cpp index ea1064a4b..e179d3898 100644 --- a/xfa/fxfa/parser/cxfa_layoutprocessor.cpp +++ b/xfa/fxfa/parser/cxfa_layoutprocessor.cpp @@ -17,18 +17,6 @@ #include "xfa/fxfa/parser/xfa_object.h" #include "xfa/fxfa/parser/xfa_utils.h" -CXFA_LayoutProcessor* CXFA_Document::GetLayoutProcessor() { - if (!m_pLayoutProcessor) { - m_pLayoutProcessor = new CXFA_LayoutProcessor(this); - ASSERT(m_pLayoutProcessor); - } - return m_pLayoutProcessor; -} - -CXFA_LayoutProcessor* CXFA_Document::GetDocLayout() { - return GetLayoutProcessor(); -} - CXFA_LayoutProcessor::CXFA_LayoutProcessor(CXFA_Document* pDocument) : m_pDocument(pDocument), m_nProgressCounter(0), @@ -80,9 +68,9 @@ int32_t CXFA_LayoutProcessor::DoLayout(IFX_Pause* pPause) { FX_FLOAT fPosY = pFormNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt); do { FX_FLOAT fAvailHeight = m_pLayoutPageMgr->GetAvailHeight(); - eStatus = - m_pRootItemLayoutProcessor->DoLayout(true, fAvailHeight, fAvailHeight); - if (eStatus != XFA_ItemLayoutProcessorResult_Done) + eStatus = m_pRootItemLayoutProcessor->DoLayout(true, fAvailHeight, + fAvailHeight, nullptr); + if (eStatus != XFA_ItemLayoutProcessorResult::Done) m_nProgressCounter++; CXFA_ContentLayoutItem* pLayoutItem = @@ -91,16 +79,16 @@ int32_t CXFA_LayoutProcessor::DoLayout(IFX_Pause* pPause) { pLayoutItem->m_sPos = CFX_PointF(fPosX, fPosY); m_pLayoutPageMgr->SubmitContentItem(pLayoutItem, eStatus); - } while (eStatus != XFA_ItemLayoutProcessorResult_Done && + } while (eStatus != XFA_ItemLayoutProcessorResult::Done && (!pPause || !pPause->NeedToPauseNow())); - if (eStatus == XFA_ItemLayoutProcessorResult_Done) { + if (eStatus == XFA_ItemLayoutProcessorResult::Done) { m_pLayoutPageMgr->FinishPaginatedPageSets(); m_pLayoutPageMgr->SyncLayoutData(); m_bNeeLayout = false; m_rgChangedContainers.RemoveAll(); } - return 100 * (eStatus == XFA_ItemLayoutProcessorResult_Done + return 100 * (eStatus == XFA_ItemLayoutProcessorResult::Done ? m_nProgressCounter : m_nProgressCounter - 1) / m_nProgressCounter; diff --git a/xfa/fxfa/parser/cxfa_line.cpp b/xfa/fxfa/parser/cxfa_line.cpp index f0d9a0bbf..38de0d8ca 100644 --- a/xfa/fxfa/parser/cxfa_line.cpp +++ b/xfa/fxfa/parser/cxfa_line.cpp @@ -12,9 +12,8 @@ int32_t CXFA_Line::GetHand() { return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand); } -bool CXFA_Line::GetSlop() { - XFA_ATTRIBUTEENUM eSlop = m_pNode->GetEnum(XFA_ATTRIBUTE_Slope); - return eSlop == XFA_ATTRIBUTEENUM_Slash; +bool CXFA_Line::GetSlope() { + return m_pNode->GetEnum(XFA_ATTRIBUTE_Slope) == XFA_ATTRIBUTEENUM_Slash; } CXFA_Edge CXFA_Line::GetEdge() { diff --git a/xfa/fxfa/parser/cxfa_line.h b/xfa/fxfa/parser/cxfa_line.h index bf180295d..f014cc061 100644 --- a/xfa/fxfa/parser/cxfa_line.h +++ b/xfa/fxfa/parser/cxfa_line.h @@ -18,7 +18,7 @@ class CXFA_Line : public CXFA_Data { explicit CXFA_Line(CXFA_Node* pNode) : CXFA_Data(pNode) {} int32_t GetHand(); - bool GetSlop(); + bool GetSlope(); CXFA_Edge GetEdge(); }; diff --git a/xfa/fxfa/parser/cxfa_measurement.cpp b/xfa/fxfa/parser/cxfa_measurement.cpp index b1843a8b4..ebf7b7bff 100644 --- a/xfa/fxfa/parser/cxfa_measurement.cpp +++ b/xfa/fxfa/parser/cxfa_measurement.cpp @@ -119,21 +119,21 @@ bool CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const { } XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) { - if (wsUnit == FX_WSTRC(L"mm")) + if (wsUnit == L"mm") return XFA_UNIT_Mm; - if (wsUnit == FX_WSTRC(L"pt")) + if (wsUnit == L"pt") return XFA_UNIT_Pt; - if (wsUnit == FX_WSTRC(L"in")) + if (wsUnit == L"in") return XFA_UNIT_In; - if (wsUnit == FX_WSTRC(L"cm")) + if (wsUnit == L"cm") return XFA_UNIT_Cm; - if (wsUnit == FX_WSTRC(L"pc")) + if (wsUnit == L"pc") return XFA_UNIT_Pc; - if (wsUnit == FX_WSTRC(L"mp")) + if (wsUnit == L"mp") return XFA_UNIT_Mp; - if (wsUnit == FX_WSTRC(L"em")) + if (wsUnit == L"em") return XFA_UNIT_Em; - if (wsUnit == FX_WSTRC(L"%")) + if (wsUnit == L"%") return XFA_UNIT_Percent; return XFA_UNIT_Unknown; } diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp index bc2a10c08..1e508969d 100644 --- a/xfa/fxfa/parser/cxfa_node.cpp +++ b/xfa/fxfa/parser/cxfa_node.cpp @@ -511,7 +511,7 @@ CXFA_Node::~CXFA_Node() { pNode = pNext; } if (m_pXMLNode && IsOwnXMLNode()) - m_pXMLNode->Release(); + delete m_pXMLNode; } CXFA_Node* CXFA_Node::Clone(bool bRecursive) { @@ -1097,7 +1097,7 @@ void CXFA_Node::Script_TreeClass_All(CFXJSE_Value* pValue, uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL; CFX_WideString wsName; GetAttribute(XFA_ATTRIBUTE_Name, wsName); - CFX_WideString wsExpression = wsName + FX_WSTRC(L"[*]"); + CFX_WideString wsExpression = wsName + L"[*]"; Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag); } @@ -1109,8 +1109,7 @@ void CXFA_Node::Script_TreeClass_Nodes(CFXJSE_Value* pValue, return; if (bSetting) { CFX_WideString wsMessage = L"Unable to set "; - FXJSE_ThrowMessage( - FX_UTF8Encode(wsMessage.c_str(), wsMessage.GetLength()).AsStringC()); + FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC()); } else { CXFA_AttachNodeList* pNodeList = new CXFA_AttachNodeList(m_pDocument, this); pValue->SetObject(pNodeList, pScriptContext->GetJseNormalClass()); @@ -1124,10 +1123,8 @@ void CXFA_Node::Script_TreeClass_ClassAll(CFXJSE_Value* pValue, ThrowInvalidPropertyException(); return; } - uint32_t dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL; - CFX_WideString wsExpression = - FX_WSTRC(L"#") + GetClassName() + FX_WSTRC(L"[*]"); + CFX_WideString wsExpression = L"#" + GetClassName() + L"[*]"; Script_Som_ResolveNodeList(pValue, wsExpression, dwFlag); } @@ -1175,7 +1172,7 @@ void CXFA_Node::Script_TreeClass_SomExpression(CFXJSE_Value* pValue, } CFX_WideString wsSOMExpression; GetSOMExpression(wsSOMExpression); - pValue->SetString(FX_UTF8Encode(wsSOMExpression).AsStringC()); + pValue->SetString(wsSOMExpression.UTF8Encode().AsStringC()); } void CXFA_Node::Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments) { @@ -1239,7 +1236,7 @@ void CXFA_Node::Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments) { GetAttribute(wsExpression.AsStringC(), wsValue); CFXJSE_Value* pValue = pArguments->GetReturnValue(); if (pValue) - pValue->SetString(FX_UTF8Encode(wsValue).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } void CXFA_Node::Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments) { @@ -1406,10 +1403,8 @@ void CXFA_Node::Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments) { } pFakeRoot->SetFlag(XFA_NodeFlag_HasRemovedChildren, false); } else { - if (pFakeXMLRoot) { - pFakeXMLRoot->Release(); - pFakeXMLRoot = nullptr; - } + delete pFakeXMLRoot; + pFakeXMLRoot = nullptr; } } @@ -1511,7 +1506,7 @@ void CXFA_Node::Script_NodeClass_Ns(CFXJSE_Value* pValue, CFX_WideString wsNameSpace; TryNamespace(wsNameSpace); - pValue->SetString(FX_UTF8Encode(wsNameSpace).AsStringC()); + pValue->SetString(wsNameSpace.UTF8Encode().AsStringC()); } void CXFA_Node::Script_NodeClass_Model(CFXJSE_Value* pValue, @@ -1861,8 +1856,7 @@ void CXFA_Node::Script_Attribute_String(CFXJSE_Value* pValue, } else { CFX_WideString wsValue; GetAttribute(eAttribute, wsValue); - pValue->SetString( - FX_UTF8Encode(wsValue.c_str(), wsValue.GetLength()).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } } @@ -1876,8 +1870,7 @@ void CXFA_Node::Script_Attribute_StringRead(CFXJSE_Value* pValue, CFX_WideString wsValue; GetAttribute(eAttribute, wsValue); - pValue->SetString( - FX_UTF8Encode(wsValue.c_str(), wsValue.GetLength()).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } void CXFA_Node::Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments) { @@ -1955,7 +1948,7 @@ void CXFA_Node::Script_Som_Message(CFXJSE_Value* pValue, default: break; } - pValue->SetString(FX_UTF8Encode(wsMessage).AsStringC()); + pValue->SetString(wsMessage.UTF8Encode().AsStringC()); } } @@ -2041,8 +2034,7 @@ void CXFA_Node::Script_Som_DefaultValue(CFXJSE_Value* pValue, CFX_Decimal decimal(content.AsStringC()); pValue->SetFloat((FX_FLOAT)(double)decimal); } else { - pValue->SetString( - FX_UTF8Encode(content.c_str(), content.GetLength()).AsStringC()); + pValue->SetString(content.UTF8Encode().AsStringC()); } } } @@ -2060,8 +2052,7 @@ void CXFA_Node::Script_Som_DefaultValue_Read(CFXJSE_Value* pValue, pValue->SetNull(); return; } - pValue->SetString( - FX_UTF8Encode(content.c_str(), content.GetLength()).AsStringC()); + pValue->SetString(content.UTF8Encode().AsStringC()); } void CXFA_Node::Script_Boolean_Value(CFXJSE_Value* pValue, @@ -2082,7 +2073,7 @@ void CXFA_Node::Script_Boolean_Value(CFXJSE_Value* pValue, SetScriptContent(wsNewValue, wsFormatValue, true, true); } else { CFX_WideString wsValue = GetScriptContent(true); - pValue->SetBoolean(wsValue == FX_WSTRC(L"1")); + pValue->SetBoolean(wsValue == L"1"); } } @@ -2112,7 +2103,7 @@ void CXFA_Node::Script_Som_BorderColor(CFXJSE_Value* pValue, ArgbDecode(color, a, r, g, b); CFX_WideString strColor; strColor.Format(L"%d,%d,%d", r, g, b); - pValue->SetString(FX_UTF8Encode(strColor).AsStringC()); + pValue->SetString(strColor.UTF8Encode().AsStringC()); } } @@ -2137,7 +2128,7 @@ void CXFA_Node::Script_Som_BorderWidth(CFXJSE_Value* pValue, CXFA_Edge edge = border.GetEdge(0); CXFA_Measurement thickness = edge.GetMSThickness(); thickness.ToString(wsThickness); - pValue->SetString(FX_UTF8Encode(wsThickness).AsStringC()); + pValue->SetString(wsThickness.UTF8Encode().AsStringC()); } } @@ -2170,7 +2161,7 @@ void CXFA_Node::Script_Som_FillColor(CFXJSE_Value* pValue, ArgbDecode(color, a, r, g, b); CFX_WideString wsColor; wsColor.Format(L"%d,%d,%d", r, g, b); - pValue->SetString(FX_UTF8Encode(wsColor).AsStringC()); + pValue->SetString(wsColor.UTF8Encode().AsStringC()); } } @@ -2207,12 +2198,10 @@ void CXFA_Node::Script_Draw_DefaultValue(CFXJSE_Value* pValue, } } else { CFX_WideString content = GetScriptContent(true); - if (content.IsEmpty()) { + if (content.IsEmpty()) pValue->SetNull(); - } else { - pValue->SetString( - FX_UTF8Encode(content.c_str(), content.GetLength()).AsStringC()); - } + else + pValue->SetString(content.UTF8Encode().AsStringC()); } } @@ -2261,8 +2250,7 @@ void CXFA_Node::Script_Field_DefaultValue(CFXJSE_Value* pValue, if (pNode && pNode->GetElementType() == XFA_Element::Decimal) { if (pUIChild->GetElementType() == XFA_Element::NumericEdit && (pNode->GetInteger(XFA_ATTRIBUTE_FracDigits) == -1)) { - pValue->SetString( - FX_UTF8Encode(content.c_str(), content.GetLength()).AsStringC()); + pValue->SetString(content.UTF8Encode().AsStringC()); } else { CFX_Decimal decimal(content.AsStringC()); pValue->SetFloat((FX_FLOAT)(double)decimal); @@ -2275,8 +2263,7 @@ void CXFA_Node::Script_Field_DefaultValue(CFXJSE_Value* pValue, CFX_Decimal decimal(content.AsStringC()); pValue->SetFloat((FX_FLOAT)(double)decimal); } else { - pValue->SetString( - FX_UTF8Encode(content.c_str(), content.GetLength()).AsStringC()); + pValue->SetString(content.UTF8Encode().AsStringC()); } } } @@ -2294,7 +2281,7 @@ void CXFA_Node::Script_Field_EditValue(CFXJSE_Value* pValue, } else { CFX_WideString wsValue; pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Edit); - pValue->SetString(FX_UTF8Encode(wsValue).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } } @@ -2326,7 +2313,7 @@ void CXFA_Node::Script_Som_FontColor(CFXJSE_Value* pValue, ArgbDecode(color, a, r, g, b); CFX_WideString wsColor; wsColor.Format(L"%d,%d,%d", r, g, b); - pValue->SetString(FX_UTF8Encode(wsColor).AsStringC()); + pValue->SetString(wsColor.UTF8Encode().AsStringC()); } } @@ -2348,7 +2335,7 @@ void CXFA_Node::Script_Field_FormattedValue(CFXJSE_Value* pValue, } else { CFX_WideString wsValue; pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Display); - pValue->SetString(FX_UTF8Encode(wsValue).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } } @@ -2369,7 +2356,7 @@ void CXFA_Node::Script_Som_Mandatory(CFXJSE_Value* pValue, CFX_WideString wsValue; if (pInfo) wsValue = pInfo->pName; - pValue->SetString(FX_UTF8Encode(wsValue).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } } @@ -2480,13 +2467,11 @@ void CXFA_Node::Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments) { return; } CFX_WideString wsValue; - bool bHasItem = pWidgetData->GetChoiceListItem(wsValue, iIndex, true); - if (bHasItem) { - pArguments->GetReturnValue()->SetString( - FX_UTF8Encode(wsValue.c_str(), wsValue.GetLength()).AsStringC()); - } else { + if (!pWidgetData->GetChoiceListItem(wsValue, iIndex, true)) { pArguments->GetReturnValue()->SetNull(); + return; } + pArguments->GetReturnValue()->SetString(wsValue.UTF8Encode().AsStringC()); } void CXFA_Node::Script_Field_BoundItem(CFXJSE_Arguments* pArguments) { @@ -2505,7 +2490,7 @@ void CXFA_Node::Script_Field_BoundItem(CFXJSE_Arguments* pArguments) { pWidgetData->GetItemValue(wsValue.AsStringC(), wsBoundValue); CFXJSE_Value* pValue = pArguments->GetReturnValue(); if (pValue) - pValue->SetString(FX_UTF8Encode(wsBoundValue).AsStringC()); + pValue->SetString(wsBoundValue.UTF8Encode().AsStringC()); } void CXFA_Node::Script_Field_GetItemState(CFXJSE_Arguments* pArguments) { @@ -2557,13 +2542,11 @@ void CXFA_Node::Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments) { return; } CFX_WideString wsValue; - bool bHasItem = pWidgetData->GetChoiceListItem(wsValue, iIndex, false); - if (bHasItem) { - pArguments->GetReturnValue()->SetString( - FX_UTF8Encode(wsValue.c_str(), wsValue.GetLength()).AsStringC()); - } else { + if (!pWidgetData->GetChoiceListItem(wsValue, iIndex, false)) { pArguments->GetReturnValue()->SetNull(); + return; } + pArguments->GetReturnValue()->SetString(wsValue.UTF8Encode().AsStringC()); } void CXFA_Node::Script_Field_SetItemState(CFXJSE_Arguments* pArguments) { @@ -2649,7 +2632,7 @@ void CXFA_Node::Script_ExclGroup_DefaultAndRawValue(CFXJSE_Value* pValue, if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) { pValue->SetNull(); } else { - pValue->SetString(FX_UTF8Encode(wsValue).AsStringC()); + pValue->SetString(wsValue.UTF8Encode().AsStringC()); } } } @@ -2817,9 +2800,7 @@ void CXFA_Node::Script_Subform_Locale(CFXJSE_Value* pValue, } else { CFX_WideString wsLocaleName; GetLocaleName(wsLocaleName); - pValue->SetString( - FX_UTF8Encode(wsLocaleName.c_str(), wsLocaleName.GetLength()) - .AsStringC()); + pValue->SetString(wsLocaleName.UTF8Encode().AsStringC()); } } @@ -3418,11 +3399,9 @@ void CXFA_Node::Script_Form_Checksum(CFXJSE_Value* pValue, SetAttribute(XFA_ATTRIBUTE_Checksum, pValue->ToWideString().AsStringC()); return; } - CFX_WideString wsChecksum; GetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum, false); - pValue->SetString( - FX_UTF8Encode(wsChecksum.c_str(), wsChecksum.GetLength()).AsStringC()); + pValue->SetString(wsChecksum.UTF8Encode().AsStringC()); } void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments) { @@ -3430,7 +3409,6 @@ void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments) { ThrowParamCountMismatchException(L"getAttribute"); return; } - CFX_ByteString bsAttributeName = pArguments->GetUTF8String(0); CFX_WideString wsAttributeValue; CFDE_XMLNode* pXMLNode = GetXMLMappingNode(); @@ -3440,8 +3418,7 @@ void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments) { wsAttributeValue); } pArguments->GetReturnValue()->SetString( - FX_UTF8Encode(wsAttributeValue.c_str(), wsAttributeValue.GetLength()) - .AsStringC()); + wsAttributeValue.UTF8Encode().AsStringC()); } void CXFA_Node::Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments) { @@ -3449,7 +3426,6 @@ void CXFA_Node::Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments) { ThrowParamCountMismatchException(L"setAttribute"); return; } - CFX_ByteString bsValue = pArguments->GetUTF8String(0); CFX_ByteString bsName = pArguments->GetUTF8String(1); CFDE_XMLNode* pXMLNode = GetXMLMappingNode(); @@ -3495,8 +3471,7 @@ void CXFA_Node::Script_Packet_Content(CFXJSE_Value* pValue, CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode); pXMLElement->GetTextData(wsTextData); } - pValue->SetString( - FX_UTF8Encode(wsTextData.c_str(), wsTextData.GetLength()).AsStringC()); + pValue->SetString(wsTextData.UTF8Encode().AsStringC()); } } @@ -3618,7 +3593,7 @@ void CXFA_Node::Script_Script_Stateless(CFXJSE_Value* pValue, ThrowInvalidPropertyException(); return; } - pValue->SetString(FX_UTF8Encode(FX_WSTRC(L"0")).AsStringC()); + pValue->SetString(FX_UTF8Encode(CFX_WideStringC(L"0", 1)).AsStringC()); } void CXFA_Node::Script_Encrypt_Format(CFXJSE_Value* pValue, @@ -3654,7 +3629,7 @@ bool CXFA_Node::SetAttribute(XFA_ATTRIBUTE eAttr, case XFA_ATTRIBUTETYPE_Cdata: return SetCData(pAttr->eName, CFX_WideString(wsValue), bNotify); case XFA_ATTRIBUTETYPE_Boolean: - return SetBoolean(pAttr->eName, wsValue != FX_WSTRC(L"0"), bNotify); + return SetBoolean(pAttr->eName, wsValue != L"0", bNotify); case XFA_ATTRIBUTETYPE_Integer: return SetInteger(pAttr->eName, FXSYS_round(FXSYS_wcstof(wsValue.c_str(), @@ -3703,7 +3678,7 @@ bool CXFA_Node::GetAttribute(XFA_ATTRIBUTE eAttr, if (!TryBoolean(pAttr->eName, bValue, bUseDefault)) { return false; } - wsValue = bValue ? FX_WSTRC(L"1") : FX_WSTRC(L"0"); + wsValue = bValue ? L"1" : L"0"; return true; } break; case XFA_ATTRIBUTETYPE_Integer: { @@ -3894,7 +3869,7 @@ bool CXFA_Node::SetCData(XFA_ATTRIBUTE eAttr, ASSERT(m_pXMLNode->GetType() == FDE_XMLNODE_Element); CFX_WideString wsAttrName = pInfo->pName; if (pInfo->eName == XFA_ATTRIBUTE_ContentType) { - wsAttrName = FX_WSTRC(L"xfa:") + wsAttrName; + wsAttrName = L"xfa:" + wsAttrName; } static_cast<CFDE_XMLElement*>(m_pXMLNode)->SetString(wsAttrName, wsValue); } @@ -4200,16 +4175,16 @@ bool CXFA_Node::SetScriptContent(const CFX_WideString& wsContent, CFX_WideString wsContentType; if (GetElementType() == XFA_Element::ExData) { GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); - if (wsContentType == FX_WSTRC(L"text/html")) { - wsContentType = FX_WSTRC(L""); + if (wsContentType == L"text/html") { + wsContentType = L""; SetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType.AsStringC()); } } CXFA_Node* pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild); if (!pContentRawDataNode) { pContentRawDataNode = CreateSamePacketNode( - (wsContentType == FX_WSTRC(L"text/xml")) ? XFA_Element::Sharpxml - : XFA_Element::Sharptext); + (wsContentType == L"text/xml") ? XFA_Element::Sharpxml + : XFA_Element::Sharptext); InsertChild(pContentRawDataNode); } return pContentRawDataNode->SetScriptContent( @@ -4293,8 +4268,7 @@ bool CXFA_Node::TryContent(CFX_WideString& wsContent, } CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild); if (pChildValue && XFA_FieldIsMultiListBox(this)) { - pChildValue->SetAttribute(XFA_ATTRIBUTE_ContentType, - FX_WSTRC(L"text/xml")); + pChildValue->SetAttribute(XFA_ATTRIBUTE_ContentType, L"text/xml"); } return pChildValue ? pChildValue->TryContent(wsContent, bScriptModify, bProto) @@ -4308,9 +4282,9 @@ bool CXFA_Node::TryContent(CFX_WideString& wsContent, if (GetElementType() == XFA_Element::ExData) { CFX_WideString wsContentType; GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); - if (wsContentType == FX_WSTRC(L"text/html")) { + if (wsContentType == L"text/html") { element = XFA_Element::SharpxHTML; - } else if (wsContentType == FX_WSTRC(L"text/xml")) { + } else if (wsContentType == L"text/xml") { element = XFA_Element::Sharpxml; } } diff --git a/xfa/fxfa/parser/cxfa_nodehelper.cpp b/xfa/fxfa/parser/cxfa_nodehelper.cpp index 18a9594da..229089231 100644 --- a/xfa/fxfa/parser/cxfa_nodehelper.cpp +++ b/xfa/fxfa/parser/cxfa_nodehelper.cpp @@ -330,7 +330,7 @@ bool CXFA_NodeHelper::CreateNode_ForCondition(CFX_WideString& wsCondition) { } } if (bAll) { - wsIndex = FX_WSTRC(L"1"); + wsIndex = L"1"; m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeAll; } else { m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne; diff --git a/xfa/fxfa/parser/cxfa_object.cpp b/xfa/fxfa/parser/cxfa_object.cpp index 45e34424a..c8cd354b4 100644 --- a/xfa/fxfa/parser/cxfa_object.cpp +++ b/xfa/fxfa/parser/cxfa_object.cpp @@ -42,9 +42,7 @@ void CXFA_Object::Script_ObjectClass_ClassName(CFXJSE_Value* pValue, ThrowInvalidPropertyException(); return; } - CFX_WideStringC className = GetClassName(); - pValue->SetString( - FX_UTF8Encode(className.c_str(), className.GetLength()).AsStringC()); + pValue->SetString(FX_UTF8Encode(GetClassName()).AsStringC()); } void CXFA_Object::ThrowInvalidPropertyException() const { @@ -71,6 +69,5 @@ void CXFA_Object::ThrowException(const FX_WCHAR* str, ...) const { va_start(arg_ptr, str); wsMessage.FormatV(str, arg_ptr); va_end(arg_ptr); - FXJSE_ThrowMessage( - FX_UTF8Encode(wsMessage.c_str(), wsMessage.GetLength()).AsStringC()); + FXJSE_ThrowMessage(wsMessage.UTF8Encode().AsStringC()); } diff --git a/xfa/fxfa/parser/cxfa_resolveprocessor.cpp b/xfa/fxfa/parser/cxfa_resolveprocessor.cpp index 271e14be6..3ef4e976c 100644 --- a/xfa/fxfa/parser/cxfa_resolveprocessor.cpp +++ b/xfa/fxfa/parser/cxfa_resolveprocessor.cpp @@ -497,7 +497,8 @@ int32_t CXFA_ResolveProcessor::ResolveAsterisk(CXFA_ResolveNodesData& rnd) { nodes.Append((CXFA_ObjArray&)array); return nodes.GetSize(); } -int32_t CXFA_ResolveProcessor::ResolvePopStack(CFX_Int32Array& stack) { +int32_t CXFA_ResolveProcessor::ResolvePopStack( + CFX_ArrayTemplate<int32_t>& stack) { int32_t nType = -1; int32_t iSize = stack.GetSize() - 1; if (iSize > -1) { @@ -520,7 +521,7 @@ int32_t CXFA_ResolveProcessor::GetFilter(const CFX_WideStringC& wsExpression, FX_WCHAR* pConditionBuf = wsCondition.GetBuffer(iLength - nStart); int32_t nNameCount = 0; int32_t nConditionCount = 0; - CFX_Int32Array stack; + CFX_ArrayTemplate<int32_t> stack; int32_t nType = -1; const FX_WCHAR* pSrc = wsExpression.c_str(); FX_WCHAR wPrev = 0, wCur; @@ -680,11 +681,9 @@ void CXFA_ResolveProcessor::DoPredicateFilter(int32_t iCurIndex, ASSERT(iFoundCount == findNodes.GetSize()); CFX_WideString wsExpression; XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown; - if (wsCondition.Left(2) == FX_WSTRC(L".[") && - wsCondition.Right(1) == FX_WSTRC(L"]")) { + if (wsCondition.Left(2) == L".[" && wsCondition.Right(1) == L"]") { eLangType = XFA_SCRIPTLANGTYPE_Formcalc; - } else if (wsCondition.Left(2) == FX_WSTRC(L".(") && - wsCondition.Right(1) == FX_WSTRC(L")")) { + } else if (wsCondition.Left(2) == L".(" && wsCondition.Right(1) == L")") { eLangType = XFA_SCRIPTLANGTYPE_Javascript; } else { return; diff --git a/xfa/fxfa/parser/cxfa_resolveprocessor.h b/xfa/fxfa/parser/cxfa_resolveprocessor.h index 2590021cd..d806d57b9 100644 --- a/xfa/fxfa/parser/cxfa_resolveprocessor.h +++ b/xfa/fxfa/parser/cxfa_resolveprocessor.h @@ -60,7 +60,7 @@ class CXFA_ResolveProcessor { int32_t ResolveNumberSign(CXFA_ResolveNodesData& rnd); int32_t ResolveAsterisk(CXFA_ResolveNodesData& rnd); int32_t ResolveNormal(CXFA_ResolveNodesData& rnd); - int32_t ResolvePopStack(CFX_Int32Array& stack); + int32_t ResolvePopStack(CFX_ArrayTemplate<int32_t>& stack); void SetStylesForChild(uint32_t dwParentStyles, CXFA_ResolveNodesData& rnd); void ConditionArray(int32_t iCurIndex, diff --git a/xfa/fxfa/parser/cxfa_script.cpp b/xfa/fxfa/parser/cxfa_script.cpp index 42911e0f1..16f65f99f 100644 --- a/xfa/fxfa/parser/cxfa_script.cpp +++ b/xfa/fxfa/parser/cxfa_script.cpp @@ -13,9 +13,9 @@ CXFA_Script::CXFA_Script(CXFA_Node* pNode) : CXFA_Data(pNode) {} XFA_SCRIPTTYPE CXFA_Script::GetContentType() { CFX_WideStringC cData; if (m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, cData, false)) { - if (cData == FX_WSTRC(L"application/x-javascript")) + if (cData == L"application/x-javascript") return XFA_SCRIPTTYPE_Javascript; - if (cData == FX_WSTRC(L"application/x-formcalc")) + if (cData == L"application/x-formcalc") return XFA_SCRIPTTYPE_Formcalc; return XFA_SCRIPTTYPE_Unkown; } diff --git a/xfa/fxfa/parser/cxfa_scriptcontext.cpp b/xfa/fxfa/parser/cxfa_scriptcontext.cpp index 44ae9a4e5..584cd76be 100644 --- a/xfa/fxfa/parser/cxfa_scriptcontext.cpp +++ b/xfa/fxfa/parser/cxfa_scriptcontext.cpp @@ -161,10 +161,9 @@ bool CXFA_ScriptContext::RunScript(XFA_SCRIPTLANGTYPE eScriptType, hRetValue->SetUndefined(); return false; } - btScript = - FX_UTF8Encode(wsJavaScript.GetBuffer(), wsJavaScript.GetLength()); + btScript = FX_UTF8Encode(wsJavaScript.AsStringC()); } else { - btScript = FX_UTF8Encode(wsScript.c_str(), wsScript.GetLength()); + btScript = FX_UTF8Encode(wsScript); } CXFA_Object* pOriginalObject = m_pThisObject; m_pThisObject = pThisObject; @@ -293,7 +292,7 @@ void CXFA_ScriptContext::NormalPropertyGetter(CFXJSE_Value* pOriginalValue, CXFA_ScriptContext* lpScriptContext = pOriginalObject->GetDocument()->GetScriptContext(); CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOriginalObject); - if (wsPropName == FX_WSTRC(L"xfa")) { + if (wsPropName == L"xfa") { CFXJSE_Value* pValue = lpScriptContext->GetJSValueFromMap( lpScriptContext->GetDocument()->GetRoot()); pReturnValue->Assign(pValue); @@ -491,8 +490,7 @@ bool CXFA_ScriptContext::RunVariablesScript(CXFA_Node* pScriptNode) { if (!pTextNode->TryCData(XFA_ATTRIBUTE_Value, wsScript)) return false; - CFX_ByteString btScript = - FX_UTF8Encode(wsScript.c_str(), wsScript.GetLength()); + CFX_ByteString btScript = FX_UTF8Encode(wsScript); std::unique_ptr<CFXJSE_Value> hRetValue(new CFXJSE_Value(m_pIsolate)); CXFA_Node* pThisObject = pParent->GetNodeItem(XFA_NODEITEM_Parent); CFXJSE_Context* pVariablesContext = diff --git a/xfa/fxfa/parser/cxfa_simple_parser.cpp b/xfa/fxfa/parser/cxfa_simple_parser.cpp index 9f6fef9c1..4a6956de1 100644 --- a/xfa/fxfa/parser/cxfa_simple_parser.cpp +++ b/xfa/fxfa/parser/cxfa_simple_parser.cpp @@ -102,8 +102,8 @@ bool ResolveAttribute(CFDE_XMLElement* pElement, wsNSPrefix = wsAttrName.Left(wsAttributeName.GetLength() - wsLocalAttrName.GetLength() - 1); } - if (wsLocalAttrName == FX_WSTRC(L"xmlns") || - wsNSPrefix == FX_WSTRC(L"xmlns") || wsNSPrefix == FX_WSTRC(L"xml")) { + if (wsLocalAttrName == L"xmlns" || wsNSPrefix == L"xmlns" || + wsNSPrefix == L"xml") { return false; } if (!XFA_FDEExtension_ResolveNamespaceQualifier( @@ -202,7 +202,7 @@ void ConvertXMLToPlainText(CFDE_XMLElement* pRootXMLNode, case FDE_XMLNODE_Element: { CFX_WideString wsTextData; static_cast<CFDE_XMLElement*>(pXMLChild)->GetTextData(wsTextData); - wsTextData += FX_WSTRC(L"\n"); + wsTextData += L"\n"; wsOutput += wsTextData; break; } @@ -257,7 +257,7 @@ bool XFA_RecognizeRichText(CFDE_XMLElement* pRichTextXMLNode) { if (pRichTextXMLNode) { CFX_WideString wsNamespaceURI; GetElementTagNamespaceURI(pRichTextXMLNode, wsNamespaceURI); - if (wsNamespaceURI == FX_WSTRC(L"http://www.w3.org/1999/xhtml")) + if (wsNamespaceURI == L"http://www.w3.org/1999/xhtml") return true; } return false; @@ -415,10 +415,10 @@ bool XFA_FDEExtension_ResolveNamespaceQualifier( CFX_WideString wsNSAttribute; bool bRet = false; if (wsQualifier.IsEmpty()) { - wsNSAttribute = FX_WSTRC(L"xmlns"); + wsNSAttribute = L"xmlns"; bRet = true; } else { - wsNSAttribute = FX_WSTRC(L"xmlns:") + wsQualifier; + wsNSAttribute = L"xmlns:" + wsQualifier; } for (; pNode != pFakeRoot; pNode = static_cast<CFDE_XMLElement*>( pNode->GetNodeItem(CFDE_XMLNode::Parent))) { @@ -482,9 +482,9 @@ CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_XDP( for (int32_t i = 0; i < iAttributeCount; i++) { CFX_WideString wsAttriName, wsAttriValue; pElement->GetAttribute(i, wsAttriName, wsAttriValue); - if (wsAttriName == FX_WSTRC(L"uuid")) + if (wsAttriName == L"uuid") pXFARootNode->SetCData(XFA_ATTRIBUTE_Uuid, wsAttriValue); - else if (wsAttriName == FX_WSTRC(L"timeStamp")) + else if (wsAttriName == L"timeStamp") pXFARootNode->SetCData(XFA_ATTRIBUTE_TimeStamp, wsAttriValue); } } @@ -720,7 +720,7 @@ CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Data( } CFDE_XMLNode* pDataXMLNode = nullptr; - if (MatchNodeName(pXMLDocumentNode, FX_WSTRC(L"data"), + if (MatchNodeName(pXMLDocumentNode, L"data", XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) { static_cast<CFDE_XMLElement*>(pXMLDocumentNode) @@ -747,7 +747,7 @@ CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Data( m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_Element::DataGroup); if (!pNode) { if (pDataXMLNode != pXMLDocumentNode) - pDataXMLNode->Release(); + delete pDataXMLNode; return nullptr; } CFX_WideString wsLocalName; @@ -910,8 +910,7 @@ CXFA_Node* CXFA_SimpleParser::NormalLoader(CXFA_Node* pXFANode, CFX_WideString wsAttrValue; pXMLElement->GetAttribute(i, wsAttrQualifiedName, wsAttrValue); GetAttributeLocalName(wsAttrQualifiedName.AsStringC(), wsAttrName); - if (wsAttrName == FX_WSTRC(L"nil") && - wsAttrValue == FX_WSTRC(L"true")) { + if (wsAttrName == L"nil" && wsAttrValue == L"true") { IsNeedValue = false; } const XFA_ATTRIBUTEINFO* lpAttrInfo = @@ -965,9 +964,9 @@ void CXFA_SimpleParser::ParseContentNode(CXFA_Node* pXFANode, if (pXFANode->GetElementType() == XFA_Element::ExData) { CFX_WideStringC wsContentType = pXFANode->GetCData(XFA_ATTRIBUTE_ContentType); - if (wsContentType == FX_WSTRC(L"text/html")) + if (wsContentType == L"text/html") element = XFA_Element::SharpxHTML; - else if (wsContentType == FX_WSTRC(L"text/xml")) + else if (wsContentType == L"text/xml") element = XFA_Element::Sharpxml; } if (element == XFA_Element::SharpxHTML) @@ -1030,12 +1029,9 @@ void CXFA_SimpleParser::ParseDataGroup(CXFA_Node* pXFANode, { CFX_WideString wsNamespaceURI; GetElementTagNamespaceURI(pXMLElement, wsNamespaceURI); - if (wsNamespaceURI == - FX_WSTRC(L"http://www.xfa.com/schema/xfa-package/") || - wsNamespaceURI == - FX_WSTRC(L"http://www.xfa.org/schema/xfa-package/") || - wsNamespaceURI == - FX_WSTRC(L"http://www.w3.org/2001/XMLSchema-instance")) { + if (wsNamespaceURI == L"http://www.xfa.com/schema/xfa-package/" || + wsNamespaceURI == L"http://www.xfa.org/schema/xfa-package/" || + wsNamespaceURI == L"http://www.w3.org/2001/XMLSchema-instance") { continue; } } @@ -1043,22 +1039,20 @@ void CXFA_SimpleParser::ParseDataGroup(CXFA_Node* pXFANode, XFA_Element eNodeType = XFA_Element::DataModel; if (eNodeType == XFA_Element::DataModel) { CFX_WideString wsDataNodeAttr; - if (FindAttributeWithNS( - pXMLElement, FX_WSTRC(L"dataNode"), - FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"), - wsDataNodeAttr)) { - if (wsDataNodeAttr == FX_WSTRC(L"dataGroup")) + if (FindAttributeWithNS(pXMLElement, L"dataNode", + L"http://www.xfa.org/schema/xfa-data/1.0/", + wsDataNodeAttr)) { + if (wsDataNodeAttr == L"dataGroup") eNodeType = XFA_Element::DataGroup; - else if (wsDataNodeAttr == FX_WSTRC(L"dataValue")) + else if (wsDataNodeAttr == L"dataValue") eNodeType = XFA_Element::DataValue; } } CFX_WideString wsContentType; if (eNodeType == XFA_Element::DataModel) { - if (FindAttributeWithNS( - pXMLElement, FX_WSTRC(L"contentType"), - FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"), - wsContentType)) { + if (FindAttributeWithNS(pXMLElement, L"contentType", + L"http://www.xfa.org/schema/xfa-data/1.0/", + wsContentType)) { if (!wsContentType.IsEmpty()) eNodeType = XFA_Element::DataValue; } @@ -1099,14 +1093,14 @@ void CXFA_SimpleParser::ParseDataGroup(CXFA_Node* pXFANode, wsName, wsNS)) { continue; } - if (wsName == FX_WSTRC(L"nil") && wsValue == FX_WSTRC(L"true")) { + if (wsName == L"nil" && wsValue == L"true") { bNeedValue = false; continue; } - if (wsNS == FX_WSTRC(L"http://www.xfa.com/schema/xfa-package/") || - wsNS == FX_WSTRC(L"http://www.xfa.org/schema/xfa-package/") || - wsNS == FX_WSTRC(L"http://www.w3.org/2001/XMLSchema-instance") || - wsNS == FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/")) { + if (wsNS == L"http://www.xfa.com/schema/xfa-package/" || + wsNS == L"http://www.xfa.org/schema/xfa-package/" || + wsNS == L"http://www.w3.org/2001/XMLSchema-instance" || + wsNS == L"http://www.xfa.org/schema/xfa-data/1.0/") { continue; } CXFA_Node* pXFAMetaData = m_pFactory->CreateNode( @@ -1285,23 +1279,21 @@ void CXFA_SimpleParser::ParseInstruction(CXFA_Node* pXFANode, CFX_WideString wsTargetName; pXMLInstruction->GetTargetName(wsTargetName); - if (wsTargetName == FX_WSTRC(L"originalXFAVersion")) { + if (wsTargetName == L"originalXFAVersion") { CFX_WideString wsData; if (pXMLInstruction->GetData(0, wsData) && (pXFANode->GetDocument()->RecognizeXFAVersionNumber(wsData) != XFA_VERSION_UNKNOWN)) { wsData.clear(); if (pXMLInstruction->GetData(1, wsData) && - wsData == FX_WSTRC(L"v2.7-scripting:1")) { + wsData == L"v2.7-scripting:1") { pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_Scripting, true); } } - } else if (wsTargetName == FX_WSTRC(L"acrobat")) { + } else if (wsTargetName == L"acrobat") { CFX_WideString wsData; - if (pXMLInstruction->GetData(0, wsData) && - wsData == FX_WSTRC(L"JavaScript")) { - if (pXMLInstruction->GetData(1, wsData) && - wsData == FX_WSTRC(L"strictScoping")) { + if (pXMLInstruction->GetData(0, wsData) && wsData == L"JavaScript") { + if (pXMLInstruction->GetData(1, wsData) && wsData == L"strictScoping") { pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_StrictScoping, true); } } diff --git a/xfa/fxfa/parser/cxfa_stroke.h b/xfa/fxfa/parser/cxfa_stroke.h index a3287d285..cf941c8f0 100644 --- a/xfa/fxfa/parser/cxfa_stroke.h +++ b/xfa/fxfa/parser/cxfa_stroke.h @@ -21,6 +21,7 @@ class CXFA_Node; class CXFA_Stroke : public CXFA_Data { public: + CXFA_Stroke() : CXFA_Stroke(nullptr) {} explicit CXFA_Stroke(CXFA_Node* pNode) : CXFA_Data(pNode) {} bool IsCorner() const { return GetElementType() == XFA_Element::Corner; } @@ -40,6 +41,4 @@ class CXFA_Stroke : public CXFA_Data { bool SameStyles(CXFA_Stroke stroke, uint32_t dwFlags = 0) const; }; -typedef CFX_ArrayTemplate<CXFA_Stroke> CXFA_StrokeArray; - #endif // XFA_FXFA_PARSER_CXFA_STROKE_H_ diff --git a/xfa/fxfa/parser/cxfa_widgetdata.cpp b/xfa/fxfa/parser/cxfa_widgetdata.cpp index 80c50b781..d3533c277 100644 --- a/xfa/fxfa/parser/cxfa_widgetdata.cpp +++ b/xfa/fxfa/parser/cxfa_widgetdata.cpp @@ -18,7 +18,7 @@ namespace { -FX_FLOAT GetEdgeThickness(const CXFA_StrokeArray& strokes, +FX_FLOAT GetEdgeThickness(const std::vector<CXFA_Stroke>& strokes, bool b3DStyle, int32_t nIndex) { FX_FLOAT fThickness = 0; @@ -407,19 +407,17 @@ CXFA_Border CXFA_WidgetData::GetUIBorder() { } CFX_RectF CXFA_WidgetData::GetUIMargin() { - CFX_RectF rtUIMargin; - rtUIMargin.Reset(); - CXFA_Node* pUIChild = GetUIChild(); CXFA_Margin mgUI = CXFA_Margin( pUIChild ? pUIChild->GetProperty(0, XFA_Element::Margin, false) : nullptr); + if (!mgUI) - return rtUIMargin; + return CFX_RectF(); CXFA_Border border = GetUIBorder(); if (border && border.GetPresence() != XFA_ATTRIBUTEENUM_Visible) - return rtUIMargin; + return CFX_RectF(); FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset; bool bLeft = mgUI.GetLeftInset(fLeftInset); @@ -431,8 +429,8 @@ CFX_RectF CXFA_WidgetData::GetUIMargin() { FX_FLOAT fThickness = 0; border.Get3DStyle(bVisible, fThickness); if (!bLeft || !bTop || !bRight || !bBottom) { - CXFA_StrokeArray strokes; - border.GetStrokes(strokes); + std::vector<CXFA_Stroke> strokes; + border.GetStrokes(&strokes); if (!bTop) fTopInset = GetEdgeThickness(strokes, bVisible, 0); if (!bRight) @@ -443,8 +441,7 @@ CFX_RectF CXFA_WidgetData::GetUIMargin() { fLeftInset = GetEdgeThickness(strokes, bVisible, 3); } } - rtUIMargin.Set(fLeftInset, fTopInset, fRightInset, fBottomInset); - return rtUIMargin; + return CFX_RectF(fLeftInset, fTopInset, fRightInset, fBottomInset); } int32_t CXFA_WidgetData::GetButtonHighlight() { @@ -462,7 +459,7 @@ bool CXFA_WidgetData::GetButtonRollover(CFX_WideString& wsRollover, while (pText) { CFX_WideStringC wsName; pText->TryCData(XFA_ATTRIBUTE_Name, wsName); - if (wsName == FX_WSTRC(L"rollover")) { + if (wsName == L"rollover") { pText->TryContent(wsRollover); bRichText = pText->GetElementType() == XFA_Element::ExData; return !wsRollover.IsEmpty(); @@ -479,7 +476,7 @@ bool CXFA_WidgetData::GetButtonDown(CFX_WideString& wsDown, bool& bRichText) { while (pText) { CFX_WideStringC wsName; pText->TryCData(XFA_ATTRIBUTE_Name, wsName); - if (wsName == FX_WSTRC(L"down")) { + if (wsName == L"down") { pText->TryContent(wsDown); bRichText = pText->GetElementType() == XFA_Element::ExData; return !wsDown.IsEmpty(); @@ -874,7 +871,7 @@ int32_t CXFA_WidgetData::GetSelectedItem(int32_t nIndex) { return -1; } -void CXFA_WidgetData::GetSelectedItems(CFX_Int32Array& iSelArray) { +void CXFA_WidgetData::GetSelectedItems(CFX_ArrayTemplate<int32_t>& iSelArray) { std::vector<CFX_WideString> wsValueArray; GetSelectedItemsValue(wsValueArray); int32_t iValues = pdfium::CollectionSize<int32_t>(wsValueArray); @@ -973,7 +970,7 @@ void CXFA_WidgetData::SetItemState(int32_t nIndex, bSyncData); } } else if (iSel >= 0) { - CFX_Int32Array iSelArray; + CFX_ArrayTemplate<int32_t> iSelArray; GetSelectedItems(iSelArray); for (int32_t i = 0; i < iSelArray.GetSize(); i++) { if (iSelArray[i] == nIndex) { @@ -999,7 +996,7 @@ void CXFA_WidgetData::SetItemState(int32_t nIndex, } } -void CXFA_WidgetData::SetSelectedItems(CFX_Int32Array& iSelArray, +void CXFA_WidgetData::SetSelectedItems(CFX_ArrayTemplate<int32_t>& iSelArray, bool bNotify, bool bScriptModify, bool bSyncData) { @@ -1010,9 +1007,8 @@ void CXFA_WidgetData::SetSelectedItems(CFX_Int32Array& iSelArray, GetChoiceListItems(wsSaveTextArray, true); CFX_WideString wsItemValue; for (int32_t i = 0; i < iSize; i++) { - wsItemValue = (iSize == 1) - ? wsSaveTextArray[iSelArray[i]] - : wsSaveTextArray[iSelArray[i]] + FX_WSTRC(L"\n"); + wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]] + : wsSaveTextArray[iSelArray[i]] + L"\n"; wsValue += wsItemValue; } } @@ -1522,7 +1518,7 @@ bool CXFA_WidgetData::SetValue(const CFX_WideString& wsValue, } } else { if (eType == XFA_Element::NumericEdit) { - if (wsNewText != FX_WSTRC(L"0")) { + if (wsNewText != L"0") { int32_t iLeadDigits = 0; int32_t iFracDigits = 0; GetLeadDigits(iLeadDigits); @@ -1572,7 +1568,7 @@ bool CXFA_WidgetData::GetPictureContent(CFX_WideString& wsPicture, wsDataPicture); pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium, wsTimePicture); - wsPicture = wsDataPicture + FX_WSTRC(L"T") + wsTimePicture; + wsPicture = wsDataPicture + L"T" + wsTimePicture; break; case XFA_VT_DECIMAL: case XFA_VT_FLOAT: @@ -1640,7 +1636,7 @@ IFX_Locale* CXFA_WidgetData::GetLocal() { CFX_WideString wsLocaleName; if (!m_pNode->GetLocaleName(wsLocaleName)) return nullptr; - if (wsLocaleName == FX_WSTRC(L"ambient")) + if (wsLocaleName == L"ambient") return m_pNode->GetDocument()->GetLocalMgr()->GetDefLocale(); return m_pNode->GetDocument()->GetLocalMgr()->GetLocaleByName(wsLocaleName); } diff --git a/xfa/fxfa/parser/cxfa_widgetdata.h b/xfa/fxfa/parser/cxfa_widgetdata.h index 7986fa9d8..4f5db3bad 100644 --- a/xfa/fxfa/parser/cxfa_widgetdata.h +++ b/xfa/fxfa/parser/cxfa_widgetdata.h @@ -102,7 +102,7 @@ class CXFA_WidgetData : public CXFA_Data { bool bSaveValue = false); int32_t CountSelectedItems(); int32_t GetSelectedItem(int32_t nIndex = 0); - void GetSelectedItems(CFX_Int32Array& iSelArray); + void GetSelectedItems(CFX_ArrayTemplate<int32_t>& iSelArray); void GetSelectedItemsValue(std::vector<CFX_WideString>& wsSelTextArray); bool GetItemState(int32_t nIndex); void SetItemState(int32_t nIndex, @@ -110,7 +110,7 @@ class CXFA_WidgetData : public CXFA_Data { bool bNotify, bool bScriptModify, bool bSyncData); - void SetSelectedItems(CFX_Int32Array& iSelArray, + void SetSelectedItems(CFX_ArrayTemplate<int32_t>& iSelArray, bool bNotify, bool bScriptModify, bool bSyncData); diff --git a/xfa/fxfa/parser/cxfa_xml_parser.cpp b/xfa/fxfa/parser/cxfa_xml_parser.cpp index 95920d977..b20202251 100644 --- a/xfa/fxfa/parser/cxfa_xml_parser.cpp +++ b/xfa/fxfa/parser/cxfa_xml_parser.cpp @@ -85,8 +85,7 @@ int32_t CXFA_XMLParser::DoParser(IFX_Pause* pPause) { break; case FDE_XmlSyntaxResult::TargetName: m_pParser->GetTargetName(m_ws1); - if (m_ws1 == FX_WSTRC(L"originalXFAVersion") || - m_ws1 == FX_WSTRC(L"acrobat")) { + if (m_ws1 == L"originalXFAVersion" || m_ws1 == L"acrobat") { m_pChild = new CFDE_XMLInstruction(m_ws1); m_pParent->InsertChildNode(m_pChild); } else { @@ -104,12 +103,12 @@ int32_t CXFA_XMLParser::DoParser(IFX_Pause* pPause) { if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 3) { CFX_WideString wsTag; static_cast<CFDE_XMLElement*>(m_pChild)->GetLocalTagName(wsTag); - if (wsTag == FX_WSTRC(L"template")) { + if (wsTag == L"template") { m_dwCheckStatus |= 0x01; m_dwCurrentCheckStatus = 0x01; m_nStart[0] = m_pParser->GetCurrentBinaryPos() - (m_pParser->GetCurrentPos() - m_nElementStart); - } else if (wsTag == FX_WSTRC(L"datasets")) { + } else if (wsTag == L"datasets") { m_dwCheckStatus |= 0x02; m_dwCurrentCheckStatus = 0x02; m_nStart[1] = m_pParser->GetCurrentBinaryPos() - diff --git a/xfa/fxfa/parser/cxfa_xml_parser.h b/xfa/fxfa/parser/cxfa_xml_parser.h index e49a9dd12..9393b7e59 100644 --- a/xfa/fxfa/parser/cxfa_xml_parser.h +++ b/xfa/fxfa/parser/cxfa_xml_parser.h @@ -32,8 +32,7 @@ class CXFA_XMLParser : public IFDE_XMLParser { protected: CFDE_XMLNode* m_pRoot; CFX_RetainPtr<IFGAS_Stream> m_pStream; - std::unique_ptr<CFDE_XMLSyntaxParser, ReleaseDeleter<CFDE_XMLSyntaxParser>> - m_pParser; + std::unique_ptr<CFDE_XMLSyntaxParser> m_pParser; CFDE_XMLNode* m_pParent; CFDE_XMLNode* m_pChild; CFX_StackTemplate<CFDE_XMLNode*> m_NodeStack; diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp index f1b60884e..03ab81e39 100644 --- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp +++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp @@ -89,9 +89,9 @@ bool FormValueNode_SetChildContent(CXFA_Node* pValueNode, CFX_WideString wsContentType; pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, false); - if (wsContentType == FX_WSTRC(L"text/html")) + if (wsContentType == L"text/html") element = XFA_Element::SharpxHTML; - else if (wsContentType == FX_WSTRC(L"text/xml")) + else if (wsContentType == L"text/xml") element = XFA_Element::Sharpxml; } pContentRawDataNode = pChildNode->CreateSamePacketNode(element); @@ -305,7 +305,7 @@ void CreateDataBinding(CXFA_Node* pFormNode, CFX_WideString wsItem; for (int32_t i = 0; i < iCounts; i++) { items[i]->TryContent(wsItem); - wsItem = (iCounts == 1) ? wsItem : wsItem + FX_WSTRC(L"\n"); + wsItem = (iCounts == 1) ? wsItem : wsItem + L"\n"; wsNormalizeValue += wsItem; } CXFA_ExData exData = defValue.GetExData(); @@ -456,7 +456,7 @@ CXFA_Node* FindDataRefDataNode(CXFA_Document* pDocument, bool bForceBind, bool bUpLevel) { uint32_t dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew; - if (bUpLevel || wsRef != FX_WSTRC(L"name")) + if (bUpLevel || wsRef != L"name") dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings); XFA_RESOLVENODE_RS rs; @@ -494,7 +494,7 @@ CXFA_Node* CloneOrMergeInstanceManager(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_NodeArray& subforms) { CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name); - CFX_WideString wsInstMgrNodeName = FX_WSTRC(L"_") + wsSubformName; + CFX_WideString wsInstMgrNodeName = L"_" + wsSubformName; uint32_t dwInstNameHash = FX_HashCode_GetW(wsInstMgrNodeName.AsStringC(), false); CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance( @@ -530,8 +530,7 @@ CXFA_Node* CloneOrMergeInstanceManager(CXFA_Document* pDocument, CXFA_Node* pNewNode = pDocument->CreateNode(XFA_XDPPACKET_Form, XFA_Element::InstanceManager); - wsInstMgrNodeName = - FX_WSTRC(L"_") + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name); + wsInstMgrNodeName = L"_" + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name); pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName); pFormParent->InsertChild(pNewNode, nullptr); pNewNode->SetTemplateNode(pTemplateNode); @@ -1040,7 +1039,7 @@ CXFA_Node* MaybeCreateDataNode(CXFA_Document* pDocument, CFX_WideString wsNamespace; if (!pDDGroupNode->TryNamespace(wsNamespace) || - wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) { + wsNamespace != L"http://ns.adobe.com/data-description/") { continue; } } @@ -1214,7 +1213,7 @@ void UpdateDataRelation(CXFA_Node* pDataNode, CXFA_Node* pDataDescriptionNode) { CFX_WideString wsNamespace; if (!pDDGroupNode->TryNamespace(wsNamespace) || - wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) { + wsNamespace != L"http://ns.adobe.com/data-description/") { continue; } } @@ -1390,7 +1389,7 @@ void CXFA_Document::DoDataMerge() { if (!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) { if (!pChildNode->TryNamespace(wsNamespaceURI)) continue; - if (wsNamespaceURI == FX_WSTRC(L"http://ns.adobe.com/data-description/")) + if (wsNamespaceURI == L"http://ns.adobe.com/data-description/") pDDRoot = pChildNode; } else if (!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) { if (!pChildNode->TryNamespace(wsNamespaceURI)) diff --git a/xfa/fxfa/parser/xfa_layout_itemlayout.cpp b/xfa/fxfa/parser/xfa_layout_itemlayout.cpp index 45dc32771..dd38c963d 100644 --- a/xfa/fxfa/parser/xfa_layout_itemlayout.cpp +++ b/xfa/fxfa/parser/xfa_layout_itemlayout.cpp @@ -8,8 +8,10 @@ #include <algorithm> #include <memory> +#include <utility> #include <vector> +#include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" #include "xfa/fxfa/app/xfa_ffnotify.h" #include "xfa/fxfa/parser/cxfa_containerlayoutitem.h" @@ -24,12 +26,12 @@ namespace { -int32_t SeparateStringW(const FX_WCHAR* pStr, - int32_t iStrLen, - FX_WCHAR delimiter, - std::vector<CFX_WideString>& pieces) { +std::vector<CFX_WideString> SeparateStringW(const FX_WCHAR* pStr, + int32_t iStrLen, + FX_WCHAR delimiter) { + std::vector<CFX_WideString> ret; if (!pStr) - return 0; + return ret; if (iStrLen < 0) iStrLen = FXSYS_wcslen(pStr); @@ -37,191 +39,461 @@ int32_t SeparateStringW(const FX_WCHAR* pStr, const FX_WCHAR* pEnd = pStr + iStrLen; while (true) { if (pStr >= pEnd || delimiter == *pStr) { - pieces.push_back(CFX_WideString(pToken, pStr - pToken)); + ret.push_back(CFX_WideString(pToken, pStr - pToken)); pToken = pStr + 1; if (pStr >= pEnd) break; } pStr++; } - return pdfium::CollectionSize<int32_t>(pieces); + return ret; } -} // namespace - -CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode, - CXFA_LayoutPageMgr* pPageMgr) - : m_bKeepBreakFinish(false), - m_bIsProcessKeep(false), - m_pKeepHeadNode(nullptr), - m_pKeepTailNode(nullptr), - m_pFormNode(pNode), - m_pLayoutItem(nullptr), - m_pOldLayoutItem(nullptr), - m_pCurChildNode(XFA_LAYOUT_INVALIDNODE), - m_pCurChildPreprocessor(nullptr), - m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None), - m_fUsedSize(0), - m_pPageMgr(pPageMgr), - m_bBreakPending(true), - m_fLastRowWidth(0), - m_fLastRowY(0), - m_fWidthLimite(0), - m_bUseInheriated(false), - m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done), - m_bHasAvailHeight(true) { - ASSERT(m_pFormNode && (m_pFormNode->IsContainerNode() || - m_pFormNode->GetElementType() == XFA_Element::Form)); - m_pOldLayoutItem = - (CXFA_ContentLayoutItem*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY); +void UpdateWidgetSize(CXFA_ContentLayoutItem* pLayoutItem, + FX_FLOAT* fWidth, + FX_FLOAT* fHeight) { + CXFA_Node* pNode = pLayoutItem->m_pFormNode; + switch (pNode->GetElementType()) { + case XFA_Element::Subform: + case XFA_Element::Area: + case XFA_Element::ExclGroup: + case XFA_Element::SubformSet: { + if (*fWidth < -XFA_LAYOUT_FLOAT_PERCISION) + *fWidth = pLayoutItem->m_sSize.width; + if (*fHeight < -XFA_LAYOUT_FLOAT_PERCISION) + *fHeight = pLayoutItem->m_sSize.height; + break; + } + case XFA_Element::Draw: + case XFA_Element::Field: { + pNode->GetDocument()->GetNotify()->StartFieldDrawLayout(pNode, *fWidth, + *fHeight); + break; + } + default: + ASSERT(false); + } } -CXFA_ItemLayoutProcessor::~CXFA_ItemLayoutProcessor() {} +CFX_SizeF CalculateContainerSpecifiedSize(CXFA_Node* pFormNode, + bool* bContainerWidthAutoSize, + bool* bContainerHeightAutoSize) { + *bContainerWidthAutoSize = true; + *bContainerHeightAutoSize = true; -CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem( - CXFA_Node* pFormNode) { - if (!pFormNode) { - return nullptr; + XFA_Element eType = pFormNode->GetElementType(); + CXFA_Measurement mTmpValue; + CFX_SizeF containerSize; + if ((eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup) && + pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, false) && + mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { + containerSize.width = mTmpValue.ToUnit(XFA_UNIT_Pt); + *bContainerWidthAutoSize = false; } - CXFA_ContentLayoutItem* pLayoutItem = nullptr; - if (m_pOldLayoutItem) { - pLayoutItem = m_pOldLayoutItem; - m_pOldLayoutItem = m_pOldLayoutItem->m_pNext; - return pLayoutItem; + if ((eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup) && + pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, false) && + mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { + containerSize.height = mTmpValue.ToUnit(XFA_UNIT_Pt); + *bContainerHeightAutoSize = false; } - pLayoutItem = (CXFA_ContentLayoutItem*)pFormNode->GetDocument() - ->GetNotify() - ->OnCreateLayoutItem(pFormNode); - CXFA_ContentLayoutItem* pPrevLayoutItem = - (CXFA_ContentLayoutItem*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY); - if (pPrevLayoutItem) { - while (pPrevLayoutItem->m_pNext) { - pPrevLayoutItem = pPrevLayoutItem->m_pNext; + if (*bContainerWidthAutoSize && eType == XFA_Element::Subform && + pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, false) && + mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { + containerSize.width = mTmpValue.ToUnit(XFA_UNIT_Pt); + *bContainerWidthAutoSize = false; + } + if (*bContainerHeightAutoSize && eType == XFA_Element::Subform && + pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, false) && + mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { + containerSize.height = mTmpValue.ToUnit(XFA_UNIT_Pt); + *bContainerHeightAutoSize = false; + } + return containerSize; +} + +CFX_SizeF CalculateContainerComponentSizeFromContentSize( + CXFA_Node* pFormNode, + bool bContainerWidthAutoSize, + FX_FLOAT fContentCalculatedWidth, + bool bContainerHeightAutoSize, + FX_FLOAT fContentCalculatedHeight, + const CFX_SizeF& currentContainerSize) { + CFX_SizeF componentSize = currentContainerSize; + CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_Element::Margin); + CXFA_Measurement mTmpValue; + if (bContainerWidthAutoSize) { + componentSize.width = fContentCalculatedWidth; + if (pMarginNode) { + if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, false)) + componentSize.width += mTmpValue.ToUnit(XFA_UNIT_Pt); + if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, false)) + componentSize.width += mTmpValue.ToUnit(XFA_UNIT_Pt); } - pPrevLayoutItem->m_pNext = pLayoutItem; - pLayoutItem->m_pPrev = pPrevLayoutItem; - } else { - pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem); } - return pLayoutItem; + + if (bContainerHeightAutoSize) { + componentSize.height = fContentCalculatedHeight; + if (pMarginNode) { + if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, false)) + componentSize.height += mTmpValue.ToUnit(XFA_UNIT_Pt); + if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue, + false)) { + componentSize.height += mTmpValue.ToUnit(XFA_UNIT_Pt); + } + } + } + return componentSize; } -bool CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos( - CXFA_ContentLayoutItem* pLayoutItem, - FX_FLOAT fCurVerticalOffset, - FX_FLOAT& fProposedSplitPos, - bool& bAppChange, - bool bCalculateMargin) { - CXFA_Node* pFormNode = pLayoutItem->m_pFormNode; - if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION && - fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y - - XFA_LAYOUT_FLOAT_PERCISION) { - switch (pFormNode->GetIntact()) { - case XFA_ATTRIBUTEENUM_None: { - bool bAnyChanged = false; - CXFA_Document* pDocument = pFormNode->GetDocument(); - CXFA_FFNotify* pNotify = pDocument->GetNotify(); - FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0; - CXFA_Node* pMarginNode = - pFormNode->GetFirstChildByClass(XFA_Element::Margin); - if (pMarginNode && bCalculateMargin) { - fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset) - .ToUnit(XFA_UNIT_Pt); - fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset) - .ToUnit(XFA_UNIT_Pt); + +void RelocateTableRowCells( + CXFA_ContentLayoutItem* pLayoutRow, + const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths, + XFA_ATTRIBUTEENUM eLayout) { + bool bContainerWidthAutoSize = true; + bool bContainerHeightAutoSize = true; + CFX_SizeF containerSize = CalculateContainerSpecifiedSize( + pLayoutRow->m_pFormNode, &bContainerWidthAutoSize, + &bContainerHeightAutoSize); + CXFA_Node* pMarginNode = + pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); + FX_FLOAT fLeftInset = 0; + FX_FLOAT fTopInset = 0; + FX_FLOAT fRightInset = 0; + FX_FLOAT fBottomInset = 0; + if (pMarginNode) { + fLeftInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); + fTopInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); + fRightInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); + fBottomInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); + } + + FX_FLOAT fContentWidthLimit = + bContainerWidthAutoSize ? FLT_MAX + : containerSize.width - fLeftInset - fRightInset; + FX_FLOAT fContentCurrentHeight = + pLayoutRow->m_sSize.height - fTopInset - fBottomInset; + FX_FLOAT fContentCalculatedWidth = 0; + FX_FLOAT fContentCalculatedHeight = 0; + FX_FLOAT fCurrentColX = 0; + int32_t nCurrentColIdx = 0; + bool bMetWholeRowCell = false; + + for (auto pLayoutChild = + static_cast<CXFA_ContentLayoutItem*>(pLayoutRow->m_pFirstChild); + pLayoutChild; pLayoutChild = static_cast<CXFA_ContentLayoutItem*>( + pLayoutChild->m_pNextSibling)) { + int32_t nOriginalColSpan = + pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan); + int32_t nColSpan = nOriginalColSpan; + FX_FLOAT fColSpanWidth = 0; + if (nColSpan == -1 || + nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) { + nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx; + } + for (int32_t i = 0; i < nColSpan; i++) + fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i]; + + if (nColSpan != nOriginalColSpan) { + fColSpanWidth = + bMetWholeRowCell ? 0 : std::max(fColSpanWidth, + pLayoutChild->m_sSize.height); + } + if (nOriginalColSpan == -1) + bMetWholeRowCell = true; + + pLayoutChild->m_sPos = CFX_PointF(fCurrentColX, 0); + pLayoutChild->m_sSize.width = fColSpanWidth; + if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) + continue; + + fCurrentColX += fColSpanWidth; + nCurrentColIdx += nColSpan; + FX_FLOAT fNewHeight = bContainerHeightAutoSize ? -1 : fContentCurrentHeight; + UpdateWidgetSize(pLayoutChild, &fColSpanWidth, &fNewHeight); + pLayoutChild->m_sSize.height = fNewHeight; + if (bContainerHeightAutoSize) { + fContentCalculatedHeight = + std::max(fContentCalculatedHeight, pLayoutChild->m_sSize.height); + } + } + + if (bContainerHeightAutoSize) { + for (CXFA_ContentLayoutItem* pLayoutChild = + (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; + pLayoutChild; + pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { + UpdateWidgetSize(pLayoutChild, &pLayoutChild->m_sSize.width, + &fContentCalculatedHeight); + FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.height; + pLayoutChild->m_sSize.height = fContentCalculatedHeight; + CXFA_Node* pParaNode = + pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_Element::Para); + if (pParaNode && pLayoutChild->m_pFirstChild) { + FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight; + XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign); + switch (eVType) { + case XFA_ATTRIBUTEENUM_Middle: + fOffHeight = fOffHeight / 2; + break; + case XFA_ATTRIBUTEENUM_Bottom: + break; + case XFA_ATTRIBUTEENUM_Top: + default: + fOffHeight = 0; + break; } - bool bChanged = true; - while (bChanged) { - bChanged = false; - { - FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset; - if (pNotify->FindSplitPos(pFormNode, pLayoutItem->GetIndex(), - fRelSplitPos)) { - bAnyChanged = true; - bChanged = true; - fProposedSplitPos = fCurVerticalOffset + fRelSplitPos; - bAppChange = true; - if (fProposedSplitPos <= - fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) { - return true; - } - } - } - FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin; - for (CXFA_ContentLayoutItem* pChildItem = - (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild; - pChildItem; - pChildItem = - (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) { - FX_FLOAT fChildOffset = - fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y; - bool bChange = false; - if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos, - bChange, bCalculateMargin)) { - if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION && - bChange) { - fProposedSplitPos = fRelSplitPos - fCurTopMargin; - } else { - fProposedSplitPos = fRelSplitPos + fCurBottomMargin; - } - bAnyChanged = true; - bChanged = true; - if (fProposedSplitPos <= - fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) { - return true; - } - if (bAnyChanged) { - break; - } - } + if (fOffHeight > 0) { + for (CXFA_ContentLayoutItem* pInnerLayoutChild = + (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild; + pInnerLayoutChild; + pInnerLayoutChild = + (CXFA_ContentLayoutItem*)pInnerLayoutChild->m_pNextSibling) { + pInnerLayoutChild->m_sPos.y += fOffHeight; } } - return bAnyChanged; - } break; - case XFA_ATTRIBUTEENUM_ContentArea: - case XFA_ATTRIBUTEENUM_PageArea: { - fProposedSplitPos = fCurVerticalOffset; - return true; } - default: - return false; } } - return false; + + if (bContainerWidthAutoSize) { + FX_FLOAT fChildSuppliedWidth = fCurrentColX; + if (fContentWidthLimit < FLT_MAX && + fContentWidthLimit > fChildSuppliedWidth) { + fChildSuppliedWidth = fContentWidthLimit; + } + fContentCalculatedWidth = + std::max(fContentCalculatedWidth, fChildSuppliedWidth); + } else { + fContentCalculatedWidth = containerSize.width - fLeftInset - fRightInset; + } + + if (pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) == + XFA_ATTRIBUTEENUM_Rl_row) { + for (CXFA_ContentLayoutItem* pLayoutChild = + (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; + pLayoutChild; + pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { + pLayoutChild->m_sPos.x = fContentCalculatedWidth - + pLayoutChild->m_sPos.x - + pLayoutChild->m_sSize.width; + } + } + pLayoutRow->m_sSize = CalculateContainerComponentSizeFromContentSize( + pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, + bContainerHeightAutoSize, fContentCalculatedHeight, containerSize); +} + +void UpdatePendingItemLayout(CXFA_ItemLayoutProcessor* pProcessor, + CXFA_ContentLayoutItem* pLayoutItem) { + XFA_ATTRIBUTEENUM eLayout = + pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); + switch (eLayout) { + case XFA_ATTRIBUTEENUM_Row: + case XFA_ATTRIBUTEENUM_Rl_row: + RelocateTableRowCells(pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, + eLayout); + break; + default: + break; + } +} + +void AddTrailerBeforeSplit(CXFA_ItemLayoutProcessor* pProcessor, + FX_FLOAT fSplitPos, + CXFA_ContentLayoutItem* pTrailerLayoutItem, + bool bUseInherited) { + if (!pTrailerLayoutItem) + return; + + FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.height; + if (bUseInherited) { + FX_FLOAT fNewSplitPos = 0; + if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) + fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight); + if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) + pProcessor->SplitLayoutItem(fNewSplitPos); + return; + } + + UpdatePendingItemLayout(pProcessor, pTrailerLayoutItem); + CXFA_Node* pMarginNode = + pProcessor->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); + FX_FLOAT fLeftInset = 0; + FX_FLOAT fTopInset = 0; + FX_FLOAT fRightInset = 0; + FX_FLOAT fBottomInset = 0; + if (pMarginNode) { + fLeftInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); + fTopInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); + fRightInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); + fBottomInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); + } + + if (!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) { + pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY; + pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth; + pProcessor->m_pLayoutItem->m_sSize.width += + pTrailerLayoutItem->m_sSize.width; + pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem); + return; + } + + FX_FLOAT fNewSplitPos = 0; + if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) + fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight); + + if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { + pProcessor->SplitLayoutItem(fNewSplitPos); + pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset; + } else { + pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset; + } + + switch (pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { + case XFA_ATTRIBUTEENUM_Right: + pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.width - + fRightInset - + pTrailerLayoutItem->m_sSize.width; + break; + case XFA_ATTRIBUTEENUM_Center: + pTrailerLayoutItem->m_sPos.x = + (pProcessor->m_pLayoutItem->m_sSize.width - fLeftInset - fRightInset - + pTrailerLayoutItem->m_sSize.width) / + 2; + break; + case XFA_ATTRIBUTEENUM_Left: + default: + pTrailerLayoutItem->m_sPos.x = fLeftInset; + break; + } + pProcessor->m_pLayoutItem->m_sSize.height += fHeight; + pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem); +} + +void AddLeaderAfterSplit(CXFA_ItemLayoutProcessor* pProcessor, + CXFA_ContentLayoutItem* pLeaderLayoutItem) { + UpdatePendingItemLayout(pProcessor, pLeaderLayoutItem); + + CXFA_Node* pMarginNode = + pProcessor->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); + FX_FLOAT fLeftInset = 0; + FX_FLOAT fRightInset = 0; + if (pMarginNode) { + fLeftInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); + fRightInset = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); + } + + FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.height; + for (CXFA_ContentLayoutItem* pChildItem = + (CXFA_ContentLayoutItem*)pProcessor->m_pLayoutItem->m_pFirstChild; + pChildItem; + pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) { + pChildItem->m_sPos.y += fHeight; + } + pLeaderLayoutItem->m_sPos.y = 0; + + switch (pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { + case XFA_ATTRIBUTEENUM_Right: + pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.width - + fRightInset - + pLeaderLayoutItem->m_sSize.width; + break; + case XFA_ATTRIBUTEENUM_Center: + pLeaderLayoutItem->m_sPos.x = + (pProcessor->m_pLayoutItem->m_sSize.width - fLeftInset - fRightInset - + pLeaderLayoutItem->m_sSize.width) / + 2; + break; + case XFA_ATTRIBUTEENUM_Left: + default: + pLeaderLayoutItem->m_sPos.x = fLeftInset; + break; + } + pProcessor->m_pLayoutItem->m_sSize.height += fHeight; + pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem); +} + +void AddPendingNode(CXFA_ItemLayoutProcessor* pProcessor, + CXFA_Node* pPendingNode, + bool bBreakPending) { + pProcessor->m_PendingNodes.push_back(pPendingNode); + pProcessor->m_bBreakPending = bBreakPending; +} + +FX_FLOAT InsertPendingItems(CXFA_ItemLayoutProcessor* pProcessor, + CXFA_Node* pCurChildNode) { + FX_FLOAT fTotalHeight = 0; + if (pProcessor->m_PendingNodes.empty()) + return fTotalHeight; + + if (!pProcessor->m_pLayoutItem) { + pProcessor->m_pLayoutItem = + pProcessor->CreateContentLayoutItem(pCurChildNode); + pProcessor->m_pLayoutItem->m_sSize.clear(); + } + + while (!pProcessor->m_PendingNodes.empty()) { + auto pPendingProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + pProcessor->m_PendingNodes.front(), nullptr); + pProcessor->m_PendingNodes.pop_front(); + pPendingProcessor->DoLayout(false, FLT_MAX, FLT_MAX, nullptr); + CXFA_ContentLayoutItem* pPendingLayoutItem = + pPendingProcessor->HasLayoutItem() + ? pPendingProcessor->ExtractLayoutItem() + : nullptr; + if (pPendingLayoutItem) { + AddLeaderAfterSplit(pProcessor, pPendingLayoutItem); + if (pProcessor->m_bBreakPending) + fTotalHeight += pPendingLayoutItem->m_sSize.height; + } + } + return fTotalHeight; } -static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout(CXFA_Node* pFormNode, - bool& bRootForceTb) { - bRootForceTb = false; + +XFA_ATTRIBUTEENUM GetLayout(CXFA_Node* pFormNode, bool* bRootForceTb) { + *bRootForceTb = false; XFA_ATTRIBUTEENUM eLayoutMode; - if (pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, false)) { + if (pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, false)) return eLayoutMode; - } + CXFA_Node* pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent); if (pParentNode && pParentNode->GetElementType() == XFA_Element::Form) { - bRootForceTb = true; + *bRootForceTb = true; return XFA_ATTRIBUTEENUM_Tb; } return XFA_ATTRIBUTEENUM_Position; } -static bool XFA_ExistContainerKeep(CXFA_Node* pCurNode, bool bPreFind) { - if (!pCurNode || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) { + +bool ExistContainerKeep(CXFA_Node* pCurNode, bool bPreFind) { + if (!pCurNode || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) return false; - } + XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling; - if (!bPreFind) { + if (!bPreFind) eItemType = XFA_NODEITEM_NextSibling; - } + CXFA_Node* pPreContainer = pCurNode->GetNodeItem(eItemType, XFA_ObjectType::ContainerNode); - if (!pPreContainer) { + if (!pPreContainer) return false; - } + CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_Element::Keep); if (pKeep) { XFA_ATTRIBUTEENUM ePrevious; XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous; - if (!bPreFind) { + if (!bPreFind) eKeepType = XFA_ATTRIBUTE_Next; - } + if (pKeep->TryEnum(eKeepType, ePrevious, false)) { if (ePrevious == XFA_ATTRIBUTEENUM_ContentArea || ePrevious == XFA_ATTRIBUTEENUM_PageArea) { @@ -229,40 +501,668 @@ static bool XFA_ExistContainerKeep(CXFA_Node* pCurNode, bool bPreFind) { } } } + pKeep = pPreContainer->GetFirstChildByClass(XFA_Element::Keep); - if (!pKeep) { + if (!pKeep) return false; - } - XFA_ATTRIBUTEENUM eNext; + XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next; - if (!bPreFind) { + if (!bPreFind) eKeepType = XFA_ATTRIBUTE_Previous; - } - if (!pKeep->TryEnum(eKeepType, eNext, false)) { + + XFA_ATTRIBUTEENUM eNext; + if (!pKeep->TryEnum(eKeepType, eNext, false)) return false; - } if (eNext == XFA_ATTRIBUTEENUM_ContentArea || eNext == XFA_ATTRIBUTEENUM_PageArea) { return true; } return false; } + +bool FindBreakNode(CXFA_Node* pContainerNode, + CXFA_Node*& pCurActionNode, + XFA_ItemLayoutProcessorStages* nCurStage, + bool bBreakBefore) { + bool bFindRs = false; + for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode; + pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { + XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before; + if (!bBreakBefore) + eAttributeType = XFA_ATTRIBUTE_After; + + switch (pBreakNode->GetElementType()) { + case XFA_Element::BreakBefore: { + if (bBreakBefore) { + pCurActionNode = pBreakNode; + *nCurStage = XFA_ItemLayoutProcessorStages::BreakBefore; + bFindRs = true; + } + break; + } + case XFA_Element::BreakAfter: { + if (!bBreakBefore) { + pCurActionNode = pBreakNode; + *nCurStage = XFA_ItemLayoutProcessorStages::BreakAfter; + bFindRs = true; + } + break; + } + case XFA_Element::Break: + if (pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) { + pCurActionNode = pBreakNode; + *nCurStage = XFA_ItemLayoutProcessorStages::BreakBefore; + if (!bBreakBefore) + *nCurStage = XFA_ItemLayoutProcessorStages::BreakAfter; + + bFindRs = true; + } + break; + default: + break; + } + if (bFindRs) + break; + } + return bFindRs; +} + +void DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) { + CXFA_FFNotify* pNotify = pGenerateNode->GetDocument()->GetNotify(); + CXFA_LayoutProcessor* pDocLayout = + pGenerateNode->GetDocument()->GetDocLayout(); + CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator( + pGenerateNode); + for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; + pNode = sIterator.MoveToNext()) { + CXFA_ContentLayoutItem* pCurLayoutItem = + (CXFA_ContentLayoutItem*)pNode->GetUserData(XFA_LAYOUTITEMKEY); + CXFA_ContentLayoutItem* pNextLayoutItem = nullptr; + while (pCurLayoutItem) { + pNextLayoutItem = pCurLayoutItem->m_pNext; + pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem); + delete pCurLayoutItem; + pCurLayoutItem = pNextLayoutItem; + } + } + pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode); +} + +uint8_t HAlignEnumToInt(XFA_ATTRIBUTEENUM eHAlign) { + switch (eHAlign) { + case XFA_ATTRIBUTEENUM_Center: + return 1; + case XFA_ATTRIBUTEENUM_Right: + return 2; + case XFA_ATTRIBUTEENUM_Left: + default: + return 0; + } +} + +XFA_ItemLayoutProcessorResult InsertFlowedItem( + CXFA_ItemLayoutProcessor* pThis, + CXFA_ItemLayoutProcessor* pProcessor, + bool bContainerWidthAutoSize, + bool bContainerHeightAutoSize, + FX_FLOAT fContainerHeight, + XFA_ATTRIBUTEENUM eFlowStrategy, + uint8_t* uCurHAlignState, + CFX_ArrayTemplate<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3], + bool bUseBreakControl, + FX_FLOAT fAvailHeight, + FX_FLOAT fRealHeight, + FX_FLOAT fContentWidthLimit, + FX_FLOAT* fContentCurRowY, + FX_FLOAT* fContentCurRowAvailWidth, + FX_FLOAT* fContentCurRowHeight, + bool* bAddedItemInRow, + bool* bForceEndPage, + CXFA_LayoutContext* pLayoutContext, + bool bNewRow) { + bool bTakeSpace = + XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode); + uint8_t uHAlign = + HAlignEnumToInt(pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign)); + if (bContainerWidthAutoSize) + uHAlign = 0; + + if ((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && + uHAlign < *uCurHAlignState) || + (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && + uHAlign > *uCurHAlignState)) { + return XFA_ItemLayoutProcessorResult::RowFullBreak; + } + + *uCurHAlignState = uHAlign; + bool bIsOwnSplit = + pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None; + bool bUseRealHeight = + bTakeSpace && bContainerHeightAutoSize && bIsOwnSplit && + pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() == + XFA_ATTRIBUTEENUM_None; + bool bIsTransHeight = bTakeSpace; + if (bIsTransHeight && !bIsOwnSplit) { + bool bRootForceTb = false; + XFA_ATTRIBUTEENUM eLayoutStrategy = + GetLayout(pProcessor->m_pFormNode, &bRootForceTb); + if (eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb || + eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) { + bIsTransHeight = false; + } + } + + bool bUseInherited = false; + CXFA_LayoutContext layoutContext; + if (pThis->m_pPageMgr) { + CXFA_Node* pOverflowNode = + pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode); + if (pOverflowNode) { + layoutContext.m_pOverflowNode = pOverflowNode; + layoutContext.m_pOverflowProcessor = pThis; + pLayoutContext = &layoutContext; + } + } + + XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult::Done; + if (!bNewRow || + pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult::Done) { + eRetValue = pProcessor->DoLayout( + bTakeSpace ? bUseBreakControl : false, + bUseRealHeight ? fRealHeight - *fContentCurRowY : FLT_MAX, + bIsTransHeight ? fRealHeight - *fContentCurRowY : FLT_MAX, + pLayoutContext); + pProcessor->m_ePreProcessRs = eRetValue; + } else { + eRetValue = pProcessor->m_ePreProcessRs; + pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult::Done; + } + if (pProcessor->HasLayoutItem() == false) + return eRetValue; + + CFX_SizeF childSize = pProcessor->GetCurrentComponentSize(); + if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) { + fRealHeight = FLT_MAX; + fAvailHeight = FLT_MAX; + } + if (bTakeSpace && (childSize.width > + *fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) && + (fContentWidthLimit - *fContentCurRowAvailWidth > + XFA_LAYOUT_FLOAT_PERCISION)) { + return XFA_ItemLayoutProcessorResult::RowFullBreak; + } + + CXFA_Node* pOverflowLeaderNode = nullptr; + CXFA_Node* pOverflowTrailerNode = nullptr; + CXFA_Node* pFormNode = nullptr; + CXFA_ContentLayoutItem* pTrailerLayoutItem = nullptr; + bool bIsAddTrailerHeight = false; + if (pThis->m_pPageMgr && + pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) { + pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode); + if (!pFormNode && pLayoutContext && pLayoutContext->m_pOverflowProcessor) { + pFormNode = pLayoutContext->m_pOverflowNode; + bUseInherited = true; + } + if (pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, + pOverflowTrailerNode, false, + false)) { + if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) { + if (pOverflowTrailerNode) { + auto pOverflowLeaderProcessor = + pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pOverflowTrailerNode, + nullptr); + pOverflowLeaderProcessor->DoLayout(false, FLT_MAX, FLT_MAX, nullptr); + pTrailerLayoutItem = + pOverflowLeaderProcessor->HasLayoutItem() + ? pOverflowLeaderProcessor->ExtractLayoutItem() + : nullptr; + } + + bIsAddTrailerHeight = + bUseInherited + ? pThis->IsAddNewRowForTrailer(pTrailerLayoutItem) + : pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem); + if (bIsAddTrailerHeight) { + childSize.height += pTrailerLayoutItem->m_sSize.height; + bIsAddTrailerHeight = true; + } + } + } + } + + if (!bTakeSpace || + *fContentCurRowY + childSize.height <= + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION || + (!bContainerHeightAutoSize && + pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >= + fContainerHeight)) { + if (!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult::Done) { + if (pProcessor->m_bUseInheriated) { + if (pTrailerLayoutItem) + AddTrailerBeforeSplit(pProcessor, childSize.height, + pTrailerLayoutItem, false); + if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) + AddPendingNode(pProcessor, pOverflowLeaderNode, false); + + pProcessor->m_bUseInheriated = false; + } else { + if (bIsAddTrailerHeight) + childSize.height -= pTrailerLayoutItem->m_sSize.height; + + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, + pOverflowTrailerNode, + pTrailerLayoutItem, pFormNode); + } + + CXFA_ContentLayoutItem* pChildLayoutItem = + pProcessor->ExtractLayoutItem(); + if (ExistContainerKeep(pProcessor->m_pFormNode, false) && + pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) { + pThis->m_arrayKeepItems.push_back(pChildLayoutItem); + } else { + pThis->m_arrayKeepItems.clear(); + } + rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem); + *bAddedItemInRow = true; + if (bTakeSpace) { + *fContentCurRowAvailWidth -= childSize.width; + *fContentCurRowHeight = + std::max(*fContentCurRowHeight, childSize.height); + } + return XFA_ItemLayoutProcessorResult::Done; + } + + if (eRetValue == XFA_ItemLayoutProcessorResult::PageFullBreak) { + if (pProcessor->m_bUseInheriated) { + if (pTrailerLayoutItem) { + AddTrailerBeforeSplit(pProcessor, childSize.height, + pTrailerLayoutItem, false); + } + if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) + AddPendingNode(pProcessor, pOverflowLeaderNode, false); + + pProcessor->m_bUseInheriated = false; + } else { + if (bIsAddTrailerHeight) + childSize.height -= pTrailerLayoutItem->m_sSize.height; + + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, + pOverflowTrailerNode, + pTrailerLayoutItem, pFormNode); + } + } + rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); + *bAddedItemInRow = true; + *fContentCurRowAvailWidth -= childSize.width; + *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height); + return eRetValue; + } + + XFA_ItemLayoutProcessorResult eResult; + if (pThis->ProcessKeepForSplit( + pThis, pProcessor, eRetValue, &rgCurLineLayoutItems[uHAlign], + fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY, + bAddedItemInRow, bForceEndPage, &eResult)) { + return eResult; + } + + *bForceEndPage = true; + FX_FLOAT fSplitPos = + pProcessor->FindSplitPos(fAvailHeight - *fContentCurRowY); + if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { + XFA_ATTRIBUTEENUM eLayout = + pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); + if (eLayout == XFA_ATTRIBUTEENUM_Tb && + eRetValue == XFA_ItemLayoutProcessorResult::Done) { + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, + pOverflowTrailerNode, pTrailerLayoutItem, + pFormNode); + rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); + *bAddedItemInRow = true; + if (bTakeSpace) { + *fContentCurRowAvailWidth -= childSize.width; + *fContentCurRowHeight = + std::max(*fContentCurRowHeight, childSize.height); + } + return XFA_ItemLayoutProcessorResult::PageFullBreak; + } + + CXFA_Node* pTempLeaderNode = nullptr; + CXFA_Node* pTempTrailerNode = nullptr; + if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated && + eRetValue != XFA_ItemLayoutProcessorResult::PageFullBreak) { + pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, + pTempTrailerNode, false, true); + } + if (pTrailerLayoutItem && bIsAddTrailerHeight) { + AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem, + bUseInherited); + } else { + pProcessor->SplitLayoutItem(fSplitPos); + } + + if (bUseInherited) { + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, + pOverflowTrailerNode, pTrailerLayoutItem, + pFormNode); + pThis->m_bUseInheriated = true; + } else { + CXFA_LayoutItem* firstChild = pProcessor->m_pLayoutItem->m_pFirstChild; + if (firstChild && !firstChild->m_pNextSibling && + firstChild->m_pFormNode->IsLayoutGeneratedNode()) { + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, + pOverflowTrailerNode, + pTrailerLayoutItem, pFormNode); + } else if (pProcessor->JudgeLeaderOrTrailerForOccur( + pOverflowLeaderNode)) { + AddPendingNode(pProcessor, pOverflowLeaderNode, false); + } + } + + if (pProcessor->m_pLayoutItem->m_pNextSibling) { + childSize = pProcessor->GetCurrentComponentSize(); + rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); + *bAddedItemInRow = true; + if (bTakeSpace) { + *fContentCurRowAvailWidth -= childSize.width; + *fContentCurRowHeight = + std::max(*fContentCurRowHeight, childSize.height); + } + } + return XFA_ItemLayoutProcessorResult::PageFullBreak; + } + + if (*fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) { + childSize = pProcessor->GetCurrentComponentSize(); + if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(childSize.height)) { + CXFA_Node* pTempLeaderNode = nullptr; + CXFA_Node* pTempTrailerNode = nullptr; + if (pThis->m_pPageMgr) { + if (!pFormNode && pLayoutContext) + pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode; + + pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, + pTempTrailerNode, false, true); + } + if (bUseInherited) { + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, + pOverflowTrailerNode, + pTrailerLayoutItem, pFormNode); + pThis->m_bUseInheriated = true; + } + return XFA_ItemLayoutProcessorResult::PageFullBreak; + } + + rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); + *bAddedItemInRow = true; + if (bTakeSpace) { + *fContentCurRowAvailWidth -= childSize.width; + *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height); + } + if (eRetValue == XFA_ItemLayoutProcessorResult::Done) + *bForceEndPage = false; + + return eRetValue; + } + + XFA_ATTRIBUTEENUM eLayout = + pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); + if (pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None && + eLayout == XFA_ATTRIBUTEENUM_Tb) { + if (pThis->m_pPageMgr) { + pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, + pOverflowTrailerNode, false, true); + } + if (pTrailerLayoutItem) + AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem, false); + if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) + AddPendingNode(pProcessor, pOverflowLeaderNode, false); + + return XFA_ItemLayoutProcessorResult::PageFullBreak; + } + + if (eRetValue != XFA_ItemLayoutProcessorResult::Done) + return XFA_ItemLayoutProcessorResult::PageFullBreak; + + if (!pFormNode && pLayoutContext) + pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode; + if (pThis->m_pPageMgr) { + pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, + pOverflowTrailerNode, false, true); + } + if (bUseInherited) { + pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, + pTrailerLayoutItem, pFormNode); + pThis->m_bUseInheriated = true; + } + return XFA_ItemLayoutProcessorResult::PageFullBreak; +} + +bool FindLayoutItemSplitPos(CXFA_ContentLayoutItem* pLayoutItem, + FX_FLOAT fCurVerticalOffset, + FX_FLOAT* fProposedSplitPos, + bool* bAppChange, + bool bCalculateMargin) { + CXFA_Node* pFormNode = pLayoutItem->m_pFormNode; + if (*fProposedSplitPos <= fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION || + *fProposedSplitPos > fCurVerticalOffset + pLayoutItem->m_sSize.height - + XFA_LAYOUT_FLOAT_PERCISION) { + return false; + } + + switch (pFormNode->GetIntact()) { + case XFA_ATTRIBUTEENUM_None: { + bool bAnyChanged = false; + CXFA_Document* pDocument = pFormNode->GetDocument(); + CXFA_FFNotify* pNotify = pDocument->GetNotify(); + FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0; + CXFA_Node* pMarginNode = + pFormNode->GetFirstChildByClass(XFA_Element::Margin); + if (pMarginNode && bCalculateMargin) { + fCurTopMargin = + pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); + fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset) + .ToUnit(XFA_UNIT_Pt); + } + bool bChanged = true; + while (bChanged) { + bChanged = false; + { + FX_FLOAT fRelSplitPos = *fProposedSplitPos - fCurVerticalOffset; + if (pNotify->FindSplitPos(pFormNode, pLayoutItem->GetIndex(), + fRelSplitPos)) { + bAnyChanged = true; + bChanged = true; + *fProposedSplitPos = fCurVerticalOffset + fRelSplitPos; + *bAppChange = true; + if (*fProposedSplitPos <= + fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) { + return true; + } + } + } + FX_FLOAT fRelSplitPos = *fProposedSplitPos - fCurBottomMargin; + for (CXFA_ContentLayoutItem* pChildItem = + (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild; + pChildItem; + pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) { + FX_FLOAT fChildOffset = + fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y; + bool bChange = false; + if (FindLayoutItemSplitPos(pChildItem, fChildOffset, &fRelSplitPos, + &bChange, bCalculateMargin)) { + if (fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION && + bChange) { + *fProposedSplitPos = fRelSplitPos - fCurTopMargin; + } else { + *fProposedSplitPos = fRelSplitPos + fCurBottomMargin; + } + bAnyChanged = true; + bChanged = true; + if (*fProposedSplitPos <= + fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) { + return true; + } + if (bAnyChanged) + break; + } + } + } + return bAnyChanged; + } + case XFA_ATTRIBUTEENUM_ContentArea: + case XFA_ATTRIBUTEENUM_PageArea: { + *fProposedSplitPos = fCurVerticalOffset; + return true; + } + default: + return false; + } +} + +CFX_PointF CalculatePositionedContainerPos(CXFA_Node* pNode, + const CFX_SizeF& size) { + XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType); + int32_t nAnchorType = 0; + switch (eAnchorType) { + case XFA_ATTRIBUTEENUM_TopLeft: + nAnchorType = 0; + break; + case XFA_ATTRIBUTEENUM_TopCenter: + nAnchorType = 1; + break; + case XFA_ATTRIBUTEENUM_TopRight: + nAnchorType = 2; + break; + case XFA_ATTRIBUTEENUM_MiddleLeft: + nAnchorType = 3; + break; + case XFA_ATTRIBUTEENUM_MiddleCenter: + nAnchorType = 4; + break; + case XFA_ATTRIBUTEENUM_MiddleRight: + nAnchorType = 5; + break; + case XFA_ATTRIBUTEENUM_BottomLeft: + nAnchorType = 6; + break; + case XFA_ATTRIBUTEENUM_BottomCenter: + nAnchorType = 7; + break; + case XFA_ATTRIBUTEENUM_BottomRight: + nAnchorType = 8; + break; + default: + break; + } + static const uint8_t nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8}, + {6, 3, 0, 7, 4, 1, 8, 5, 2}, + {8, 7, 6, 5, 4, 3, 2, 1, 0}, + {2, 5, 8, 1, 4, 7, 0, 3, 6}}; + + CFX_PointF pos(pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt), + pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt)); + int32_t nRotate = + FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); + nRotate = XFA_MapRotation(nRotate) / 90; + int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType]; + switch (nAbsoluteAnchorType / 3) { + case 1: + pos.y -= size.height / 2; + break; + case 2: + pos.y -= size.height; + break; + default: + break; + } + switch (nAbsoluteAnchorType % 3) { + case 1: + pos.x -= size.width / 2; + break; + case 2: + pos.x -= size.width; + break; + default: + break; + } + return pos; +} + +} // namespace + +CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node* pNode, + CXFA_LayoutPageMgr* pPageMgr) + : m_pFormNode(pNode), + m_pLayoutItem(nullptr), + m_pCurChildNode(XFA_LAYOUT_INVALIDNODE), + m_fUsedSize(0), + m_pPageMgr(pPageMgr), + m_bBreakPending(true), + m_fLastRowWidth(0), + m_fLastRowY(0), + m_bUseInheriated(false), + m_ePreProcessRs(XFA_ItemLayoutProcessorResult::Done), + m_bKeepBreakFinish(false), + m_bIsProcessKeep(false), + m_pKeepHeadNode(nullptr), + m_pKeepTailNode(nullptr), + m_pOldLayoutItem(nullptr), + m_pCurChildPreprocessor(nullptr), + m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages::None), + m_fWidthLimite(0), + m_bHasAvailHeight(true) { + ASSERT(m_pFormNode && (m_pFormNode->IsContainerNode() || + m_pFormNode->GetElementType() == XFA_Element::Form)); + m_pOldLayoutItem = + (CXFA_ContentLayoutItem*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY); +} + +CXFA_ItemLayoutProcessor::~CXFA_ItemLayoutProcessor() {} + +CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::CreateContentLayoutItem( + CXFA_Node* pFormNode) { + if (!pFormNode) + return nullptr; + + CXFA_ContentLayoutItem* pLayoutItem = nullptr; + if (m_pOldLayoutItem) { + pLayoutItem = m_pOldLayoutItem; + m_pOldLayoutItem = m_pOldLayoutItem->m_pNext; + return pLayoutItem; + } + pLayoutItem = (CXFA_ContentLayoutItem*)pFormNode->GetDocument() + ->GetNotify() + ->OnCreateLayoutItem(pFormNode); + CXFA_ContentLayoutItem* pPrevLayoutItem = + (CXFA_ContentLayoutItem*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY); + if (pPrevLayoutItem) { + while (pPrevLayoutItem->m_pNext) + pPrevLayoutItem = pPrevLayoutItem->m_pNext; + + pPrevLayoutItem->m_pNext = pLayoutItem; + pLayoutItem->m_pPrev = pPrevLayoutItem; + } else { + pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem); + } + return pLayoutItem; +} + FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos) { ASSERT(m_pLayoutItem); XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); - bool bCalculateMargin = true; - if (eLayout == XFA_ATTRIBUTEENUM_Position) { - bCalculateMargin = false; - } + bool bCalculateMargin = eLayout != XFA_ATTRIBUTEENUM_Position; while (fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { bool bAppChange = false; - if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange, - bCalculateMargin)) { + if (!FindLayoutItemSplitPos(m_pLayoutItem, 0, &fProposedSplitPos, + &bAppChange, bCalculateMargin)) { break; } } return fProposedSplitPos; } + void CXFA_ItemLayoutProcessor::SplitLayoutItem( CXFA_ContentLayoutItem* pLayoutItem, CXFA_ContentLayoutItem* pSecondParent, @@ -270,9 +1170,9 @@ void CXFA_ItemLayoutProcessor::SplitLayoutItem( FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0; XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); bool bCalculateMargin = true; - if (eLayout == XFA_ATTRIBUTEENUM_Position) { + if (eLayout == XFA_ATTRIBUTEENUM_Position) bCalculateMargin = false; - } + CXFA_Node* pMarginNode = pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); if (pMarginNode && bCalculateMargin) { @@ -281,6 +1181,7 @@ void CXFA_ItemLayoutProcessor::SplitLayoutItem( fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); } + CXFA_ContentLayoutItem* pSecondLayoutItem = nullptr; if (m_pCurChildPreprocessor && m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) { @@ -290,21 +1191,21 @@ void CXFA_ItemLayoutProcessor::SplitLayoutItem( pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode); } pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x; - pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x; + pSecondLayoutItem->m_sSize.width = pLayoutItem->m_sSize.width; pSecondLayoutItem->m_sPos.y = 0; - pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos; - pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y; - if (pLayoutItem->m_pFirstChild) { - pSecondLayoutItem->m_sSize.y += fCurTopMargin; - } + pSecondLayoutItem->m_sSize.height = pLayoutItem->m_sSize.height - fSplitPos; + pLayoutItem->m_sSize.height -= pSecondLayoutItem->m_sSize.height; + if (pLayoutItem->m_pFirstChild) + pSecondLayoutItem->m_sSize.height += fCurTopMargin; + if (pSecondParent) { pSecondParent->AddChild(pSecondLayoutItem); if (fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) { - pSecondParent->m_sSize.y += fCurTopMargin; + pSecondParent->m_sSize.height += fCurTopMargin; CXFA_ContentLayoutItem* pParentItem = (CXFA_ContentLayoutItem*)pSecondParent->m_pParent; while (pParentItem) { - pParentItem->m_sSize.y += fCurTopMargin; + pParentItem->m_sSize.height += fCurTopMargin; pParentItem = (CXFA_ContentLayoutItem*)pParentItem->m_pParent; } } @@ -313,6 +1214,7 @@ void CXFA_ItemLayoutProcessor::SplitLayoutItem( pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling; pLayoutItem->m_pNextSibling = pSecondLayoutItem; } + CXFA_ContentLayoutItem* pChildren = (CXFA_ContentLayoutItem*)pLayoutItem->m_pFirstChild; pLayoutItem->m_pFirstChild = nullptr; @@ -325,249 +1227,66 @@ void CXFA_ItemLayoutProcessor::SplitLayoutItem( pChildItem->m_pNextSibling = nullptr; if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin + XFA_LAYOUT_FLOAT_PERCISION) { - if (!XFA_ExistContainerKeep(pChildItem->m_pFormNode, true)) { + if (!ExistContainerKeep(pChildItem->m_pFormNode, true)) { pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin; pChildItem->m_sPos.y += lHeightForKeep; pChildItem->m_sPos.y += fAddMarginHeight; pSecondLayoutItem->AddChild(pChildItem); - } else { - if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) { - for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); - iIndex++) { - CXFA_ContentLayoutItem* pPreItem = keepLayoutItems[iIndex]; - pLayoutItem->RemoveChild(pPreItem); - pPreItem->m_sPos.y -= fSplitPos; - if (pPreItem->m_sPos.y < 0) { - pPreItem->m_sPos.y = 0; - } - if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) { - pPreItem->m_sPos.y = lHeightForKeep; - lHeightForKeep += pPreItem->m_sSize.y; - pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y; - if (pSecondParent) { - pSecondParent->m_sSize.y += pPreItem->m_sSize.y; - } - } - pSecondLayoutItem->AddChild(pPreItem); - } - } - pChildItem->m_sPos.y -= fSplitPos; - pChildItem->m_sPos.y += lHeightForKeep; - pChildItem->m_sPos.y += fAddMarginHeight; - pSecondLayoutItem->AddChild(pChildItem); - } - } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >= - fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y + - pChildItem->m_sSize.y) { - pLayoutItem->AddChild(pChildItem); - if (XFA_ExistContainerKeep(pChildItem->m_pFormNode, false)) { - keepLayoutItems.Add(pChildItem); - } else { - keepLayoutItems.RemoveAll(); + continue; } - } else { - FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y; - SplitLayoutItem( - pChildItem, pSecondLayoutItem, - fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y); - fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight; - pLayoutItem->AddChild(pChildItem); - } - } -} -void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos) { - ASSERT(m_pLayoutItem); - SplitLayoutItem(m_pLayoutItem, nullptr, fSplitPos); -} -CXFA_ContainerLayoutItem* CXFA_LayoutItem::GetPage() const { - for (CXFA_LayoutItem* pCurNode = const_cast<CXFA_LayoutItem*>(this); pCurNode; - pCurNode = pCurNode->m_pParent) { - if (pCurNode->m_pFormNode->GetElementType() == XFA_Element::PageArea) - return static_cast<CXFA_ContainerLayoutItem*>(pCurNode); - } - return nullptr; -} - -CXFA_Node* CXFA_LayoutItem::GetFormNode() const { - return m_pFormNode; -} + if (lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) { + for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) { + CXFA_ContentLayoutItem* pPreItem = keepLayoutItems[iIndex]; + pLayoutItem->RemoveChild(pPreItem); + pPreItem->m_sPos.y -= fSplitPos; + if (pPreItem->m_sPos.y < 0) + pPreItem->m_sPos.y = 0; -void CXFA_LayoutItem::GetRect(CFX_RectF& rtLayout, bool bRelative) const { - ASSERT(m_bIsContentLayoutItem); - const CXFA_ContentLayoutItem* pThis = - static_cast<const CXFA_ContentLayoutItem*>(this); - CFX_PointF sPos = pThis->m_sPos; - CFX_SizeF sSize = pThis->m_sSize; - if (!bRelative) { - for (CXFA_LayoutItem* pLayoutItem = pThis->m_pParent; pLayoutItem; - pLayoutItem = pLayoutItem->m_pParent) { - if (CXFA_ContentLayoutItem* pContent = - pLayoutItem->AsContentLayoutItem()) { - sPos += pContent->m_sPos; - if (CXFA_Node* pMarginNode = - pLayoutItem->m_pFormNode->GetFirstChildByClass( - XFA_Element::Margin)) { - sPos += CFX_PointF(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset) - .ToUnit(XFA_UNIT_Pt), - pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset) - .ToUnit(XFA_UNIT_Pt)); - } - } else { - if (pLayoutItem->m_pFormNode->GetElementType() == - XFA_Element::ContentArea) { - sPos += - CFX_PointF(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X) - .ToUnit(XFA_UNIT_Pt), - pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y) - .ToUnit(XFA_UNIT_Pt)); - break; - } else if (pLayoutItem->m_pFormNode->GetElementType() == - XFA_Element::PageArea) { - break; + if (pPreItem->m_sPos.y + pPreItem->m_sSize.height > lHeightForKeep) { + pPreItem->m_sPos.y = lHeightForKeep; + lHeightForKeep += pPreItem->m_sSize.height; + pSecondLayoutItem->m_sSize.height += pPreItem->m_sSize.height; + if (pSecondParent) + pSecondParent->m_sSize.height += pPreItem->m_sSize.height; + } + pSecondLayoutItem->AddChild(pPreItem); } } - } - } - rtLayout.Set(sPos.x, sPos.y, sSize.x, sSize.y); -} - -CXFA_LayoutItem* CXFA_LayoutItem::GetParent() const { - return m_pParent; -} - -const CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() const { - ASSERT(m_bIsContentLayoutItem); - const CXFA_ContentLayoutItem* pCurNode = - static_cast<const CXFA_ContentLayoutItem*>(this); - while (pCurNode->m_pPrev) { - pCurNode = pCurNode->m_pPrev; - } - return pCurNode; -} -CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() { - ASSERT(m_bIsContentLayoutItem); - CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this); - while (pCurNode->m_pPrev) { - pCurNode = pCurNode->m_pPrev; - } - return pCurNode; -} - -CXFA_LayoutItem* CXFA_LayoutItem::GetLast() { - ASSERT(m_bIsContentLayoutItem); - CXFA_ContentLayoutItem* pCurNode = static_cast<CXFA_ContentLayoutItem*>(this); - while (pCurNode->m_pNext) { - pCurNode = pCurNode->m_pNext; - } - return pCurNode; -} - -const CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const { - ASSERT(m_bIsContentLayoutItem); - const CXFA_ContentLayoutItem* pCurNode = - static_cast<const CXFA_ContentLayoutItem*>(this); - while (pCurNode->m_pNext) { - pCurNode = pCurNode->m_pNext; - } - return pCurNode; -} + pChildItem->m_sPos.y -= fSplitPos; + pChildItem->m_sPos.y += lHeightForKeep; + pChildItem->m_sPos.y += fAddMarginHeight; + pSecondLayoutItem->AddChild(pChildItem); + continue; + } -CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const { - ASSERT(m_bIsContentLayoutItem); - return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pPrev; -} + if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >= + fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y + + pChildItem->m_sSize.height) { + pLayoutItem->AddChild(pChildItem); + if (ExistContainerKeep(pChildItem->m_pFormNode, false)) + keepLayoutItems.Add(pChildItem); + else + keepLayoutItems.RemoveAll(); -CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const { - ASSERT(m_bIsContentLayoutItem); - return static_cast<const CXFA_ContentLayoutItem*>(this)->m_pNext; -} + continue; + } -int32_t CXFA_LayoutItem::GetIndex() const { - ASSERT(m_bIsContentLayoutItem); - int32_t iIndex = 0; - const CXFA_ContentLayoutItem* pCurNode = - static_cast<const CXFA_ContentLayoutItem*>(this); - while (pCurNode->m_pPrev) { - pCurNode = pCurNode->m_pPrev; - ++iIndex; + FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.height; + SplitLayoutItem( + pChildItem, pSecondLayoutItem, + fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y); + fAddMarginHeight = pSecondLayoutItem->m_sSize.height - fOldHeight; + pLayoutItem->AddChild(pChildItem); } - return iIndex; } -int32_t CXFA_LayoutItem::GetCount() const { - ASSERT(m_bIsContentLayoutItem); - int32_t iCount = GetIndex() + 1; - const CXFA_ContentLayoutItem* pCurNode = - static_cast<const CXFA_ContentLayoutItem*>(this); - while (pCurNode->m_pNext) { - pCurNode = pCurNode->m_pNext; - iCount++; - } - return iCount; +void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos) { + ASSERT(m_pLayoutItem); + SplitLayoutItem(m_pLayoutItem, nullptr, fSplitPos); } -void CXFA_LayoutItem::AddChild(CXFA_LayoutItem* pChildItem) { - if (pChildItem->m_pParent) { - pChildItem->m_pParent->RemoveChild(pChildItem); - } - pChildItem->m_pParent = this; - if (!m_pFirstChild) { - m_pFirstChild = pChildItem; - } else { - CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; - while (pExistingChildItem->m_pNextSibling) { - pExistingChildItem = pExistingChildItem->m_pNextSibling; - } - pExistingChildItem->m_pNextSibling = pChildItem; - } -} -void CXFA_LayoutItem::AddHeadChild(CXFA_LayoutItem* pChildItem) { - if (pChildItem->m_pParent) { - pChildItem->m_pParent->RemoveChild(pChildItem); - } - pChildItem->m_pParent = this; - if (!m_pFirstChild) { - m_pFirstChild = pChildItem; - } else { - CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; - m_pFirstChild = pChildItem; - m_pFirstChild->m_pNextSibling = pExistingChildItem; - } -} -void CXFA_LayoutItem::InsertChild(CXFA_LayoutItem* pBeforeItem, - CXFA_LayoutItem* pChildItem) { - if (pBeforeItem->m_pParent != this) { - return; - } - if (pChildItem->m_pParent) { - pChildItem->m_pParent = nullptr; - } - pChildItem->m_pParent = this; - CXFA_LayoutItem* pExistingChildItem = pBeforeItem->m_pNextSibling; - pBeforeItem->m_pNextSibling = pChildItem; - pChildItem->m_pNextSibling = pExistingChildItem; -} -void CXFA_LayoutItem::RemoveChild(CXFA_LayoutItem* pChildItem) { - if (pChildItem->m_pParent != this) { - return; - } - if (m_pFirstChild == pChildItem) { - m_pFirstChild = pChildItem->m_pNextSibling; - } else { - CXFA_LayoutItem* pExistingChildItem = m_pFirstChild; - while (pExistingChildItem && - pExistingChildItem->m_pNextSibling != pChildItem) { - pExistingChildItem = pExistingChildItem->m_pNextSibling; - } - if (pExistingChildItem) { - pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling; - } - } - pChildItem->m_pNextSibling = nullptr; - pChildItem->m_pParent = nullptr; -} CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() { CXFA_ContentLayoutItem* pLayoutItem = m_pLayoutItem; if (pLayoutItem) { @@ -575,11 +1294,15 @@ CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() { static_cast<CXFA_ContentLayoutItem*>(pLayoutItem->m_pNextSibling); pLayoutItem->m_pNextSibling = nullptr; } - if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done || - !ToContentLayoutItem(m_pOldLayoutItem)) + + if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Done || + !ToContentLayoutItem(m_pOldLayoutItem)) { return pLayoutItem; + } + if (m_pOldLayoutItem->m_pPrev) m_pOldLayoutItem->m_pPrev->m_pNext = nullptr; + CXFA_FFNotify* pNotify = m_pOldLayoutItem->m_pFormNode->GetDocument()->GetNotify(); CXFA_LayoutProcessor* pDocLayout = @@ -590,79 +1313,15 @@ CXFA_ContentLayoutItem* CXFA_ItemLayoutProcessor::ExtractLayoutItem() { pNotify->OnLayoutItemRemoving(pDocLayout, pOldLayoutItem); if (pOldLayoutItem->m_pParent) pOldLayoutItem->m_pParent->RemoveChild(pOldLayoutItem); + delete pOldLayoutItem; pOldLayoutItem = pNextOldLayoutItem; } m_pOldLayoutItem = nullptr; return pLayoutItem; } -static bool XFA_ItemLayoutProcessor_FindBreakNode( - CXFA_Node* pContainerNode, - CXFA_Node*& pCurActionNode, - XFA_ItemLayoutProcessorStages& nCurStage, - bool bBreakBefore) { - bool bFindRs = false; - for (CXFA_Node* pBreakNode = pContainerNode; pBreakNode; - pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { - XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before; - if (!bBreakBefore) { - eAttributeType = XFA_ATTRIBUTE_After; - } - switch (pBreakNode->GetElementType()) { - case XFA_Element::BreakBefore: { - if (bBreakBefore) { - pCurActionNode = pBreakNode; - nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore; - bFindRs = true; - } - } break; - case XFA_Element::BreakAfter: { - if (!bBreakBefore) { - pCurActionNode = pBreakNode; - nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter; - bFindRs = true; - } - } break; - case XFA_Element::Break: - if (pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) { - pCurActionNode = pBreakNode; - nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore; - if (!bBreakBefore) { - nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter; - } - bFindRs = true; - break; - } - default: - break; - } - if (bFindRs) { - break; - } - } - return bFindRs; -} -static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode) { - CXFA_FFNotify* pNotify = pGenerateNode->GetDocument()->GetNotify(); - CXFA_LayoutProcessor* pDocLayout = - pGenerateNode->GetDocument()->GetDocLayout(); - CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator( - pGenerateNode); - for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; - pNode = sIterator.MoveToNext()) { - CXFA_ContentLayoutItem* pCurLayoutItem = - (CXFA_ContentLayoutItem*)pNode->GetUserData(XFA_LAYOUTITEMKEY); - CXFA_ContentLayoutItem* pNextLayoutItem = nullptr; - while (pCurLayoutItem) { - pNextLayoutItem = pCurLayoutItem->m_pNext; - pNotify->OnLayoutItemRemoving(pDocLayout, pCurLayoutItem); - delete pCurLayoutItem; - pCurLayoutItem = pNextLayoutItem; - } - } - pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode); -} -void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( + +void CXFA_ItemLayoutProcessor::GotoNextContainerNode( CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pParentContainer, @@ -670,32 +1329,33 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( CXFA_Node* pEntireContainer = pParentContainer; CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE; switch (nCurStage) { - case XFA_ItemLayoutProcessorStages_BreakBefore: - case XFA_ItemLayoutProcessorStages_BreakAfter: { + case XFA_ItemLayoutProcessorStages::BreakBefore: + case XFA_ItemLayoutProcessorStages::BreakAfter: { pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent); - } break; - case XFA_ItemLayoutProcessorStages_Keep: - case XFA_ItemLayoutProcessorStages_Container: + break; + } + case XFA_ItemLayoutProcessorStages::Keep: + case XFA_ItemLayoutProcessorStages::Container: pChildContainer = pCurActionNode; break; default: pChildContainer = XFA_LAYOUT_INVALIDNODE; break; } + switch (nCurStage) { - case XFA_ItemLayoutProcessorStages_Keep: { + case XFA_ItemLayoutProcessorStages::Keep: { CXFA_Node* pBreakAfterNode = pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild); if (!m_bKeepBreakFinish && - XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, - nCurStage, false)) { + FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage, false)) { return; } goto CheckNextChildContainer; } - case XFA_ItemLayoutProcessorStages_None: { + case XFA_ItemLayoutProcessorStages::None: { pCurActionNode = XFA_LAYOUT_INVALIDNODE; - case XFA_ItemLayoutProcessorStages_BookendLeader: + case XFA_ItemLayoutProcessorStages::BookendLeader: for (CXFA_Node* pBookendNode = pCurActionNode == XFA_LAYOUT_INVALIDNODE ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) @@ -706,7 +1366,7 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( case XFA_Element::Bookend: case XFA_Element::Break: pCurActionNode = pBookendNode; - nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader; + nCurStage = XFA_ItemLayoutProcessorStages::BookendLeader; return; default: break; @@ -715,13 +1375,13 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( } { pCurActionNode = XFA_LAYOUT_INVALIDNODE; - case XFA_ItemLayoutProcessorStages_BreakBefore: + case XFA_ItemLayoutProcessorStages::BreakBefore: if (pCurActionNode != XFA_LAYOUT_INVALIDNODE) { CXFA_Node* pBreakBeforeNode = pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling); if (!m_bKeepBreakFinish && - XFA_ItemLayoutProcessor_FindBreakNode( - pBreakBeforeNode, pCurActionNode, nCurStage, true)) { + FindBreakNode(pBreakBeforeNode, pCurActionNode, &nCurStage, + true)) { return; } if (m_bIsProcessKeep) { @@ -732,33 +1392,34 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( goto CheckNextChildContainer; } pCurActionNode = pChildContainer; - nCurStage = XFA_ItemLayoutProcessorStages_Container; + nCurStage = XFA_ItemLayoutProcessorStages::Container; return; } goto CheckNextChildContainer; } - case XFA_ItemLayoutProcessorStages_Container: { + case XFA_ItemLayoutProcessorStages::Container: { pCurActionNode = XFA_LAYOUT_INVALIDNODE; - case XFA_ItemLayoutProcessorStages_BreakAfter: { + case XFA_ItemLayoutProcessorStages::BreakAfter: { if (pCurActionNode == XFA_LAYOUT_INVALIDNODE) { CXFA_Node* pBreakAfterNode = pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild); if (!m_bKeepBreakFinish && - XFA_ItemLayoutProcessor_FindBreakNode( - pBreakAfterNode, pCurActionNode, nCurStage, false)) { + FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage, + false)) { return; } } else { CXFA_Node* pBreakAfterNode = pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling); - if (XFA_ItemLayoutProcessor_FindBreakNode( - pBreakAfterNode, pCurActionNode, nCurStage, false)) { + if (FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage, + false)) { return; } } goto CheckNextChildContainer; } } + CheckNextChildContainer : { CXFA_Node* pNextChildContainer = pChildContainer == XFA_LAYOUT_INVALIDNODE @@ -772,33 +1433,33 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( pNextChildContainer = pNextChildContainer->GetNodeItem( XFA_NODEITEM_NextSibling, XFA_ObjectType::ContainerNode); if (pSaveNode->IsUnusedNode()) - XFA_DeleteLayoutGeneratedNode(pSaveNode); + DeleteLayoutGeneratedNode(pSaveNode); } - if (!pNextChildContainer) { + if (!pNextChildContainer) goto NoMoreChildContainer; - } + bool bLastKeep = false; if (ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage, pNextChildContainer, bLastKeep)) { return; } if (!m_bKeepBreakFinish && !bLastKeep && - XFA_ItemLayoutProcessor_FindBreakNode( + FindBreakNode( pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild), - pCurActionNode, nCurStage, true)) { + pCurActionNode, &nCurStage, true)) { return; } pCurActionNode = pNextChildContainer; - if (m_bIsProcessKeep) { - nCurStage = XFA_ItemLayoutProcessorStages_Keep; - } else { - nCurStage = XFA_ItemLayoutProcessorStages_Container; - } + if (m_bIsProcessKeep) + nCurStage = XFA_ItemLayoutProcessorStages::Keep; + else + nCurStage = XFA_ItemLayoutProcessorStages::Container; return; } + NoMoreChildContainer : { pCurActionNode = XFA_LAYOUT_INVALIDNODE; - case XFA_ItemLayoutProcessorStages_BookendTrailer: + case XFA_ItemLayoutProcessorStages::BookendTrailer: for (CXFA_Node* pBookendNode = pCurActionNode == XFA_LAYOUT_INVALIDNODE ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) @@ -809,7 +1470,7 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( case XFA_Element::Bookend: case XFA_Element::Break: pCurActionNode = pBookendNode; - nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer; + nCurStage = XFA_ItemLayoutProcessorStages::BookendTrailer; return; default: break; @@ -818,9 +1479,10 @@ void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode( } default: pCurActionNode = nullptr; - nCurStage = XFA_ItemLayoutProcessorStages_Done; + nCurStage = XFA_ItemLayoutProcessorStages::Done; } } + bool CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext( CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, @@ -828,38 +1490,39 @@ bool CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext( bool& bLastKeepNode) { const bool bCanSplit = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None; bool bNextKeep = false; - if (XFA_ExistContainerKeep(pNextContainer, false)) { + if (ExistContainerKeep(pNextContainer, false)) bNextKeep = true; - } + if (bNextKeep && !bCanSplit) { if (!m_bIsProcessKeep && !m_bKeepBreakFinish) { m_pKeepHeadNode = pNextContainer; m_bIsProcessKeep = true; } - } else { - if (m_bIsProcessKeep && m_pKeepHeadNode) { - m_pKeepTailNode = pNextContainer; - if (!m_bKeepBreakFinish && - XFA_ItemLayoutProcessor_FindBreakNode( - pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild), - pCurActionNode, nCurStage, true)) { - return true; - } else { - pNextContainer = m_pKeepHeadNode; - m_bKeepBreakFinish = true; - m_pKeepHeadNode = nullptr; - m_pKeepTailNode = nullptr; - m_bIsProcessKeep = false; - } - } else { - if (m_bKeepBreakFinish) { - bLastKeepNode = true; - } - m_bKeepBreakFinish = false; + return false; + } + + if (m_bIsProcessKeep && m_pKeepHeadNode) { + m_pKeepTailNode = pNextContainer; + if (!m_bKeepBreakFinish && + FindBreakNode(pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild), + pCurActionNode, &nCurStage, true)) { + return true; } + + pNextContainer = m_pKeepHeadNode; + m_bKeepBreakFinish = true; + m_pKeepHeadNode = nullptr; + m_pKeepTailNode = nullptr; + m_bIsProcessKeep = false; + } else { + if (m_bKeepBreakFinish) + bLastKeepNode = true; + m_bKeepBreakFinish = false; } + return false; } + bool CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore( CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, @@ -870,214 +1533,61 @@ bool CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore( m_pKeepHeadNode = nullptr; m_pKeepTailNode = nullptr; m_bIsProcessKeep = false; - nCurStage = XFA_ItemLayoutProcessorStages_Container; + nCurStage = XFA_ItemLayoutProcessorStages::Container; return true; } + CXFA_Node* pBreakAfterNode = pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild); - if (XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, - nCurStage, false)) { - return true; - } - return false; + return FindBreakNode(pBreakAfterNode, pCurActionNode, &nCurStage, false); } + bool XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode) { XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence); return ePresence == XFA_ATTRIBUTEENUM_Visible || ePresence == XFA_ATTRIBUTEENUM_Invisible; } -static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( - CXFA_Node* pFormNode, - FX_FLOAT& fContainerWidth, - FX_FLOAT& fContainerHeight, - bool& bContainerWidthAutoSize, - bool& bContainerHeightAutoSize) { - fContainerWidth = 0; - fContainerHeight = 0; - bContainerWidthAutoSize = true; - bContainerHeightAutoSize = true; - XFA_Element eType = pFormNode->GetElementType(); - CXFA_Measurement mTmpValue; - if (bContainerWidthAutoSize && - (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup) && - pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, false) && - mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { - fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt); - bContainerWidthAutoSize = false; - } - if (bContainerHeightAutoSize && - (eType == XFA_Element::Subform || eType == XFA_Element::ExclGroup) && - pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, false) && - mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { - fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt); - bContainerHeightAutoSize = false; - } - if (bContainerWidthAutoSize && eType == XFA_Element::Subform && - pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, false) && - mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { - fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt); - bContainerWidthAutoSize = false; - } - if (bContainerHeightAutoSize && eType == XFA_Element::Subform && - pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, false) && - mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) { - fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt); - bContainerHeightAutoSize = false; - } -} -static inline void -XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( - CXFA_Node* pFormNode, - bool bContainerWidthAutoSize, - FX_FLOAT fContentCalculatedWidth, - FX_FLOAT& fContainerWidth, - bool bContainerHeightAutoSize, - FX_FLOAT fContentCalculatedHeight, - FX_FLOAT& fContainerHeight) { - CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_Element::Margin); - CXFA_Measurement mTmpValue; - if (bContainerWidthAutoSize) { - fContainerWidth = fContentCalculatedWidth; - if (pMarginNode) { - if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, false)) { - fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt); - } - if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, false)) { - fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt); - } - } - } - if (bContainerHeightAutoSize) { - fContainerHeight = fContentCalculatedHeight; - if (pMarginNode) { - if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, false)) { - fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt); - } - if (pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue, - false)) { - fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt); - } - } - } -} -void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos( - CXFA_Node* pNode, - FX_FLOAT fWidth, - FX_FLOAT fHeight, - FX_FLOAT& fAbsoluteX, - FX_FLOAT& fAbsoluteY) { - XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType); - int32_t nAnchorType = 0; - switch (eAnchorType) { - case XFA_ATTRIBUTEENUM_TopLeft: - nAnchorType = 0; - break; - case XFA_ATTRIBUTEENUM_TopCenter: - nAnchorType = 1; - break; - case XFA_ATTRIBUTEENUM_TopRight: - nAnchorType = 2; - break; - case XFA_ATTRIBUTEENUM_MiddleLeft: - nAnchorType = 3; - break; - case XFA_ATTRIBUTEENUM_MiddleCenter: - nAnchorType = 4; - break; - case XFA_ATTRIBUTEENUM_MiddleRight: - nAnchorType = 5; - break; - case XFA_ATTRIBUTEENUM_BottomLeft: - nAnchorType = 6; - break; - case XFA_ATTRIBUTEENUM_BottomCenter: - nAnchorType = 7; - break; - case XFA_ATTRIBUTEENUM_BottomRight: - nAnchorType = 8; - break; - default: - break; - } - static const uint8_t nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8}, - {6, 3, 0, 7, 4, 1, 8, 5, 2}, - {8, 7, 6, 5, 4, 3, 2, 1, 0}, - {2, 5, 8, 1, 4, 7, 0, 3, 6}}; - FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt); - FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt); - int32_t nRotate = - FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); - nRotate = XFA_MapRotation(nRotate) / 90; - int32_t nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType]; - fAbsoluteX = fAnchorX; - fAbsoluteY = fAnchorY; - switch (nAbsoluteAnchorType / 3) { - case 1: - fAbsoluteY -= fHeight / 2; - break; - case 2: - fAbsoluteY -= fHeight; - break; - default: - break; - } - switch (nAbsoluteAnchorType % 3) { - case 1: - fAbsoluteX -= fWidth / 2; - break; - case 2: - fAbsoluteX -= fWidth; - break; - default: - break; - } -} bool CXFA_ItemLayoutProcessor::IncrementRelayoutNode( CXFA_LayoutProcessor* pLayoutProcessor, CXFA_Node* pNode, CXFA_Node* pParentNode) { return false; } + void CXFA_ItemLayoutProcessor::DoLayoutPageArea( CXFA_ContainerLayoutItem* pPageAreaLayoutItem) { CXFA_Node* pFormNode = pPageAreaLayoutItem->m_pFormNode; CXFA_Node* pCurChildNode = XFA_LAYOUT_INVALIDNODE; XFA_ItemLayoutProcessorStages nCurChildNodeStage = - XFA_ItemLayoutProcessorStages_None; + XFA_ItemLayoutProcessorStages::None; CXFA_LayoutItem* pBeforeItem = nullptr; - for (XFA_ItemLayoutProcessor_GotoNextContainerNode( - pCurChildNode, nCurChildNodeStage, pFormNode, false); - pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode( - pCurChildNode, nCurChildNodeStage, pFormNode, false)) { - if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) { + for (GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, + false); + pCurChildNode; GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, + pFormNode, false)) { + if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Container) continue; - } - if (pCurChildNode->GetElementType() == XFA_Element::Variables) { + if (pCurChildNode->GetElementType() == XFA_Element::Variables) continue; - } - CXFA_ItemLayoutProcessor* pProcessor = - new CXFA_ItemLayoutProcessor(pCurChildNode, nullptr); - pProcessor->DoLayout(false, XFA_LAYOUT_FLOAT_MAX); - if (!pProcessor->HasLayoutItem()) { - delete pProcessor; + + auto pProcessor = + pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pCurChildNode, nullptr); + pProcessor->DoLayout(false, FLT_MAX, FLT_MAX, nullptr); + if (!pProcessor->HasLayoutItem()) continue; - } - FX_FLOAT fWidth, fHeight; - pProcessor->GetCurrentComponentSize(fWidth, fHeight); - FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0; - CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX, - fAbsoluteY); - pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY); + + pProcessor->SetCurrentComponentPos(CalculatePositionedContainerPos( + pCurChildNode, pProcessor->GetCurrentComponentSize())); CXFA_LayoutItem* pProcessItem = pProcessor->ExtractLayoutItem(); - if (!pBeforeItem) { + if (!pBeforeItem) pPageAreaLayoutItem->AddHeadChild(pProcessItem); - } else { + else pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem); - } + pBeforeItem = pProcessItem; - delete pProcessor; } + pBeforeItem = nullptr; CXFA_LayoutItem* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild; while (pLayoutItem) { @@ -1086,19 +1596,21 @@ void CXFA_ItemLayoutProcessor::DoLayoutPageArea( pLayoutItem = pLayoutItem->m_pNextSibling; continue; } - if (pLayoutItem->m_pFormNode->GetElementType() == XFA_Element::Draw) { - CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling; - pPageAreaLayoutItem->RemoveChild(pLayoutItem); - if (!pBeforeItem) { - pPageAreaLayoutItem->AddHeadChild(pLayoutItem); - } else { - pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem); - } - pBeforeItem = pLayoutItem; - pLayoutItem = pNextLayoutItem; - } + if (pLayoutItem->m_pFormNode->GetElementType() != XFA_Element::Draw) + continue; + + CXFA_LayoutItem* pNextLayoutItem = pLayoutItem->m_pNextSibling; + pPageAreaLayoutItem->RemoveChild(pLayoutItem); + if (!pBeforeItem) + pPageAreaLayoutItem->AddHeadChild(pLayoutItem); + else + pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem); + + pBeforeItem = pLayoutItem; + pLayoutItem = pNextLayoutItem; } } + void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer( CXFA_LayoutContext* pContext) { if (m_pLayoutItem) @@ -1107,29 +1619,30 @@ void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer( m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); bool bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) != XFA_ATTRIBUTEENUM_Position); - FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; - bool bContainerWidthAutoSize = true, bContainerHeightAutoSize = true; - XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( - m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, - bContainerHeightAutoSize); - FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; - FX_FLOAT fHiddenContentCalculatedWidth = 0, - fHiddenContentCalculatedHeight = 0; + bool bContainerWidthAutoSize = true; + bool bContainerHeightAutoSize = true; + CFX_SizeF containerSize = CalculateContainerSpecifiedSize( + m_pFormNode, &bContainerWidthAutoSize, &bContainerHeightAutoSize); + + FX_FLOAT fContentCalculatedWidth = 0; + FX_FLOAT fContentCalculatedHeight = 0; + FX_FLOAT fHiddenContentCalculatedWidth = 0; + FX_FLOAT fHiddenContentCalculatedHeight = 0; if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) { - XFA_ItemLayoutProcessor_GotoNextContainerNode( - m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, false); + GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, + false); } + int32_t iColIndex = 0; - for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode( + for (; m_pCurChildNode; GotoNextContainerNode( m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, false)) { - if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) { + if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Container) continue; - } - if (m_pCurChildNode->GetElementType() == XFA_Element::Variables) { + if (m_pCurChildNode->GetElementType() == XFA_Element::Variables) continue; - } - CXFA_ItemLayoutProcessor* pProcessor = - new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr); + + auto pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + m_pCurChildNode, m_pPageMgr); if (pContext && pContext->m_prgSpecifiedColumnWidths) { int32_t iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan); if (iColSpan <= @@ -1138,39 +1651,37 @@ void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer( pContext->m_bCurColumnWidthAvaiable = true; if (iColSpan == -1) iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize(); + for (int32_t i = 0; iColIndex + i < iColSpan; ++i) { pContext->m_fCurColumnWidth += pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i); } if (pContext->m_fCurColumnWidth == 0) pContext->m_bCurColumnWidthAvaiable = false; + iColIndex += iColSpan >= 0 ? iColSpan : 0; } } - pProcessor->DoLayout(false, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, - pContext); - if (!pProcessor->HasLayoutItem()) { - delete pProcessor; + + pProcessor->DoLayout(false, FLT_MAX, FLT_MAX, pContext); + if (!pProcessor->HasLayoutItem()) continue; - } - FX_FLOAT fWidth, fHeight; - pProcessor->GetCurrentComponentSize(fWidth, fHeight); + + CFX_SizeF size = pProcessor->GetCurrentComponentSize(); bool bChangeParentSize = false; - if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) { + if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) bChangeParentSize = true; - } - FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0; - if (!bIgnoreXY) { - CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight, - fAbsoluteX, fAbsoluteY); - } - pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY); + + CFX_PointF absolutePos; + if (!bIgnoreXY) + absolutePos = CalculatePositionedContainerPos(m_pCurChildNode, size); + + pProcessor->SetCurrentComponentPos(absolutePos); if (bContainerWidthAutoSize) { - FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth; + FX_FLOAT fChildSuppliedWidth = absolutePos.x + size.width; if (bChangeParentSize) { - if (fContentCalculatedWidth < fChildSuppliedWidth) { - fContentCalculatedWidth = fChildSuppliedWidth; - } + fContentCalculatedWidth = + std::max(fContentCalculatedWidth, fChildSuppliedWidth); } else { if (fHiddenContentCalculatedWidth < fChildSuppliedWidth && m_pCurChildNode->GetElementType() != XFA_Element::Subform) { @@ -1178,12 +1689,12 @@ void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer( } } } + if (bContainerHeightAutoSize) { - FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight; + FX_FLOAT fChildSuppliedHeight = absolutePos.y + size.height; if (bChangeParentSize) { - if (fContentCalculatedHeight < fChildSuppliedHeight) { - fContentCalculatedHeight = fChildSuppliedHeight; - } + fContentCalculatedHeight = + std::max(fContentCalculatedHeight, fChildSuppliedHeight); } else { if (fHiddenContentCalculatedHeight < fChildSuppliedHeight && m_pCurChildNode->GetElementType() != XFA_Element::Subform) { @@ -1192,201 +1703,35 @@ void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer( } } m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem()); - delete pProcessor; } + XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode(); - if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) { + if (fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) fContentCalculatedWidth = fHiddenContentCalculatedWidth; - } - if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) { + if (fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) fContentCalculatedHeight = fHiddenContentCalculatedHeight; - } - XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( + + containerSize = CalculateContainerComponentSizeFromContentSize( m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, - fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, - fContainerHeight); - SetCurrentComponentSize(fContainerWidth, fContainerHeight); -} -static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize( - CXFA_ContentLayoutItem* pLayoutItem, - FX_FLOAT& fWidth, - FX_FLOAT& fHeight) { - CXFA_Node* pNode = pLayoutItem->m_pFormNode; - ASSERT(pNode); - switch (pNode->GetElementType()) { - case XFA_Element::Subform: - case XFA_Element::Area: - case XFA_Element::ExclGroup: - case XFA_Element::SubformSet: { - if (fWidth < -XFA_LAYOUT_FLOAT_PERCISION) { - fWidth = pLayoutItem->m_sSize.x; - } - if (fHeight < -XFA_LAYOUT_FLOAT_PERCISION) { - fHeight = pLayoutItem->m_sSize.y; - } - break; - } - case XFA_Element::Draw: - case XFA_Element::Field: { - pNode->GetDocument()->GetNotify()->StartFieldDrawLayout(pNode, fWidth, - fHeight); - break; - } - default: - ASSERT(false); - } -} -static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells( - CXFA_ContentLayoutItem* pLayoutRow, - const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths, - XFA_ATTRIBUTEENUM eLayout) { - FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; - bool bContainerWidthAutoSize = true, bContainerHeightAutoSize = true; - XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( - pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight, - bContainerWidthAutoSize, bContainerHeightAutoSize); - CXFA_Node* pMarginNode = - pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); - FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; - if (pMarginNode) { - fLeftInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); - fTopInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); - fRightInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); - fBottomInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); - } - FX_FLOAT fContentWidthLimit = - bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX - : fContainerWidth - fLeftInset - fRightInset; - FX_FLOAT fContentCurrentHeight = - pLayoutRow->m_sSize.y - fTopInset - fBottomInset; - FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; - FX_FLOAT fCurrentColX = 0; - int32_t nCurrentColIdx = 0; - bool bMetWholeRowCell = false; - for (CXFA_ContentLayoutItem* pLayoutChild = - (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; - pLayoutChild; - pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { - int32_t nOriginalColSpan = - pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan); - int32_t nColSpan = nOriginalColSpan; - FX_FLOAT fColSpanWidth = 0; - if (nColSpan == -1 || - nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) { - nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx; - } - for (int32_t i = 0; i < nColSpan; i++) { - fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i]; - } - if (nColSpan != nOriginalColSpan) { - fColSpanWidth = bMetWholeRowCell ? 0 : std::max(fColSpanWidth, - pLayoutChild->m_sSize.y); - } - if (nOriginalColSpan == -1) { - bMetWholeRowCell = true; - } - pLayoutChild->m_sPos = CFX_PointF(fCurrentColX, 0); - pLayoutChild->m_sSize.x = fColSpanWidth; - if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) { - fCurrentColX += fColSpanWidth; - nCurrentColIdx += nColSpan; - FX_FLOAT fNewHeight = - bContainerHeightAutoSize ? -1 : fContentCurrentHeight; - XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth, - fNewHeight); - pLayoutChild->m_sSize.y = fNewHeight; - if (bContainerHeightAutoSize) { - FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y; - if (fContentCalculatedHeight < fChildSuppliedHeight) { - fContentCalculatedHeight = fChildSuppliedHeight; - } - } - } - } - if (bContainerHeightAutoSize) { - for (CXFA_ContentLayoutItem* pLayoutChild = - (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; - pLayoutChild; - pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { - XFA_ItemLayoutProcessor_UpdateWidgetSize( - pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight); - FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y; - pLayoutChild->m_sSize.y = fContentCalculatedHeight; - CXFA_Node* pParaNode = - pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_Element::Para); - if (pParaNode && pLayoutChild->m_pFirstChild) { - FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight; - XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign); - switch (eVType) { - case XFA_ATTRIBUTEENUM_Middle: - fOffHeight = fOffHeight / 2; - break; - case XFA_ATTRIBUTEENUM_Bottom: - break; - case XFA_ATTRIBUTEENUM_Top: - default: - fOffHeight = 0; - break; - } - if (fOffHeight > 0) { - for (CXFA_ContentLayoutItem* pInnerLayoutChild = - (CXFA_ContentLayoutItem*)pLayoutChild->m_pFirstChild; - pInnerLayoutChild; - pInnerLayoutChild = - (CXFA_ContentLayoutItem*)pInnerLayoutChild->m_pNextSibling) { - pInnerLayoutChild->m_sPos.y += fOffHeight; - } - } - } - } - } - if (bContainerWidthAutoSize) { - FX_FLOAT fChildSuppliedWidth = fCurrentColX; - if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && - fContentWidthLimit > fChildSuppliedWidth) { - fChildSuppliedWidth = fContentWidthLimit; - } - if (fContentCalculatedWidth < fChildSuppliedWidth) { - fContentCalculatedWidth = fChildSuppliedWidth; - } - } else { - fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset; - } - if (pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) == - XFA_ATTRIBUTEENUM_Rl_row) { - for (CXFA_ContentLayoutItem* pLayoutChild = - (CXFA_ContentLayoutItem*)pLayoutRow->m_pFirstChild; - pLayoutChild; - pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { - pLayoutChild->m_sPos.x = fContentCalculatedWidth - - pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x; - } - } - XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( - pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, - fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, - fContainerHeight); - pLayoutRow->m_sSize = CFX_SizeF(fContainerWidth, fContainerHeight); + bContainerHeightAutoSize, fContentCalculatedHeight, containerSize); + SetCurrentComponentSize(containerSize); } + void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) { if (m_pLayoutItem) return; - - if (!pLayoutNode) { + if (!pLayoutNode) pLayoutNode = m_pFormNode; - } + ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE); + m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); - FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; - bool bContainerWidthAutoSize = true, bContainerHeightAutoSize = true; - XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( - m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, - bContainerHeightAutoSize); - FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; + bool bContainerWidthAutoSize = true; + bool bContainerHeightAutoSize = true; + CFX_SizeF containerSize = CalculateContainerSpecifiedSize( + m_pFormNode, &bContainerWidthAutoSize, &bContainerHeightAutoSize); + FX_FLOAT fContentCalculatedWidth = 0; + FX_FLOAT fContentCalculatedHeight = 0; CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); FX_FLOAT fLeftInset = 0; @@ -1397,54 +1742,52 @@ void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) { fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); } + FX_FLOAT fContentWidthLimit = - bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX - : fContainerWidth - fLeftInset - fRightInset; + bContainerWidthAutoSize ? FLT_MAX + : containerSize.width - fLeftInset - fRightInset; CFX_WideStringC wsColumnWidths; if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) { - std::vector<CFX_WideString> widths; - if (SeparateStringW(wsColumnWidths.c_str(), wsColumnWidths.GetLength(), - L' ', widths) > 0) { - int32_t iCols = pdfium::CollectionSize<int32_t>(widths); - CFX_WideString wsWidth; - for (int32_t i = 0; i < iCols; i++) { - wsWidth = widths[i]; - wsWidth.TrimLeft(L' '); - if (!wsWidth.IsEmpty()) { - CXFA_Measurement measure(wsWidth.AsStringC()); - m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt)); - } - } + auto widths = SeparateStringW(wsColumnWidths.c_str(), + wsColumnWidths.GetLength(), L' '); + for (auto& width : widths) { + width.TrimLeft(L' '); + if (width.IsEmpty()) + continue; + + CXFA_Measurement measure(width.AsStringC()); + m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt)); } } + int32_t iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize(); CXFA_LayoutContext layoutContext; layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths; CXFA_LayoutContext* pLayoutContext = iSpecifiedColumnCount > 0 ? &layoutContext : nullptr; if (m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) { - XFA_ItemLayoutProcessor_GotoNextContainerNode( - m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, false); + GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, + false); } - for (; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode( + + for (; m_pCurChildNode; GotoNextContainerNode( m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, false)) { layoutContext.m_bCurColumnWidthAvaiable = false; layoutContext.m_fCurColumnWidth = 0; - if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) { + if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Container) continue; - } - CXFA_ItemLayoutProcessor* pProcessor = - new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr); - pProcessor->DoLayout(false, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, - pLayoutContext); - if (!pProcessor->HasLayoutItem()) { - delete pProcessor; + + auto pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + m_pCurChildNode, m_pPageMgr); + pProcessor->DoLayout(false, FLT_MAX, FLT_MAX, pLayoutContext); + if (!pProcessor->HasLayoutItem()) continue; - } + m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem()); - delete pProcessor; } - int32_t iRowCount = 0, iColCount = 0; + + int32_t iRowCount = 0; + int32_t iColCount = 0; { CFX_ArrayTemplate<CXFA_ContentLayoutItem*> rgRowItems; CFX_ArrayTemplate<int32_t> rgRowItemsSpan; @@ -1453,12 +1796,11 @@ void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) { (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { - if (pLayoutChild->m_pFormNode->GetElementType() != XFA_Element::Subform) { + if (pLayoutChild->m_pFormNode->GetElementType() != XFA_Element::Subform) continue; - } - if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) { + if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) continue; - } + XFA_ATTRIBUTEENUM eLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); if (eLayout != XFA_ATTRIBUTEENUM_Row && @@ -1471,9 +1813,10 @@ void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) { int32_t iColSpan = pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan); rgRowItemsSpan.Add(iColSpan); - rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x); + rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.width); } } + iRowCount = rgRowItems.GetSize(); iColCount = 0; bool bMoreColumns = true; @@ -1495,390 +1838,212 @@ void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode) { pNewCell ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan) : 0; - rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0; + rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.width : 0; } CXFA_ContentLayoutItem* pCell = rgRowItems[i]; - if (!pCell) { + if (!pCell) continue; - } + bMoreColumns = true; - if (rgRowItemsSpan[i] == 1) { - if (iColCount >= iSpecifiedColumnCount) { - for (int32_t j = 0, c = iColCount + 1 - - m_rgSpecifiedColumnWidths.GetSize(); - j < c; j++) { - m_rgSpecifiedColumnWidths.Add(0); - } - } - if (m_rgSpecifiedColumnWidths[iColCount] < - XFA_LAYOUT_FLOAT_PERCISION) { - bAutoCol = true; - } - if (bAutoCol && - m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) { - m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i]; - } + if (rgRowItemsSpan[i] != 1) + continue; + + if (iColCount >= iSpecifiedColumnCount) { + int32_t c = iColCount + 1 - m_rgSpecifiedColumnWidths.GetSize(); + for (int32_t j = 0; j < c; j++) + m_rgSpecifiedColumnWidths.Add(0); } - } - if (bMoreColumns) { - FX_FLOAT fFinalColumnWidth = 0.0f; - if (iColCount < m_rgSpecifiedColumnWidths.GetSize()) - fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount]; - for (int32_t i = 0; i < iRowCount; ++i) { - if (!rgRowItems[i]) - continue; - --rgRowItemsSpan[i]; - rgRowItemsWidth[i] -= fFinalColumnWidth; + if (m_rgSpecifiedColumnWidths[iColCount] < XFA_LAYOUT_FLOAT_PERCISION) + bAutoCol = true; + if (bAutoCol && + m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) { + m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i]; } - ++iColCount; } + + if (!bMoreColumns) + continue; + + FX_FLOAT fFinalColumnWidth = 0.0f; + if (iColCount < m_rgSpecifiedColumnWidths.GetSize()) + fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount]; + for (int32_t i = 0; i < iRowCount; ++i) { + if (!rgRowItems[i]) + continue; + --rgRowItemsSpan[i]; + rgRowItemsWidth[i] -= fFinalColumnWidth; + } + ++iColCount; } } + FX_FLOAT fCurrentRowY = 0; for (CXFA_ContentLayoutItem* pLayoutChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItem*)pLayoutChild->m_pNextSibling) { - if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) { + if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) continue; - } + if (pLayoutChild->m_pFormNode->GetElementType() == XFA_Element::Subform) { XFA_ATTRIBUTEENUM eSubformLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); if (eSubformLayout == XFA_ATTRIBUTEENUM_Row || eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) { - XFA_ItemLayoutProcessor_RelocateTableRowCells( - pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout); + RelocateTableRowCells(pLayoutChild, m_rgSpecifiedColumnWidths, + eSubformLayout); } } + pLayoutChild->m_sPos.y = fCurrentRowY; if (bContainerWidthAutoSize) { pLayoutChild->m_sPos.x = 0; } else { switch (pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { - case XFA_ATTRIBUTEENUM_Left: - default: - pLayoutChild->m_sPos.x = 0; - break; case XFA_ATTRIBUTEENUM_Center: pLayoutChild->m_sPos.x = - (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2; + (fContentWidthLimit - pLayoutChild->m_sSize.width) / 2; break; case XFA_ATTRIBUTEENUM_Right: - pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x; + pLayoutChild->m_sPos.x = + fContentWidthLimit - pLayoutChild->m_sSize.width; + break; + case XFA_ATTRIBUTEENUM_Left: + default: + pLayoutChild->m_sPos.x = 0; break; } } + if (bContainerWidthAutoSize) { FX_FLOAT fChildSuppliedWidth = - pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x; - if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && + pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.width; + if (fContentWidthLimit < FLT_MAX && fContentWidthLimit > fChildSuppliedWidth) { fChildSuppliedWidth = fContentWidthLimit; } - if (fContentCalculatedWidth < fChildSuppliedWidth) { - fContentCalculatedWidth = fChildSuppliedWidth; - } - } - fCurrentRowY += pLayoutChild->m_sSize.y; - } - if (bContainerHeightAutoSize) { - FX_FLOAT fChildSuppliedHeight = fCurrentRowY; - if (fContentCalculatedHeight < fChildSuppliedHeight) { - fContentCalculatedHeight = fChildSuppliedHeight; + fContentCalculatedWidth = + std::max(fContentCalculatedWidth, fChildSuppliedWidth); } + fCurrentRowY += pLayoutChild->m_sSize.height; } - XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( + + if (bContainerHeightAutoSize) + fContentCalculatedHeight = std::max(fContentCalculatedHeight, fCurrentRowY); + + containerSize = CalculateContainerComponentSizeFromContentSize( m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, - fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, - fContainerHeight); - SetCurrentComponentSize(fContainerWidth, fContainerHeight); -} -static uint8_t XFA_ItemLayoutProcessor_HAlignEnumToInt( - XFA_ATTRIBUTEENUM eHAlign) { - switch (eHAlign) { - case XFA_ATTRIBUTEENUM_Center: - return 1; - case XFA_ATTRIBUTEENUM_Right: - return 2; - case XFA_ATTRIBUTEENUM_Left: - default: - return 0; - } -} -static void XFA_ItemLayoutProcessor_UpdatePendedItemLayout( - CXFA_ItemLayoutProcessor* pProcessor, - CXFA_ContentLayoutItem* pLayoutItem) { - XFA_ATTRIBUTEENUM eLayout = - pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); - switch (eLayout) { - case XFA_ATTRIBUTEENUM_Row: - case XFA_ATTRIBUTEENUM_Rl_row: - XFA_ItemLayoutProcessor_RelocateTableRowCells( - pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout); - break; - default: - break; - } + bContainerHeightAutoSize, fContentCalculatedHeight, containerSize); + SetCurrentComponentSize(containerSize); } + bool CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer( CXFA_ContentLayoutItem* pTrailerItem) { - if (!pTrailerItem) { + if (!pTrailerItem) return false; - } - FX_FLOAT fWidth = pTrailerItem->m_sSize.x; + + FX_FLOAT fWidth = pTrailerItem->m_sSize.width; XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); - if (eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) { - return false; - } - return true; -} -static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( - CXFA_ItemLayoutProcessor* pProcessor, - FX_FLOAT fSplitPos, - CXFA_ContentLayoutItem* pTrailerLayoutItem, - bool bUseInherited = false) { - if (!pTrailerLayoutItem) { - return; - } - FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y; - if (bUseInherited) { - FX_FLOAT fNewSplitPos = 0; - if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) { - fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight); - } - if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { - pProcessor->SplitLayoutItem(fNewSplitPos); - } - return; - } - XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, - pTrailerLayoutItem); - CXFA_Node* pMarginNode = - pProcessor->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); - FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; - if (pMarginNode) { - fLeftInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); - fTopInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt); - fRightInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); - fBottomInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); - } - if (!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) { - pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY; - pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth; - pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x; - pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem); - return; - } - FX_FLOAT fNewSplitPos = 0; - if (fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) { - fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight); - } - if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { - pProcessor->SplitLayoutItem(fNewSplitPos); - pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset; - } else { - pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset; - } - switch (pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { - case XFA_ATTRIBUTEENUM_Left: - default: - pTrailerLayoutItem->m_sPos.x = fLeftInset; - break; - case XFA_ATTRIBUTEENUM_Right: - pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - - fRightInset - - pTrailerLayoutItem->m_sSize.x; - break; - case XFA_ATTRIBUTEENUM_Center: - pTrailerLayoutItem->m_sPos.x = - (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - - pTrailerLayoutItem->m_sSize.x) / - 2; - break; - } - pProcessor->m_pLayoutItem->m_sSize.y += fHeight; - pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem); -} -static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit( - CXFA_ItemLayoutProcessor* pProcessor, - CXFA_ContentLayoutItem* pLeaderLayoutItem) { - XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem); - CXFA_Node* pMarginNode = - pProcessor->m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); - FX_FLOAT fLeftInset = 0; - FX_FLOAT fRightInset = 0; - if (pMarginNode) { - fLeftInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); - fRightInset = - pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt); - } - FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y; - for (CXFA_ContentLayoutItem* pChildItem = - (CXFA_ContentLayoutItem*)pProcessor->m_pLayoutItem->m_pFirstChild; - pChildItem; - pChildItem = (CXFA_ContentLayoutItem*)pChildItem->m_pNextSibling) { - pChildItem->m_sPos.y += fHeight; - } - pLeaderLayoutItem->m_sPos.y = 0; - switch (pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) { - case XFA_ATTRIBUTEENUM_Left: - default: - pLeaderLayoutItem->m_sPos.x = fLeftInset; - break; - case XFA_ATTRIBUTEENUM_Right: - pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - - fRightInset - pLeaderLayoutItem->m_sSize.x; - break; - case XFA_ATTRIBUTEENUM_Center: - pLeaderLayoutItem->m_sPos.x = - (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - - pLeaderLayoutItem->m_sSize.x) / - 2; - break; - } - pProcessor->m_pLayoutItem->m_sSize.y += fHeight; - pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem); -} -static void XFA_ItemLayoutProcessor_AddPendingNode( - CXFA_ItemLayoutProcessor* pProcessor, - CXFA_Node* pPendingNode, - bool bBreakPending) { - pProcessor->m_PendingNodes.push_back(pPendingNode); - pProcessor->m_bBreakPending = bBreakPending; -} -static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems( - CXFA_ItemLayoutProcessor* pProcessor, - CXFA_Node* pCurChildNode) { - FX_FLOAT fTotalHeight = 0; - if (pProcessor->m_PendingNodes.empty()) { - return fTotalHeight; - } - if (!pProcessor->m_pLayoutItem) { - pProcessor->m_pLayoutItem = - pProcessor->CreateContentLayoutItem(pCurChildNode); - pProcessor->m_pLayoutItem->m_sSize.clear(); - } - while (!pProcessor->m_PendingNodes.empty()) { - std::unique_ptr<CXFA_ItemLayoutProcessor> pPendingProcessor( - new CXFA_ItemLayoutProcessor(pProcessor->m_PendingNodes.front(), - nullptr)); - pProcessor->m_PendingNodes.pop_front(); - pPendingProcessor->DoLayout(false, XFA_LAYOUT_FLOAT_MAX); - CXFA_ContentLayoutItem* pPendingLayoutItem = - pPendingProcessor->HasLayoutItem() - ? pPendingProcessor->ExtractLayoutItem() - : nullptr; - if (pPendingLayoutItem) { - XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor, - pPendingLayoutItem); - if (pProcessor->m_bBreakPending) { - fTotalHeight += pPendingLayoutItem->m_sSize.y; - } - } - } - return fTotalHeight; + return eLayout == XFA_ATTRIBUTEENUM_Tb || m_fWidthLimite <= fWidth; } + FX_FLOAT CXFA_ItemLayoutProcessor::InsertKeepLayoutItems() { + if (m_arrayKeepItems.empty()) + return 0; + + if (!m_pLayoutItem) { + m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); + m_pLayoutItem->m_sSize.clear(); + } + FX_FLOAT fTotalHeight = 0; - if (m_arrayKeepItems.GetSize()) { - if (!m_pLayoutItem) { - m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); - m_pLayoutItem->m_sSize.clear(); - } - for (int32_t iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0; - iIndex--) { - XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this, - m_arrayKeepItems[iIndex]); - fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y; - } - m_arrayKeepItems.RemoveAll(); + for (auto iter = m_arrayKeepItems.rbegin(); iter != m_arrayKeepItems.rend(); + iter++) { + AddLeaderAfterSplit(this, *iter); + fTotalHeight += (*iter)->m_sSize.height; } + m_arrayKeepItems.clear(); + return fTotalHeight; } -bool CXFA_ItemLayoutProcessor::ProcessKeepForSplite( + +bool CXFA_ItemLayoutProcessor::ProcessKeepForSplit( CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue, - CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem, - FX_FLOAT& fContentCurRowAvailWidth, - FX_FLOAT& fContentCurRowHeight, - FX_FLOAT& fContentCurRowY, - bool& bAddedItemInRow, - bool& bForceEndPage, - XFA_ItemLayoutProcessorResult& result) { - if (!pParentProcessor || !pChildProcessor) { + CFX_ArrayTemplate<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem, + FX_FLOAT* fContentCurRowAvailWidth, + FX_FLOAT* fContentCurRowHeight, + FX_FLOAT* fContentCurRowY, + bool* bAddedItemInRow, + bool* bForceEndPage, + XFA_ItemLayoutProcessorResult* result) { + if (!pParentProcessor || !pChildProcessor) return false; + + if (pParentProcessor->m_pCurChildNode->GetIntact() == + XFA_ATTRIBUTEENUM_None && + pChildProcessor->m_bHasAvailHeight) + return false; + + if (!ExistContainerKeep(pParentProcessor->m_pCurChildNode, true)) + return false; + + CFX_SizeF childSize = pChildProcessor->GetCurrentComponentSize(); + std::vector<CXFA_ContentLayoutItem*> keepLayoutItems; + if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem, + childSize.height, &keepLayoutItems)) { + m_arrayKeepItems.clear(); + + for (auto item : keepLayoutItems) { + pParentProcessor->m_pLayoutItem->RemoveChild(item); + *fContentCurRowY -= item->m_sSize.height; + m_arrayKeepItems.push_back(item); + } + *bAddedItemInRow = true; + *bForceEndPage = true; + *result = XFA_ItemLayoutProcessorResult::PageFullBreak; + return true; } - if (pParentProcessor->m_pCurChildNode->GetIntact() != - XFA_ATTRIBUTEENUM_None || - !pChildProcessor->m_bHasAvailHeight) { - if (XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, true)) { - FX_FLOAT fChildWidth, fChildHeight; - pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); - CFX_ArrayTemplate<CXFA_ContentLayoutItem*> keepLayoutItems; - if (pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem, - fChildHeight, keepLayoutItems)) { - m_arrayKeepItems.RemoveAll(); - for (int32_t iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) { - CXFA_ContentLayoutItem* pItem = keepLayoutItems.GetAt(iIndex); - pParentProcessor->m_pLayoutItem->RemoveChild(pItem); - fContentCurRowY -= pItem->m_sSize.y; - m_arrayKeepItems.Add(pItem); - } - bAddedItemInRow = true; - bForceEndPage = true; - result = XFA_ItemLayoutProcessorResult_PageFullBreak; - return true; - } - rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem()); - bAddedItemInRow = true; - fContentCurRowAvailWidth -= fChildWidth; - if (fContentCurRowHeight < fChildHeight) { - fContentCurRowHeight = fChildHeight; - } - result = eRetValue; - return true; - } - } - return false; + + rgCurLineLayoutItem->Add(pChildProcessor->ExtractLayoutItem()); + *bAddedItemInRow = true; + *fContentCurRowAvailWidth -= childSize.width; + *fContentCurRowHeight = std::max(*fContentCurRowHeight, childSize.height); + *result = eRetValue; + + return true; } + bool CXFA_ItemLayoutProcessor::JudgePutNextPage( CXFA_ContentLayoutItem* pParentLayoutItem, FX_FLOAT fChildHeight, - CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems) { - if (!pParentLayoutItem) { + std::vector<CXFA_ContentLayoutItem*>* pKeepItems) { + if (!pParentLayoutItem) return false; - } + FX_FLOAT fItemsHeight = 0; for (CXFA_ContentLayoutItem* pChildLayoutItem = (CXFA_ContentLayoutItem*)pParentLayoutItem->m_pFirstChild; pChildLayoutItem; pChildLayoutItem = (CXFA_ContentLayoutItem*)pChildLayoutItem->m_pNextSibling) { - if (XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, false)) { - pKeepItems.Add(pChildLayoutItem); - fItemsHeight += pChildLayoutItem->m_sSize.y; + if (ExistContainerKeep(pChildLayoutItem->m_pFormNode, false)) { + pKeepItems->push_back(pChildLayoutItem); + fItemsHeight += pChildLayoutItem->m_sSize.height; } else { - pKeepItems.RemoveAll(); + pKeepItems->clear(); fItemsHeight = 0; } } fItemsHeight += fChildHeight; - if (m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) { - return true; - } - return false; + return m_pPageMgr->GetNextAvailContentHeight(fItemsHeight); } + void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) { - if (!pFormNode) { + if (!pFormNode) return; - } + CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator( pFormNode); for (CXFA_Node* pNode = sIterator.MoveToNext(); pNode; @@ -1893,6 +2058,7 @@ void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) { pNode->SetFlag(XFA_NodeFlag_UnusedNode, true); } } + void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow( CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, @@ -1900,370 +2066,19 @@ void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow( CXFA_Node* pFormNode) { ProcessUnUseBinds(pLeaderNode); ProcessUnUseBinds(pTrailerNode); - if (!pFormNode) { + if (!pFormNode) return; - } + if (pFormNode->GetElementType() == XFA_Element::Overflow || pFormNode->GetElementType() == XFA_Element::Break) { pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent); } - if (pLeaderNode && pFormNode) { + if (pLeaderNode && pFormNode) pFormNode->RemoveChild(pLeaderNode); - } - if (pTrailerNode && pFormNode) { + if (pTrailerNode && pFormNode) pFormNode->RemoveChild(pTrailerNode); - } - if (pTrailerItem) { + if (pTrailerItem) XFA_ReleaseLayoutItem(pTrailerItem); - } -} -static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem( - CXFA_ItemLayoutProcessor* pThis, - CXFA_ItemLayoutProcessor* pProcessor, - bool bContainerWidthAutoSize, - bool bContainerHeightAutoSize, - FX_FLOAT fContainerHeight, - XFA_ATTRIBUTEENUM eFlowStrategy, - uint8_t& uCurHAlignState, - CFX_ArrayTemplate<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3], - bool bUseBreakControl, - FX_FLOAT fAvailHeight, - FX_FLOAT fRealHeight, - FX_FLOAT& fContentCurRowY, - FX_FLOAT& fContentWidthLimit, - FX_FLOAT& fContentCurRowAvailWidth, - FX_FLOAT& fContentCurRowHeight, - bool& bAddedItemInRow, - bool& bForceEndPage, - CXFA_LayoutContext* pLayoutContext = nullptr, - bool bNewRow = false) { - bool bTakeSpace = - XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode); - uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt( - pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign)); - if (bContainerWidthAutoSize) { - uHAlign = 0; - } - if ((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) || - (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) { - return XFA_ItemLayoutProcessorResult_RowFullBreak; - } - uCurHAlignState = uHAlign; - bool bIsOwnSplite = - pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None; - bool bUseRealHeight = - bTakeSpace && bContainerHeightAutoSize && bIsOwnSplite && - pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() == - XFA_ATTRIBUTEENUM_None; - bool bIsTransHeight = bTakeSpace; - if (bIsTransHeight && !bIsOwnSplite) { - bool bRootForceTb = false; - XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout( - pProcessor->m_pFormNode, bRootForceTb); - if (eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb || - eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) { - bIsTransHeight = false; - } - } - bool bUseInherited = false; - CXFA_LayoutContext layoutContext; - if (pThis->m_pPageMgr) { - CXFA_Node* pOverflowNode = - pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode); - if (pOverflowNode) { - layoutContext.m_pOverflowNode = pOverflowNode; - layoutContext.m_pOverflowProcessor = pThis; - pLayoutContext = &layoutContext; - } - } - XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done; - if (!bNewRow || - pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) { - eRetValue = pProcessor->DoLayout( - bTakeSpace ? bUseBreakControl : false, - bUseRealHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, - bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, - pLayoutContext); - pProcessor->m_ePreProcessRs = eRetValue; - } else { - eRetValue = pProcessor->m_ePreProcessRs; - pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done; - } - if (pProcessor->HasLayoutItem() == false) { - return eRetValue; - } - FX_FLOAT fChildWidth, fChildHeight; - pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); - if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) { - fRealHeight = XFA_LAYOUT_FLOAT_MAX; - fAvailHeight = XFA_LAYOUT_FLOAT_MAX; - } - if (!bTakeSpace || - (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) || - (fContentWidthLimit - fContentCurRowAvailWidth <= - XFA_LAYOUT_FLOAT_PERCISION)) { - CXFA_Node* pOverflowLeaderNode = nullptr; - CXFA_Node* pOverflowTrailerNode = nullptr; - CXFA_Node* pFormNode = nullptr; - CXFA_ContentLayoutItem* pTrailerLayoutItem = nullptr; - bool bIsAddTrailerHeight = false; - if (pThis->m_pPageMgr && - pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) { - pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode); - if (!pFormNode && pLayoutContext && - pLayoutContext->m_pOverflowProcessor) { - pFormNode = pLayoutContext->m_pOverflowNode; - bUseInherited = true; - } - if (pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, - pOverflowTrailerNode, false, - false)) { - if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) { - if (pOverflowTrailerNode) { - CXFA_ItemLayoutProcessor* pOverflowLeaderProcessor = - new CXFA_ItemLayoutProcessor(pOverflowTrailerNode, nullptr); - pOverflowLeaderProcessor->DoLayout(false, XFA_LAYOUT_FLOAT_MAX); - pTrailerLayoutItem = - pOverflowLeaderProcessor->HasLayoutItem() - ? pOverflowLeaderProcessor->ExtractLayoutItem() - : nullptr; - delete pOverflowLeaderProcessor; - } - if (bUseInherited) { - bIsAddTrailerHeight = - pThis->IsAddNewRowForTrailer(pTrailerLayoutItem); - } else { - bIsAddTrailerHeight = - pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem); - } - if (bIsAddTrailerHeight) { - FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y; - fChildHeight += fTrailerHeight; - bIsAddTrailerHeight = true; - } - } - } - } - if (!bTakeSpace || - fContentCurRowY + fChildHeight <= - fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION || - (!bContainerHeightAutoSize && - pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >= - fContainerHeight)) { - if (!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) { - if (pProcessor->m_bUseInheriated) { - if (pTrailerLayoutItem) { - XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( - pProcessor, fChildHeight, pTrailerLayoutItem); - } - if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { - XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, - pOverflowLeaderNode, false); - } - pProcessor->m_bUseInheriated = false; - } else { - if (bIsAddTrailerHeight) { - fChildHeight -= pTrailerLayoutItem->m_sSize.y; - } - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - } - CXFA_ContentLayoutItem* pChildLayoutItem = - pProcessor->ExtractLayoutItem(); - if (XFA_ExistContainerKeep(pProcessor->m_pFormNode, false) && - pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) { - pThis->m_arrayKeepItems.Add(pChildLayoutItem); - } else { - pThis->m_arrayKeepItems.RemoveAll(); - } - rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem); - bAddedItemInRow = true; - if (bTakeSpace) { - fContentCurRowAvailWidth -= fChildWidth; - if (fContentCurRowHeight < fChildHeight) { - fContentCurRowHeight = fChildHeight; - } - } - return XFA_ItemLayoutProcessorResult_Done; - } else { - if (eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) { - if (pProcessor->m_bUseInheriated) { - if (pTrailerLayoutItem) { - XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( - pProcessor, fChildHeight, pTrailerLayoutItem); - } - if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { - XFA_ItemLayoutProcessor_AddPendingNode( - pProcessor, pOverflowLeaderNode, false); - } - pProcessor->m_bUseInheriated = false; - } else { - if (bIsAddTrailerHeight) { - fChildHeight -= pTrailerLayoutItem->m_sSize.y; - } - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - } - } - rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); - bAddedItemInRow = true; - fContentCurRowAvailWidth -= fChildWidth; - if (fContentCurRowHeight < fChildHeight) { - fContentCurRowHeight = fChildHeight; - } - return eRetValue; - } - } else { - XFA_ItemLayoutProcessorResult eResult; - if (pThis->ProcessKeepForSplite( - pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign], - fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY, - bAddedItemInRow, bForceEndPage, eResult)) { - return eResult; - } - bForceEndPage = true; - FX_FLOAT fSplitPos = - pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY); - if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) { - XFA_ATTRIBUTEENUM eLayout = - pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); - if (eLayout == XFA_ATTRIBUTEENUM_Tb && - eRetValue == XFA_ItemLayoutProcessorResult_Done) { - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); - bAddedItemInRow = true; - if (bTakeSpace) { - fContentCurRowAvailWidth -= fChildWidth; - if (fContentCurRowHeight < fChildHeight) { - fContentCurRowHeight = fChildHeight; - } - } - return XFA_ItemLayoutProcessorResult_PageFullBreak; - } - CXFA_Node* pTempLeaderNode = nullptr; - CXFA_Node* pTempTrailerNode = nullptr; - if (pThis->m_pPageMgr && !pProcessor->m_bUseInheriated && - eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) { - pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, - pTempTrailerNode, false, true); - } - if (pTrailerLayoutItem && bIsAddTrailerHeight) { - XFA_ItemLayoutProcessor_AddTrailerBeforeSplit( - pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited); - } else { - pProcessor->SplitLayoutItem(fSplitPos); - } - if (bUseInherited) { - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - pThis->m_bUseInheriated = true; - } else { - CXFA_LayoutItem* firstChild = - pProcessor->m_pLayoutItem->m_pFirstChild; - if (firstChild && !firstChild->m_pNextSibling && - firstChild->m_pFormNode->IsLayoutGeneratedNode()) { - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - } else { - if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { - XFA_ItemLayoutProcessor_AddPendingNode( - pProcessor, pOverflowLeaderNode, false); - } - } - } - if (pProcessor->m_pLayoutItem->m_pNextSibling) { - pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); - rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); - bAddedItemInRow = true; - if (bTakeSpace) { - fContentCurRowAvailWidth -= fChildWidth; - if (fContentCurRowHeight < fChildHeight) { - fContentCurRowHeight = fChildHeight; - } - } - } - return XFA_ItemLayoutProcessorResult_PageFullBreak; - } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) { - pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight); - if (pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) { - CXFA_Node* pTempLeaderNode = nullptr; - CXFA_Node* pTempTrailerNode = nullptr; - if (pThis->m_pPageMgr) { - if (!pFormNode && pLayoutContext) { - pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode; - } - pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, - pTempTrailerNode, false, true); - } - if (bUseInherited) { - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - pThis->m_bUseInheriated = true; - } - return XFA_ItemLayoutProcessorResult_PageFullBreak; - } - rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem()); - bAddedItemInRow = true; - if (bTakeSpace) { - fContentCurRowAvailWidth -= fChildWidth; - if (fContentCurRowHeight < fChildHeight) { - fContentCurRowHeight = fChildHeight; - } - } - if (eRetValue == XFA_ItemLayoutProcessorResult_Done) { - bForceEndPage = false; - } - return eRetValue; - } else { - XFA_ATTRIBUTEENUM eLayout = - pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout); - if (pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None && - eLayout == XFA_ATTRIBUTEENUM_Tb) { - if (pThis->m_pPageMgr) { - pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, - pOverflowTrailerNode, false, - true); - } - if (pTrailerLayoutItem) { - XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, - pTrailerLayoutItem); - } - if (pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) { - XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, - pOverflowLeaderNode, false); - } - } else { - if (eRetValue == XFA_ItemLayoutProcessorResult_Done) { - if (!pFormNode && pLayoutContext) { - pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode; - } - if (pThis->m_pPageMgr) { - pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, - pOverflowTrailerNode, false, - true); - } - if (bUseInherited) { - pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, - pOverflowTrailerNode, - pTrailerLayoutItem, pFormNode); - pThis->m_bUseInheriated = true; - } - } - } - return XFA_ItemLayoutProcessorResult_PageFullBreak; - } - } - } else { - return XFA_ItemLayoutProcessorResult_RowFullBreak; - } - return XFA_ItemLayoutProcessorResult_Done; } XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( @@ -2274,44 +2089,47 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( CXFA_LayoutContext* pContext, bool bRootForceTb) { m_bHasAvailHeight = true; - FX_FLOAT fContainerWidth = 0, fContainerHeight = 0; bool bBreakDone = false; - bool bContainerWidthAutoSize = true, bContainerHeightAutoSize = true; + bool bContainerWidthAutoSize = true; + bool bContainerHeightAutoSize = true; bool bForceEndPage = false; bool bIsManualBreak = false; if (m_pCurChildPreprocessor) { m_pCurChildPreprocessor->m_ePreProcessRs = - XFA_ItemLayoutProcessorResult_Done; + XFA_ItemLayoutProcessorResult::Done; } - XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize( - m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, - bContainerHeightAutoSize); + + CFX_SizeF containerSize = CalculateContainerSpecifiedSize( + m_pFormNode, &bContainerWidthAutoSize, &bContainerHeightAutoSize); if (pContext && pContext->m_bCurColumnWidthAvaiable) { bContainerWidthAutoSize = false; - fContainerWidth = pContext->m_fCurColumnWidth; - } - if (!bContainerHeightAutoSize) { - fContainerHeight -= m_fUsedSize; + containerSize.width = pContext->m_fCurColumnWidth; } + if (!bContainerHeightAutoSize) + containerSize.height -= m_fUsedSize; + if (!bContainerHeightAutoSize) { CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent); bool bFocrTb = false; if (pParentNode && - XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) == - XFA_ATTRIBUTEENUM_Row) { + GetLayout(pParentNode, &bFocrTb) == XFA_ATTRIBUTEENUM_Row) { CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem( XFA_NODEITEM_FirstChild, XFA_ObjectType::ContainerNode); if (pChildContainer && pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_ObjectType::ContainerNode)) { - fContainerHeight = 0; + containerSize.height = 0; bContainerHeightAutoSize = true; } } } + CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_Element::Margin); - FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0; + FX_FLOAT fLeftInset = 0; + FX_FLOAT fTopInset = 0; + FX_FLOAT fRightInset = 0; + FX_FLOAT fBottomInset = 0; if (pMarginNode) { fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt); @@ -2323,68 +2141,67 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt); } FX_FLOAT fContentWidthLimit = - bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX - : fContainerWidth - fLeftInset - fRightInset; - FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0; + bContainerWidthAutoSize ? FLT_MAX + : containerSize.width - fLeftInset - fRightInset; + FX_FLOAT fContentCalculatedWidth = 0; + FX_FLOAT fContentCalculatedHeight = 0; FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset; - if (fAvailHeight < 0) { + if (fAvailHeight < 0) m_bHasAvailHeight = false; - } + fRealHeight = fRealHeight - fTopInset - fBottomInset; FX_FLOAT fContentCurRowY = 0; CXFA_ContentLayoutItem* pLayoutChild = nullptr; if (m_pLayoutItem) { - if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done && + if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Done && eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) { pLayoutChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; for (CXFA_ContentLayoutItem* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItem*)pLayoutNext->m_pNextSibling) { - if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) { + if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) pLayoutChild = pLayoutNext; - } } } + for (CXFA_ContentLayoutItem* pLayoutTempChild = (CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild; pLayoutTempChild != pLayoutChild; pLayoutTempChild = (CXFA_ContentLayoutItem*)pLayoutTempChild->m_pNextSibling) { - if (XFA_ItemLayoutProcessor_IsTakingSpace( - pLayoutTempChild->m_pFormNode)) { - FX_FLOAT fChildContentWidth = - pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x; - FX_FLOAT fChildContentHeight = - pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y; - if (fContentCalculatedWidth < fChildContentWidth) { - fContentCalculatedWidth = fChildContentWidth; - } - if (fContentCalculatedHeight < fChildContentHeight) { - fContentCalculatedHeight = fChildContentHeight; - } - } + if (!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutTempChild->m_pFormNode)) + continue; + + fContentCalculatedWidth = std::max( + fContentCalculatedWidth, + pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.width); + fContentCalculatedHeight = std::max( + fContentCalculatedHeight, + pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.height); } - if (pLayoutChild) { + + if (pLayoutChild) fContentCurRowY = pLayoutChild->m_sPos.y; - } else { + else fContentCurRowY = fContentCalculatedHeight; - } } + fContentCurRowY += InsertKeepLayoutItems(); - if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) { - XFA_ItemLayoutProcessor_GotoNextContainerNode( - m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, true); + if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::None) { + GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, + true); } - fContentCurRowY += - XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode); + + fContentCurRowY += InsertPendingItems(this, m_pFormNode); if (m_pCurChildPreprocessor && - m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) { - if (XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), false)) { + m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::Container) { + if (ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), false)) { m_pKeepHeadNode = m_pCurChildNode; m_bIsProcessKeep = true; - m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep; + m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages::Keep; } } - while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) { + + while (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages::Done) { FX_FLOAT fContentCurRowHeight = 0; FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit; m_fWidthLimite = fContentCurRowAvailWidth; @@ -2400,23 +2217,22 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext; break; } - uint8_t uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt( + uint8_t uHAlign = HAlignEnumToInt( pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)); rgCurLineLayoutItems[uHAlign].Add(pLayoutNext); if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) { - if (uHAlign > uCurHAlignState) { + if (uHAlign > uCurHAlignState) uCurHAlignState = uHAlign; - } } else if (uHAlign < uCurHAlignState) { uCurHAlignState = uHAlign; } if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) { - if (pLayoutNext->m_sSize.y > fContentCurRowHeight) { - fContentCurRowHeight = pLayoutNext->m_sSize.y; - } - fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x; + if (pLayoutNext->m_sSize.height > fContentCurRowHeight) + fContentCurRowHeight = pLayoutNext->m_sSize.height; + fContentCurRowAvailWidth -= pLayoutNext->m_sSize.width; } } + if ((CXFA_ContentLayoutItem*)m_pLayoutItem->m_pFirstChild == pLayoutChild) { m_pLayoutItem->m_pFirstChild = nullptr; @@ -2433,6 +2249,7 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( } } } + CXFA_ContentLayoutItem* pLayoutNextTemp = (CXFA_ContentLayoutItem*)pLayoutChild; while (pLayoutNextTemp) { @@ -2444,272 +2261,273 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer( } pLayoutChild = nullptr; } + while (m_pCurChildNode) { - CXFA_ItemLayoutProcessor* pProcessor = nullptr; + std::unique_ptr<CXFA_ItemLayoutProcessor> pProcessor; bool bAddedItemInRow = false; - fContentCurRowY += - XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode); + fContentCurRowY += InsertPendingItems(this, m_pFormNode); switch (m_nCurChildNodeStage) { - case XFA_ItemLayoutProcessorStages_Keep: - case XFA_ItemLayoutProcessorStages_None: + case XFA_ItemLayoutProcessorStages::Keep: + case XFA_ItemLayoutProcessorStages::None: break; - case XFA_ItemLayoutProcessorStages_BreakBefore: { - for (int32_t iIndex = 0; iIndex < m_arrayKeepItems.GetSize(); - iIndex++) { - CXFA_ContentLayoutItem* pItem = m_arrayKeepItems.GetAt(iIndex); - m_pLayoutItem->RemoveChild(pItem); - fContentCalculatedHeight -= pItem->m_sSize.y; + case XFA_ItemLayoutProcessorStages::BreakBefore: { + for (auto item : m_arrayKeepItems) { + m_pLayoutItem->RemoveChild(item); + fContentCalculatedHeight -= item->m_sSize.height; } + CXFA_Node* pLeaderNode = nullptr; CXFA_Node* pTrailerNode = nullptr; bool bCreatePage = false; - if (bUseBreakControl && m_pPageMgr && - m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, true, - pLeaderNode, pTrailerNode, - bCreatePage) && - m_pFormNode->GetElementType() != XFA_Element::Form && - bCreatePage) { - if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { - XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, true); - } - if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) { - if (m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent) - ->GetElementType() == XFA_Element::Form && - !m_pLayoutItem) { - XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode, - true); - } else { - std::unique_ptr<CXFA_ItemLayoutProcessor> pTempProcessor( - new CXFA_ItemLayoutProcessor(pTrailerNode, nullptr)); - XFA_ItemLayoutProcessor_InsertFlowedItem( - this, pTempProcessor.get(), bContainerWidthAutoSize, - bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, - uCurHAlignState, rgCurLineLayoutItems, false, - XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, - fContentWidthLimit, fContentCurRowAvailWidth, - fContentCurRowHeight, bAddedItemInRow, bForceEndPage, - pContext); - } + if (!bUseBreakControl || !m_pPageMgr || + !m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, true, + pLeaderNode, pTrailerNode, + bCreatePage) || + m_pFormNode->GetElementType() == XFA_Element::Form || + !bCreatePage) { + break; + } + + if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) + AddPendingNode(this, pLeaderNode, true); + + if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) { + if (m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent) + ->GetElementType() == XFA_Element::Form && + !m_pLayoutItem) { + AddPendingNode(this, pTrailerNode, true); + } else { + auto pTempProcessor = + pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pTrailerNode, + nullptr); + InsertFlowedItem( + this, pTempProcessor.get(), bContainerWidthAutoSize, + bContainerHeightAutoSize, containerSize.height, eFlowStrategy, + &uCurHAlignState, rgCurLineLayoutItems, false, FLT_MAX, + FLT_MAX, fContentWidthLimit, &fContentCurRowY, + &fContentCurRowAvailWidth, &fContentCurRowHeight, + &bAddedItemInRow, &bForceEndPage, pContext, false); } - XFA_ItemLayoutProcessor_GotoNextContainerNode( - m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, true); - bForceEndPage = true; - bIsManualBreak = true; - goto SuspendAndCreateNewRow; } - } break; - case XFA_ItemLayoutProcessorStages_BreakAfter: { + GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, + m_pFormNode, true); + bForceEndPage = true; + bIsManualBreak = true; + goto SuspendAndCreateNewRow; + } + case XFA_ItemLayoutProcessorStages::BreakAfter: { CXFA_Node* pLeaderNode = nullptr; CXFA_Node* pTrailerNode = nullptr; bool bCreatePage = false; - if (bUseBreakControl && m_pPageMgr && - m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, false, - pLeaderNode, pTrailerNode, - bCreatePage) && - m_pFormNode->GetElementType() != XFA_Element::Form) { - if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) { - std::unique_ptr<CXFA_ItemLayoutProcessor> pTempProcessor( - new CXFA_ItemLayoutProcessor(pTrailerNode, nullptr)); - XFA_ItemLayoutProcessor_InsertFlowedItem( + if (!bUseBreakControl || !m_pPageMgr || + !m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, false, + pLeaderNode, pTrailerNode, + bCreatePage) || + m_pFormNode->GetElementType() == XFA_Element::Form) { + break; + } + + if (JudgeLeaderOrTrailerForOccur(pTrailerNode)) { + auto pTempProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + pTrailerNode, nullptr); + InsertFlowedItem( + this, pTempProcessor.get(), bContainerWidthAutoSize, + bContainerHeightAutoSize, containerSize.height, eFlowStrategy, + &uCurHAlignState, rgCurLineLayoutItems, false, FLT_MAX, FLT_MAX, + fContentWidthLimit, &fContentCurRowY, &fContentCurRowAvailWidth, + &fContentCurRowHeight, &bAddedItemInRow, &bForceEndPage, + pContext, false); + } + if (!bCreatePage) { + if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { + CalculateRowChildPosition( + rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, + bContainerWidthAutoSize, &fContentCalculatedWidth, + &fContentCalculatedHeight, &fContentCurRowY, + fContentCurRowHeight, fContentWidthLimit, false); + rgCurLineLayoutItems->RemoveAll(); + auto pTempProcessor = + pdfium::MakeUnique<CXFA_ItemLayoutProcessor>(pLeaderNode, + nullptr); + InsertFlowedItem( this, pTempProcessor.get(), bContainerWidthAutoSize, - bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, - uCurHAlignState, rgCurLineLayoutItems, false, - XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, - fContentWidthLimit, fContentCurRowAvailWidth, - fContentCurRowHeight, bAddedItemInRow, bForceEndPage, - pContext); + bContainerHeightAutoSize, containerSize.height, eFlowStrategy, + &uCurHAlignState, rgCurLineLayoutItems, false, FLT_MAX, + FLT_MAX, fContentWidthLimit, &fContentCurRowY, + &fContentCurRowAvailWidth, &fContentCurRowHeight, + &bAddedItemInRow, &bForceEndPage, pContext, false); } - if (!bCreatePage) { - if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { - CalculateRowChildPosition( - rgCurLineLayoutItems, eFlowStrategy, - bContainerHeightAutoSize, bContainerWidthAutoSize, - fContentCalculatedWidth, fContentCalculatedHeight, - fContentCurRowY, fContentCurRowHeight, fContentWidthLimit); - rgCurLineLayoutItems->RemoveAll(); - std::unique_ptr<CXFA_ItemLayoutProcessor> pTempProcessor( - new CXFA_ItemLayoutProcessor(pLeaderNode, nullptr)); - XFA_ItemLayoutProcessor_InsertFlowedItem( - this, pTempProcessor.get(), bContainerWidthAutoSize, - bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, - uCurHAlignState, rgCurLineLayoutItems, false, - XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, - fContentWidthLimit, fContentCurRowAvailWidth, - fContentCurRowHeight, bAddedItemInRow, bForceEndPage, - pContext); - } - } else { - if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) { - XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, true); - } - } - XFA_ItemLayoutProcessor_GotoNextContainerNode( - m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, true); - if (bCreatePage) { - bForceEndPage = true; - bIsManualBreak = true; - if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) { - bBreakDone = true; - } - } - goto SuspendAndCreateNewRow; + } else { + if (JudgeLeaderOrTrailerForOccur(pLeaderNode)) + AddPendingNode(this, pLeaderNode, true); + } + + GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, + m_pFormNode, true); + if (bCreatePage) { + bForceEndPage = true; + bIsManualBreak = true; + if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::Done) + bBreakDone = true; } - } break; - case XFA_ItemLayoutProcessorStages_BookendLeader: { + goto SuspendAndCreateNewRow; + } + case XFA_ItemLayoutProcessorStages::BookendLeader: { CXFA_Node* pLeaderNode = nullptr; if (m_pCurChildPreprocessor) { - pProcessor = m_pCurChildPreprocessor; + pProcessor.reset(m_pCurChildPreprocessor); m_pCurChildPreprocessor = nullptr; } else if (m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer( m_pCurChildNode, true, pLeaderNode)) { - pProcessor = new CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr); + pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + pLeaderNode, m_pPageMgr); } + if (pProcessor) { - if (XFA_ItemLayoutProcessor_InsertFlowedItem( - this, pProcessor, bContainerWidthAutoSize, - bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, - uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, - fAvailHeight, fRealHeight, fContentCurRowY, - fContentWidthLimit, fContentCurRowAvailWidth, - fContentCurRowHeight, bAddedItemInRow, bForceEndPage, - pContext) != XFA_ItemLayoutProcessorResult_Done) { + if (InsertFlowedItem( + this, pProcessor.get(), bContainerWidthAutoSize, + bContainerHeightAutoSize, containerSize.height, + eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, + bUseBreakControl, fAvailHeight, fRealHeight, + fContentWidthLimit, &fContentCurRowY, + &fContentCurRowAvailWidth, &fContentCurRowHeight, + &bAddedItemInRow, &bForceEndPage, pContext, + false) != XFA_ItemLayoutProcessorResult::Done) { goto SuspendAndCreateNewRow; } else { - delete pProcessor; - pProcessor = nullptr; + pProcessor.reset(); } } - } break; - case XFA_ItemLayoutProcessorStages_BookendTrailer: { + break; + } + case XFA_ItemLayoutProcessorStages::BookendTrailer: { CXFA_Node* pTrailerNode = nullptr; if (m_pCurChildPreprocessor) { - pProcessor = m_pCurChildPreprocessor; + pProcessor.reset(m_pCurChildPreprocessor); m_pCurChildPreprocessor = nullptr; } else if (m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer( m_pCurChildNode, false, pTrailerNode)) { - pProcessor = new CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr); + pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + pTrailerNode, m_pPageMgr); } if (pProcessor) { - if (XFA_ItemLayoutProcessor_InsertFlowedItem( - this, pProcessor, bContainerWidthAutoSize, - bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, - uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, - fAvailHeight, fRealHeight, fContentCurRowY, - fContentWidthLimit, fContentCurRowAvailWidth, - fContentCurRowHeight, bAddedItemInRow, bForceEndPage, - pContext) != XFA_ItemLayoutProcessorResult_Done) { + if (InsertFlowedItem( + this, pProcessor.get(), bContainerWidthAutoSize, + bContainerHeightAutoSize, containerSize.height, + eFlowStrategy, &uCurHAlignState, rgCurLineLayoutItems, + bUseBreakControl, fAvailHeight, fRealHeight, + fContentWidthLimit, &fContentCurRowY, + &fContentCurRowAvailWidth, &fContentCurRowHeight, + &bAddedItemInRow, &bForceEndPage, pContext, + false) != XFA_ItemLayoutProcessorResult::Done) { goto SuspendAndCreateNewRow; } else { - delete pProcessor; - pProcessor = nullptr; + pProcessor.reset(); } } - } break; - case XFA_ItemLayoutProcessorStages_Container: + break; + } + case XFA_ItemLayoutProcessorStages::Container: { ASSERT(m_pCurChildNode->IsContainerNode()); - if (m_pCurChildNode->GetElementType() == XFA_Element::Variables) { + if (m_pCurChildNode->GetElementType() == XFA_Element::Variables) break; - } if (fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION && XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) { bForceEndPage = true; goto SuspendAndCreateNewRow; } - if (m_pCurChildNode->IsContainerNode()) { - bool bNewRow = false; - if (m_pCurChildPreprocessor) { - pProcessor = m_pCurChildPreprocessor; - m_pCurChildPreprocessor = nullptr; - bNewRow = true; - } else { - pProcessor = - new CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr); - } - XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, - m_pCurChildNode); - XFA_ItemLayoutProcessorResult rs = - XFA_ItemLayoutProcessor_InsertFlowedItem( - this, pProcessor, bContainerWidthAutoSize, - bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, - uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, - fAvailHeight, fRealHeight, fContentCurRowY, - fContentWidthLimit, fContentCurRowAvailWidth, - fContentCurRowHeight, bAddedItemInRow, bForceEndPage, - pContext, bNewRow); - switch (rs) { - case XFA_ItemLayoutProcessorResult_ManualBreak: - bIsManualBreak = true; - case XFA_ItemLayoutProcessorResult_PageFullBreak: - bForceEndPage = true; - case XFA_ItemLayoutProcessorResult_RowFullBreak: - goto SuspendAndCreateNewRow; - case XFA_ItemLayoutProcessorResult_Done: - default: - fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems( - pProcessor, m_pCurChildNode); - delete pProcessor; - pProcessor = nullptr; - } + if (!m_pCurChildNode->IsContainerNode()) + break; + + bool bNewRow = false; + if (m_pCurChildPreprocessor) { + pProcessor.reset(m_pCurChildPreprocessor); + m_pCurChildPreprocessor = nullptr; + bNewRow = true; + } else { + pProcessor = pdfium::MakeUnique<CXFA_ItemLayoutProcessor>( + m_pCurChildNode, m_pPageMgr); + } + + InsertPendingItems(pProcessor.get(), m_pCurChildNode); + XFA_ItemLayoutProcessorResult rs = InsertFlowedItem( + this, pProcessor.get(), bContainerWidthAutoSize, + bContainerHeightAutoSize, containerSize.height, eFlowStrategy, + &uCurHAlignState, rgCurLineLayoutItems, bUseBreakControl, + fAvailHeight, fRealHeight, fContentWidthLimit, &fContentCurRowY, + &fContentCurRowAvailWidth, &fContentCurRowHeight, + &bAddedItemInRow, &bForceEndPage, pContext, bNewRow); + switch (rs) { + case XFA_ItemLayoutProcessorResult::ManualBreak: + bIsManualBreak = true; + case XFA_ItemLayoutProcessorResult::PageFullBreak: + bForceEndPage = true; + case XFA_ItemLayoutProcessorResult::RowFullBreak: + goto SuspendAndCreateNewRow; + case XFA_ItemLayoutProcessorResult::Done: + default: + fContentCurRowY += + InsertPendingItems(pProcessor.get(), m_pCurChildNode); + pProcessor.reset(); } break; - case XFA_ItemLayoutProcessorStages_Done: + } + case XFA_ItemLayoutProcessorStages::Done: break; default: break; } - XFA_ItemLayoutProcessor_GotoNextContainerNode( - m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, true); - if (bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) { + GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, + true); + if (bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) break; - } else { + else continue; - } SuspendAndCreateNewRow: - if (pProcessor) { - m_pCurChildPreprocessor = pProcessor; - } + if (pProcessor) + m_pCurChildPreprocessor = pProcessor.release(); break; } - CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, - bContainerHeightAutoSize, bContainerWidthAutoSize, - fContentCalculatedWidth, fContentCalculatedHeight, - fContentCurRowY, fContentCurRowHeight, - fContentWidthLimit, bRootForceTb); + + CalculateRowChildPosition( + rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, + bContainerWidthAutoSize, &fContentCalculatedWidth, + &fContentCalculatedHeight, &fContentCurRowY, fContentCurRowHeight, + fContentWidthLimit, bRootForceTb); m_fWidthLimite = fContentCurRowAvailWidth; - if (bForceEndPage) { + if (bForceEndPage) break; - } } - bool bRetValue = m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && - m_PendingNodes.empty(); - if (bBreakDone) { + + bool bRetValue = + m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages::Done && + m_PendingNodes.empty(); + if (bBreakDone) bRetValue = false; - } - XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize( + + containerSize = CalculateContainerComponentSizeFromContentSize( m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, - fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, - fContainerHeight); - if (fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem || + bContainerHeightAutoSize, fContentCalculatedHeight, containerSize); + + if (containerSize.height >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem || bRetValue) { - if (!m_pLayoutItem) { + if (!m_pLayoutItem) m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); - } - if (fContainerHeight < 0) { - fContainerHeight = 0; - } - SetCurrentComponentSize(fContainerWidth, fContainerHeight); - if (bForceEndPage) { + containerSize.height = std::max(containerSize.height, 0.f); + + SetCurrentComponentSize(containerSize); + if (bForceEndPage) m_fUsedSize = 0; - } else { - m_fUsedSize += m_pLayoutItem->m_sSize.y; - } + else + m_fUsedSize += m_pLayoutItem->m_sSize.height; } + return bRetValue - ? XFA_ItemLayoutProcessorResult_Done - : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak - : XFA_ItemLayoutProcessorResult_PageFullBreak); + ? XFA_ItemLayoutProcessorResult::Done + : (bIsManualBreak ? XFA_ItemLayoutProcessorResult::ManualBreak + : XFA_ItemLayoutProcessorResult::PageFullBreak); } bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( @@ -2717,9 +2535,9 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( XFA_ATTRIBUTEENUM eFlowStrategy, bool bContainerHeightAutoSize, bool bContainerWidthAutoSize, - FX_FLOAT& fContentCalculatedWidth, - FX_FLOAT& fContentCalculatedHeight, - FX_FLOAT& fContentCurRowY, + FX_FLOAT* fContentCalculatedWidth, + FX_FLOAT* fContentCalculatedHeight, + FX_FLOAT* fContentCurRowY, FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit, bool bRootForceTb) { @@ -2732,39 +2550,36 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( nTotalLength++; if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[i][j]->m_pFormNode)) { - fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x; + fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.width; } } } + if (!nTotalLength) { if (bContainerHeightAutoSize) { - FX_FLOAT fNewHeight = fContentCurRowY; - if (fContentCalculatedHeight > fNewHeight) { - fContentCalculatedHeight = fNewHeight; - } + *fContentCalculatedHeight = + std::min(*fContentCalculatedHeight, *fContentCurRowY); } return false; } - if (!m_pLayoutItem) { + + if (!m_pLayoutItem) m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); - } + if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) { FX_FLOAT fCurPos; fCurPos = 0; for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) { if (bRootForceTb) { - FX_FLOAT fAbsoluteX, fAbsoluteY; - CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode, - rgCurLineLayoutItems[0][j]->m_sSize.x, - rgCurLineLayoutItems[0][j]->m_sSize.y, - fAbsoluteX, fAbsoluteY); - rgCurLineLayoutItems[0][j]->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY); + rgCurLineLayoutItems[0][j]->m_sPos = CalculatePositionedContainerPos( + rgCurLineLayoutItems[0][j]->m_pFormNode, + rgCurLineLayoutItems[0][j]->m_sSize); } else { rgCurLineLayoutItems[0][j]->m_sPos = - CFX_PointF(fCurPos, fContentCurRowY); + CFX_PointF(fCurPos, *fContentCurRowY); if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[0][j]->m_pFormNode)) { - fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x; + fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.width; } } m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]); @@ -2775,18 +2590,15 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( 2; for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) { if (bRootForceTb) { - FX_FLOAT fAbsoluteX, fAbsoluteY; - CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode, - rgCurLineLayoutItems[1][j]->m_sSize.x, - rgCurLineLayoutItems[1][j]->m_sSize.y, - fAbsoluteX, fAbsoluteY); - rgCurLineLayoutItems[1][j]->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY); + rgCurLineLayoutItems[1][j]->m_sPos = CalculatePositionedContainerPos( + rgCurLineLayoutItems[1][j]->m_pFormNode, + rgCurLineLayoutItems[1][j]->m_sSize); } else { rgCurLineLayoutItems[1][j]->m_sPos = - CFX_PointF(fCurPos, fContentCurRowY); + CFX_PointF(fCurPos, *fContentCurRowY); if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[1][j]->m_pFormNode)) { - fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x; + fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.width; } } m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]); @@ -2795,18 +2607,15 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( fCurPos = fContentWidthLimit - fGroupWidths[2]; for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) { if (bRootForceTb) { - FX_FLOAT fAbsoluteX, fAbsoluteY; - CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode, - rgCurLineLayoutItems[2][j]->m_sSize.x, - rgCurLineLayoutItems[2][j]->m_sSize.y, - fAbsoluteX, fAbsoluteY); - rgCurLineLayoutItems[2][j]->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY); + rgCurLineLayoutItems[2][j]->m_sPos = CalculatePositionedContainerPos( + rgCurLineLayoutItems[2][j]->m_pFormNode, + rgCurLineLayoutItems[2][j]->m_sSize); } else { rgCurLineLayoutItems[2][j]->m_sPos = - CFX_PointF(fCurPos, fContentCurRowY); + CFX_PointF(fCurPos, *fContentCurRowY); if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[2][j]->m_pFormNode)) { - fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x; + fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.width; } } m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]); @@ -2818,9 +2627,10 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( for (int32_t c = nGroupLengths[0], j = 0; j < c; j++) { if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[0][j]->m_pFormNode)) { - fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x; + fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.width; } - rgCurLineLayoutItems[0][j]->m_sPos = CFX_PointF(fCurPos, fContentCurRowY); + rgCurLineLayoutItems[0][j]->m_sPos = + CFX_PointF(fCurPos, *fContentCurRowY); m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]); m_fLastRowWidth = fCurPos; } @@ -2830,9 +2640,10 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( for (int32_t c = nGroupLengths[1], j = 0; j < c; j++) { if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[1][j]->m_pFormNode)) { - fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x; + fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.width; } - rgCurLineLayoutItems[1][j]->m_sPos = CFX_PointF(fCurPos, fContentCurRowY); + rgCurLineLayoutItems[1][j]->m_sPos = + CFX_PointF(fCurPos, *fContentCurRowY); m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]); m_fLastRowWidth = fCurPos; } @@ -2840,70 +2651,68 @@ bool CXFA_ItemLayoutProcessor::CalculateRowChildPosition( for (int32_t c = nGroupLengths[2], j = 0; j < c; j++) { if (XFA_ItemLayoutProcessor_IsTakingSpace( rgCurLineLayoutItems[2][j]->m_pFormNode)) { - fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x; + fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.width; } - rgCurLineLayoutItems[2][j]->m_sPos = CFX_PointF(fCurPos, fContentCurRowY); + rgCurLineLayoutItems[2][j]->m_sPos = + CFX_PointF(fCurPos, *fContentCurRowY); m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]); m_fLastRowWidth = fCurPos; } } - m_fLastRowY = fContentCurRowY; - fContentCurRowY += fContentCurRowHeight; + m_fLastRowY = *fContentCurRowY; + *fContentCurRowY += fContentCurRowHeight; if (bContainerWidthAutoSize) { FX_FLOAT fChildSuppliedWidth = fGroupWidths[0]; - if (fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && + if (fContentWidthLimit < FLT_MAX && fContentWidthLimit > fChildSuppliedWidth) { fChildSuppliedWidth = fContentWidthLimit; } - if (fContentCalculatedWidth < fChildSuppliedWidth) { - fContentCalculatedWidth = fChildSuppliedWidth; - } + *fContentCalculatedWidth = + std::max(*fContentCalculatedWidth, fChildSuppliedWidth); } if (bContainerHeightAutoSize) { - FX_FLOAT fChildSuppliedHeight = fContentCurRowY; - if (fContentCalculatedHeight < fChildSuppliedHeight) { - fContentCalculatedHeight = fChildSuppliedHeight; - } + *fContentCalculatedHeight = + std::max(*fContentCalculatedHeight, *fContentCurRowY); } return true; } + CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent( CXFA_Node* pSubformSet) { if (pSubformSet && pSubformSet->GetElementType() == XFA_Element::SubformSet) { CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent); while (pParent) { - if (pParent->GetElementType() != XFA_Element::SubformSet) { + if (pParent->GetElementType() != XFA_Element::SubformSet) return pParent; - } pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent); } } return pSubformSet; } + void CXFA_ItemLayoutProcessor::DoLayoutField() { if (m_pLayoutItem) return; ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE); m_pLayoutItem = CreateContentLayoutItem(m_pFormNode); - if (!m_pLayoutItem) { + if (!m_pLayoutItem) return; - } + CXFA_Document* pDocument = m_pFormNode->GetDocument(); CXFA_FFNotify* pNotify = pDocument->GetNotify(); - FX_FLOAT fHeight = -1; - FX_FLOAT fWidth = -1; - pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight); + CFX_SizeF size(-1, -1); + pNotify->StartFieldDrawLayout(m_pFormNode, size.width, size.height); + int32_t nRotate = FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue()); nRotate = XFA_MapRotation(nRotate); - if (nRotate == 90 || nRotate == 270) { - FX_FLOAT fTmp = fWidth; - fWidth = fHeight; - fHeight = fTmp; - } - SetCurrentComponentSize(fWidth, fHeight); + if (nRotate == 90 || nRotate == 270) + std::swap(size.width, size.height); + + SetCurrentComponentSize(size); } + XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout( bool bUseBreakControl, FX_FLOAT fHeightLimit, @@ -2916,8 +2725,7 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout( case XFA_Element::SubformSet: { bool bRootForceTb = false; CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode); - XFA_ATTRIBUTEENUM eLayoutStrategy = - XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb); + XFA_ATTRIBUTEENUM eLayoutStrategy = GetLayout(pLayoutNode, &bRootForceTb); switch (eLayoutStrategy) { case XFA_ATTRIBUTEENUM_Tb: case XFA_ATTRIBUTEENUM_Lr_tb: @@ -2930,44 +2738,36 @@ XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout( case XFA_ATTRIBUTEENUM_Rl_row: default: DoLayoutPositionedContainer(pContext); - m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done; - return XFA_ItemLayoutProcessorResult_Done; + m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages::Done; + return XFA_ItemLayoutProcessorResult::Done; case XFA_ATTRIBUTEENUM_Table: DoLayoutTableContainer(pLayoutNode); - m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done; - return XFA_ItemLayoutProcessorResult_Done; + m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages::Done; + return XFA_ItemLayoutProcessorResult::Done; } } case XFA_Element::Draw: case XFA_Element::Field: DoLayoutField(); - m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done; - return XFA_ItemLayoutProcessorResult_Done; + m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages::Done; + return XFA_ItemLayoutProcessorResult::Done; case XFA_Element::ContentArea: - return XFA_ItemLayoutProcessorResult_Done; + return XFA_ItemLayoutProcessorResult::Done; default: - return XFA_ItemLayoutProcessorResult_Done; + return XFA_ItemLayoutProcessorResult::Done; } } -void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, - FX_FLOAT& fAbsoluteY) { - ASSERT(m_pLayoutItem); - fAbsoluteX = m_pLayoutItem->m_sPos.x; - fAbsoluteY = m_pLayoutItem->m_sPos.y; -} -void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth, - FX_FLOAT& fHeight) { - ASSERT(m_pLayoutItem); - fWidth = m_pLayoutItem->m_sSize.x; - fHeight = m_pLayoutItem->m_sSize.y; + +CFX_SizeF CXFA_ItemLayoutProcessor::GetCurrentComponentSize() { + return CFX_SizeF(m_pLayoutItem->m_sSize.width, m_pLayoutItem->m_sSize.height); } -void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX, - FX_FLOAT fAbsoluteY) { - m_pLayoutItem->m_sPos = CFX_PointF(fAbsoluteX, fAbsoluteY); + +void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(const CFX_PointF& pos) { + m_pLayoutItem->m_sPos = pos; } -void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth, - FX_FLOAT fHeight) { - m_pLayoutItem->m_sSize = CFX_SizeF(fWidth, fHeight); + +void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(const CFX_SizeF& size) { + m_pLayoutItem->m_sSize = size; } bool CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur( diff --git a/xfa/fxfa/parser/xfa_layout_itemlayout.h b/xfa/fxfa/parser/xfa_layout_itemlayout.h index 0d114a4d5..d411bf0e9 100644 --- a/xfa/fxfa/parser/xfa_layout_itemlayout.h +++ b/xfa/fxfa/parser/xfa_layout_itemlayout.h @@ -11,13 +11,15 @@ #include <list> #include <map> +#include <tuple> +#include <vector> #include "core/fxcrt/fx_basic.h" +#include "core/fxcrt/fx_coordinates.h" #include "xfa/fxfa/fxfa_basic.h" #define XFA_LAYOUT_INVALIDNODE ((CXFA_Node*)(intptr_t)-1) #define XFA_LAYOUT_FLOAT_PERCISION (0.0005f) -#define XFA_LAYOUT_FLOAT_MAX FLT_MAX class CXFA_ContainerLayoutItem; class CXFA_ContentLayoutItem; @@ -26,22 +28,22 @@ class CXFA_LayoutPageMgr; class CXFA_LayoutProcessor; class CXFA_Node; -enum XFA_ItemLayoutProcessorResult { - XFA_ItemLayoutProcessorResult_Done, - XFA_ItemLayoutProcessorResult_PageFullBreak, - XFA_ItemLayoutProcessorResult_RowFullBreak, - XFA_ItemLayoutProcessorResult_ManualBreak, +enum class XFA_ItemLayoutProcessorResult { + Done, + PageFullBreak, + RowFullBreak, + ManualBreak, }; -enum XFA_ItemLayoutProcessorStages { - XFA_ItemLayoutProcessorStages_None, - XFA_ItemLayoutProcessorStages_BookendLeader, - XFA_ItemLayoutProcessorStages_BreakBefore, - XFA_ItemLayoutProcessorStages_Keep, - XFA_ItemLayoutProcessorStages_Container, - XFA_ItemLayoutProcessorStages_BreakAfter, - XFA_ItemLayoutProcessorStages_BookendTrailer, - XFA_ItemLayoutProcessorStages_Done, +enum class XFA_ItemLayoutProcessorStages { + None, + BookendLeader, + BreakBefore, + Keep, + Container, + BreakAfter, + BookendTrailer, + Done, }; class CXFA_LayoutContext { @@ -52,7 +54,8 @@ class CXFA_LayoutContext { m_bCurColumnWidthAvaiable(false), m_pOverflowProcessor(nullptr), m_pOverflowNode(nullptr) {} - ~CXFA_LayoutContext() { m_pOverflowProcessor = nullptr; } + ~CXFA_LayoutContext() {} + CFX_ArrayTemplate<FX_FLOAT>* m_prgSpecifiedColumnWidths; FX_FLOAT m_fCurColumnWidth; bool m_bCurColumnWidthAvaiable; @@ -60,99 +63,104 @@ class CXFA_LayoutContext { CXFA_Node* m_pOverflowNode; }; +bool XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode); + class CXFA_ItemLayoutProcessor { public: + static bool IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, + CXFA_Node* pNode, + CXFA_Node* pParentNode); + CXFA_ItemLayoutProcessor(CXFA_Node* pNode, CXFA_LayoutPageMgr* pPageMgr); ~CXFA_ItemLayoutProcessor(); - XFA_ItemLayoutProcessorResult DoLayout( - bool bUseBreakControl, - FX_FLOAT fHeightLimit, - FX_FLOAT fRealHeight = XFA_LAYOUT_FLOAT_MAX, - CXFA_LayoutContext* pContext = nullptr); - - void GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY); - - void GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight); - - void SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY); + XFA_ItemLayoutProcessorResult DoLayout(bool bUseBreakControl, + FX_FLOAT fHeightLimit, + FX_FLOAT fRealHeight, + CXFA_LayoutContext* pContext); + void DoLayoutPageArea(CXFA_ContainerLayoutItem* pPageAreaLayoutItem); - void SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight); + CFX_SizeF GetCurrentComponentSize(); CXFA_Node* GetFormNode() { return m_pFormNode; } - bool HasLayoutItem() { return !!m_pLayoutItem; } + bool HasLayoutItem() const { return !!m_pLayoutItem; } CXFA_ContentLayoutItem* ExtractLayoutItem(); + void SplitLayoutItem(FX_FLOAT fSplitPos); - static bool IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, - CXFA_Node* pNode, - CXFA_Node* pParentNode); - static void CalculatePositionedContainerPos(CXFA_Node* pNode, - FX_FLOAT fWidth, - FX_FLOAT fHeight, - FX_FLOAT& fAbsoluteX, - FX_FLOAT& fAbsoluteY); - static bool FindLayoutItemSplitPos(CXFA_ContentLayoutItem* pLayoutItem, - FX_FLOAT fCurVerticalOffset, - FX_FLOAT& fProposedSplitPos, - bool& bAppChange, - bool bCalculateMargin = true); FX_FLOAT FindSplitPos(FX_FLOAT fProposedSplitPos); - void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem, - CXFA_ContentLayoutItem* pSecondParent, - FX_FLOAT fSplitPos); - void SplitLayoutItem(FX_FLOAT fSplitPos); - bool JudgePutNextPage(CXFA_ContentLayoutItem* pParentLayoutItem, - FX_FLOAT fChildHeight, - CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& pKeepItems); - bool ProcessKeepForSplite( + + bool ProcessKeepForSplit( CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue, - CFX_ArrayTemplate<CXFA_ContentLayoutItem*>& rgCurLineLayoutItem, - FX_FLOAT& fContentCurRowAvailWidth, - FX_FLOAT& fContentCurRowHeight, - FX_FLOAT& fContentCurRowY, - bool& bAddedItemInRow, - bool& bForceEndPage, - XFA_ItemLayoutProcessorResult& result); + CFX_ArrayTemplate<CXFA_ContentLayoutItem*>* rgCurLineLayoutItem, + FX_FLOAT* fContentCurRowAvailWidth, + FX_FLOAT* fContentCurRowHeight, + FX_FLOAT* fContentCurRowY, + bool* bAddedItemInRow, + bool* bForceEndPage, + XFA_ItemLayoutProcessorResult* result); + void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, + CXFA_Node* pTrailerNode, + CXFA_ContentLayoutItem* pTrailerItem, + CXFA_Node* pFormNode); + bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem); + bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode); + + CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode); + + CXFA_Node* m_pFormNode; + CXFA_ContentLayoutItem* m_pLayoutItem; + CXFA_Node* m_pCurChildNode; + FX_FLOAT m_fUsedSize; + CXFA_LayoutPageMgr* m_pPageMgr; + std::list<CXFA_Node*> m_PendingNodes; + bool m_bBreakPending; + CFX_ArrayTemplate<FX_FLOAT> m_rgSpecifiedColumnWidths; + std::vector<CXFA_ContentLayoutItem*> m_arrayKeepItems; + FX_FLOAT m_fLastRowWidth; + FX_FLOAT m_fLastRowY; + bool m_bUseInheriated; + XFA_ItemLayoutProcessorResult m_ePreProcessRs; + + private: + void SetCurrentComponentPos(const CFX_PointF& pos); + void SetCurrentComponentSize(const CFX_SizeF& size); + + void SplitLayoutItem(CXFA_ContentLayoutItem* pLayoutItem, + CXFA_ContentLayoutItem* pSecondParent, + FX_FLOAT fSplitPos); FX_FLOAT InsertKeepLayoutItems(); - void DoLayoutPageArea(CXFA_ContainerLayoutItem* pPageAreaLayoutItem); bool CalculateRowChildPosition( CFX_ArrayTemplate<CXFA_ContentLayoutItem*> (&rgCurLineLayoutItems)[3], XFA_ATTRIBUTEENUM eFlowStrategy, bool bContainerHeightAutoSize, bool bContainerWidthAutoSize, - FX_FLOAT& fContentCalculatedWidth, - FX_FLOAT& fContentCalculatedHeight, - FX_FLOAT& fContentCurRowY, + FX_FLOAT* fContentCalculatedWidth, + FX_FLOAT* fContentCalculatedHeight, + FX_FLOAT* fContentCurRowY, FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit, - bool bRootForceTb = false); - - void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, - CXFA_Node* pTrailerNode, - CXFA_ContentLayoutItem* pTrailerItem, - CXFA_Node* pFormNode); + bool bRootForceTb); void ProcessUnUseBinds(CXFA_Node* pFormNode); - bool IsAddNewRowForTrailer(CXFA_ContentLayoutItem* pTrailerItem); - bool JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode); - CXFA_ContentLayoutItem* CreateContentLayoutItem(CXFA_Node* pFormNode); + bool JudgePutNextPage(CXFA_ContentLayoutItem* pParentLayoutItem, + FX_FLOAT fChildHeight, + std::vector<CXFA_ContentLayoutItem*>* pKeepItems); - protected: - void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext = nullptr); + void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext); void DoLayoutTableContainer(CXFA_Node* pLayoutNode); XFA_ItemLayoutProcessorResult DoLayoutFlowedContainer( bool bUseBreakControl, XFA_ATTRIBUTEENUM eFlowStrategy, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, - CXFA_LayoutContext* pContext = nullptr, - bool bRootForceTb = false); + CXFA_LayoutContext* pContext, + bool bRootForceTb); void DoLayoutField(); - void XFA_ItemLayoutProcessor_GotoNextContainerNode( - CXFA_Node*& pCurActionNode, - XFA_ItemLayoutProcessorStages& nCurStage, - CXFA_Node* pParentContainer, - bool bUsePageBreak); + + void GotoNextContainerNode(CXFA_Node*& pCurActionNode, + XFA_ItemLayoutProcessorStages& nCurStage, + CXFA_Node* pParentContainer, + bool bUsePageBreak); bool ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, @@ -165,31 +173,16 @@ class CXFA_ItemLayoutProcessor { CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet); - public: bool m_bKeepBreakFinish; bool m_bIsProcessKeep; CXFA_Node* m_pKeepHeadNode; CXFA_Node* m_pKeepTailNode; - CXFA_Node* m_pFormNode; - CXFA_ContentLayoutItem* m_pLayoutItem; CXFA_ContentLayoutItem* m_pOldLayoutItem; - CXFA_Node* m_pCurChildNode; CXFA_ItemLayoutProcessor* m_pCurChildPreprocessor; XFA_ItemLayoutProcessorStages m_nCurChildNodeStage; - FX_FLOAT m_fUsedSize; - CXFA_LayoutPageMgr* m_pPageMgr; - std::list<CXFA_Node*> m_PendingNodes; - bool m_bBreakPending; - CFX_ArrayTemplate<FX_FLOAT> m_rgSpecifiedColumnWidths; - CFX_ArrayTemplate<CXFA_ContentLayoutItem*> m_arrayKeepItems; std::map<CXFA_Node*, int32_t> m_PendingNodesCount; - FX_FLOAT m_fLastRowWidth; - FX_FLOAT m_fLastRowY; FX_FLOAT m_fWidthLimite; - bool m_bUseInheriated; - XFA_ItemLayoutProcessorResult m_ePreProcessRs; bool m_bHasAvailHeight; }; -bool XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode); #endif // XFA_FXFA_PARSER_XFA_LAYOUT_ITEMLAYOUT_H_ diff --git a/xfa/fxfa/parser/xfa_locale.cpp b/xfa/fxfa/parser/xfa_locale.cpp index 5b18bcf64..d835eb2bc 100644 --- a/xfa/fxfa/parser/xfa_locale.cpp +++ b/xfa/fxfa/parser/xfa_locale.cpp @@ -35,31 +35,31 @@ void CXFA_XMLLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, switch (eType) { case FX_LOCALENUMSYMBOL_Decimal: bsSymbols = "numberSymbols"; - wsName = FX_WSTRC(L"decimal"); + wsName = L"decimal"; break; case FX_LOCALENUMSYMBOL_Grouping: bsSymbols = "numberSymbols"; - wsName = FX_WSTRC(L"grouping"); + wsName = L"grouping"; break; case FX_LOCALENUMSYMBOL_Percent: bsSymbols = "numberSymbols"; - wsName = FX_WSTRC(L"percent"); + wsName = L"percent"; break; case FX_LOCALENUMSYMBOL_Minus: bsSymbols = "numberSymbols"; - wsName = FX_WSTRC(L"minus"); + wsName = L"minus"; break; case FX_LOCALENUMSYMBOL_Zero: bsSymbols = "numberSymbols"; - wsName = FX_WSTRC(L"zero"); + wsName = L"zero"; break; case FX_LOCALENUMSYMBOL_CurrencySymbol: bsSymbols = "currencySymbols"; - wsName = FX_WSTRC(L"symbol"); + wsName = L"symbol"; break; case FX_LOCALENUMSYMBOL_CurrencyName: bsSymbols = "currencySymbols"; - wsName = FX_WSTRC(L"isoname"); + wsName = L"isoname"; break; default: return; @@ -238,28 +238,25 @@ void CXFA_NodeLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const { switch (eType) { case FX_LOCALENUMSYMBOL_Decimal: - wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, FX_WSTRC(L"decimal")); + wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, L"decimal"); break; case FX_LOCALENUMSYMBOL_Grouping: - wsNumSymbol = - GetSymbol(XFA_Element::NumberSymbols, FX_WSTRC(L"grouping")); + wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, L"grouping"); break; case FX_LOCALENUMSYMBOL_Percent: - wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, FX_WSTRC(L"percent")); + wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, L"percent"); break; case FX_LOCALENUMSYMBOL_Minus: - wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, FX_WSTRC(L"minus")); + wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, L"minus"); break; case FX_LOCALENUMSYMBOL_Zero: - wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, FX_WSTRC(L"zero")); + wsNumSymbol = GetSymbol(XFA_Element::NumberSymbols, L"zero"); break; case FX_LOCALENUMSYMBOL_CurrencySymbol: - wsNumSymbol = - GetSymbol(XFA_Element::CurrencySymbols, FX_WSTRC(L"symbol")); + wsNumSymbol = GetSymbol(XFA_Element::CurrencySymbols, L"symbol"); break; case FX_LOCALENUMSYMBOL_CurrencyName: - wsNumSymbol = - GetSymbol(XFA_Element::CurrencySymbols, FX_WSTRC(L"isoname")); + wsNumSymbol = GetSymbol(XFA_Element::CurrencySymbols, L"isoname"); break; } } @@ -302,17 +299,17 @@ void CXFA_NodeLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const { switch (eType) { case FX_LOCALEDATETIMESUBCATEGORY_Short: - wsPattern = GetSymbol(XFA_Element::DatePatterns, FX_WSTRC(L"short")); + wsPattern = GetSymbol(XFA_Element::DatePatterns, L"short"); break; case FX_LOCALEDATETIMESUBCATEGORY_Medium: case FX_LOCALEDATETIMESUBCATEGORY_Default: - wsPattern = GetSymbol(XFA_Element::DatePatterns, FX_WSTRC(L"med")); + wsPattern = GetSymbol(XFA_Element::DatePatterns, L"med"); break; case FX_LOCALEDATETIMESUBCATEGORY_Full: - wsPattern = GetSymbol(XFA_Element::DatePatterns, FX_WSTRC(L"full")); + wsPattern = GetSymbol(XFA_Element::DatePatterns, L"full"); break; case FX_LOCALEDATETIMESUBCATEGORY_Long: - wsPattern = GetSymbol(XFA_Element::DatePatterns, FX_WSTRC(L"long")); + wsPattern = GetSymbol(XFA_Element::DatePatterns, L"long"); break; } } @@ -321,17 +318,17 @@ void CXFA_NodeLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const { switch (eType) { case FX_LOCALEDATETIMESUBCATEGORY_Short: - wsPattern = GetSymbol(XFA_Element::TimePatterns, FX_WSTRC(L"short")); + wsPattern = GetSymbol(XFA_Element::TimePatterns, L"short"); break; case FX_LOCALEDATETIMESUBCATEGORY_Medium: case FX_LOCALEDATETIMESUBCATEGORY_Default: - wsPattern = GetSymbol(XFA_Element::TimePatterns, FX_WSTRC(L"med")); + wsPattern = GetSymbol(XFA_Element::TimePatterns, L"med"); break; case FX_LOCALEDATETIMESUBCATEGORY_Full: - wsPattern = GetSymbol(XFA_Element::TimePatterns, FX_WSTRC(L"full")); + wsPattern = GetSymbol(XFA_Element::TimePatterns, L"full"); break; case FX_LOCALEDATETIMESUBCATEGORY_Long: - wsPattern = GetSymbol(XFA_Element::TimePatterns, FX_WSTRC(L"long")); + wsPattern = GetSymbol(XFA_Element::TimePatterns, L"long"); break; } } diff --git a/xfa/fxfa/parser/xfa_localemgr.cpp b/xfa/fxfa/parser/xfa_localemgr.cpp index cfa5801e3..0cd64ea6d 100644 --- a/xfa/fxfa/parser/xfa_localemgr.cpp +++ b/xfa/fxfa/parser/xfa_localemgr.cpp @@ -1053,7 +1053,7 @@ static std::unique_ptr<IFX_Locale> XFA_GetLocaleFromBuffer(const uint8_t* pBuf, pCodecMgr->GetFlateModule()->FlateOrLZWDecode(false, pBuf, nBufLen, true, 0, 0, 0, 0, 0, pOut, dwSize); if (pOut) { - pLocale.reset(CXML_Element::Parse(pOut, dwSize)); + pLocale = CXML_Element::Parse(pOut, dwSize); FX_Free(pOut); } return pLocale ? std::unique_ptr<IFX_Locale>( diff --git a/xfa/fxfa/parser/xfa_localevalue.cpp b/xfa/fxfa/parser/xfa_localevalue.cpp index 87961358e..7e92535c3 100644 --- a/xfa/fxfa/parser/xfa_localevalue.cpp +++ b/xfa/fxfa/parser/xfa_localevalue.cpp @@ -128,7 +128,7 @@ bool CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, case FX_LOCALECATEGORY_Zero: bRet = pFormat->ParseZero(wsValue, wsFormat); if (!bRet) { - bRet = wsValue == FX_WSTRC(L"0"); + bRet = wsValue == L"0"; } break; case FX_LOCALECATEGORY_Num: { @@ -498,7 +498,7 @@ bool CXFA_LocaleValue::FormatSinglePattern(CFX_WideString& wsResult, } break; case FX_LOCALECATEGORY_Zero: - if (m_wsValue == FX_WSTRC(L"0")) { + if (m_wsValue == L"0") { bRet = pFormat->FormatZero(wsFormat, wsResult); } break; @@ -813,9 +813,8 @@ bool CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, break; case FX_LOCALECATEGORY_Zero: bRet = pFormat->ParseZero(wsValue, wsFormat); - if (bRet) { - m_wsValue = FX_WSTRC(L"0"); - } + if (bRet) + m_wsValue = L"0"; break; case FX_LOCALECATEGORY_Num: { CFX_WideString fNum; diff --git a/xfa/fxfa/xfa_ffpageview.h b/xfa/fxfa/xfa_ffpageview.h index c6bbe7dbe..4b50a2365 100644 --- a/xfa/fxfa/xfa_ffpageview.h +++ b/xfa/fxfa/xfa_ffpageview.h @@ -1,4 +1,4 @@ -// Copyright 2014 PDFium Authors. All rights reserved. +// Copyrig 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. @@ -7,6 +7,8 @@ #ifndef XFA_FXFA_XFA_FFPAGEVIEW_H_ #define XFA_FXFA_XFA_FFPAGEVIEW_H_ +#include <vector> + #include "xfa/fxfa/parser/cxfa_containerlayoutitem.h" #include "xfa/fxfa/parser/cxfa_contentlayoutitem.h" #include "xfa/fxfa/parser/cxfa_traversestrategy_layoutitem.h" @@ -20,10 +22,8 @@ class CXFA_FFPageView : public CXFA_ContainerLayoutItem { ~CXFA_FFPageView() override; CXFA_FFDocView* GetDocView() const; - void GetPageViewRect(CFX_RectF& rtPage) const; - void GetDisplayMatrix(CFX_Matrix& mt, - const CFX_Rect& rtDisp, - int32_t iRotate) const; + CFX_RectF GetPageViewRect() const; + CFX_Matrix GetDisplayMatrix(const CFX_Rect& rtDisp, int32_t iRotate) const; IXFA_WidgetIterator* CreateWidgetIterator( uint32_t dwTraverseWay = XFA_TRAVERSEWAY_Form, uint32_t dwWidgetFilter = XFA_WidgetStatus_Visible | @@ -59,7 +59,6 @@ class CXFA_FFPageWidgetIterator : public IXFA_WidgetIterator { bool m_bIgnorerelevant; CXFA_LayoutItemIterator m_sIterator; }; -typedef CFX_ArrayTemplate<CXFA_FFWidget*> CXFA_WidgetArray; class CXFA_TabParam { public: @@ -67,7 +66,7 @@ class CXFA_TabParam { ~CXFA_TabParam(); CXFA_FFWidget* m_pWidget; - CXFA_WidgetArray m_Children; + std::vector<CXFA_FFWidget*> m_Children; }; class CXFA_FFTabOrderPageWidgetIterator : public IXFA_WidgetIterator { @@ -89,7 +88,7 @@ class CXFA_FFTabOrderPageWidgetIterator : public IXFA_WidgetIterator { CXFA_FFWidget* FindWidgetByName(const CFX_WideString& wsWidgetName, CXFA_FFWidget* pRefWidget); void CreateTabOrderWidgetArray(); - void CreateSpaceOrderWidgetArray(CXFA_WidgetArray& WidgetArray); + void CreateSpaceOrderWidgetArray(std::vector<CXFA_FFWidget*>* WidgetArray); CXFA_FFWidget* GetWidget(CXFA_LayoutItem* pLayoutItem); void OrderContainer(CXFA_LayoutItemIterator* sIterator, CXFA_LayoutItem* pContainerItem, @@ -98,7 +97,7 @@ class CXFA_FFTabOrderPageWidgetIterator : public IXFA_WidgetIterator { bool& bContentArea, bool bMarsterPage = false); - CXFA_WidgetArray m_TabOrderWidgetArray; + std::vector<CXFA_FFWidget*> m_TabOrderWidgetArray; CXFA_FFPageView* m_pPageView; uint32_t m_dwFilter; int32_t m_iCurWidget; diff --git a/xfa/fxfa/xfa_ffwidget.h b/xfa/fxfa/xfa_ffwidget.h index f4ef8ce97..5972b8ad7 100644 --- a/xfa/fxfa/xfa_ffwidget.h +++ b/xfa/fxfa/xfa_ffwidget.h @@ -24,7 +24,9 @@ enum class FWL_WidgetHit; inline FX_FLOAT XFA_UnitPx2Pt(FX_FLOAT fPx, FX_FLOAT fDpi) { return fPx * 72.0f / fDpi; } + #define XFA_FLOAT_PERCISION 0.001f + enum XFA_WIDGETITEM { XFA_WIDGETITEM_Parent, XFA_WIDGETITEM_FirstChild, @@ -37,18 +39,16 @@ class CXFA_CalcData { CXFA_CalcData(); ~CXFA_CalcData(); - CFX_ArrayTemplate<CXFA_WidgetAcc*> m_Globals; + std::vector<CXFA_WidgetAcc*> m_Globals; int32_t m_iRefCount; }; class CXFA_FFWidget : public CXFA_ContentLayoutItem { public: - CXFA_FFWidget(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc); + explicit CXFA_FFWidget(CXFA_WidgetAcc* pDataAcc); ~CXFA_FFWidget() override; - virtual bool GetBBox(CFX_RectF& rtBox, - uint32_t dwStatus, - bool bDrawFocus = false); + virtual CFX_RectF GetBBox(uint32_t dwStatus, bool bDrawFocus = false); virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix, uint32_t dwStatus); @@ -60,25 +60,24 @@ class CXFA_FFWidget : public CXFA_ContentLayoutItem { virtual void UpdateWidgetProperty(); virtual bool OnMouseEnter(); virtual bool OnMouseExit(); - virtual bool OnLButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - virtual bool OnLButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - virtual bool OnLButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - virtual bool OnMouseMove(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); + virtual bool OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point); + virtual bool OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point); + virtual bool OnLButtonDblClk(uint32_t dwFlags, const CFX_PointF& point); + virtual bool OnMouseMove(uint32_t dwFlags, const CFX_PointF& point); virtual bool OnMouseWheel(uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy); - virtual bool OnRButtonDown(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - virtual bool OnRButtonUp(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); - virtual bool OnRButtonDblClk(uint32_t dwFlags, FX_FLOAT fx, FX_FLOAT fy); + const CFX_PointF& point); + virtual bool OnRButtonDown(uint32_t dwFlags, const CFX_PointF& point); + virtual bool OnRButtonUp(uint32_t dwFlags, const CFX_PointF& point); + virtual bool OnRButtonDblClk(uint32_t dwFlags, const CFX_PointF& point); virtual bool OnSetFocus(CXFA_FFWidget* pOldWidget); virtual bool OnKillFocus(CXFA_FFWidget* pNewWidget); virtual bool OnKeyDown(uint32_t dwKeyCode, uint32_t dwFlags); virtual bool OnKeyUp(uint32_t dwKeyCode, uint32_t dwFlags); virtual bool OnChar(uint32_t dwChar, uint32_t dwFlags); - virtual FWL_WidgetHit OnHitTest(FX_FLOAT fx, FX_FLOAT fy); - virtual bool OnSetCursor(FX_FLOAT fx, FX_FLOAT fy); + virtual FWL_WidgetHit OnHitTest(const CFX_PointF& point); + virtual bool OnSetCursor(const CFX_PointF& point); virtual bool CanUndo(); virtual bool CanRedo(); virtual bool Undo(); @@ -100,10 +99,10 @@ class CXFA_FFWidget : public CXFA_ContentLayoutItem { virtual bool ReplaceSpellCheckWord(CFX_PointF pointf, const CFX_ByteStringC& bsReplace); - CXFA_FFPageView* GetPageView(); - void SetPageView(CXFA_FFPageView* pPageView); - void GetWidgetRect(CFX_RectF& rtWidget); - CFX_RectF ReCacheWidgetRect(); + CXFA_FFPageView* GetPageView() const { return m_pPageView; } + void SetPageView(CXFA_FFPageView* pPageView) { m_pPageView = pPageView; } + CFX_RectF GetWidgetRect(); + CFX_RectF RecacheWidgetRect(); uint32_t GetStatus(); void ModifyStatus(uint32_t dwAdded, uint32_t dwRemoved); @@ -119,24 +118,23 @@ class CXFA_FFWidget : public CXFA_ContentLayoutItem { void AddInvalidateRect(const CFX_RectF* pRect = nullptr); bool GetCaptionText(CFX_WideString& wsCap); bool IsFocused(); - void Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy); - void GetRotateMatrix(CFX_Matrix& mt); + CFX_PointF Rotate2Normal(const CFX_PointF& point); + CFX_Matrix GetRotateMatrix(); bool IsLayoutRectEmpty(); CXFA_FFWidget* GetParent(); bool IsAncestorOf(CXFA_FFWidget* pWidget); const CFWL_App* GetFWLApp(); protected: - virtual bool PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy); + virtual bool PtInActiveRect(const CFX_PointF& point); void DrawBorder(CFX_Graphics* pGS, CXFA_Box box, const CFX_RectF& rtBorder, CFX_Matrix* pMatrix, uint32_t dwFlags = 0); - void GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth); - void GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight); - void GetRectWithoutRotate(CFX_RectF& rtWidget); + + CFX_RectF GetRectWithoutRotate(); bool IsMatchVisibleStatus(uint32_t dwStatus); void EventKillFocus(); bool IsButtonDown(); diff --git a/xfa/fxfa/xfa_ffwidgethandler.h b/xfa/fxfa/xfa_ffwidgethandler.h index 7335f9d1b..66bda3e02 100644 --- a/xfa/fxfa/xfa_ffwidgethandler.h +++ b/xfa/fxfa/xfa_ffwidgethandler.h @@ -29,43 +29,35 @@ class CXFA_FFWidgetHandler { bool OnMouseExit(CXFA_FFWidget* hWidget); bool OnLButtonDown(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnLButtonUp(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnLButtonDblClk(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnMouseMove(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnMouseWheel(CXFA_FFWidget* hWidget, uint32_t dwFlags, int16_t zDelta, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnRButtonDown(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnRButtonUp(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnRButtonDblClk(CXFA_FFWidget* hWidget, uint32_t dwFlags, - FX_FLOAT fx, - FX_FLOAT fy); + const CFX_PointF& point); bool OnKeyDown(CXFA_FFWidget* hWidget, uint32_t dwKeyCode, uint32_t dwFlags); bool OnKeyUp(CXFA_FFWidget* hWidget, uint32_t dwKeyCode, uint32_t dwFlags); bool OnChar(CXFA_FFWidget* hWidget, uint32_t dwChar, uint32_t dwFlags); - FWL_WidgetHit OnHitTest(CXFA_FFWidget* hWidget, FX_FLOAT fx, FX_FLOAT fy); - bool OnSetCursor(CXFA_FFWidget* hWidget, FX_FLOAT fx, FX_FLOAT fy); + FWL_WidgetHit OnHitTest(CXFA_FFWidget* hWidget, const CFX_PointF& point); + bool OnSetCursor(CXFA_FFWidget* hWidget, const CFX_PointF& point); void RenderWidget(CXFA_FFWidget* hWidget, CFX_Graphics* pGS, CFX_Matrix* pMatrix, diff --git a/xfa/fxgraphics/cagg_graphics.cpp b/xfa/fxgraphics/cagg_graphics.cpp deleted file mode 100644 index 5d1f56361..000000000 --- a/xfa/fxgraphics/cagg_graphics.cpp +++ /dev/null @@ -1,30 +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 "xfa/fxgraphics/cagg_graphics.h" - -CAGG_Graphics::CAGG_Graphics() : m_owner(nullptr) {} - -FWL_Error CAGG_Graphics::Create(CFX_Graphics* owner, - int32_t width, - int32_t height, - FXDIB_Format format) { - if (owner->m_renderDevice) - return FWL_Error::ParameterInvalid; - if (m_owner) - return FWL_Error::PropertyInvalid; - - CFX_FxgeDevice* device = new CFX_FxgeDevice; - device->Create(width, height, format, nullptr); - m_owner = owner; - m_owner->m_renderDevice = device; - m_owner->m_renderDevice->GetBitmap()->Clear(0xFFFFFFFF); - return FWL_Error::Succeeded; -} - -CAGG_Graphics::~CAGG_Graphics() { - delete m_owner->m_renderDevice; -} diff --git a/xfa/fxgraphics/cagg_graphics.h b/xfa/fxgraphics/cagg_graphics.h deleted file mode 100644 index 9f57a7234..000000000 --- a/xfa/fxgraphics/cagg_graphics.h +++ /dev/null @@ -1,29 +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 XFA_FXGRAPHICS_CAGG_GRAPHICS_H_ -#define XFA_FXGRAPHICS_CAGG_GRAPHICS_H_ - -#include "core/fxge/fx_dib.h" -#include "xfa/fxgraphics/cfx_graphics.h" - -class CFX_Graphics; - -class CAGG_Graphics { - public: - CAGG_Graphics(); - virtual ~CAGG_Graphics(); - - FWL_Error Create(CFX_Graphics* owner, - int32_t width, - int32_t height, - FXDIB_Format format); - - private: - CFX_Graphics* m_owner; -}; - -#endif // XFA_FXGRAPHICS_CAGG_GRAPHICS_H_ diff --git a/xfa/fxgraphics/cfx_color.cpp b/xfa/fxgraphics/cfx_color.cpp index 2044b7605..36025a82c 100644 --- a/xfa/fxgraphics/cfx_color.cpp +++ b/xfa/fxgraphics/cfx_color.cpp @@ -24,26 +24,23 @@ CFX_Color::~CFX_Color() { m_type = FX_COLOR_None; } -FWL_Error CFX_Color::Set(const FX_ARGB argb) { +void CFX_Color::Set(const FX_ARGB argb) { m_type = FX_COLOR_Solid; m_info.argb = argb; m_info.pattern = nullptr; - return FWL_Error::Succeeded; } -FWL_Error CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) { +void CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) { if (!pattern) - return FWL_Error::ParameterInvalid; + return; m_type = FX_COLOR_Pattern; m_info.argb = argb; m_info.pattern = pattern; - return FWL_Error::Succeeded; } -FWL_Error CFX_Color::Set(CFX_Shading* shading) { +void CFX_Color::Set(CFX_Shading* shading) { if (!shading) - return FWL_Error::ParameterInvalid; + return; m_type = FX_COLOR_Shading; m_shading = shading; - return FWL_Error::Succeeded; } diff --git a/xfa/fxgraphics/cfx_color.h b/xfa/fxgraphics/cfx_color.h index f47f8c472..75f7fe201 100644 --- a/xfa/fxgraphics/cfx_color.h +++ b/xfa/fxgraphics/cfx_color.h @@ -23,9 +23,9 @@ class CFX_Color { CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb); virtual ~CFX_Color(); - FWL_Error Set(const FX_ARGB argb); - FWL_Error Set(CFX_Pattern* pattern, const FX_ARGB argb); - FWL_Error Set(CFX_Shading* shading); + void Set(const FX_ARGB argb); + void Set(CFX_Pattern* pattern, const FX_ARGB argb); + void Set(CFX_Shading* shading); private: friend class CFX_Graphics; diff --git a/xfa/fxgraphics/cfx_graphics.cpp b/xfa/fxgraphics/cfx_graphics.cpp index 059872f81..d2f2151d9 100644 --- a/xfa/fxgraphics/cfx_graphics.cpp +++ b/xfa/fxgraphics/cfx_graphics.cpp @@ -13,10 +13,8 @@ #include "core/fxge/cfx_renderdevice.h" #include "core/fxge/cfx_unicodeencoding.h" #include "third_party/base/ptr_util.h" -#include "xfa/fxgraphics/cagg_graphics.h" #include "xfa/fxgraphics/cfx_color.h" #include "xfa/fxgraphics/cfx_path.h" -#include "xfa/fxgraphics/cfx_path_generator.h" #include "xfa/fxgraphics/cfx_pattern.h" #include "xfa/fxgraphics/cfx_shading.h" @@ -36,668 +34,111 @@ struct FX_HATCHDATA { }; const FX_HATCHDATA hatchBitmapData[FX_HATCHSTYLE_Total] = { - {16, + {16, // Horizontal 16, { - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }}, - {16, + {16, // Vertical 16, { - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, + 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, + 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, }}, - {16, + {16, // ForwardDiagonal 16, { - 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, - 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, + 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, + 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, + 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, }}, - {16, + {16, // BackwardDiagonal 16, { - 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, - 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, + 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, + 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, + 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, }}, - {16, + {16, // Cross 16, { - 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, + 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, + 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, }}, - {16, + {16, // DiagonalCross 16, { - 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, - 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, - 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, - 0x81, 0x81, 0x00, 0x00, - }}, - {16, - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, - }}, - {16, - 16, - { - 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, - 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, - }}, - {16, - 16, - { - 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, - 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x15, 0x15, 0x00, 0x00, - }}, - {16, - 16, - { - 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, - }}, - {16, - 16, - { - 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, - }}, - {16, - 16, - { - 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, - 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, - 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, - 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, - 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, - 0xdd, 0xdd, 0x00, 0x00, - }}, - {16, - 16, - { - 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, - }}, - {16, - 16, - { - 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x7f, 0x7f, 0x00, 0x00, - }}, - {16, - 16, - { - 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, - }}, - {16, - 16, - { - 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, - }}, - {16, - 16, - { - 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, - 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, - }}, - {16, - 16, - { - 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, - 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, - 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, - }}, - {16, - 16, - { - 0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, - 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, - 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, - 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, - 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, - 0x83, 0x83, 0x00, 0x00, - }}, - {16, - 16, - { - 0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, - 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, - 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, - 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, - 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, - 0xc1, 0xc1, 0x00, 0x00, - }}, - {16, - 16, - { - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, - 0xcc, 0xcc, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, - }}, - {16, - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, - 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, - 0x04, 0x04, 0x00, 0x00, - }}, - {16, - 16, - { - 0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, - 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00, 0xb1, 0xb1, 0x00, 0x00, - 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, - 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, - 0x8d, 0x8d, 0x00, 0x00, - }}, - {16, - 16, - { - 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, - 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, - 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, - }}, - {16, - 16, - { - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, - 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, - 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, - 0xc0, 0xc0, 0x00, 0x00, - }}, - {16, - 16, - { - 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, - 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, - 0x81, 0x81, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, - }}, - {16, - 16, - { - 0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x51, 0x51, 0x00, 0x00, - }}, - {16, - 16, - { - 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, - 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, - 0xf0, 0xf0, 0x00, 0x00, - }}, - {16, - 16, - { - 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, - }}, - {16, - 16, - { - 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }}, - {16, - 16, - { - 0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, - 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, - 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, - 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, - }}, - {16, - 16, - { - 0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, - 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, - 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, - 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, - 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, - 0xf8, 0xf8, 0x00, 0x00, - }}, - {16, - 16, - { - 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, - 0x88, 0x88, 0x00, 0x00, - }}, - {16, - 16, - { - 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, - 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, - 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, - 0x99, 0x99, 0x00, 0x00, - }}, - {16, - 16, - { - 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, - 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, - 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, - 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, - 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, - 0x0f, 0x0f, 0x00, 0x00, - }}, - {16, - 16, - { - 0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, - 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, - 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, - }}, - {16, - 16, - { - 0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, - 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, - 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, + 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, + 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, + 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, + 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, + 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, }}, }; } // namespace -CFX_Graphics::CFX_Graphics() - : m_type(FX_CONTEXT_None), m_renderDevice(nullptr) {} - -FWL_Error CFX_Graphics::Create(CFX_RenderDevice* renderDevice, - bool isAntialiasing) { +CFX_Graphics::CFX_Graphics(CFX_RenderDevice* renderDevice) + : m_type(FX_CONTEXT_None), m_renderDevice(renderDevice) { if (!renderDevice) - return FWL_Error::ParameterInvalid; - if (m_type != FX_CONTEXT_None) - return FWL_Error::PropertyInvalid; - - m_type = FX_CONTEXT_Device; - m_info.isAntialiasing = isAntialiasing; - m_renderDevice = renderDevice; - if (m_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) - return FWL_Error::Succeeded; - return FWL_Error::Indefinite; -} - -FWL_Error CFX_Graphics::Create(int32_t width, - int32_t height, - FXDIB_Format format, - bool isNative, - bool isAntialiasing) { - if (m_type != FX_CONTEXT_None) - return FWL_Error::PropertyInvalid; - + return; m_type = FX_CONTEXT_Device; - m_info.isAntialiasing = isAntialiasing; - m_aggGraphics = pdfium::MakeUnique<CAGG_Graphics>(); - return m_aggGraphics->Create(this, width, height, format); } CFX_Graphics::~CFX_Graphics() {} -FWL_Error CFX_Graphics::GetDeviceCap(const int32_t capID, - FX_DeviceCap& capVal) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - capVal = m_renderDevice->GetDeviceCaps(capID); - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::IsPrinterDevice(bool& isPrinter) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - isPrinter = m_renderDevice->GetDeviceClass() == FXDC_PRINTER; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} +void CFX_Graphics::SaveGraphState() { + if (m_type != FX_CONTEXT_Device || !m_renderDevice) + return; -FWL_Error CFX_Graphics::EnableAntialiasing(bool isAntialiasing) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.isAntialiasing = isAntialiasing; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; + m_renderDevice->SaveState(); + m_infoStack.push_back(pdfium::MakeUnique<TInfo>(m_info)); } -FWL_Error CFX_Graphics::SaveGraphState() { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_renderDevice->SaveState(); - m_infoStack.Add(new TInfo(m_info)); - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} +void CFX_Graphics::RestoreGraphState() { + if (m_type != FX_CONTEXT_Device || !m_renderDevice) + return; -FWL_Error CFX_Graphics::RestoreGraphState() { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_renderDevice->RestoreState(false); - int32_t size = m_infoStack.GetSize(); - if (size <= 0) { - return FWL_Error::IntermediateValueInvalid; - } - int32_t topIndex = size - 1; - std::unique_ptr<TInfo> info(m_infoStack.GetAt(topIndex)); - if (!info) - return FWL_Error::IntermediateValueInvalid; - m_info = *info; - m_infoStack.RemoveAt(topIndex); - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} + m_renderDevice->RestoreState(false); + if (m_infoStack.empty() || !m_infoStack.back()) + return; -FWL_Error CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - lineCap = m_info.graphState.m_LineCap; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; + m_info = *m_infoStack.back(); + m_infoStack.pop_back(); + return; } -FWL_Error CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) { +void CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) { if (m_type == FX_CONTEXT_Device && m_renderDevice) { m_info.graphState.m_LineCap = lineCap; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::GetDashCount(int32_t& dashCount) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - dashCount = m_info.graphState.m_DashCount; - return FWL_Error::Succeeded; } - return FWL_Error::PropertyInvalid; } -FWL_Error CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase, - FX_FLOAT* dashArray) const { - if (!dashArray) - return FWL_Error::ParameterInvalid; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - dashPhase = m_info.graphState.m_DashPhase; - FXSYS_memcpy(dashArray, m_info.graphState.m_DashArray, - m_info.graphState.m_DashCount * sizeof(FX_FLOAT)); - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetLineDash(FX_FLOAT dashPhase, - FX_FLOAT* dashArray, - int32_t dashCount) { +void CFX_Graphics::SetLineDash(FX_FLOAT dashPhase, + FX_FLOAT* dashArray, + int32_t dashCount) { if (dashCount > 0 && !dashArray) - return FWL_Error::ParameterInvalid; + return; dashCount = dashCount < 0 ? 0 : dashCount; if (m_type == FX_CONTEXT_Device && m_renderDevice) { @@ -710,165 +151,68 @@ FWL_Error CFX_Graphics::SetLineDash(FX_FLOAT dashPhase, for (int32_t i = 0; i < dashCount; i++) { m_info.graphState.m_DashArray[i] = dashArray[i] * scale; } - return FWL_Error::Succeeded; } - return FWL_Error::PropertyInvalid; } -FWL_Error CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) { +void CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) { if (m_type == FX_CONTEXT_Device && m_renderDevice) - return RenderDeviceSetLineDash(dashStyle); - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::GetLineJoin( - CFX_GraphStateData::LineJoin& lineJoin) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - lineJoin = m_info.graphState.m_LineJoin; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.graphState.m_LineJoin = lineJoin; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - miterLimit = m_info.graphState.m_MiterLimit; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.graphState.m_MiterLimit = miterLimit; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - lineWidth = m_info.graphState.m_LineWidth; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; + RenderDeviceSetLineDash(dashStyle); } -FWL_Error CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, bool isActOnDash) { +void CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, bool isActOnDash) { if (m_type == FX_CONTEXT_Device && m_renderDevice) { m_info.graphState.m_LineWidth = lineWidth; m_info.isActOnDash = isActOnDash; - return FWL_Error::Succeeded; } - return FWL_Error::PropertyInvalid; } -FWL_Error CFX_Graphics::GetStrokeAlignment( - FX_StrokeAlignment& strokeAlignment) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - strokeAlignment = m_info.strokeAlignment; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.strokeAlignment = strokeAlignment; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetStrokeColor(CFX_Color* color) { +void CFX_Graphics::SetStrokeColor(CFX_Color* color) { if (!color) - return FWL_Error::ParameterInvalid; + return; if (m_type == FX_CONTEXT_Device && m_renderDevice) { m_info.strokeColor = color; - return FWL_Error::Succeeded; } - return FWL_Error::PropertyInvalid; } -FWL_Error CFX_Graphics::SetFillColor(CFX_Color* color) { +void CFX_Graphics::SetFillColor(CFX_Color* color) { if (!color) - return FWL_Error::ParameterInvalid; + return; if (m_type == FX_CONTEXT_Device && m_renderDevice) { m_info.fillColor = color; - return FWL_Error::Succeeded; } - return FWL_Error::PropertyInvalid; } -FWL_Error CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) { +void CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) { if (!path) - return FWL_Error::ParameterInvalid; - if (m_type == FX_CONTEXT_Device && m_renderDevice) - return RenderDeviceStrokePath(path, matrix); - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::FillPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { - if (!path) - return FWL_Error::ParameterInvalid; + return; if (m_type == FX_CONTEXT_Device && m_renderDevice) - return RenderDeviceFillPath(path, fillMode, matrix); - return FWL_Error::PropertyInvalid; + RenderDeviceStrokePath(path, matrix); } -FWL_Error CFX_Graphics::ClipPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { +void CFX_Graphics::FillPath(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { if (!path) - return FWL_Error::ParameterInvalid; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - bool result = - m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); - if (!result) - return FWL_Error::Indefinite; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::DrawImage(CFX_DIBSource* source, - const CFX_PointF& point, - CFX_Matrix* matrix) { - if (!source) - return FWL_Error::ParameterInvalid; + return; if (m_type == FX_CONTEXT_Device && m_renderDevice) - return RenderDeviceDrawImage(source, point, matrix); - return FWL_Error::PropertyInvalid; + RenderDeviceFillPath(path, fillMode, matrix); } -FWL_Error CFX_Graphics::StretchImage(CFX_DIBSource* source, - const CFX_RectF& rect, - CFX_Matrix* matrix) { +void CFX_Graphics::StretchImage(CFX_DIBSource* source, + const CFX_RectF& rect, + CFX_Matrix* matrix) { if (!source) - return FWL_Error::ParameterInvalid; + return; if (m_type == FX_CONTEXT_Device && m_renderDevice) - return RenderDeviceStretchImage(source, rect, matrix); - return FWL_Error::PropertyInvalid; + RenderDeviceStretchImage(source, rect, matrix); } -FWL_Error CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) { +void CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) { if (!matrix) - return FWL_Error::ParameterInvalid; + return; if (m_type == FX_CONTEXT_Device && m_renderDevice) { m_info.CTM.Concat(*matrix); - return FWL_Error::Succeeded; } - return FWL_Error::PropertyInvalid; } CFX_Matrix* CFX_Graphics::GetMatrix() { @@ -877,445 +221,131 @@ CFX_Matrix* CFX_Graphics::GetMatrix() { return nullptr; } -FWL_Error CFX_Graphics::GetClipRect(CFX_RectF& rect) const { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - FX_RECT r = m_renderDevice->GetClipBox(); - rect.left = (FX_FLOAT)r.left; - rect.top = (FX_FLOAT)r.top; - rect.width = (FX_FLOAT)r.Width(); - rect.height = (FX_FLOAT)r.Height(); - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetClipRect(const CFX_RectF& rect) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - if (!m_renderDevice->SetClip_Rect( - FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top), - FXSYS_round(rect.right()), FXSYS_round(rect.bottom())))) { - return FWL_Error::MethodNotSupported; - } - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::ClearClip() { - if (m_type == FX_CONTEXT_Device && m_renderDevice) - return FWL_Error::Succeeded; - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetFont(CFX_Font* font) { - if (!font) - return FWL_Error::ParameterInvalid; - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.font = font; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetFontSize(const FX_FLOAT size) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.fontSize = size <= 0 ? 1.0f : size; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetFontHScale(const FX_FLOAT scale) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.fontHScale = scale <= 0 ? 1.0f : scale; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - m_info.fontSpacing = spacing < 0 ? 0 : spacing; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::SetTextDrawingMode(const int32_t mode) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) - return FWL_Error::Succeeded; - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::ShowText(const CFX_PointF& point, - const CFX_WideString& text, - CFX_Matrix* matrix) { - if (m_type == FX_CONTEXT_Device && m_renderDevice) - return RenderDeviceShowText(point, text, matrix); - return FWL_Error::PropertyInvalid; -} - -void CFX_Graphics::CalcTextRect(CFX_RectF& rect, - const CFX_WideString& text, - bool isMultiline, - CFX_Matrix* matrix) { +CFX_RectF CFX_Graphics::GetClipRect() const { if (m_type != FX_CONTEXT_Device || !m_renderDevice) - return; + return CFX_RectF(); - int32_t length = text.GetLength(); - uint32_t* charCodes = FX_Alloc(uint32_t, length); - FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length); - CalcTextInfo(text, charCodes, charPos, rect); - FX_Free(charPos); - FX_Free(charCodes); + FX_RECT r = m_renderDevice->GetClipBox(); + return CFX_Rect(r.left, r.top, r.Width(), r.Height()).As<FX_FLOAT>(); } -FWL_Error CFX_Graphics::Transfer(CFX_Graphics* graphics, - const CFX_Matrix* matrix) { - if (!graphics || !graphics->m_renderDevice) - return FWL_Error::ParameterInvalid; - CFX_Matrix m; - m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); - if (matrix) { - m.Concat(*matrix); - } - if (m_type == FX_CONTEXT_Device && m_renderDevice) { - CFX_DIBitmap* bitmap = graphics->m_renderDevice->GetBitmap(); - bool result = m_renderDevice->SetDIBits(bitmap, 0, 0); - if (!result) - return FWL_Error::MethodNotSupported; - return FWL_Error::Succeeded; - } - return FWL_Error::PropertyInvalid; -} - -FWL_Error CFX_Graphics::Transfer(CFX_Graphics* graphics, - FX_FLOAT srcLeft, - FX_FLOAT srcTop, - const CFX_RectF& dstRect, - const CFX_Matrix* matrix) { - if (!graphics || !graphics->m_renderDevice) - return FWL_Error::ParameterInvalid; - CFX_Matrix m; - m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); - if (matrix) { - m.Concat(*matrix); - } +void CFX_Graphics::SetClipRect(const CFX_RectF& rect) { if (m_type == FX_CONTEXT_Device && m_renderDevice) { - CFX_DIBitmap bmp; - bool result = - bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height, - graphics->m_renderDevice->GetBitmap()->GetFormat()); - if (!result) - return FWL_Error::IntermediateValueInvalid; - result = graphics->m_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft, - (int32_t)srcTop); - if (!result) - return FWL_Error::MethodNotSupported; - result = m_renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left, - (int32_t)dstRect.top); - if (!result) - return FWL_Error::MethodNotSupported; - return FWL_Error::Succeeded; + m_renderDevice->SetClip_Rect( + FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top), + FXSYS_round(rect.right()), FXSYS_round(rect.bottom()))); } - return FWL_Error::PropertyInvalid; } CFX_RenderDevice* CFX_Graphics::GetRenderDevice() { return m_renderDevice; } -FWL_Error CFX_Graphics::InverseRect(const CFX_RectF& rect) { - if (!m_renderDevice) - return FWL_Error::PropertyInvalid; - CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap(); - if (!bitmap) - return FWL_Error::PropertyInvalid; - CFX_RectF temp(rect); - m_info.CTM.TransformRect(temp); - CFX_RectF r; - r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth()); - r.Intersect(temp); - if (r.IsEmpty()) { - return FWL_Error::ParameterInvalid; - } - FX_ARGB* pBuf = - (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch()); - int32_t bottom = (int32_t)r.bottom(); - int32_t right = (int32_t)r.right(); - for (int32_t i = (int32_t)r.top; i < bottom; i++) { - FX_ARGB* pLine = pBuf + (int32_t)r.left; - for (int32_t j = (int32_t)r.left; j < right; j++) { - FX_ARGB c = *pLine; - *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF)); - } - pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch()); - } - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap, - const CFX_RectF& rect) { - if (!m_renderDevice) - return FWL_Error::PropertyInvalid; - CFX_DIBitmap* dst = m_renderDevice->GetBitmap(); - if (!dst) - return FWL_Error::PropertyInvalid; - CFX_RectF temp(rect); - m_info.CTM.TransformRect(temp); - CFX_RectF r; - r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth()); - r.Intersect(temp); - if (r.IsEmpty()) { - return FWL_Error::ParameterInvalid; - } - FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + - int32_t(r.top) * srcBitmap->GetPitch()); - FX_ARGB* pDstBuf = - (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch()); - int32_t bottom = (int32_t)r.bottom(); - int32_t right = (int32_t)r.right(); - for (int32_t i = (int32_t)r.top; i < bottom; i++) { - FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left; - FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left; - for (int32_t j = (int32_t)r.left; j < right; j++) { - FX_ARGB c = *pDstLine; - *pDstLine++ = - ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)); - pSrcLine++; - } - pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch()); - pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch()); - } - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap, - const CFX_RectF& rect) { - if (!m_renderDevice) - return FWL_Error::PropertyInvalid; - CFX_DIBitmap* dst = m_renderDevice->GetBitmap(); - if (!dst) - return FWL_Error::PropertyInvalid; - CFX_RectF temp(rect); - m_info.CTM.TransformRect(temp); - CFX_RectF r; - r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth()); - r.Intersect(temp); - if (r.IsEmpty()) { - return FWL_Error::ParameterInvalid; - } - FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + - int32_t(r.top) * srcBitmap->GetPitch()); - FX_ARGB* pDstBuf = - (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch()); - int32_t bottom = (int32_t)r.bottom(); - int32_t right = (int32_t)r.right(); - for (int32_t i = (int32_t)r.top; i < bottom; i++) { - FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left; - FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left; - for (int32_t j = (int32_t)r.left; j < right; j++) { - FX_ARGB c = *pDstLine; - *pDstLine++ = - ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF))); - pSrcLine++; - } - pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch()); - pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch()); - } - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) { +void CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) { switch (dashStyle) { case FX_DASHSTYLE_Solid: { m_info.graphState.SetDashCount(0); - return FWL_Error::Succeeded; + return; } case FX_DASHSTYLE_Dash: { FX_FLOAT dashArray[] = {3, 1}; SetLineDash(0, dashArray, 2); - return FWL_Error::Succeeded; + return; } case FX_DASHSTYLE_Dot: { FX_FLOAT dashArray[] = {1, 1}; SetLineDash(0, dashArray, 2); - return FWL_Error::Succeeded; + return; } case FX_DASHSTYLE_DashDot: { FX_FLOAT dashArray[] = {3, 1, 1, 1}; SetLineDash(0, dashArray, 4); - return FWL_Error::Succeeded; + return; } case FX_DASHSTYLE_DashDotDot: { FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1}; SetLineDash(0, dashArray, 6); - return FWL_Error::Succeeded; + return; } default: - return FWL_Error::ParameterInvalid; + return; } } -FWL_Error CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path, - CFX_Matrix* matrix) { +void CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path, CFX_Matrix* matrix) { if (!m_info.strokeColor) - return FWL_Error::PropertyInvalid; - CFX_Matrix m; - m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); + return; + CFX_Matrix m(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, + m_info.CTM.e, m_info.CTM.f); if (matrix) { m.Concat(*matrix); } switch (m_info.strokeColor->m_type) { case FX_COLOR_Solid: { - bool result = - m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, - 0x0, m_info.strokeColor->m_info.argb, 0); - if (!result) - return FWL_Error::Indefinite; - return FWL_Error::Succeeded; + m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, 0x0, + m_info.strokeColor->m_info.argb, 0); + return; } - case FX_COLOR_Pattern: - return StrokePathWithPattern(path, &m); - case FX_COLOR_Shading: - return StrokePathWithShading(path, &m); default: - return FWL_Error::PropertyInvalid; + return; } } -FWL_Error CFX_Graphics::RenderDeviceFillPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { +void CFX_Graphics::RenderDeviceFillPath(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { if (!m_info.fillColor) - return FWL_Error::PropertyInvalid; - CFX_Matrix m; - m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); + return; + CFX_Matrix m(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, + m_info.CTM.e, m_info.CTM.f); if (matrix) { m.Concat(*matrix); } switch (m_info.fillColor->m_type) { case FX_COLOR_Solid: { - bool result = m_renderDevice->DrawPath( - path->GetPathData(), &m, &m_info.graphState, - m_info.fillColor->m_info.argb, 0x0, fillMode); - if (!result) - return FWL_Error::Indefinite; - return FWL_Error::Succeeded; + m_renderDevice->DrawPath(path->GetPathData(), &m, &m_info.graphState, + m_info.fillColor->m_info.argb, 0x0, fillMode); + return; } case FX_COLOR_Pattern: - return FillPathWithPattern(path, fillMode, &m); + FillPathWithPattern(path, fillMode, &m); + return; case FX_COLOR_Shading: - return FillPathWithShading(path, fillMode, &m); + FillPathWithShading(path, fillMode, &m); + return; default: - return FWL_Error::PropertyInvalid; - } -} - -FWL_Error CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source, - const CFX_PointF& point, - CFX_Matrix* matrix) { - CFX_Matrix m1; - m1.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); - if (matrix) { - m1.Concat(*matrix); - } - CFX_Matrix m2; - m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(), - point.x, point.y); - m2.Concat(m1); - int32_t left, top; - std::unique_ptr<CFX_DIBitmap> bmp1 = source->FlipImage(false, true); - std::unique_ptr<CFX_DIBitmap> bmp2 = bmp1->TransformTo(&m2, left, top); - CFX_RectF r; - GetClipRect(r); - CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap(); - CFX_DIBitmap bmp; - if (bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb) && - m_renderDevice->GetDIBits(&bmp, 0, 0) && - bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top), - FXSYS_round(r.Width()), FXSYS_round(r.Height()), - bmp2.get(), FXSYS_round(r.left - left), - FXSYS_round(r.top - top)) && - m_renderDevice->SetDIBits(&bmp, 0, 0)) { - return FWL_Error::Succeeded; + return; } - return FWL_Error::Indefinite; } -FWL_Error CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source, - const CFX_RectF& rect, - CFX_Matrix* matrix) { - CFX_Matrix m1; - m1.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); +void CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source, + const CFX_RectF& rect, + CFX_Matrix* matrix) { + CFX_Matrix m1(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, + m_info.CTM.e, m_info.CTM.f); if (matrix) { m1.Concat(*matrix); } std::unique_ptr<CFX_DIBitmap> bmp1 = source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height()); - CFX_Matrix m2; - m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top); + CFX_Matrix m2(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top); m2.Concat(m1); - int32_t left, top; + + int32_t left; + int32_t top; std::unique_ptr<CFX_DIBitmap> bmp2 = bmp1->FlipImage(false, true); std::unique_ptr<CFX_DIBitmap> bmp3 = bmp2->TransformTo(&m2, left, top); - CFX_RectF r; - GetClipRect(r); + CFX_RectF r = GetClipRect(); CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap(); - if (bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top), - FXSYS_round(r.Width()), FXSYS_round(r.Height()), - bmp3.get(), FXSYS_round(r.left - left), - FXSYS_round(r.top - top))) { - return FWL_Error::Succeeded; - } - return FWL_Error::Indefinite; + bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top), + FXSYS_round(r.Width()), FXSYS_round(r.Height()), + bmp3.get(), FXSYS_round(r.left - left), + FXSYS_round(r.top - top)); } -FWL_Error CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point, - const CFX_WideString& text, - CFX_Matrix* matrix) { - int32_t length = text.GetLength(); - uint32_t* charCodes = FX_Alloc(uint32_t, length); - FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length); - CFX_RectF rect; - rect.Set(point.x, point.y, 0, 0); - CalcTextInfo(text, charCodes, charPos, rect); - CFX_Matrix m; - m.Set(m_info.CTM.a, m_info.CTM.b, m_info.CTM.c, m_info.CTM.d, m_info.CTM.e, - m_info.CTM.f); - m.Translate(0, m_info.fontSize * m_info.fontHScale); - if (matrix) { - m.Concat(*matrix); - } - bool result = m_renderDevice->DrawNormalText( - length, charPos, m_info.font, -m_info.fontSize * m_info.fontHScale, &m, - m_info.fillColor->m_info.argb, FXTEXT_CLEARTYPE); - if (!result) - return FWL_Error::Indefinite; - FX_Free(charPos); - FX_Free(charCodes); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Graphics::StrokePathWithPattern(CFX_Path* path, - CFX_Matrix* matrix) { - return FWL_Error::MethodNotSupported; -} - -FWL_Error CFX_Graphics::StrokePathWithShading(CFX_Path* path, - CFX_Matrix* matrix) { - return FWL_Error::MethodNotSupported; -} - -FWL_Error CFX_Graphics::FillPathWithPattern(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { +void CFX_Graphics::FillPathWithPattern(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { CFX_Pattern* pattern = m_info.fillColor->m_info.pattern; CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap(); int32_t width = bitmap->GetWidth(); @@ -1325,18 +355,15 @@ FWL_Error CFX_Graphics::FillPathWithPattern(CFX_Path* path, m_renderDevice->GetDIBits(&bmp, 0, 0); FX_HatchStyle hatchStyle = m_info.fillColor->m_info.pattern->m_hatchStyle; - if (hatchStyle < FX_HATCHSTYLE_Horizontal || - hatchStyle > FX_HATCHSTYLE_SolidDiamond) { - return FWL_Error::IntermediateValueInvalid; - } - const FX_HATCHDATA& data = hatchBitmapData[hatchStyle]; + const FX_HATCHDATA& data = hatchBitmapData[static_cast<int>(hatchStyle)]; + CFX_DIBitmap mask; mask.Create(data.width, data.height, FXDIB_1bppMask); FXSYS_memcpy(mask.GetBuffer(), data.maskBits, mask.GetPitch() * data.height); CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox(); - if (matrix) { - rectf.Transform(matrix); - } + if (matrix) + matrix->TransformRect(rectf); + FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top), FXSYS_round(rectf.right), FXSYS_round(rectf.bottom)); CFX_FxgeDevice device; @@ -1353,12 +380,11 @@ FWL_Error CFX_Graphics::FillPathWithPattern(CFX_Path* path, m_renderDevice->SetClip_PathFill(path->GetPathData(), matrix, fillMode); SetDIBitsWithMatrix(&bmp, &pattern->m_matrix); m_renderDevice->RestoreState(false); - return FWL_Error::Succeeded; } -FWL_Error CFX_Graphics::FillPathWithShading(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix) { +void CFX_Graphics::FillPathWithShading(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix) { CFX_DIBitmap* bitmap = m_renderDevice->GetBitmap(); int32_t width = bitmap->GetWidth(); int32_t height = bitmap->GetHeight(); @@ -1474,106 +500,39 @@ FWL_Error CFX_Graphics::FillPathWithShading(CFX_Path* path, SetDIBitsWithMatrix(&bmp, matrix); m_renderDevice->RestoreState(false); } - return result ? FWL_Error::Succeeded : FWL_Error::PropertyInvalid; } -FWL_Error CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source, - CFX_Matrix* matrix) { +void CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source, + CFX_Matrix* matrix) { if (matrix->IsIdentity()) { m_renderDevice->SetDIBits(source, 0, 0); } else { - CFX_Matrix m; - m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0, - 0); + CFX_Matrix m((FX_FLOAT)source->GetWidth(), 0, 0, + (FX_FLOAT)source->GetHeight(), 0, 0); m.Concat(*matrix); - int32_t left, top; + int32_t left; + int32_t top; std::unique_ptr<CFX_DIBitmap> bmp1 = source->FlipImage(false, true); std::unique_ptr<CFX_DIBitmap> bmp2 = bmp1->TransformTo(&m, left, top); m_renderDevice->SetDIBits(bmp2.get(), left, top); } - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Graphics::CalcTextInfo(const CFX_WideString& text, - uint32_t* charCodes, - FXTEXT_CHARPOS* charPos, - CFX_RectF& rect) { - std::unique_ptr<CFX_UnicodeEncoding> encoding( - new CFX_UnicodeEncoding(m_info.font)); - int32_t length = text.GetLength(); - FX_FLOAT penX = (FX_FLOAT)rect.left; - FX_FLOAT penY = (FX_FLOAT)rect.top; - FX_FLOAT left = (FX_FLOAT)(0); - FX_FLOAT top = (FX_FLOAT)(0); - charCodes[0] = text.GetAt(0); - charPos[0].m_OriginX = penX + left; - charPos[0].m_OriginY = penY + top; - charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]); - charPos[0].m_FontCharWidth = FXSYS_round( - m_info.font->GetGlyphWidth(charPos[0].m_GlyphIndex) * m_info.fontHScale); - charPos[0].m_bGlyphAdjust = true; - charPos[0].m_AdjustMatrix[0] = -1; - charPos[0].m_AdjustMatrix[1] = 0; - charPos[0].m_AdjustMatrix[2] = 0; - charPos[0].m_AdjustMatrix[3] = 1; - penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * m_info.fontSize / 1000 + - m_info.fontSpacing; - for (int32_t i = 1; i < length; i++) { - charCodes[i] = text.GetAt(i); - charPos[i].m_OriginX = penX + left; - charPos[i].m_OriginY = penY + top; - charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]); - charPos[i].m_FontCharWidth = - FXSYS_round(m_info.font->GetGlyphWidth(charPos[i].m_GlyphIndex) * - m_info.fontHScale); - charPos[i].m_bGlyphAdjust = true; - charPos[i].m_AdjustMatrix[0] = -1; - charPos[i].m_AdjustMatrix[1] = 0; - charPos[i].m_AdjustMatrix[2] = 0; - charPos[i].m_AdjustMatrix[3] = 1; - penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * m_info.fontSize / 1000 + - m_info.fontSpacing; - } - rect.width = (FX_FLOAT)penX - rect.left; - rect.height = rect.top + m_info.fontSize * m_info.fontHScale - rect.top; - return FWL_Error::Succeeded; } CFX_Graphics::TInfo::TInfo() - : isAntialiasing(true), - strokeAlignment(FX_STROKEALIGNMENT_Center), - isActOnDash(false), - strokeColor(nullptr), - fillColor(nullptr), - font(nullptr), - fontSize(40.0), - fontHScale(1.0), - fontSpacing(0.0) {} + : isActOnDash(false), strokeColor(nullptr), fillColor(nullptr) {} CFX_Graphics::TInfo::TInfo(const TInfo& info) : graphState(info.graphState), - isAntialiasing(info.isAntialiasing), - strokeAlignment(info.strokeAlignment), CTM(info.CTM), isActOnDash(info.isActOnDash), strokeColor(info.strokeColor), - fillColor(info.fillColor), - font(info.font), - fontSize(info.fontSize), - fontHScale(info.fontHScale), - fontSpacing(info.fontSpacing) {} + fillColor(info.fillColor) {} CFX_Graphics::TInfo& CFX_Graphics::TInfo::operator=(const TInfo& other) { graphState.Copy(other.graphState); - isAntialiasing = other.isAntialiasing; - strokeAlignment = other.strokeAlignment; CTM = other.CTM; isActOnDash = other.isActOnDash; strokeColor = other.strokeColor; fillColor = other.fillColor; - font = other.font; - fontSize = other.fontSize; - fontHScale = other.fontHScale; - fontSpacing = other.fontSpacing; return *this; } diff --git a/xfa/fxgraphics/cfx_graphics.h b/xfa/fxgraphics/cfx_graphics.h index e18564bf6..c18f8eb4c 100644 --- a/xfa/fxgraphics/cfx_graphics.h +++ b/xfa/fxgraphics/cfx_graphics.h @@ -8,6 +8,7 @@ #define XFA_FXGRAPHICS_CFX_GRAPHICS_H_ #include <memory> +#include <vector> #include "core/fxcrt/fx_system.h" #include "core/fxge/cfx_fxgedevice.h" @@ -15,13 +16,10 @@ #include "core/fxge/cfx_renderdevice.h" #include "core/fxge/fx_dib.h" #include "core/fxge/fx_font.h" -#include "xfa/fwl/fwl_error.h" class CFX_Color; class CFX_Path; -class CAGG_Graphics; -using FX_DeviceCap = int32_t; using FX_FillMode = int32_t; enum FX_DashStyle { @@ -32,152 +30,44 @@ enum FX_DashStyle { FX_DASHSTYLE_DashDotDot = 4 }; -enum FX_StrokeAlignment { - FX_STROKEALIGNMENT_Center = 0, - FX_STROKEALIGNMENT_Inset = 1, - FX_STROKEALIGNMENT_Outset = 2, - FX_STROKEALIGNMENT_Left = 3, - FX_STROKEALIGNMENT_Right = 4 -}; - -enum FX_HatchStyle { - FX_HATCHSTYLE_Horizontal = 0, - FX_HATCHSTYLE_Vertical = 1, - FX_HATCHSTYLE_ForwardDiagonal = 2, - FX_HATCHSTYLE_BackwardDiagonal = 3, - FX_HATCHSTYLE_Cross = 4, - FX_HATCHSTYLE_DiagonalCross = 5, - FX_HATCHSTYLE_05Percent = 6, - FX_HATCHSTYLE_10Percent = 7, - FX_HATCHSTYLE_20Percent = 8, - FX_HATCHSTYLE_25Percent = 9, - FX_HATCHSTYLE_30Percent = 10, - FX_HATCHSTYLE_40Percent = 11, - FX_HATCHSTYLE_50Percent = 12, - FX_HATCHSTYLE_60Percent = 13, - FX_HATCHSTYLE_70Percent = 14, - FX_HATCHSTYLE_75Percent = 15, - FX_HATCHSTYLE_80Percent = 16, - FX_HATCHSTYLE_90Percent = 17, - FX_HATCHSTYLE_LightDownwardDiagonal = 18, - FX_HATCHSTYLE_LightUpwardDiagonal = 19, - FX_HATCHSTYLE_DarkDownwardDiagonal = 20, - FX_HATCHSTYLE_DarkUpwardDiagonal = 21, - FX_HATCHSTYLE_WideDownwardDiagonal = 22, - FX_HATCHSTYLE_WideUpwardDiagonal = 23, - FX_HATCHSTYLE_LightVertical = 24, - FX_HATCHSTYLE_LightHorizontal = 25, - FX_HATCHSTYLE_NarrowVertical = 26, - FX_HATCHSTYLE_NarrowHorizontal = 27, - FX_HATCHSTYLE_DarkVertical = 28, - FX_HATCHSTYLE_DarkHorizontal = 29, - FX_HATCHSTYLE_DashedDownwardDiagonal = 30, - FX_HATCHSTYLE_DashedUpwardDiagonal = 31, - FX_HATCHSTYLE_DashedHorizontal = 32, - FX_HATCHSTYLE_DashedVertical = 33, - FX_HATCHSTYLE_SmallConfetti = 34, - FX_HATCHSTYLE_LargeConfetti = 35, - FX_HATCHSTYLE_ZigZag = 36, - FX_HATCHSTYLE_Wave = 37, - FX_HATCHSTYLE_DiagonalBrick = 38, - FX_HATCHSTYLE_HorizontalBrick = 39, - FX_HATCHSTYLE_Weave = 40, - FX_HATCHSTYLE_Plaid = 41, - FX_HATCHSTYLE_Divot = 42, - FX_HATCHSTYLE_DottedGrid = 43, - FX_HATCHSTYLE_DottedDiamond = 44, - FX_HATCHSTYLE_Shingle = 45, - FX_HATCHSTYLE_Trellis = 46, - FX_HATCHSTYLE_Sphere = 47, - FX_HATCHSTYLE_SmallGrid = 48, - FX_HATCHSTYLE_SmallCheckerBoard = 49, - FX_HATCHSTYLE_LargeCheckerBoard = 50, - FX_HATCHSTYLE_OutlinedDiamond = 51, - FX_HATCHSTYLE_SolidDiamond = 52 +enum class FX_HatchStyle { + Horizontal = 0, + Vertical = 1, + ForwardDiagonal = 2, + BackwardDiagonal = 3, + Cross = 4, + DiagonalCross = 5 }; class CFX_RenderDevice; class CFX_Graphics { public: - CFX_Graphics(); - virtual ~CFX_Graphics(); - - FWL_Error Create(CFX_RenderDevice* renderDevice, bool isAntialiasing = true); - FWL_Error Create(int32_t width, - int32_t height, - FXDIB_Format format, - bool isNative = true, - bool isAntialiasing = true); - - FWL_Error GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal); - FWL_Error IsPrinterDevice(bool& isPrinter); - FWL_Error EnableAntialiasing(bool isAntialiasing); - - FWL_Error SaveGraphState(); - FWL_Error RestoreGraphState(); - - FWL_Error GetLineCap(CFX_GraphStateData::LineCap& lineCap) const; - FWL_Error GetDashCount(int32_t& dashCount) const; - FWL_Error GetLineDash(FX_FLOAT& dashPhase, FX_FLOAT* dashArray) const; - FWL_Error GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin) const; - FWL_Error GetMiterLimit(FX_FLOAT& miterLimit) const; - FWL_Error GetLineWidth(FX_FLOAT& lineWidth) const; - FWL_Error GetStrokeAlignment(FX_StrokeAlignment& strokeAlignment) const; - FWL_Error GetClipRect(CFX_RectF& rect) const; + explicit CFX_Graphics(CFX_RenderDevice* renderDevice); + ~CFX_Graphics(); + + void SaveGraphState(); + void RestoreGraphState(); + + CFX_RectF GetClipRect() const; CFX_Matrix* GetMatrix(); CFX_RenderDevice* GetRenderDevice(); - FWL_Error SetLineCap(CFX_GraphStateData::LineCap lineCap); - FWL_Error SetLineDash(FX_FLOAT dashPhase, - FX_FLOAT* dashArray, - int32_t dashCount); - FWL_Error SetLineDash(FX_DashStyle dashStyle); - FWL_Error SetLineJoin(CFX_GraphStateData::LineJoin lineJoin); - FWL_Error SetMiterLimit(FX_FLOAT miterLimit); - FWL_Error SetLineWidth(FX_FLOAT lineWidth, bool isActOnDash = false); - FWL_Error SetStrokeAlignment(FX_StrokeAlignment strokeAlignment); - FWL_Error SetStrokeColor(CFX_Color* color); - FWL_Error SetFillColor(CFX_Color* color); - FWL_Error SetClipRect(const CFX_RectF& rect); - FWL_Error SetFont(CFX_Font* font); - FWL_Error SetFontSize(const FX_FLOAT size); - FWL_Error SetFontHScale(const FX_FLOAT scale); - FWL_Error SetCharSpacing(const FX_FLOAT spacing); - FWL_Error SetTextDrawingMode(const int32_t mode); - - FWL_Error StrokePath(CFX_Path* path, CFX_Matrix* matrix = nullptr); - FWL_Error FillPath(CFX_Path* path, - FX_FillMode fillMode = FXFILL_WINDING, - CFX_Matrix* matrix = nullptr); - FWL_Error ClipPath(CFX_Path* path, - FX_FillMode fillMode = FXFILL_WINDING, - CFX_Matrix* matrix = nullptr); - FWL_Error DrawImage(CFX_DIBSource* source, - const CFX_PointF& point, - CFX_Matrix* matrix = nullptr); - FWL_Error StretchImage(CFX_DIBSource* source, - const CFX_RectF& rect, - CFX_Matrix* matrix = nullptr); - FWL_Error ConcatMatrix(const CFX_Matrix* matrix); - FWL_Error ClearClip(); - FWL_Error ShowText(const CFX_PointF& point, - const CFX_WideString& text, - CFX_Matrix* matrix = nullptr); - void CalcTextRect(CFX_RectF& rect, - const CFX_WideString& text, - bool isMultiline = false, + void SetLineCap(CFX_GraphStateData::LineCap lineCap); + void SetLineDash(FX_FLOAT dashPhase, FX_FLOAT* dashArray, int32_t dashCount); + void SetLineDash(FX_DashStyle dashStyle); + void SetLineWidth(FX_FLOAT lineWidth, bool isActOnDash = false); + void SetStrokeColor(CFX_Color* color); + void SetFillColor(CFX_Color* color); + void SetClipRect(const CFX_RectF& rect); + void StrokePath(CFX_Path* path, CFX_Matrix* matrix = nullptr); + void FillPath(CFX_Path* path, + FX_FillMode fillMode = FXFILL_WINDING, + CFX_Matrix* matrix = nullptr); + void StretchImage(CFX_DIBSource* source, + const CFX_RectF& rect, CFX_Matrix* matrix = nullptr); - FWL_Error Transfer(CFX_Graphics* graphics, const CFX_Matrix* matrix); - FWL_Error Transfer(CFX_Graphics* graphics, - FX_FLOAT srcLeft, - FX_FLOAT srcTop, - const CFX_RectF& dstRect, - const CFX_Matrix* matrix); - - FWL_Error InverseRect(const CFX_RectF& rect); - FWL_Error XorDIBitmap(const CFX_DIBitmap* srcBitmap, const CFX_RectF& rect); - FWL_Error EqvDIBitmap(const CFX_DIBitmap* srcBitmap, const CFX_RectF& rect); + void ConcatMatrix(const CFX_Matrix* matrix); protected: int32_t m_type; @@ -189,53 +79,32 @@ class CFX_Graphics { TInfo& operator=(const TInfo& other); CFX_GraphStateData graphState; - bool isAntialiasing; - FX_StrokeAlignment strokeAlignment; CFX_Matrix CTM; bool isActOnDash; CFX_Color* strokeColor; CFX_Color* fillColor; - CFX_Font* font; - FX_FLOAT fontSize; - FX_FLOAT fontHScale; - FX_FLOAT fontSpacing; } m_info; - FWL_Error RenderDeviceSetLineDash(FX_DashStyle dashStyle); - FWL_Error RenderDeviceStrokePath(CFX_Path* path, CFX_Matrix* matrix); - FWL_Error RenderDeviceFillPath(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix); - FWL_Error RenderDeviceDrawImage(CFX_DIBSource* source, - const CFX_PointF& point, - CFX_Matrix* matrix); - FWL_Error RenderDeviceStretchImage(CFX_DIBSource* source, - const CFX_RectF& rect, - CFX_Matrix* matrix); - FWL_Error RenderDeviceShowText(const CFX_PointF& point, - const CFX_WideString& text, - CFX_Matrix* matrix); - - FWL_Error StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix); - FWL_Error StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix); - - FWL_Error FillPathWithPattern(CFX_Path* path, - FX_FillMode fillMode, - CFX_Matrix* matrix); - FWL_Error FillPathWithShading(CFX_Path* path, - FX_FillMode fillMode, + void RenderDeviceSetLineDash(FX_DashStyle dashStyle); + void RenderDeviceStrokePath(CFX_Path* path, CFX_Matrix* matrix); + void RenderDeviceFillPath(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix); + void RenderDeviceStretchImage(CFX_DIBSource* source, + const CFX_RectF& rect, CFX_Matrix* matrix); - FWL_Error SetDIBitsWithMatrix(CFX_DIBSource* source, CFX_Matrix* matrix); - FWL_Error CalcTextInfo(const CFX_WideString& text, - uint32_t* charCodes, - FXTEXT_CHARPOS* charPos, - CFX_RectF& rect); + void FillPathWithPattern(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix); + void FillPathWithShading(CFX_Path* path, + FX_FillMode fillMode, + CFX_Matrix* matrix); + + void SetDIBitsWithMatrix(CFX_DIBSource* source, CFX_Matrix* matrix); CFX_RenderDevice* m_renderDevice; - CFX_ArrayTemplate<TInfo*> m_infoStack; - std::unique_ptr<CAGG_Graphics> m_aggGraphics; - friend class CAGG_Graphics; + std::vector<std::unique_ptr<TInfo>> m_infoStack; }; #endif // XFA_FXGRAPHICS_CFX_GRAPHICS_H_ diff --git a/xfa/fxgraphics/cfx_path.cpp b/xfa/fxgraphics/cfx_path.cpp index 3288631f1..d56eb13f6 100644 --- a/xfa/fxgraphics/cfx_path.cpp +++ b/xfa/fxgraphics/cfx_path.cpp @@ -8,171 +8,144 @@ #include "core/fxge/cfx_pathdata.h" #include "third_party/base/ptr_util.h" -#include "xfa/fxgraphics/cfx_path_generator.h" CFX_Path::CFX_Path() {} -FWL_Error CFX_Path::Create() { - if (m_generator) - return FWL_Error::PropertyInvalid; - - m_generator = pdfium::MakeUnique<CFX_PathGenerator>(); - return FWL_Error::Succeeded; -} - CFX_Path::~CFX_Path() {} -FWL_Error CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->MoveTo(x, y); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->LineTo(x, y); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::BezierTo(FX_FLOAT ctrlX1, - FX_FLOAT ctrlY1, - FX_FLOAT ctrlX2, - FX_FLOAT ctrlY2, - FX_FLOAT toX, - FX_FLOAT toY) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::ArcTo(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->ArcTo(left + width / 2, top + height / 2, width / 2, height / 2, - startAngle, sweepAngle); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::Close() { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->Close(); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddLine(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddLine(x1, y1, x2, y2); - return FWL_Error::Succeeded; +void CFX_Path::Clear() { + data_.Clear(); } -FWL_Error CFX_Path::AddBezier(FX_FLOAT startX, - FX_FLOAT startY, - FX_FLOAT ctrlX1, - FX_FLOAT ctrlY1, - FX_FLOAT ctrlX2, - FX_FLOAT ctrlY2, - FX_FLOAT endX, - FX_FLOAT endY) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, - endY); - return FWL_Error::Succeeded; +void CFX_Path::Close() { + data_.ClosePath(); } -FWL_Error CFX_Path::AddRectangle(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddRectangle(left, top, left + width, top + height); - return FWL_Error::Succeeded; +void CFX_Path::MoveTo(const CFX_PointF& point) { + data_.AppendPoint(point, FXPT_TYPE::MoveTo, false); } -FWL_Error CFX_Path::AddEllipse(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddEllipse(left + width / 2, top + height / 2, width / 2, - height / 2); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddEllipse(const CFX_RectF& rect) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddEllipse(rect.left + rect.Width() / 2, - rect.top + rect.Height() / 2, rect.Width() / 2, - rect.Height() / 2); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddArc(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddArc(left + width / 2, top + height / 2, width / 2, height / 2, - startAngle, sweepAngle); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddPie(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddPie(left + width / 2, top + height / 2, width / 2, height / 2, - startAngle, sweepAngle); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::AddSubpath(CFX_Path* path) { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->AddPathData(path->GetPathData()); - return FWL_Error::Succeeded; -} - -FWL_Error CFX_Path::Clear() { - if (!m_generator) - return FWL_Error::PropertyInvalid; - m_generator->GetPathData()->SetPointCount(0); - return FWL_Error::Succeeded; -} - -bool CFX_Path::IsEmpty() const { - if (!m_generator) - return false; - if (m_generator->GetPathData()->GetPointCount() == 0) - return true; - return false; -} +void CFX_Path::LineTo(const CFX_PointF& point) { + data_.AppendPoint(point, FXPT_TYPE::LineTo, false); +} + +void CFX_Path::BezierTo(const CFX_PointF& c1, + const CFX_PointF& c2, + const CFX_PointF& to) { + data_.AppendPoint(c1, FXPT_TYPE::BezierTo, false); + data_.AppendPoint(c2, FXPT_TYPE::BezierTo, false); + data_.AppendPoint(to, FXPT_TYPE::BezierTo, false); +} + +void CFX_Path::ArcTo(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle) { + CFX_SizeF new_size = size / 2.0f; + ArcToInternal(CFX_PointF(pos.x + new_size.width, pos.y + new_size.height), + new_size, start_angle, sweep_angle); +} -CFX_PathData* CFX_Path::GetPathData() const { - if (!m_generator) - return nullptr; - return m_generator->GetPathData(); +void CFX_Path::ArcToInternal(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle) { + FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2); + FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2); + FX_FLOAT tx = ((1.0f - x0) * 4) / (3 * 1.0f); + FX_FLOAT ty = y0 - ((tx * x0) / y0); + + CFX_PointF points[] = {CFX_PointF(x0 + tx, -ty), CFX_PointF(x0 + tx, ty)}; + FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2); + FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2); + + CFX_PointF bezier; + bezier.x = pos.x + (size.width * ((points[0].x * cs) - (points[0].y * sn))); + bezier.y = pos.y + (size.height * ((points[0].x * sn) + (points[0].y * cs))); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); + + bezier.x = pos.x + (size.width * ((points[1].x * cs) - (points[1].y * sn))); + bezier.y = pos.y + (size.height * ((points[1].x * sn) + (points[1].y * cs))); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); + + bezier.x = pos.x + (size.width * FXSYS_cos(start_angle + sweep_angle)); + bezier.y = pos.y + (size.height * FXSYS_sin(start_angle + sweep_angle)); + data_.AppendPoint(bezier, FXPT_TYPE::BezierTo, false); +} + +void CFX_Path::AddLine(const CFX_PointF& p1, const CFX_PointF& p2) { + data_.AppendPoint(p1, FXPT_TYPE::MoveTo, false); + data_.AppendPoint(p2, FXPT_TYPE::LineTo, false); +} + +void CFX_Path::AddRectangle(FX_FLOAT left, + FX_FLOAT top, + FX_FLOAT width, + FX_FLOAT height) { + data_.AppendRect(left, top, left + width, top + height); +} + +void CFX_Path::AddEllipse(const CFX_RectF& rect) { + AddArc(rect.TopLeft(), rect.Size(), 0, FX_PI * 2); +} + +void CFX_Path::AddArc(const CFX_PointF& original_pos, + const CFX_SizeF& original_size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle) { + if (sweep_angle == 0) + return; + + const FX_FLOAT bezier_arc_angle_epsilon = 0.01f; + while (start_angle > FX_PI * 2) + start_angle -= FX_PI * 2; + while (start_angle < 0) + start_angle += FX_PI * 2; + if (sweep_angle >= FX_PI * 2) + sweep_angle = FX_PI * 2; + if (sweep_angle <= -FX_PI * 2) + sweep_angle = -FX_PI * 2; + + CFX_SizeF size = original_size / 2; + CFX_PointF pos(original_pos.x + size.width, original_pos.y + size.height); + data_.AppendPoint(pos + CFX_PointF(size.width * FXSYS_cos(start_angle), + size.height * FXSYS_sin(start_angle)), + FXPT_TYPE::MoveTo, false); + + FX_FLOAT total_sweep = 0; + FX_FLOAT local_sweep = 0; + FX_FLOAT prev_sweep = 0; + bool done = false; + do { + if (sweep_angle < 0) { + prev_sweep = total_sweep; + local_sweep = -FX_PI / 2; + total_sweep -= FX_PI / 2; + if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } else { + prev_sweep = total_sweep; + local_sweep = FX_PI / 2; + total_sweep += FX_PI / 2; + if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + + ArcToInternal(pos, size, start_angle, local_sweep); + start_angle += local_sweep; + } while (!done); +} + +void CFX_Path::AddSubpath(CFX_Path* path) { + if (!path) + return; + data_.Append(&path->data_, nullptr); +} + +void CFX_Path::TransformBy(const CFX_Matrix& mt) { + data_.Transform(&mt); } diff --git a/xfa/fxgraphics/cfx_path.h b/xfa/fxgraphics/cfx_path.h index 9171a91a0..267831603 100644 --- a/xfa/fxgraphics/cfx_path.h +++ b/xfa/fxgraphics/cfx_path.h @@ -7,74 +7,52 @@ #ifndef XFA_FXGRAPHICS_CFX_PATH_H_ #define XFA_FXGRAPHICS_CFX_PATH_H_ -#include <memory> - #include "core/fxcrt/fx_system.h" +#include "core/fxge/cfx_pathdata.h" #include "xfa/fxgraphics/cfx_graphics.h" -class CFX_PathData; -class CFX_PathGenerator; - class CFX_Path final { public: CFX_Path(); ~CFX_Path(); - FWL_Error Create(); - FWL_Error MoveTo(FX_FLOAT x, FX_FLOAT y); - FWL_Error LineTo(FX_FLOAT x, FX_FLOAT y); - FWL_Error BezierTo(FX_FLOAT ctrlX1, - FX_FLOAT ctrlY1, - FX_FLOAT ctrlX2, - FX_FLOAT ctrlY2, - FX_FLOAT toX, - FX_FLOAT toY); - FWL_Error ArcTo(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle); - FWL_Error Close(); - - FWL_Error AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2); - FWL_Error AddBezier(FX_FLOAT startX, - FX_FLOAT startY, - FX_FLOAT ctrlX1, - FX_FLOAT ctrlY1, - FX_FLOAT ctrlX2, - FX_FLOAT ctrlY2, - FX_FLOAT endX, - FX_FLOAT endY); - FWL_Error AddRectangle(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height); - FWL_Error AddEllipse(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height); - FWL_Error AddEllipse(const CFX_RectF& rect); - FWL_Error AddArc(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle); - FWL_Error AddPie(FX_FLOAT left, - FX_FLOAT top, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT startAngle, - FX_FLOAT sweepAngle); - FWL_Error AddSubpath(CFX_Path* path); - FWL_Error Clear(); - - bool IsEmpty() const; - CFX_PathData* GetPathData() const; + const CFX_PathData* GetPathData() const { return &data_; } + + void Clear(); + bool IsEmpty() const { return data_.GetPoints().empty(); } + void TransformBy(const CFX_Matrix& mt); + + void Close(); + void MoveTo(const CFX_PointF& point); + void LineTo(const CFX_PointF& point); + void BezierTo(const CFX_PointF& c1, + const CFX_PointF& c2, + const CFX_PointF& to); + void ArcTo(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT startAngle, + FX_FLOAT sweepAngle); + + void AddLine(const CFX_PointF& p1, const CFX_PointF& p2); + void AddRectangle(FX_FLOAT left, + FX_FLOAT top, + FX_FLOAT width, + FX_FLOAT height); + void AddEllipse(const CFX_RectF& rect); + void AddArc(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT startAngle, + FX_FLOAT sweepAngle); + + void AddSubpath(CFX_Path* path); private: - std::unique_ptr<CFX_PathGenerator> m_generator; + void ArcToInternal(const CFX_PointF& pos, + const CFX_SizeF& size, + FX_FLOAT start_angle, + FX_FLOAT sweep_angle); + + CFX_PathData data_; }; #endif // XFA_FXGRAPHICS_CFX_PATH_H_ diff --git a/xfa/fxgraphics/cfx_path_generator.cpp b/xfa/fxgraphics/cfx_path_generator.cpp deleted file mode 100644 index 0122b1ce4..000000000 --- a/xfa/fxgraphics/cfx_path_generator.cpp +++ /dev/null @@ -1,206 +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 "xfa/fxgraphics/cfx_path_generator.h" - -#include "core/fxge/cfx_pathdata.h" -#include "core/fxge/cfx_renderdevice.h" - -CFX_PathGenerator::CFX_PathGenerator() : m_pPathData(new CFX_PathData) {} - -CFX_PathGenerator::~CFX_PathGenerator() {} - -void CFX_PathGenerator::AddPathData(CFX_PathData* pPathData) { - if (pPathData && pPathData->GetPointCount() > 0) { - int nCount = pPathData->GetPointCount(); - FX_PATHPOINT* pPoints = pPathData->GetPoints(); - AddPathData(pPoints, nCount); - } -} - -void CFX_PathGenerator::AddPathData(FX_PATHPOINT* pPoints, int nCount) { - if (pPoints && nCount > 0) { - int nOldCount = m_pPathData->GetPointCount(); - m_pPathData->AddPointCount(nCount); - FX_PATHPOINT* pDstPoints = m_pPathData->GetPoints(); - FXSYS_memcpy(pDstPoints + nOldCount, pPoints, - sizeof(FX_PATHPOINT) * nCount); - } -} - -void CFX_PathGenerator::MoveTo(FX_FLOAT x, FX_FLOAT y) { - m_pPathData->AddPointCount(1); - m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_MOVETO); -} - -void CFX_PathGenerator::LineTo(FX_FLOAT x, FX_FLOAT y) { - m_pPathData->AddPointCount(1); - m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_LINETO); -} - -void CFX_PathGenerator::BezierTo(FX_FLOAT ctrl_x1, - FX_FLOAT ctrl_y1, - FX_FLOAT ctrl_x2, - FX_FLOAT ctrl_y2, - FX_FLOAT to_x, - FX_FLOAT to_y) { - int old_count = m_pPathData->GetPointCount(); - m_pPathData->AddPointCount(3); - m_pPathData->SetPoint(old_count, ctrl_x1, ctrl_y1, FXPT_BEZIERTO); - m_pPathData->SetPoint(old_count + 1, ctrl_x2, ctrl_y2, FXPT_BEZIERTO); - m_pPathData->SetPoint(old_count + 2, to_x, to_y, FXPT_BEZIERTO); -} - -void CFX_PathGenerator::Close() { - if (m_pPathData->GetPointCount() > 0) { - int index = m_pPathData->GetPointCount() - 1; - FX_PATHPOINT* pPoints = m_pPathData->GetPoints(); - pPoints[index].m_Flag |= FXPT_CLOSEFIGURE; - } -} - -void CFX_PathGenerator::AddLine(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2) { - int old_count = m_pPathData->GetPointCount(); - m_pPathData->AddPointCount(2); - m_pPathData->SetPoint(old_count, x1, y1, FXPT_MOVETO); - m_pPathData->SetPoint(old_count + 1, x2, y2, FXPT_LINETO); -} - -void CFX_PathGenerator::AddBezier(FX_FLOAT start_x, - FX_FLOAT start_y, - FX_FLOAT ctrl_x1, - FX_FLOAT ctrl_y1, - FX_FLOAT ctrl_x2, - FX_FLOAT ctrl_y2, - FX_FLOAT end_x, - FX_FLOAT end_y) { - int old_count = m_pPathData->GetPointCount(); - m_pPathData->AddPointCount(4); - m_pPathData->SetPoint(old_count, start_x, start_y, FXPT_MOVETO); - m_pPathData->SetPoint(old_count + 1, ctrl_x1, ctrl_y1, FXPT_BEZIERTO); - m_pPathData->SetPoint(old_count + 2, ctrl_x2, ctrl_y2, FXPT_BEZIERTO); - m_pPathData->SetPoint(old_count + 3, end_x, end_y, FXPT_BEZIERTO); -} - -void CFX_PathGenerator::AddRectangle(FX_FLOAT x1, - FX_FLOAT y1, - FX_FLOAT x2, - FX_FLOAT y2) { - m_pPathData->AppendRect(x1, y1, x2, y2); -} - -void CFX_PathGenerator::AddEllipse(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height) { - AddArc(x, y, width, height, 0, FX_PI * 2); -} - -void CFX_PathGenerator::ArcTo(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT start_angle, - FX_FLOAT sweep_angle) { - FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2); - FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2); - FX_FLOAT tx = ((1.0f - x0) * 4) / (3 * 1.0f); - FX_FLOAT ty = y0 - ((tx * x0) / y0); - FX_FLOAT px[3], py[3]; - px[0] = x0 + tx; - py[0] = -ty; - px[1] = x0 + tx; - py[1] = ty; - FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2); - FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2); - int old_count = m_pPathData->GetPointCount(); - m_pPathData->AddPointCount(3); - FX_FLOAT bezier_x, bezier_y; - bezier_x = x + (width * ((px[0] * cs) - (py[0] * sn))); - bezier_y = y + (height * ((px[0] * sn) + (py[0] * cs))); - m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_BEZIERTO); - bezier_x = x + (width * ((px[1] * cs) - (py[1] * sn))); - bezier_y = y + (height * ((px[1] * sn) + (py[1] * cs))); - m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_BEZIERTO); - bezier_x = x + (width * FXSYS_cos(start_angle + sweep_angle)); - bezier_y = y + (height * FXSYS_sin(start_angle + sweep_angle)); - m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_BEZIERTO); -} - -void CFX_PathGenerator::AddArc(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT start_angle, - FX_FLOAT sweep_angle) { - if (sweep_angle == 0) { - return; - } - - const FX_FLOAT bezier_arc_angle_epsilon = 0.01f; - while (start_angle > FX_PI * 2) { - start_angle -= FX_PI * 2; - } - while (start_angle < 0) { - start_angle += FX_PI * 2; - } - if (sweep_angle >= FX_PI * 2) { - sweep_angle = FX_PI * 2; - } - if (sweep_angle <= -FX_PI * 2) { - sweep_angle = -FX_PI * 2; - } - m_pPathData->AddPointCount(1); - m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, - x + (width * FXSYS_cos(start_angle)), - y + (height * FXSYS_sin(start_angle)), FXPT_MOVETO); - FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0; - bool done = false; - do { - if (sweep_angle < 0) { - prev_sweep = total_sweep; - local_sweep = -FX_PI / 2; - total_sweep -= FX_PI / 2; - if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) { - local_sweep = sweep_angle - prev_sweep; - done = true; - } - } else { - prev_sweep = total_sweep; - local_sweep = FX_PI / 2; - total_sweep += FX_PI / 2; - if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) { - local_sweep = sweep_angle - prev_sweep; - done = true; - } - } - ArcTo(x, y, width, height, start_angle, local_sweep); - start_angle += local_sweep; - } while (!done); -} - -void CFX_PathGenerator::AddPie(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT start_angle, - FX_FLOAT sweep_angle) { - if (sweep_angle == 0) { - int old_count = m_pPathData->GetPointCount(); - m_pPathData->AddPointCount(2); - m_pPathData->SetPoint(old_count, x, y, FXPT_MOVETO); - m_pPathData->SetPoint(old_count + 1, x + (width * FXSYS_cos(start_angle)), - y + (height * FXSYS_sin(start_angle)), FXPT_LINETO); - return; - } - AddArc(x, y, width, height, start_angle, sweep_angle); - m_pPathData->AddPointCount(1); - m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, - FXPT_LINETO | FXPT_CLOSEFIGURE); -} diff --git a/xfa/fxgraphics/cfx_path_generator.h b/xfa/fxgraphics/cfx_path_generator.h deleted file mode 100644 index 75e3a5763..000000000 --- a/xfa/fxgraphics/cfx_path_generator.h +++ /dev/null @@ -1,68 +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 XFA_FXGRAPHICS_CFX_PATH_GENERATOR_H_ -#define XFA_FXGRAPHICS_CFX_PATH_GENERATOR_H_ - -#include <memory> - -#include "core/fxge/cfx_pathdata.h" - -class CFX_PathGenerator { - public: - CFX_PathGenerator(); - ~CFX_PathGenerator(); - - CFX_PathData* GetPathData() const { return m_pPathData.get(); } - - void AddPathData(CFX_PathData* path_data); - void AddPathData(FX_PATHPOINT* points, int count); - - void MoveTo(FX_FLOAT x, FX_FLOAT y); - void LineTo(FX_FLOAT x, FX_FLOAT y); - void BezierTo(FX_FLOAT ctrl_x1, - FX_FLOAT ctrl_y1, - FX_FLOAT ctrl_x2, - FX_FLOAT ctrl_y2, - FX_FLOAT to_x, - FX_FLOAT to_y); - void Close(); - void ArcTo(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT start_angle, - FX_FLOAT sweep_angle); - - void AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2); - void AddBezier(FX_FLOAT start_x, - FX_FLOAT start_y, - FX_FLOAT ctrl_x1, - FX_FLOAT ctrl_y1, - FX_FLOAT ctrl_x2, - FX_FLOAT ctrl_y2, - FX_FLOAT end_x, - FX_FLOAT end_y); - void AddRectangle(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2); - void AddEllipse(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height); - void AddArc(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT start_angle, - FX_FLOAT sweep_angle); - void AddPie(FX_FLOAT x, - FX_FLOAT y, - FX_FLOAT width, - FX_FLOAT height, - FX_FLOAT start_angle, - FX_FLOAT sweep_angle); - - protected: - std::unique_ptr<CFX_PathData> m_pPathData; -}; - -#endif // XFA_FXGRAPHICS_CFX_PATH_GENERATOR_H_ diff --git a/xfa/fxgraphics/cfx_pattern.cpp b/xfa/fxgraphics/cfx_pattern.cpp index f70a78d56..a20ec24aa 100644 --- a/xfa/fxgraphics/cfx_pattern.cpp +++ b/xfa/fxgraphics/cfx_pattern.cpp @@ -11,16 +11,10 @@ CFX_Pattern::CFX_Pattern(FX_HatchStyle hatchStyle, const FX_ARGB backArgb, CFX_Matrix* matrix) : m_hatchStyle(hatchStyle), m_foreArgb(foreArgb), m_backArgb(backArgb) { - ASSERT(m_hatchStyle >= FX_HATCHSTYLE_Horizontal && - m_hatchStyle <= FX_HATCHSTYLE_SolidDiamond); - - if (matrix) { - // TODO(dsinclair): Add a Set(const CFX_Matrix&) method. pdfium:436 - m_matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, - matrix->f); - } else { + if (matrix) + m_matrix = *matrix; + else m_matrix.SetIdentity(); - } } CFX_Pattern::~CFX_Pattern() {} |