/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkRemoteGlyphCacheImpl_DEFINED #define SkRemoteGlyphCacheImpl_DEFINED #include "src/core/SkArenaAlloc.h" #include "src/core/SkDescriptor.h" #include "src/core/SkGlyphRun.h" #include "src/core/SkGlyphRunPainter.h" #include "src/core/SkRemoteGlyphCache.h" class SkStrikeServer::SkGlyphCacheState : public SkStrikeInterface { public: // N.B. SkGlyphCacheState is not valid until ensureScalerContext is called. SkGlyphCacheState(const SkDescriptor& descriptor, std::unique_ptr context, SkDiscardableHandleId discardableHandleId); ~SkGlyphCacheState() override; void addGlyph(SkPackedGlyphID, bool pathOnly); void writePendingGlyphs(Serializer* serializer); SkDiscardableHandleId discardableHandleId() const { return fDiscardableHandleId; } bool isSubpixel() const { return fIsSubpixel; } const SkDescriptor& getDescriptor() const override { return *fDescriptor.getDesc(); } void setTypefaceAndEffects(const SkTypeface* typeface, SkScalerContextEffects effects); SkVector rounding() const override; SkIPoint subpixelMask() const override { return SkIPoint::Make((!fIsSubpixel || fAxisAlignment == kY_SkAxisAlignment) ? 0 : ~0u, (!fIsSubpixel || fAxisAlignment == kX_SkAxisAlignment) ? 0 : ~0u); } SkSpan prepareForDrawing(const SkPackedGlyphID packedGlyphIDs[], const SkPoint positions[], size_t n, int maxDimension, PreparationDetail detail, SkGlyphPos results[]) override; void onAboutToExitScope() override {} private: bool hasPendingGlyphs() const { return !fPendingGlyphImages.empty() || !fPendingGlyphPaths.empty(); } void writeGlyphPath(const SkPackedGlyphID& glyphID, Serializer* serializer) const; void ensureScalerContext(); void resetScalerContext(); // The set of glyphs cached on the remote client. SkTHashSet fCachedGlyphImages; SkTHashSet fCachedGlyphPaths; // The set of glyphs which has not yet been serialized and sent to the // remote client. std::vector fPendingGlyphImages; std::vector fPendingGlyphPaths; const SkAutoDescriptor fDescriptor; const SkDiscardableHandleId fDiscardableHandleId; // Values saved from the initial context. const bool fIsSubpixel; const SkAxisAlignment fAxisAlignment; // The context built using fDescriptor std::unique_ptr fContext; // These fields are set every time getOrCreateCache. This allows the code to maintain the // fContext as lazy as possible. const SkTypeface* fTypeface{nullptr}; SkScalerContextEffects fEffects; class GlyphMapHashTraits { public: static SkPackedGlyphID GetKey(const SkGlyph* glyph) { return glyph->getPackedID(); } static uint32_t Hash(SkPackedGlyphID glyphId) { return glyphId.hash(); } }; // FallbackTextHelper cases require glyph metrics when analyzing a glyph run, in which case // we cache them here. SkTHashTable fGlyphMap; SkArenaAlloc fAlloc{256}; }; class SkTextBlobCacheDiffCanvas::TrackLayerDevice : public SkNoPixelsDevice { public: TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server, sk_sp colorSpace, const SkTextBlobCacheDiffCanvas::Settings& settings); SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override; protected: void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override; private: SkStrikeServer* const fStrikeServer; const SkTextBlobCacheDiffCanvas::Settings fSettings; SkGlyphRunListPainter fPainter; }; #endif // SkRemoteGlyphCacheImpl_DEFINED