blob: aedfbbe9dfc2c80e3ed71d7e6a4793d50f5f2935 [file] [log] [blame]
Florin Malita9867f612018-12-12 10:54:49 -05001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkShaper.h"
Florin Malita9867f612018-12-12 10:54:49 -05009#include "SkTextBlobPriv.h"
Ben Wagner3bdb69c2019-04-01 19:01:09 -040010#include "SkFontMetrics.h"
Florin Malita9867f612018-12-12 10:54:49 -050011
Ben Wagnerb0591942019-02-15 14:46:18 -050012std::unique_ptr<SkShaper> SkShaper::Make() {
13#ifdef SK_SHAPER_HARFBUZZ_AVAILABLE
14 std::unique_ptr<SkShaper> shaper = SkShaper::MakeHarfBuzz();
15 if (shaper) {
16 return shaper;
17 }
18#endif
19 return SkShaper::MakePrimitive();
20}
21
22SkShaper::SkShaper() {}
23SkShaper::~SkShaper() {}
24
Ben Wagner3bdb69c2019-04-01 19:01:09 -040025void SkTextBlobBuilderRunHandler::beginLine() {
26 fCurrentPosition = fOffset;
27 fMaxRunAscent = 0;
28 fMaxRunDescent = 0;
29 fMaxRunLeading = 0;
30}
31void SkTextBlobBuilderRunHandler::runInfo(const RunInfo& info) {
32 SkFontMetrics metrics;
33 info.fFont.getMetrics(&metrics);
34 fMaxRunAscent = SkTMin(fMaxRunAscent, metrics.fAscent);
35 fMaxRunDescent = SkTMax(fMaxRunDescent, metrics.fDescent);
36 fMaxRunLeading = SkTMax(fMaxRunLeading, metrics.fLeading);
37}
38
39void SkTextBlobBuilderRunHandler::commitRunInfo() {
40 fCurrentPosition.fY -= fMaxRunAscent;
41}
42
43SkShaper::RunHandler::Buffer SkTextBlobBuilderRunHandler::runBuffer(const RunInfo& info) {
44 int glyphCount = SkTFitsIn<int>(info.glyphCount) ? info.glyphCount : INT_MAX;
45 int utf8RangeSize = SkTFitsIn<int>(info.utf8Range.size()) ? info.utf8Range.size() : INT_MAX;
46
47 const auto& runBuffer = SkTextBlobBuilderPriv::AllocRunTextPos(&fBuilder, info.fFont, glyphCount,
48 utf8RangeSize, SkString());
Ben Wagner454e5fb2019-02-08 17:46:38 -050049 if (runBuffer.utf8text && fUtf8Text) {
Ben Wagner3bdb69c2019-04-01 19:01:09 -040050 memcpy(runBuffer.utf8text, fUtf8Text + info.utf8Range.begin(), utf8RangeSize);
Ben Wagner454e5fb2019-02-08 17:46:38 -050051 }
52 fClusters = runBuffer.clusters;
53 fGlyphCount = glyphCount;
Ben Wagner3bdb69c2019-04-01 19:01:09 -040054 fClusterOffset = info.utf8Range.begin();
Ben Wagner454e5fb2019-02-08 17:46:38 -050055
Florin Malita9867f612018-12-12 10:54:49 -050056 return { runBuffer.glyphs,
Mike Reed22451cc2019-01-01 15:40:28 -050057 runBuffer.points(),
Ben Wagner3bdb69c2019-04-01 19:01:09 -040058 nullptr,
59 runBuffer.clusters,
60 fCurrentPosition };
Florin Malita9867f612018-12-12 10:54:49 -050061}
62
Ben Wagner3bdb69c2019-04-01 19:01:09 -040063void SkTextBlobBuilderRunHandler::commitRunBuffer(const RunInfo& info) {
Ben Wagner18ea3c72019-02-15 16:35:48 -050064 SkASSERT(0 <= fClusterOffset);
Ben Wagner454e5fb2019-02-08 17:46:38 -050065 for (int i = 0; i < fGlyphCount; ++i) {
Ben Wagner18ea3c72019-02-15 16:35:48 -050066 SkASSERT(fClusters[i] >= (unsigned)fClusterOffset);
Ben Wagner454e5fb2019-02-08 17:46:38 -050067 fClusters[i] -= fClusterOffset;
68 }
Ben Wagner3bdb69c2019-04-01 19:01:09 -040069 fCurrentPosition += info.fAdvance;
70}
71void SkTextBlobBuilderRunHandler::commitLine() {
72 fOffset += { 0, fMaxRunDescent + fMaxRunLeading - fMaxRunAscent };
Ben Wagner454e5fb2019-02-08 17:46:38 -050073}
74
Florin Malita950243d2019-01-11 11:08:35 -050075sk_sp<SkTextBlob> SkTextBlobBuilderRunHandler::makeBlob() {
Florin Malita9867f612018-12-12 10:54:49 -050076 return fBuilder.make();
77}