[M120 Migration][VD] Remove accessing oom_score_adj in zygote process
[platform/framework/web/chromium-efl.git] / printing / metafile_skia_unittest.cc
1 // Copyright 2018 The Chromium 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 "printing/metafile_skia.h"
6
7 #include <utility>
8
9 #include "build/build_config.h"
10 #include "cc/paint/paint_op.h"
11 #include "cc/paint/paint_record.h"
12 #include "printing/common/metafile_utils.h"
13 #include "printing/mojom/print.mojom.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "third_party/skia/include/core/SkCanvas.h"
17 #include "third_party/skia/include/core/SkPaint.h"
18 #include "third_party/skia/include/core/SkPicture.h"
19 #include "third_party/skia/include/core/SkPictureRecorder.h"
20 #include "third_party/skia/include/core/SkRect.h"
21 #include "third_party/skia/include/core/SkRefCnt.h"
22 #include "third_party/skia/include/core/SkSerialProcs.h"
23 #include "third_party/skia/include/core/SkSize.h"
24 #include "third_party/skia/include/core/SkStream.h"
25 #include "third_party/skia/include/core/SkSurfaceProps.h"
26 #include "third_party/skia/include/core/SkTextBlob.h"
27
28 namespace printing {
29
30 TEST(MetafileSkiaTest, FrameContent) {
31   constexpr int kPictureSideLen = 100;
32   constexpr int kPageSideLen = 150;
33
34   // Create a placeholder picture.
35   sk_sp<SkPicture> pic_holder = SkPicture::MakePlaceholder(
36       SkRect::MakeXYWH(0, 0, kPictureSideLen, kPictureSideLen));
37
38   // Create the page with nested content which is the placeholder and will be
39   // replaced later.
40   cc::PaintOpBuffer buffer;
41   cc::PaintFlags flags;
42   flags.setColor(SK_ColorWHITE);
43   const SkRect page_rect = SkRect::MakeXYWH(0, 0, kPageSideLen, kPageSideLen);
44   buffer.push<cc::DrawRectOp>(page_rect, flags);
45   const uint32_t content_id = pic_holder->uniqueID();
46   buffer.push<cc::CustomDataOp>(content_id);
47   SkSize page_size = SkSize::Make(kPageSideLen, kPageSideLen);
48
49   // Finish creating the entire metafile.
50   MetafileSkia metafile(mojom::SkiaDocumentType::kMSKP, 1);
51   metafile.AppendPage(page_size, buffer.ReleaseAsRecord());
52   metafile.AppendSubframeInfo(content_id, base::UnguessableToken::Create(),
53                               std::move(pic_holder));
54   metafile.FinishFrameContent();
55   SkStreamAsset* metafile_stream = metafile.GetPdfData();
56   ASSERT_TRUE(metafile_stream);
57
58   // Draw a 100 by 100 red square which will be the actual content of
59   // the placeholder.
60   SkPictureRecorder recorder;
61   SkCanvas* canvas = recorder.beginRecording(kPictureSideLen, kPictureSideLen);
62   SkPaint paint;
63   paint.setStyle(SkPaint::kFill_Style);
64   paint.setColor(SK_ColorRED);
65   paint.setAlpha(SK_AlphaOPAQUE);
66   canvas->drawRect(SkRect::MakeXYWH(0, 0, kPictureSideLen, kPictureSideLen),
67                    paint);
68   sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
69   EXPECT_TRUE(picture);
70
71   // Get the complete picture by replacing the placeholder.
72   PictureDeserializationContext subframes;
73   subframes[content_id] = picture;
74   SkDeserialProcs procs = DeserializationProcs(&subframes, nullptr);
75   sk_sp<SkPicture> pic = SkPicture::MakeFromStream(metafile_stream, &procs);
76   ASSERT_TRUE(pic);
77
78   // Verify the resultant picture is as expected by comparing the sizes and
79   // detecting the color inside and outside of the square area.
80   EXPECT_TRUE(pic->cullRect() == page_rect);
81   SkBitmap bitmap;
82   bitmap.allocN32Pixels(kPageSideLen, kPageSideLen);
83   SkCanvas bitmap_canvas(bitmap, SkSurfaceProps{});
84   pic->playback(&bitmap_canvas);
85   // Check top left pixel color of the red square.
86   EXPECT_EQ(bitmap.getColor(0, 0), SK_ColorRED);
87   // Check bottom right pixel of the red square.
88   EXPECT_EQ(bitmap.getColor(kPictureSideLen - 1, kPictureSideLen - 1),
89             SK_ColorRED);
90   // Check inside of the red square.
91   EXPECT_EQ(bitmap.getColor(kPictureSideLen / 2, kPictureSideLen / 2),
92             SK_ColorRED);
93   // Check outside of the red square.
94   EXPECT_EQ(bitmap.getColor(kPictureSideLen, kPictureSideLen), SK_ColorWHITE);
95 }
96
97 TEST(MetafileSkiaTest, GetPageBounds) {
98   constexpr int kPictureSideLen = 100;
99   constexpr int kPageSideWidth = 150;
100   constexpr int kPageSideHeight = 120;
101
102   // Create a placeholder picture.
103   sk_sp<SkPicture> pic_holder = SkPicture::MakePlaceholder(
104       SkRect::MakeXYWH(0, 0, kPictureSideLen, kPictureSideLen));
105
106   // Create the page with nested content which is the placeholder and will be
107   // replaced later.
108   cc::PaintOpBuffer buffer;
109   cc::PaintFlags flags;
110   flags.setColor(SK_ColorWHITE);
111   const SkRect page_rect =
112       SkRect::MakeXYWH(0, 0, kPageSideWidth, kPageSideHeight);
113   buffer.push<cc::DrawRectOp>(page_rect, flags);
114   const uint32_t content_id = pic_holder->uniqueID();
115   buffer.push<cc::CustomDataOp>(content_id);
116   SkSize page_size = SkSize::Make(kPageSideWidth, kPageSideHeight);
117
118   // Finish creating the entire metafile.
119   MetafileSkia metafile(mojom::SkiaDocumentType::kMSKP, 1);
120   metafile.AppendPage(page_size, buffer.ReleaseAsRecord());
121   metafile.AppendSubframeInfo(content_id, base::UnguessableToken::Create(),
122                               std::move(pic_holder));
123   metafile.FinishFrameContent();
124
125   // Confirm there is 1 page in the doc.
126   EXPECT_EQ(1u, metafile.GetPageCount());
127
128   // Test in bound case.
129   EXPECT_EQ(gfx::Rect(kPageSideWidth, kPageSideHeight),
130             metafile.GetPageBounds(/*page_number=*/1));
131
132   // Test out of bounds cases.
133   EXPECT_EQ(gfx::Rect(), metafile.GetPageBounds(/*page_number=*/0));
134   EXPECT_EQ(gfx::Rect(), metafile.GetPageBounds(/*page_number=*/2));
135 }
136
137 TEST(MetafileSkiaTest, MultiPictureDocumentTypefaces) {
138   constexpr int kPictureSideLen = 100;
139   constexpr int kPageSideLen = 150;
140   constexpr int kDocumentCookie = 1;
141   constexpr int kNumDocumentPages = 2;
142
143   // The content tracking for serialization/deserialization.
144   ContentProxySet serialize_typeface_ctx;
145   PictureDeserializationContext subframes;
146   TypefaceDeserializationContext typefaces;
147   SkDeserialProcs procs = DeserializationProcs(&subframes, &typefaces);
148
149   // The typefaces which will be reused across the multiple (duplicate) pages.
150   constexpr char kTypefaceName1[] = "sans-serif";
151 #if BUILDFLAG(IS_WIN)
152   constexpr char kTypefaceName2[] = "Courier New";
153 #else
154   constexpr char kTypefaceName2[] = "monospace";
155 #endif
156   constexpr size_t kNumTypefaces = 2;
157   sk_sp<SkTypeface> typeface1 =
158       SkTypeface::MakeFromName(kTypefaceName1, SkFontStyle());
159   sk_sp<SkTypeface> typeface2 =
160       SkTypeface::MakeFromName(kTypefaceName2, SkFontStyle());
161   const SkFont font1 = SkFont(typeface1, 10);
162   const SkFont font2 = SkFont(typeface2, 12);
163
164   // Node IDs for the text, which will increase for each text blob added.
165   cc::NodeId node_id = 7;
166
167   // All text can just be black.
168   cc::PaintFlags flags_text;
169   flags_text.setColor(SK_ColorBLACK);
170
171   // Mark the text on white pages, each of the same size.
172   cc::PaintFlags flags;
173   flags.setColor(SK_ColorWHITE);
174   const SkRect page_rect = SkRect::MakeXYWH(0, 0, kPageSideLen, kPageSideLen);
175   SkSize page_size = SkSize::Make(kPageSideLen, kPageSideLen);
176
177   for (int i = 0; i < kNumDocumentPages; i++) {
178     MetafileSkia metafile(mojom::SkiaDocumentType::kMSKP, kDocumentCookie);
179
180     // When the stream is serialized inside FinishFrameContent(), any typeface
181     // which is used on any page will be serialized only once by the first
182     // page's metafile which needed it.  Any subsequent page that reuses the
183     // same typeface will rely upon `serialize_typeface_ctx` which is used by
184     // printing::SerializeOopTypeface() to optimize away the need to resend.
185     metafile.UtilizeTypefaceContext(&serialize_typeface_ctx);
186
187     sk_sp<SkPicture> pic_holder = SkPicture::MakePlaceholder(
188         SkRect::MakeXYWH(0, 0, kPictureSideLen, kPictureSideLen));
189
190     // Create the page for the text content.
191     cc::PaintOpBuffer buffer;
192     buffer.push<cc::DrawRectOp>(page_rect, flags);
193     const uint32_t content_id = pic_holder->uniqueID();
194     buffer.push<cc::CustomDataOp>(content_id);
195
196     // Mark the page with some text using multiple fonts.
197     // Use the first font.
198     sk_sp<SkTextBlob> text_blob1 = SkTextBlob::MakeFromString("foo", font1);
199     buffer.push<cc::DrawTextBlobOp>(text_blob1, 0.0f, 0.0f, ++node_id,
200                                     flags_text);
201
202     // Use the second font.
203     sk_sp<SkTextBlob> text_blob2 = SkTextBlob::MakeFromString("bar", font2);
204     buffer.push<cc::DrawTextBlobOp>(text_blob2, 0.0f, 0.0f, ++node_id,
205                                     flags_text);
206
207     // Reuse the first font again on same page.
208     sk_sp<SkTextBlob> text_blob3 = SkTextBlob::MakeFromString("bar", font2);
209     buffer.push<cc::DrawTextBlobOp>(text_blob3, 0.0f, 0.0f, ++node_id,
210                                     flags_text);
211
212     metafile.AppendPage(page_size, buffer.ReleaseAsRecord());
213     metafile.AppendSubframeInfo(content_id, base::UnguessableToken::Create(),
214                                 std::move(pic_holder));
215     metafile.FinishFrameContent();
216     SkStreamAsset* metafile_stream = metafile.GetPdfData();
217     ASSERT_TRUE(metafile_stream);
218
219     // Deserialize the stream.  Any given typeface is expected to appear only
220     // once in the stream, so the deserialization context of `typefaces` bundled
221     // with `procs` should be empty the first time through, and afterwards
222     // there should never be more than the number of unique typefaces we used,
223     // regardless of number of pages.
224     EXPECT_EQ(typefaces.size(), i ? kNumTypefaces : 0);
225     ASSERT_TRUE(SkPicture::MakeFromStream(metafile_stream, &procs));
226     EXPECT_EQ(typefaces.size(), kNumTypefaces);
227   }
228 }
229
230 }  // namespace printing