summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Nakashima <hnakashima@chromium.org>2018-03-27 16:26:44 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-03-27 16:26:44 +0000
commitc90adc58b97200d20b0532bde95b79dcba00637f (patch)
tree002895239afa554f84a0fb76e6cb85265fef19b3
parentc526e38a47a7fc7d83cc87aaf521d14bb7b7304d (diff)
downloadpdfium-c90adc58b97200d20b0532bde95b79dcba00637f.tar.xz
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 <hnakashima@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org>
-rw-r--r--fpdfsdk/fpdfedit_embeddertest.cpp91
-rw-r--r--fpdfsdk/fpdfeditpage.cpp41
-rw-r--r--fpdfsdk/fpdfview.cpp6
-rw-r--r--fpdfsdk/fpdfview_c_api_test.c3
-rw-r--r--fpdfsdk/fsdk_define.h4
-rw-r--r--public/fpdf_edit.h34
-rw-r--r--public/fpdfview.h1
-rw-r--r--testing/resources/text_in_page_marked.in136
-rw-r--r--testing/resources/text_in_page_marked.pdf152
9 files changed, 464 insertions, 4 deletions
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<void, FPDFBitmapDeleter> 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<void, FPDFBitmapDeleter> 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<void, FPDFBitmapDeleter> 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<FPDF_PAGEOBJECT> 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<unsigned short*>(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<void, FPDFBitmapDeleter> 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<FPDF_PAGEOBJECTMARK>(&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<CPDF_PageObject*>(page_object);
}
+const CPDF_ContentMarkItem* CPDFContentMarkItemFromFPDFPageObjectMark(
+ FPDF_PAGEOBJECTMARK mark) {
+ return static_cast<const CPDF_ContentMarkItem*>(mark);
+}
+
CPDF_Object* CPDFObjectFromFPDFAttachment(FPDF_ATTACHMENT attachment) {
return static_cast<CPDF_Object*>(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 <</Factor 1>> 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 <</Factor 2>> 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 <</Factor 3>> 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 <</Factor 2>> 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 [<f341ae654a77acd5065a7645e596e6e6><bc37298a3f87f479229bce997ca791f7>]
+>>
+{{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 <</Factor 1>> 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 <</Factor 2>> 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 <</Factor 3>> 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 <</Factor 2>> 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 [<f341ae654a77acd5065a7645e596e6e6><bc37298a3f87f479229bce997ca791f7>]
+>>
+startxref
+3186
+%%EOF