5 #include "flutter/fml/native_library.h"
6 #include "flutter/fml/string_conversion.h"
7 #include "flutter/testing/testing.h"
36 hpp::DisplayListBuilder builder;
39 ASSERT_EQ(builder.GetSaveCount(), 1u);
41 ASSERT_EQ(builder.GetSaveCount(), 2u);
43 ASSERT_EQ(builder.GetSaveCount(), 1u);
49 <<
"This test checks wrapping FBOs which is an OpenGL ES only call.";
54 const auto window_size = GetWindowSize();
73 color = {1.0, 0.0, 0.0, 1.0};
86 auto dl = Adopt<DisplayList>(
90 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
97 auto compressed = LoadFixtureImageCompressed(
98 flutter::testing::OpenFixtureAsMapping(
"boston.jpg"));
99 ASSERT_NE(compressed,
nullptr);
100 auto decompressed = compressed->Decode().ConvertToRGBA();
101 ASSERT_TRUE(decompressed.IsValid());
103 mapping.
data = decompressed.GetAllocation()->GetMapping();
104 mapping.
length = decompressed.GetAllocation()->GetSize();
106 auto context = GetInteropContext();
109 desc.
size = {decompressed.GetSize().
width, decompressed.GetSize().height};
112 context.GetC(), &desc, &mapping,
nullptr));
113 ASSERT_TRUE(texture);
120 auto dl = Adopt<DisplayList>(
123 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
130 auto context = GetInteropContext();
132 auto impeller_context = context->GetContext();
134 if (impeller_context->GetBackendType() !=
136 GTEST_SKIP() <<
"This test works with OpenGL handles is only suitable for "
142 const auto& gl = gl_context.GetReactor()->GetProcTable();
144 constexpr
ISize external_texture_size = {200, 300};
148 texture_data.
Truncate(
Bytes{external_texture_size.Area() * 4u},
false));
152 for (
size_t i = 0; i < external_texture_size.Area() * 4u; i += 4u) {
153 memcpy(texture_data.
GetBuffer() + i, kClearColor.data(), 4);
156 GLuint external_texture = GL_NONE;
157 gl.GenTextures(1u, &external_texture);
158 ASSERT_NE(external_texture, 0u);
159 gl.BindTexture(GL_TEXTURE_2D, external_texture);
160 gl.TexImage2D(GL_TEXTURE_2D,
163 external_texture_size.width,
164 external_texture_size.height,
173 desc.
size = {external_texture_size.
width, external_texture_size.height};
180 ASSERT_TRUE(texture);
190 auto dl = Adopt<DisplayList>(
193 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
200 auto context = GetInteropContext();
201 auto impeller_context = context->GetContext();
202 if (impeller_context->GetBackendType() !=
204 GTEST_SKIP() <<
"This test works with OpenGL handles is only suitable for "
209 const auto& gl = gl_context.GetReactor()->GetProcTable();
217 color = {1.0, 0.0, 0.0, 1.0};
223 auto dl = Adopt<DisplayList>(
227 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
231 GLboolean stencil_enabled =
true;
232 gl.GetBooleanv(GL_STENCIL_TEST, &stencil_enabled);
233 return stencil_enabled == GL_FALSE;
239 hpp::TypographyContext type_context;
240 ASSERT_TRUE(type_context);
243 hpp::ParagraphBuilder builder(type_context);
244 ASSERT_TRUE(builder);
248 hpp::ParagraphStyle style;
250 style.SetFontSize(150.0f);
251 style.SetHeight(2.0f);
256 paint.SetColor({1.0, 0.0, 0.0, 1.0});
257 style.SetForeground(paint);
262 paint.SetColor({1.0, 1.0, 1.0, 1.0});
263 style.SetBackground(paint);
267 builder.PushStyle(style);
268 std::string text =
"the ⚡️ quick ⚡️ brown 🦊 fox jumps over the lazy dog 🐶.";
271 builder.AddText(text);
274 auto paragraph = builder.Build(1200.0f);
275 ASSERT_TRUE(paragraph);
278 hpp::DisplayListBuilder dl_builder;
279 dl_builder.DrawParagraph(paragraph, {20, 20});
282 auto dl = dl_builder.Build();
285 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
286 hpp::Surface window(surface.GetC());
293 hpp::DisplayListBuilder builder;
295 hpp::Paint red_paint;
296 red_paint.SetColor({1.0, 0.0, 0.0, 1.0});
297 red_paint.SetStrokeWidth(10.0);
299 builder.Translate(10, 10);
300 builder.DrawRect({0, 0, 100, 100}, red_paint);
301 builder.Translate(100, 100);
302 builder.DrawOval({0, 0, 100, 100}, red_paint);
303 builder.Translate(100, 100);
304 builder.DrawLine({0, 0}, {100, 100}, red_paint);
306 builder.Translate(100, 100);
310 builder.DrawRoundedRect({0, 0, 100, 100}, radii, red_paint);
312 builder.Translate(100, 100);
313 builder.DrawPath(hpp::PathBuilder{}.AddOval({0, 0, 100, 100}).Build(),
316 auto dl = builder.Build();
318 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
319 hpp::Surface window(surface.GetC());
328 ASSERT_TRUE(type_context);
331 std::unique_ptr<fml::Mapping> font_data =
332 flutter::testing::OpenFixtureAsMapping(
"wtf.otf");
333 ASSERT_NE(font_data,
nullptr);
334 ASSERT_GT(font_data->GetSize(), 0u);
336 .
data = font_data->GetMapping(),
337 .length = font_data->GetSize(),
338 .on_release = [](
auto ctx) {
339 delete reinterpret_cast<fml::Mapping*
>(ctx);
347 ASSERT_TRUE(registered);
352 ASSERT_TRUE(builder);
371 std::string text =
"0F0F0F0";
375 reinterpret_cast<const uint8_t*
>(text.data()),
379 auto paragraph = Adopt<Paragraph>(
381 ASSERT_TRUE(paragraph);
389 auto dl = Adopt<DisplayList>(
393 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
400 hpp::DisplayListBuilder& builder,
401 hpp::ParagraphStyle& p_style,
402 const hpp::Paint& bg,
407 "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
415 builder.DrawRect(box_rect, fg);
419 p_style.SetForeground(fg);
420 p_style.SetBackground(bg);
421 p_style.SetTextAlignment(align);
423 hpp::ParagraphBuilder p_builder(tc);
424 p_builder.PushStyle(p_style);
425 p_builder.AddText(
reinterpret_cast<const uint8_t*
>(text),
sizeof(text));
427 auto left_p = p_builder.Build(box_rect.
width - 20.0);
429 float w = left_p.GetMaxWidth();
430 float h = left_p.GetHeight();
431 builder.DrawParagraph(left_p, pt);
436 builder.DrawRect(inner_box_rect, fg);
440 hpp::TypographyContext tc;
442 hpp::DisplayListBuilder builder;
444 hpp::ParagraphStyle p_style;
445 p_style.SetFontFamily(
"Roboto");
446 p_style.SetFontSize(24.0);
451 bg.SetColor(clear_color);
452 builder.DrawPaint(bg);
468 auto dl = builder.Build();
471 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
472 hpp::Surface window(surface.GetC());
479 hpp::DisplayListBuilder builder;
487 hpp::PathBuilder path_builder;
488 path_builder.AddRect(box);
490 builder.DrawShadow(path_builder.Build(), shadow_color, 4.0f,
false, 1.0f);
493 hpp::Paint red_paint;
496 builder.DrawRect(box, red_paint);
498 auto dl = builder.Build();
500 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
501 hpp::Surface window(surface.GetC());
508 hpp::TypographyContext type_context;
509 hpp::ParagraphBuilder paragraph_builder(type_context);
510 hpp::ParagraphStyle paragraph_style;
511 paragraph_style.SetFontSize(50);
512 paragraph_builder.PushStyle(paragraph_style);
513 const std::string text =
514 "🏁 Can 👨👨👦👦 Measure 🔍 Text\nAnd this is line "
515 "two.\nWhoa! Three lines. How high does this go?\r\nI stopped counting.";
516 const auto u16text = fml::Utf8ToUtf16(text);
517 ASSERT_NE(text.size(), u16text.size());
518 paragraph_builder.AddText(
reinterpret_cast<const uint8_t*
>(text.data()),
520 hpp::DisplayListBuilder builder;
523 hpp::Paragraph paragraph = paragraph_builder.Build(FLT_MAX);
524 const auto line_count = paragraph.GetLineCount();
525 ASSERT_EQ(line_count, 4u);
529 auto metrics = paragraph.GetLineMetrics();
530 ASSERT_GT(metrics.GetAscent(0), 0.0);
531 ASSERT_GT(metrics.GetUnscaledAscent(0), 0.0);
532 ASSERT_GT(metrics.GetDescent(0), 0.0);
533 ASSERT_GT(metrics.GetBaseline(0), 0.0);
534 ASSERT_TRUE(metrics.IsHardbreak(0));
535 ASSERT_DOUBLE_EQ(metrics.GetLeft(0), 0.0);
536 ASSERT_EQ(metrics.GetCodeUnitStartIndex(0), 0u);
537 ASSERT_EQ(metrics.GetCodeUnitEndIndexIncludingNewline(0),
538 metrics.GetCodeUnitEndIndex(0) + 1u);
539 ASSERT_GT(metrics.GetCodeUnitStartIndex(1), 0u);
541 ASSERT_EQ(metrics.GetCodeUnitEndIndex(3), u16text.size());
546 auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
548 ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeBegin(), 0u);
549 ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
550 fml::Utf8ToUtf16(
"🏁").size());
551 auto bounds = glyph.GetGraphemeClusterBounds();
552 ASSERT_GT(bounds.width, 0.0);
553 ASSERT_GT(bounds.height, 0.0);
554 ASSERT_FALSE(glyph.IsEllipsis());
560 auto glyph = paragraph.GlyphInfoAtParagraphCoordinates(0.0, 0.0);
562 ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
563 fml::Utf8ToUtf16(
"🏁").size());
568 auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
571 paragraph.GetWordBoundary(glyph.GetGraphemeClusterCodeUnitRangeEnd());
572 ASSERT_GT(range.end, 0u);
576 auto dl = builder.Build();
578 OpenPlaygroundHere([&](
const auto& context,
const auto& surface) ->
bool {
579 hpp::Surface window(surface.GetC());
Describes an allocation on the heap.
uint8_t * GetBuffer() const
Gets the pointer to the start of the allocation.
bool Truncate(Bytes length, bool npot=true)
Resize the underlying allocation to at least given number of bytes.
static ContextGLES & Cast(Context &base)
@ kImpellerTextDirectionLTR
@ kImpellerTextureSamplingLinear
@ kImpellerDrawStyleStroke
@ kImpellerColorSpaceSRGB
@ kImpellerTextAlignmentLeft
@ kImpellerTextAlignmentCenter
@ kImpellerTextAlignmentRight
@ kImpellerClipOperationDifference
@ kImpellerPixelFormatRGBA8888
std::shared_ptr< Context > CreateContext()
TEST_P(InteropPlaygroundTest, CanCreateContext)
static void DrawTextFrame(const hpp::TypographyContext &tc, hpp::DisplayListBuilder &builder, hpp::ParagraphStyle &p_style, const hpp::Paint &bg, ImpellerColor color, ImpellerTextAlignment align, float x_offset)
INSTANTIATE_PLAYGROUND_SUITE(InteropPlaygroundTest)
IMPELLER_EXTERN_C uint64_t ImpellerTextureGetOpenGLHandle(ImpellerTexture texture)
IMPELLER_EXTERN_C ImpellerSurface ImpellerSurfaceCreateWrappedFBONew(ImpellerContext context, uint64_t fbo, ImpellerPixelFormat format, const ImpellerISize *size)
IMPELLER_EXTERN_C ImpellerDisplayList ImpellerDisplayListBuilderCreateDisplayListNew(ImpellerDisplayListBuilder builder)
IMPELLER_EXTERN_C ImpellerParagraphBuilder ImpellerParagraphBuilderNew(ImpellerTypographyContext context)
IMPELLER_EXTERN_C ImpellerDisplayListBuilder ImpellerDisplayListBuilderNew(const ImpellerRect *cull_rect)
IMPELLER_EXTERN_C ImpellerPaint ImpellerPaintNew()
IMPELLER_EXTERN_C ImpellerParagraph ImpellerParagraphBuilderBuildParagraphNew(ImpellerParagraphBuilder paragraph_builder, float width)
IMPELLER_EXTERN_C void ImpellerParagraphBuilderPushStyle(ImpellerParagraphBuilder paragraph_builder, ImpellerParagraphStyle style)
IMPELLER_EXTERN_C ImpellerTypographyContext ImpellerTypographyContextNew()
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderClipRect(ImpellerDisplayListBuilder builder, const ImpellerRect *rect, ImpellerClipOperation op)
constexpr Matrix ToImpellerType(const ImpellerMatrix &m)
IMPELLER_EXTERN_C ImpellerTexture ImpellerTextureCreateWithOpenGLTextureHandleNew(ImpellerContext context, const ImpellerTextureDescriptor *descriptor, uint64_t external_gl_handle)
IMPELLER_EXTERN_C ImpellerTexture ImpellerTextureCreateWithContentsNew(ImpellerContext context, const ImpellerTextureDescriptor *descriptor, const ImpellerMapping *contents, void *contents_on_release_user_data)
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderTransform(ImpellerDisplayListBuilder builder, const ImpellerMatrix *transform)
IMPELLER_EXTERN_C bool ImpellerTypographyContextRegisterFont(ImpellerTypographyContext context, const ImpellerMapping *contents, void *contents_on_release_user_data, const char *family_name_alias)
IMPELLER_EXTERN_C void ImpellerParagraphStyleSetFontSize(ImpellerParagraphStyle paragraph_style, float size)
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderDrawParagraph(ImpellerDisplayListBuilder builder, ImpellerParagraph paragraph, const ImpellerPoint *point)
IMPELLER_EXTERN_C void ImpellerParagraphStyleSetFontFamily(ImpellerParagraphStyle paragraph_style, const char *family_name)
IMPELLER_EXTERN_C bool ImpellerSurfaceDrawDisplayList(ImpellerSurface surface, ImpellerDisplayList display_list)
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderTranslate(ImpellerDisplayListBuilder builder, float x_translation, float y_translation)
IMPELLER_EXTERN_C void ImpellerParagraphStyleSetForeground(ImpellerParagraphStyle paragraph_style, ImpellerPaint paint)
IMPELLER_EXTERN_C ImpellerParagraphStyle ImpellerParagraphStyleNew()
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderDrawTexture(ImpellerDisplayListBuilder builder, ImpellerTexture texture, const ImpellerPoint *point, ImpellerTextureSampling sampling, ImpellerPaint paint)
IMPELLER_EXTERN_C void ImpellerDisplayListBuilderDrawRect(ImpellerDisplayListBuilder builder, const ImpellerRect *rect, ImpellerPaint paint)
IMPELLER_EXTERN_C void ImpellerPaintSetColor(ImpellerPaint paint, const ImpellerColor *color)
IMPELLER_EXTERN_C void ImpellerParagraphBuilderAddText(ImpellerParagraphBuilder paragraph_builder, const uint8_t *data, uint32_t length)
const uint8_t *IMPELLER_NONNULL data
ImpellerPoint bottom_right
ImpellerPixelFormat pixel_format
constexpr std::array< uint8_t, 4 > ToR8G8B8A8() const
Convert to R8G8B8A8 representation.
static constexpr Color Fuchsia()
constexpr bool IsIdentity() const