mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] libImpeller: Implement APIs for fetching glyph and line metrics. (#165701)
This patch adds support in the typography subsystem of the public Impeller API such that users can implement text editing functionality. * Line metrics for a fully laid out paragraph can be retrieved. The metrics contain information about offsets into the original code unit buffer used to create the paragraph. These offsets can be used to implement functionality that edits whole lines. * Glyph information for a specific code unit offset, as well as a coordinate offset relative to the paragraph origin, can be obtained. This information can be used place decorations (like carets), select words surrounding the caret (a hit-test), and edit the source buffer to re-layout the paragraph. * Word boundaries (as specified in Unicode Standard Annex 29) can be retrieved to select and modify paragraph subsets by character, word, and line at caret. Like in Flutter, the code unit buffers are assumed to be arrays of UTF-16 bytes. I'd have preferred this to be UTF-8 because the initial paragraph construction is using UTF-8 bytes. Also, Skia internally seems to work with UTF-8 too but the interfaces are exposed using UTF-16 (presumably for users like Flutter that work with Dart strings that are UTF-16). Exposing additional APIs in txt::Paragraph to back this out seemed onerous. Instead, a UTF-16 assumption for all APIs that retrieve metrics is made (and documented). It stands to reason that paragraphs should be constructable using UTF-16 buffers in the public API too. I'll add that in a subsequent patch as that has little to do with metrics. Fixes https://github.com/flutter/flutter/issues/165509
This commit is contained in:
parent
9e829cbd92
commit
39103d9512
@ -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
|
||||
|
||||
@ -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",
|
||||
|
||||
42
engine/src/flutter/impeller/toolkit/interop/glyph_info.cc
Normal file
42
engine/src/flutter/impeller/toolkit/interop/glyph_info.cc
Normal file
@ -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
|
||||
63
engine/src/flutter/impeller/toolkit/interop/glyph_info.h
Normal file
63
engine/src/flutter/impeller/toolkit/interop/glyph_info.h
Normal file
@ -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<GlyphInfo,
|
||||
IMPELLER_INTERNAL_HANDLE_NAME(ImpellerGlyphInfo)> {
|
||||
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_
|
||||
@ -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<TypographyContext>();
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<ImpellerGlyphInfo, ImpellerGlyphInfoTraits> {
|
||||
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<ImpellerLineMetrics, ImpellerLineMetricsTraits> {
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -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<const uint8_t*>(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
|
||||
|
||||
76
engine/src/flutter/impeller/toolkit/interop/line_metrics.cc
Normal file
76
engine/src/flutter/impeller/toolkit/interop/line_metrics.cc
Normal file
@ -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<txt::LineMetrics>& 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
|
||||
104
engine/src/flutter/impeller/toolkit/interop/line_metrics.h
Normal file
104
engine/src/flutter/impeller/toolkit/interop/line_metrics.h
Normal file
@ -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 <map>
|
||||
|
||||
#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<LineMetrics,
|
||||
IMPELLER_INTERNAL_HANDLE_NAME(ImpellerLineMetrics)> {
|
||||
public:
|
||||
explicit LineMetrics(const std::vector<txt::LineMetrics>& 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<size_t /* line number */, txt::LineMetrics> metrics_;
|
||||
|
||||
const txt::LineMetrics& GetLine(size_t line) const;
|
||||
};
|
||||
|
||||
} // namespace impeller::interop
|
||||
|
||||
#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_LINE_METRICS_H_
|
||||
@ -47,4 +47,39 @@ const std::unique_ptr<txt::Paragraph>& Paragraph::GetHandle() const {
|
||||
return paragraph_;
|
||||
}
|
||||
|
||||
ScopedObject<LineMetrics> 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<LineMetrics>(paragraph_->GetLineMetrics());
|
||||
return lazy_line_metrics_;
|
||||
}
|
||||
|
||||
ScopedObject<GlyphInfo> Paragraph::GetGlyphInfoAtCodeUnitIndex(
|
||||
size_t code_unit_index) const {
|
||||
skia::textlayout::Paragraph::GlyphInfo info = {};
|
||||
if (paragraph_->GetGlyphInfoAt(code_unit_index, &info)) {
|
||||
return Create<GlyphInfo>(info);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScopedObject<GlyphInfo> Paragraph::GetClosestGlyphInfoAtParagraphCoordinates(
|
||||
double x,
|
||||
double y) const {
|
||||
skia::textlayout::Paragraph::GlyphInfo info = {};
|
||||
if (paragraph_->GetClosestGlyphInfoAtCoordinate(x, y, &info)) {
|
||||
return Create<GlyphInfo>(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
|
||||
|
||||
@ -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<Paragraph,
|
||||
IMPELLER_INTERNAL_HANDLE_NAME(ImpellerParagraph)> {
|
||||
@ -41,8 +46,20 @@ class Paragraph final
|
||||
|
||||
const std::unique_ptr<txt::Paragraph>& GetHandle() const;
|
||||
|
||||
ScopedObject<LineMetrics> GetLineMetrics() const;
|
||||
|
||||
ScopedObject<GlyphInfo> GetGlyphInfoAtCodeUnitIndex(
|
||||
size_t code_unit_index) const;
|
||||
|
||||
ScopedObject<GlyphInfo> GetClosestGlyphInfoAtParagraphCoordinates(
|
||||
double x,
|
||||
double y) const;
|
||||
|
||||
ImpellerRange GetWordBoundary(size_t code_unit_index) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<txt::Paragraph> paragraph_;
|
||||
mutable ScopedObject<LineMetrics> lazy_line_metrics_;
|
||||
};
|
||||
|
||||
} // namespace impeller::interop
|
||||
|
||||
@ -55,7 +55,7 @@ class LineMetrics {
|
||||
// are before layout and are the base values we calculate from.
|
||||
std::map<size_t, RunMetrics> run_metrics;
|
||||
|
||||
LineMetrics();
|
||||
LineMetrics() = default;
|
||||
|
||||
LineMetrics(size_t start,
|
||||
size_t end,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user