gfx/thebes/gfxSVGGlyphs.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef GFX_SVG_GLYPHS_WRAPPER_H
michael@0 6 #define GFX_SVG_GLYPHS_WRAPPER_H
michael@0 7
michael@0 8 #include "gfxFontUtils.h"
michael@0 9 #include "nsString.h"
michael@0 10 #include "nsAutoPtr.h"
michael@0 11 #include "nsClassHashtable.h"
michael@0 12 #include "nsBaseHashtable.h"
michael@0 13 #include "nsHashKeys.h"
michael@0 14 #include "gfxPattern.h"
michael@0 15 #include "mozilla/gfx/UserData.h"
michael@0 16 #include "nsRefreshDriver.h"
michael@0 17 #include "DrawMode.h"
michael@0 18
michael@0 19 class nsIDocument;
michael@0 20 class nsIContentViewer;
michael@0 21 class nsIPresShell;
michael@0 22 class gfxSVGGlyphs;
michael@0 23 class gfxTextContextPaint;
michael@0 24
michael@0 25 namespace mozilla {
michael@0 26 namespace dom {
michael@0 27 class Element;
michael@0 28 }
michael@0 29 }
michael@0 30
michael@0 31 /**
michael@0 32 * Wraps an SVG document contained in the SVG table of an OpenType font.
michael@0 33 * There may be multiple SVG documents in an SVG table which we lazily parse
michael@0 34 * so we have an instance of this class for every document in the SVG table
michael@0 35 * which contains a glyph ID which has been used
michael@0 36 * Finds and looks up elements contained in the SVG document which have glyph
michael@0 37 * mappings to be drawn by gfxSVGGlyphs
michael@0 38 */
michael@0 39 class gfxSVGGlyphsDocument MOZ_FINAL : public nsAPostRefreshObserver
michael@0 40 {
michael@0 41 typedef mozilla::dom::Element Element;
michael@0 42
michael@0 43 public:
michael@0 44 gfxSVGGlyphsDocument(const uint8_t *aBuffer, uint32_t aBufLen,
michael@0 45 gfxSVGGlyphs *aSVGGlyphs);
michael@0 46
michael@0 47 Element *GetGlyphElement(uint32_t aGlyphId);
michael@0 48
michael@0 49 ~gfxSVGGlyphsDocument();
michael@0 50
michael@0 51 virtual void DidRefresh() MOZ_OVERRIDE;
michael@0 52
michael@0 53 private:
michael@0 54 nsresult ParseDocument(const uint8_t *aBuffer, uint32_t aBufLen);
michael@0 55
michael@0 56 nsresult SetupPresentation();
michael@0 57
michael@0 58 void FindGlyphElements(Element *aElement);
michael@0 59
michael@0 60 void InsertGlyphId(Element *aGlyphElement);
michael@0 61
michael@0 62 // Weak so as not to create a cycle. mOwner owns us so this can't dangle.
michael@0 63 gfxSVGGlyphs* mOwner;
michael@0 64 nsCOMPtr<nsIDocument> mDocument;
michael@0 65 nsCOMPtr<nsIContentViewer> mViewer;
michael@0 66 nsCOMPtr<nsIPresShell> mPresShell;
michael@0 67
michael@0 68 nsBaseHashtable<nsUint32HashKey, Element*, Element*> mGlyphIdMap;
michael@0 69
michael@0 70 nsAutoCString mSVGGlyphsDocumentURI;
michael@0 71 };
michael@0 72
michael@0 73 /**
michael@0 74 * Used by |gfxFontEntry| to represent the SVG table of an OpenType font.
michael@0 75 * Handles lazy parsing of the SVG documents in the table, looking up SVG glyphs
michael@0 76 * and rendering SVG glyphs.
michael@0 77 * Each |gfxFontEntry| owns at most one |gfxSVGGlyphs| instance.
michael@0 78 */
michael@0 79 class gfxSVGGlyphs
michael@0 80 {
michael@0 81 private:
michael@0 82 typedef mozilla::dom::Element Element;
michael@0 83
michael@0 84 public:
michael@0 85 /**
michael@0 86 * @param aSVGTable The SVG table from the OpenType font
michael@0 87 *
michael@0 88 * The gfxSVGGlyphs object takes over ownership of the blob references
michael@0 89 * that are passed in, and will hb_blob_destroy() them when finished;
michael@0 90 * the caller should -not- destroy these references.
michael@0 91 */
michael@0 92 gfxSVGGlyphs(hb_blob_t *aSVGTable, gfxFontEntry *aFontEntry);
michael@0 93
michael@0 94 /**
michael@0 95 * Releases our references to the SVG table and cleans up everything else.
michael@0 96 */
michael@0 97 ~gfxSVGGlyphs();
michael@0 98
michael@0 99 /**
michael@0 100 * This is called when the refresh driver has ticked.
michael@0 101 */
michael@0 102 void DidRefresh();
michael@0 103
michael@0 104 /**
michael@0 105 * Find the |gfxSVGGlyphsDocument| containing an SVG glyph for |aGlyphId|.
michael@0 106 * If |aGlyphId| does not map to an SVG document, return null.
michael@0 107 * If a |gfxSVGGlyphsDocument| has not been created for the document, create one.
michael@0 108 */
michael@0 109 gfxSVGGlyphsDocument *FindOrCreateGlyphsDocument(uint32_t aGlyphId);
michael@0 110
michael@0 111 /**
michael@0 112 * Return true iff there is an SVG glyph for |aGlyphId|
michael@0 113 */
michael@0 114 bool HasSVGGlyph(uint32_t aGlyphId);
michael@0 115
michael@0 116 /**
michael@0 117 * Render the SVG glyph for |aGlyphId|
michael@0 118 * @param aDrawMode Whether to fill or stroke or both; see DrawMode
michael@0 119 * @param aContextPaint Information on text context paints.
michael@0 120 * See |gfxTextContextPaint|.
michael@0 121 */
michael@0 122 bool RenderGlyph(gfxContext *aContext, uint32_t aGlyphId, DrawMode aDrawMode,
michael@0 123 gfxTextContextPaint *aContextPaint);
michael@0 124
michael@0 125 /**
michael@0 126 * Get the extents for the SVG glyph associated with |aGlyphId|
michael@0 127 * @param aSVGToAppSpace The matrix mapping the SVG glyph space to the
michael@0 128 * target context space
michael@0 129 */
michael@0 130 bool GetGlyphExtents(uint32_t aGlyphId, const gfxMatrix& aSVGToAppSpace,
michael@0 131 gfxRect *aResult);
michael@0 132
michael@0 133 private:
michael@0 134 Element *GetGlyphElement(uint32_t aGlyphId);
michael@0 135
michael@0 136 nsClassHashtable<nsUint32HashKey, gfxSVGGlyphsDocument> mGlyphDocs;
michael@0 137 nsBaseHashtable<nsUint32HashKey, Element*, Element*> mGlyphIdMap;
michael@0 138
michael@0 139 hb_blob_t *mSVGData;
michael@0 140 gfxFontEntry *mFontEntry;
michael@0 141
michael@0 142 const struct Header {
michael@0 143 mozilla::AutoSwap_PRUint16 mVersion;
michael@0 144 mozilla::AutoSwap_PRUint32 mDocIndexOffset;
michael@0 145 mozilla::AutoSwap_PRUint32 mColorPalettesOffset;
michael@0 146 } *mHeader;
michael@0 147
michael@0 148 struct IndexEntry {
michael@0 149 mozilla::AutoSwap_PRUint16 mStartGlyph;
michael@0 150 mozilla::AutoSwap_PRUint16 mEndGlyph;
michael@0 151 mozilla::AutoSwap_PRUint32 mDocOffset;
michael@0 152 mozilla::AutoSwap_PRUint32 mDocLength;
michael@0 153 };
michael@0 154
michael@0 155 const struct DocIndex {
michael@0 156 mozilla::AutoSwap_PRUint16 mNumEntries;
michael@0 157 IndexEntry mEntries[1]; /* actual length = mNumEntries */
michael@0 158 } *mDocIndex;
michael@0 159
michael@0 160 static int CompareIndexEntries(const void *_a, const void *_b);
michael@0 161 };
michael@0 162
michael@0 163 /**
michael@0 164 * Used for trickling down paint information through to SVG glyphs.
michael@0 165 */
michael@0 166 class gfxTextContextPaint
michael@0 167 {
michael@0 168 protected:
michael@0 169 gfxTextContextPaint() { }
michael@0 170
michael@0 171 public:
michael@0 172 static mozilla::gfx::UserDataKey sUserDataKey;
michael@0 173
michael@0 174 /*
michael@0 175 * Get text context pattern with the specified opacity value.
michael@0 176 * This lets us inherit paints and paint opacities (i.e. fill/stroke and
michael@0 177 * fill-opacity/stroke-opacity) separately.
michael@0 178 */
michael@0 179 virtual already_AddRefed<gfxPattern> GetFillPattern(float aOpacity,
michael@0 180 const gfxMatrix& aCTM) = 0;
michael@0 181 virtual already_AddRefed<gfxPattern> GetStrokePattern(float aOpacity,
michael@0 182 const gfxMatrix& aCTM) = 0;
michael@0 183
michael@0 184 virtual float GetFillOpacity() { return 1.0f; }
michael@0 185 virtual float GetStrokeOpacity() { return 1.0f; }
michael@0 186
michael@0 187 void InitStrokeGeometry(gfxContext *aContext,
michael@0 188 float devUnitsPerSVGUnit);
michael@0 189
michael@0 190 FallibleTArray<gfxFloat>& GetStrokeDashArray() {
michael@0 191 return mDashes;
michael@0 192 }
michael@0 193
michael@0 194 gfxFloat GetStrokeDashOffset() {
michael@0 195 return mDashOffset;
michael@0 196 }
michael@0 197
michael@0 198 gfxFloat GetStrokeWidth() {
michael@0 199 return mStrokeWidth;
michael@0 200 }
michael@0 201
michael@0 202 already_AddRefed<gfxPattern> GetFillPattern(const gfxMatrix& aCTM) {
michael@0 203 return GetFillPattern(GetFillOpacity(), aCTM);
michael@0 204 }
michael@0 205
michael@0 206 already_AddRefed<gfxPattern> GetStrokePattern(const gfxMatrix& aCTM) {
michael@0 207 return GetStrokePattern(GetStrokeOpacity(), aCTM);
michael@0 208 }
michael@0 209
michael@0 210 virtual ~gfxTextContextPaint() { }
michael@0 211
michael@0 212 private:
michael@0 213 FallibleTArray<gfxFloat> mDashes;
michael@0 214 gfxFloat mDashOffset;
michael@0 215 gfxFloat mStrokeWidth;
michael@0 216 };
michael@0 217
michael@0 218 /**
michael@0 219 * For passing in patterns where the text context has no separate pattern
michael@0 220 * opacity value.
michael@0 221 */
michael@0 222 class SimpleTextContextPaint : public gfxTextContextPaint
michael@0 223 {
michael@0 224 private:
michael@0 225 static const gfxRGBA sZero;
michael@0 226
michael@0 227 public:
michael@0 228 static gfxMatrix SetupDeviceToPatternMatrix(gfxPattern *aPattern,
michael@0 229 const gfxMatrix& aCTM)
michael@0 230 {
michael@0 231 if (!aPattern) {
michael@0 232 return gfxMatrix();
michael@0 233 }
michael@0 234 gfxMatrix deviceToUser = aCTM;
michael@0 235 deviceToUser.Invert();
michael@0 236 return deviceToUser * aPattern->GetMatrix();
michael@0 237 }
michael@0 238
michael@0 239 SimpleTextContextPaint(gfxPattern *aFillPattern, gfxPattern *aStrokePattern,
michael@0 240 const gfxMatrix& aCTM) :
michael@0 241 mFillPattern(aFillPattern ? aFillPattern : new gfxPattern(sZero)),
michael@0 242 mStrokePattern(aStrokePattern ? aStrokePattern : new gfxPattern(sZero))
michael@0 243 {
michael@0 244 mFillMatrix = SetupDeviceToPatternMatrix(aFillPattern, aCTM);
michael@0 245 mStrokeMatrix = SetupDeviceToPatternMatrix(aStrokePattern, aCTM);
michael@0 246 }
michael@0 247
michael@0 248 already_AddRefed<gfxPattern> GetFillPattern(float aOpacity,
michael@0 249 const gfxMatrix& aCTM) {
michael@0 250 if (mFillPattern) {
michael@0 251 mFillPattern->SetMatrix(aCTM * mFillMatrix);
michael@0 252 }
michael@0 253 nsRefPtr<gfxPattern> fillPattern = mFillPattern;
michael@0 254 return fillPattern.forget();
michael@0 255 }
michael@0 256
michael@0 257 already_AddRefed<gfxPattern> GetStrokePattern(float aOpacity,
michael@0 258 const gfxMatrix& aCTM) {
michael@0 259 if (mStrokePattern) {
michael@0 260 mStrokePattern->SetMatrix(aCTM * mStrokeMatrix);
michael@0 261 }
michael@0 262 nsRefPtr<gfxPattern> strokePattern = mStrokePattern;
michael@0 263 return strokePattern.forget();
michael@0 264 }
michael@0 265
michael@0 266 float GetFillOpacity() {
michael@0 267 return mFillPattern ? 1.0f : 0.0f;
michael@0 268 }
michael@0 269
michael@0 270 float GetStrokeOpacity() {
michael@0 271 return mStrokePattern ? 1.0f : 0.0f;
michael@0 272 }
michael@0 273
michael@0 274 private:
michael@0 275 nsRefPtr<gfxPattern> mFillPattern;
michael@0 276 nsRefPtr<gfxPattern> mStrokePattern;
michael@0 277
michael@0 278 // Device space to pattern space transforms
michael@0 279 gfxMatrix mFillMatrix;
michael@0 280 gfxMatrix mStrokeMatrix;
michael@0 281 };
michael@0 282
michael@0 283 #endif

mercurial