diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index ffbe0003f4..8fe7bf3855 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -51763,6 +51763,8 @@ ORIGIN: ../../../flutter/impeller/toolkit/interop/example_mtl.m + ../../../flutt ORIGIN: ../../../flutter/impeller/toolkit/interop/example_vk.c + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/formats.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/formats.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/glyph_info.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/glyph_info.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/image_filter.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/image_filter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller.cc + ../../../flutter/LICENSE @@ -51770,6 +51772,8 @@ ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller.h + ../../../flutter/ ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller.hpp + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller_c.c + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/impeller_cc.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/line_metrics.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/interop/line_metrics.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/mask_filter.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/mask_filter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/interop/object.cc + ../../../flutter/LICENSE @@ -54745,6 +54749,8 @@ FILE: ../../../flutter/impeller/toolkit/interop/example_mtl.m FILE: ../../../flutter/impeller/toolkit/interop/example_vk.c FILE: ../../../flutter/impeller/toolkit/interop/formats.cc FILE: ../../../flutter/impeller/toolkit/interop/formats.h +FILE: ../../../flutter/impeller/toolkit/interop/glyph_info.cc +FILE: ../../../flutter/impeller/toolkit/interop/glyph_info.h FILE: ../../../flutter/impeller/toolkit/interop/image_filter.cc FILE: ../../../flutter/impeller/toolkit/interop/image_filter.h FILE: ../../../flutter/impeller/toolkit/interop/impeller.cc @@ -54752,6 +54758,8 @@ FILE: ../../../flutter/impeller/toolkit/interop/impeller.h FILE: ../../../flutter/impeller/toolkit/interop/impeller.hpp FILE: ../../../flutter/impeller/toolkit/interop/impeller_c.c FILE: ../../../flutter/impeller/toolkit/interop/impeller_cc.cc +FILE: ../../../flutter/impeller/toolkit/interop/line_metrics.cc +FILE: ../../../flutter/impeller/toolkit/interop/line_metrics.h FILE: ../../../flutter/impeller/toolkit/interop/mask_filter.cc FILE: ../../../flutter/impeller/toolkit/interop/mask_filter.h FILE: ../../../flutter/impeller/toolkit/interop/object.cc diff --git a/engine/src/flutter/impeller/toolkit/interop/BUILD.gn b/engine/src/flutter/impeller/toolkit/interop/BUILD.gn index 2fcf715166..19622807ed 100644 --- a/engine/src/flutter/impeller/toolkit/interop/BUILD.gn +++ b/engine/src/flutter/impeller/toolkit/interop/BUILD.gn @@ -41,8 +41,12 @@ impeller_component("interop_base") { "dl_builder.h", "formats.cc", "formats.h", + "glyph_info.cc", + "glyph_info.h", "image_filter.cc", "image_filter.h", + "line_metrics.cc", + "line_metrics.h", "mask_filter.cc", "mask_filter.h", "object.cc", diff --git a/engine/src/flutter/impeller/toolkit/interop/glyph_info.cc b/engine/src/flutter/impeller/toolkit/interop/glyph_info.cc new file mode 100644 index 0000000000..93eb41ff43 --- /dev/null +++ b/engine/src/flutter/impeller/toolkit/interop/glyph_info.cc @@ -0,0 +1,42 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/toolkit/interop/glyph_info.h" + +namespace impeller::interop { + +GlyphInfo::~GlyphInfo() = default; + +size_t GlyphInfo::GetGraphemeClusterCodeUnitRangeBegin() const { + return info_.fGraphemeClusterTextRange.start; +} + +size_t GlyphInfo::GetGraphemeClusterCodeUnitRangeEnd() const { + return info_.fGraphemeClusterTextRange.end; +} + +ImpellerRect GlyphInfo::GetGraphemeClusterBounds() const { + return ImpellerRect{ + info_.fGraphemeLayoutBounds.y(), + info_.fGraphemeLayoutBounds.x(), + info_.fGraphemeLayoutBounds.width(), + info_.fGraphemeLayoutBounds.height(), + }; +} + +bool GlyphInfo::IsEllipsis() const { + return info_.fIsEllipsis; +} + +ImpellerTextDirection GlyphInfo::GetTextDirection() const { + switch (info_.fDirection) { + case skia::textlayout::TextDirection::kRtl: + return kImpellerTextDirectionRTL; + case skia::textlayout::TextDirection::kLtr: + return kImpellerTextDirectionLTR; + } + return kImpellerTextDirectionLTR; +} + +} // namespace impeller::interop diff --git a/engine/src/flutter/impeller/toolkit/interop/glyph_info.h b/engine/src/flutter/impeller/toolkit/interop/glyph_info.h new file mode 100644 index 0000000000..0b40e61fce --- /dev/null +++ b/engine/src/flutter/impeller/toolkit/interop/glyph_info.h @@ -0,0 +1,63 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_TOOLKIT_INTEROP_GLYPH_INFO_H_ +#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_GLYPH_INFO_H_ + +#include "flutter/third_party/skia/modules/skparagraph/include/Paragraph.h" +#include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/object.h" + +namespace impeller::interop { + +//------------------------------------------------------------------------------ +/// @brief Internal C++ peer of ImpellerGlyphInfo. For detailed +/// documentation, refer to the headerdocs in the public API in +/// impeller.h. +/// +class GlyphInfo final + : public Object { + public: + explicit GlyphInfo(skia::textlayout::Paragraph::GlyphInfo info) + : info_(info) {} + + ~GlyphInfo(); + + GlyphInfo(const GlyphInfo&) = delete; + + GlyphInfo& operator=(const GlyphInfo&) = delete; + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeBegin. + /// + size_t GetGraphemeClusterCodeUnitRangeBegin() const; + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeEnd. + /// + size_t GetGraphemeClusterCodeUnitRangeEnd() const; + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetGraphemeClusterBounds. + /// + ImpellerRect GetGraphemeClusterBounds() const; + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoIsEllipsis. + /// + bool IsEllipsis() const; + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetTextDirection. + /// + ImpellerTextDirection GetTextDirection() const; + + private: + const skia::textlayout::Paragraph::GlyphInfo info_; +}; + +} // namespace impeller::interop + +#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_GLYPH_INFO_H_ diff --git a/engine/src/flutter/impeller/toolkit/interop/impeller.cc b/engine/src/flutter/impeller/toolkit/interop/impeller.cc index ad55da1280..9913cc1fd1 100644 --- a/engine/src/flutter/impeller/toolkit/interop/impeller.cc +++ b/engine/src/flutter/impeller/toolkit/interop/impeller.cc @@ -17,7 +17,9 @@ #include "impeller/toolkit/interop/context.h" #include "impeller/toolkit/interop/dl_builder.h" #include "impeller/toolkit/interop/formats.h" +#include "impeller/toolkit/interop/glyph_info.h" #include "impeller/toolkit/interop/image_filter.h" +#include "impeller/toolkit/interop/line_metrics.h" #include "impeller/toolkit/interop/mask_filter.h" #include "impeller/toolkit/interop/object.h" #include "impeller/toolkit/interop/paint.h" @@ -58,7 +60,9 @@ DEFINE_PEER_GETTER(ColorSource, ImpellerColorSource); DEFINE_PEER_GETTER(Context, ImpellerContext); DEFINE_PEER_GETTER(DisplayList, ImpellerDisplayList); DEFINE_PEER_GETTER(DisplayListBuilder, ImpellerDisplayListBuilder); +DEFINE_PEER_GETTER(GlyphInfo, ImpellerGlyphInfo); DEFINE_PEER_GETTER(ImageFilter, ImpellerImageFilter); +DEFINE_PEER_GETTER(LineMetrics, ImpellerLineMetrics); DEFINE_PEER_GETTER(MaskFilter, ImpellerMaskFilter); DEFINE_PEER_GETTER(Paint, ImpellerPaint); DEFINE_PEER_GETTER(Paragraph, ImpellerParagraph); @@ -1272,6 +1276,12 @@ uint32_t ImpellerParagraphGetLineCount(ImpellerParagraph paragraph) { return GetPeer(paragraph)->GetLineCount(); } +IMPELLER_EXTERN_C +ImpellerRange ImpellerParagraphGetWordBoundary(ImpellerParagraph paragraph, + size_t code_unit_index) { + return GetPeer(paragraph)->GetWordBoundary(code_unit_index); +} + IMPELLER_EXTERN_C ImpellerTypographyContext ImpellerTypographyContextNew() { auto context = Create(); @@ -1309,4 +1319,154 @@ bool ImpellerTypographyContextRegisterFont(ImpellerTypographyContext context, family_name_alias); } +IMPELLER_EXTERN_C +ImpellerLineMetrics ImpellerParagraphGetLineMetrics( + ImpellerParagraph paragraph) { + return GetPeer(paragraph)->GetLineMetrics().GetC(); +} + +IMPELLER_EXTERN_C +ImpellerGlyphInfo ImpellerParagraphCreateGlyphInfoAtCodeUnitIndexNew( + ImpellerParagraph paragraph, + size_t code_unit_index) { + return GetPeer(paragraph) + ->GetGlyphInfoAtCodeUnitIndex(code_unit_index) + .Leak(); +} + +IMPELLER_EXTERN_C +ImpellerGlyphInfo ImpellerParagraphCreateGlyphInfoAtParagraphCoordinatesNew( + ImpellerParagraph paragraph, + double x, + double y) { + return GetPeer(paragraph) + ->GetClosestGlyphInfoAtParagraphCoordinates(x, y) + .Leak(); +} + +//------------------------------------------------------------------------------ +// Line Metrics +//------------------------------------------------------------------------------ + +IMPELLER_EXTERN_C +void ImpellerLineMetricsRetain(ImpellerLineMetrics line_metrics) { + ObjectBase::SafeRetain(line_metrics); +} + +IMPELLER_EXTERN_C +void ImpellerLineMetricsRelease(ImpellerLineMetrics line_metrics) { + ObjectBase::SafeRelease(line_metrics); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetUnscaledAscent(ImpellerLineMetrics metrics, + size_t line) { + return GetPeer(metrics)->GetUnscaledAscent(line); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetAscent(ImpellerLineMetrics metrics, size_t line) { + return GetPeer(metrics)->GetAscent(line); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetDescent(ImpellerLineMetrics metrics, size_t line) { + return GetPeer(metrics)->GetDescent(line); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetBaseline(ImpellerLineMetrics metrics, + size_t line) { + return GetPeer(metrics)->GetBaseline(line); +} + +IMPELLER_EXTERN_C +bool ImpellerLineMetricsIsHardbreak(ImpellerLineMetrics metrics, size_t line) { + return GetPeer(metrics)->IsHardbreak(line); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetWidth(ImpellerLineMetrics metrics, size_t line) { + return GetPeer(metrics)->GetWidth(line); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetHeight(ImpellerLineMetrics metrics, size_t line) { + return GetPeer(metrics)->GetHeight(line); +} + +IMPELLER_EXTERN_C +double ImpellerLineMetricsGetLeft(ImpellerLineMetrics metrics, size_t line) { + return GetPeer(metrics)->GetLeft(line); +} + +IMPELLER_EXTERN_C +size_t ImpellerLineMetricsGetCodeUnitStartIndex(ImpellerLineMetrics metrics, + size_t line) { + return GetPeer(metrics)->GetCodeUnitStartIndex(line); +} + +IMPELLER_EXTERN_C +size_t ImpellerLineMetricsGetCodeUnitEndIndex(ImpellerLineMetrics metrics, + size_t line) { + return GetPeer(metrics)->GetCodeUnitEndIndex(line); +} + +IMPELLER_EXTERN_C +size_t ImpellerLineMetricsGetCodeUnitEndIndexExcludingWhitespace( + ImpellerLineMetrics metrics, + size_t line) { + return GetPeer(metrics)->GetCodeUnitEndIndexExcludingWhitespace(line); +} + +IMPELLER_EXTERN_C +size_t ImpellerLineMetricsGetCodeUnitEndIndexIncludingNewline( + ImpellerLineMetrics metrics, + size_t line) { + return GetPeer(metrics)->GetCodeUnitEndIndexIncludingNewline(line); +} + +//------------------------------------------------------------------------------ +// Glyph Info +//------------------------------------------------------------------------------ + +IMPELLER_EXTERN_C +void ImpellerGlyphInfoRetain(ImpellerGlyphInfo glyph_info) { + ObjectBase::SafeRetain(glyph_info); +} + +IMPELLER_EXTERN_C +void ImpellerGlyphInfoRelease(ImpellerGlyphInfo glyph_info) { + ObjectBase::SafeRelease(glyph_info); +} + +IMPELLER_EXTERN_C +size_t ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeBegin( + ImpellerGlyphInfo glyph_info) { + return GetPeer(glyph_info)->GetGraphemeClusterCodeUnitRangeBegin(); +} + +IMPELLER_EXTERN_C +size_t ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeEnd( + ImpellerGlyphInfo glyph_info) { + return GetPeer(glyph_info)->GetGraphemeClusterCodeUnitRangeEnd(); +} + +IMPELLER_EXTERN_C +ImpellerRect ImpellerGlyphInfoGetGraphemeClusterBounds( + ImpellerGlyphInfo glyph_info) { + return GetPeer(glyph_info)->GetGraphemeClusterBounds(); +} + +IMPELLER_EXTERN_C +bool ImpellerGlyphInfoIsEllipsis(ImpellerGlyphInfo glyph_info) { + return GetPeer(glyph_info)->IsEllipsis(); +} + +IMPELLER_EXTERN_C +ImpellerTextDirection ImpellerGlyphInfoGetTextDirection( + ImpellerGlyphInfo glyph_info) { + return GetPeer(glyph_info)->GetTextDirection(); +} + } // namespace impeller::interop diff --git a/engine/src/flutter/impeller/toolkit/interop/impeller.h b/engine/src/flutter/impeller/toolkit/interop/impeller.h index 4d65a3cfd9..5f1b4589ab 100644 --- a/engine/src/flutter/impeller/toolkit/interop/impeller.h +++ b/engine/src/flutter/impeller/toolkit/interop/impeller.h @@ -246,6 +246,20 @@ IMPELLER_DEFINE_HANDLE(ImpellerParagraphBuilder); /// IMPELLER_DEFINE_HANDLE(ImpellerParagraphStyle); +//------------------------------------------------------------------------------ +/// Describes the metrics of lines in a fully laid out paragraph. +/// +/// Regardless of how the string of text is specified to the paragraph builder, +/// offsets into buffers that are returned by line metrics are always assumed to +/// be into buffers of UTF-16 code units. +/// +IMPELLER_DEFINE_HANDLE(ImpellerLineMetrics); + +//------------------------------------------------------------------------------ +/// Describes the metrics of glyphs in a paragraph line. +/// +IMPELLER_DEFINE_HANDLE(ImpellerGlyphInfo); + //------------------------------------------------------------------------------ /// Represents a two-dimensional path that is immutable and graphics context /// agnostic. @@ -483,6 +497,11 @@ typedef struct ImpellerISize { int64_t height; } ImpellerISize; +typedef struct ImpellerRange { + uint64_t start; + uint64_t end; +} ImpellerRange; + //------------------------------------------------------------------------------ /// A 4x4 transformation matrix using column-major storage. /// @@ -2610,6 +2629,335 @@ IMPELLER_EXPORT uint32_t ImpellerParagraphGetLineCount( ImpellerParagraph IMPELLER_NONNULL paragraph); +//------------------------------------------------------------------------------ +/// @brief Get the range into the UTF-16 code unit buffer that represents +/// the word at the specified caret location in the same buffer. +/// +/// Word boundaries are defined more precisely in [Unicode Standard +/// Annex #29](http://www.unicode.org/reports/tr29/#Word_Boundaries) +/// +/// @param[in] paragraph The paragraph +/// @param[in] code_unit_index The code unit index +/// +/// @return The impeller range. +/// +IMPELLER_EXPORT +ImpellerRange ImpellerParagraphGetWordBoundary( + ImpellerParagraph IMPELLER_NONNULL paragraph, + size_t code_unit_index); + +//------------------------------------------------------------------------------ +/// @brief Get the line metrics of this laid out paragraph. Calculating the +/// line metrics is expensive. The first time line metrics are +/// requested, they will be cached along with the paragraph (which +/// is immutable). +/// +/// @param[in] paragraph The paragraph. +/// +/// @return The line metrics. +/// +IMPELLER_EXPORT +ImpellerLineMetrics IMPELLER_NULLABLE ImpellerParagraphGetLineMetrics( + ImpellerParagraph IMPELLER_NONNULL paragraph); + +//------------------------------------------------------------------------------ +/// @brief Create a new instance of glyph info that can be queried for +/// information about the glyph at the given UTF-16 code unit index. +/// The instance must be freed using `ImpellerGlyphInfoRelease`. +/// +/// @param[in] paragraph The paragraph. +/// @param[in] code_unit_index The UTF-16 code unit index. +/// +/// @return The glyph information. +/// +IMPELLER_EXPORT +IMPELLER_NODISCARD ImpellerGlyphInfo IMPELLER_NULLABLE +ImpellerParagraphCreateGlyphInfoAtCodeUnitIndexNew( + ImpellerParagraph IMPELLER_NONNULL paragraph, + size_t code_unit_index); + +//------------------------------------------------------------------------------ +/// @brief Create a new instance of glyph info that can be queried for +/// information about the glyph closest to the specified coordinates +/// relative to the origin of the paragraph. The instance must be +/// freed using `ImpellerGlyphInfoRelease`. +/// +/// @param[in] paragraph The paragraph. +/// @param[in] x The x coordinate relative to paragraph origin. +/// @param[in] y The x coordinate relative to paragraph origin. +/// +/// @return The glyph information. +/// +IMPELLER_EXPORT +IMPELLER_NODISCARD ImpellerGlyphInfo IMPELLER_NULLABLE +ImpellerParagraphCreateGlyphInfoAtParagraphCoordinatesNew( + ImpellerParagraph IMPELLER_NONNULL paragraph, + double x, + double y); + +//------------------------------------------------------------------------------ +// Line Metrics +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// @brief Retain a strong reference to the object. The object can be NULL +/// in which case this method is a no-op. +/// +/// @param[in] line_metrics The line metrics. +/// +IMPELLER_EXPORT +void ImpellerLineMetricsRetain( + ImpellerLineMetrics IMPELLER_NULLABLE line_metrics); + +//------------------------------------------------------------------------------ +/// @brief Release a previously retained reference to the object. The +/// object can be NULL in which case this method is a no-op. +/// +/// @param[in] line_metrics The line metrics. +/// +IMPELLER_EXPORT +void ImpellerLineMetricsRelease( + ImpellerLineMetrics IMPELLER_NULLABLE line_metrics); + +//------------------------------------------------------------------------------ +/// @brief The rise from the baseline as calculated from the font and style +/// for this line ignoring the height from the text style. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The unscaled ascent. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetUnscaledAscent( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief The rise from the baseline as calculated from the font and style +/// for this line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The ascent. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetAscent( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief The drop from the baseline as calculated from the font and style +/// for this line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The descent. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetDescent( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief The y coordinate of the baseline for this line from the top of +/// the paragraph. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The baseline. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetBaseline( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Used to determine if this line ends with an explicit line break +/// (e.g. '\n') or is the end of the paragraph. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return True if the line is a hard break. +/// +IMPELLER_EXPORT +bool ImpellerLineMetricsIsHardbreak( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Width of the line from the left edge of the leftmost glyph to +/// the right edge of the rightmost glyph. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The width. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetWidth(ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Total height of the line from the top edge to the bottom edge. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The height. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetHeight( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief The x coordinate of left edge of the line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The left edge coordinate. +/// +IMPELLER_EXPORT +double ImpellerLineMetricsGetLeft(ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Fetch the start index in the buffer of UTF-16 code units used to +/// represent the paragraph line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The UTF-16 code units start index. +/// +IMPELLER_EXPORT +size_t ImpellerLineMetricsGetCodeUnitStartIndex( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Fetch the end index in the buffer of UTF-16 code units used to +/// represent the paragraph line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The UTF-16 code units end index. +/// +IMPELLER_EXPORT +size_t ImpellerLineMetricsGetCodeUnitEndIndex( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Fetch the end index (excluding whitespace) in the buffer of +/// UTF-16 code units used to represent the paragraph line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The UTF-16 code units end index excluding whitespace. +/// +IMPELLER_EXPORT +size_t ImpellerLineMetricsGetCodeUnitEndIndexExcludingWhitespace( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +/// @brief Fetch the end index (including newlines) in the buffer of UTF-16 +/// code units used to represent the paragraph line. +/// +/// @param[in] metrics The metrics. +/// @param[in] line The line index (zero based). +/// +/// @return The UTF-16 code units end index including newlines. +/// +IMPELLER_EXPORT +size_t ImpellerLineMetricsGetCodeUnitEndIndexIncludingNewline( + ImpellerLineMetrics IMPELLER_NONNULL metrics, + size_t line); + +//------------------------------------------------------------------------------ +// Glyph Info +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +/// @brief Retain a strong reference to the object. The object can be NULL +/// in which case this method is a no-op. +/// +/// @param[in] glyph_info The glyph information. +/// +IMPELLER_EXPORT +void ImpellerGlyphInfoRetain(ImpellerGlyphInfo IMPELLER_NULLABLE glyph_info); + +//------------------------------------------------------------------------------ +/// @brief Release a previously retained reference to the object. The +/// object can be NULL in which case this method is a no-op. +/// +/// @param[in] glyph_info The glyph information. +/// +IMPELLER_EXPORT +void ImpellerGlyphInfoRelease(ImpellerGlyphInfo IMPELLER_NULLABLE glyph_info); + +//------------------------------------------------------------------------------ +/// @brief Fetch the start index in the buffer of UTF-16 code units used to +/// represent the grapheme cluster for a glyph. +/// +/// @param[in] glyph_info The glyph information. +/// +/// @return The UTF-16 code units start index. +/// +IMPELLER_EXPORT +size_t ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeBegin( + ImpellerGlyphInfo IMPELLER_NONNULL glyph_info); + +//------------------------------------------------------------------------------ +/// @brief Fetch the end index in the buffer of UTF-16 code units used to +/// represent the grapheme cluster for a glyph. +/// +/// @param[in] glyph_info The glyph information. +/// +/// @return The UTF-16 code units end index. +/// +IMPELLER_EXPORT +size_t ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeEnd( + ImpellerGlyphInfo IMPELLER_NONNULL glyph_info); + +//------------------------------------------------------------------------------ +/// @brief Fetch the bounds of the grapheme cluster for the glyph in the +/// coordinate space of the paragraph. +/// +/// @param[in] glyph_info The glyph information. +/// +/// @return The grapheme cluster bounds. +/// +IMPELLER_EXPORT +ImpellerRect ImpellerGlyphInfoGetGraphemeClusterBounds( + ImpellerGlyphInfo IMPELLER_NONNULL glyph_info); + +//------------------------------------------------------------------------------ +/// @param[in] glyph_info The glyph information. +/// +/// @return True if the glyph represents an ellipsis. False otherwise. +/// +IMPELLER_EXPORT +bool ImpellerGlyphInfoIsEllipsis(ImpellerGlyphInfo IMPELLER_NONNULL glyph_info); + +//------------------------------------------------------------------------------ +/// @param[in] glyph_info The glyph information. +/// +/// @return The direction of the run that contains the glyph. +/// +IMPELLER_EXPORT +ImpellerTextDirection ImpellerGlyphInfoGetTextDirection( + ImpellerGlyphInfo IMPELLER_NONNULL glyph_info); + IMPELLER_EXTERN_C_END // NOLINTEND(google-objc-function-naming) diff --git a/engine/src/flutter/impeller/toolkit/interop/impeller.hpp b/engine/src/flutter/impeller/toolkit/interop/impeller.hpp index 22e5a30ae9..77cb632e37 100644 --- a/engine/src/flutter/impeller/toolkit/interop/impeller.hpp +++ b/engine/src/flutter/impeller/toolkit/interop/impeller.hpp @@ -44,149 +44,174 @@ struct Proc { } }; -#define IMPELLER_HPP_EACH_PROC(PROC) \ - PROC(ImpellerColorFilterCreateBlendNew) \ - PROC(ImpellerColorFilterCreateColorMatrixNew) \ - PROC(ImpellerColorFilterRelease) \ - PROC(ImpellerColorFilterRetain) \ - PROC(ImpellerColorSourceCreateConicalGradientNew) \ - PROC(ImpellerColorSourceCreateImageNew) \ - PROC(ImpellerColorSourceCreateLinearGradientNew) \ - PROC(ImpellerColorSourceCreateRadialGradientNew) \ - PROC(ImpellerColorSourceCreateSweepGradientNew) \ - PROC(ImpellerColorSourceRelease) \ - PROC(ImpellerColorSourceRetain) \ - PROC(ImpellerContextCreateMetalNew) \ - PROC(ImpellerContextCreateOpenGLESNew) \ - PROC(ImpellerContextCreateVulkanNew) \ - PROC(ImpellerContextGetVulkanInfo) \ - PROC(ImpellerContextRelease) \ - PROC(ImpellerContextRetain) \ - PROC(ImpellerDisplayListBuilderClipOval) \ - PROC(ImpellerDisplayListBuilderClipPath) \ - PROC(ImpellerDisplayListBuilderClipRect) \ - PROC(ImpellerDisplayListBuilderClipRoundedRect) \ - PROC(ImpellerDisplayListBuilderCreateDisplayListNew) \ - PROC(ImpellerDisplayListBuilderDrawDashedLine) \ - PROC(ImpellerDisplayListBuilderDrawDisplayList) \ - PROC(ImpellerDisplayListBuilderDrawLine) \ - PROC(ImpellerDisplayListBuilderDrawOval) \ - PROC(ImpellerDisplayListBuilderDrawPaint) \ - PROC(ImpellerDisplayListBuilderDrawParagraph) \ - PROC(ImpellerDisplayListBuilderDrawShadow) \ - PROC(ImpellerDisplayListBuilderDrawPath) \ - PROC(ImpellerDisplayListBuilderDrawRect) \ - PROC(ImpellerDisplayListBuilderDrawRoundedRect) \ - PROC(ImpellerDisplayListBuilderDrawRoundedRectDifference) \ - PROC(ImpellerDisplayListBuilderDrawTexture) \ - PROC(ImpellerDisplayListBuilderDrawTextureRect) \ - PROC(ImpellerDisplayListBuilderGetSaveCount) \ - PROC(ImpellerDisplayListBuilderGetTransform) \ - PROC(ImpellerDisplayListBuilderNew) \ - PROC(ImpellerDisplayListBuilderRelease) \ - PROC(ImpellerDisplayListBuilderResetTransform) \ - PROC(ImpellerDisplayListBuilderRestore) \ - PROC(ImpellerDisplayListBuilderRestoreToCount) \ - PROC(ImpellerDisplayListBuilderRetain) \ - PROC(ImpellerDisplayListBuilderRotate) \ - PROC(ImpellerDisplayListBuilderSave) \ - PROC(ImpellerDisplayListBuilderSaveLayer) \ - PROC(ImpellerDisplayListBuilderScale) \ - PROC(ImpellerDisplayListBuilderSetTransform) \ - PROC(ImpellerDisplayListBuilderTransform) \ - PROC(ImpellerDisplayListBuilderTranslate) \ - PROC(ImpellerDisplayListRelease) \ - PROC(ImpellerDisplayListRetain) \ - PROC(ImpellerGetVersion) \ - PROC(ImpellerImageFilterCreateBlurNew) \ - PROC(ImpellerImageFilterCreateComposeNew) \ - PROC(ImpellerImageFilterCreateDilateNew) \ - PROC(ImpellerImageFilterCreateErodeNew) \ - PROC(ImpellerImageFilterCreateMatrixNew) \ - PROC(ImpellerImageFilterRelease) \ - PROC(ImpellerImageFilterRetain) \ - PROC(ImpellerMaskFilterCreateBlurNew) \ - PROC(ImpellerMaskFilterRelease) \ - PROC(ImpellerMaskFilterRetain) \ - PROC(ImpellerPaintNew) \ - PROC(ImpellerPaintRelease) \ - PROC(ImpellerPaintRetain) \ - PROC(ImpellerPaintSetBlendMode) \ - PROC(ImpellerPaintSetColor) \ - PROC(ImpellerPaintSetColorFilter) \ - PROC(ImpellerPaintSetColorSource) \ - PROC(ImpellerPaintSetDrawStyle) \ - PROC(ImpellerPaintSetImageFilter) \ - PROC(ImpellerPaintSetMaskFilter) \ - PROC(ImpellerPaintSetStrokeCap) \ - PROC(ImpellerPaintSetStrokeJoin) \ - PROC(ImpellerPaintSetStrokeMiter) \ - PROC(ImpellerPaintSetStrokeWidth) \ - PROC(ImpellerParagraphBuilderAddText) \ - PROC(ImpellerParagraphBuilderBuildParagraphNew) \ - PROC(ImpellerParagraphBuilderNew) \ - PROC(ImpellerParagraphBuilderPopStyle) \ - PROC(ImpellerParagraphBuilderPushStyle) \ - PROC(ImpellerParagraphBuilderRelease) \ - PROC(ImpellerParagraphBuilderRetain) \ - PROC(ImpellerParagraphGetAlphabeticBaseline) \ - PROC(ImpellerParagraphGetHeight) \ - PROC(ImpellerParagraphGetIdeographicBaseline) \ - PROC(ImpellerParagraphGetLineCount) \ - PROC(ImpellerParagraphGetLongestLineWidth) \ - PROC(ImpellerParagraphGetMaxIntrinsicWidth) \ - PROC(ImpellerParagraphGetMaxWidth) \ - PROC(ImpellerParagraphGetMinIntrinsicWidth) \ - PROC(ImpellerParagraphRelease) \ - PROC(ImpellerParagraphRetain) \ - PROC(ImpellerParagraphStyleNew) \ - PROC(ImpellerParagraphStyleRelease) \ - PROC(ImpellerParagraphStyleRetain) \ - PROC(ImpellerParagraphStyleSetBackground) \ - PROC(ImpellerParagraphStyleSetFontFamily) \ - PROC(ImpellerParagraphStyleSetFontSize) \ - PROC(ImpellerParagraphStyleSetFontStyle) \ - PROC(ImpellerParagraphStyleSetFontWeight) \ - PROC(ImpellerParagraphStyleSetForeground) \ - PROC(ImpellerParagraphStyleSetHeight) \ - PROC(ImpellerParagraphStyleSetLocale) \ - PROC(ImpellerParagraphStyleSetMaxLines) \ - PROC(ImpellerParagraphStyleSetTextAlignment) \ - PROC(ImpellerParagraphStyleSetTextDirection) \ - PROC(ImpellerPathBuilderAddArc) \ - PROC(ImpellerPathBuilderAddOval) \ - PROC(ImpellerPathBuilderAddRect) \ - PROC(ImpellerPathBuilderAddRoundedRect) \ - PROC(ImpellerPathBuilderClose) \ - PROC(ImpellerPathBuilderCopyPathNew) \ - PROC(ImpellerPathBuilderCubicCurveTo) \ - PROC(ImpellerPathBuilderLineTo) \ - PROC(ImpellerPathBuilderMoveTo) \ - PROC(ImpellerPathBuilderNew) \ - PROC(ImpellerPathBuilderQuadraticCurveTo) \ - PROC(ImpellerPathBuilderRelease) \ - PROC(ImpellerPathBuilderRetain) \ - PROC(ImpellerPathBuilderTakePathNew) \ - PROC(ImpellerPathRelease) \ - PROC(ImpellerPathRetain) \ - PROC(ImpellerSurfaceCreateWrappedFBONew) \ - PROC(ImpellerSurfaceCreateWrappedMetalDrawableNew) \ - PROC(ImpellerSurfaceDrawDisplayList) \ - PROC(ImpellerSurfacePresent) \ - PROC(ImpellerSurfaceRelease) \ - PROC(ImpellerSurfaceRetain) \ - PROC(ImpellerTextureCreateWithContentsNew) \ - PROC(ImpellerTextureCreateWithOpenGLTextureHandleNew) \ - PROC(ImpellerTextureGetOpenGLHandle) \ - PROC(ImpellerTextureRelease) \ - PROC(ImpellerTextureRetain) \ - PROC(ImpellerTypographyContextNew) \ - PROC(ImpellerTypographyContextRegisterFont) \ - PROC(ImpellerTypographyContextRelease) \ - PROC(ImpellerTypographyContextRetain) \ - PROC(ImpellerVulkanSwapchainAcquireNextSurfaceNew) \ - PROC(ImpellerVulkanSwapchainCreateNew) \ - PROC(ImpellerVulkanSwapchainRelease) \ +#define IMPELLER_HPP_EACH_PROC(PROC) \ + PROC(ImpellerColorFilterCreateBlendNew) \ + PROC(ImpellerColorFilterCreateColorMatrixNew) \ + PROC(ImpellerColorFilterRelease) \ + PROC(ImpellerColorFilterRetain) \ + PROC(ImpellerColorSourceCreateConicalGradientNew) \ + PROC(ImpellerColorSourceCreateImageNew) \ + PROC(ImpellerColorSourceCreateLinearGradientNew) \ + PROC(ImpellerColorSourceCreateRadialGradientNew) \ + PROC(ImpellerColorSourceCreateSweepGradientNew) \ + PROC(ImpellerColorSourceRelease) \ + PROC(ImpellerColorSourceRetain) \ + PROC(ImpellerContextCreateMetalNew) \ + PROC(ImpellerContextCreateOpenGLESNew) \ + PROC(ImpellerContextCreateVulkanNew) \ + PROC(ImpellerContextGetVulkanInfo) \ + PROC(ImpellerContextRelease) \ + PROC(ImpellerContextRetain) \ + PROC(ImpellerDisplayListBuilderClipOval) \ + PROC(ImpellerDisplayListBuilderClipPath) \ + PROC(ImpellerDisplayListBuilderClipRect) \ + PROC(ImpellerDisplayListBuilderClipRoundedRect) \ + PROC(ImpellerDisplayListBuilderCreateDisplayListNew) \ + PROC(ImpellerDisplayListBuilderDrawDashedLine) \ + PROC(ImpellerDisplayListBuilderDrawDisplayList) \ + PROC(ImpellerDisplayListBuilderDrawLine) \ + PROC(ImpellerDisplayListBuilderDrawOval) \ + PROC(ImpellerDisplayListBuilderDrawPaint) \ + PROC(ImpellerDisplayListBuilderDrawParagraph) \ + PROC(ImpellerDisplayListBuilderDrawPath) \ + PROC(ImpellerDisplayListBuilderDrawRect) \ + PROC(ImpellerDisplayListBuilderDrawRoundedRect) \ + PROC(ImpellerDisplayListBuilderDrawRoundedRectDifference) \ + PROC(ImpellerDisplayListBuilderDrawShadow) \ + PROC(ImpellerDisplayListBuilderDrawTexture) \ + PROC(ImpellerDisplayListBuilderDrawTextureRect) \ + PROC(ImpellerDisplayListBuilderGetSaveCount) \ + PROC(ImpellerDisplayListBuilderGetTransform) \ + PROC(ImpellerDisplayListBuilderNew) \ + PROC(ImpellerDisplayListBuilderRelease) \ + PROC(ImpellerDisplayListBuilderResetTransform) \ + PROC(ImpellerDisplayListBuilderRestore) \ + PROC(ImpellerDisplayListBuilderRestoreToCount) \ + PROC(ImpellerDisplayListBuilderRetain) \ + PROC(ImpellerDisplayListBuilderRotate) \ + PROC(ImpellerDisplayListBuilderSave) \ + PROC(ImpellerDisplayListBuilderSaveLayer) \ + PROC(ImpellerDisplayListBuilderScale) \ + PROC(ImpellerDisplayListBuilderSetTransform) \ + PROC(ImpellerDisplayListBuilderTransform) \ + PROC(ImpellerDisplayListBuilderTranslate) \ + PROC(ImpellerDisplayListRelease) \ + PROC(ImpellerDisplayListRetain) \ + PROC(ImpellerGetVersion) \ + PROC(ImpellerGlyphInfoGetGraphemeClusterBounds) \ + PROC(ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeBegin) \ + PROC(ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeEnd) \ + PROC(ImpellerGlyphInfoGetTextDirection) \ + PROC(ImpellerGlyphInfoIsEllipsis) \ + PROC(ImpellerGlyphInfoRelease) \ + PROC(ImpellerGlyphInfoRetain) \ + PROC(ImpellerImageFilterCreateBlurNew) \ + PROC(ImpellerImageFilterCreateComposeNew) \ + PROC(ImpellerImageFilterCreateDilateNew) \ + PROC(ImpellerImageFilterCreateErodeNew) \ + PROC(ImpellerImageFilterCreateMatrixNew) \ + PROC(ImpellerImageFilterRelease) \ + PROC(ImpellerImageFilterRetain) \ + PROC(ImpellerLineMetricsGetAscent) \ + PROC(ImpellerLineMetricsGetBaseline) \ + PROC(ImpellerLineMetricsGetCodeUnitEndIndex) \ + PROC(ImpellerLineMetricsGetCodeUnitEndIndexExcludingWhitespace) \ + PROC(ImpellerLineMetricsGetCodeUnitEndIndexIncludingNewline) \ + PROC(ImpellerLineMetricsGetCodeUnitStartIndex) \ + PROC(ImpellerLineMetricsGetDescent) \ + PROC(ImpellerLineMetricsGetHeight) \ + PROC(ImpellerLineMetricsIsHardbreak) \ + PROC(ImpellerLineMetricsGetLeft) \ + PROC(ImpellerLineMetricsGetUnscaledAscent) \ + PROC(ImpellerLineMetricsGetWidth) \ + PROC(ImpellerLineMetricsRelease) \ + PROC(ImpellerLineMetricsRetain) \ + PROC(ImpellerMaskFilterCreateBlurNew) \ + PROC(ImpellerMaskFilterRelease) \ + PROC(ImpellerMaskFilterRetain) \ + PROC(ImpellerPaintNew) \ + PROC(ImpellerPaintRelease) \ + PROC(ImpellerPaintRetain) \ + PROC(ImpellerPaintSetBlendMode) \ + PROC(ImpellerPaintSetColor) \ + PROC(ImpellerPaintSetColorFilter) \ + PROC(ImpellerPaintSetColorSource) \ + PROC(ImpellerPaintSetDrawStyle) \ + PROC(ImpellerPaintSetImageFilter) \ + PROC(ImpellerPaintSetMaskFilter) \ + PROC(ImpellerPaintSetStrokeCap) \ + PROC(ImpellerPaintSetStrokeJoin) \ + PROC(ImpellerPaintSetStrokeMiter) \ + PROC(ImpellerPaintSetStrokeWidth) \ + PROC(ImpellerParagraphBuilderAddText) \ + PROC(ImpellerParagraphBuilderBuildParagraphNew) \ + PROC(ImpellerParagraphBuilderNew) \ + PROC(ImpellerParagraphBuilderPopStyle) \ + PROC(ImpellerParagraphBuilderPushStyle) \ + PROC(ImpellerParagraphBuilderRelease) \ + PROC(ImpellerParagraphBuilderRetain) \ + PROC(ImpellerParagraphCreateGlyphInfoAtCodeUnitIndexNew) \ + PROC(ImpellerParagraphCreateGlyphInfoAtParagraphCoordinatesNew) \ + PROC(ImpellerParagraphGetAlphabeticBaseline) \ + PROC(ImpellerParagraphGetHeight) \ + PROC(ImpellerParagraphGetIdeographicBaseline) \ + PROC(ImpellerParagraphGetLineCount) \ + PROC(ImpellerParagraphGetLineMetrics) \ + PROC(ImpellerParagraphGetLongestLineWidth) \ + PROC(ImpellerParagraphGetMaxIntrinsicWidth) \ + PROC(ImpellerParagraphGetMaxWidth) \ + PROC(ImpellerParagraphGetMinIntrinsicWidth) \ + PROC(ImpellerParagraphGetWordBoundary) \ + PROC(ImpellerParagraphRelease) \ + PROC(ImpellerParagraphRetain) \ + PROC(ImpellerParagraphStyleNew) \ + PROC(ImpellerParagraphStyleRelease) \ + PROC(ImpellerParagraphStyleRetain) \ + PROC(ImpellerParagraphStyleSetBackground) \ + PROC(ImpellerParagraphStyleSetFontFamily) \ + PROC(ImpellerParagraphStyleSetFontSize) \ + PROC(ImpellerParagraphStyleSetFontStyle) \ + PROC(ImpellerParagraphStyleSetFontWeight) \ + PROC(ImpellerParagraphStyleSetForeground) \ + PROC(ImpellerParagraphStyleSetHeight) \ + PROC(ImpellerParagraphStyleSetLocale) \ + PROC(ImpellerParagraphStyleSetMaxLines) \ + PROC(ImpellerParagraphStyleSetTextAlignment) \ + PROC(ImpellerParagraphStyleSetTextDirection) \ + PROC(ImpellerPathBuilderAddArc) \ + PROC(ImpellerPathBuilderAddOval) \ + PROC(ImpellerPathBuilderAddRect) \ + PROC(ImpellerPathBuilderAddRoundedRect) \ + PROC(ImpellerPathBuilderClose) \ + PROC(ImpellerPathBuilderCopyPathNew) \ + PROC(ImpellerPathBuilderCubicCurveTo) \ + PROC(ImpellerPathBuilderLineTo) \ + PROC(ImpellerPathBuilderMoveTo) \ + PROC(ImpellerPathBuilderNew) \ + PROC(ImpellerPathBuilderQuadraticCurveTo) \ + PROC(ImpellerPathBuilderRelease) \ + PROC(ImpellerPathBuilderRetain) \ + PROC(ImpellerPathBuilderTakePathNew) \ + PROC(ImpellerPathRelease) \ + PROC(ImpellerPathRetain) \ + PROC(ImpellerSurfaceCreateWrappedFBONew) \ + PROC(ImpellerSurfaceCreateWrappedMetalDrawableNew) \ + PROC(ImpellerSurfaceDrawDisplayList) \ + PROC(ImpellerSurfacePresent) \ + PROC(ImpellerSurfaceRelease) \ + PROC(ImpellerSurfaceRetain) \ + PROC(ImpellerTextureCreateWithContentsNew) \ + PROC(ImpellerTextureCreateWithOpenGLTextureHandleNew) \ + PROC(ImpellerTextureGetOpenGLHandle) \ + PROC(ImpellerTextureRelease) \ + PROC(ImpellerTextureRetain) \ + PROC(ImpellerTypographyContextNew) \ + PROC(ImpellerTypographyContextRegisterFont) \ + PROC(ImpellerTypographyContextRelease) \ + PROC(ImpellerTypographyContextRetain) \ + PROC(ImpellerVulkanSwapchainAcquireNextSurfaceNew) \ + PROC(ImpellerVulkanSwapchainCreateNew) \ + PROC(ImpellerVulkanSwapchainRelease) \ PROC(ImpellerVulkanSwapchainRetain) struct ProcTable { @@ -284,7 +309,9 @@ IMPELLER_HPP_DEFINE_TRAITS(ImpellerColorSource); IMPELLER_HPP_DEFINE_TRAITS(ImpellerContext); IMPELLER_HPP_DEFINE_TRAITS(ImpellerDisplayList); IMPELLER_HPP_DEFINE_TRAITS(ImpellerDisplayListBuilder); +IMPELLER_HPP_DEFINE_TRAITS(ImpellerGlyphInfo); IMPELLER_HPP_DEFINE_TRAITS(ImpellerImageFilter); +IMPELLER_HPP_DEFINE_TRAITS(ImpellerLineMetrics); IMPELLER_HPP_DEFINE_TRAITS(ImpellerMaskFilter); IMPELLER_HPP_DEFINE_TRAITS(ImpellerPaint); IMPELLER_HPP_DEFINE_TRAITS(ImpellerParagraph); @@ -638,6 +665,149 @@ class MaskFilter final } }; +//------------------------------------------------------------------------------ +/// @see ImpellerGlyphInfo +/// +class GlyphInfo final + : public Object { + public: + GlyphInfo(ImpellerGlyphInfo info, AdoptTag tag) : Object(info, tag) {} + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeBegin + /// + size_t GetGraphemeClusterCodeUnitRangeBegin() const { + return gGlobalProcTable + .ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeBegin(Get()); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeEnd + /// + size_t GetGraphemeClusterCodeUnitRangeEnd() const { + return gGlobalProcTable.ImpellerGlyphInfoGetGraphemeClusterCodeUnitRangeEnd( + Get()); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetGraphemeClusterBounds + /// + ImpellerRect GetGraphemeClusterBounds() const { + return gGlobalProcTable.ImpellerGlyphInfoGetGraphemeClusterBounds(Get()); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoIsEllipsis + /// + bool IsEllipsis() const { + return gGlobalProcTable.ImpellerGlyphInfoIsEllipsis(Get()); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerGlyphInfoGetTextDirection + /// + ImpellerTextDirection GetTextDirection() const { + return gGlobalProcTable.ImpellerGlyphInfoGetTextDirection(Get()); + } +}; + +//------------------------------------------------------------------------------ +/// @see ImpellerLineMetrics +/// +class LineMetrics final + : public Object { + public: + LineMetrics(ImpellerLineMetrics metrics, AdoptTag tag) + : Object(metrics, tag) {} + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetUnscaledAscent + /// + double GetUnscaledAscent(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetUnscaledAscent(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetAscent + /// + double GetAscent(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetAscent(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetDescent + /// + double GetDescent(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetDescent(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetBaseline + /// + double GetBaseline(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetBaseline(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsIsHardbreak + /// + bool IsHardbreak(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsIsHardbreak(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetWidth + /// + double GetWidth(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetWidth(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetHeight + /// + double GetHeight(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetHeight(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetLeft + /// + double GetLeft(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetLeft(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitStartIndex + /// + size_t GetCodeUnitStartIndex(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetCodeUnitStartIndex(Get(), + line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitEndIndex + /// + size_t GetCodeUnitEndIndex(size_t line) const { + return gGlobalProcTable.ImpellerLineMetricsGetCodeUnitEndIndex(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitEndIndexExcludingWhitespace + /// + size_t GetCodeUnitEndIndexExcludingWhitespace(size_t line) const { + return gGlobalProcTable + .ImpellerLineMetricsGetCodeUnitEndIndexExcludingWhitespace(Get(), line); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitEndIndexIncludingNewline + /// + size_t GetCodeUnitEndIndexIncludingNewline(size_t line) const { + return gGlobalProcTable + .ImpellerLineMetricsGetCodeUnitEndIndexIncludingNewline(Get(), line); + } +}; + //------------------------------------------------------------------------------ /// @see ImpellerParagraph /// @@ -702,6 +872,47 @@ class Paragraph final float GetMinIntrinsicWidth() { return gGlobalProcTable.ImpellerParagraphGetMinIntrinsicWidth(Get()); } + + //---------------------------------------------------------------------------- + /// @see ImpellerParagraphGetLineMetrics + /// + LineMetrics GetLineMetrics() const { + auto metrics = gGlobalProcTable.ImpellerParagraphGetLineMetrics(Get()); + gGlobalProcTable.ImpellerLineMetricsRetain(metrics); + return LineMetrics(metrics, AdoptTag::kAdopt); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerParagraphCreateGlyphInfoAtCodeUnitIndexNew + /// + GlyphInfo GlyphInfoAtCodeUnitIndex(size_t code_unit_index) { + return GlyphInfo( + gGlobalProcTable.ImpellerParagraphCreateGlyphInfoAtCodeUnitIndexNew( + Get(), code_unit_index), + AdoptTag::kAdopt); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerParagraphCreateGlyphInfoAtParagraphCoordinatesNew + /// + GlyphInfo GlyphInfoAtParagraphCoordinates(double x, double y) { + return GlyphInfo( + gGlobalProcTable + .ImpellerParagraphCreateGlyphInfoAtParagraphCoordinatesNew( + Get(), // + x, // + y // + ), + AdoptTag::kAdopt); + } + + //---------------------------------------------------------------------------- + /// @see ImpellerParagraphGetWordBoundary + /// + ImpellerRange GetWordBoundary(size_t code_unit_index) { + return gGlobalProcTable.ImpellerParagraphGetWordBoundary(Get(), + code_unit_index); + } }; //------------------------------------------------------------------------------ diff --git a/engine/src/flutter/impeller/toolkit/interop/impeller_unittests.cc b/engine/src/flutter/impeller/toolkit/interop/impeller_unittests.cc index c512e9473a..16d0b48483 100644 --- a/engine/src/flutter/impeller/toolkit/interop/impeller_unittests.cc +++ b/engine/src/flutter/impeller/toolkit/interop/impeller_unittests.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/fml/native_library.h" +#include "flutter/fml/string_conversion.h" #include "flutter/testing/testing.h" #include "impeller/base/allocation.h" #include "impeller/renderer/backend/gles/context_gles.h" @@ -503,4 +504,82 @@ TEST_P(InteropPlaygroundTest, CanRenderShadows) { })); } +TEST_P(InteropPlaygroundTest, CanMeasureText) { + hpp::TypographyContext type_context; + hpp::ParagraphBuilder paragraph_builder(type_context); + hpp::ParagraphStyle paragraph_style; + paragraph_style.SetFontSize(50); + paragraph_builder.PushStyle(paragraph_style); + const std::string text = + "🏁 Can 👨‍👨‍👦‍👦 Measure 🔍 Text\nAnd this is line " + "two.\nWhoa! Three lines. How high does this go?\r\nI stopped counting."; + const auto u16text = fml::Utf8ToUtf16(text); + ASSERT_NE(text.size(), u16text.size()); + paragraph_builder.AddText(reinterpret_cast(text.data()), + text.size()); + hpp::DisplayListBuilder builder; + // Don't rely on implicit line breaks in this test to make it less brittle to + // different fonts being picked. + hpp::Paragraph paragraph = paragraph_builder.Build(FLT_MAX); + const auto line_count = paragraph.GetLineCount(); + ASSERT_EQ(line_count, 4u); + + // Line Metrics. + { + auto metrics = paragraph.GetLineMetrics(); + ASSERT_GT(metrics.GetAscent(0), 0.0); + ASSERT_GT(metrics.GetUnscaledAscent(0), 0.0); + ASSERT_GT(metrics.GetDescent(0), 0.0); + ASSERT_GT(metrics.GetBaseline(0), 0.0); + ASSERT_TRUE(metrics.IsHardbreak(0)); + ASSERT_DOUBLE_EQ(metrics.GetLeft(0), 0.0); + ASSERT_EQ(metrics.GetCodeUnitStartIndex(0), 0u); + ASSERT_EQ(metrics.GetCodeUnitEndIndexIncludingNewline(0), + metrics.GetCodeUnitEndIndex(0) + 1u); + ASSERT_GT(metrics.GetCodeUnitStartIndex(1), 0u); + // Last line should cover the entire range. + ASSERT_EQ(metrics.GetCodeUnitEndIndex(3), u16text.size()); + } + + // Glyph info by code point. + { + auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u); + ASSERT_TRUE(glyph); + ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeBegin(), 0u); + ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(), + fml::Utf8ToUtf16("🏁").size()); + auto bounds = glyph.GetGraphemeClusterBounds(); + ASSERT_GT(bounds.width, 0.0); + ASSERT_GT(bounds.height, 0.0); + ASSERT_FALSE(glyph.IsEllipsis()); + ASSERT_EQ(glyph.GetTextDirection(), kImpellerTextDirectionLTR); + } + + // Glyph info by coordinates. + { + auto glyph = paragraph.GlyphInfoAtParagraphCoordinates(0.0, 0.0); + ASSERT_TRUE(glyph); + ASSERT_EQ(glyph.GetGraphemeClusterCodeUnitRangeEnd(), + fml::Utf8ToUtf16("🏁").size()); + } + + // Glyph Figure out word boundaries. + { + auto glyph = paragraph.GlyphInfoAtCodeUnitIndex(0u); + ASSERT_TRUE(glyph); + auto range = + paragraph.GetWordBoundary(glyph.GetGraphemeClusterCodeUnitRangeEnd()); + ASSERT_GT(range.end, 0u); + } + + builder.DrawParagraph(paragraph, ImpellerPoint{100, 100}); + auto dl = builder.Build(); + ASSERT_TRUE( + OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool { + hpp::Surface window(surface.GetC()); + window.Draw(dl); + return true; + })); +} + } // namespace impeller::interop::testing diff --git a/engine/src/flutter/impeller/toolkit/interop/line_metrics.cc b/engine/src/flutter/impeller/toolkit/interop/line_metrics.cc new file mode 100644 index 0000000000..59773389ca --- /dev/null +++ b/engine/src/flutter/impeller/toolkit/interop/line_metrics.cc @@ -0,0 +1,76 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/impeller/toolkit/interop/line_metrics.h" + +namespace impeller::interop { + +LineMetrics::LineMetrics(const std::vector& metrics) { + // There aren't any guarantees (documented or otherwise) that metrics will + // have line numbers that are sorted or contiguous. + for (const auto& metric : metrics) { + metrics_[metric.line_number] = metric; + } +} + +LineMetrics::~LineMetrics() = default; + +double LineMetrics::GetAscent(size_t line) const { + return GetLine(line).ascent; +} + +double LineMetrics::GetUnscaledAscent(size_t line) const { + return GetLine(line).unscaled_ascent; +} + +double LineMetrics::GetDescent(size_t line) const { + return GetLine(line).descent; +} + +double LineMetrics::GetBaseline(size_t line) const { + return GetLine(line).baseline; +} + +bool LineMetrics::IsHardbreak(size_t line) const { + return GetLine(line).hard_break; +} + +double LineMetrics::GetWidth(size_t line) const { + return GetLine(line).width; +} + +double LineMetrics::GetHeight(size_t line) const { + return GetLine(line).height; +} + +double LineMetrics::GetLeft(size_t line) const { + return GetLine(line).left; +} + +size_t LineMetrics::GetCodeUnitStartIndex(size_t line) const { + return GetLine(line).start_index; +} + +size_t LineMetrics::GetCodeUnitEndIndex(size_t line) const { + return GetLine(line).end_index; +} + +size_t LineMetrics::GetCodeUnitEndIndexExcludingWhitespace(size_t line) const { + return GetLine(line).end_excluding_whitespace; +} + +size_t LineMetrics::GetCodeUnitEndIndexIncludingNewline(size_t line) const { + return GetLine(line).end_including_newline; +} + +const txt::LineMetrics& LineMetrics::GetLine(size_t line) const { + auto found = metrics_.find(line); + if (found != metrics_.end()) { + return found->second; + } + static txt::LineMetrics kDefaultMetrics = {}; + return kDefaultMetrics; +} + +} // namespace impeller::interop diff --git a/engine/src/flutter/impeller/toolkit/interop/line_metrics.h b/engine/src/flutter/impeller/toolkit/interop/line_metrics.h new file mode 100644 index 0000000000..fdd1d39664 --- /dev/null +++ b/engine/src/flutter/impeller/toolkit/interop/line_metrics.h @@ -0,0 +1,104 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_TOOLKIT_INTEROP_LINE_METRICS_H_ +#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_LINE_METRICS_H_ + +#include + +#include "flutter/txt/src/txt/line_metrics.h" +#include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/object.h" + +namespace impeller::interop { + +//------------------------------------------------------------------------------ +/// @brief Internal C++ peer of ImpellerLineMetrics. For detailed +/// documentation, refer to the headerdocs in the public API in +/// impeller.h. +/// +/// Accessing metrics of missing lines returns default initialized +/// values. +/// +class LineMetrics final + : public Object { + public: + explicit LineMetrics(const std::vector& metrics); + + ~LineMetrics(); + + LineMetrics(const LineMetrics&) = delete; + + LineMetrics& operator=(const LineMetrics&) = delete; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetAscent. + /// + double GetAscent(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetUnscaledAscent. + /// + double GetUnscaledAscent(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetDescent. + /// + double GetDescent(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetBaseline. + /// + double GetBaseline(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsIsHardbreak. + /// + bool IsHardbreak(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetWidth. + /// + double GetWidth(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetHeight. + /// + double GetHeight(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetLeft. + /// + double GetLeft(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitStartIndex. + /// + size_t GetCodeUnitStartIndex(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitEndIndex. + /// + size_t GetCodeUnitEndIndex(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitEndIndexExcludingWhitespace. + /// + size_t GetCodeUnitEndIndexExcludingWhitespace(size_t line) const; + + //---------------------------------------------------------------------------- + /// @see ImpellerLineMetricsGetCodeUnitEndIndexIncludingNewline. + /// + size_t GetCodeUnitEndIndexIncludingNewline(size_t line) const; + + private: + std::map metrics_; + + const txt::LineMetrics& GetLine(size_t line) const; +}; + +} // namespace impeller::interop + +#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_LINE_METRICS_H_ diff --git a/engine/src/flutter/impeller/toolkit/interop/paragraph.cc b/engine/src/flutter/impeller/toolkit/interop/paragraph.cc index fa06b6bf57..d4388f369a 100644 --- a/engine/src/flutter/impeller/toolkit/interop/paragraph.cc +++ b/engine/src/flutter/impeller/toolkit/interop/paragraph.cc @@ -47,4 +47,39 @@ const std::unique_ptr& Paragraph::GetHandle() const { return paragraph_; } +ScopedObject Paragraph::GetLineMetrics() const { + // Line metrics are expensive to calculate and the recommendation is that + // the metric after each layout must be cached. But interop::Paragraphs are + // immutable. So do the caching on behalf of the caller. + if (lazy_line_metrics_) { + return lazy_line_metrics_; + } + lazy_line_metrics_ = Create(paragraph_->GetLineMetrics()); + return lazy_line_metrics_; +} + +ScopedObject Paragraph::GetGlyphInfoAtCodeUnitIndex( + size_t code_unit_index) const { + skia::textlayout::Paragraph::GlyphInfo info = {}; + if (paragraph_->GetGlyphInfoAt(code_unit_index, &info)) { + return Create(info); + } + return nullptr; +} + +ScopedObject Paragraph::GetClosestGlyphInfoAtParagraphCoordinates( + double x, + double y) const { + skia::textlayout::Paragraph::GlyphInfo info = {}; + if (paragraph_->GetClosestGlyphInfoAtCoordinate(x, y, &info)) { + return Create(info); + } + return nullptr; +} + +ImpellerRange Paragraph::GetWordBoundary(size_t code_unit_index) const { + const auto range = paragraph_->GetWordBoundary(code_unit_index); + return ImpellerRange{range.start, range.end}; +} + } // namespace impeller::interop diff --git a/engine/src/flutter/impeller/toolkit/interop/paragraph.h b/engine/src/flutter/impeller/toolkit/interop/paragraph.h index 06eb5583ed..7635873f9d 100644 --- a/engine/src/flutter/impeller/toolkit/interop/paragraph.h +++ b/engine/src/flutter/impeller/toolkit/interop/paragraph.h @@ -6,11 +6,16 @@ #define FLUTTER_IMPELLER_TOOLKIT_INTEROP_PARAGRAPH_H_ #include "flutter/txt/src/txt/paragraph.h" +#include "impeller/toolkit/interop/glyph_info.h" #include "impeller/toolkit/interop/impeller.h" +#include "impeller/toolkit/interop/line_metrics.h" #include "impeller/toolkit/interop/object.h" namespace impeller::interop { +/** + * An immutable fully laid out paragraph. + */ class Paragraph final : public Object { @@ -41,8 +46,20 @@ class Paragraph final const std::unique_ptr& GetHandle() const; + ScopedObject GetLineMetrics() const; + + ScopedObject GetGlyphInfoAtCodeUnitIndex( + size_t code_unit_index) const; + + ScopedObject GetClosestGlyphInfoAtParagraphCoordinates( + double x, + double y) const; + + ImpellerRange GetWordBoundary(size_t code_unit_index) const; + private: std::unique_ptr paragraph_; + mutable ScopedObject lazy_line_metrics_; }; } // namespace impeller::interop diff --git a/engine/src/flutter/txt/src/txt/line_metrics.h b/engine/src/flutter/txt/src/txt/line_metrics.h index 1dc77900f0..05984c6e08 100644 --- a/engine/src/flutter/txt/src/txt/line_metrics.h +++ b/engine/src/flutter/txt/src/txt/line_metrics.h @@ -55,7 +55,7 @@ class LineMetrics { // are before layout and are the base values we calculate from. std::map run_metrics; - LineMetrics(); + LineMetrics() = default; LineMetrics(size_t start, size_t end,