text: /*
   * Copyright 2014 Google Inc.
   *
   * Use of this source code is governed by a BSD-style license that can be
   * found in the LICENSE file.
   */
  
  #ifndef TestSVGTypeface_DEFINED
  #define TestSVGTypeface_DEFINED
  
  #include "include/core/SkFontArguments.h"
  #include "include/core/SkFontMetrics.h"
  #include "include/core/SkPaint.h"
  #include "include/core/SkPoint.h"
  #include "include/core/SkRect.h"
  #include "include/core/SkRefCnt.h"
  #include "include/core/SkScalar.h"
  #include "include/core/SkStream.h"
  #include "include/core/SkString.h"
  #include "include/core/SkTypeface.h"
  #include "include/core/SkTypes.h"
  #include "include/pathops/SkPathOps.h"
  #include "include/private/SkMutex.h"
  #include "include/private/SkTArray.h"
  #include "include/private/SkTHash.h"
  #include "src/core/SkSpan.h"
  
  #include <memory>
  
  class SkCanvas;
  class SkDescriptor;
  class SkFontDescriptor;
  class SkFontStyle;
  class SkGlyph;
  class SkPath;
  class SkScalerContext;
  class SkSVGDOM;
  class SkWStream;
  struct SkAdvancedTypefaceMetrics;
  struct SkScalerContextEffects;
  struct SkScalerContextRec;
  
  struct SkSVGTestTypefaceGlyphData {
      const char* fSvgResourcePath;
      SkPoint     fOrigin;  // y-down
      SkScalar    fAdvance;
      SkUnichar   fUnicode;  // TODO: this limits to 1:1
  };
  
  class TestSVGTypeface : public SkTypeface {
  public:
      TestSVGTypeface(const char*                              name,
                      int                                      upem,
                      const SkFontMetrics&                     metrics,
                      SkSpan<const SkSVGTestTypefaceGlyphData> data,
                      const SkFontStyle&                       style);
      ~TestSVGTypeface() override;
      void getAdvance(SkGlyph* glyph) const;
      void getFontMetrics(SkFontMetrics* metrics) const;
  
      static sk_sp<TestSVGTypeface> Default();
      static sk_sp<TestSVGTypeface> Planets();
      void                          exportTtxCbdt(SkWStream*, SkSpan<unsigned> strikeSizes) const;
      void                          exportTtxSbix(SkWStream*, SkSpan<unsigned> strikeSizes) const;
      void                          exportTtxColr(SkWStream*) const;
      virtual bool                  getPathOp(SkColor, SkPathOp*) const = 0;
  
      struct GlyfLayerInfo {
          GlyfLayerInfo(int layerColorIndex, SkIRect bounds)
                  : fLayerColorIndex(layerColorIndex), fBounds(bounds) {}
          int     fLayerColorIndex;
          SkIRect fBounds;
      };
      struct GlyfInfo {
          GlyfInfo() : fBounds(SkIRect::MakeEmpty()) {}
          SkIRect                 fBounds;
          SkTArray<GlyfLayerInfo> fLayers;
      };
  
  protected:
      void exportTtxCommon(SkWStream*, const char* type, const SkTArray<GlyfInfo>* = nullptr) const;
  
      SkScalerContext*                           onCreateScalerContext(const SkScalerContextEffects&,
                                                                       const SkDescriptor* desc) const override;
      void                                       onFilterRec(SkScalerContextRec* rec) const override;
      void                                       getGlyphToUnicodeMap(SkUnichar*) const override;
      std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
  
      std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override { return nullptr; }
  
      sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
          return sk_ref_sp(this);
      }
  
      void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;
  
      void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override;
  
      void getPostScriptGlyphNames(SkString*) const override {}
  
      int onCountGlyphs() const override { return fGlyphCount; }
  
      int onGetUPEM() const override { return fUpem; }
  
      void                          onGetFamilyName(SkString* familyName) const override;
      SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
  
      int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
                                       int coordinateCount) const override {
          return 0;
      }
  
      int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[],
                                         int parameterCount) const override {
          return 0;
      }
  
      int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
  
      size_t onGetTableData(SkFontTableTag tag,
                            size_t         offset,
                            size_t         length,
                            void*          data) const override {
          return 0;
      }
  
  private:
      struct Glyph {
          Glyph();
          ~Glyph();
          SkPoint     fOrigin;
          SkScalar    fAdvance;
          const char* fResourcePath;
  
          SkSize size() const;
          void render(SkCanvas*) const;
  
      private:
          // Lazily parses the SVG from fResourcePath, and manages mutex locking.
          template <typename Fn> void withSVG(Fn&&) const;
  
          // The mutex guards lazy parsing of the SVG, but also predates that.
          // Must be SkSVGDOM::render() is not thread safe?
          // If not, an SkOnce is enough here.
          mutable SkMutex         fSvgMutex;
          mutable bool            fParsedSvg = false;
          mutable sk_sp<SkSVGDOM> fSvg;
      };
  
      SkString                         fName;
      int                              fUpem;
      const SkFontMetrics              fFontMetrics;
      std::unique_ptr<Glyph[]>         fGlyphs;
      int                              fGlyphCount;
      SkTHashMap<SkUnichar, SkGlyphID> fCMap;
      friend class SkTestSVGScalerContext;
  };
  
  #endif
  