Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef _MOZILLA_GFX_2D_H
7 #define _MOZILLA_GFX_2D_H
9 #include "Types.h"
10 #include "Point.h"
11 #include "Rect.h"
12 #include "Matrix.h"
13 #include "UserData.h"
15 // GenericRefCountedBase allows us to hold on to refcounted objects of any type
16 // (contrary to RefCounted<T> which requires knowing the type T) and, in particular,
17 // without having a dependency on that type. This is used for DrawTargetSkia
18 // to be able to hold on to a GLContext.
19 #include "mozilla/GenericRefCounted.h"
21 // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
22 // outparams using the &-operator. But it will have to do as there's no easy
23 // solution.
24 #include "mozilla/RefPtr.h"
26 #include "mozilla/DebugOnly.h"
28 #ifdef MOZ_ENABLE_FREETYPE
29 #include <string>
30 #endif
32 struct _cairo_surface;
33 typedef _cairo_surface cairo_surface_t;
35 struct _cairo_scaled_font;
36 typedef _cairo_scaled_font cairo_scaled_font_t;
38 struct ID3D10Device1;
39 struct ID3D10Texture2D;
40 struct ID3D11Device;
41 struct ID2D1Device;
42 struct IDWriteRenderingParams;
44 class GrContext;
45 struct GrGLInterface;
47 struct CGContext;
48 typedef struct CGContext *CGContextRef;
50 namespace mozilla {
52 namespace gfx {
54 class SourceSurface;
55 class DataSourceSurface;
56 class DrawTarget;
57 class DrawEventRecorder;
58 class FilterNode;
60 struct NativeSurface {
61 NativeSurfaceType mType;
62 SurfaceFormat mFormat;
63 gfx::IntSize mSize;
64 void *mSurface;
65 };
67 struct NativeFont {
68 NativeFontType mType;
69 void *mFont;
70 };
72 /*
73 * This structure is used to send draw options that are universal to all drawing
74 * operations. It consists of the following:
75 *
76 * mAlpha - Alpha value by which the mask generated by this operation is
77 * multiplied.
78 * mCompositionOp - The operator that indicates how the source and destination
79 * patterns are blended.
80 * mAntiAliasMode - The AntiAlias mode used for this drawing operation.
81 */
82 struct DrawOptions {
83 DrawOptions(Float aAlpha = 1.0f,
84 CompositionOp aCompositionOp = CompositionOp::OP_OVER,
85 AntialiasMode aAntialiasMode = AntialiasMode::DEFAULT)
86 : mAlpha(aAlpha)
87 , mCompositionOp(aCompositionOp)
88 , mAntialiasMode(aAntialiasMode)
89 {}
91 Float mAlpha;
92 CompositionOp mCompositionOp;
93 AntialiasMode mAntialiasMode;
94 };
96 /*
97 * This structure is used to send stroke options that are used in stroking
98 * operations. It consists of the following:
99 *
100 * mLineWidth - Width of the stroke in userspace.
101 * mLineJoin - Join style used for joining lines.
102 * mLineCap - Cap style used for capping lines.
103 * mMiterLimit - Miter limit in units of linewidth
104 * mDashPattern - Series of on/off userspace lengths defining dash.
105 * Owned by the caller; must live at least as long as
106 * this StrokeOptions.
107 * mDashPattern != null <=> mDashLength > 0.
108 * mDashLength - Number of on/off lengths in mDashPattern.
109 * mDashOffset - Userspace offset within mDashPattern at which stroking
110 * begins.
111 */
112 struct StrokeOptions {
113 StrokeOptions(Float aLineWidth = 1.0f,
114 JoinStyle aLineJoin = JoinStyle::MITER_OR_BEVEL,
115 CapStyle aLineCap = CapStyle::BUTT,
116 Float aMiterLimit = 10.0f,
117 size_t aDashLength = 0,
118 const Float* aDashPattern = 0,
119 Float aDashOffset = 0.f)
120 : mLineWidth(aLineWidth)
121 , mMiterLimit(aMiterLimit)
122 , mDashPattern(aDashLength > 0 ? aDashPattern : 0)
123 , mDashLength(aDashLength)
124 , mDashOffset(aDashOffset)
125 , mLineJoin(aLineJoin)
126 , mLineCap(aLineCap)
127 {
128 MOZ_ASSERT(aDashLength == 0 || aDashPattern);
129 }
131 Float mLineWidth;
132 Float mMiterLimit;
133 const Float* mDashPattern;
134 size_t mDashLength;
135 Float mDashOffset;
136 JoinStyle mLineJoin;
137 CapStyle mLineCap;
138 };
140 /*
141 * This structure supplies additional options for calls to DrawSurface.
142 *
143 * mFilter - Filter used when resampling source surface region to the
144 * destination region.
145 * aSamplingBounds - This indicates whether the implementation is allowed
146 * to sample pixels outside the source rectangle as
147 * specified in DrawSurface on the surface.
148 */
149 struct DrawSurfaceOptions {
150 DrawSurfaceOptions(Filter aFilter = Filter::LINEAR,
151 SamplingBounds aSamplingBounds = SamplingBounds::UNBOUNDED)
152 : mFilter(aFilter)
153 , mSamplingBounds(aSamplingBounds)
154 { }
156 Filter mFilter;
157 SamplingBounds mSamplingBounds;
158 };
160 /*
161 * This class is used to store gradient stops, it can only be used with a
162 * matching DrawTarget. Not adhering to this condition will make a draw call
163 * fail.
164 */
165 class GradientStops : public RefCounted<GradientStops>
166 {
167 public:
168 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
169 virtual ~GradientStops() {}
171 virtual BackendType GetBackendType() const = 0;
173 protected:
174 GradientStops() {}
175 };
177 /*
178 * This is the base class for 'patterns'. Patterns describe the pixels used as
179 * the source for a masked composition operation that is done by the different
180 * drawing commands. These objects are not backend specific, however for
181 * example the gradient stops on a gradient pattern can be backend specific.
182 */
183 class Pattern
184 {
185 public:
186 virtual ~Pattern() {}
188 virtual PatternType GetType() const = 0;
190 protected:
191 Pattern() {}
192 };
194 class ColorPattern : public Pattern
195 {
196 public:
197 ColorPattern(const Color &aColor)
198 : mColor(aColor)
199 {}
201 virtual PatternType GetType() const { return PatternType::COLOR; }
203 Color mColor;
204 };
206 /*
207 * This class is used for Linear Gradient Patterns, the gradient stops are
208 * stored in a separate object and are backend dependent. This class itself
209 * may be used on the stack.
210 */
211 class LinearGradientPattern : public Pattern
212 {
213 public:
214 /*
215 * aBegin Start of the linear gradient
216 * aEnd End of the linear gradient - NOTE: In the case of a zero length
217 * gradient it will act as the color of the last stop.
218 * aStops GradientStops object for this gradient, this should match the
219 * backend type of the draw target this pattern will be used with.
220 * aMatrix A matrix that transforms the pattern into user space
221 */
222 LinearGradientPattern(const Point &aBegin,
223 const Point &aEnd,
224 GradientStops *aStops,
225 const Matrix &aMatrix = Matrix())
226 : mBegin(aBegin)
227 , mEnd(aEnd)
228 , mStops(aStops)
229 , mMatrix(aMatrix)
230 {
231 }
233 virtual PatternType GetType() const { return PatternType::LINEAR_GRADIENT; }
235 Point mBegin;
236 Point mEnd;
237 RefPtr<GradientStops> mStops;
238 Matrix mMatrix;
239 };
241 /*
242 * This class is used for Radial Gradient Patterns, the gradient stops are
243 * stored in a separate object and are backend dependent. This class itself
244 * may be used on the stack.
245 */
246 class RadialGradientPattern : public Pattern
247 {
248 public:
249 /*
250 * aCenter1 Center of the inner (focal) circle.
251 * aCenter2 Center of the outer circle.
252 * aRadius1 Radius of the inner (focal) circle.
253 * aRadius2 Radius of the outer circle.
254 * aStops GradientStops object for this gradient, this should match the
255 * backend type of the draw target this pattern will be used with.
256 * aMatrix A matrix that transforms the pattern into user space
257 */
258 RadialGradientPattern(const Point &aCenter1,
259 const Point &aCenter2,
260 Float aRadius1,
261 Float aRadius2,
262 GradientStops *aStops,
263 const Matrix &aMatrix = Matrix())
264 : mCenter1(aCenter1)
265 , mCenter2(aCenter2)
266 , mRadius1(aRadius1)
267 , mRadius2(aRadius2)
268 , mStops(aStops)
269 , mMatrix(aMatrix)
270 {
271 }
273 virtual PatternType GetType() const { return PatternType::RADIAL_GRADIENT; }
275 Point mCenter1;
276 Point mCenter2;
277 Float mRadius1;
278 Float mRadius2;
279 RefPtr<GradientStops> mStops;
280 Matrix mMatrix;
281 };
283 /*
284 * This class is used for Surface Patterns, they wrap a surface and a
285 * repetition mode for the surface. This may be used on the stack.
286 */
287 class SurfacePattern : public Pattern
288 {
289 public:
290 /*
291 * aSourceSurface Surface to use for drawing
292 * aExtendMode This determines how the image is extended outside the bounds
293 * of the image.
294 * aMatrix A matrix that transforms the pattern into user space
295 * aFilter Resampling filter used for resampling the image.
296 */
297 SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode,
298 const Matrix &aMatrix = Matrix(), Filter aFilter = Filter::GOOD)
299 : mSurface(aSourceSurface)
300 , mExtendMode(aExtendMode)
301 , mFilter(aFilter)
302 , mMatrix(aMatrix)
303 {}
305 virtual PatternType GetType() const { return PatternType::SURFACE; }
307 RefPtr<SourceSurface> mSurface;
308 ExtendMode mExtendMode;
309 Filter mFilter;
310 Matrix mMatrix;
311 };
313 /*
314 * This is the base class for source surfaces. These objects are surfaces
315 * which may be used as a source in a SurfacePattern or a DrawSurface call.
316 * They cannot be drawn to directly.
317 */
318 class SourceSurface : public RefCounted<SourceSurface>
319 {
320 public:
321 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
322 virtual ~SourceSurface() {}
324 virtual SurfaceType GetType() const = 0;
325 virtual IntSize GetSize() const = 0;
326 virtual SurfaceFormat GetFormat() const = 0;
328 /* This returns false if some event has made this source surface invalid for
329 * usage with current DrawTargets. For example in the case of Direct2D this
330 * could return false if we have switched devices since this surface was
331 * created.
332 */
333 virtual bool IsValid() const { return true; }
335 /*
336 * This function will get a DataSourceSurface for this surface, a
337 * DataSourceSurface's data can be accessed directly.
338 */
339 virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
341 /* Tries to get this SourceSurface's native surface. This will fail if aType
342 * is not the type of this SourceSurface's native surface.
343 */
344 virtual void *GetNativeSurface(NativeSurfaceType aType) {
345 return nullptr;
346 }
348 void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
349 mUserData.Add(key, userData, destroy);
350 }
351 void *GetUserData(UserDataKey *key) {
352 return mUserData.Get(key);
353 }
355 protected:
356 UserData mUserData;
357 };
359 class DataSourceSurface : public SourceSurface
360 {
361 public:
362 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface)
363 DataSourceSurface()
364 : mIsMapped(false)
365 {
366 }
368 #ifdef DEBUG
369 virtual ~DataSourceSurface()
370 {
371 MOZ_ASSERT(!mIsMapped, "Someone forgot to call Unmap()");
372 }
373 #endif
375 struct MappedSurface {
376 uint8_t *mData;
377 int32_t mStride;
378 };
380 enum MapType {
381 READ,
382 WRITE,
383 READ_WRITE
384 };
386 virtual SurfaceType GetType() const { return SurfaceType::DATA; }
387 /* [DEPRECATED]
388 * Get the raw bitmap data of the surface.
389 * Can return null if there was OOM allocating surface data.
390 */
391 virtual uint8_t *GetData() = 0;
393 /* [DEPRECATED]
394 * Stride of the surface, distance in bytes between the start of the image
395 * data belonging to row y and row y+1. This may be negative.
396 * Can return 0 if there was OOM allocating surface data.
397 */
398 virtual int32_t Stride() = 0;
400 virtual bool Map(MapType, MappedSurface *aMappedSurface)
401 {
402 aMappedSurface->mData = GetData();
403 aMappedSurface->mStride = Stride();
404 mIsMapped = true;
405 return true;
406 }
408 virtual void Unmap()
409 {
410 MOZ_ASSERT(mIsMapped);
411 mIsMapped = false;
412 }
414 /*
415 * Returns a DataSourceSurface with the same data as this one, but
416 * guaranteed to have surface->GetType() == SurfaceType::DATA.
417 */
418 virtual TemporaryRef<DataSourceSurface> GetDataSurface();
420 bool mIsMapped;
421 };
423 /* This is an abstract object that accepts path segments. */
424 class PathSink : public RefCounted<PathSink>
425 {
426 public:
427 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink)
428 virtual ~PathSink() {}
430 /* Move the current point in the path, any figure currently being drawn will
431 * be considered closed during fill operations, however when stroking the
432 * closing line segment will not be drawn.
433 */
434 virtual void MoveTo(const Point &aPoint) = 0;
435 /* Add a linesegment to the current figure */
436 virtual void LineTo(const Point &aPoint) = 0;
437 /* Add a cubic bezier curve to the current figure */
438 virtual void BezierTo(const Point &aCP1,
439 const Point &aCP2,
440 const Point &aCP3) = 0;
441 /* Add a quadratic bezier curve to the current figure */
442 virtual void QuadraticBezierTo(const Point &aCP1,
443 const Point &aCP2) = 0;
444 /* Close the current figure, this will essentially generate a line segment
445 * from the current point to the starting point for the current figure
446 */
447 virtual void Close() = 0;
448 /* Add an arc to the current figure */
449 virtual void Arc(const Point &aOrigin, float aRadius, float aStartAngle,
450 float aEndAngle, bool aAntiClockwise = false) = 0;
451 /* Point the current subpath is at - or where the next subpath will start
452 * if there is no active subpath.
453 */
454 virtual Point CurrentPoint() const = 0;
455 };
457 class PathBuilder;
458 class FlattenedPath;
460 /* The path class is used to create (sets of) figures of any shape that can be
461 * filled or stroked to a DrawTarget
462 */
463 class Path : public RefCounted<Path>
464 {
465 public:
466 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
467 virtual ~Path();
469 virtual BackendType GetBackendType() const = 0;
471 /* This returns a PathBuilder object that contains a copy of the contents of
472 * this path and is still writable.
473 */
474 virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
475 virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
476 FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
478 /* This function checks if a point lies within a path. It allows passing a
479 * transform that will transform the path to the coordinate space in which
480 * aPoint is given.
481 */
482 virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const = 0;
485 /* This function checks if a point lies within the stroke of a path using the
486 * specified strokeoptions. It allows passing a transform that will transform
487 * the path to the coordinate space in which aPoint is given.
488 */
489 virtual bool StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
490 const Point &aPoint,
491 const Matrix &aTransform) const = 0;
493 /* This functions gets the bounds of this path. These bounds are not
494 * guaranteed to be tight. A transform may be specified that gives the bounds
495 * after application of the transform.
496 */
497 virtual Rect GetBounds(const Matrix &aTransform = Matrix()) const = 0;
499 /* This function gets the bounds of the stroke of this path using the
500 * specified strokeoptions. These bounds are not guaranteed to be tight.
501 * A transform may be specified that gives the bounds after application of
502 * the transform.
503 */
504 virtual Rect GetStrokedBounds(const StrokeOptions &aStrokeOptions,
505 const Matrix &aTransform = Matrix()) const = 0;
507 /* Take the contents of this path and stream it to another sink, this works
508 * regardless of the backend that might be used for the destination sink.
509 */
510 virtual void StreamToSink(PathSink *aSink) const = 0;
512 /* This gets the fillrule this path's builder was created with. This is not
513 * mutable.
514 */
515 virtual FillRule GetFillRule() const = 0;
517 virtual Float ComputeLength();
519 virtual Point ComputePointAtLength(Float aLength,
520 Point* aTangent = nullptr);
522 protected:
523 Path();
524 void EnsureFlattenedPath();
526 RefPtr<FlattenedPath> mFlattenedPath;
527 };
529 /* The PathBuilder class allows path creation. Once finish is called on the
530 * pathbuilder it may no longer be written to.
531 */
532 class PathBuilder : public PathSink
533 {
534 public:
535 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilder)
536 /* Finish writing to the path and return a Path object that can be used for
537 * drawing. Future use of the builder results in a crash!
538 */
539 virtual TemporaryRef<Path> Finish() = 0;
540 };
542 struct Glyph
543 {
544 uint32_t mIndex;
545 Point mPosition;
546 };
548 /* This class functions as a glyph buffer that can be drawn to a DrawTarget.
549 * XXX - This should probably contain the guts of gfxTextRun in the future as
550 * roc suggested. But for now it's a simple container for a glyph vector.
551 */
552 struct GlyphBuffer
553 {
554 // A pointer to a buffer of glyphs. Managed by the caller.
555 const Glyph *mGlyphs;
556 // Number of glyphs mGlyphs points to.
557 uint32_t mNumGlyphs;
558 };
560 /* This class is an abstraction of a backend/platform specific font object
561 * at a particular size. It is passed into text drawing calls to describe
562 * the font used for the drawing call.
563 */
564 class ScaledFont : public RefCounted<ScaledFont>
565 {
566 public:
567 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
568 virtual ~ScaledFont() {}
570 typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex, Float aGlyphSize, void *aBaton);
572 virtual FontType GetType() const = 0;
574 /* This allows getting a path that describes the outline of a set of glyphs.
575 * A target is passed in so that the guarantee is made the returned path
576 * can be used with any DrawTarget that has the same backend as the one
577 * passed in.
578 */
579 virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) = 0;
581 /* This copies the path describing the glyphs into a PathBuilder. We use this
582 * API rather than a generic API to append paths because it allows easier
583 * implementation in some backends, and more efficient implementation in
584 * others.
585 */
586 virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint = nullptr) = 0;
588 virtual bool GetFontFileData(FontFileDataOutput, void *) { return false; }
590 void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
591 mUserData.Add(key, userData, destroy);
592 }
593 void *GetUserData(UserDataKey *key) {
594 return mUserData.Get(key);
595 }
597 protected:
598 ScaledFont() {}
600 UserData mUserData;
601 };
603 #ifdef MOZ_ENABLE_FREETYPE
604 /**
605 * Describes a font
606 * Used to pass the key informatin from a gfxFont into Azure
607 * XXX Should be replaced by a more long term solution, perhaps Bug 738014
608 */
609 struct FontOptions
610 {
611 std::string mName;
612 FontStyle mStyle;
613 };
614 #endif
617 /* This class is designed to allow passing additional glyph rendering
618 * parameters to the glyph drawing functions. This is an empty wrapper class
619 * merely used to allow holding on to and passing around platform specific
620 * parameters. This is because different platforms have unique rendering
621 * parameters.
622 */
623 class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
624 {
625 public:
626 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptions)
627 virtual ~GlyphRenderingOptions() {}
629 virtual FontType GetType() const = 0;
631 protected:
632 GlyphRenderingOptions() {}
633 };
635 /* This is the main class used for all the drawing. It is created through the
636 * factory and accepts drawing commands. The results of drawing to a target
637 * may be used either through a Snapshot or by flushing the target and directly
638 * accessing the backing store a DrawTarget was created with.
639 */
640 class DrawTarget : public RefCounted<DrawTarget>
641 {
642 public:
643 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
644 DrawTarget() : mTransformDirty(false), mPermitSubpixelAA(false) {}
645 virtual ~DrawTarget() {}
647 virtual BackendType GetType() const = 0;
648 /**
649 * Returns a SourceSurface which is a snapshot of the current contents of the DrawTarget.
650 * Multiple calls to Snapshot() without any drawing operations in between will
651 * normally return the same SourceSurface object.
652 */
653 virtual TemporaryRef<SourceSurface> Snapshot() = 0;
654 virtual IntSize GetSize() = 0;
656 /**
657 * If possible returns the bits to this DrawTarget for direct manipulation. While
658 * the bits is locked any modifications to this DrawTarget is forbidden.
659 * Release takes the original data pointer for safety.
660 */
661 virtual bool LockBits(uint8_t** aData, IntSize* aSize,
662 int32_t* aStride, SurfaceFormat* aFormat) { return false; }
663 virtual void ReleaseBits(uint8_t* aData) {}
665 /* Ensure that the DrawTarget backend has flushed all drawing operations to
666 * this draw target. This must be called before using the backing surface of
667 * this draw target outside of GFX 2D code.
668 */
669 virtual void Flush() = 0;
671 /*
672 * Draw a surface to the draw target. Possibly doing partial drawing or
673 * applying scaling. No sampling happens outside the source.
674 *
675 * aSurface Source surface to draw
676 * aDest Destination rectangle that this drawing operation should draw to
677 * aSource Source rectangle in aSurface coordinates, this area of aSurface
678 * will be stretched to the size of aDest.
679 * aOptions General draw options that are applied to the operation
680 * aSurfOptions DrawSurface options that are applied
681 */
682 virtual void DrawSurface(SourceSurface *aSurface,
683 const Rect &aDest,
684 const Rect &aSource,
685 const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
686 const DrawOptions &aOptions = DrawOptions()) = 0;
688 /*
689 * Draw the output of a FilterNode to the DrawTarget.
690 *
691 * aNode FilterNode to draw
692 * aSourceRect Source rectangle in FilterNode space to draw
693 * aDestPoint Destination point on the DrawTarget to draw the
694 * SourceRectangle of the filter output to
695 */
696 virtual void DrawFilter(FilterNode *aNode,
697 const Rect &aSourceRect,
698 const Point &aDestPoint,
699 const DrawOptions &aOptions = DrawOptions()) = 0;
701 /*
702 * Blend a surface to the draw target with a shadow. The shadow is drawn as a
703 * gaussian blur using a specified sigma. The shadow is clipped to the size
704 * of the input surface, so the input surface should contain a transparent
705 * border the size of the approximate coverage of the blur (3 * aSigma).
706 * NOTE: This function works in device space!
707 *
708 * aSurface Source surface to draw.
709 * aDest Destination point that this drawing operation should draw to.
710 * aColor Color of the drawn shadow
711 * aOffset Offset of the shadow
712 * aSigma Sigma used for the guassian filter kernel
713 * aOperator Composition operator used
714 */
715 virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
716 const Point &aDest,
717 const Color &aColor,
718 const Point &aOffset,
719 Float aSigma,
720 CompositionOp aOperator) = 0;
722 /*
723 * Clear a rectangle on the draw target to transparent black. This will
724 * respect the clipping region and transform.
725 *
726 * aRect Rectangle to clear
727 */
728 virtual void ClearRect(const Rect &aRect) = 0;
730 /*
731 * This is essentially a 'memcpy' between two surfaces. It moves a pixel
732 * aligned area from the source surface unscaled directly onto the
733 * drawtarget. This ignores both transform and clip.
734 *
735 * aSurface Surface to copy from
736 * aSourceRect Source rectangle to be copied
737 * aDest Destination point to copy the surface to
738 */
739 virtual void CopySurface(SourceSurface *aSurface,
740 const IntRect &aSourceRect,
741 const IntPoint &aDestination) = 0;
743 /*
744 * Same as CopySurface, except uses itself as the source.
745 *
746 * Some backends may be able to optimize this better
747 * than just taking a snapshot and using CopySurface.
748 */
749 virtual void CopyRect(const IntRect &aSourceRect,
750 const IntPoint &aDestination)
751 {
752 RefPtr<SourceSurface> source = Snapshot();
753 CopySurface(source, aSourceRect, aDestination);
754 }
756 /*
757 * Fill a rectangle on the DrawTarget with a certain source pattern.
758 *
759 * aRect Rectangle that forms the mask of this filling operation
760 * aPattern Pattern that forms the source of this filling operation
761 * aOptions Options that are applied to this operation
762 */
763 virtual void FillRect(const Rect &aRect,
764 const Pattern &aPattern,
765 const DrawOptions &aOptions = DrawOptions()) = 0;
767 /*
768 * Stroke a rectangle on the DrawTarget with a certain source pattern.
769 *
770 * aRect Rectangle that forms the mask of this stroking operation
771 * aPattern Pattern that forms the source of this stroking operation
772 * aOptions Options that are applied to this operation
773 */
774 virtual void StrokeRect(const Rect &aRect,
775 const Pattern &aPattern,
776 const StrokeOptions &aStrokeOptions = StrokeOptions(),
777 const DrawOptions &aOptions = DrawOptions()) = 0;
779 /*
780 * Stroke a line on the DrawTarget with a certain source pattern.
781 *
782 * aStart Starting point of the line
783 * aEnd End point of the line
784 * aPattern Pattern that forms the source of this stroking operation
785 * aOptions Options that are applied to this operation
786 */
787 virtual void StrokeLine(const Point &aStart,
788 const Point &aEnd,
789 const Pattern &aPattern,
790 const StrokeOptions &aStrokeOptions = StrokeOptions(),
791 const DrawOptions &aOptions = DrawOptions()) = 0;
793 /*
794 * Stroke a path on the draw target with a certain source pattern.
795 *
796 * aPath Path that is to be stroked
797 * aPattern Pattern that should be used for the stroke
798 * aStrokeOptions Stroke options used for this operation
799 * aOptions Draw options used for this operation
800 */
801 virtual void Stroke(const Path *aPath,
802 const Pattern &aPattern,
803 const StrokeOptions &aStrokeOptions = StrokeOptions(),
804 const DrawOptions &aOptions = DrawOptions()) = 0;
806 /*
807 * Fill a path on the draw target with a certain source pattern.
808 *
809 * aPath Path that is to be filled
810 * aPattern Pattern that should be used for the fill
811 * aOptions Draw options used for this operation
812 */
813 virtual void Fill(const Path *aPath,
814 const Pattern &aPattern,
815 const DrawOptions &aOptions = DrawOptions()) = 0;
817 /*
818 * Fill a series of clyphs on the draw target with a certain source pattern.
819 */
820 virtual void FillGlyphs(ScaledFont *aFont,
821 const GlyphBuffer &aBuffer,
822 const Pattern &aPattern,
823 const DrawOptions &aOptions = DrawOptions(),
824 const GlyphRenderingOptions *aRenderingOptions = nullptr) = 0;
826 /*
827 * This takes a source pattern and a mask, and composites the source pattern
828 * onto the destination surface using the alpha channel of the mask pattern
829 * as a mask for the operation.
830 *
831 * aSource Source pattern
832 * aMask Mask pattern
833 * aOptions Drawing options
834 */
835 virtual void Mask(const Pattern &aSource,
836 const Pattern &aMask,
837 const DrawOptions &aOptions = DrawOptions()) = 0;
839 /*
840 * This takes a source pattern and a mask, and composites the source pattern
841 * onto the destination surface using the alpha channel of the mask source.
842 * The operation is bound by the extents of the mask.
843 *
844 * aSource Source pattern
845 * aMask Mask surface
846 * aOffset a transformed offset that the surface is masked at
847 * aOptions Drawing options
848 */
849 virtual void MaskSurface(const Pattern &aSource,
850 SourceSurface *aMask,
851 Point aOffset,
852 const DrawOptions &aOptions = DrawOptions()) = 0;
854 /*
855 * Push a clip to the DrawTarget.
856 *
857 * aPath The path to clip to
858 */
859 virtual void PushClip(const Path *aPath) = 0;
861 /*
862 * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
863 * is specified in user space.
864 *
865 * aRect The rect to clip to
866 */
867 virtual void PushClipRect(const Rect &aRect) = 0;
869 /* Pop a clip from the DrawTarget. A pop without a corresponding push will
870 * be ignored.
871 */
872 virtual void PopClip() = 0;
874 /*
875 * Create a SourceSurface optimized for use with this DrawTarget from
876 * existing bitmap data in memory.
877 *
878 * The SourceSurface does not take ownership of aData, and may be freed at any time.
879 */
880 virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
881 const IntSize &aSize,
882 int32_t aStride,
883 SurfaceFormat aFormat) const = 0;
885 /*
886 * Create a SourceSurface optimized for use with this DrawTarget from an
887 * arbitrary SourceSurface type supported by this backend. This may return
888 * aSourceSurface or some other existing surface.
889 */
890 virtual TemporaryRef<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const = 0;
892 /*
893 * Create a SourceSurface for a type of NativeSurface. This may fail if the
894 * draw target does not know how to deal with the type of NativeSurface passed
895 * in.
896 */
897 virtual TemporaryRef<SourceSurface>
898 CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const = 0;
900 /*
901 * Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
902 */
903 virtual TemporaryRef<DrawTarget>
904 CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
906 /*
907 * Create a draw target optimized for drawing a shadow.
908 *
909 * Note that aSigma is the blur radius that must be used when we draw the
910 * shadow. Also note that this doesn't affect the size of the allocated
911 * surface, the caller is still responsible for including the shadow area in
912 * its size.
913 */
914 virtual TemporaryRef<DrawTarget>
915 CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
916 float aSigma) const
917 {
918 return CreateSimilarDrawTarget(aSize, aFormat);
919 }
921 /*
922 * Create a path builder with the specified fillmode.
923 *
924 * We need the fill mode up front because of Direct2D.
925 * ID2D1SimplifiedGeometrySink requires the fill mode
926 * to be set before calling BeginFigure().
927 */
928 virtual TemporaryRef<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
930 /*
931 * Create a GradientStops object that holds information about a set of
932 * gradient stops, this object is required for linear or radial gradient
933 * patterns to represent the color stops in the gradient.
934 *
935 * aStops An array of gradient stops
936 * aNumStops Number of stops in the array aStops
937 * aExtendNone This describes how to extend the stop color outside of the
938 * gradient area.
939 */
940 virtual TemporaryRef<GradientStops>
941 CreateGradientStops(GradientStop *aStops,
942 uint32_t aNumStops,
943 ExtendMode aExtendMode = ExtendMode::CLAMP) const = 0;
945 /*
946 * Create a FilterNode object that can be used to apply a filter to various
947 * inputs.
948 *
949 * aType Type of filter node to be created.
950 */
951 virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType) = 0;
953 const Matrix &GetTransform() const { return mTransform; }
955 /*
956 * Set a transform on the surface, this transform is applied at drawing time
957 * to both the mask and source of the operation.
958 */
959 virtual void SetTransform(const Matrix &aTransform)
960 { mTransform = aTransform; mTransformDirty = true; }
962 SurfaceFormat GetFormat() { return mFormat; }
964 /* Tries to get a native surface for a DrawTarget, this may fail if the
965 * draw target cannot convert to this surface type.
966 */
967 virtual void *GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
969 virtual bool IsDualDrawTarget() { return false; }
971 void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
972 mUserData.Add(key, userData, destroy);
973 }
974 void *GetUserData(UserDataKey *key) {
975 return mUserData.Get(key);
976 }
978 /* Within this rectangle all pixels will be opaque by the time the result of
979 * this DrawTarget is first used for drawing. Either by the underlying surface
980 * being used as an input to external drawing, or Snapshot() being called.
981 * This rectangle is specified in device space.
982 */
983 void SetOpaqueRect(const IntRect &aRect) {
984 mOpaqueRect = aRect;
985 }
987 const IntRect &GetOpaqueRect() const {
988 return mOpaqueRect;
989 }
991 virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) {
992 mPermitSubpixelAA = aPermitSubpixelAA;
993 }
995 bool GetPermitSubpixelAA() {
996 return mPermitSubpixelAA;
997 }
999 #ifdef USE_SKIA_GPU
1000 virtual bool InitWithGrContext(GrContext* aGrContext,
1001 const IntSize &aSize,
1002 SurfaceFormat aFormat)
1003 {
1004 MOZ_CRASH();
1005 }
1006 #endif
1008 protected:
1009 UserData mUserData;
1010 Matrix mTransform;
1011 IntRect mOpaqueRect;
1012 bool mTransformDirty : 1;
1013 bool mPermitSubpixelAA : 1;
1015 SurfaceFormat mFormat;
1016 };
1018 class DrawEventRecorder : public RefCounted<DrawEventRecorder>
1019 {
1020 public:
1021 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
1022 virtual ~DrawEventRecorder() { }
1023 };
1025 class GFX2D_API Factory
1026 {
1027 public:
1028 static bool HasSSE2();
1030 /* Make sure that the given dimensions don't overflow a 32-bit signed int
1031 * using 4 bytes per pixel; optionally, make sure that either dimension
1032 * doesn't exceed the given limit.
1033 */
1034 static bool CheckSurfaceSize(const IntSize &sz, int32_t limit = 0);
1036 static TemporaryRef<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
1038 static TemporaryRef<DrawTarget>
1039 CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
1041 static TemporaryRef<DrawTarget>
1042 CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
1044 static TemporaryRef<DrawTarget>
1045 CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
1047 static TemporaryRef<ScaledFont>
1048 CreateScaledFontForNativeFont(const NativeFont &aNativeFont, Float aSize);
1050 /**
1051 * This creates a ScaledFont from TrueType data.
1052 *
1053 * aData - Pointer to the data
1054 * aSize - Size of the TrueType data
1055 * aFaceIndex - Index of the font face in the truetype data this ScaledFont needs to represent.
1056 * aGlyphSize - Size of the glyphs in this ScaledFont
1057 * aType - Type of ScaledFont that should be created.
1058 */
1059 static TemporaryRef<ScaledFont>
1060 CreateScaledFontForTrueTypeData(uint8_t *aData, uint32_t aSize, uint32_t aFaceIndex, Float aGlyphSize, FontType aType);
1062 /*
1063 * This creates a scaled font with an associated cairo_scaled_font_t, and
1064 * must be used when using the Cairo backend. The NativeFont and
1065 * cairo_scaled_font_t* parameters must correspond to the same font.
1066 */
1067 static TemporaryRef<ScaledFont>
1068 CreateScaledFontWithCairo(const NativeFont &aNativeFont, Float aSize, cairo_scaled_font_t* aScaledFont);
1070 /*
1071 * This creates a simple data source surface for a certain size. It allocates
1072 * new memory for the surface. This memory is freed when the surface is
1073 * destroyed.
1074 */
1075 static TemporaryRef<DataSourceSurface>
1076 CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat);
1078 /*
1079 * This creates a simple data source surface for a certain size with a
1080 * specific stride, which must be large enough to fit all pixels.
1081 * It allocates new memory for the surface. This memory is freed when
1082 * the surface is destroyed.
1083 */
1084 static TemporaryRef<DataSourceSurface>
1085 CreateDataSourceSurfaceWithStride(const IntSize &aSize, SurfaceFormat aFormat, int32_t aStride);
1087 /*
1088 * This creates a simple data source surface for some existing data. It will
1089 * wrap this data and the data for this source surface. The caller is
1090 * responsible for deallocating the memory only after destruction of the
1091 * surface.
1092 */
1093 static TemporaryRef<DataSourceSurface>
1094 CreateWrappingDataSourceSurface(uint8_t *aData, int32_t aStride,
1095 const IntSize &aSize, SurfaceFormat aFormat);
1097 static TemporaryRef<DrawEventRecorder>
1098 CreateEventRecorderForFile(const char *aFilename);
1100 static void SetGlobalEventRecorder(DrawEventRecorder *aRecorder);
1102 #ifdef USE_SKIA_GPU
1103 static TemporaryRef<DrawTarget>
1104 CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
1105 const IntSize &aSize,
1106 SurfaceFormat aFormat);
1107 #endif
1109 static void PurgeAllCaches();
1111 #if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
1112 static TemporaryRef<GlyphRenderingOptions>
1113 CreateCairoGlyphRenderingOptions(FontHinting aHinting, bool aAutoHinting);
1114 #endif
1115 static TemporaryRef<DrawTarget>
1116 CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB);
1118 #ifdef XP_MACOSX
1119 static TemporaryRef<DrawTarget> CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize);
1120 #endif
1122 #ifdef WIN32
1123 static TemporaryRef<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
1124 static TemporaryRef<DrawTarget>
1125 CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
1126 ID3D10Texture2D *aTextureB,
1127 SurfaceFormat aFormat);
1129 static void SetDirect3D10Device(ID3D10Device1 *aDevice);
1130 static ID3D10Device1 *GetDirect3D10Device();
1131 #ifdef USE_D2D1_1
1132 static void SetDirect3D11Device(ID3D11Device *aDevice);
1133 static ID3D11Device *GetDirect3D11Device();
1134 static ID2D1Device *GetD2D1Device();
1135 #endif
1137 static TemporaryRef<GlyphRenderingOptions>
1138 CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams);
1140 static uint64_t GetD2DVRAMUsageDrawTarget();
1141 static uint64_t GetD2DVRAMUsageSourceSurface();
1142 static void D2DCleanup();
1144 private:
1145 static ID3D10Device1 *mD3D10Device;
1146 #ifdef USE_D2D1_1
1147 static ID3D11Device *mD3D11Device;
1148 static ID2D1Device *mD2D1Device;
1149 #endif
1150 #endif
1152 static DrawEventRecorder *mRecorder;
1153 };
1155 }
1156 }
1158 #endif // _MOZILLA_GFX_2D_H