15#include "impeller/toolkit/interop/impeller.hpp"
39 hpp::DisplayListBuilder builder;
42 ASSERT_EQ(builder.GetSaveCount(), 1u);
44 ASSERT_EQ(builder.GetSaveCount(), 2u);
46 ASSERT_EQ(builder.GetSaveCount(), 1u);
53 <<
"This test checks wrapping FBOs which is an OpenGL ES only call.";
58 const auto window_size = GetWindowSize();
63 ImpellerPixelFormat::kImpellerPixelFormatRGBA8888,
77 color = {1.0, 0.0, 0.0, 1.0};
90 auto dl = Adopt<DisplayList>(
94 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
101 auto compressed = LoadFixtureImageCompressed(
103 ASSERT_NE(compressed,
nullptr);
104 auto decompressed = std::make_shared<impeller::DecompressedImage>(
105 compressed->Decode().ConvertToRGBA());
106 ASSERT_TRUE(decompressed->IsValid());
107 auto mapping = std::make_unique<hpp::Mapping>(
108 decompressed->GetAllocation()->GetMapping(),
109 decompressed->GetAllocation()->GetSize(), [decompressed]() {
113 auto context = GetHPPContext();
115 desc.
pixel_format = ImpellerPixelFormat::kImpellerPixelFormatRGBA8888;
116 desc.
size = {decompressed->GetSize().
width, decompressed->GetSize().height};
118 auto texture = hpp::Texture::WithContents(
context, desc, std::move(mapping));
121 auto dl = hpp::DisplayListBuilder{}
122 .DrawTexture(
texture, {100, 100},
127 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
135 auto context = GetInteropContext();
137 auto impeller_context =
context->GetContext();
139 if (impeller_context->GetBackendType() !=
141 GTEST_SKIP() <<
"This test works with OpenGL handles is only suitable for "
147 const auto& gl = gl_context.GetReactor()->GetProcTable();
149 constexpr ISize external_texture_size = {200, 300};
153 texture_data.
Truncate(
Bytes{external_texture_size.Area() * 4u},
false));
157 for (
size_t i = 0;
i < external_texture_size.
Area() * 4u;
i += 4u) {
158 memcpy(texture_data.
GetBuffer() +
i, kClearColor.data(), 4);
161 GLuint external_texture = GL_NONE;
162 gl.GenTextures(1u, &external_texture);
163 ASSERT_NE(external_texture, 0u);
164 gl.BindTexture(GL_TEXTURE_2D, external_texture);
165 gl.TexImage2D(GL_TEXTURE_2D,
168 external_texture_size.
width,
169 external_texture_size.
height,
177 desc.
pixel_format = ImpellerPixelFormat::kImpellerPixelFormatRGBA8888;
178 desc.
size = {external_texture_size.
width, external_texture_size.
height};
195 auto dl = Adopt<DisplayList>(
198 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
205 auto context = GetInteropContext();
206 auto impeller_context =
context->GetContext();
207 if (impeller_context->GetBackendType() !=
209 GTEST_SKIP() <<
"This test works with OpenGL handles is only suitable for "
214 const auto& gl = gl_context.GetReactor()->GetProcTable();
222 color = {1.0, 0.0, 0.0, 1.0};
228 auto dl = Adopt<DisplayList>(
232 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
236 GLboolean stencil_enabled =
true;
237 gl.GetBooleanv(GL_STENCIL_TEST, &stencil_enabled);
238 return stencil_enabled == GL_FALSE;
244 hpp::TypographyContext type_context;
245 ASSERT_TRUE(type_context);
248 hpp::ParagraphBuilder builder(type_context);
249 ASSERT_TRUE(builder);
253 hpp::ParagraphStyle style;
255 style.SetFontSize(150.0f);
256 style.SetHeight(2.0f);
261 paint.SetColor({1.0, 0.0, 0.0, 1.0});
262 style.SetForeground(paint);
267 paint.SetColor({1.0, 1.0, 1.0, 1.0});
268 style.SetBackground(paint);
272 builder.PushStyle(style);
273 std::string
text =
"the ⚡️ quick ⚡️ brown 🦊 fox jumps over the lazy dog 🐶.";
276 builder.AddText(
text);
279 auto paragraph = builder.Build(1200.0f);
280 ASSERT_TRUE(paragraph);
283 hpp::DisplayListBuilder dl_builder;
284 dl_builder.DrawParagraph(paragraph, {20, 20});
287 auto dl = dl_builder.Build();
290 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
298 hpp::TypographyContext
context;
302 hpp::ParagraphStyle{}
303 .SetForeground(hpp::Paint{}.SetColor({1.0, 0.0, 0.0, 1.0}))
310 .thickness_multiplier = 1.5,
312 .AddText(std::string{
"Holy text decorations Batman!"})
314 auto dl = hpp::DisplayListBuilder{}.DrawParagraph(para, {100, 100}).Build();
316 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
324 hpp::DisplayListBuilder builder;
326 hpp::Paint red_paint;
327 red_paint.SetColor({1.0, 0.0, 0.0, 1.0});
328 red_paint.SetStrokeWidth(10.0);
330 builder.Translate(10, 10);
331 builder.DrawRect({0, 0, 100, 100}, red_paint);
332 builder.Translate(100, 100);
333 builder.DrawOval({0, 0, 100, 100}, red_paint);
334 builder.Translate(100, 100);
335 builder.DrawLine({0, 0}, {100, 100}, red_paint);
337 builder.Translate(100, 100);
341 builder.DrawRoundedRect({0, 0, 100, 100}, radii, red_paint);
343 builder.Translate(100, 100);
344 builder.DrawPath(hpp::PathBuilder{}.AddOval({0, 0, 100, 100}).Build(),
347 auto dl = builder.Build();
349 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
359 ASSERT_TRUE(type_context);
362 std::unique_ptr<fml::Mapping> font_data =
364 ASSERT_NE(font_data,
nullptr);
365 ASSERT_GT(font_data->GetSize(), 0u);
367 .
data = font_data->GetMapping(),
368 .length = font_data->GetSize(),
369 .on_release = [](
auto ctx) {
378 ASSERT_TRUE(registered);
383 ASSERT_TRUE(builder);
402 std::string
text =
"0F0F0F0";
406 reinterpret_cast<const uint8_t*
>(
text.data()),
410 auto paragraph = Adopt<Paragraph>(
412 ASSERT_TRUE(paragraph);
420 auto dl = Adopt<DisplayList>(
424 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
431 hpp::DisplayListBuilder& builder,
432 hpp::ParagraphStyle& p_style,
433 const hpp::Paint& bg,
438 "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
446 builder.DrawRect(box_rect, fg);
450 p_style.SetForeground(fg);
451 p_style.SetBackground(bg);
452 p_style.SetTextAlignment(align);
454 hpp::ParagraphBuilder p_builder(tc);
455 p_builder.PushStyle(p_style);
456 p_builder.AddText(
reinterpret_cast<const uint8_t*
>(
text),
sizeof(
text));
458 auto left_p = p_builder.Build(box_rect.
width - 20.0);
460 float w = left_p.GetMaxWidth();
461 float h = left_p.GetHeight();
462 builder.DrawParagraph(left_p, pt);
467 builder.DrawRect(inner_box_rect, fg);
471 hpp::TypographyContext tc;
473 hpp::DisplayListBuilder builder;
475 hpp::ParagraphStyle p_style;
476 p_style.SetFontFamily(
"Roboto");
477 p_style.SetFontSize(24.0);
482 bg.SetColor(clear_color);
483 builder.DrawPaint(bg);
499 auto dl = builder.Build();
502 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
510 hpp::DisplayListBuilder builder;
518 hpp::PathBuilder path_builder;
519 path_builder.AddRect(box);
521 builder.DrawShadow(path_builder.Build(), shadow_color, 4.0f,
false, 1.0f);
524 hpp::Paint red_paint;
527 builder.DrawRect(box, red_paint);
529 auto dl = builder.Build();
531 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
539 hpp::TypographyContext type_context;
540 hpp::ParagraphBuilder paragraph_builder(type_context);
541 hpp::ParagraphStyle paragraph_style;
542 paragraph_style.SetFontSize(50);
543 paragraph_builder.PushStyle(paragraph_style);
544 const std::string
text =
545 "🏁 Can 👨👨👦👦 Measure 🔍 Text\nAnd this is line "
546 "two.\nWhoa! Three lines. How high does this go?\r\nI stopped counting.";
548 ASSERT_NE(
text.size(), u16text.size());
549 paragraph_builder.AddText(
reinterpret_cast<const uint8_t*
>(
text.data()),
551 hpp::DisplayListBuilder builder;
554 hpp::Paragraph paragraph = paragraph_builder.Build(FLT_MAX);
555 const auto line_count = paragraph.GetLineCount();
556 ASSERT_EQ(line_count, 4u);
560 auto metrics = paragraph.GetLineMetrics();
561 ASSERT_GT(metrics.GetAscent(0), 0.0);
562 ASSERT_GT(metrics.GetUnscaledAscent(0), 0.0);
563 ASSERT_GT(metrics.GetDescent(0), 0.0);
564 ASSERT_GT(metrics.GetBaseline(0), 0.0);
565 ASSERT_TRUE(metrics.IsHardbreak(0));
566 ASSERT_DOUBLE_EQ(metrics.GetLeft(0), 0.0);
567 ASSERT_EQ(metrics.GetCodeUnitStartIndex(0), 0u);
568 ASSERT_EQ(metrics.GetCodeUnitEndIndexIncludingNewline(0),
569 metrics.GetCodeUnitEndIndex(0) + 1u);
570 ASSERT_GT(metrics.GetCodeUnitStartIndex(1), 0u);
572 ASSERT_EQ(metrics.GetCodeUnitEndIndex(3), u16text.size());
577 auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
579 ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeBegin(), 0u);
580 ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
582 auto bounds = glyph.GetGraphemeClusterBounds();
583 ASSERT_GT(bounds.width, 0.0);
584 ASSERT_GT(bounds.height, 0.0);
585 ASSERT_FALSE(glyph.IsEllipsis());
590 ASSERT_EQ(bounds.width, bounds2.
width);
591 ASSERT_EQ(bounds.height, bounds2.
height);
596 auto glyph = paragraph.GlyphInfoAtParagraphCoordinates(0.0, 0.0);
598 ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(),
604 auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u);
607 paragraph.GetWordBoundary(glyph.GetGraphemeClusterCodeUnitRangeEnd());
608 ASSERT_GT(range.end, 0u);
611 paragraph.Get(), glyph.GetGraphemeClusterCodeUnitRangeEnd(), &range2);
612 ASSERT_EQ(range.start, range2.
start);
613 ASSERT_EQ(range.end, range2.
end);
617 auto dl = builder.Build();
619 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
628 hpp::PathBuilder{}.MoveTo({100, 100}).
LineTo({200, 200}).Build();
629 const auto bounds = path.GetBounds();
630 ASSERT_EQ(bounds.x, 100);
631 ASSERT_EQ(bounds.y, 100);
632 ASSERT_EQ(bounds.width, 100);
633 ASSERT_EQ(bounds.height, 100);
637 hpp::TypographyContext
context;
638 auto style = hpp::ParagraphStyle{};
639 style.SetFontSize(50);
640 style.SetForeground(hpp::Paint{}.SetColor({.red = 1.0, .alpha = 1.0}));
641 const auto text = std::string{
"The quick brown fox jumped over the lazy dog"};
642 style.SetEllipsis(
"🐶");
644 hpp::ParagraphBuilder{
context}.PushStyle(style).AddText(
text).Build(250);
645 style.SetForeground(hpp::Paint{}.SetColor({.green = 1.0, .alpha = 1.0}));
646 style.SetEllipsis(
nullptr);
648 hpp::ParagraphBuilder{
context}.PushStyle(style).AddText(
text).Build(250);
649 auto dl = hpp::DisplayListBuilder{}
650 .DrawParagraph(para1, {100, 100})
651 .DrawParagraph(para2, {100, 200})
654 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
662 auto iplr = OpenAssetAsHPPMapping(
"interop_runtime_stage_cs.frag.iplr");
664 auto program = hpp::FragmentProgram::WithData(std::move(iplr));
665 ASSERT_TRUE(program);
666 auto context = GetHPPContext();
668 hpp::ImageFilter::FragmentProgram(
context, program, {},
nullptr);
670 auto bay_bridge = OpenAssetAsHPPTexture(
"bay_bridge.jpg");
671 ASSERT_TRUE(bay_bridge);
673 float size_data[4] = {500, 500};
674 auto uniform_data = hpp::Mapping{
reinterpret_cast<const uint8_t*
>(&size_data),
675 sizeof(size_data),
nullptr};
677 auto dl = hpp::DisplayListBuilder{}
678 .DrawRect({10, 10, 500, 500},
680 .SetColor({1.0, 1.0, 1.0, 1.0})
681 .SetColorSource(hpp::ColorSource::FragmentProgram(
689 OpenPlaygroundHere([&](
const auto&
context,
const auto&
surface) ->
bool {
697 bool deleted =
false;
699 hpp::Mapping mapping(
nullptr, 0, [&deleted]() { deleted =
true; });
701 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
std::unique_ptr< fml::Mapping > OpenFixtureAsMapping(const std::string &fixture_name)
Opens a fixture of the given file name and returns a mapping to its contents.
std::u16string Utf8ToUtf16(const std::string_view string)
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)
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)
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
std::shared_ptr< ContextGLES > context
const uint8_t *IMPELLER_NONNULL data
ImpellerPoint bottom_right
int types
A mask of ImpellerTextDecorationTypes to enable.
ImpellerPixelFormat pixel_format
static constexpr Color Fuchsia()
std::array< uint8_t, 4 > ToR8G8B8A8() const
Convert to R8G8B8A8 representation.
constexpr bool IsIdentity() const
constexpr Type Area() const