| /* |
| * Copyright 2019 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkGlyphBuffer_DEFINED |
| #define SkGlyphBuffer_DEFINED |
| |
| #include "src/core/SkGlyph.h" |
| #include "src/core/SkZip.h" |
| |
| class SkStrikeForGPU; |
| struct SkGlyphPositionRoundingSpec; |
| |
| // A memory format that allows an SkPackedGlyphID, SkGlyph*, and SkPath* to occupy the same |
| // memory. This allows SkPackedGlyphIDs as input, and SkGlyph*/SkPath* as output using the same |
| // memory. |
| class SkGlyphVariant { |
| public: |
| SkGlyphVariant() : fV{nullptr} { } |
| SkGlyphVariant& operator= (SkPackedGlyphID packedID) { |
| fV.packedID = packedID; |
| SkDEBUGCODE(fTag = kPackedID); |
| return *this; |
| } |
| SkGlyphVariant& operator= (SkGlyph* glyph) { |
| fV.glyph = glyph; |
| SkDEBUGCODE(fTag = kGlyph); |
| return *this; |
| |
| } |
| SkGlyphVariant& operator= (const SkPath* path) { |
| fV.path = path; |
| SkDEBUGCODE(fTag = kPath); |
| return *this; |
| } |
| |
| SkGlyph* glyph() const { |
| SkASSERT(fTag == kGlyph); |
| return fV.glyph; |
| } |
| const SkPath* path() const { |
| SkASSERT(fTag == kPath); |
| return fV.path; |
| } |
| SkPackedGlyphID packedID() const { |
| SkASSERT(fTag == kPackedID); |
| return fV.packedID; |
| } |
| |
| operator SkPackedGlyphID() const { return this->packedID(); } |
| operator SkGlyph*() const { return this->glyph(); } |
| operator const SkPath*() const { return this->path(); } |
| |
| private: |
| union { |
| SkGlyph* glyph; |
| const SkPath* path; |
| SkPackedGlyphID packedID; |
| } fV; |
| |
| #ifdef SK_DEBUG |
| enum { |
| kEmpty, |
| kPackedID, |
| kGlyph, |
| kPath |
| } fTag{kEmpty}; |
| #endif |
| }; |
| |
| // A buffer for converting SkPackedGlyph to SkGlyph* or SkPath*. Initially the buffer contains |
| // SkPackedGlyphIDs, but those are used to lookup SkGlyph*/SkPath* which are then copied over the |
| // SkPackedGlyphIDs. |
| class SkDrawableGlyphBuffer { |
| public: |
| void ensureSize(size_t size); |
| |
| // Load the buffer with SkPackedGlyphIDs and positions in source space. |
| void startSource(const SkZip<const SkGlyphID, const SkPoint>& source, SkPoint origin); |
| |
| // Load the buffer with SkPackedGlyphIDs and positions using the device transform. |
| void startDevice( |
| const SkZip<const SkGlyphID, const SkPoint>& source, |
| SkPoint origin, const SkMatrix& viewMatrix, |
| const SkGlyphPositionRoundingSpec& roundingSpec); |
| |
| // The input of SkPackedGlyphIDs |
| SkZip<SkGlyphVariant, SkPoint> input() { |
| SkASSERT(fPhase == kInput); |
| SkDEBUGCODE(fPhase = kProcess); |
| return SkZip<SkGlyphVariant, SkPoint>{fInputSize, fMultiBuffer, fPositions}; |
| } |
| |
| // Store the glyph in the next drawable slot, using the position information located at index |
| // from. |
| void push_back(SkGlyph* glyph, size_t from) { |
| SkASSERT(fPhase == kProcess); |
| SkASSERT(fDrawableSize <= from); |
| fPositions[fDrawableSize] = fPositions[from]; |
| fMultiBuffer[fDrawableSize] = glyph; |
| fDrawableSize++; |
| } |
| |
| // Store the path in the next drawable slot, using the position information located at index |
| // from. |
| void push_back(const SkPath* path, size_t from) { |
| SkASSERT(fPhase == kProcess); |
| SkASSERT(fDrawableSize <= from); |
| fPositions[fDrawableSize] = fPositions[from]; |
| fMultiBuffer[fDrawableSize] = path; |
| fDrawableSize++; |
| } |
| |
| // The result after a series of push_backs of drawable SkGlyph* or SkPath*. |
| SkZip<SkGlyphVariant, SkPoint> drawable() { |
| SkASSERT(fPhase == kProcess); |
| SkDEBUGCODE(fPhase = kDraw); |
| return SkZip<SkGlyphVariant, SkPoint>{fDrawableSize, fMultiBuffer, fPositions}; |
| } |
| |
| void reset(); |
| |
| private: |
| size_t fMaxSize{0}; |
| size_t fInputSize{0}; |
| size_t fDrawableSize{0}; |
| SkAutoTMalloc<SkGlyphVariant> fMultiBuffer; |
| SkAutoTMalloc<SkPoint> fPositions; |
| |
| #ifdef SK_DEBUG |
| enum { |
| kReset, |
| kInput, |
| kProcess, |
| kDraw |
| } fPhase{kReset}; |
| #endif |
| }; |
| #endif // SkGlyphBuffer_DEFINED |