Bug 1708193 - Remove mozapps/extensions/internal/Content.js r=rpl
[gecko.git] / gfx / thebes / gfxSVGGlyphs.h
blob8ce2e5aa6cc715b4e88d566e046b32a55992bd15
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef GFX_SVG_GLYPHS_WRAPPER_H
6 #define GFX_SVG_GLYPHS_WRAPPER_H
8 #include "gfxFontUtils.h"
9 #include "mozilla/gfx/2D.h"
10 #include "nsString.h"
11 #include "nsClassHashtable.h"
12 #include "nsBaseHashtable.h"
13 #include "nsHashKeys.h"
14 #include "gfxPattern.h"
15 #include "mozilla/gfx/UserData.h"
16 #include "mozilla/SVGContextPaint.h"
17 #include "nsRefreshObservers.h"
19 class nsIContentViewer;
20 class gfxSVGGlyphs;
22 namespace mozilla {
23 class PresShell;
24 class SVGContextPaint;
25 namespace dom {
26 class Document;
27 class Element;
28 } // namespace dom
29 } // namespace mozilla
31 /**
32 * Wraps an SVG document contained in the SVG table of an OpenType font.
33 * There may be multiple SVG documents in an SVG table which we lazily parse
34 * so we have an instance of this class for every document in the SVG table
35 * which contains a glyph ID which has been used
36 * Finds and looks up elements contained in the SVG document which have glyph
37 * mappings to be drawn by gfxSVGGlyphs
39 class gfxSVGGlyphsDocument final : public nsAPostRefreshObserver {
40 typedef mozilla::dom::Element Element;
42 public:
43 gfxSVGGlyphsDocument(const uint8_t* aBuffer, uint32_t aBufLen,
44 gfxSVGGlyphs* aSVGGlyphs);
46 Element* GetGlyphElement(uint32_t aGlyphId);
48 ~gfxSVGGlyphsDocument();
50 void DidRefresh() override;
52 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
54 private:
55 nsresult ParseDocument(const uint8_t* aBuffer, uint32_t aBufLen);
57 nsresult SetupPresentation();
59 void FindGlyphElements(Element* aElement);
61 void InsertGlyphId(Element* aGlyphElement);
63 // Weak so as not to create a cycle. mOwner owns us so this can't dangle.
64 gfxSVGGlyphs* mOwner;
65 RefPtr<mozilla::dom::Document> mDocument;
66 nsCOMPtr<nsIContentViewer> mViewer;
67 RefPtr<mozilla::PresShell> mPresShell;
69 nsBaseHashtable<nsUint32HashKey, Element*, Element*> mGlyphIdMap;
71 nsCString mSVGGlyphsDocumentURI;
74 /**
75 * Used by |gfxFontEntry| to represent the SVG table of an OpenType font.
76 * Handles lazy parsing of the SVG documents in the table, looking up SVG glyphs
77 * and rendering SVG glyphs.
78 * Each |gfxFontEntry| owns at most one |gfxSVGGlyphs| instance.
80 class gfxSVGGlyphs {
81 private:
82 typedef mozilla::dom::Element Element;
84 public:
85 /**
86 * @param aSVGTable The SVG table from the OpenType font
88 * The gfxSVGGlyphs object takes over ownership of the blob references
89 * that are passed in, and will hb_blob_destroy() them when finished;
90 * the caller should -not- destroy these references.
92 gfxSVGGlyphs(hb_blob_t* aSVGTable, gfxFontEntry* aFontEntry);
94 /**
95 * Releases our references to the SVG table and cleans up everything else.
97 ~gfxSVGGlyphs();
99 /**
100 * This is called when the refresh driver has ticked.
102 void DidRefresh();
105 * Find the |gfxSVGGlyphsDocument| containing an SVG glyph for |aGlyphId|.
106 * If |aGlyphId| does not map to an SVG document, return null.
107 * If a |gfxSVGGlyphsDocument| has not been created for the document, create
108 * one.
110 gfxSVGGlyphsDocument* FindOrCreateGlyphsDocument(uint32_t aGlyphId);
113 * Return true iff there is an SVG glyph for |aGlyphId|
115 bool HasSVGGlyph(uint32_t aGlyphId);
118 * Render the SVG glyph for |aGlyphId|
119 * @param aContextPaint Information on text context paints.
120 * See |SVGContextPaint|.
122 void RenderGlyph(gfxContext* aContext, uint32_t aGlyphId,
123 mozilla::SVGContextPaint* aContextPaint);
126 * Get the extents for the SVG glyph associated with |aGlyphId|
127 * @param aSVGToAppSpace The matrix mapping the SVG glyph space to the
128 * target context space
130 bool GetGlyphExtents(uint32_t aGlyphId, const gfxMatrix& aSVGToAppSpace,
131 gfxRect* aResult);
133 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
135 private:
136 Element* GetGlyphElement(uint32_t aGlyphId);
138 nsClassHashtable<nsUint32HashKey, gfxSVGGlyphsDocument> mGlyphDocs;
139 nsBaseHashtable<nsUint32HashKey, Element*, Element*> mGlyphIdMap;
141 hb_blob_t* mSVGData;
143 // pointer to the font entry that owns this gfxSVGGlyphs object
144 gfxFontEntry* MOZ_NON_OWNING_REF mFontEntry;
146 const struct Header {
147 mozilla::AutoSwap_PRUint16 mVersion;
148 mozilla::AutoSwap_PRUint32 mDocIndexOffset;
149 mozilla::AutoSwap_PRUint32 mColorPalettesOffset;
150 } * mHeader;
152 struct IndexEntry {
153 mozilla::AutoSwap_PRUint16 mStartGlyph;
154 mozilla::AutoSwap_PRUint16 mEndGlyph;
155 mozilla::AutoSwap_PRUint32 mDocOffset;
156 mozilla::AutoSwap_PRUint32 mDocLength;
159 const struct DocIndex {
160 mozilla::AutoSwap_PRUint16 mNumEntries;
161 IndexEntry mEntries[1]; /* actual length = mNumEntries */
162 } * mDocIndex;
164 static int CompareIndexEntries(const void* _a, const void* _b);
168 * XXX This is a complete hack and should die (see bug 1291494).
170 * This class is used when code fails to pass through an SVGContextPaint from
171 * the context in which we are painting. In that case we create one of these
172 * as a fallback and have it wrap the gfxContext's current gfxPattern and
173 * pretend that that is the paint context's fill pattern. In some contexts
174 * that will be the case, in others it will not. As we convert more code to
175 * Moz2D the less likely it is that this hack will work. It will also make
176 * converting to Moz2D harder.
178 class SimpleTextContextPaint : public mozilla::SVGContextPaint {
179 private:
180 static const mozilla::gfx::DeviceColor sZero;
182 static gfxMatrix SetupDeviceToPatternMatrix(gfxPattern* aPattern,
183 const gfxMatrix& aCTM) {
184 if (!aPattern) {
185 return gfxMatrix();
187 gfxMatrix deviceToUser = aCTM;
188 if (!deviceToUser.Invert()) {
189 return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
191 return deviceToUser * aPattern->GetMatrix();
194 public:
195 SimpleTextContextPaint(gfxPattern* aFillPattern, gfxPattern* aStrokePattern,
196 const gfxMatrix& aCTM)
197 : mFillPattern(aFillPattern ? aFillPattern : new gfxPattern(sZero)),
198 mStrokePattern(aStrokePattern ? aStrokePattern
199 : new gfxPattern(sZero)) {
200 mFillMatrix = SetupDeviceToPatternMatrix(aFillPattern, aCTM);
201 mStrokeMatrix = SetupDeviceToPatternMatrix(aStrokePattern, aCTM);
204 already_AddRefed<gfxPattern> GetFillPattern(
205 const DrawTarget* aDrawTarget, float aOpacity, const gfxMatrix& aCTM,
206 imgDrawingParams& aImgParams) override {
207 if (mFillPattern) {
208 mFillPattern->SetMatrix(aCTM * mFillMatrix);
210 RefPtr<gfxPattern> fillPattern = mFillPattern;
211 return fillPattern.forget();
214 already_AddRefed<gfxPattern> GetStrokePattern(
215 const DrawTarget* aDrawTarget, float aOpacity, const gfxMatrix& aCTM,
216 imgDrawingParams& aImgParams) override {
217 if (mStrokePattern) {
218 mStrokePattern->SetMatrix(aCTM * mStrokeMatrix);
220 RefPtr<gfxPattern> strokePattern = mStrokePattern;
221 return strokePattern.forget();
224 float GetFillOpacity() const override { return mFillPattern ? 1.0f : 0.0f; }
226 float GetStrokeOpacity() const override {
227 return mStrokePattern ? 1.0f : 0.0f;
230 private:
231 RefPtr<gfxPattern> mFillPattern;
232 RefPtr<gfxPattern> mStrokePattern;
234 // Device space to pattern space transforms
235 gfxMatrix mFillMatrix;
236 gfxMatrix mStrokeMatrix;
239 #endif