From c90adc58b97200d20b0532bde95b79dcba00637f Mon Sep 17 00:00:00 2001 From: Henrique Nakashima Date: Tue, 27 Mar 2018 16:26:44 +0000 Subject: Open FPDF_PAGEOBJECTMARK API. Initially it contains: - FPDFPageObj_CountMarks - FPDFPageObj_GetMark - FPDFPageObjMark_GetName This allows reading the content marks from a page object. Bug: pdfium:1037 Change-Id: I3d7554b71f938778890fdb44088e0d45dd2718d9 Reviewed-on: https://pdfium-review.googlesource.com/28710 Commit-Queue: Henrique Nakashima Reviewed-by: Lei Zhang --- fpdfsdk/fpdfedit_embeddertest.cpp | 91 +++++++++++++++++- fpdfsdk/fpdfeditpage.cpp | 41 ++++++++ fpdfsdk/fpdfview.cpp | 6 ++ fpdfsdk/fpdfview_c_api_test.c | 3 + fpdfsdk/fsdk_define.h | 4 + public/fpdf_edit.h | 34 +++++++ public/fpdfview.h | 1 + testing/resources/text_in_page_marked.in | 136 ++++++++++++++++++++++++++ testing/resources/text_in_page_marked.pdf | 152 ++++++++++++++++++++++++++++++ 9 files changed, 464 insertions(+), 4 deletions(-) create mode 100644 testing/resources/text_in_page_marked.in create mode 100644 testing/resources/text_in_page_marked.pdf diff --git a/fpdfsdk/fpdfedit_embeddertest.cpp b/fpdfsdk/fpdfedit_embeddertest.cpp index ec403c74b3..65e790cc32 100644 --- a/fpdfsdk/fpdfedit_embeddertest.cpp +++ b/fpdfsdk/fpdfedit_embeddertest.cpp @@ -387,7 +387,8 @@ TEST_F(FPDFEditEmbeddertest, RemovePageObject) { FPDF_PAGE page = LoadPage(0); ASSERT_TRUE(page); -// Show how the original file looks like. + // Show what the original file looks like. + { #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ const char kOriginalMD5[] = "b90475ca64d1348c3bf5e2b77ad9187a"; #elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ @@ -395,7 +396,6 @@ TEST_F(FPDFEditEmbeddertest, RemovePageObject) { #else const char kOriginalMD5[] = "2baa4c0e1758deba1b9c908e1fbd04ed"; #endif - { std::unique_ptr page_bitmap = RenderPageWithFlags(page, nullptr, 0); CompareBitmap(page_bitmap.get(), 200, 200, kOriginalMD5); @@ -407,7 +407,8 @@ TEST_F(FPDFEditEmbeddertest, RemovePageObject) { ASSERT_TRUE(page_object); EXPECT_TRUE(FPDFPage_RemoveObject(page, page_object)); -// Verify the "Hello, world!" text is gone. + // Verify the "Hello, world!" text is gone. + { #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ const char kRemovedMD5[] = "af760c4702467cb1492a57fb8215efaa"; #elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ @@ -415,7 +416,6 @@ TEST_F(FPDFEditEmbeddertest, RemovePageObject) { #else const char kRemovedMD5[] = "b76df015fe88009c3c342395df96abf1"; #endif - { std::unique_ptr page_bitmap = RenderPageWithFlags(page, nullptr, 0); CompareBitmap(page_bitmap.get(), 200, 200, kRemovedMD5); @@ -426,6 +426,89 @@ TEST_F(FPDFEditEmbeddertest, RemovePageObject) { FPDFPageObj_Destroy(page_object); } +TEST_F(FPDFEditEmbeddertest, RemoveMarkedObjectsPrime) { + // Load document with some text. + EXPECT_TRUE(OpenDocument("text_in_page_marked.pdf")); + FPDF_PAGE page = LoadPage(0); + ASSERT_TRUE(page); + + // Show what the original file looks like. + { +#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ + const char kOriginalMD5[] = "5a5eb63cb21cc15084fea1f14284b8df"; +#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + const char kOriginalMD5[] = "587c507a40f613f9c530b2ce2d58d655"; +#else + const char kOriginalMD5[] = "2edc6e70d54889aa0c0b7bdf3e168f86"; +#endif + std::unique_ptr page_bitmap = + RenderPageWithFlags(page, nullptr, 0); + CompareBitmap(page_bitmap.get(), 200, 200, kOriginalMD5); + } + + // Iterate over all objects, counting the number of times each content mark + // name appears. + int object_count = FPDFPage_CountObjects(page); + ASSERT_EQ(19, object_count); + + unsigned long prime_count = 0; + unsigned long square_count = 0; + unsigned long greater_than_ten_count = 0; + std::vector primes; + for (int i = 0; i < object_count; ++i) { + FPDF_PAGEOBJECT page_object = FPDFPage_GetObject(page, i); + + int mark_count = FPDFPageObj_CountMarks(page_object); + for (int j = 0; j < mark_count; ++j) { + FPDF_PAGEOBJECTMARK mark = FPDFPageObj_GetMark(page_object, j); + + char buffer[256]; + ASSERT_GT(FPDFPageObjMark_GetName(mark, buffer, 256), 0u); + std::wstring name = + GetPlatformWString(reinterpret_cast(buffer)); + if (name == L"Prime") { + prime_count++; + primes.push_back(page_object); + } else if (name == L"Square") { + square_count++; + } else if (name == L"GreaterThanTen") { + greater_than_ten_count++; + } else { + FAIL(); + } + } + } + + // Expect certain number of tagged objects. The test file contains strings + // from 1 to 19. + EXPECT_EQ(8u, prime_count); + EXPECT_EQ(4u, square_count); + EXPECT_EQ(9u, greater_than_ten_count); + + // Remove all objects marked with "Prime". + for (FPDF_PAGEOBJECT page_object : primes) { + EXPECT_TRUE(FPDFPage_RemoveObject(page, page_object)); + FPDFPageObj_Destroy(page_object); + } + + EXPECT_EQ(11, FPDFPage_CountObjects(page)); + + { +#if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_ + const char kNonPrimesMD5[] = "57e76dc7375d896704f0fd6d6d1b9e65"; +#elif _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_ + const char kNonPrimesMD5[] = "4d906b57fba36c70c600cf50d60f508c"; +#else + const char kNonPrimesMD5[] = "33d9c45bec41ead92a295e252f6b7922"; +#endif + std::unique_ptr page_bitmap = + RenderPageWithFlags(page, nullptr, 0); + CompareBitmap(page_bitmap.get(), 200, 200, kNonPrimesMD5); + } + + UnloadPage(page); +} + TEST_F(FPDFEditEmbeddertest, AddAndRemovePaths) { // Start with a blank page. FPDF_PAGE page = FPDFPage_New(CreateNewDocument(), 0, 612, 792); diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp index 902aab4dd1..d0724d5359 100644 --- a/fpdfsdk/fpdfeditpage.cpp +++ b/fpdfsdk/fpdfeditpage.cpp @@ -222,6 +222,47 @@ FPDF_EXPORT void FPDF_CALLCONV FPDFPageObj_Destroy(FPDF_PAGEOBJECT page_obj) { delete CPDFPageObjectFromFPDFPageObject(page_obj); } +FPDF_EXPORT int FPDF_CALLCONV +FPDFPageObj_CountMarks(FPDF_PAGEOBJECT page_object) { + if (!page_object) + return -1; + + const auto& mark = + CPDFPageObjectFromFPDFPageObject(page_object)->m_ContentMark; + return mark.HasRef() ? mark.CountItems() : 0; +} + +FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV +FPDFPageObj_GetMark(FPDF_PAGEOBJECT page_object, unsigned long index) { + if (!page_object) + return nullptr; + + const auto& mark = + CPDFPageObjectFromFPDFPageObject(page_object)->m_ContentMark; + if (!mark.HasRef()) + return nullptr; + + if (index >= mark.CountItems()) + return nullptr; + + return static_cast(&mark.GetItem(index)); +} + +FPDF_EXPORT unsigned long FPDF_CALLCONV +FPDFPageObjMark_GetName(FPDF_PAGEOBJECTMARK mark, + void* buffer, + unsigned long buflen) { + if (!mark) + return 0; + + const CPDF_ContentMarkItem* pMarkItem = + CPDFContentMarkItemFromFPDFPageObjectMark(mark); + + return Utf16EncodeMaybeCopyAndReturnLength( + WideString::FromUTF8(pMarkItem->GetName().AsStringView()), buffer, + buflen); +} + FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject) { if (!pageObject) diff --git a/fpdfsdk/fpdfview.cpp b/fpdfsdk/fpdfview.cpp index e890aa0090..a9078102e3 100644 --- a/fpdfsdk/fpdfview.cpp +++ b/fpdfsdk/fpdfview.cpp @@ -12,6 +12,7 @@ #include "core/fpdfapi/cpdf_modulemgr.h" #include "core/fpdfapi/cpdf_pagerendercontext.h" +#include "core/fpdfapi/page/cpdf_contentmarkitem.h" #include "core/fpdfapi/page/cpdf_image.h" #include "core/fpdfapi/page/cpdf_imageobject.h" #include "core/fpdfapi/page/cpdf_page.h" @@ -345,6 +346,11 @@ CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object) { return static_cast(page_object); } +const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark( + FPDF_PAGEOBJECTMARK mark) { + return static_cast(mark); +} + CPDF_Object* CPDFObjectFromFPDFAttachment(FPDF_ATTACHMENT attachment) { return static_cast(attachment); } diff --git a/fpdfsdk/fpdfview_c_api_test.c b/fpdfsdk/fpdfview_c_api_test.c index 201fd90669..a0bcc13ff3 100644 --- a/fpdfsdk/fpdfview_c_api_test.c +++ b/fpdfsdk/fpdfview_c_api_test.c @@ -144,6 +144,9 @@ int CheckPDFiumCApi() { CHK(FPDFPageObj_Transform); CHK(FPDFPage_TransformAnnots); CHK(FPDFPageObj_NewImageObj); + CHK(FPDFPageObj_CountMarks); + CHK(FPDFPageObj_GetMark); + CHK(FPDFPageObjMark_GetName); CHK(FPDFImageObj_LoadJpegFile); CHK(FPDFImageObj_LoadJpegFileInline); CHK(FPDFImageObj_SetMatrix); diff --git a/fpdfsdk/fsdk_define.h b/fpdfsdk/fsdk_define.h index acd8437169..94497bb237 100644 --- a/fpdfsdk/fsdk_define.h +++ b/fpdfsdk/fsdk_define.h @@ -23,6 +23,7 @@ #endif class CPDF_Annot; +class CPDF_ContentMarkItem; class CPDF_Page; class CPDF_PageObject; class CPDF_PageRenderContext; @@ -70,6 +71,9 @@ CPDF_PathObject* CPDFPathObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); CPDF_PageObject* CPDFPageObjectFromFPDFPageObject(FPDF_PAGEOBJECT page_object); +const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark( + FPDF_PAGEOBJECTMARK mark); + CPDF_Object* CPDFObjectFromFPDFAttachment(FPDF_ATTACHMENT attachment); ByteString CFXByteStringFromFPDFWideString(FPDF_WIDESTRING wide_string); diff --git a/public/fpdf_edit.h b/public/fpdf_edit.h index 1e84e8f7ff..7c37b83aa9 100644 --- a/public/fpdf_edit.h +++ b/public/fpdf_edit.h @@ -281,6 +281,40 @@ FPDF_EXPORT void FPDF_CALLCONV FPDFPage_TransformAnnots(FPDF_PAGE page, FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV FPDFPageObj_NewImageObj(FPDF_DOCUMENT document); +// Get number of content marks in |page_object|. +// +// page_object - handle to a page object. +// +// Returns the number of content marks in |page_object|, or -1 in case of +// failure. +FPDF_EXPORT int FPDF_CALLCONV +FPDFPageObj_CountMarks(FPDF_PAGEOBJECT page_object); + +// Get content mark in |page_object| at |index|. +// +// page_object - handle to a page object. +// index - the index of a page object. +// +// Returns the handle to the content mark, or NULL on failure. The handle is +// still owned by the library, and it should not be freed directly. It becomes +// invalid if the page object is destroyed, either directly or indirectly by +// unloading the page. +FPDF_EXPORT FPDF_PAGEOBJECTMARK FPDF_CALLCONV +FPDFPageObj_GetMark(FPDF_PAGEOBJECT page_object, unsigned long index); + +// Get name of a content mark. |buffer| is only modified if |buflen| is longer +// than the length of the name. +// +// mark - handle to a content mark. +// buffer - buffer for holding the returned name in UTF16-LE. +// buflen - length of the buffer. +// +// Returns the length of the name. +FPDF_EXPORT unsigned long FPDF_CALLCONV +FPDFPageObjMark_GetName(FPDF_PAGEOBJECTMARK mark, + void* buffer, + unsigned long buflen); + // Load an image from a JPEG image file and then set it into |image_object|. // // pages - pointer to the start of all loaded pages, may be NULL. diff --git a/public/fpdfview.h b/public/fpdfview.h index ffa4678347..de7fbe4663 100644 --- a/public/fpdfview.h +++ b/public/fpdfview.h @@ -46,6 +46,7 @@ typedef void* FPDF_LINK; typedef void* FPDF_PAGE; typedef void* FPDF_PAGELINK; typedef void* FPDF_PAGEOBJECT; // Page object(text, path, etc) +typedef void const* FPDF_PAGEOBJECTMARK; typedef void* FPDF_PAGERANGE; typedef void* FPDF_RECORDER; typedef void* FPDF_SCHHANDLE; diff --git a/testing/resources/text_in_page_marked.in b/testing/resources/text_in_page_marked.in new file mode 100644 index 0000000000..e2387a440c --- /dev/null +++ b/testing/resources/text_in_page_marked.in @@ -0,0 +1,136 @@ +{{header}} +{{object 1 0}} +<< /Pages 2 0 R /Type /Catalog >> +endobj +{{object 2 0}} +<< /Count 1 /Kids [ 3 0 R ] /MediaBox [ 0 0 200 200 ] /Type /Pages >> +endobj +{{object 3 0}} +<< + /Contents 4 0 R + /Parent 2 0 R + /Resources << + /ExtGState << /FXE1 5 0 R /FXE2 6 0 R >> + /Font << /F1 7 0 R /F2 8 0 R /FXF1 9 0 R /FXF2 10 0 R >> + >> + /Type /Page +>> +endobj +{{object 4 0}} +[ 12 0 R ] +endobj +{{object 5 0}} +<< /BM /Normal /CA 1 /ca 1 >> +endobj +{{object 6 0}} +<< /ca 0.705882 >> +endobj +{{object 7 0}} +<< /BaseFont /Times-Roman /Subtype /Type1 /Type /Font >> +endobj +{{object 8 0}} +<< /BaseFont /Helvetica /Subtype /Type1 /Type /Font >> +endobj +{{object 9 0}} +<< /BaseFont /Courier-Bold /Subtype /Type1 /Type /Font >> +endobj +{{object 10 0}} +<< /BaseFont /Times-Bold /Subtype /Type1 /Type /Font >> +endobj +{{object 12 0}} +<< {{streamlen}} >> +stream +q +0 0 0 RG 0 0 0 rg 1 w 0 J 0 j +/FXE1 gs +/Square <> BDC +q 0 0 0 rg /FXE2 gs BT 1 0 0 1 120 100 Tm /FXF1 9 Tf (Test 1) Tj ET Q +EMC +/Prime BMC +q 0 0 0.0509804 rg /FXE2 gs +BT 0.995597 -0.341789 0.341789 0.995597 119.912 93.1642 +Tm /FXF2 9 Tf (Test 2) Tj ET Q +q 0 0 0.101961 rg /FXE2 gs +BT 0.872208 -0.678867 0.678867 0.872208 117.444 86.4227 +Tm /FXF1 9 Tf (Test 3) Tj ET Q +EMC +/Square <> BDC +q 0 0 0.156863 rg /FXE2 gs +BT 0.633308 -0.969351 0.969351 0.633308 112.666 80.613 +Tm /FXF2 9 Tf (Test 4) Tj ET Q +EMC +/Prime BMC +q 0 0 0.207843 rg /FXE2 gs +BT 0.297167 -1.17348 1.17348 0.297167 105.943 76.5303 +Tm /FXF1 9 Tf (Test 5) Tj ET Q +EMC +q 0 0 0.262745 rg /FXE2 gs +BT -0.104311 -1.25884 1.25884 -0.104311 97.9138 74.8231 +Tm /FXF2 9 Tf (Test 6) Tj ET Q +/Prime BMC +q 0 0 0.313726 rg /FXE2 gs +BT -0.528547 -1.20496 1.20496 -0.528547 89.4291 75.9007 +Tm /FXF1 9 Tf (Test 7) Tj ET Q +EMC +q 0 0 0.364706 rg /FXE2 gs +BT -0.926806 -1.00678 1.00678 -0.926806 81.4639 79.8644 +Tm /FXF2 9 Tf (Test 8) Tj ET Q +/Square <> BDC +q 0 0 0.419608 rg /FXE2 gs +BT -1.24978 -0.676346 0.676346 -1.24978 75.0044 86.4731 +Tm /FXF1 9 Tf (Test 9) Tj ET Q +EMC +q 0 0 0.470588 rg /FXE2 gs +BT -1.45359 -0.24256 0.24256 -1.45359 70.9283 95.1488 +Tm /FXF2 9 Tf (Test 10) Tj ET Q +/GreaterThanTen BMC +/Prime BMC +q 0 0 0.52549 rg /FXE2 gs +BT -1.5055 0.251223 -0.251223 -1.5055 69.89 105.024 +Tm /FXF1 9 Tf (Test 11) Tj ET Q +EMC +q 0 0 0.576471 rg /FXE2 gs +BT -1.38864 0.751496 -0.751496 -1.38864 72.2271 115.03 +Tm /FXF2 9 Tf (Test 12) Tj ET Q +/Prime BMC +q 0 0 0.631373 rg /FXE2 gs +BT -1.10504 1.20039 -1.20039 -1.10504 77.8992 124.008 +Tm /FXF1 9 Tf (Test 13) Tj ET Q +EMC +q 0 0 0.682353 rg /FXE2 gs +BT -0.67654 1.54236 -1.54236 -0.67654 86.4692 130.847 +Tm /FXF2 9 Tf (Test 14) Tj ET Q +q 0 0 0.733333 rg /FXE2 gs +BT -0.143427 1.73091 -1.73091 -0.143427 97.1315 134.618 +Tm /FXF1 9 Tf (Test 15) Tj ET Q +/Square <> BDC +q 0 0 0.788235 rg /FXE2 gs +BT 0.43929 1.73472 -1.73472 0.43929 108.786 134.694 +Tm /FXF2 9 Tf (Test 16) Tj ET Q +EMC +/Prime BMC +q 0 0 0.839216 rg /FXE2 gs +BT 1.00754 1.54215 -1.54215 1.00754 120.151 130.843 +Tm /FXF1 9 Tf (Test 17) Tj ET Q +EMC +q 0 0 0.894118 rg /FXE2 gs +BT 1.49521 1.16377 -1.16377 1.49521 129.904 123.275 +Tm /FXF2 9 Tf (Test 18) Tj ET Q +/Prime BMC +q 0 0 0.945098 rg /FXE2 gs +BT 1.84185 0.632309 -0.632309 1.84185 136.837 112.646 +Tm /FXF1 9 Tf (Test 19) Tj ET Q +EMC +EMC +Q +endstream +endobj + +{{xref}} +trailer << + /Root 1 0 R + /Size 13 + /ID [] +>> +{{startxref}} +%%EOF diff --git a/testing/resources/text_in_page_marked.pdf b/testing/resources/text_in_page_marked.pdf new file mode 100644 index 0000000000..5f9467f61c --- /dev/null +++ b/testing/resources/text_in_page_marked.pdf @@ -0,0 +1,152 @@ +%PDF-1.7 +% ò¤ô +1 0 obj +<< /Pages 2 0 R /Type /Catalog >> +endobj +2 0 obj +<< /Count 1 /Kids [ 3 0 R ] /MediaBox [ 0 0 200 200 ] /Type /Pages >> +endobj +3 0 obj +<< + /Contents 4 0 R + /Parent 2 0 R + /Resources << + /ExtGState << /FXE1 5 0 R /FXE2 6 0 R >> + /Font << /F1 7 0 R /F2 8 0 R /FXF1 9 0 R /FXF2 10 0 R >> + >> + /Type /Page +>> +endobj +4 0 obj +[ 12 0 R ] +endobj +5 0 obj +<< /BM /Normal /CA 1 /ca 1 >> +endobj +6 0 obj +<< /ca 0.705882 >> +endobj +7 0 obj +<< /BaseFont /Times-Roman /Subtype /Type1 /Type /Font >> +endobj +8 0 obj +<< /BaseFont /Helvetica /Subtype /Type1 /Type /Font >> +endobj +9 0 obj +<< /BaseFont /Courier-Bold /Subtype /Type1 /Type /Font >> +endobj +10 0 obj +<< /BaseFont /Times-Bold /Subtype /Type1 /Type /Font >> +endobj +12 0 obj +<< /Length 2396 >> +stream +q +0 0 0 RG 0 0 0 rg 1 w 0 J 0 j +/FXE1 gs +/Square <> BDC +q 0 0 0 rg /FXE2 gs BT 1 0 0 1 120 100 Tm /FXF1 9 Tf (Test 1) Tj ET Q +EMC +/Prime BMC +q 0 0 0.0509804 rg /FXE2 gs +BT 0.995597 -0.341789 0.341789 0.995597 119.912 93.1642 +Tm /FXF2 9 Tf (Test 2) Tj ET Q +q 0 0 0.101961 rg /FXE2 gs +BT 0.872208 -0.678867 0.678867 0.872208 117.444 86.4227 +Tm /FXF1 9 Tf (Test 3) Tj ET Q +EMC +/Square <> BDC +q 0 0 0.156863 rg /FXE2 gs +BT 0.633308 -0.969351 0.969351 0.633308 112.666 80.613 +Tm /FXF2 9 Tf (Test 4) Tj ET Q +EMC +/Prime BMC +q 0 0 0.207843 rg /FXE2 gs +BT 0.297167 -1.17348 1.17348 0.297167 105.943 76.5303 +Tm /FXF1 9 Tf (Test 5) Tj ET Q +EMC +q 0 0 0.262745 rg /FXE2 gs +BT -0.104311 -1.25884 1.25884 -0.104311 97.9138 74.8231 +Tm /FXF2 9 Tf (Test 6) Tj ET Q +/Prime BMC +q 0 0 0.313726 rg /FXE2 gs +BT -0.528547 -1.20496 1.20496 -0.528547 89.4291 75.9007 +Tm /FXF1 9 Tf (Test 7) Tj ET Q +EMC +q 0 0 0.364706 rg /FXE2 gs +BT -0.926806 -1.00678 1.00678 -0.926806 81.4639 79.8644 +Tm /FXF2 9 Tf (Test 8) Tj ET Q +/Square <> BDC +q 0 0 0.419608 rg /FXE2 gs +BT -1.24978 -0.676346 0.676346 -1.24978 75.0044 86.4731 +Tm /FXF1 9 Tf (Test 9) Tj ET Q +EMC +q 0 0 0.470588 rg /FXE2 gs +BT -1.45359 -0.24256 0.24256 -1.45359 70.9283 95.1488 +Tm /FXF2 9 Tf (Test 10) Tj ET Q +/GreaterThanTen BMC +/Prime BMC +q 0 0 0.52549 rg /FXE2 gs +BT -1.5055 0.251223 -0.251223 -1.5055 69.89 105.024 +Tm /FXF1 9 Tf (Test 11) Tj ET Q +EMC +q 0 0 0.576471 rg /FXE2 gs +BT -1.38864 0.751496 -0.751496 -1.38864 72.2271 115.03 +Tm /FXF2 9 Tf (Test 12) Tj ET Q +/Prime BMC +q 0 0 0.631373 rg /FXE2 gs +BT -1.10504 1.20039 -1.20039 -1.10504 77.8992 124.008 +Tm /FXF1 9 Tf (Test 13) Tj ET Q +EMC +q 0 0 0.682353 rg /FXE2 gs +BT -0.67654 1.54236 -1.54236 -0.67654 86.4692 130.847 +Tm /FXF2 9 Tf (Test 14) Tj ET Q +q 0 0 0.733333 rg /FXE2 gs +BT -0.143427 1.73091 -1.73091 -0.143427 97.1315 134.618 +Tm /FXF1 9 Tf (Test 15) Tj ET Q +/Square <> BDC +q 0 0 0.788235 rg /FXE2 gs +BT 0.43929 1.73472 -1.73472 0.43929 108.786 134.694 +Tm /FXF2 9 Tf (Test 16) Tj ET Q +EMC +/Prime BMC +q 0 0 0.839216 rg /FXE2 gs +BT 1.00754 1.54215 -1.54215 1.00754 120.151 130.843 +Tm /FXF1 9 Tf (Test 17) Tj ET Q +EMC +q 0 0 0.894118 rg /FXE2 gs +BT 1.49521 1.16377 -1.16377 1.49521 129.904 123.275 +Tm /FXF2 9 Tf (Test 18) Tj ET Q +/Prime BMC +q 0 0 0.945098 rg /FXE2 gs +BT 1.84185 0.632309 -0.632309 1.84185 136.837 112.646 +Tm /FXF1 9 Tf (Test 19) Tj ET Q +EMC +EMC +Q +endstream +endobj + +xref +0 13 +0000000000 65535 f +0000000015 00000 n +0000000064 00000 n +0000000149 00000 n +0000000345 00000 n +0000000371 00000 n +0000000416 00000 n +0000000450 00000 n +0000000522 00000 n +0000000592 00000 n +0000000665 00000 n +0000000000 65535 f +0000000737 00000 n +trailer << + /Root 1 0 R + /Size 13 + /ID [] +>> +startxref +3186 +%%EOF -- cgit v1.2.3