[PDF Ink Signatures] Implement PDFiumEngine::UpdateShapeActive()
To support (un)erasing "V2" Ink shapes that were loaded from the PDF, there needs to be a PDFiumEngine::UpdateShapeActive() method, similar to how manipulating strokes require UpdateStrokeActive(). Add UpdateShapeActive(), along with tests. Though one part of it is disabled due to a crash in PDFium that requires investigating. As part of this, rename PDFiumEngineInkStrokesTest to PDFiumEngineInkDrawTest to better reflect what the test does. Bug: 353942910 Change-Id: I42ada29f9dc63634882748e5d77ba2c5fbab979a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6007521 Reviewed-by: Alan Screen <awscreen@chromium.org> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com> Commit-Queue: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/main@{#1380790}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
e573960348
commit
8feb02c87b
@ -4444,6 +4444,17 @@ PDFiumEngine::LoadV2InkPathsForPage(int page_index) {
|
||||
|
||||
return page_shape_map;
|
||||
}
|
||||
|
||||
void PDFiumEngine::UpdateShapeActive(int page_index,
|
||||
InkModeledShapeId id,
|
||||
bool active) {
|
||||
CHECK(PageIndexInBounds(page_index));
|
||||
auto it = ink_modeled_shape_map_.find(id);
|
||||
CHECK(it != ink_modeled_shape_map_.end());
|
||||
bool result = FPDFPageObj_SetIsActive(it->second, active);
|
||||
CHECK(result);
|
||||
ink_stroked_pages_needing_regeneration_.insert(page_index);
|
||||
}
|
||||
#endif // BUILDFLAG(ENABLE_PDF_INK2)
|
||||
|
||||
PDFiumEngine::ProgressivePaint::ProgressivePaint(int index,
|
||||
|
@ -402,6 +402,19 @@ class PDFiumEngine : public DocumentLoader::Client, public IFSDK_PAUSE {
|
||||
virtual std::map<InkModeledShapeId, ink::ModeledShape> LoadV2InkPathsForPage(
|
||||
int page_index);
|
||||
|
||||
// Modifies an existing shape identified by `id` on the page at `page_index`
|
||||
// to become either active or inactive. The caller must pass the same
|
||||
// consistent and valid `page_index`/`id` pair as was provided by
|
||||
// `LoadV2InkPathsForPage()`.
|
||||
// Shape objects that become inactive will no longer be included for
|
||||
// rendering or saving out to PDF data. Their inclusion can be restored if
|
||||
// another call makes them active again.
|
||||
//
|
||||
// Virtual to support testing.
|
||||
virtual void UpdateShapeActive(int page_index,
|
||||
InkModeledShapeId id,
|
||||
bool active);
|
||||
|
||||
const std::map<InkModeledShapeId, FPDF_PAGEOBJECT>&
|
||||
ink_modeled_shape_map_for_testing() const {
|
||||
return ink_modeled_shape_map_;
|
||||
|
@ -2063,9 +2063,9 @@ TEST_P(PDFiumEngineInkTest, LoadV2InkPathsForPage) {
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(All, PDFiumEngineInkTest, testing::Bool());
|
||||
|
||||
using PDFiumEngineInkStrokesTest = PDFiumTestBase;
|
||||
using PDFiumEngineInkDrawTest = PDFiumTestBase;
|
||||
|
||||
TEST_P(PDFiumEngineInkStrokesTest, NoStrokeData) {
|
||||
TEST_P(PDFiumEngineInkDrawTest, NoStrokeData) {
|
||||
NiceMock<MockTestClient> client;
|
||||
std::unique_ptr<PDFiumEngine> engine =
|
||||
InitializeEngine(&client, FILE_PATH_LITERAL("blank.pdf"));
|
||||
@ -2076,7 +2076,7 @@ TEST_P(PDFiumEngineInkStrokesTest, NoStrokeData) {
|
||||
0);
|
||||
}
|
||||
|
||||
TEST_P(PDFiumEngineInkStrokesTest, StrokeData) {
|
||||
TEST_P(PDFiumEngineInkDrawTest, StrokeData) {
|
||||
NiceMock<MockTestClient> client;
|
||||
std::unique_ptr<PDFiumEngine> engine =
|
||||
InitializeEngine(&client, FILE_PATH_LITERAL("blank.pdf"));
|
||||
@ -2164,11 +2164,64 @@ TEST_P(PDFiumEngineInkStrokesTest, StrokeData) {
|
||||
2);
|
||||
}
|
||||
|
||||
TEST_P(PDFiumEngineInkDrawTest, LoadedV2InkPathsAndUpdateShapeActive) {
|
||||
NiceMock<MockTestClient> client;
|
||||
std::unique_ptr<PDFiumEngine> engine =
|
||||
InitializeEngine(&client, FILE_PATH_LITERAL("ink_v2.pdf"));
|
||||
ASSERT_TRUE(engine);
|
||||
ASSERT_EQ(1, engine->GetNumberOfPages());
|
||||
|
||||
// Check the initial loaded PDF.
|
||||
constexpr int kPageIndex = 0;
|
||||
constexpr gfx::Size kPageSizeInPoints(200, 200);
|
||||
const base::FilePath kInkV2PngPath = GetInkTestDataFilePath("ink_v2.png");
|
||||
PDFiumPage& page = GetPDFiumPageForTest(*engine, kPageIndex);
|
||||
CheckPdfRendering(page.GetPage(), kPageSizeInPoints, kInkV2PngPath);
|
||||
EXPECT_EQ(GetPdfMarkObjCountForTesting(engine->doc(),
|
||||
kInkAnnotationIdentifierKeyV2),
|
||||
1);
|
||||
|
||||
// Check the LoadV2InkPathsForPage() call does not change the rendering.
|
||||
std::map<InkModeledShapeId, ink::ModeledShape> ink_shapes =
|
||||
engine->LoadV2InkPathsForPage(kPageIndex);
|
||||
ASSERT_EQ(1u, ink_shapes.size());
|
||||
CheckPdfRendering(page.GetPage(), kPageSizeInPoints, kInkV2PngPath);
|
||||
EXPECT_EQ(GetPdfMarkObjCountForTesting(engine->doc(),
|
||||
kInkAnnotationIdentifierKeyV2),
|
||||
1);
|
||||
|
||||
// Erase the shape and check the rendering. Also check the save version.
|
||||
const auto ink_shapes_it = ink_shapes.begin();
|
||||
const InkModeledShapeId& shape_id = ink_shapes_it->first;
|
||||
engine->UpdateShapeActive(kPageIndex, shape_id, /*active=*/false);
|
||||
const base::FilePath kBlankPngPath(FILE_PATH_LITERAL("blank.png"));
|
||||
CheckPdfRendering(page.GetPage(), kPageSizeInPoints, kBlankPngPath);
|
||||
std::vector<uint8_t> saved_pdf_data = engine->GetSaveData();
|
||||
ASSERT_FALSE(saved_pdf_data.empty());
|
||||
CheckPdfRendering(saved_pdf_data, kPageIndex, kPageSizeInPoints,
|
||||
kBlankPngPath);
|
||||
EXPECT_EQ(GetPdfMarkObjCountForTesting(engine->doc(),
|
||||
kInkAnnotationIdentifierKeyV2),
|
||||
0);
|
||||
|
||||
// Undo the erasure and check the rendering.
|
||||
engine->UpdateShapeActive(kPageIndex, shape_id, /*active=*/true);
|
||||
CheckPdfRendering(page.GetPage(), kPageSizeInPoints, kInkV2PngPath);
|
||||
#if 0
|
||||
// TODO(thestig): Figure out why this crashes and re-enable.
|
||||
saved_pdf_data = engine->GetSaveData();
|
||||
ASSERT_FALSE(saved_pdf_data.empty());
|
||||
CheckPdfRendering(saved_pdf_data, kPageIndex, kPageSizeInPoints,
|
||||
kInkV2PngPath);
|
||||
EXPECT_EQ(GetPdfMarkObjCountForTesting(engine->doc(),
|
||||
kInkAnnotationIdentifierKeyV2),
|
||||
1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Don't be concerned about any slight rendering differences in AGG vs. Skia,
|
||||
// covering one of these is sufficient for checking how data is written out.
|
||||
INSTANTIATE_TEST_SUITE_P(All,
|
||||
PDFiumEngineInkStrokesTest,
|
||||
testing::Values(false));
|
||||
INSTANTIATE_TEST_SUITE_P(All, PDFiumEngineInkDrawTest, testing::Values(false));
|
||||
|
||||
#endif // BUILDFLAG(ENABLE_PDF_INK2)
|
||||
|
||||
|
BIN
pdf/test/data/ink/ink_v2.png
Normal file
BIN
pdf/test/data/ink/ink_v2.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1.6 KiB |
@ -111,6 +111,11 @@ class TestPDFiumEngine : public PDFiumEngine {
|
||||
LoadV2InkPathsForPage,
|
||||
(int),
|
||||
(override));
|
||||
|
||||
MOCK_METHOD(void,
|
||||
UpdateShapeActive,
|
||||
(int, InkModeledShapeId, bool),
|
||||
(override));
|
||||
#endif // BUILDFLAG(ENABLE_PDF_INK2)
|
||||
|
||||
std::vector<uint8_t> GetSaveData() override;
|
||||
|
Reference in New Issue
Block a user