gfx/thebes/gfxSVGGlyphs.h

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

mercurial