1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkGlyphBuffer.h" 9cb93a386Sopenharmony_ci#include "src/core/SkGlyphRunPainter.h" 10cb93a386Sopenharmony_ci#include "src/core/SkStrikeForGPU.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_civoid SkSourceGlyphBuffer::reset() { 13cb93a386Sopenharmony_ci fRejectedGlyphIDs.reset(); 14cb93a386Sopenharmony_ci fRejectedPositions.reset(); 15cb93a386Sopenharmony_ci} 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_civoid SkDrawableGlyphBuffer::ensureSize(size_t size) { 18cb93a386Sopenharmony_ci if (size > fMaxSize) { 19cb93a386Sopenharmony_ci fMultiBuffer.reset(size); 20cb93a386Sopenharmony_ci fPositions.reset(size); 21cb93a386Sopenharmony_ci fMaxSize = size; 22cb93a386Sopenharmony_ci } 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci fInputSize = 0; 25cb93a386Sopenharmony_ci fDrawableSize = 0; 26cb93a386Sopenharmony_ci} 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_civoid SkDrawableGlyphBuffer::startSource(const SkZip<const SkGlyphID, const SkPoint>& source) { 29cb93a386Sopenharmony_ci fInputSize = source.size(); 30cb93a386Sopenharmony_ci fDrawableSize = 0; 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci auto positions = source.get<1>(); 33cb93a386Sopenharmony_ci memcpy(fPositions, positions.data(), positions.size() * sizeof(SkPoint)); 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ci // Convert from SkGlyphIDs to SkPackedGlyphIDs. 36cb93a386Sopenharmony_ci SkGlyphVariant* packedIDCursor = fMultiBuffer.get(); 37cb93a386Sopenharmony_ci for (auto t : source) { 38cb93a386Sopenharmony_ci *packedIDCursor++ = SkPackedGlyphID{std::get<0>(t)}; 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci SkDEBUGCODE(fPhase = kInput); 41cb93a386Sopenharmony_ci} 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_civoid SkDrawableGlyphBuffer::startBitmapDevice( 44cb93a386Sopenharmony_ci const SkZip<const SkGlyphID, const SkPoint>& source, 45cb93a386Sopenharmony_ci SkPoint origin, const SkMatrix& viewMatrix, 46cb93a386Sopenharmony_ci const SkGlyphPositionRoundingSpec& roundingSpec) { 47cb93a386Sopenharmony_ci fInputSize = source.size(); 48cb93a386Sopenharmony_ci fDrawableSize = 0; 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci // Map the positions including subpixel position. 51cb93a386Sopenharmony_ci auto positions = source.get<1>(); 52cb93a386Sopenharmony_ci SkMatrix matrix = viewMatrix; 53cb93a386Sopenharmony_ci matrix.preTranslate(origin.x(), origin.y()); 54cb93a386Sopenharmony_ci SkPoint halfSampleFreq = roundingSpec.halfAxisSampleFreq; 55cb93a386Sopenharmony_ci matrix.postTranslate(halfSampleFreq.x(), halfSampleFreq.y()); 56cb93a386Sopenharmony_ci matrix.mapPoints(fPositions, positions.data(), positions.size()); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci // Mask for controlling axis alignment. 59cb93a386Sopenharmony_ci SkIPoint mask = roundingSpec.ignorePositionFieldMask; 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci // Convert glyph ids and positions to packed glyph ids. 62cb93a386Sopenharmony_ci SkZip<const SkGlyphID, const SkPoint> withMappedPos = 63cb93a386Sopenharmony_ci SkMakeZip(source.get<0>(), fPositions.get()); 64cb93a386Sopenharmony_ci SkGlyphVariant* packedIDCursor = fMultiBuffer.get(); 65cb93a386Sopenharmony_ci for (auto [glyphID, pos] : withMappedPos) { 66cb93a386Sopenharmony_ci *packedIDCursor++ = SkPackedGlyphID{glyphID, pos, mask}; 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci SkDEBUGCODE(fPhase = kInput); 69cb93a386Sopenharmony_ci} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_civoid SkDrawableGlyphBuffer::startGPUDevice( 72cb93a386Sopenharmony_ci const SkZip<const SkGlyphID, const SkPoint>& source, 73cb93a386Sopenharmony_ci const SkMatrix& drawMatrix, 74cb93a386Sopenharmony_ci const SkGlyphPositionRoundingSpec& roundingSpec) { 75cb93a386Sopenharmony_ci fInputSize = source.size(); 76cb93a386Sopenharmony_ci fDrawableSize = 0; 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci // Build up the mapping from source space to device space. Add the rounding constant 79cb93a386Sopenharmony_ci // halfSampleFreq so we just need to floor to get the device result. 80cb93a386Sopenharmony_ci SkMatrix device = drawMatrix; 81cb93a386Sopenharmony_ci SkPoint halfSampleFreq = roundingSpec.halfAxisSampleFreq; 82cb93a386Sopenharmony_ci device.postTranslate(halfSampleFreq.x(), halfSampleFreq.y()); 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci auto positions = source.get<1>(); 85cb93a386Sopenharmony_ci device.mapPoints(fPositions, positions.data(), positions.size()); 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci auto floor = [](SkPoint pt) -> SkPoint { 88cb93a386Sopenharmony_ci return {SkScalarFloorToScalar(pt.x()), SkScalarFloorToScalar(pt.y())}; 89cb93a386Sopenharmony_ci }; 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci for (auto [packedGlyphID, glyphID, pos] 92cb93a386Sopenharmony_ci : SkMakeZip(fMultiBuffer.get(), source.get<0>(), fPositions.get())) { 93cb93a386Sopenharmony_ci packedGlyphID = SkPackedGlyphID{glyphID, pos, roundingSpec.ignorePositionFieldMask}; 94cb93a386Sopenharmony_ci // Store rounded device coords back in pos. 95cb93a386Sopenharmony_ci pos = floor(pos); 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci 98cb93a386Sopenharmony_ci SkDEBUGCODE(fPhase = kInput); 99cb93a386Sopenharmony_ci} 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ciSkString SkDrawableGlyphBuffer::dumpInput() const { 102cb93a386Sopenharmony_ci SkASSERT(fPhase == kInput); 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci SkString msg; 105cb93a386Sopenharmony_ci for (auto [packedGlyphID, pos] 106cb93a386Sopenharmony_ci : SkZip<SkGlyphVariant, SkPoint>{fInputSize, fMultiBuffer.get(), fPositions.get()}) { 107cb93a386Sopenharmony_ci msg.appendf("0x%x:(%a,%a), ", packedGlyphID.packedID().value(), pos.x(), pos.y()); 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci return msg; 110cb93a386Sopenharmony_ci} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_civoid SkDrawableGlyphBuffer::reset() { 113cb93a386Sopenharmony_ci SkDEBUGCODE(fPhase = kReset); 114cb93a386Sopenharmony_ci if (fMaxSize > 200) { 115cb93a386Sopenharmony_ci fMultiBuffer.reset(); 116cb93a386Sopenharmony_ci fPositions.reset(); 117cb93a386Sopenharmony_ci fMaxSize = 0; 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci fInputSize = 0; 120cb93a386Sopenharmony_ci fDrawableSize = 0; 121cb93a386Sopenharmony_ci} 122cb93a386Sopenharmony_ci 123