1/*
2 * Copyright 2019 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 "src/core/SkGlyphBuffer.h"
9#include "src/core/SkGlyphRunPainter.h"
10#include "src/core/SkStrikeForGPU.h"
11
12void SkSourceGlyphBuffer::reset() {
13 fRejectedGlyphIDs.reset();
14 fRejectedPositions.reset();
15}
16
17void SkDrawableGlyphBuffer::ensureSize(size_t size) {
18 if (size > fMaxSize) {
19 fMultiBuffer.reset(size);
20 fPositions.reset(size);
21 fMaxSize = size;
22 }
23
24 fInputSize = 0;
25 fDrawableSize = 0;
26}
27
28void SkDrawableGlyphBuffer::startSource(
29 const SkZip<const SkGlyphID, const SkPoint>& source, SkPoint origin) {
30 fInputSize = source.size();
31 fDrawableSize = 0;
32
33 // Map all the positions.
34 auto positions = source.get<1>();
35 SkMatrix::MakeTrans(origin.x(), origin.y()).mapPoints(
36 fPositions, positions.data(), positions.size());
37
38 // Convert from SkGlyphIDs to SkPackedGlyphIDs.
39 SkGlyphVariant* packedIDCursor = fMultiBuffer;
40 for (auto t : source) {
41 *packedIDCursor++ = SkPackedGlyphID{std::get<0>(t)};
42 }
43 SkDEBUGCODE(fPhase = kInput);
44}
45
46void SkDrawableGlyphBuffer::startPaths(const SkZip<const SkGlyphID, const SkPoint> &source) {
47 fInputSize = source.size();
48 fDrawableSize = 0;
49
50 auto positions = source.get<1>();
51 memcpy(fPositions, positions.data(), positions.size() * sizeof(SkPoint));
52
53 // Convert from SkGlyphIDs to SkPackedGlyphIDs.
54 SkGlyphVariant* packedIDCursor = fMultiBuffer;
55 for (auto t : source) {
56 *packedIDCursor++ = SkPackedGlyphID{std::get<0>(t)};
57 }
58 SkDEBUGCODE(fPhase = kInput);
59}
60
61void SkDrawableGlyphBuffer::startDevice(
62 const SkZip<const SkGlyphID, const SkPoint>& source,
63 SkPoint origin, const SkMatrix& viewMatrix,
64 const SkGlyphPositionRoundingSpec& roundingSpec) {
65 fInputSize = source.size();
66 fDrawableSize = 0;
67
68 // Map the positions including subpixel position.
69 auto positions = source.get<1>();
70 SkMatrix matrix = viewMatrix;
71 matrix.preTranslate(origin.x(), origin.y());
72 SkPoint halfSampleFreq = roundingSpec.halfAxisSampleFreq;
73 matrix.postTranslate(halfSampleFreq.x(), halfSampleFreq.y());
74 matrix.mapPoints(fPositions, positions.data(), positions.size());
75
76 // Mask for controlling axis alignment.
77 SkIPoint mask = roundingSpec.ignorePositionFieldMask;
78
79 // Convert glyph ids and positions to packed glyph ids.
80 SkZip<const SkGlyphID, const SkPoint> withMappedPos =
81 SkMakeZip(source.get<0>(), fPositions.get());
82 SkGlyphVariant* packedIDCursor = fMultiBuffer;
83 for (auto [glyphID, pos] : withMappedPos) {
84 *packedIDCursor++ = SkPackedGlyphID{glyphID, pos, mask};
85 }
86 SkDEBUGCODE(fPhase = kInput);
87}
88
89void SkDrawableGlyphBuffer::reset() {
90 SkDEBUGCODE(fPhase = kReset);
91 if (fMaxSize > 200) {
92 fMultiBuffer.reset();
93 fPositions.reset();
94 fMaxSize = 0;
95 }
96 fInputSize = 0;
97 fDrawableSize = 0;
98}
99
100