| /* |
| * Copyright 2018 The Android Open Source Project |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkGlyphRunPainter_DEFINED |
| #define SkGlyphRunPainter_DEFINED |
| |
| #include "include/core/SkSurfaceProps.h" |
| #include "src/core/SkDistanceFieldGen.h" |
| #include "src/core/SkGlyphBuffer.h" |
| #include "src/core/SkGlyphRun.h" |
| #include "src/core/SkScalerContext.h" |
| #include "src/core/SkTextBlobPriv.h" |
| |
| #if SK_SUPPORT_GPU |
| #include "src/gpu/text/GrSDFTControl.h" |
| class GrColorInfo; |
| namespace skgpu { namespace v1 { class SurfaceDrawContext; }} |
| #endif |
| |
| class SkGlyphRunPainterInterface; |
| class SkStrikeSpec; |
| class GrSDFTMatrixRange; |
| |
| // round and ignorePositionMask are used to calculate the subpixel position of a glyph. |
| // The per component (x or y) calculation is: |
| // |
| // subpixelOffset = (floor((viewportPosition + rounding) & mask) >> 14) & 3 |
| // |
| // where mask is either 0 or ~0, and rounding is either |
| // 1/2 for non-subpixel or 1/8 for subpixel. |
| struct SkGlyphPositionRoundingSpec { |
| SkGlyphPositionRoundingSpec(bool isSubpixel, SkAxisAlignment axisAlignment); |
| const SkVector halfAxisSampleFreq; |
| const SkIPoint ignorePositionMask; |
| const SkIPoint ignorePositionFieldMask; |
| |
| private: |
| static SkVector HalfAxisSampleFreq(bool isSubpixel, SkAxisAlignment axisAlignment); |
| static SkIPoint IgnorePositionMask(bool isSubpixel, SkAxisAlignment axisAlignment); |
| static SkIPoint IgnorePositionFieldMask(bool isSubpixel, SkAxisAlignment axisAlignment); |
| }; |
| |
| class SkStrikeCommon { |
| public: |
| // An atlas consists of plots, and plots hold glyphs. The minimum a plot can be is 256x256. |
| // This means that the maximum size a glyph can be is 256x256. |
| inline static constexpr uint16_t kSkSideTooBigForAtlas = 256; |
| }; |
| |
| class SkGlyphRunListPainter { |
| public: |
| // Constructor for SkBitmpapDevice. |
| SkGlyphRunListPainter(const SkSurfaceProps& props, |
| SkColorType colorType, |
| SkColorSpace* cs, |
| SkStrikeForGPUCacheInterface* strikeCache); |
| |
| #if SK_SUPPORT_GPU |
| // The following two ctors are used exclusively by the GPU, and will always use the global |
| // strike cache. |
| SkGlyphRunListPainter(const SkSurfaceProps&, const GrColorInfo&); |
| explicit SkGlyphRunListPainter(const skgpu::v1::SurfaceDrawContext&); |
| #endif // SK_SUPPORT_GPU |
| |
| class BitmapDevicePainter { |
| public: |
| BitmapDevicePainter() = default; |
| BitmapDevicePainter(const BitmapDevicePainter&) = default; |
| virtual ~BitmapDevicePainter() = default; |
| |
| virtual void paintMasks(SkDrawableGlyphBuffer* accepted, const SkPaint& paint) const = 0; |
| virtual void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull, |
| const SkSamplingOptions&, const SkPaint&) const = 0; |
| }; |
| |
| void drawForBitmapDevice( |
| SkCanvas* canvas, const BitmapDevicePainter* bitmapDevice, |
| const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix); |
| |
| #if SK_SUPPORT_GPU |
| // A nullptr for process means that the calls to the cache will be performed, but none of the |
| // callbacks will be called. |
| void processGlyphRun(SkGlyphRunPainterInterface* process, |
| const SkGlyphRun& glyphRun, |
| const SkMatrix& drawMatrix, |
| const SkPaint& drawPaint, |
| const GrSDFTControl& control, |
| const char* tag = nullptr, |
| uint64_t blobID = SK_InvalidUniqueID); |
| #endif // SK_SUPPORT_GPU |
| |
| private: |
| SkGlyphRunListPainter(const SkSurfaceProps& props, SkColorType colorType, |
| SkScalerContextFlags flags, SkStrikeForGPUCacheInterface* strikeCache); |
| |
| struct ScopedBuffers { |
| ScopedBuffers(SkGlyphRunListPainter* painter, size_t size); |
| ~ScopedBuffers(); |
| SkGlyphRunListPainter* fPainter; |
| }; |
| |
| ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRunList& glyphRunList); |
| ScopedBuffers SK_WARN_UNUSED_RESULT ensureBuffers(const SkGlyphRun& glyphRun); |
| |
| // The props as on the actual device. |
| const SkSurfaceProps fDeviceProps; |
| // The props for when the bitmap device can't draw LCD text. |
| const SkSurfaceProps fBitmapFallbackProps; |
| const SkColorType fColorType; |
| const SkScalerContextFlags fScalerContextFlags; |
| |
| SkStrikeForGPUCacheInterface* const fStrikeCache; |
| |
| SkDrawableGlyphBuffer fAccepted; |
| SkSourceGlyphBuffer fRejected; |
| }; |
| |
| // SkGlyphRunPainterInterface are all the ways that Ganesh generates glyphs. The first |
| // distinction is between Device and Source. |
| // * Device - the data in the cache is scaled to the device. There is no transformation from the |
| // cache to the screen. |
| // * Source - the data in the cache needs to be scaled from the cache to source space using the |
| // factor cacheToSourceScale. When drawn the system must combine cacheToSourceScale and the |
| // deviceView matrix to transform the cache data onto the screen. This allows zooming and |
| // simple animation to reuse the same glyph data by just changing the transform. |
| // |
| // In addition to transformation type above, Masks, Paths, SDFT, and Fallback (or really the |
| // rendering method of last resort) are the different |
| // formats of data used from the cache. |
| class SkGlyphRunPainterInterface { |
| public: |
| virtual ~SkGlyphRunPainterInterface() = default; |
| |
| virtual void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted, |
| sk_sp<SkStrike>&& strike) = 0; |
| |
| virtual void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted, |
| sk_sp<SkStrike>&& strike, |
| SkScalar strikeToSourceScale) = 0; |
| |
| virtual void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& accepted, |
| const SkFont& runFont, |
| SkScalar strikeToSourceScale) = 0; |
| |
| virtual void processSourceDrawables(const SkZip<SkGlyphVariant, SkPoint>& accepted, |
| const SkFont& runFont, |
| SkScalar strikeToSourceScale) = 0; |
| |
| virtual void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& accepted, |
| sk_sp<SkStrike>&& strike, |
| SkScalar strikeToSourceScale, |
| const SkFont& runFont, |
| const GrSDFTMatrixRange& matrixRange) = 0; |
| }; |
| |
| #endif // SkGlyphRunPainter_DEFINED |