36#include <initializer_list>
60prepare_for_path_drawing(
SkStrike* strike,
73 digest.actionFor(kPath)) {
74 case GlyphAction::kAccept:
75 acceptedBuffer[acceptedSize++] = std::make_tuple(strike->
glyph(digest),
pos);
77 case GlyphAction::kReject:
78 rejectedBuffer[rejectedSize++] = std::make_tuple(glyphID,
pos);
85 return {acceptedBuffer.
first(acceptedSize), rejectedBuffer.
first(rejectedSize)};
91prepare_for_drawable_drawing(
SkStrike* strike,
104 digest.actionFor(kDrawable)) {
105 case GlyphAction::kAccept:
106 acceptedBuffer[acceptedSize++] = std::make_tuple(strike->
glyph(digest),
pos);
108 case GlyphAction::kReject:
109 rejectedBuffer[rejectedSize++] = std::make_tuple(glyphID,
pos);
116 return {acceptedBuffer.
first(acceptedSize), rejectedBuffer.
first(rejectedSize)};
120prepare_for_direct_mask_drawing(
SkStrike* strike,
130 SkMatrix positionMatrixWithRounding = creationMatrix;
131 positionMatrixWithRounding.
postTranslate(halfSampleFreq.
x(), halfSampleFreq.
y());
133 int acceptedSize = 0;
134 int rejectedSize = 0;
144 digest.actionFor(kDirectMaskCPU)) {
145 case GlyphAction::kAccept: {
148 acceptedBuffer[acceptedSize++] =
149 std::make_tuple(strike->
glyph(digest), roundedPos);
152 case GlyphAction::kReject:
153 rejectedBuffer[rejectedSize++] = std::make_tuple(glyphID,
pos);
161 return {acceptedBuffer.
first(acceptedSize), rejectedBuffer.
first(rejectedSize)};
169 : fDeviceProps{props}
172 , fScalerContextFlags{compute_scaler_context_flags(cs)} {}
184 acceptedPackedGlyphIDs.
resize(maxGlyphRunSize);
185 acceptedPositions.
resize(maxGlyphRunSize);
186 const auto acceptedBuffer =
SkMakeZip(acceptedPackedGlyphIDs, acceptedPositions);
187 rejectedGlyphIDs.
resize(maxGlyphRunSize);
188 rejectedPositions.
resize(maxGlyphRunSize);
189 const auto rejectedBuffer =
SkMakeZip(rejectedGlyphIDs, rejectedPositions);
193 auto& props = (kN32_SkColorType == fColorType &&
paint.isSrcOver())
195 : fBitmapFallbackProps;
198 SkMatrix positionMatrix{drawMatrix};
200 for (
auto& glyphRun : glyphRunList) {
201 const SkFont& runFont = glyphRun.font();
206 auto [strikeSpec, strikeToSourceScale] =
209 auto strike = strikeSpec.findOrCreateStrike();
212 auto [accepted, rejected] = prepare_for_path_drawing(strike.get(),
225 const bool needsExactCTM = pathPaint.
getShader() ||
228 (stroking && !hairline);
230 if (!needsExactCTM) {
231 for (
auto [glyph,
pos] : accepted) {
232 const SkPath* path = glyph->path();
235 m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,
236 translate.
x(), translate.
y());
242 for (
auto [glyph,
pos] : accepted) {
243 const SkPath* path = glyph->path();
246 m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,
247 translate.
x(), translate.
y());
250 path->transform(m, &deviceOutline);
252 canvas->
drawPath(deviceOutline, pathPaint);
258 auto [accepted, rejected] = prepare_for_drawable_drawing(strike.get(),
264 for (
auto [glyph,
pos] : accepted) {
268 m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,
269 translate.
x(), translate.
y());
272 m.mapRect(&drawableBounds);
274 drawable->
draw(canvas, &m);
278 if (!
source.
empty() && !positionMatrix.hasPerspective()) {
280 runFont,
paint, props, fScalerContextFlags, positionMatrix);
284 auto [accepted, rejected] = prepare_for_direct_mask_drawing(strike.get(),
293 std::vector<SkPoint> sourcePositions;
300 auto glyphIDs =
source.get<0>();
301 auto positions =
source.get<1>();
307 if (glyph->isEmpty()) {
313 sourcePositions.push_back(srcPos);
314 SkRect rect = glyph->rect();
315 rect.makeOffset(srcPos);
316 positionMatrix.mapRectToQuad(corners, rect);
319 maxScale = std::max(maxScale,
scale);
321 scale = (corners[2] - corners[1]).
length() / rect.height();
322 maxScale = std::max(maxScale,
scale);
324 scale = (corners[3] - corners[2]).
length() / rect.width();
325 maxScale = std::max(maxScale,
scale);
327 scale = (corners[0] - corners[3]).
length() / rect.height();
328 maxScale = std::max(maxScale,
scale);
335 if (maxScale * runFont.
getSize() > 256) {
336 maxScale = 256.0f / runFont.
getSize();
341 runFont,
paint, props, fScalerContextFlags, cacheScale);
345 auto [accepted, rejected] = prepare_for_direct_mask_drawing(strike.get(),
350 const SkScalar invMaxScale = 1.0f/maxScale;
351 for (
auto [glyph, srcPos] :
SkMakeZip(accepted.get<0>(), sourcePositions)) {
352 SkMask mask = glyph->mask();
359 const_cast<uint8_t*
>(mask.
fImage),
371 translate.
preScale(invMaxScale, invMaxScale);
static bool SkIsFinite(T x, Pack... values)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
#define SkScalarFloorToScalar(x)
@ kFakeGammaAndBoostContrast
@ kUnknown_SkPixelGeometry
constexpr auto SkMakeZip(Ts &&... ts)
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
void drawPath(const SkPath &path, const SkPaint &paint)
void concat(const SkMatrix &matrix)
bool gammaIsLinear() const
void draw(SkCanvas *, const SkMatrix *=nullptr)
virtual void drawBitmap(const SkBitmap &, const SkMatrix &, const SkRect *dstOrNull, const SkSamplingOptions &, const SkPaint &) const =0
virtual void paintMasks(SkZip< const SkGlyph *, SkPoint > accepted, const SkPaint &paint) const =0
void drawForBitmapDevice(SkCanvas *canvas, const BitmapDevicePainter *bitmapDevice, const sktext::GlyphRunList &glyphRunList, const SkPaint &paint, const SkMatrix &drawMatrix)
SkGlyphRunListPainterCPU(const SkSurfaceProps &props, SkColorType colorType, SkColorSpace *cs)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
static SkMatrix Translate(SkScalar dx, SkScalar dy)
SkPoint mapPoint(SkPoint pt) const
static const SkMatrix & I()
SkMatrix & preTranslate(SkScalar dx, SkScalar dy)
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
SkPathEffect * getPathEffect() const
void setAntiAlias(bool aa)
@ kFill_Style
set to fill geometry
SkMaskFilter * getMaskFilter() const
SkScalar getStrokeWidth() const
SkShader * getShader() const
SkPath & setIsVolatile(bool isVolatile)
static SkStrikeSpec MakeMask(const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix)
static bool ShouldDrawAsPath(const SkPaint &paint, const SkFont &font, const SkMatrix &matrix)
sk_sp< SkStrike > findOrCreateStrike() const
static std::tuple< SkStrikeSpec, SkScalar > MakePath(const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags)
void unlock() override SK_RELEASE_CAPABILITY(fStrikeLock)
void lock() override SK_ACQUIRE(fStrikeLock)
SkGlyph * glyph(SkGlyphDigest) SK_REQUIRES(fStrikeLock)
const SkGlyphPositionRoundingSpec & roundingSpec() const override
SkGlyphDigest digestFor(skglyph::ActionType, SkPackedGlyphID) override SK_REQUIRES(fStrikeLock)
constexpr SkZip first(size_t n) const
void resize(size_t count)
size_t maxGlyphRunSize() const
const SkVector halfAxisSampleFreq
const SkIPoint ignorePositionFieldMask
constexpr int32_t top() const
constexpr SkISize size() const
constexpr int32_t left() const
static SkImageInfo MakeN32Premul(int width, int height)
@ kARGB32_Format
SkPMColor.
uint8_t const *const fImage
static constexpr SkPoint Make(float x, float y)
constexpr float y() const
constexpr float x() const