9d0d426028
This reverts commitefb7ae16dd
. Reason for revert: Excluding all non-linux tests Original change's description: > Revert "The very first version of a new SkText API." > > This reverts commit8a20cea604
. > > Reason for revert: Breaking some tests > > Original change's description: > > The very first version of a new SkText API. > > > > SkText public API added. > > Interface.h updated. > > > > Change-Id: I82a87f33e6cf1394fa2520387f6895d33601376e > > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/442003 > > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > > Commit-Queue: Julia Lavrova <jlavrova@google.com> > > Change-Id: I879b198bc6fb44c46d11d967118f8d69eb74fee0 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/449296 > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > Reviewed-by: John Stiles <johnstiles@google.com> > Commit-Queue: Julia Lavrova <jlavrova@google.com> Change-Id: Ieb65b45532d8c7455f091cf7a9e21fa7dea47606 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/449297 Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Julia Lavrova <jlavrova@google.com>
192 lines
8.7 KiB
C++
192 lines
8.7 KiB
C++
// Copyright 2021 Google LLC.
|
|
#ifndef Interface_DEFINED
|
|
#define Interface_DEFINED
|
|
#include <string>
|
|
#include "experimental/sktext/include/Types.h"
|
|
#include "experimental/sktext/src/Line.h"
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkFontMgr.h"
|
|
#include "include/core/SkFontStyle.h"
|
|
#include "include/core/SkPaint.h"
|
|
#include "include/core/SkSize.h"
|
|
#include "include/core/SkString.h"
|
|
#include "include/core/SkTextBlob.h"
|
|
#include "modules/skshaper/include/SkShaper.h"
|
|
#include "modules/skunicode/include/SkUnicode.h"
|
|
|
|
using namespace skia::text;
|
|
namespace skia {
|
|
namespace API {
|
|
/**
|
|
* This class contains all the SKUnicode/ICU information.
|
|
*/
|
|
class UnicodeText {
|
|
public:
|
|
/** Makes calls to SkShaper and collects all the shaped data.
|
|
@param blocks a range of FontBlock elements that keep information about
|
|
fonts required to shape the text.
|
|
It's utf16 range but internally it will have to be converted
|
|
to utf8 (since all shaping operations use utf8 encoding)
|
|
@param textDirection a starting text direction value
|
|
@return an object that contains the result of shaping operations
|
|
*/
|
|
std::unique_ptr<ShapedText> shape(SkSpan<FontBlock> blocks, TextDirection textDirection);
|
|
|
|
UnicodeText(std::unique_ptr<SkUnicode> unicode, SkSpan<uint16_t> utf16);
|
|
UnicodeText(std::unique_ptr<SkUnicode> unicode, const SkString& utf8);
|
|
|
|
bool hasProperty(TextIndex index, CodeUnitFlags flag) const
|
|
bool isHardLineBreak(TextIndex index) const ;
|
|
bool isSoftLineBreak(TextIndex index) const;
|
|
bool isWhitespaces(TextRange range) const;
|
|
|
|
SkUnicode* getUnicode() const;
|
|
SkSpan<const char16_t> getText16() const;
|
|
};
|
|
|
|
class WrappedText;
|
|
/**
|
|
* This class provides all the information from SkShaper/harfbuzz in a raw format.
|
|
* It does require a single existing font for each codepoint.
|
|
*/
|
|
// Question: do we provide a visitor for ShapedText?
|
|
class ShapedText {
|
|
public:
|
|
/** Break text by lines with a given width (and possible new lines).
|
|
@param unicodeText a reference to UnicodeText that is used to query Unicode information
|
|
@param width a line width at which the text gets wrapped
|
|
@param height a text height, currently not supported
|
|
@return an object that contains the result of shaping operations (wrapping and formatting).
|
|
*/
|
|
std::unique_ptr<WrappedText> wrap(UnicodeText* unicodeText, float width, float height);
|
|
SkSpan<const LogicalRun> getLogicalRuns() const;
|
|
};
|
|
|
|
/**
|
|
* This is a helper visitor class that allows a user to process the wrapped text
|
|
* structures: lines and runs (to draw them, for instance)
|
|
*/
|
|
class Visitor {
|
|
public:
|
|
virtual ~Visitor() = default;
|
|
virtual void onBeginLine(size_t index, TextRange lineText, bool hardBreak, SkRect bounds) { }
|
|
virtual void onEndLine(size_t index, TextRange lineText, GlyphRange trailingSpaces, size_t glyphCount) { }
|
|
virtual void onGlyphRun(const SkFont& font,
|
|
TextRange textRange, // Currently we make sure that the run edges are the grapheme cluster edges
|
|
SkRect bounds, // bounds contains the physical boundaries of the run
|
|
int trailingSpaces, // Depending of TextDirection it goes right to the end (LTR) or left to the start (RTL)
|
|
int glyphCount, // Just the number of glyphs
|
|
const uint16_t glyphs[],
|
|
const SkPoint positions[], // Positions relative to the line
|
|
const TextIndex clusters[]) // Text indices inside the entire text
|
|
{ }
|
|
virtual void onPlaceholder(TextRange, const SkRect& bounds) { }
|
|
};
|
|
|
|
class DrawableText;
|
|
class SelectableText;
|
|
/**
|
|
* This class provides all the information about wrapped/formatted text.
|
|
*/
|
|
class WrappedText {
|
|
public:
|
|
/** Builds a list of SkTextBlobs to draw on a canvas.
|
|
@param positionType specifies a text adjustment granularity (grapheme cluster, grapheme, glypheme, glyph)
|
|
@param blocks a range of text indices that cause an additional run breaking to be used for styling
|
|
@return an object that contains a list of SkTextBlobs to draw on a canvas
|
|
*/
|
|
std::unique_ptr<DrawableText> prepareToDraw(UnicodeText* unicodeText, PositionType positionType, SkSpan<TextIndex> blocks) const;
|
|
/** Aggregates all the data to navigate the text (move up, down, left, right),
|
|
select some text near the cursor point, adjust all text position to word,
|
|
grapheme cluster and such.
|
|
@return an object that contains all the data for navigation
|
|
*/
|
|
std::unique_ptr<SelectableText> prepareToEdit(UnicodeText* unicodeText) const;
|
|
/** Formats a text line by line.
|
|
@param textAlign specifies a text placement on the line:
|
|
left, right, center and justified (last one currently not supported)
|
|
@param textDirection specifies a text direction that also used in formatting
|
|
*/
|
|
void format(TextAlign textAlign, TextDirection textDirection);
|
|
/** Breaks the text runs into smaller runs by given list of chunks to be used for styling.
|
|
@param unicodeText a reference to UnicodeText object
|
|
@param chunks a range of text indices that cause an additional run breaking to be used for styling
|
|
*/
|
|
void decorate(UnicodeText* unicodeText, SkSpan<TextIndex> chunks);
|
|
|
|
/** Walks though the data structures and makes certain callbacks on visitor so the visitor can collect all the information.
|
|
@param visitor a reference to Visitor object
|
|
*/
|
|
void visit(Visitor* visitor) const;
|
|
/** Walks though the data structures and makes certain callbacks on visitor so the visitor can collect all the information.
|
|
@param unicodeText a reference to UnicodeText object
|
|
@param visitor a reference to Visitor object
|
|
@param positionType specifies a text adjustment granularity (grapheme cluster, grapheme, glypheme, glyph)
|
|
to map text blocks to glyph ranges.
|
|
@param blocks a range of text indices that cause an additional run breaking to be used for styling
|
|
*/
|
|
void visit(UnicodeText* unicodeText, Visitor* visitor, PositionType positionType, SkSpan<TextIndex> blocks) const;
|
|
};
|
|
|
|
/** This class contains all the data that allows easily paint the text on canvas.
|
|
Strictly speaking, it is not an important part of SkText API but
|
|
it presents a good example of SkText usages and simplifies testing.
|
|
*/
|
|
class DrawableText : public Visitor {
|
|
public:
|
|
std::vector<sk_sp<SkTextBlob>>& getTextBlobs();
|
|
};
|
|
|
|
struct Position {
|
|
Position(PositionType positionType, size_t lineIndex, GlyphRange glyphRange, TextRange textRange, SkRect rect);
|
|
Position(PositionType positionType);
|
|
PositionType fPositionType;
|
|
size_t fLineIndex;
|
|
GlyphRange fGlyphRange;
|
|
TextRange fTextRange;
|
|
SkRect fBoundaries;
|
|
};
|
|
struct BoxLine {
|
|
BoxLine(size_t index, TextRange text, bool hardBreak, SkRect bounds);
|
|
SkTArray<SkRect, true> fBoxGlyphs;
|
|
SkTArray<TextIndex, true> fTextByGlyph; // by glyph cluster
|
|
GlyphIndex fTextEnd;
|
|
GlyphIndex fTrailingSpacesEnd;
|
|
TextRange fTextRange;
|
|
size_t fIndex;
|
|
bool fIsHardBreak;
|
|
SkRect fBounds;
|
|
};
|
|
|
|
/** This class contains all the data that allows all navigation operations on the text:
|
|
move up/down/left/right, select some units of text and such.
|
|
*/
|
|
class SelectableText : public Visitor {
|
|
public:
|
|
SelectableText() = default;
|
|
|
|
/** Find the drawable unit (specified by positionType) closest to the screen point
|
|
@param positionType specifies a text adjustment granularity (grapheme cluster, grapheme, glypheme, glyph)
|
|
@param point a physical coordinates on a screen to find the closest glyph
|
|
@return a position object that contains all required information
|
|
*/
|
|
Position adjustedPosition(PositionType positionType, SkPoint point) const;
|
|
|
|
Position previousPosition(Position current) const;
|
|
Position nextPosition(Position current) const;
|
|
Position firstPosition(PositionType positionType) const;
|
|
Position lastPosition(PositionType positionType) const;
|
|
Position firstInLinePosition(PositionType positionType, LineIndex lineIndex) const;
|
|
Position lastInLinePosition(PositionType positionType, LineIndex lineIndex) const;
|
|
|
|
bool isFirstOnTheLine(Position element) const;
|
|
bool isLastOnTheLine(Position element) const;
|
|
|
|
size_t countLines() const;
|
|
BoxLine getLine(size_t lineIndex) const;
|
|
};
|
|
} // namespace text
|
|
} // namespace skia
|
|
|
|
#endif // Processor_DEFINED
|