1 /*
   2  * Copyright © 2018  Ebrahim Byagowi
   3  *
   4  *  This is part of HarfBuzz, a text shaping library.
   5  *
   6  * Permission is hereby granted, without written agreement and without
   7  * license or royalty fees, to use, copy, modify, and distribute this
   8  * software and its documentation for any purpose, provided that the
   9  * above copyright notice and the following two paragraphs appear in
  10  * all copies of this software.
  11  *
  12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  16  * DAMAGE.
  17  *
  18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  23  */
  24 
  25 #ifndef HB_OT_COLOR_SVG_TABLE_HH
  26 #define HB_OT_COLOR_SVG_TABLE_HH
  27 
  28 #include "hb-open-type-private.hh"
  29 
  30 /*
  31  * SVG -- SVG (Scalable Vector Graphics)
  32  * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
  33  */
  34 
  35 #define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
  36 
  37 
  38 namespace OT {
  39 
  40 
  41 struct SVGDocumentIndexEntry
  42 {
  43   friend struct SVG;
  44 
  45   inline bool sanitize (hb_sanitize_context_t *c, const void* base) const
  46   {
  47     TRACE_SANITIZE (this);
  48     return_trace (c->check_struct (this) &&
  49                   (base+svgDoc).sanitize (c, svgDocLength));
  50   }
  51 
  52   protected:
  53   HBUINT16      startGlyphID;   /* The first glyph ID in the range described by
  54                                  * this index entry. */
  55   HBUINT16      endGlyphID;     /* The last glyph ID in the range described by
  56                                  * this index entry. Must be >= startGlyphID. */
  57   LOffsetTo<UnsizedArrayOf<HBUINT8> >
  58                 svgDoc;         /* Offset from the beginning of the SVG Document Index
  59                                  * to an SVG document. Must be non-zero. */
  60   HBUINT32 svgDocLength;        /* Length of the SVG document.
  61                                  * Must be non-zero. */
  62   public:
  63   DEFINE_SIZE_STATIC (12);
  64 };
  65 
  66 struct SVGDocumentIndex
  67 {
  68   friend struct SVG;
  69 
  70   inline bool sanitize (hb_sanitize_context_t *c) const
  71   {
  72     TRACE_SANITIZE (this);
  73     return_trace (c->check_struct (this) &&
  74                   entries.sanitize (c, this));
  75   }
  76 
  77   protected:
  78   ArrayOf<SVGDocumentIndexEntry>
  79                 entries;        /* Array of SVG Document Index Entries. */
  80   public:
  81   DEFINE_SIZE_ARRAY (2, entries);
  82 };
  83 
  84 struct SVG
  85 {
  86   static const hb_tag_t tableTag = HB_OT_TAG_SVG;
  87 
  88   inline bool sanitize (hb_sanitize_context_t *c) const
  89   {
  90     TRACE_SANITIZE (this);
  91     return_trace (likely (c->check_struct (this) &&
  92                           (this+svgDocIndex).sanitize (c)));
  93   }
  94 
  95   struct accelerator_t
  96   {
  97     inline void init (hb_face_t *face)
  98     {
  99       OT::Sanitizer<OT::SVG> sanitizer;
 100       svg_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_SVG));
 101       svg_len = hb_blob_get_length (svg_blob);
 102       svg = svg_blob->as<OT::SVG> ();
 103 
 104     }
 105 
 106     inline void fini (void)
 107     {
 108       hb_blob_destroy (svg_blob);
 109     }
 110 
 111     inline void
 112     dump (void (*callback) (const uint8_t* data, unsigned int length,
 113                             unsigned int start_glyph, unsigned int end_glyph)) const
 114     {
 115       const SVGDocumentIndex &index = svg+svg->svgDocIndex;
 116       const ArrayOf<SVGDocumentIndexEntry> &entries = index.entries;
 117       for (unsigned int i = 0; i < entries.len; ++i)
 118       {
 119         const SVGDocumentIndexEntry &entry = entries[i];
 120         callback ((const uint8_t*) &entry.svgDoc (&index), entry.svgDocLength,
 121                                                   entry.startGlyphID, entry.endGlyphID);
 122       }
 123     }
 124 
 125     private:
 126     hb_blob_t *svg_blob;
 127     const SVG *svg;
 128 
 129     unsigned int svg_len;
 130   };
 131 
 132   protected:
 133   HBUINT16      version;        /* Table version (starting at 0). */
 134   LOffsetTo<SVGDocumentIndex>
 135                 svgDocIndex;    /* Offset (relative to the start of the SVG table) to the
 136                                  * SVG Documents Index. Must be non-zero. */
 137   HBUINT32      reserved;       /* Set to 0. */
 138   public:
 139   DEFINE_SIZE_STATIC (10);
 140 };
 141 
 142 } /* namespace OT */
 143 
 144 
 145 #endif /* HB_OT_COLOR_SVG_TABLE_HH */