blob: 2dba20c8f65729e6106b4250babe14b38174775a [file] [log] [blame]
// Copyright 2019 Google LLC.
#ifndef LineBreaker_DEFINED
#define LineBreaker_DEFINED
#include <functional> // std::function
#include <queue>
#include "modules/skparagraph/include/TextStyle.h"
#include "modules/skparagraph/src/ParagraphImpl.h"
#include "modules/skparagraph/src/Run.h"
#include "src/core/SkSpan.h"
namespace skia {
namespace textlayout {
typedef size_t GlyphIndex;
typedef SkRange<GlyphIndex> GlyphRange;
class ParagraphImpl;
class OneLineShaper : public SkShaper::RunHandler {
public:
explicit OneLineShaper(ParagraphImpl* paragraph)
: fParagraph(paragraph) { }
bool shape();
private:
struct RunBlock {
RunBlock() { fRun = nullptr; }
// First unresolved block
RunBlock(TextRange text) {
fRun = nullptr;
fScore = 0;
fText = text;
}
RunBlock(Run* run, TextRange text, GlyphRange glyphs, size_t score) {
fRun = run;
fText = text;
fGlyphs = glyphs;
fScore = score;
}
// Entire run comes as one block fully resolved
RunBlock(Run* run) {
fRun = run;
fGlyphs = GlyphRange(0, run->size());
fScore = run->size();
fText = run->fTextRange;
}
Run* fRun;
TextRange fText;
GlyphRange fGlyphs;
size_t fScore;
bool isFullyResolved() { return fRun != nullptr && fScore == fRun->size(); }
};
using ShapeVisitor =
std::function<SkScalar(SkSpan<const char>, SkSpan<Block>, SkScalar&, TextIndex)>;
bool iterateThroughShapingRegions(ShapeVisitor shape);
using ShapeSingleFontVisitor = std::function<void(Block)>;
void iterateThroughFontStyles(SkSpan<Block> styleSpan, ShapeSingleFontVisitor visitor);
using TypefaceVisitor = std::function<bool(sk_sp<SkTypeface> typeface)>;
void matchResolvedFonts(const TextStyle& textStyle, TypefaceVisitor visitor);
void printState();
void dropUnresolved();
void finish(TextRange text, SkScalar height, SkScalar& advanceX);
void beginLine() override {}
void runInfo(const RunInfo&) override {}
void commitRunInfo() override {}
void commitLine() override {}
Buffer runBuffer(const RunInfo& info) override {
fCurrentRun = new Run(fParagraph,
info,
fCurrentText.start,
fHeight,
fParagraph->fRuns.count(),
fAdvance.fX);
return fCurrentRun->newRunBuffer();
}
void commitRunBuffer(const RunInfo&) override;
TextRange clusteredText(GlyphRange glyphs);
void addFullyResolved();
void addUnresolvedWithRun(GlyphRange glyphRange);
void sortOutGlyphs(std::function<void(GlyphRange)>&& sortOutUnresolvedBLock);
ClusterRange normalizeTextRange(GlyphRange glyphRange);
void increment(TextIndex& index);
void fillGaps(size_t);
ParagraphImpl* fParagraph;
TextRange fCurrentText;
SkScalar fHeight;
SkVector fAdvance;
Run* fCurrentRun;
SkTArray<const Run*> fRuns;
std::queue<RunBlock> fUnresolvedBlocks;
std::vector<RunBlock> fResolvedBlocks;
};
}
}
#endif