/work/obj-fuzz/dist/include/TextDrawTarget.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef TextDrawTarget_h |
8 | | #define TextDrawTarget_h |
9 | | |
10 | | #include "mozilla/gfx/2D.h" |
11 | | #include "mozilla/layers/WebRenderLayerManager.h" |
12 | | #include "mozilla/layers/WebRenderBridgeChild.h" |
13 | | #include "mozilla/webrender/WebRenderAPI.h" |
14 | | #include "mozilla/layers/StackingContextHelper.h" |
15 | | #include "mozilla/layers/IpcResourceUpdateQueue.h" |
16 | | |
17 | | namespace mozilla { |
18 | | namespace layout { |
19 | | |
20 | | using namespace gfx; |
21 | | |
22 | | // This class is fake DrawTarget, used to intercept text draw calls, while |
23 | | // also collecting up the other aspects of text natively. |
24 | | // |
25 | | // When using advanced-layers in nsDisplayText's constructor, we construct this |
26 | | // and run the full painting algorithm with this as the DrawTarget. This is |
27 | | // done to avoid having to massively refactor gecko's text painting code (which |
28 | | // has lots of components shared between other rendering algorithms). |
29 | | // |
30 | | // In some phases of the painting algorithm, we can grab the relevant values |
31 | | // and feed them directly into TextDrawTarget. For instance, selections, |
32 | | // decorations, and shadows are handled in this manner. In those cases we can |
33 | | // also short-circuit the painting algorithm to save work. |
34 | | // |
35 | | // In other phases, the computed values are sufficiently buried in complex |
36 | | // code that it's best for us to just intercept the final draw calls. This |
37 | | // is how we handle computing the glyphs of the main text and text-emphasis |
38 | | // (see our overloaded FillGlyphs implementation). |
39 | | // |
40 | | // To be clear: this is a big hack. With time we hope to refactor the codebase |
41 | | // so that all the elements of text are handled directly by TextDrawTarget, |
42 | | // which is to say everything is done like we do selections and shadows now. |
43 | | // This design is a good step for doing this work incrementally. |
44 | | // |
45 | | // This is also likely to be a bit buggy (missing or misinterpreted info) |
46 | | // while we further develop the design. |
47 | | // |
48 | | // TextDrawTarget doesn't yet support all features. See mHasUnsupportedFeatures |
49 | | // for details. |
50 | | class TextDrawTarget : public DrawTarget |
51 | | { |
52 | | public: |
53 | | explicit TextDrawTarget(wr::DisplayListBuilder& aBuilder, |
54 | | wr::IpcResourceUpdateQueue& aResources, |
55 | | const layers::StackingContextHelper& aSc, |
56 | | layers::WebRenderLayerManager* aManager, |
57 | | nsDisplayItem* aItem, |
58 | | nsRect& aBounds) |
59 | | : mBuilder(aBuilder), mResources(aResources), mSc(aSc), mManager(aManager) |
60 | | { |
61 | | SetPermitSubpixelAA(!aItem->IsSubpixelAADisabled()); |
62 | | |
63 | | // Compute clip/bounds |
64 | | auto appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel(); |
65 | | LayoutDeviceRect layoutBoundsRect = LayoutDeviceRect::FromAppUnits( |
66 | | aBounds, appUnitsPerDevPixel); |
67 | | LayoutDeviceRect layoutClipRect = layoutBoundsRect; |
68 | | mBoundsRect = wr::ToRoundedLayoutRect(layoutBoundsRect); |
69 | | |
70 | | // Add 1 pixel of dirty area around clip rect to allow us to paint |
71 | | // antialiased pixels beyond the measured text extents. |
72 | | layoutClipRect.Inflate(1); |
73 | | mSize = IntSize::Ceil(layoutClipRect.Width(), layoutClipRect.Height()); |
74 | | mClipStack.AppendElement(layoutClipRect); |
75 | | |
76 | | mBackfaceVisible = !aItem->BackfaceIsHidden(); |
77 | | |
78 | | mBuilder.Save(); |
79 | | } |
80 | | |
81 | | // Prevent this from being copied |
82 | | TextDrawTarget(const TextDrawTarget& src) = delete; |
83 | | TextDrawTarget& operator=(const TextDrawTarget&) = delete; |
84 | | |
85 | | ~TextDrawTarget() |
86 | | { |
87 | | if (mHasUnsupportedFeatures) { |
88 | | mBuilder.Restore(); |
89 | | } else { |
90 | | mBuilder.ClearSave(); |
91 | | } |
92 | | } |
93 | | |
94 | 0 | void FoundUnsupportedFeature() { mHasUnsupportedFeatures = true; } |
95 | | bool HasUnsupportedFeatures() { return mHasUnsupportedFeatures; } |
96 | | |
97 | 0 | wr::FontInstanceFlags GetWRGlyphFlags() const { return mWRGlyphFlags; } |
98 | 0 | void SetWRGlyphFlags(wr::FontInstanceFlags aFlags) { mWRGlyphFlags = aFlags; } |
99 | | |
100 | | class AutoRestoreWRGlyphFlags |
101 | | { |
102 | | public: |
103 | | ~AutoRestoreWRGlyphFlags() |
104 | 0 | { |
105 | 0 | if (mTarget) { |
106 | 0 | mTarget->SetWRGlyphFlags(mFlags); |
107 | 0 | } |
108 | 0 | } |
109 | | |
110 | | void Save(TextDrawTarget* aTarget) |
111 | 0 | { |
112 | 0 | // This allows for recursive saves, in case the flags need to be modified |
113 | 0 | // under multiple conditions (i.e. transforms and synthetic italics), |
114 | 0 | // since the flags will be restored to the first saved value in the |
115 | 0 | // destructor on scope exit. |
116 | 0 | if (!mTarget) { |
117 | 0 | // Only record the first save with the original flags that will be restored. |
118 | 0 | mTarget = aTarget; |
119 | 0 | mFlags = aTarget->GetWRGlyphFlags(); |
120 | 0 | } else { |
121 | 0 | // Ensure that this is actually a recursive save to the same target |
122 | 0 | MOZ_ASSERT(mTarget == aTarget, |
123 | 0 | "Recursive save of WR glyph flags to different TextDrawTargets"); |
124 | 0 | } |
125 | 0 | } |
126 | | |
127 | | private: |
128 | | TextDrawTarget* mTarget = nullptr; |
129 | | wr::FontInstanceFlags mFlags = {0}; |
130 | | }; |
131 | | |
132 | | // This overload just stores the glyphs/font/color. |
133 | | void |
134 | | FillGlyphs(ScaledFont* aFont, |
135 | | const GlyphBuffer& aBuffer, |
136 | | const Pattern& aPattern, |
137 | | const DrawOptions& aOptions) override |
138 | | { |
139 | | // Make sure we're only given boring color patterns |
140 | | MOZ_RELEASE_ASSERT(aOptions.mCompositionOp == CompositionOp::OP_OVER); |
141 | | MOZ_RELEASE_ASSERT(aOptions.mAlpha == 1.0f); |
142 | | MOZ_RELEASE_ASSERT(aPattern.GetType() == PatternType::COLOR); |
143 | | |
144 | | // Make sure the font exists, and can be serialized |
145 | | MOZ_RELEASE_ASSERT(aFont); |
146 | | if (!aFont->CanSerialize()) { |
147 | | FoundUnsupportedFeature(); |
148 | | return; |
149 | | } |
150 | | |
151 | | auto* colorPat = static_cast<const ColorPattern*>(&aPattern); |
152 | | auto color = wr::ToColorF(colorPat->mColor); |
153 | | MOZ_ASSERT(aBuffer.mNumGlyphs); |
154 | | auto glyphs = Range<const wr::GlyphInstance>(reinterpret_cast<const wr::GlyphInstance*>(aBuffer.mGlyphs), aBuffer.mNumGlyphs); |
155 | | // MSVC won't let us use offsetof on the following directly so we give it a |
156 | | // name with typedef |
157 | | typedef std::remove_reference<decltype(aBuffer.mGlyphs[0])>::type GlyphType; |
158 | | // Compare gfx::Glyph and wr::GlyphInstance to make sure that they are |
159 | | // structurally equivalent to ensure that our cast above was ok |
160 | | static_assert(std::is_same<decltype(aBuffer.mGlyphs[0].mIndex), decltype(glyphs[0].index)>() |
161 | | && std::is_same<decltype(aBuffer.mGlyphs[0].mPosition.x), decltype(glyphs[0].point.x)>() |
162 | | && std::is_same<decltype(aBuffer.mGlyphs[0].mPosition.y), decltype(glyphs[0].point.y)>() |
163 | | && offsetof(GlyphType, mIndex) == offsetof(wr::GlyphInstance, index) |
164 | | && offsetof(GlyphType, mPosition) == offsetof(wr::GlyphInstance, point) |
165 | | && offsetof(decltype(aBuffer.mGlyphs[0].mPosition), x) == offsetof(decltype(glyphs[0].point), x) |
166 | | && offsetof(decltype(aBuffer.mGlyphs[0].mPosition), y) == offsetof(decltype(glyphs[0].point), y) |
167 | | && std::is_standard_layout<std::remove_reference<decltype(aBuffer.mGlyphs[0])>>::value |
168 | | && std::is_standard_layout<std::remove_reference<decltype(glyphs[0])>>::value |
169 | | && sizeof(aBuffer.mGlyphs[0]) == sizeof(glyphs[0]) |
170 | | && sizeof(aBuffer.mGlyphs[0].mPosition) == sizeof(glyphs[0].point) |
171 | | , "glyph buf types don't match"); |
172 | | |
173 | | wr::GlyphOptions glyphOptions; |
174 | | glyphOptions.render_mode = wr::ToFontRenderMode(aOptions.mAntialiasMode, GetPermitSubpixelAA()); |
175 | | glyphOptions.flags = mWRGlyphFlags; |
176 | | |
177 | | mManager->WrBridge()->PushGlyphs(mBuilder, glyphs, aFont, color, mSc, |
178 | | mBoundsRect, ClipRect(), mBackfaceVisible, |
179 | | &glyphOptions); |
180 | | } |
181 | | |
182 | | void |
183 | | PushClipRect(const Rect &aRect) override { |
184 | | LayoutDeviceRect rect = LayoutDeviceRect::FromUnknownRect(aRect); |
185 | | rect = rect.Intersect(mClipStack.LastElement()); |
186 | | mClipStack.AppendElement(rect); |
187 | | } |
188 | | |
189 | | void |
190 | | PopClip() override { |
191 | | mClipStack.RemoveLastElement(); |
192 | | } |
193 | | |
194 | | IntSize GetSize() const override { |
195 | | return mSize; |
196 | | } |
197 | | |
198 | | void |
199 | | AppendShadow(const wr::Shadow& aShadow) |
200 | | { |
201 | | mBuilder.PushShadow(mBoundsRect, ClipRect(), mBackfaceVisible, aShadow); |
202 | | mHasShadows = true; |
203 | | } |
204 | | |
205 | | void |
206 | | TerminateShadows() |
207 | | { |
208 | | if (mHasShadows) { |
209 | | mBuilder.PopAllShadows(); |
210 | | mHasShadows = false; |
211 | | } |
212 | | } |
213 | | |
214 | | void |
215 | | AppendSelectionRect(const LayoutDeviceRect& aRect, const Color& aColor) |
216 | | { |
217 | | auto rect = wr::ToLayoutRect(aRect); |
218 | | auto color = wr::ToColorF(aColor); |
219 | | mBuilder.PushRect(rect, ClipRect(), mBackfaceVisible, color); |
220 | | } |
221 | | |
222 | | |
223 | | // This function is basically designed to slide into the decoration drawing |
224 | | // code of nsCSSRendering with minimum disruption, to minimize the |
225 | | // chances of implementation drift. As such, it mostly looks like a call |
226 | | // to a skia-style StrokeLine method: two end-points, with a thickness |
227 | | // and style. Notably the end-points are *centered* in the block direction, |
228 | | // even though webrender wants a rect-like representation, where the points |
229 | | // are on corners. |
230 | | // |
231 | | // So we mangle the format here in a single centralized place, where neither |
232 | | // webrender nor nsCSSRendering has to care about this mismatch. |
233 | | // |
234 | | // NOTE: we assume the points are axis-aligned, and aStart should be used |
235 | | // as the top-left corner of the rect. |
236 | | void |
237 | | AppendDecoration(const Point& aStart, |
238 | | const Point& aEnd, |
239 | | const float aThickness, |
240 | | const bool aVertical, |
241 | | const Color& aColor, |
242 | | const uint8_t aStyle) |
243 | | { |
244 | | auto pos = LayoutDevicePoint::FromUnknownPoint(aStart); |
245 | | LayoutDeviceSize size; |
246 | | |
247 | | if (aVertical) { |
248 | | pos.x -= aThickness / 2; // adjust from center to corner |
249 | | size = LayoutDeviceSize(aThickness, aEnd.y - aStart.y); |
250 | | } else { |
251 | | pos.y -= aThickness / 2; // adjust from center to corner |
252 | | size = LayoutDeviceSize(aEnd.x - aStart.x, aThickness); |
253 | | } |
254 | | |
255 | | wr::Line decoration; |
256 | | decoration.bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect(pos, size)); |
257 | | decoration.wavyLineThickness = 0; // dummy value, unused |
258 | | decoration.color = wr::ToColorF(aColor); |
259 | | decoration.orientation = aVertical |
260 | | ? wr::LineOrientation::Vertical |
261 | | : wr::LineOrientation::Horizontal; |
262 | | |
263 | | switch (aStyle) { |
264 | | case NS_STYLE_TEXT_DECORATION_STYLE_SOLID: |
265 | | decoration.style = wr::LineStyle::Solid; |
266 | | break; |
267 | | case NS_STYLE_TEXT_DECORATION_STYLE_DOTTED: |
268 | | decoration.style = wr::LineStyle::Dotted; |
269 | | break; |
270 | | case NS_STYLE_TEXT_DECORATION_STYLE_DASHED: |
271 | | decoration.style = wr::LineStyle::Dashed; |
272 | | break; |
273 | | // Wavy lines should go through AppendWavyDecoration |
274 | | case NS_STYLE_TEXT_DECORATION_STYLE_WAVY: |
275 | | // Double lines should be lowered to two solid lines |
276 | | case NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE: |
277 | | default: |
278 | | MOZ_CRASH("TextDrawTarget received unsupported line style"); |
279 | | } |
280 | | |
281 | | mBuilder.PushLine(ClipRect(), mBackfaceVisible, decoration); |
282 | | } |
283 | | |
284 | | // Seperated out from AppendDecoration because Wavy Lines are completely |
285 | | // different, and trying to merge the concept is more of a mess than it's |
286 | | // worth. |
287 | | void |
288 | | AppendWavyDecoration(const Rect& aBounds, |
289 | | const float aThickness, |
290 | | const bool aVertical, |
291 | | const Color& aColor) |
292 | | { |
293 | | wr::Line decoration; |
294 | | |
295 | | decoration.bounds = wr::ToRoundedLayoutRect( |
296 | | LayoutDeviceRect::FromUnknownRect(aBounds)); |
297 | | decoration.wavyLineThickness = aThickness; |
298 | | decoration.color = wr::ToColorF(aColor); |
299 | | decoration.orientation = aVertical |
300 | | ? wr::LineOrientation::Vertical |
301 | | : wr::LineOrientation::Horizontal; |
302 | | decoration.style = wr::LineStyle::Wavy; |
303 | | |
304 | | mBuilder.PushLine(ClipRect(), mBackfaceVisible, decoration); |
305 | | } |
306 | | |
307 | 0 | layers::WebRenderBridgeChild* WrBridge() { return mManager->WrBridge(); } |
308 | 0 | layers::WebRenderLayerManager* WrLayerManager() { return mManager; } |
309 | | |
310 | | Maybe<wr::ImageKey> |
311 | | DefineImage(const IntSize& aSize, |
312 | | uint32_t aStride, |
313 | | SurfaceFormat aFormat, |
314 | | const uint8_t* aData) |
315 | 0 | { |
316 | 0 | wr::ImageKey key = mManager->WrBridge()->GetNextImageKey(); |
317 | 0 | wr::ImageDescriptor desc(aSize, aStride, aFormat); |
318 | 0 | Range<uint8_t> bytes(const_cast<uint8_t*>(aData), aStride * aSize.height); |
319 | 0 | if (mResources.AddImage(key, desc, bytes)) { |
320 | 0 | return Some(key); |
321 | 0 | } |
322 | 0 | return Nothing(); |
323 | 0 | } |
324 | | |
325 | | void PushImage(wr::ImageKey aKey, |
326 | | const wr::LayoutRect& aBounds, |
327 | | const wr::LayoutRect& aClip, |
328 | | wr::ImageRendering aFilter, |
329 | | const wr::ColorF& aColor) |
330 | 0 | { |
331 | 0 | mBuilder.PushImage(aBounds, aClip, true, aFilter, aKey, true, aColor); |
332 | 0 | } |
333 | | |
334 | | private: |
335 | | wr::LayoutRect ClipRect() |
336 | | { |
337 | | return wr::ToRoundedLayoutRect(mClipStack.LastElement()); |
338 | | } |
339 | | // Whether anything unsupported was encountered. Currently: |
340 | | // |
341 | | // * Synthetic bold/italics |
342 | | // * SVG fonts |
343 | | // * Unserializable fonts |
344 | | // * Tofu glyphs |
345 | | // * Pratial ligatures |
346 | | // * Text writing-mode |
347 | | // * Text stroke |
348 | | bool mHasUnsupportedFeatures = false; |
349 | | |
350 | | // Whether PopAllShadows needs to be called |
351 | | bool mHasShadows = false; |
352 | | |
353 | | // Things used to push to webrender |
354 | | wr::DisplayListBuilder& mBuilder; |
355 | | wr::IpcResourceUpdateQueue& mResources; |
356 | | const layers::StackingContextHelper& mSc; |
357 | | layers::WebRenderLayerManager* mManager; |
358 | | |
359 | | // Computed facts |
360 | | IntSize mSize; |
361 | | wr::LayoutRect mBoundsRect; |
362 | | nsTArray<LayoutDeviceRect> mClipStack; |
363 | | bool mBackfaceVisible; |
364 | | |
365 | | wr::FontInstanceFlags mWRGlyphFlags = {0}; |
366 | | |
367 | | // The rest of this is dummy implementations of DrawTarget's API |
368 | | public: |
369 | | DrawTargetType GetType() const override { |
370 | | return DrawTargetType::SOFTWARE_RASTER; |
371 | | } |
372 | | |
373 | | BackendType GetBackendType() const override { |
374 | | return BackendType::WEBRENDER_TEXT; |
375 | | } |
376 | | |
377 | | bool IsRecording() const override { return true; } |
378 | | bool IsCaptureDT() const override { return false; } |
379 | | |
380 | | already_AddRefed<SourceSurface> Snapshot() override { |
381 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
382 | | return nullptr; |
383 | | } |
384 | | |
385 | | already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType, |
386 | | float aOpacity) override { |
387 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
388 | | return nullptr; |
389 | | } |
390 | | |
391 | | void Flush() override { |
392 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
393 | | } |
394 | | |
395 | | void DrawCapturedDT(DrawTargetCapture *aCaptureDT, |
396 | | const Matrix& aTransform) override { |
397 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
398 | | } |
399 | | |
400 | | void DrawSurface(SourceSurface *aSurface, |
401 | | const Rect &aDest, |
402 | | const Rect &aSource, |
403 | | const DrawSurfaceOptions &aSurfOptions, |
404 | | const DrawOptions &aOptions) override { |
405 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
406 | | } |
407 | | |
408 | | void DrawFilter(FilterNode *aNode, |
409 | | const Rect &aSourceRect, |
410 | | const Point &aDestPoint, |
411 | | const DrawOptions &aOptions) override { |
412 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
413 | | } |
414 | | |
415 | | void DrawSurfaceWithShadow(SourceSurface *aSurface, |
416 | | const Point &aDest, |
417 | | const Color &aColor, |
418 | | const Point &aOffset, |
419 | | Float aSigma, |
420 | | CompositionOp aOperator) override { |
421 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
422 | | } |
423 | | |
424 | | void ClearRect(const Rect &aRect) override { |
425 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
426 | | } |
427 | | |
428 | | void CopySurface(SourceSurface *aSurface, |
429 | | const IntRect &aSourceRect, |
430 | | const IntPoint &aDestination) override { |
431 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
432 | | } |
433 | | |
434 | | void FillRect(const Rect &aRect, |
435 | | const Pattern &aPattern, |
436 | | const DrawOptions &aOptions = DrawOptions()) override { |
437 | | MOZ_RELEASE_ASSERT(aPattern.GetType() == PatternType::COLOR); |
438 | | |
439 | | auto rect = wr::ToRoundedLayoutRect(LayoutDeviceRect::FromUnknownRect(aRect)); |
440 | | auto color = wr::ToColorF(static_cast<const ColorPattern&>(aPattern).mColor); |
441 | | mBuilder.PushRect(rect, ClipRect(), mBackfaceVisible, color); |
442 | | } |
443 | | |
444 | | void StrokeRect(const Rect &aRect, |
445 | | const Pattern &aPattern, |
446 | | const StrokeOptions &aStrokeOptions, |
447 | | const DrawOptions &aOptions) override { |
448 | | MOZ_RELEASE_ASSERT(aPattern.GetType() == PatternType::COLOR && |
449 | | aStrokeOptions.mDashLength == 0); |
450 | | |
451 | | wr::LayoutSideOffsets widths = { |
452 | | aStrokeOptions.mLineWidth, |
453 | | aStrokeOptions.mLineWidth, |
454 | | aStrokeOptions.mLineWidth, |
455 | | aStrokeOptions.mLineWidth |
456 | | }; |
457 | | wr::ColorF color = wr::ToColorF(static_cast<const ColorPattern&>(aPattern).mColor); |
458 | | wr::BorderSide sides[4] = { |
459 | | { color, wr::BorderStyle::Solid }, |
460 | | { color, wr::BorderStyle::Solid }, |
461 | | { color, wr::BorderStyle::Solid }, |
462 | | { color, wr::BorderStyle::Solid } |
463 | | }; |
464 | | wr::BorderRadius radius = { |
465 | | { 0, 0 }, |
466 | | { 0, 0 }, |
467 | | { 0, 0 }, |
468 | | { 0, 0 } |
469 | | }; |
470 | | Rect rect(aRect); |
471 | | rect.Inflate(aStrokeOptions.mLineWidth / 2); |
472 | | wr::LayoutRect bounds = wr::ToRoundedLayoutRect(LayoutDeviceRect::FromUnknownRect(rect)); |
473 | | mBuilder.PushBorder(bounds, ClipRect(), true, widths, Range<const wr::BorderSide>(sides, 4), radius); |
474 | | } |
475 | | |
476 | | void StrokeLine(const Point &aStart, |
477 | | const Point &aEnd, |
478 | | const Pattern &aPattern, |
479 | | const StrokeOptions &aStrokeOptions, |
480 | | const DrawOptions &aOptions) override { |
481 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
482 | | } |
483 | | |
484 | | |
485 | | void Stroke(const Path *aPath, |
486 | | const Pattern &aPattern, |
487 | | const StrokeOptions &aStrokeOptions, |
488 | | const DrawOptions &aOptions) override { |
489 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
490 | | } |
491 | | |
492 | | void Fill(const Path *aPath, |
493 | | const Pattern &aPattern, |
494 | | const DrawOptions &aOptions) override { |
495 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
496 | | } |
497 | | |
498 | | void StrokeGlyphs(ScaledFont* aFont, |
499 | | const GlyphBuffer& aBuffer, |
500 | | const Pattern& aPattern, |
501 | | const StrokeOptions& aStrokeOptions, |
502 | | const DrawOptions& aOptions) override { |
503 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
504 | | } |
505 | | |
506 | | void Mask(const Pattern &aSource, |
507 | | const Pattern &aMask, |
508 | | const DrawOptions &aOptions) override { |
509 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
510 | | } |
511 | | |
512 | | void MaskSurface(const Pattern &aSource, |
513 | | SourceSurface *aMask, |
514 | | Point aOffset, |
515 | | const DrawOptions &aOptions) override { |
516 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
517 | | } |
518 | | |
519 | | bool Draw3DTransformedSurface(SourceSurface* aSurface, |
520 | | const Matrix4x4& aMatrix) override { |
521 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
522 | | } |
523 | | |
524 | | void PushClip(const Path *aPath) override { |
525 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
526 | | } |
527 | | |
528 | | void PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount) override { |
529 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
530 | | } |
531 | | |
532 | | |
533 | | |
534 | | void PushLayer(bool aOpaque, Float aOpacity, |
535 | | SourceSurface* aMask, |
536 | | const Matrix& aMaskTransform, |
537 | | const IntRect& aBounds, |
538 | | bool aCopyBackground) override { |
539 | | // Fine to pretend we do this |
540 | | } |
541 | | |
542 | | void PopLayer() override { |
543 | | // Fine to pretend we do this |
544 | | } |
545 | | |
546 | | |
547 | | already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData, |
548 | | const IntSize &aSize, |
549 | | int32_t aStride, |
550 | | SurfaceFormat aFormat) const override { |
551 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
552 | | return nullptr; |
553 | | } |
554 | | |
555 | | already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override { |
556 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
557 | | return nullptr; |
558 | | } |
559 | | |
560 | | already_AddRefed<SourceSurface> |
561 | | CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const override { |
562 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
563 | | return nullptr; |
564 | | } |
565 | | |
566 | | already_AddRefed<DrawTarget> |
567 | | CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const override { |
568 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
569 | | return nullptr; |
570 | | } |
571 | | |
572 | | already_AddRefed<PathBuilder> CreatePathBuilder(FillRule aFillRule) const override { |
573 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
574 | | return nullptr; |
575 | | } |
576 | | |
577 | | already_AddRefed<FilterNode> CreateFilter(FilterType aType) override { |
578 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
579 | | return nullptr; |
580 | | } |
581 | | |
582 | | already_AddRefed<GradientStops> |
583 | | CreateGradientStops(GradientStop *aStops, |
584 | | uint32_t aNumStops, |
585 | | ExtendMode aExtendMode) const override { |
586 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
587 | | return nullptr; |
588 | | } |
589 | | |
590 | | void* GetNativeSurface(NativeSurfaceType aType) override { |
591 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
592 | | return nullptr; |
593 | | } |
594 | | |
595 | | void DetachAllSnapshots() override { |
596 | | MOZ_CRASH("TextDrawTarget: Method shouldn't be called"); |
597 | | } |
598 | | }; |
599 | | |
600 | | } |
601 | | } |
602 | | |
603 | | #endif |