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 | |
12 | void SkSourceGlyphBuffer::reset() { |
13 | fRejectedGlyphIDs.reset(); |
14 | fRejectedPositions.reset(); |
15 | } |
16 | |
17 | void 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 | |
28 | void 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 | |
46 | void 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 | |
61 | void 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 | |
89 | void 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 | |