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(
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 ASSERT_TRUE(context && context->IsValid());
126 std::shared_ptr<GlyphAtlas> atlas =
129 atlas_context, text_frame, {0, 0});
131 ISize texture_size = atlas->GetTexture()->GetSize();
135 std::nullopt, atlas);
137 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
138 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
147 #ifndef FML_OS_MACOSX
148 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
151 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
152 std::shared_ptr<TextFrame> text_frame =
153 MakeTextFrame(
"1",
"ahem.ttf", TextOptions{.font_size = 50});
156 std::shared_ptr<GlyphAtlasContext> atlas_context =
159 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
160 ASSERT_TRUE(context && context->IsValid());
162 std::shared_ptr<GlyphAtlas> atlas =
165 atlas_context, text_frame, {0, 0});
167 ISize texture_size = atlas->GetTexture()->GetSize();
169 data.data(), text_frame,
static_cast<Scalar>(font_scale),
172 static_cast<Scalar>(font_scale), 1}),
174 std::nullopt, atlas);
176 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
177 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
183 std::shared_ptr<TextFrame> text_frame =
184 MakeTextFrame(
"th",
"ahem.ttf", TextOptions{.font_size = 50});
187 std::shared_ptr<GlyphAtlasContext> atlas_context =
190 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
191 ASSERT_TRUE(context && context->IsValid());
193 for (
int i = 0; i <= 1000; ++i) {
194 Rational font_scale(440 + i, 1000.0);
195 Rect position_rect[2];
199 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(12);
201 std::shared_ptr<GlyphAtlas> atlas =
204 atlas_context, text_frame, {0, 0});
205 ISize texture_size = atlas->GetTexture()->GetSize();
208 data.data(), text_frame,
static_cast<Scalar>(font_scale),
211 static_cast<Scalar>(font_scale), 1}),
213 std::nullopt, atlas);
214 position_rect[0] = PerVertexDataPositionToRect(
data.begin());
215 uv_rect[0] = PerVertexDataUVToRect(
data.begin(), texture_size);
216 position_rect[1] = PerVertexDataPositionToRect(
data.begin() + 4);
217 uv_rect[1] = PerVertexDataUVToRect(
data.begin() + 4, texture_size);
219 EXPECT_NEAR(GetAspectRatio(position_rect[1]), GetAspectRatio(uv_rect[1]),
226 #ifndef FML_OS_MACOSX
227 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
230 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
232 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
233 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
236 std::shared_ptr<GlyphAtlasContext> atlas_context =
239 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
240 ASSERT_TRUE(context && context->IsValid());
242 std::shared_ptr<GlyphAtlas> atlas =
245 atlas_context, text_frame,
offset);
247 ISize texture_size = atlas->GetTexture()->GetSize();
249 data.data(), text_frame, 1.0,
251 std::nullopt, atlas);
253 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
254 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
263 #ifndef FML_OS_MACOSX
264 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
267 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
269 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
270 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
273 std::shared_ptr<GlyphAtlasContext> atlas_context =
276 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
277 ASSERT_TRUE(context && context->IsValid());
280 std::shared_ptr<GlyphAtlas> atlas =
283 atlas_context, text_frame,
offset);
285 ISize texture_size = atlas->GetTexture()->GetSize();
287 data.data(), text_frame,
static_cast<Scalar>(font_scale),
291 static_cast<Scalar>(font_scale), 1}),
293 std::nullopt, atlas);
295 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
296 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
301 <<
"position size:" << position_rect.
GetSize();
303 <<
"position size:" << position_rect.
GetSize();
307 #ifndef FML_OS_MACOSX
308 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
311 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
313 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
314 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
317 std::shared_ptr<GlyphAtlasContext> atlas_context =
320 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
321 ASSERT_TRUE(context && context->IsValid());
323 std::shared_ptr<GlyphAtlas> atlas =
326 atlas_context, text_frame,
offset);
328 ISize texture_size = atlas->GetTexture()->GetSize();
330 data.data(), text_frame, 1.0,
332 std::nullopt, atlas);
334 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
335 Rect uv_rect = PerVertexDataUVToRect(
data.begin(), texture_size);
344 #ifndef FML_OS_MACOSX
345 GTEST_SKIP() <<
"Results aren't stable across linux and macos.";
348 std::vector<GlyphAtlasPipeline::VertexShader::PerVertexData>
data(4);
350 std::shared_ptr<TextFrame> text_frame = MakeTextFrame(
351 "1",
"ahem.ttf", TextOptions{.font_size = 50, .is_subpixel =
true});
354 std::shared_ptr<GlyphAtlasContext> atlas_context =
357 GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
358 ASSERT_TRUE(context && context->IsValid());
360 std::shared_ptr<GlyphAtlas> atlas =
363 atlas_context, text_frame,
offset);
365 ISize texture_size = atlas->GetTexture()->GetSize();
367 data.data(), text_frame, 1.0,
369 std::nullopt, atlas);
371 Rect position_rect = PerVertexDataPositionToRect(
data.begin());
372 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)
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