5 #include "flutter/fml/native_library.h" 
    6 #include "flutter/fml/string_conversion.h" 
    7 #include "flutter/testing/testing.h" 
   39   hpp::DisplayListBuilder builder;
 
   42   ASSERT_EQ(builder.GetSaveCount(), 1u);
 
   44   ASSERT_EQ(builder.GetSaveCount(), 2u);
 
   46   ASSERT_EQ(builder.GetSaveCount(), 1u);
 
   52         << 
"This test checks wrapping FBOs which is an OpenGL ES only call.";
 
   57   const auto window_size = GetWindowSize();
 
   76   color = {1.0, 0.0, 0.0, 1.0};
 
   89   auto dl = Adopt<DisplayList>(
 
   93       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  100   auto compressed = LoadFixtureImageCompressed(
 
  101       flutter::testing::OpenFixtureAsMapping(
"boston.jpg"));
 
  102   ASSERT_NE(compressed, 
nullptr);
 
  103   auto decompressed = std::make_shared<impeller::DecompressedImage>(
 
  104       compressed->Decode().ConvertToRGBA());
 
  105   ASSERT_TRUE(decompressed->IsValid());
 
  106   auto mapping = std::make_unique<hpp::Mapping>(
 
  107       decompressed->GetAllocation()->GetMapping(),
 
  108       decompressed->GetAllocation()->GetSize(), [decompressed]() {
 
  112   auto context = GetHPPContext();
 
  115   desc.
size = {decompressed->GetSize().
width, decompressed->GetSize().height};
 
  117   auto texture = hpp::Texture::WithContents(context, desc, std::move(mapping));
 
  118   ASSERT_TRUE(texture);
 
  120   auto dl = hpp::DisplayListBuilder{}
 
  121                 .DrawTexture(texture, {100, 100},
 
  126       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  127         hpp::Surface window(surface.GetC());
 
  134   auto context = GetInteropContext();
 
  136   auto impeller_context = context->GetContext();
 
  138   if (impeller_context->GetBackendType() !=
 
  140     GTEST_SKIP() << 
"This test works with OpenGL handles is only suitable for " 
  146   const auto& gl = gl_context.GetReactor()->GetProcTable();
 
  148   constexpr 
ISize external_texture_size = {200, 300};
 
  152       texture_data.
Truncate(
Bytes{external_texture_size.Area() * 4u}, 
false));
 
  156   for (
size_t i = 0; i < external_texture_size.Area() * 4u; i += 4u) {
 
  157     memcpy(texture_data.
GetBuffer() + i, kClearColor.data(), 4);
 
  160   GLuint external_texture = GL_NONE;
 
  161   gl.GenTextures(1u, &external_texture);
 
  162   ASSERT_NE(external_texture, 0u);
 
  163   gl.BindTexture(GL_TEXTURE_2D, external_texture);
 
  164   gl.TexImage2D(GL_TEXTURE_2D,                 
 
  167                 external_texture_size.width,   
 
  168                 external_texture_size.height,  
 
  177   desc.
size = {external_texture_size.
width, external_texture_size.height};
 
  184   ASSERT_TRUE(texture);
 
  194   auto dl = Adopt<DisplayList>(
 
  197       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  204   auto context = GetInteropContext();
 
  205   auto impeller_context = context->GetContext();
 
  206   if (impeller_context->GetBackendType() !=
 
  208     GTEST_SKIP() << 
"This test works with OpenGL handles is only suitable for " 
  213   const auto& gl = gl_context.GetReactor()->GetProcTable();
 
  221   color = {1.0, 0.0, 0.0, 1.0};
 
  227   auto dl = Adopt<DisplayList>(
 
  231       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  235         GLboolean stencil_enabled = 
true;
 
  236         gl.GetBooleanv(GL_STENCIL_TEST, &stencil_enabled);
 
  237         return stencil_enabled == GL_FALSE;
 
  243   hpp::TypographyContext type_context;
 
  244   ASSERT_TRUE(type_context);
 
  247   hpp::ParagraphBuilder builder(type_context);
 
  248   ASSERT_TRUE(builder);
 
  252   hpp::ParagraphStyle style;
 
  254   style.SetFontSize(150.0f);
 
  255   style.SetHeight(2.0f);
 
  260     paint.SetColor({1.0, 0.0, 0.0, 1.0});
 
  261     style.SetForeground(paint);
 
  266     paint.SetColor({1.0, 1.0, 1.0, 1.0});
 
  267     style.SetBackground(paint);
 
  271   builder.PushStyle(style);
 
  272   std::string text = 
"the ⚡️ quick ⚡️ brown 🦊 fox jumps over the lazy dog 🐶.";
 
  275   builder.AddText(text);
 
  278   auto paragraph = builder.Build(1200.0f);
 
  279   ASSERT_TRUE(paragraph);
 
  282   hpp::DisplayListBuilder dl_builder;
 
  283   dl_builder.DrawParagraph(paragraph, {20, 20});
 
  286   auto dl = dl_builder.Build();
 
  289       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  290         hpp::Surface window(surface.GetC());
 
  297   hpp::TypographyContext context;
 
  299       hpp::ParagraphBuilder(context)
 
  301               hpp::ParagraphStyle{}
 
  302                   .SetForeground(hpp::Paint{}.SetColor({1.0, 0.0, 0.0, 1.0}))
 
  309                       .thickness_multiplier = 1.5,
 
  311           .AddText(std::string{
"Holy text decorations Batman!"})
 
  313   auto dl = hpp::DisplayListBuilder{}.DrawParagraph(para, {100, 100}).Build();
 
  315       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  316         hpp::Surface window(surface.GetC());
 
  323   hpp::DisplayListBuilder builder;
 
  325   hpp::Paint red_paint;
 
  326   red_paint.SetColor({1.0, 0.0, 0.0, 1.0});
 
  327   red_paint.SetStrokeWidth(10.0);
 
  329   builder.Translate(10, 10);
 
  330   builder.DrawRect({0, 0, 100, 100}, red_paint);
 
  331   builder.Translate(100, 100);
 
  332   builder.DrawOval({0, 0, 100, 100}, red_paint);
 
  333   builder.Translate(100, 100);
 
  334   builder.DrawLine({0, 0}, {100, 100}, red_paint);
 
  336   builder.Translate(100, 100);
 
  340   builder.DrawRoundedRect({0, 0, 100, 100}, radii, red_paint);
 
  342   builder.Translate(100, 100);
 
  346   auto dl = builder.Build();
 
  348       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  349         hpp::Surface window(surface.GetC());
 
  358   ASSERT_TRUE(type_context);
 
  361   std::unique_ptr<fml::Mapping> font_data =
 
  362       flutter::testing::OpenFixtureAsMapping(
"wtf.otf");
 
  363   ASSERT_NE(font_data, 
nullptr);
 
  364   ASSERT_GT(font_data->GetSize(), 0u);
 
  366       .
data = font_data->GetMapping(),
 
  367       .length = font_data->GetSize(),
 
  368       .on_release = [](
auto ctx) {
 
  369         delete reinterpret_cast<fml::Mapping*
>(ctx);
 
  377   ASSERT_TRUE(registered);
 
  382   ASSERT_TRUE(builder);
 
  401   std::string text = 
"0F0F0F0";
 
  405                                   reinterpret_cast<const uint8_t*
>(text.data()),
 
  409   auto paragraph = Adopt<Paragraph>(
 
  411   ASSERT_TRUE(paragraph);
 
  419   auto dl = Adopt<DisplayList>(
 
  423       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  430                           hpp::DisplayListBuilder& builder,
 
  431                           hpp::ParagraphStyle& p_style,
 
  432                           const hpp::Paint& bg,
 
  437       "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
 
  445   builder.DrawRect(box_rect, fg);
 
  449   p_style.SetForeground(fg);
 
  450   p_style.SetBackground(bg);
 
  451   p_style.SetTextAlignment(align);
 
  453   hpp::ParagraphBuilder p_builder(tc);
 
  454   p_builder.PushStyle(p_style);
 
  455   p_builder.AddText(
reinterpret_cast<const uint8_t*
>(text), 
sizeof(text));
 
  457   auto left_p = p_builder.Build(box_rect.
width - 20.0);
 
  459   float w = left_p.GetMaxWidth();
 
  460   float h = left_p.GetHeight();
 
  461   builder.DrawParagraph(left_p, pt);
 
  466   builder.DrawRect(inner_box_rect, fg);
 
  470   hpp::TypographyContext tc;
 
  472   hpp::DisplayListBuilder builder;
 
  474   hpp::ParagraphStyle p_style;
 
  475   p_style.SetFontFamily(
"Roboto");
 
  476   p_style.SetFontSize(24.0);
 
  481   bg.SetColor(clear_color);
 
  482   builder.DrawPaint(bg);
 
  498   auto dl = builder.Build();
 
  501       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  502         hpp::Surface window(surface.GetC());
 
  509   hpp::DisplayListBuilder builder;
 
  518     path_builder.AddRect(box);
 
  520     builder.DrawShadow(path_builder.Build(), shadow_color, 4.0f, 
false, 1.0f);
 
  523     hpp::Paint red_paint;
 
  526     builder.DrawRect(box, red_paint);
 
  528   auto dl = builder.Build();
 
  530       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  531         hpp::Surface window(surface.GetC());
 
  538   hpp::TypographyContext type_context;
 
  539   hpp::ParagraphBuilder paragraph_builder(type_context);
 
  540   hpp::ParagraphStyle paragraph_style;
 
  541   paragraph_style.SetFontSize(50);
 
  542   paragraph_builder.PushStyle(paragraph_style);
 
  543   const std::string text =
 
  544       "🏁 Can 👨👨👦👦 Measure 🔍 Text\nAnd this is line " 
  545       "two.\nWhoa! Three lines. How high does this go?\r\nI stopped counting.";
 
  546   const auto u16text = fml::Utf8ToUtf16(text);
 
  547   ASSERT_NE(text.size(), u16text.size());
 
  548   paragraph_builder.AddText(
reinterpret_cast<const uint8_t*
>(text.data()),
 
  550   hpp::DisplayListBuilder builder;
 
  553   hpp::Paragraph paragraph = paragraph_builder.Build(FLT_MAX);
 
  554   const auto line_count = paragraph.GetLineCount();
 
  555   ASSERT_EQ(line_count, 4u);
 
  559     auto metrics = paragraph.GetLineMetrics();
 
  560     ASSERT_GT(metrics.GetAscent(0), 0.0);
 
  561     ASSERT_GT(metrics.GetUnscaledAscent(0), 0.0);
 
  562     ASSERT_GT(metrics.GetDescent(0), 0.0);
 
  563     ASSERT_GT(metrics.GetBaseline(0), 0.0);
 
  564     ASSERT_TRUE(metrics.IsHardbreak(0));
 
  565     ASSERT_DOUBLE_EQ(metrics.GetLeft(0), 0.0);
 
  566     ASSERT_EQ(metrics.GetCodeUnitStartIndex(0), 0u);
 
  567     ASSERT_EQ(metrics.GetCodeUnitEndIndexIncludingNewline(0),
 
  568               metrics.GetCodeUnitEndIndex(0) + 1u);
 
  569     ASSERT_GT(metrics.GetCodeUnitStartIndex(1), 0u);
 
  571     ASSERT_EQ(metrics.GetCodeUnitEndIndex(3), u16text.size());
 
  576     auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
 
  578     ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeBegin(), 0u);
 
  579     ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
 
  580               fml::Utf8ToUtf16(
"🏁").size());
 
  581     auto bounds = glyph.GetGraphemeClusterBounds();
 
  582     ASSERT_GT(bounds.width, 0.0);
 
  583     ASSERT_GT(bounds.height, 0.0);
 
  584     ASSERT_FALSE(glyph.IsEllipsis());
 
  589     ASSERT_EQ(bounds.width, bounds2.
width);
 
  590     ASSERT_EQ(bounds.height, bounds2.
height);
 
  595     auto glyph = paragraph.GlyphInfoAtParagraphCoordinates(0.0, 0.0);
 
  597     ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
 
  598               fml::Utf8ToUtf16(
"🏁").size());
 
  603     auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
 
  606         paragraph.GetWordBoundary(glyph.GetGraphemeClusterCodeUnitRangeEnd());
 
  607     ASSERT_GT(range.end, 0u);
 
  610         paragraph.Get(), glyph.GetGraphemeClusterCodeUnitRangeEnd(), &range2);
 
  611     ASSERT_EQ(range.start, range2.
start);
 
  612     ASSERT_EQ(range.end, range2.
end);
 
  616   auto dl = builder.Build();
 
  618       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  619         hpp::Surface window(surface.GetC());
 
  628   const auto bounds = path.GetBounds();
 
  629   ASSERT_EQ(bounds.x, 100);
 
  630   ASSERT_EQ(bounds.y, 100);
 
  631   ASSERT_EQ(bounds.width, 100);
 
  632   ASSERT_EQ(bounds.height, 100);
 
  636   hpp::TypographyContext context;
 
  637   auto style = hpp::ParagraphStyle{};
 
  638   style.SetFontSize(50);
 
  639   style.SetForeground(hpp::Paint{}.SetColor({.red = 1.0, .alpha = 1.0}));
 
  640   const auto text = std::string{
"The quick brown fox jumped over the lazy dog"};
 
  641   style.SetEllipsis(
"🐶");
 
  643       hpp::ParagraphBuilder{context}.PushStyle(style).AddText(text).Build(250);
 
  644   style.SetForeground(hpp::Paint{}.SetColor({.green = 1.0, .alpha = 1.0}));
 
  645   style.SetEllipsis(
nullptr);
 
  647       hpp::ParagraphBuilder{context}.PushStyle(style).AddText(text).Build(250);
 
  648   auto dl = hpp::DisplayListBuilder{}
 
  649                 .DrawParagraph(para1, {100, 100})
 
  650                 .DrawParagraph(para2, {100, 200})
 
  653       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  654         hpp::Surface window(surface.GetC());
 
  661   auto iplr = OpenAssetAsHPPMapping(
"interop_runtime_stage_cs.frag.iplr");
 
  663   auto program = hpp::FragmentProgram::WithData(std::move(iplr));
 
  664   ASSERT_TRUE(program);
 
  665   auto context = GetHPPContext();
 
  667       hpp::ImageFilter::FragmentProgram(context, program, {}, 
nullptr);
 
  669   auto bay_bridge = OpenAssetAsHPPTexture(
"bay_bridge.jpg");
 
  670   ASSERT_TRUE(bay_bridge);
 
  672   float size_data[4] = {500, 500};
 
  673   auto uniform_data = hpp::Mapping{
reinterpret_cast<const uint8_t*
>(&size_data),
 
  674                                    sizeof(size_data), 
nullptr};
 
  676   auto dl = hpp::DisplayListBuilder{}
 
  677                 .DrawRect({10, 10, 500, 500},
 
  679                               .SetColor({1.0, 1.0, 1.0, 1.0})
 
  680                               .SetColorSource(hpp::ColorSource::FragmentProgram(
 
  688       OpenPlaygroundHere([&](
const auto& context, 
const auto& surface) -> 
bool {
 
  689         hpp::Surface window(surface.GetC());
 
  696   bool deleted = 
false;
 
  698     hpp::Mapping mapping(
nullptr, 0, [&deleted]() { deleted = 
true; });
 
  700   ASSERT_TRUE(deleted);
 
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
@ kImpellerTextDecorationTypeLineThrough
@ kImpellerTextDecorationTypeUnderline
@ kImpellerTextDecorationStyleWavy
@ 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 void ImpellerParagraphGetWordBoundary(ImpellerParagraph paragraph, size_t code_unit_index, ImpellerRange *out_range)
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 void ImpellerGlyphInfoGetGraphemeClusterBounds(ImpellerGlyphInfo glyph_info, ImpellerRect *out_bounds)
IMPELLER_EXTERN_C ImpellerTexture ImpellerTextureCreateWithOpenGLTextureHandleNew(ImpellerContext context, const ImpellerTextureDescriptor *descriptor, uint64_t external_gl_handle)
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)
flutter::DlPathBuilder PathBuilder
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
const uint8_t *IMPELLER_NONNULL data
ImpellerPoint bottom_right
int types
A mask of ImpellerTextDecorationTypes to enable.
ImpellerPixelFormat pixel_format
std::array< uint8_t, 4 > ToR8G8B8A8() const
Convert to R8G8B8A8 representation.
static constexpr Color Fuchsia()
constexpr bool IsIdentity() const