|
6 | 6 |
|
7 | 7 | #include <iterator> |
8 | 8 | #include <memory> |
| 9 | +#include <string> |
9 | 10 | #include <utility> |
10 | 11 |
|
11 | 12 | #include "core/fpdfapi/font/cpdf_font.h" |
@@ -50,6 +51,32 @@ class CPDFPageContentGeneratorTest : public TestWithPageModule { |
50 | 51 | CPDF_TextObject* pTextObj) { |
51 | 52 | pGen->ProcessText(buf, pTextObj); |
52 | 53 | } |
| 54 | + |
| 55 | + ByteString GetResourceNameBeforeOperator(const ByteString& stream, |
| 56 | + const std::string& op) { |
| 57 | + std::string text(stream.c_str(), stream.GetLength()); |
| 58 | + size_t op_pos = text.find(op); |
| 59 | + EXPECT_NE(std::string::npos, op_pos); |
| 60 | + if (op_pos == std::string::npos) { |
| 61 | + return ByteString(); |
| 62 | + } |
| 63 | + |
| 64 | + size_t slash_pos = text.rfind('/', op_pos); |
| 65 | + EXPECT_NE(std::string::npos, slash_pos); |
| 66 | + if (slash_pos == std::string::npos) { |
| 67 | + return ByteString(); |
| 68 | + } |
| 69 | + |
| 70 | + size_t name_start = slash_pos + 1; |
| 71 | + size_t name_end = text.find(' ', name_start); |
| 72 | + EXPECT_NE(std::string::npos, name_end); |
| 73 | + EXPECT_LE(name_end, op_pos); |
| 74 | + if (name_end == std::string::npos || name_end > op_pos) { |
| 75 | + return ByteString(); |
| 76 | + } |
| 77 | + |
| 78 | + return ByteString(text.substr(name_start, name_end - name_start).c_str()); |
| 79 | + } |
53 | 80 | }; |
54 | 81 |
|
55 | 82 | TEST_F(CPDFPageContentGeneratorTest, ProcessRect) { |
@@ -286,42 +313,30 @@ TEST_F(CPDFPageContentGeneratorTest, ProcessStandardText) { |
286 | 313 | fxcrt::ostringstream buf; |
287 | 314 | TestProcessText(&generator, &buf, pTextObj.get()); |
288 | 315 | ByteString text_string(buf); |
289 | | - auto first_resource_at = text_string.Find('/'); |
290 | | - ASSERT_TRUE(first_resource_at.has_value()); |
291 | | - first_resource_at = first_resource_at.value() + 1; |
292 | | - auto second_resource_at = text_string.ReverseFind('/'); |
293 | | - ASSERT_TRUE(second_resource_at.has_value()); |
294 | | - second_resource_at = second_resource_at.value() + 1; |
295 | | - ByteString first_string = text_string.First(first_resource_at.value()); |
296 | | - ByteString mid_string = text_string.Substr( |
297 | | - first_resource_at.value(), |
298 | | - second_resource_at.value() - first_resource_at.value()); |
299 | | - ByteString last_string = |
300 | | - text_string.Last(text_string.GetLength() - second_resource_at.value()); |
301 | | - // q and Q must be outside the BT .. ET operations |
302 | | - const ByteString kCompareString1 = |
| 316 | + ByteString gs_name = GetResourceNameBeforeOperator(text_string, " gs "); |
| 317 | + ByteString font_name = GetResourceNameBeforeOperator(text_string, " 10 Tf "); |
| 318 | + |
| 319 | + std::string expected = |
303 | 320 | "q .5 .69999999 .34999999 rg 1 .89999998 0 RG /"; |
304 | | - // Color RGB values used are integers divided by 255. |
305 | | - const ByteString kCompareString2 = " gs BT 1 0 0 1 100 100 Tm /"; |
306 | | - const ByteString kCompareString3 = |
307 | | - " 10 Tf 0 Tr <48656C6C6F20576F726C64> Tj ET Q\n"; |
308 | | - EXPECT_LT(kCompareString1.GetLength() + kCompareString2.GetLength() + |
309 | | - kCompareString3.GetLength(), |
310 | | - text_string.GetLength()); |
311 | | - EXPECT_EQ(kCompareString1, first_string.First(kCompareString1.GetLength())); |
312 | | - EXPECT_EQ(kCompareString2, mid_string.Last(kCompareString2.GetLength())); |
313 | | - EXPECT_EQ(kCompareString3, last_string.Last(kCompareString3.GetLength())); |
| 321 | + expected += gs_name.c_str(); |
| 322 | + expected += |
| 323 | + " gs 1 0 0 1 100 100 cm BT 1 0 0 1 0 0 Tm /"; |
| 324 | + expected += font_name.c_str(); |
| 325 | + expected += " 10 Tf 0 Tr <48656C6C6F20576F726C64> Tj ET Q\n"; |
| 326 | + EXPECT_EQ(ByteString(expected.c_str()), text_string); |
| 327 | + |
| 328 | + std::string text_output(text_string.c_str(), text_string.GetLength()); |
| 329 | + EXPECT_LT(text_output.find("100 100 cm "), text_output.find("BT ")); |
| 330 | + EXPECT_EQ(std::string::npos, |
| 331 | + text_output.find(" cm ", text_output.find("BT "))); |
| 332 | + |
314 | 333 | RetainPtr<const CPDF_Dictionary> external_gs = TestGetResource( |
315 | | - &generator, "ExtGState", |
316 | | - mid_string.AsStringView().First(mid_string.GetLength() - |
317 | | - kCompareString2.GetLength())); |
| 334 | + &generator, "ExtGState", gs_name.AsStringView()); |
318 | 335 | ASSERT_TRUE(external_gs); |
319 | 336 | EXPECT_EQ(0.5f, external_gs->GetFloatFor("ca")); |
320 | 337 | EXPECT_EQ(0.8f, external_gs->GetFloatFor("CA")); |
321 | | - RetainPtr<const CPDF_Dictionary> font_dict = TestGetResource( |
322 | | - &generator, "Font", |
323 | | - last_string.AsStringView().First(last_string.GetLength() - |
324 | | - kCompareString3.GetLength())); |
| 338 | + RetainPtr<const CPDF_Dictionary> font_dict = |
| 339 | + TestGetResource(&generator, "Font", font_name.AsStringView()); |
325 | 340 | ASSERT_TRUE(font_dict); |
326 | 341 | EXPECT_EQ("Font", font_dict->GetNameFor("Type")); |
327 | 342 | EXPECT_EQ("Type1", font_dict->GetNameFor("Subtype")); |
@@ -374,26 +389,16 @@ TEST_F(CPDFPageContentGeneratorTest, ProcessText) { |
374 | 389 | } |
375 | 390 |
|
376 | 391 | ByteString text_string(buf); |
377 | | - auto first_resource_at = text_string.Find('/'); |
378 | | - ASSERT_TRUE(first_resource_at.has_value()); |
379 | | - first_resource_at = first_resource_at.value() + 1; |
380 | | - ByteString first_string = text_string.First(first_resource_at.value()); |
381 | | - ByteString last_string = |
382 | | - text_string.Last(text_string.GetLength() - first_resource_at.value()); |
383 | | - // q and Q must be outside the BT .. ET operations |
384 | | - ByteString compare_string1 = "q 0 0 5 4 re W* n BT /"; |
385 | | - ByteString compare_string2 = |
386 | | - " 15.5 Tf 4 Tr <4920616D20696E646972656374> Tj ET Q\n"; |
387 | | - EXPECT_LT(compare_string1.GetLength() + compare_string2.GetLength(), |
388 | | - text_string.GetLength()); |
389 | | - EXPECT_EQ(compare_string1, text_string.First(compare_string1.GetLength())); |
390 | | - EXPECT_EQ(compare_string2, text_string.Last(compare_string2.GetLength())); |
391 | | - RetainPtr<const CPDF_Dictionary> font_dict = TestGetResource( |
392 | | - &generator, "Font", |
393 | | - text_string.AsStringView().Substr(compare_string1.GetLength(), |
394 | | - text_string.GetLength() - |
395 | | - compare_string1.GetLength() - |
396 | | - compare_string2.GetLength())); |
| 392 | + ByteString font_name = |
| 393 | + GetResourceNameBeforeOperator(text_string, " 15.5 Tf "); |
| 394 | + |
| 395 | + std::string expected = "q 0 0 5 4 re W* n BT 1 0 0 1 0 0 Tm /"; |
| 396 | + expected += font_name.c_str(); |
| 397 | + expected += " 15.5 Tf 4 Tr <4920616D20696E646972656374> Tj ET Q\n"; |
| 398 | + EXPECT_EQ(ByteString(expected.c_str()), text_string); |
| 399 | + |
| 400 | + RetainPtr<const CPDF_Dictionary> font_dict = |
| 401 | + TestGetResource(&generator, "Font", font_name.AsStringView()); |
397 | 402 | ASSERT_TRUE(font_dict); |
398 | 403 | EXPECT_TRUE(font_dict->GetObjNum()); |
399 | 404 | EXPECT_EQ("Font", font_dict->GetNameFor("Type")); |
|
0 commit comments