diff options
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 66 | ||||
-rw-r--r-- | fpdfsdk/fpdfannot_embeddertest.cpp | 89 | ||||
-rw-r--r-- | public/fpdf_annot.h | 14 |
3 files changed, 71 insertions, 98 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp index fee99c844b..5c4aae2075 100644 --- a/fpdfsdk/fpdfannot.cpp +++ b/fpdfsdk/fpdfannot.cpp @@ -601,45 +601,18 @@ FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot, if (!pAnnotDict) return false; - // If the annotation's appearance stream is defined, then retrieve the - // quadpoints defined by the "BBox" entry in the AP dictionary, since its - // "BBox" entry comes from annotation dictionary's "QuadPoints" entry, but - // takes priority over "QuadPoints" when rendering. Otherwise, retrieve - // the "Quadpoints" entry from the annotation dictionary. - CPDF_Array* pArray; - CPDF_Stream* pStream = - FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal); - if (pStream) { - pArray = pStream->GetDict()->GetArrayFor("BBox"); - if (!pArray) - return false; - - // Convert the BBox array into quadpoint coordinates. BBox array follows the - // order of a rectangle array: (left, bottom, right, up); and quadpoints - // follows the following order: (top-left vertex, top-right vertex, bottom- - // left vertex, bottom-right vertex). - quadPoints->x1 = pArray->GetNumberAt(0); - quadPoints->y1 = pArray->GetNumberAt(3); - quadPoints->x2 = pArray->GetNumberAt(2); - quadPoints->y2 = pArray->GetNumberAt(3); - quadPoints->x3 = pArray->GetNumberAt(0); - quadPoints->y3 = pArray->GetNumberAt(1); - quadPoints->x4 = pArray->GetNumberAt(2); - quadPoints->y4 = pArray->GetNumberAt(1); - } else { - pArray = pAnnotDict->GetArrayFor("QuadPoints"); - if (!pArray) - return false; - - quadPoints->x1 = pArray->GetNumberAt(0); - quadPoints->y1 = pArray->GetNumberAt(1); - quadPoints->x2 = pArray->GetNumberAt(2); - quadPoints->y2 = pArray->GetNumberAt(3); - quadPoints->x3 = pArray->GetNumberAt(4); - quadPoints->y3 = pArray->GetNumberAt(5); - quadPoints->x4 = pArray->GetNumberAt(6); - quadPoints->y4 = pArray->GetNumberAt(7); - } + CPDF_Array* pArray = pAnnotDict->GetArrayFor("QuadPoints"); + if (!pArray) + return false; + + quadPoints->x1 = pArray->GetNumberAt(0); + quadPoints->y1 = pArray->GetNumberAt(1); + quadPoints->x2 = pArray->GetNumberAt(2); + quadPoints->y2 = pArray->GetNumberAt(3); + quadPoints->x3 = pArray->GetNumberAt(4); + quadPoints->y3 = pArray->GetNumberAt(5); + quadPoints->x4 = pArray->GetNumberAt(6); + quadPoints->y4 = pArray->GetNumberAt(7); return true; } @@ -683,20 +656,7 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetRect(FPDF_ANNOTATION annot, if (!pAnnotDict) return false; - // If the annotation's appearance stream is defined and the annotation is of - // a type that does not have quadpoints, then retrieve the rectangle defined - // by the "BBox" entry in the AP dictionary, since its "BBox" entry comes - // from annotation dictionary's "Rect" entry, but takes priority over "Rect" - // when rendering. Otherwise, retrieve the "Rect" entry from the annotation - // dictionary. - CFX_FloatRect rt; - CPDF_Stream* pStream = - FPDFDOC_GetAnnotAP(pAnnotDict, CPDF_Annot::AppearanceMode::Normal); - if (!pStream || FPDFAnnot_HasAttachmentPoints(annot)) - rt = pAnnotDict->GetRectFor("Rect"); - else - rt = pStream->GetDict()->GetRectFor("BBox"); - + CFX_FloatRect rt = pAnnotDict->GetRectFor("Rect"); rect->left = rt.left; rect->bottom = rt.bottom; rect->right = rt.right; diff --git a/fpdfsdk/fpdfannot_embeddertest.cpp b/fpdfsdk/fpdfannot_embeddertest.cpp index 32edd7a503..4aca839226 100644 --- a/fpdfsdk/fpdfannot_embeddertest.cpp +++ b/fpdfsdk/fpdfannot_embeddertest.cpp @@ -317,12 +317,31 @@ TEST_F(FPDFAnnotEmbeddertest, AddAndSaveUnderlineAnnotation) { } TEST_F(FPDFAnnotEmbeddertest, ModifyRectQuadpointsWithAP) { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + const char md5_original[] = "63af8432fab95a67cdebb7cd0e514941"; + const char md5_modified_highlight[] = "aec26075011349dec9bace891856b5f2"; + const char md5_modified_square[] = "057f57a32be95975775e5ec513fdcb56"; +#elif _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ + const char md5_original[] = "ade6762a70e85605546ce067e7d2148f"; + const char md5_modified_highlight[] = "fb8440ed1a070b53ed5598ce7451cfad"; + const char md5_modified_square[] = "7925f6726b343393f258e8b4e93dd65d"; +#else + const char md5_original[] = "ade6762a70e85605546ce067e7d2148f"; + const char md5_modified_highlight[] = "fb8440ed1a070b53ed5598ce7451cfad"; + const char md5_modified_square[] = "7925f6726b343393f258e8b4e93dd65d"; +#endif + // Open a file with four annotations and load its first page. ASSERT_TRUE(OpenDocument("annotation_highlight_square_with_ap.pdf")); FPDF_PAGE page = FPDF_LoadPage(document(), 0); ASSERT_TRUE(page); EXPECT_EQ(4, FPDFPage_GetAnnotCount(page)); + // Check that the original file renders correctly. + FPDF_BITMAP bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 612, 792, md5_original); + FPDFBitmap_Destroy(bitmap); + // Retrieve the highlight annotation which has its AP stream already defined. FPDF_ANNOTATION annot = FPDFPage_GetAnnot(page, 0); ASSERT_TRUE(annot); @@ -332,41 +351,33 @@ TEST_F(FPDFAnnotEmbeddertest, ModifyRectQuadpointsWithAP) { EXPECT_FALSE( FPDFAnnot_SetColor(annot, FPDFANNOT_COLORTYPE_Color, 51, 102, 153, 204)); - // Check that when getting the attachment points, bounding box points are - // returned since this is a markup annotation with AP defined. + // Verify its attachment points. FS_QUADPOINTSF quadpoints; ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, &quadpoints)); - EXPECT_NEAR(0.f, quadpoints.x1, 0.001f); - EXPECT_NEAR(16.9955f, quadpoints.y1, 0.001f); - EXPECT_NEAR(68.5953f, quadpoints.x4, 0.001f); - EXPECT_NEAR(0.f, quadpoints.y4, 0.001f); - - // Check that when new attachment points define a smaller bounding box, the - // bounding box does not get updated. - quadpoints.x1 = 1.0f; - quadpoints.x3 = 1.0f; + EXPECT_NEAR(72.0000f, quadpoints.x1, 0.001f); + EXPECT_NEAR(720.792f, quadpoints.y1, 0.001f); + EXPECT_NEAR(132.055f, quadpoints.x4, 0.001f); + EXPECT_NEAR(704.796f, quadpoints.y4, 0.001f); + + // Check that updating the attachment points would succeed. + quadpoints.x1 -= 50.f; + quadpoints.x2 -= 50.f; + quadpoints.x3 -= 50.f; + quadpoints.x4 -= 50.f; ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, &quadpoints)); FS_QUADPOINTSF new_quadpoints; ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, &new_quadpoints)); - EXPECT_NE(quadpoints.x1, new_quadpoints.x1); - - // Check that the bounding box gets updated successfully when valid attachment - // points are set. - quadpoints.x1 = 0.f; - quadpoints.y1 = 721.792f; - quadpoints.x2 = 133.055f; - quadpoints.y2 = 721.792f; - quadpoints.x3 = 0.f; - quadpoints.x4 = 133.055f; - ASSERT_TRUE(FPDFAnnot_SetAttachmentPoints(annot, &quadpoints)); - ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, &new_quadpoints)); EXPECT_EQ(quadpoints.x1, new_quadpoints.x1); EXPECT_EQ(quadpoints.y1, new_quadpoints.y1); EXPECT_EQ(quadpoints.x4, new_quadpoints.x4); EXPECT_EQ(quadpoints.y4, new_quadpoints.y4); - // Check that when getting the annotation rectangle, rectangle points are - // returned, but not bounding box points. + // Check that updating quadpoints does not change the annotation's position. + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 612, 792, md5_original); + FPDFBitmap_Destroy(bitmap); + + // Verify its annotation rectangle. FS_RECTF rect; ASSERT_TRUE(FPDFAnnot_GetRect(annot, &rect)); EXPECT_NEAR(67.7299f, rect.left, 0.001f); @@ -374,34 +385,38 @@ TEST_F(FPDFAnnotEmbeddertest, ModifyRectQuadpointsWithAP) { EXPECT_NEAR(136.325f, rect.right, 0.001f); EXPECT_NEAR(721.292f, rect.top, 0.001f); - // Check that the rectangle gets updated successfully when a valid rectangle - // is set, and that the bounding box is not modified. - rect.left = 0.f; - rect.bottom = 0.f; - rect.right = 134.055f; - rect.top = 722.792f; + // Check that updating the rectangle would succeed. + rect.left -= 60.f; + rect.right -= 60.f; ASSERT_TRUE(FPDFAnnot_SetRect(annot, &rect)); FS_RECTF new_rect; ASSERT_TRUE(FPDFAnnot_GetRect(annot, &new_rect)); EXPECT_EQ(rect.right, new_rect.right); - ASSERT_TRUE(FPDFAnnot_GetAttachmentPoints(annot, &new_quadpoints)); - EXPECT_NE(rect.right, new_quadpoints.x2); - FPDFPage_CloseAnnot(annot); + // Check that updating the rectangle changes the annotation's position. + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 612, 792, md5_modified_highlight); + FPDFBitmap_Destroy(bitmap); + // Retrieve the square annotation which has its AP stream already defined. annot = FPDFPage_GetAnnot(page, 2); ASSERT_TRUE(annot); EXPECT_EQ(FPDF_ANNOT_SQUARE, FPDFAnnot_GetSubtype(annot)); - // Check that the rectangle and the bounding box get updated successfully when - // a valid rectangle is set, since this is not a markup annotation. + // Check that updating the rectangle would succeed. ASSERT_TRUE(FPDFAnnot_GetRect(annot, &rect)); - rect.right += 1.f; + rect.left += 70.f; + rect.right += 70.f; ASSERT_TRUE(FPDFAnnot_SetRect(annot, &rect)); ASSERT_TRUE(FPDFAnnot_GetRect(annot, &new_rect)); EXPECT_EQ(rect.right, new_rect.right); + // Check that updating the rectangle changes the square annotation's position. + bitmap = RenderPageWithFlags(page, form_handle_, FPDF_ANNOT); + CompareBitmap(bitmap, 612, 792, md5_modified_square); + FPDFBitmap_Destroy(bitmap); + FPDFPage_CloseAnnot(annot); UnloadPage(page); } diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index 1de99453fc..6cd06dd9db 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h @@ -283,7 +283,8 @@ FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot); // Experimental API. // Set the attachment points (i.e. quadpoints) of an annotation. If the // annotation's appearance stream is defined and this annotation is of a type -// with quadpoints, then update the bounding box too. +// with quadpoints, then update the bounding box too if the new quadpoints +// define a bigger one. // // annot - handle to an annotation. // quadPoints - the quadpoints to be set. @@ -294,9 +295,7 @@ FPDFAnnot_SetAttachmentPoints(FPDF_ANNOTATION annot, const FS_QUADPOINTSF* quadPoints); // Experimental API. -// Get the attachment points (i.e. quadpoints) of an annotation. If the -// annotation's appearance stream is defined and this annotation is of a type -// with quadpoints, then return the bounding box it specifies instead. +// Get the attachment points (i.e. quadpoints) of an annotation. // // annot - handle to an annotation. // quadPoints - receives the quadpoints; must not be NULL. @@ -309,7 +308,8 @@ FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot, // Experimental API. // Set the annotation rectangle defining the location of the annotation. If the // annotation's appearance stream is defined and this annotation is of a type -// without quadpoints, then update the bounding box too. +// without quadpoints, then update the bounding box too if the new rectangle +// defines a bigger one. // // annot - handle to an annotation. // rect - the annotation rectangle to be set. @@ -319,9 +319,7 @@ FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_SetRect(FPDF_ANNOTATION annot, const FS_RECTF* rect); // Experimental API. -// Get the annotation rectangle defining the location of the annotation. If the -// annotation's appearance stream is defined and this annotation is of a type -// without quadpoints, then return the bounding box it specifies instead. +// Get the annotation rectangle defining the location of the annotation. // // annot - handle to an annotation. // rect - receives the rectangle; must not be NULL. |