6 #include "flutter/impeller/renderer/testing/mocks.h"
7 #include "flutter/testing/testing.h"
12 #include "third_party/googletest/googletest/include/gtest/gtest.h"
13 #include "txt/platform.h"
15 #pragma GCC diagnostic ignored "-Wunreachable-code"
23 using ::testing::Return;
31 std::shared_ptr<TextFrame> MakeTextFrame(
const std::string& text,
32 const std::string_view& font_fixture,
33 const TextOptions& options) {
34 auto c_font_fixture = std::string(font_fixture);
35 auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
39 sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
40 SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
41 if (options.is_subpixel) {
42 sk_font.setSubpixel(
true);
44 auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
54 const TypographerContext* typographer_context,
55 HostBuffer& host_buffer,
58 const std::shared_ptr<GlyphAtlasContext>& atlas_context,
59 const std::shared_ptr<TextFrame>& frame,
61 frame->SetPerFrameData(
65 Vector3{
static_cast<Scalar>(scale),
static_cast<Scalar>(scale), 1}),
67 return typographer_context->CreateGlyphAtlas(context,
type, host_buffer,
68 atlas_context, {frame});
71 Rect PerVertexDataPositionToRect(
72 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>::iterator
78 for (
int i = 0; i < 4; ++i) {
79 right = std::max(right,
data[i].position.x);
80 left = std::min(left,
data[i].position.x);
81 top = std::min(top,
data[i].position.y);
82 bottom = std::max(bottom,
data[i].position.y);
88 Rect PerVertexDataUVToRect(
89 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>::iterator
data,
95 for (
int i = 0; i < 4; ++i) {
96 right = std::max(right,
data[i].uv.x * texture_size.width);
97 left = std::min(left,
data[i].uv.x * texture_size.width);
98 top = std::min(top,
data[i].uv.y * texture_size.height);
99 bottom = std::max(bottom,
data[i].uv.y * texture_size.height);
105 double GetAspectRatio(
Rect rect) {
106 return static_cast<double>(rect.GetWidth()) / rect.GetHeight();
111 #ifndef FML_OS_MACOSX
112 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
115 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
117 std::shared_ptr<TextFrame> text_frame =
118 MakeTextFrame(
"1",
"ahem.ttf", TextOptions{.font_size = 50});
121 std::shared_ptr<GlyphAtlasContext> atlas_context =
124 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
125 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
126 ASSERT_TRUE(context && context->IsValid());
127 std::shared_ptr<GlyphAtlas> atlas =
130 atlas_context, text_frame, {0, 0});
132 ISize texture_size = atlas->GetTexture()->GetSize();
136 std::nullopt, atlas);
138 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
139 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
148 #ifndef FML_OS_MACOSX
149 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
152 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
153 std::shared_ptr<TextFrame> text_frame =
154 MakeTextFrame(
"1",
"ahem.ttf", TextOptions{.font_size = 50});
157 std::shared_ptr<GlyphAtlasContext> atlas_context =
160 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
161 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
162 ASSERT_TRUE(context && context->IsValid());
164 std::shared_ptr<GlyphAtlas> atlas =
167 atlas_context, text_frame, {0, 0});
169 ISize texture_size = atlas->GetTexture()->GetSize();
171 data.data(), text_frame,
static_cast<Scalar>(font_scale),
174 static_cast<Scalar>(font_scale), 1}),
176 std::nullopt, atlas);
178 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
179 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
185 std::shared_ptr<TextFrame> text_frame =
186 MakeTextFrame(
"th",
"ahem.ttf", TextOptions{.font_size = 50});
189 std::shared_ptr<GlyphAtlasContext> atlas_context =
192 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
193 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
194 ASSERT_TRUE(context && context->IsValid());
196 for (
int i = 0; i <= 1000; ++i) {
197 Rational font_scale(440 + i, 1000.0);
198 Rect position_rect[2];
202 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(12);
204 std::shared_ptr<GlyphAtlas> atlas =
207 atlas_context, text_frame, {0, 0});
208 ISize texture_size = atlas->GetTexture()->GetSize();
211 data.data(), text_frame,
static_cast<Scalar>(font_scale),
214 static_cast<Scalar>(font_scale), 1}),
216 std::nullopt, atlas);
217 position_rect[0] = PerVertexDataPositionToRect(
data.begin());
218 uv_rect[0] = PerVertexDataUVToRect(
data.begin(), texture_size);
219 position_rect[1] = PerVertexDataPositionToRect(
data.begin() + 4);
220 uv_rect[1] = PerVertexDataUVToRect(
data.begin() + 4, texture_size);
222 EXPECT_NEAR(GetAspectRatio(position_rect[1]), GetAspectRatio(uv_rect[1]),
229 #ifndef FML_OS_MACOSX
230 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
233 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
235 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
236 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
239 std::shared_ptr<GlyphAtlasContext> atlas_context =
242 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
243 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
244 ASSERT_TRUE(context && context->IsValid());
246 std::shared_ptr<GlyphAtlas> atlas =
249 atlas_context, text_frame, offset);
251 ISize texture_size = atlas->GetTexture()->GetSize();
253 data.data(), text_frame, 1.0,
255 std::nullopt, atlas);
257 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
258 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
267 #ifndef FML_OS_MACOSX
268 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
271 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
273 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
274 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
277 std::shared_ptr<GlyphAtlasContext> atlas_context =
280 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
281 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
282 ASSERT_TRUE(context && context->IsValid());
284 Point offset = {0.16667, 0};
285 std::shared_ptr<GlyphAtlas> atlas =
288 atlas_context, text_frame, offset);
290 ISize texture_size = atlas->GetTexture()->GetSize();
292 data.data(), text_frame,
static_cast<Scalar>(font_scale),
296 static_cast<Scalar>(font_scale), 1}),
298 std::nullopt, atlas);
300 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
301 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
306 <<
"position size:" << position_rect.
GetSize();
308 <<
"position size:" << position_rect.
GetSize();
312 #ifndef FML_OS_MACOSX
313 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
316 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
318 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
319 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
322 std::shared_ptr<GlyphAtlasContext> atlas_context =
325 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
326 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
327 ASSERT_TRUE(context && context->IsValid());
329 std::shared_ptr<GlyphAtlas> atlas =
332 atlas_context, text_frame, offset);
334 ISize texture_size = atlas->GetTexture()->GetSize();
336 data.data(), text_frame, 1.0,
338 std::nullopt, atlas);
340 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
341 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
350 #ifndef FML_OS_MACOSX
351 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
354 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
356 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
357 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
360 std::shared_ptr<GlyphAtlasContext> atlas_context =
363 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter(),
364 GetContext()->GetCapabilities()->GetMinimumUniformAlignment());
365 ASSERT_TRUE(context && context->IsValid());
367 std::shared_ptr<GlyphAtlas> atlas =
370 atlas_context, text_frame, offset);
372 ISize texture_size = atlas->GetTexture()->GetSize();
374 data.data(), text_frame, 1.0,
376 std::nullopt, atlas);
378 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
379 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
Type
Describes how the glyphs are represented in the texture.
static std::shared_ptr< HostBuffer > Create(const std::shared_ptr< Allocator > &allocator, const std::shared_ptr< const IdleWaiter > &idle_waiter, size_t minimum_uniform_alignment)
static void ComputeVertexData(GlyphAtlasPipeline::VertexShader::PerVertexData *vtx_contents, const std::shared_ptr< TextFrame > &frame, Scalar scale, const Matrix &entity_transform, Vector2 offset, std::optional< GlyphProperties > glyph_properties, const std::shared_ptr< GlyphAtlas > &atlas)
static Rational RoundScaledFontSize(Scalar scale)
static std::shared_ptr< TypographerContext > Make()
#define EXPECT_RECT_NEAR(a, b)
TEST_P(AiksTest, DrawAtlasNoColor)
INSTANTIATE_PLAYGROUND_SUITE(AiksTest)
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Rational scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::shared_ptr< TextFrame > &frame)
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeTranslation(const Vector3 &t)
static constexpr Matrix MakeScale(const Vector3 &s)
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
std::shared_ptr< const fml::Mapping > data