xref: /aosp_15_r20/external/pdfium/xfa/fde/cfde_textout_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2022 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "xfa/fde/cfde_textout.h"
6 
7 #include <memory>
8 
9 #include "build/build_config.h"
10 #include "core/fdrm/fx_crypt.h"
11 #include "core/fxcrt/bytestring.h"
12 #include "core/fxcrt/fx_codepage.h"
13 #include "core/fxcrt/fx_coordinates.h"
14 #include "core/fxcrt/retain_ptr.h"
15 #include "core/fxge/cfx_defaultrenderdevice.h"
16 #include "core/fxge/dib/cfx_dibitmap.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "testing/utils/hash.h"
19 #include "xfa/fgas/font/cfgas_fontmgr.h"
20 #include "xfa/fgas/font/cfgas_gefont.h"
21 #include "xfa/fgas/font/cfgas_gemodule.h"
22 
23 class CFDETextOutTest : public testing::Test {
24  public:
25   CFDETextOutTest() = default;
26   ~CFDETextOutTest() override = default;
27 
SetUp()28   void SetUp() override {
29     CFX_Size bitmap_size = GetBitmapSize();
30     bitmap_ = pdfium::MakeRetain<CFX_DIBitmap>();
31     ASSERT_TRUE(bitmap_->Create(bitmap_size.width, bitmap_size.height,
32                                 FXDIB_Format::kArgb));
33 
34     device_ = std::make_unique<CFX_DefaultRenderDevice>();
35     device_->Attach(bitmap_);
36 
37     font_ = LoadFont();
38     ASSERT_TRUE(font_);
39 
40     text_out_ = std::make_unique<CFDE_TextOut>();
41     text_out_->SetFont(font_);
42     text_out_->SetFontSize(12.0f);
43 
44     EXPECT_STREQ(GetEmptyBitmapChecksum(), GetBitmapChecksum().c_str());
45   }
46 
TearDown()47   void TearDown() override {
48     text_out_.reset();
49     font_.Reset();
50     device_.reset();
51     bitmap_.Reset();
52   }
53 
LoadFont()54   virtual RetainPtr<CFGAS_GEFont> LoadFont() {
55     const wchar_t kFontFamily[] = L"Arimo Bold";
56     return CFGAS_GEFont::LoadFont(kFontFamily, /*dwFontStyles=*/0,
57                                   FX_CodePage::kDefANSI);
58   }
59 
GetBitmapSize()60   virtual CFX_Size GetBitmapSize() { return CFX_Size(200, 100); }
61 
GetEmptyBitmapChecksum()62   virtual const char* GetEmptyBitmapChecksum() {
63     static const char kEmptyBitmapChecksum[] =
64         "a042237c5493fdb9656b94a83608d11a";
65     return kEmptyBitmapChecksum;
66   }
67 
device()68   CFX_DefaultRenderDevice* device() { return device_.get(); }
text_out()69   CFDE_TextOut& text_out() { return *text_out_; }
70 
GetBitmapChecksum()71   ByteString GetBitmapChecksum() {
72     CRYPT_md5_context context = CRYPT_MD5Start();
73     for (int i = 0; i < bitmap_->GetHeight(); ++i)
74       CRYPT_MD5Update(&context, bitmap_->GetScanline(i));
75     uint8_t digest[16];
76     CRYPT_MD5Finish(&context, digest);
77     return ByteString(CryptToBase16(digest).c_str());
78   }
79 
80  private:
81   RetainPtr<CFX_DIBitmap> bitmap_;
82   std::unique_ptr<CFX_DefaultRenderDevice> device_;
83   RetainPtr<CFGAS_GEFont> font_;
84   std::unique_ptr<CFDE_TextOut> text_out_;
85 };
86 
TEST_F(CFDETextOutTest,DrawLogicTextBasic)87 TEST_F(CFDETextOutTest, DrawLogicTextBasic) {
88   text_out().DrawLogicText(device(), L"foo", CFX_RectF(0, 0, 2100, 100));
89   const char* checksum = []() {
90 #if BUILDFLAG(IS_WIN)
91     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
92       return "76fd535f7d490d963598474494d0701e";
93 #endif
94     return "b26f1c171fcdbf185823364185adacf0";
95   }();
96   EXPECT_STREQ(checksum, GetBitmapChecksum().c_str());
97 }
98 
TEST_F(CFDETextOutTest,DrawLogicTextEmptyRect)99 TEST_F(CFDETextOutTest, DrawLogicTextEmptyRect) {
100   text_out().DrawLogicText(device(), L"foo", CFX_RectF());
101   EXPECT_STREQ(GetEmptyBitmapChecksum(), GetBitmapChecksum().c_str());
102 }
103 
104 #if !BUILDFLAG(IS_WIN)
105 // This test depends on a particular font being present.
106 class CFDETextOutLargeBitmapTest : public CFDETextOutTest {
107  public:
108   CFDETextOutLargeBitmapTest() = default;
109   ~CFDETextOutLargeBitmapTest() override = default;
110 
LoadFont()111   RetainPtr<CFGAS_GEFont> LoadFont() override {
112     const wchar_t kFontFamily[] = L"DejaVu Sans";
113     auto* font_manager = CFGAS_GEModule::Get()->GetFontMgr();
114     return font_manager->LoadFont(kFontFamily, /*dwFontStyles=*/0,
115                                   FX_CodePage::kFailure);
116   }
117 
GetBitmapSize()118   CFX_Size GetBitmapSize() override { return CFX_Size(2100, 20); }
119 
GetEmptyBitmapChecksum()120   const char* GetEmptyBitmapChecksum() override {
121     static const char kEmptyLargeBitmapChecksum[] =
122         "101745f76351fd5d916bf3817b71563c";
123     return kEmptyLargeBitmapChecksum;
124   }
125 
GetLargeTextBlobChecksum()126   const char* GetLargeTextBlobChecksum() {
127     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
128       return "cd357c6afbf17bb2ac48817df5d9eaad";
129     }
130     return "268b71a8660b51e31c6bf30fc7ff1e08";
131   }
132 };
133 
TEST_F(CFDETextOutLargeBitmapTest,DrawLogicTextBug953881)134 TEST_F(CFDETextOutLargeBitmapTest, DrawLogicTextBug953881) {
135   FDE_TextStyle styles;
136   styles.single_line_ = true;
137   text_out().SetStyles(styles);
138   text_out().SetAlignment(FDE_TextAlignment::kCenterLeft);
139   text_out().SetFontSize(10.0f);
140 
141   static const wchar_t kText[] =
142       L"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"
143       L"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSssssssssss"
144       L"sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
145       L"sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
146       L"sssssssssssssssssssssssssssssssssssssssssssssssssnnnnnnnnnnn"
147       "\xfeba"
148       L"Sssssssssssssssssss"
149       "\xfeba"
150       L"iiiiisssss";
151   text_out().DrawLogicText(device(), WideString(kText),
152                            CFX_RectF(3, 3, 2048, 10));
153   EXPECT_STREQ(GetLargeTextBlobChecksum(), GetBitmapChecksum().c_str());
154 }
155 
TEST_F(CFDETextOutLargeBitmapTest,DrawLogicTextBug1342078)156 TEST_F(CFDETextOutLargeBitmapTest, DrawLogicTextBug1342078) {
157   FDE_TextStyle styles;
158   styles.single_line_ = true;
159   text_out().SetStyles(styles);
160   text_out().SetAlignment(FDE_TextAlignment::kCenterLeft);
161   text_out().SetFontSize(10.0f);
162 
163   static const wchar_t kText[] =
164       L"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"
165       L"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSssssssssss"
166       L"sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
167       L"sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"
168       L"sssssssssssssssssssssssssssssssssssssssssssssssssnnnnnnnnnnn"
169       "\xfeba"
170       L"Sssssssssssssssssss"
171       "\xfeba"
172       L"iiiiiiiiiisssss";
173   text_out().DrawLogicText(device(), WideString(kText),
174                            CFX_RectF(3, 3, 2048, 10));
175   EXPECT_STREQ(GetLargeTextBlobChecksum(), GetBitmapChecksum().c_str());
176 }
177 #endif  // !BUILDFLAG(IS_WIN)
178