xref: /aosp_15_r20/external/pdfium/core/fxge/win32/cfx_psrenderer_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2021 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 "core/fxge/win32/cfx_psrenderer.h"
6 
7 #include "core/fxcrt/bytestring.h"
8 #include "core/fxcrt/data_vector.h"
9 #include "core/fxcrt/fx_coordinates.h"
10 #include "core/fxcrt/fx_stream.h"
11 #include "core/fxcrt/retain_ptr.h"
12 #include "core/fxge/dib/cfx_dibitmap.h"
13 #include "core/fxge/dib/fx_dib.h"
14 #include "core/fxge/win32/cfx_psfonttracker.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/abseil-cpp/absl/types/optional.h"
17 #include "third_party/base/containers/span.h"
18 
19 namespace {
20 
FakeA85Encode(pdfium::span<const uint8_t> src_span)21 DataVector<uint8_t> FakeA85Encode(pdfium::span<const uint8_t> src_span) {
22   return DataVector<uint8_t>({'d', 'u', 'm', 'm', 'y', 'a', '8', '5'});
23 }
24 
25 class TestWriteStream final : public IFX_RetainableWriteStream {
26  public:
27   CONSTRUCT_VIA_MAKE_RETAIN;
28 
29   // IFX_RetainableWriteStream:
WriteBlock(pdfium::span<const uint8_t> buffer)30   bool WriteBlock(pdfium::span<const uint8_t> buffer) override {
31     data_.insert(data_.end(), buffer.begin(), buffer.end());
32     return true;
33   }
34 
GetSpan() const35   pdfium::span<const uint8_t> GetSpan() const { return data_; }
36 
37  private:
38   DataVector<uint8_t> data_;
39 };
40 
41 }  // namespace
42 
TEST(PSRendererTest,GenerateType42SfntData)43 TEST(PSRendererTest, GenerateType42SfntData) {
44   absl::optional<ByteString> result;
45 
46   result = CFX_PSRenderer::GenerateType42SfntDataForTesting("empty", {});
47   EXPECT_FALSE(result.has_value());
48 
49   constexpr uint8_t kOddByteCountTestData[] = {0, 32, 55};
50   static constexpr char kExpectedOddByteCountResult[] = R"(/odd_sfnts [
51 <
52 002037
53 >
54 ] def
55 )";
56   result = CFX_PSRenderer::GenerateType42SfntDataForTesting(
57       "odd", kOddByteCountTestData);
58   ASSERT_TRUE(result.has_value());
59   EXPECT_STREQ(kExpectedOddByteCountResult, result.value().c_str());
60 
61   // Requires padding.
62   constexpr uint8_t kEvenByteCountTestData[] = {0, 32, 66, 77};
63   static constexpr char kExpectedEvenByteCountResult[] = R"(/even_sfnts [
64 <
65 0020424D00
66 >
67 ] def
68 )";
69   result = CFX_PSRenderer::GenerateType42SfntDataForTesting(
70       "even", kEvenByteCountTestData);
71   ASSERT_TRUE(result.has_value());
72   EXPECT_STREQ(kExpectedEvenByteCountResult, result.value().c_str());
73 }
74 
TEST(PSRendererTest,GenerateType42FontDictionary)75 TEST(PSRendererTest, GenerateType42FontDictionary) {
76   ByteString result;
77 
78   static constexpr char kExpected1DescendantFontResult[] = R"(8 dict begin
79 /FontType 42 def
80 /FontMatrix [1 0 0 1 0 0] def
81 /FontName /1descendant_0 def
82 /Encoding 3 array
83 dup 0 /c00 put
84 dup 1 /c01 put
85 dup 2 /c02 put
86 readonly def
87 /FontBBox [1 2 3 4] def
88 /PaintType 0 def
89 /CharStrings 4 dict dup begin
90 /.notdef 0 def
91 /c00 0 def
92 /c01 1 def
93 /c02 2 def
94 end readonly def
95 /sfnts 1descendant_sfnts def
96 FontName currentdict end definefont pop
97 6 dict begin
98 /FontName /1descendant def
99 /FontType 0 def
100 /FontMatrix [1 0 0 1 0 0] def
101 /FMapType 2 def
102 /Encoding [
103 0
104 ] def
105 /FDepVector [
106 /1descendant_0 findfont
107 ] def
108 FontName currentdict end definefont pop
109 %%EndResource
110 )";
111   result = CFX_PSRenderer::GenerateType42FontDictionaryForTesting(
112       "1descendant", FX_RECT(1, 2, 3, 4), /*num_glyphs=*/3,
113       /*glyphs_per_descendant_font=*/3);
114   EXPECT_STREQ(kExpected1DescendantFontResult, result.c_str());
115 
116   static constexpr char kExpected2DescendantFontResult[] = R"(8 dict begin
117 /FontType 42 def
118 /FontMatrix [1 0 0 1 0 0] def
119 /FontName /2descendant_0 def
120 /Encoding 3 array
121 dup 0 /c00 put
122 dup 1 /c01 put
123 dup 2 /c02 put
124 readonly def
125 /FontBBox [12 -5 34 199] def
126 /PaintType 0 def
127 /CharStrings 4 dict dup begin
128 /.notdef 0 def
129 /c00 0 def
130 /c01 1 def
131 /c02 2 def
132 end readonly def
133 /sfnts 2descendant_sfnts def
134 FontName currentdict end definefont pop
135 8 dict begin
136 /FontType 42 def
137 /FontMatrix [1 0 0 1 0 0] def
138 /FontName /2descendant_1 def
139 /Encoding 3 array
140 dup 0 /c00 put
141 dup 1 /c01 put
142 readonly def
143 /FontBBox [12 -5 34 199] def
144 /PaintType 0 def
145 /CharStrings 4 dict dup begin
146 /.notdef 0 def
147 /c00 3 def
148 /c01 4 def
149 end readonly def
150 /sfnts 2descendant_sfnts def
151 FontName currentdict end definefont pop
152 6 dict begin
153 /FontName /2descendant def
154 /FontType 0 def
155 /FontMatrix [1 0 0 1 0 0] def
156 /FMapType 2 def
157 /Encoding [
158 0
159 1
160 ] def
161 /FDepVector [
162 /2descendant_0 findfont
163 /2descendant_1 findfont
164 ] def
165 FontName currentdict end definefont pop
166 %%EndResource
167 )";
168   result = CFX_PSRenderer::GenerateType42FontDictionaryForTesting(
169       "2descendant", FX_RECT(12, -5, 34, 199), /*num_glyphs=*/5,
170       /*glyphs_per_descendant_font=*/3);
171   EXPECT_STREQ(kExpected2DescendantFontResult, result.c_str());
172 }
173 
TEST(PSRendererTest,DrawDIBits)174 TEST(PSRendererTest, DrawDIBits) {
175   static constexpr char kExpectedOutput[] = R"(
176 save
177 /im/initmatrix load def
178 /n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load def/h/closepath load def
179 /f/fill load def/F/eofill load def/s/stroke load def/W/clip load def/W*/eoclip load def
180 /rg/setrgbcolor load def/k/setcmykcolor load def
181 /J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load def/M/setmiterlimit load def/d/setdash load def
182 /q/gsave load def/Q/grestore load def/iM/imagemask load def
183 /Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont load def
184 /cm/concat load def/Cm/currentmatrix load def/mx/matrix load def/sm/setmatrix load def
185 q
186 [1 0 0 1 0 0]cm 10 2 1[10 0 0 -2 0 2]currentfile/ASCII85Decode filter false 1 colorimage
187 dummya85
188 Q
189 
190 restore
191 )";
192   auto output_stream = pdfium::MakeRetain<TestWriteStream>();
193 
194   {
195     constexpr int kWidth = 10;
196     constexpr int kHeight = 2;
197     CFX_PSFontTracker font_tracker;
198     const EncoderIface encoder_interface{&FakeA85Encode, nullptr, nullptr,
199                                          nullptr, nullptr};
200     CFX_PSRenderer renderer(&font_tracker, &encoder_interface);
201     renderer.Init(output_stream, CFX_PSRenderer::RenderingLevel::kLevel2,
202                   kWidth, kHeight);
203 
204     auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
205     bool result = bitmap->Create(kWidth, kHeight, FXDIB_Format::k1bppRgb);
206     ASSERT_TRUE(result);
207     ASSERT_TRUE(renderer.DrawDIBits(bitmap, /*color=*/0, CFX_Matrix(),
208                                     FXDIB_ResampleOptions()));
209   }
210 
211   ByteString output(output_stream->GetSpan());
212   EXPECT_STREQ(output.c_str(), kExpectedOutput);
213 }
214