Line data Source code
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/. */
5 :
6 : #ifndef _MOZILLA_GFX_2D_H
7 : #define _MOZILLA_GFX_2D_H
8 :
9 : #include "Types.h"
10 : #include "Point.h"
11 : #include "Rect.h"
12 : #include "Matrix.h"
13 : #include "Quaternion.h"
14 : #include "UserData.h"
15 : #include "FontVariation.h"
16 : #include <vector>
17 :
18 : // GenericRefCountedBase allows us to hold on to refcounted objects of any type
19 : // (contrary to RefCounted<T> which requires knowing the type T) and, in particular,
20 : // without having a dependency on that type. This is used for DrawTargetSkia
21 : // to be able to hold on to a GLContext.
22 : #include "mozilla/GenericRefCounted.h"
23 : #include "mozilla/MemoryReporting.h"
24 :
25 : // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T**
26 : // outparams using the &-operator. But it will have to do as there's no easy
27 : // solution.
28 : #include "mozilla/RefPtr.h"
29 : #include "mozilla/ServoUtils.h"
30 : #include "mozilla/WeakPtr.h"
31 :
32 : #include "mozilla/DebugOnly.h"
33 :
34 : #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK)
35 : #ifndef MOZ_ENABLE_FREETYPE
36 : #define MOZ_ENABLE_FREETYPE
37 : #endif
38 : #endif
39 :
40 : struct _cairo_surface;
41 : typedef _cairo_surface cairo_surface_t;
42 :
43 : struct _cairo_scaled_font;
44 : typedef _cairo_scaled_font cairo_scaled_font_t;
45 :
46 : struct _FcPattern;
47 : typedef _FcPattern FcPattern;
48 :
49 : struct FT_LibraryRec_;
50 : typedef FT_LibraryRec_* FT_Library;
51 :
52 : struct FT_FaceRec_;
53 : typedef FT_FaceRec_* FT_Face;
54 :
55 : struct ID3D11Texture2D;
56 : struct ID3D11Device;
57 : struct ID2D1Device;
58 : struct IDWriteFactory;
59 : struct IDWriteRenderingParams;
60 : struct IDWriteFontFace;
61 :
62 : class GrContext;
63 : class SkCanvas;
64 : struct gfxFontStyle;
65 :
66 : struct CGContext;
67 : typedef struct CGContext *CGContextRef;
68 :
69 : namespace mozilla {
70 :
71 : class Mutex;
72 :
73 : namespace gfx {
74 : class UnscaledFont;
75 : }
76 :
77 : template<>
78 : struct WeakPtrTraits<gfx::UnscaledFont>
79 : {
80 0 : static void AssertSafeToAccessFromNonOwningThread()
81 : {
82 : // We want to allow UnscaledFont objects that were created on the main
83 : // thread to be accessed from other threads if the Servo font metrics
84 : // mutex is locked, and for objects created on Servo style worker threads
85 : // to be accessed later back on the main thread.
86 0 : AssertIsMainThreadOrServoFontMetricsLocked();
87 0 : }
88 : };
89 :
90 : namespace gfx {
91 :
92 : class ScaledFont;
93 : class SourceSurface;
94 : class DataSourceSurface;
95 : class DrawTarget;
96 : class DrawEventRecorder;
97 : class FilterNode;
98 : class LogForwarder;
99 :
100 0 : struct NativeSurface {
101 : NativeSurfaceType mType;
102 : SurfaceFormat mFormat;
103 : gfx::IntSize mSize;
104 : void *mSurface;
105 : };
106 :
107 : struct NativeFont {
108 : NativeFontType mType;
109 : void *mFont;
110 : };
111 :
112 : /**
113 : * This structure is used to send draw options that are universal to all drawing
114 : * operations.
115 : */
116 : struct DrawOptions {
117 : /// For constructor parameter description, see member data documentation.
118 424 : explicit DrawOptions(Float aAlpha = 1.0f,
119 : CompositionOp aCompositionOp = CompositionOp::OP_OVER,
120 : AntialiasMode aAntialiasMode = AntialiasMode::DEFAULT)
121 424 : : mAlpha(aAlpha)
122 : , mCompositionOp(aCompositionOp)
123 424 : , mAntialiasMode(aAntialiasMode)
124 424 : {}
125 :
126 : Float mAlpha; /**< Alpha value by which the mask generated by this
127 : operation is multiplied. */
128 : CompositionOp mCompositionOp; /**< The operator that indicates how the source and
129 : destination patterns are blended. */
130 : AntialiasMode mAntialiasMode; /**< The AntiAlias mode used for this drawing
131 : operation. */
132 : };
133 :
134 : /**
135 : * This structure is used to send stroke options that are used in stroking
136 : * operations.
137 : */
138 : struct StrokeOptions {
139 : /// For constructor parameter description, see member data documentation.
140 282 : explicit StrokeOptions(Float aLineWidth = 1.0f,
141 : JoinStyle aLineJoin = JoinStyle::MITER_OR_BEVEL,
142 : CapStyle aLineCap = CapStyle::BUTT,
143 : Float aMiterLimit = 10.0f,
144 : size_t aDashLength = 0,
145 : const Float* aDashPattern = 0,
146 : Float aDashOffset = 0.f)
147 282 : : mLineWidth(aLineWidth)
148 : , mMiterLimit(aMiterLimit)
149 282 : , mDashPattern(aDashLength > 0 ? aDashPattern : 0)
150 : , mDashLength(aDashLength)
151 : , mDashOffset(aDashOffset)
152 : , mLineJoin(aLineJoin)
153 564 : , mLineCap(aLineCap)
154 : {
155 282 : MOZ_ASSERT(aDashLength == 0 || aDashPattern);
156 282 : }
157 :
158 : Float mLineWidth; //!< Width of the stroke in userspace.
159 : Float mMiterLimit; //!< Miter limit in units of linewidth
160 : const Float* mDashPattern; /**< Series of on/off userspace lengths defining dash.
161 : Owned by the caller; must live at least as long as
162 : this StrokeOptions.
163 : mDashPattern != null <=> mDashLength > 0. */
164 : size_t mDashLength; //!< Number of on/off lengths in mDashPattern.
165 : Float mDashOffset; /**< Userspace offset within mDashPattern at which
166 : stroking begins. */
167 : JoinStyle mLineJoin; //!< Join style used for joining lines.
168 : CapStyle mLineCap; //!< Cap style used for capping lines.
169 : };
170 :
171 : /**
172 : * This structure supplies additional options for calls to DrawSurface.
173 : */
174 : struct DrawSurfaceOptions {
175 : /// For constructor parameter description, see member data documentation.
176 151 : explicit DrawSurfaceOptions(SamplingFilter aSamplingFilter = SamplingFilter::LINEAR,
177 : SamplingBounds aSamplingBounds = SamplingBounds::UNBOUNDED)
178 151 : : mSamplingFilter(aSamplingFilter)
179 151 : , mSamplingBounds(aSamplingBounds)
180 151 : { }
181 :
182 : SamplingFilter mSamplingFilter; /**< SamplingFilter used when resampling source surface
183 : region to the destination region. */
184 : SamplingBounds mSamplingBounds; /**< This indicates whether the implementation is
185 : allowed to sample pixels outside the source
186 : rectangle as specified in DrawSurface on
187 : the surface. */
188 :
189 : };
190 :
191 : /**
192 : * This class is used to store gradient stops, it can only be used with a
193 : * matching DrawTarget. Not adhering to this condition will make a draw call
194 : * fail.
195 : */
196 : class GradientStops : public RefCounted<GradientStops>
197 : {
198 : public:
199 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
200 0 : virtual ~GradientStops() {}
201 :
202 : virtual BackendType GetBackendType() const = 0;
203 20 : virtual bool IsValid() const { return true; }
204 :
205 : protected:
206 6 : GradientStops() {}
207 : };
208 :
209 : /**
210 : * This is the base class for 'patterns'. Patterns describe the pixels used as
211 : * the source for a masked composition operation that is done by the different
212 : * drawing commands. These objects are not backend specific, however for
213 : * example the gradient stops on a gradient pattern can be backend specific.
214 : */
215 14 : class Pattern
216 : {
217 : public:
218 445 : virtual ~Pattern() {}
219 :
220 : virtual PatternType GetType() const = 0;
221 :
222 : protected:
223 431 : Pattern() {}
224 : };
225 :
226 197 : class ColorPattern : public Pattern
227 : {
228 : public:
229 : // Explicit because consumers should generally use ToDeviceColor when
230 : // creating a ColorPattern.
231 169 : explicit ColorPattern(const Color &aColor)
232 169 : : mColor(aColor)
233 169 : {}
234 :
235 230 : virtual PatternType GetType() const override
236 : {
237 230 : return PatternType::COLOR;
238 : }
239 :
240 : Color mColor;
241 : };
242 :
243 : /**
244 : * This class is used for Linear Gradient Patterns, the gradient stops are
245 : * stored in a separate object and are backend dependent. This class itself
246 : * may be used on the stack.
247 : */
248 26 : class LinearGradientPattern : public Pattern
249 : {
250 : public:
251 : /// For constructor parameter description, see member data documentation.
252 26 : LinearGradientPattern(const Point &aBegin,
253 : const Point &aEnd,
254 : GradientStops *aStops,
255 : const Matrix &aMatrix = Matrix())
256 26 : : mBegin(aBegin)
257 : , mEnd(aEnd)
258 : , mStops(aStops)
259 26 : , mMatrix(aMatrix)
260 : {
261 26 : }
262 :
263 75 : virtual PatternType GetType() const override
264 : {
265 75 : return PatternType::LINEAR_GRADIENT;
266 : }
267 :
268 : Point mBegin; //!< Start of the linear gradient
269 : Point mEnd; /**< End of the linear gradient - NOTE: In the case
270 : of a zero length gradient it will act as the
271 : color of the last stop. */
272 : RefPtr<GradientStops> mStops; /**< GradientStops object for this gradient, this
273 : should match the backend type of the draw
274 : target this pattern will be used with. */
275 : Matrix mMatrix; /**< A matrix that transforms the pattern into
276 : user space */
277 : };
278 :
279 : /**
280 : * This class is used for Radial Gradient Patterns, the gradient stops are
281 : * stored in a separate object and are backend dependent. This class itself
282 : * may be used on the stack.
283 : */
284 0 : class RadialGradientPattern : public Pattern
285 : {
286 : public:
287 : /// For constructor parameter description, see member data documentation.
288 0 : RadialGradientPattern(const Point &aCenter1,
289 : const Point &aCenter2,
290 : Float aRadius1,
291 : Float aRadius2,
292 : GradientStops *aStops,
293 : const Matrix &aMatrix = Matrix())
294 0 : : mCenter1(aCenter1)
295 : , mCenter2(aCenter2)
296 : , mRadius1(aRadius1)
297 : , mRadius2(aRadius2)
298 : , mStops(aStops)
299 0 : , mMatrix(aMatrix)
300 : {
301 0 : }
302 :
303 0 : virtual PatternType GetType() const override
304 : {
305 0 : return PatternType::RADIAL_GRADIENT;
306 : }
307 :
308 : Point mCenter1; //!< Center of the inner (focal) circle.
309 : Point mCenter2; //!< Center of the outer circle.
310 : Float mRadius1; //!< Radius of the inner (focal) circle.
311 : Float mRadius2; //!< Radius of the outer circle.
312 : RefPtr<GradientStops> mStops; /**< GradientStops object for this gradient, this
313 : should match the backend type of the draw target
314 : this pattern will be used with. */
315 : Matrix mMatrix; //!< A matrix that transforms the pattern into user space
316 : };
317 :
318 : /**
319 : * This class is used for Surface Patterns, they wrap a surface and a
320 : * repetition mode for the surface. This may be used on the stack.
321 : */
322 236 : class SurfacePattern : public Pattern
323 : {
324 : public:
325 : /// For constructor parameter description, see member data documentation.
326 236 : SurfacePattern(SourceSurface *aSourceSurface, ExtendMode aExtendMode,
327 : const Matrix &aMatrix = Matrix(),
328 : SamplingFilter aSamplingFilter = SamplingFilter::GOOD,
329 : const IntRect &aSamplingRect = IntRect())
330 236 : : mSurface(aSourceSurface)
331 : , mExtendMode(aExtendMode)
332 : , mSamplingFilter(aSamplingFilter)
333 : , mMatrix(aMatrix)
334 236 : , mSamplingRect(aSamplingRect)
335 236 : {}
336 :
337 335 : virtual PatternType GetType() const override
338 : {
339 335 : return PatternType::SURFACE;
340 : }
341 :
342 : RefPtr<SourceSurface> mSurface; //!< Surface to use for drawing
343 : ExtendMode mExtendMode; /**< This determines how the image is extended
344 : outside the bounds of the image */
345 : SamplingFilter mSamplingFilter; //!< Resampling filter for resampling the image.
346 : Matrix mMatrix; //!< Transforms the pattern into user space
347 :
348 : IntRect mSamplingRect; /**< Rect that must not be sampled outside of,
349 : or an empty rect if none has been specified. */
350 : };
351 :
352 : class StoredPattern;
353 : class DrawTargetCaptureImpl;
354 :
355 : /**
356 : * This is the base class for source surfaces. These objects are surfaces
357 : * which may be used as a source in a SurfacePattern or a DrawSurface call.
358 : * They cannot be drawn to directly.
359 : *
360 : * Although SourceSurface has thread-safe refcount, some SourceSurface cannot
361 : * be used on random threads at the same time. Only DataSourceSurface can be
362 : * used on random threads now. This will be fixed in the future. Eventually
363 : * all SourceSurface should be thread-safe.
364 : */
365 170 : class SourceSurface : public external::AtomicRefCounted<SourceSurface>
366 : {
367 : public:
368 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
369 52 : virtual ~SourceSurface() {}
370 :
371 : virtual SurfaceType GetType() const = 0;
372 : virtual IntSize GetSize() const = 0;
373 : virtual SurfaceFormat GetFormat() const = 0;
374 :
375 : /** This returns false if some event has made this source surface invalid for
376 : * usage with current DrawTargets. For example in the case of Direct2D this
377 : * could return false if we have switched devices since this surface was
378 : * created.
379 : */
380 73 : virtual bool IsValid() const { return true; }
381 :
382 : /**
383 : * This function will return true if the surface type matches that of a
384 : * DataSourceSurface and if GetDataSurface will return the same object.
385 : */
386 95 : bool IsDataSourceSurface() const {
387 95 : SurfaceType type = GetType();
388 95 : return type == SurfaceType::DATA ||
389 95 : type == SurfaceType::DATA_SHARED;
390 : }
391 :
392 : /**
393 : * This function will get a DataSourceSurface for this surface, a
394 : * DataSourceSurface's data can be accessed directly.
395 : */
396 : virtual already_AddRefed<DataSourceSurface> GetDataSurface() = 0;
397 :
398 : /** Tries to get this SourceSurface's native surface. This will fail if aType
399 : * is not the type of this SourceSurface's native surface.
400 : */
401 0 : virtual void *GetNativeSurface(NativeSurfaceType aType) {
402 0 : return nullptr;
403 : }
404 :
405 0 : void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
406 0 : mUserData.Add(key, userData, destroy);
407 0 : }
408 0 : void *GetUserData(UserDataKey *key) {
409 0 : return mUserData.Get(key);
410 : }
411 0 : void RemoveUserData(UserDataKey *key) {
412 0 : mUserData.RemoveAndDestroy(key);
413 0 : }
414 :
415 : protected:
416 : friend class DrawTargetCaptureImpl;
417 : friend class StoredPattern;
418 :
419 : // This is for internal use, it ensures the SourceSurface's data remains
420 : // valid during the lifetime of the SourceSurface.
421 : // @todo XXX - We need something better here :(. But we may be able to get rid
422 : // of CreateWrappingDataSourceSurface in the future.
423 0 : virtual void GuaranteePersistance() {}
424 :
425 : UserData mUserData;
426 : };
427 :
428 : class DataSourceSurface : public SourceSurface
429 : {
430 : public:
431 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface, override)
432 170 : DataSourceSurface()
433 170 : : mIsMapped(false)
434 : {
435 170 : }
436 :
437 : #ifdef DEBUG
438 52 : virtual ~DataSourceSurface()
439 104 : {
440 52 : MOZ_ASSERT(!mIsMapped, "Someone forgot to call Unmap()");
441 52 : }
442 : #endif
443 :
444 : struct MappedSurface {
445 : uint8_t *mData;
446 : int32_t mStride;
447 : };
448 :
449 : enum MapType {
450 : READ,
451 : WRITE,
452 : READ_WRITE
453 : };
454 :
455 : /**
456 : * This is a scoped version of Map(). Map() is called in the constructor and
457 : * Unmap() in the destructor. Use this for automatic unmapping of your data
458 : * surfaces.
459 : *
460 : * Use IsMapped() to verify whether Map() succeeded or not.
461 : */
462 : class ScopedMap {
463 : public:
464 285 : explicit ScopedMap(DataSourceSurface* aSurface, MapType aType)
465 285 : : mSurface(aSurface)
466 285 : , mIsMapped(aSurface->Map(aType, &mMap)) {}
467 :
468 454 : virtual ~ScopedMap()
469 454 : {
470 227 : if (mIsMapped) {
471 227 : mSurface->Unmap();
472 : }
473 681 : }
474 :
475 74 : uint8_t* GetData() const
476 : {
477 74 : MOZ_ASSERT(mIsMapped);
478 74 : return mMap.mData;
479 : }
480 :
481 0 : int32_t GetStride() const
482 : {
483 0 : MOZ_ASSERT(mIsMapped);
484 0 : return mMap.mStride;
485 : }
486 :
487 0 : const MappedSurface* GetMappedSurface() const
488 : {
489 0 : MOZ_ASSERT(mIsMapped);
490 0 : return &mMap;
491 : }
492 :
493 285 : bool IsMapped() const { return mIsMapped; }
494 :
495 : private:
496 : RefPtr<DataSourceSurface> mSurface;
497 : MappedSurface mMap;
498 : bool mIsMapped;
499 : };
500 :
501 0 : virtual SurfaceType GetType() const override { return SurfaceType::DATA; }
502 : /** @deprecated
503 : * Get the raw bitmap data of the surface.
504 : * Can return null if there was OOM allocating surface data.
505 : */
506 : virtual uint8_t *GetData() = 0;
507 :
508 : /** @deprecated
509 : * Stride of the surface, distance in bytes between the start of the image
510 : * data belonging to row y and row y+1. This may be negative.
511 : * Can return 0 if there was OOM allocating surface data.
512 : */
513 : virtual int32_t Stride() = 0;
514 :
515 : /**
516 : * The caller is responsible for ensuring aMappedSurface is not null.
517 : */
518 0 : virtual bool Map(MapType, MappedSurface *aMappedSurface)
519 : {
520 0 : aMappedSurface->mData = GetData();
521 0 : aMappedSurface->mStride = Stride();
522 0 : mIsMapped = !!aMappedSurface->mData;
523 0 : return mIsMapped;
524 : }
525 :
526 0 : virtual void Unmap()
527 : {
528 0 : MOZ_ASSERT(mIsMapped);
529 0 : mIsMapped = false;
530 0 : }
531 :
532 : /**
533 : * Returns a DataSourceSurface with the same data as this one, but
534 : * guaranteed to have surface->GetType() == SurfaceType::DATA.
535 : *
536 : * The returning surface might be null, because of OOM or gfx device reset.
537 : * The caller needs to do null-check before using it.
538 : */
539 : virtual already_AddRefed<DataSourceSurface> GetDataSurface() override;
540 :
541 : /**
542 : * Add the size of the underlying data buffer to the aggregate.
543 : */
544 0 : virtual void AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
545 : size_t& aHeapSizeOut,
546 : size_t& aNonHeapSizeOut) const
547 : {
548 0 : }
549 :
550 : /**
551 : * Returns whether or not the data was allocated on the heap. This should
552 : * be used to determine if the memory needs to be cleared to 0.
553 : */
554 0 : virtual bool OnHeap() const
555 : {
556 0 : return true;
557 : }
558 :
559 : protected:
560 : bool mIsMapped;
561 : };
562 :
563 : /** This is an abstract object that accepts path segments. */
564 130 : class PathSink : public RefCounted<PathSink>
565 : {
566 : public:
567 54 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink)
568 130 : virtual ~PathSink() {}
569 :
570 : /** Move the current point in the path, any figure currently being drawn will
571 : * be considered closed during fill operations, however when stroking the
572 : * closing line segment will not be drawn.
573 : */
574 : virtual void MoveTo(const Point &aPoint) = 0;
575 : /** Add a linesegment to the current figure */
576 : virtual void LineTo(const Point &aPoint) = 0;
577 : /** Add a cubic bezier curve to the current figure */
578 : virtual void BezierTo(const Point &aCP1,
579 : const Point &aCP2,
580 : const Point &aCP3) = 0;
581 : /** Add a quadratic bezier curve to the current figure */
582 : virtual void QuadraticBezierTo(const Point &aCP1,
583 : const Point &aCP2) = 0;
584 : /** Close the current figure, this will essentially generate a line segment
585 : * from the current point to the starting point for the current figure
586 : */
587 : virtual void Close() = 0;
588 : /** Add an arc to the current figure */
589 : virtual void Arc(const Point &aOrigin, float aRadius, float aStartAngle,
590 : float aEndAngle, bool aAntiClockwise = false) = 0;
591 : /** Point the current subpath is at - or where the next subpath will start
592 : * if there is no active subpath.
593 : */
594 : virtual Point CurrentPoint() const = 0;
595 : };
596 :
597 : class PathBuilder;
598 : class FlattenedPath;
599 :
600 : /** The path class is used to create (sets of) figures of any shape that can be
601 : * filled or stroked to a DrawTarget
602 : */
603 : class Path : public RefCounted<Path>
604 : {
605 : public:
606 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
607 : virtual ~Path();
608 :
609 : virtual BackendType GetBackendType() const = 0;
610 :
611 : /** This returns a PathBuilder object that contains a copy of the contents of
612 : * this path and is still writable.
613 : */
614 0 : inline already_AddRefed<PathBuilder> CopyToBuilder() const {
615 0 : return CopyToBuilder(GetFillRule());
616 : }
617 0 : inline already_AddRefed<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform) const {
618 0 : return TransformedCopyToBuilder(aTransform, GetFillRule());
619 : }
620 : /** This returns a PathBuilder object that contains a copy of the contents of
621 : * this path, converted to use the specified FillRule, and still writable.
622 : */
623 : virtual already_AddRefed<PathBuilder> CopyToBuilder(FillRule aFillRule) const = 0;
624 : virtual already_AddRefed<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
625 : FillRule aFillRule) const = 0;
626 :
627 : /** This function checks if a point lies within a path. It allows passing a
628 : * transform that will transform the path to the coordinate space in which
629 : * aPoint is given.
630 : */
631 : virtual bool ContainsPoint(const Point &aPoint, const Matrix &aTransform) const = 0;
632 :
633 :
634 : /** This function checks if a point lies within the stroke of a path using the
635 : * specified strokeoptions. It allows passing a transform that will transform
636 : * the path to the coordinate space in which aPoint is given.
637 : */
638 : virtual bool StrokeContainsPoint(const StrokeOptions &aStrokeOptions,
639 : const Point &aPoint,
640 : const Matrix &aTransform) const = 0;
641 :
642 : /** This functions gets the bounds of this path. These bounds are not
643 : * guaranteed to be tight. A transform may be specified that gives the bounds
644 : * after application of the transform.
645 : */
646 : virtual Rect GetBounds(const Matrix &aTransform = Matrix()) const = 0;
647 :
648 : /** This function gets the bounds of the stroke of this path using the
649 : * specified strokeoptions. These bounds are not guaranteed to be tight.
650 : * A transform may be specified that gives the bounds after application of
651 : * the transform.
652 : */
653 : virtual Rect GetStrokedBounds(const StrokeOptions &aStrokeOptions,
654 : const Matrix &aTransform = Matrix()) const = 0;
655 :
656 : /** Take the contents of this path and stream it to another sink, this works
657 : * regardless of the backend that might be used for the destination sink.
658 : */
659 : virtual void StreamToSink(PathSink *aSink) const = 0;
660 :
661 : /** This gets the fillrule this path's builder was created with. This is not
662 : * mutable.
663 : */
664 : virtual FillRule GetFillRule() const = 0;
665 :
666 : virtual Float ComputeLength();
667 :
668 : virtual Point ComputePointAtLength(Float aLength,
669 : Point* aTangent = nullptr);
670 :
671 : protected:
672 : Path();
673 : void EnsureFlattenedPath();
674 :
675 : RefPtr<FlattenedPath> mFlattenedPath;
676 : };
677 :
678 : /** The PathBuilder class allows path creation. Once finish is called on the
679 : * pathbuilder it may no longer be written to.
680 : */
681 224 : class PathBuilder : public PathSink
682 : {
683 : public:
684 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilder)
685 : /** Finish writing to the path and return a Path object that can be used for
686 : * drawing. Future use of the builder results in a crash!
687 : */
688 : virtual already_AddRefed<Path> Finish() = 0;
689 :
690 : virtual BackendType GetBackendType() const = 0;
691 : };
692 :
693 3570 : struct Glyph
694 : {
695 : uint32_t mIndex;
696 : Point mPosition;
697 : };
698 :
699 0 : static inline bool operator==(const Glyph& aOne, const Glyph& aOther) {
700 0 : return aOne.mIndex == aOther.mIndex && aOne.mPosition == aOther.mPosition;
701 : }
702 :
703 : /** This class functions as a glyph buffer that can be drawn to a DrawTarget.
704 : * @todo XXX - This should probably contain the guts of gfxTextRun in the future as
705 : * roc suggested. But for now it's a simple container for a glyph vector.
706 : */
707 : struct GlyphBuffer
708 : {
709 : const Glyph *mGlyphs; //!< A pointer to a buffer of glyphs. Managed by the caller.
710 : uint32_t mNumGlyphs; //!< Number of glyphs mGlyphs points to.
711 : };
712 :
713 : struct GlyphMetrics
714 : {
715 : // Horizontal distance from the origin to the leftmost side of the bounding
716 : // box of the drawn glyph. This can be negative!
717 : Float mXBearing;
718 : // Horizontal distance from the origin of this glyph to the origin of the
719 : // next glyph.
720 : Float mXAdvance;
721 : // Vertical distance from the origin to the topmost side of the bounding box
722 : // of the drawn glyph.
723 : Float mYBearing;
724 : // Vertical distance from the origin of this glyph to the origin of the next
725 : // glyph, this is used when drawing vertically and will typically be 0.
726 : Float mYAdvance;
727 : // Width of the glyph's black box.
728 : Float mWidth;
729 : // Height of the glyph's black box.
730 : Float mHeight;
731 : };
732 :
733 : class UnscaledFont
734 : : public external::AtomicRefCounted<UnscaledFont>
735 : , public SupportsWeakPtr<UnscaledFont>
736 : {
737 : public:
738 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(UnscaledFont)
739 399 : MOZ_DECLARE_WEAKREFERENCE_TYPENAME(UnscaledFont)
740 :
741 : virtual ~UnscaledFont();
742 :
743 : virtual FontType GetType() const = 0;
744 :
745 0 : static uint32_t DeletionCounter() { return sDeletionCounter; }
746 :
747 : typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex,
748 : void *aBaton);
749 : typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
750 : typedef void (*FontDescriptorOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
751 :
752 0 : virtual bool GetFontFileData(FontFileDataOutput, void *) { return false; }
753 :
754 0 : virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; }
755 :
756 0 : virtual bool GetFontDescriptor(FontDescriptorOutput, void *) { return false; }
757 :
758 : virtual already_AddRefed<ScaledFont>
759 0 : CreateScaledFont(Float aGlyphSize,
760 : const uint8_t* aInstanceData,
761 : uint32_t aInstanceDataLength)
762 : {
763 0 : return nullptr;
764 : }
765 :
766 : protected:
767 6 : UnscaledFont() {}
768 :
769 : private:
770 : static uint32_t sDeletionCounter;
771 : };
772 :
773 : /** This class is an abstraction of a backend/platform specific font object
774 : * at a particular size. It is passed into text drawing calls to describe
775 : * the font used for the drawing call.
776 : */
777 : class ScaledFont : public external::AtomicRefCounted<ScaledFont>
778 : {
779 : public:
780 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
781 21 : virtual ~ScaledFont() {}
782 :
783 : virtual FontType GetType() const = 0;
784 : virtual Float GetSize() const = 0;
785 : virtual AntialiasMode GetDefaultAAMode();
786 :
787 : /** This allows getting a path that describes the outline of a set of glyphs.
788 : * A target is passed in so that the guarantee is made the returned path
789 : * can be used with any DrawTarget that has the same backend as the one
790 : * passed in.
791 : */
792 : virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget) = 0;
793 :
794 : /** This copies the path describing the glyphs into a PathBuilder. We use this
795 : * API rather than a generic API to append paths because it allows easier
796 : * implementation in some backends, and more efficient implementation in
797 : * others.
798 : */
799 : virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, const Matrix *aTransformHint = nullptr) = 0;
800 :
801 : /* This gets the metrics of a set of glyphs for the current font face.
802 : */
803 : virtual void GetGlyphDesignMetrics(const uint16_t* aGlyphIndices, uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics) = 0;
804 :
805 : typedef void (*FontInstanceDataOutput)(const uint8_t* aData, uint32_t aLength, void* aBaton);
806 :
807 0 : virtual bool GetFontInstanceData(FontInstanceDataOutput, void *) { return false; }
808 :
809 0 : virtual bool CanSerialize() { return false; }
810 :
811 0 : void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
812 0 : mUserData.Add(key, userData, destroy);
813 0 : }
814 0 : void *GetUserData(UserDataKey *key) {
815 0 : return mUserData.Get(key);
816 : }
817 :
818 0 : void RemoveUserData(UserDataKey *key) {
819 0 : mUserData.RemoveAndDestroy(key);
820 0 : }
821 :
822 0 : const RefPtr<UnscaledFont>& GetUnscaledFont() const { return mUnscaledFont; }
823 :
824 : protected:
825 21 : explicit ScaledFont(const RefPtr<UnscaledFont>& aUnscaledFont)
826 21 : : mUnscaledFont(aUnscaledFont)
827 21 : {}
828 :
829 : UserData mUserData;
830 : RefPtr<UnscaledFont> mUnscaledFont;
831 : };
832 :
833 : /**
834 : * Derived classes hold a native font resource from which to create
835 : * ScaledFonts.
836 : */
837 0 : class NativeFontResource : public external::AtomicRefCounted<NativeFontResource>
838 : {
839 : public:
840 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(NativeFontResource)
841 :
842 : /**
843 : * Creates a UnscaledFont using the font corresponding to the index.
844 : *
845 : * @param aIndex index for the font within the resource.
846 : * @param aInstanceData pointer to read-only buffer of any available instance data.
847 : * @param aInstanceDataLength the size of the instance data.
848 : * @return an already_addrefed UnscaledFont, containing nullptr if failed.
849 : */
850 : virtual already_AddRefed<UnscaledFont>
851 : CreateUnscaledFont(uint32_t aIndex,
852 : const uint8_t* aInstanceData,
853 : uint32_t aInstanceDataLength) = 0;
854 :
855 0 : virtual ~NativeFontResource() {}
856 : };
857 :
858 : /** This class is designed to allow passing additional glyph rendering
859 : * parameters to the glyph drawing functions. This is an empty wrapper class
860 : * merely used to allow holding on to and passing around platform specific
861 : * parameters. This is because different platforms have unique rendering
862 : * parameters.
863 : */
864 : class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
865 : {
866 : public:
867 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptions)
868 : virtual ~GlyphRenderingOptions() {}
869 :
870 : virtual FontType GetType() const = 0;
871 :
872 : protected:
873 : GlyphRenderingOptions() {}
874 : };
875 :
876 : class DrawTargetCapture;
877 :
878 : /** This is the main class used for all the drawing. It is created through the
879 : * factory and accepts drawing commands. The results of drawing to a target
880 : * may be used either through a Snapshot or by flushing the target and directly
881 : * accessing the backing store a DrawTarget was created with.
882 : */
883 : class DrawTarget : public RefCounted<DrawTarget>
884 : {
885 : public:
886 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
887 63 : DrawTarget() : mTransformDirty(false), mPermitSubpixelAA(false) {}
888 37 : virtual ~DrawTarget() {}
889 :
890 347 : virtual bool IsValid() const { return true; };
891 : virtual DrawTargetType GetType() const = 0;
892 :
893 : virtual BackendType GetBackendType() const = 0;
894 :
895 35 : virtual bool IsRecording() const { return false; }
896 0 : virtual bool IsCaptureDT() const { return false; }
897 :
898 : /**
899 : * Returns a SourceSurface which is a snapshot of the current contents of the DrawTarget.
900 : * Multiple calls to Snapshot() without any drawing operations in between will
901 : * normally return the same SourceSurface object.
902 : */
903 : virtual already_AddRefed<SourceSurface> Snapshot() = 0;
904 :
905 : // Snapshots the contents and returns an alpha mask
906 : // based on the RGB values.
907 : virtual already_AddRefed<SourceSurface> IntoLuminanceSource(LuminanceType aLuminanceType,
908 : float aOpacity);
909 : virtual IntSize GetSize() = 0;
910 :
911 : /**
912 : * If possible returns the bits to this DrawTarget for direct manipulation. While
913 : * the bits is locked any modifications to this DrawTarget is forbidden.
914 : * Release takes the original data pointer for safety.
915 : */
916 0 : virtual bool LockBits(uint8_t** aData, IntSize* aSize,
917 : int32_t* aStride, SurfaceFormat* aFormat,
918 0 : IntPoint* aOrigin = nullptr) { return false; }
919 0 : virtual void ReleaseBits(uint8_t* aData) {}
920 :
921 : /** Ensure that the DrawTarget backend has flushed all drawing operations to
922 : * this draw target. This must be called before using the backing surface of
923 : * this draw target outside of GFX 2D code.
924 : */
925 : virtual void Flush() = 0;
926 :
927 : /**
928 : * Realize a DrawTargetCapture onto the draw target.
929 : *
930 : * @param aSource Capture DrawTarget to draw
931 : * @param aTransform Transform to apply when replaying commands
932 : */
933 : virtual void DrawCapturedDT(DrawTargetCapture *aCaptureDT,
934 : const Matrix& aTransform);
935 :
936 : /**
937 : * Draw a surface to the draw target. Possibly doing partial drawing or
938 : * applying scaling. No sampling happens outside the source.
939 : *
940 : * @param aSurface Source surface to draw
941 : * @param aDest Destination rectangle that this drawing operation should draw to
942 : * @param aSource Source rectangle in aSurface coordinates, this area of aSurface
943 : * will be stretched to the size of aDest.
944 : * @param aOptions General draw options that are applied to the operation
945 : * @param aSurfOptions DrawSurface options that are applied
946 : */
947 : virtual void DrawSurface(SourceSurface *aSurface,
948 : const Rect &aDest,
949 : const Rect &aSource,
950 : const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
951 : const DrawOptions &aOptions = DrawOptions()) = 0;
952 :
953 : /**
954 : * Draw the output of a FilterNode to the DrawTarget.
955 : *
956 : * @param aNode FilterNode to draw
957 : * @param aSourceRect Source rectangle in FilterNode space to draw
958 : * @param aDestPoint Destination point on the DrawTarget to draw the
959 : * SourceRectangle of the filter output to
960 : */
961 : virtual void DrawFilter(FilterNode *aNode,
962 : const Rect &aSourceRect,
963 : const Point &aDestPoint,
964 : const DrawOptions &aOptions = DrawOptions()) = 0;
965 :
966 : /**
967 : * Blend a surface to the draw target with a shadow. The shadow is drawn as a
968 : * gaussian blur using a specified sigma. The shadow is clipped to the size
969 : * of the input surface, so the input surface should contain a transparent
970 : * border the size of the approximate coverage of the blur (3 * aSigma).
971 : * NOTE: This function works in device space!
972 : *
973 : * @param aSurface Source surface to draw.
974 : * @param aDest Destination point that this drawing operation should draw to.
975 : * @param aColor Color of the drawn shadow
976 : * @param aOffset Offset of the shadow
977 : * @param aSigma Sigma used for the guassian filter kernel
978 : * @param aOperator Composition operator used
979 : */
980 : virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
981 : const Point &aDest,
982 : const Color &aColor,
983 : const Point &aOffset,
984 : Float aSigma,
985 : CompositionOp aOperator) = 0;
986 :
987 : /**
988 : * Clear a rectangle on the draw target to transparent black. This will
989 : * respect the clipping region and transform.
990 : *
991 : * @param aRect Rectangle to clear
992 : */
993 : virtual void ClearRect(const Rect &aRect) = 0;
994 :
995 : /**
996 : * This is essentially a 'memcpy' between two surfaces. It moves a pixel
997 : * aligned area from the source surface unscaled directly onto the
998 : * drawtarget. This ignores both transform and clip.
999 : *
1000 : * @param aSurface Surface to copy from
1001 : * @param aSourceRect Source rectangle to be copied
1002 : * @param aDest Destination point to copy the surface to
1003 : */
1004 : virtual void CopySurface(SourceSurface *aSurface,
1005 : const IntRect &aSourceRect,
1006 : const IntPoint &aDestination) = 0;
1007 :
1008 : /** @see CopySurface
1009 : * Same as CopySurface, except uses itself as the source.
1010 : *
1011 : * Some backends may be able to optimize this better
1012 : * than just taking a snapshot and using CopySurface.
1013 : */
1014 0 : virtual void CopyRect(const IntRect &aSourceRect,
1015 : const IntPoint &aDestination)
1016 : {
1017 0 : RefPtr<SourceSurface> source = Snapshot();
1018 0 : CopySurface(source, aSourceRect, aDestination);
1019 0 : }
1020 :
1021 : /**
1022 : * Fill a rectangle on the DrawTarget with a certain source pattern.
1023 : *
1024 : * @param aRect Rectangle that forms the mask of this filling operation
1025 : * @param aPattern Pattern that forms the source of this filling operation
1026 : * @param aOptions Options that are applied to this operation
1027 : */
1028 : virtual void FillRect(const Rect &aRect,
1029 : const Pattern &aPattern,
1030 : const DrawOptions &aOptions = DrawOptions()) = 0;
1031 :
1032 : /**
1033 : * Stroke a rectangle on the DrawTarget with a certain source pattern.
1034 : *
1035 : * @param aRect Rectangle that forms the mask of this stroking operation
1036 : * @param aPattern Pattern that forms the source of this stroking operation
1037 : * @param aOptions Options that are applied to this operation
1038 : */
1039 : virtual void StrokeRect(const Rect &aRect,
1040 : const Pattern &aPattern,
1041 : const StrokeOptions &aStrokeOptions = StrokeOptions(),
1042 : const DrawOptions &aOptions = DrawOptions()) = 0;
1043 :
1044 : /**
1045 : * Stroke a line on the DrawTarget with a certain source pattern.
1046 : *
1047 : * @param aStart Starting point of the line
1048 : * @param aEnd End point of the line
1049 : * @param aPattern Pattern that forms the source of this stroking operation
1050 : * @param aOptions Options that are applied to this operation
1051 : */
1052 : virtual void StrokeLine(const Point &aStart,
1053 : const Point &aEnd,
1054 : const Pattern &aPattern,
1055 : const StrokeOptions &aStrokeOptions = StrokeOptions(),
1056 : const DrawOptions &aOptions = DrawOptions()) = 0;
1057 :
1058 : /**
1059 : * Stroke a path on the draw target with a certain source pattern.
1060 : *
1061 : * @param aPath Path that is to be stroked
1062 : * @param aPattern Pattern that should be used for the stroke
1063 : * @param aStrokeOptions Stroke options used for this operation
1064 : * @param aOptions Draw options used for this operation
1065 : */
1066 : virtual void Stroke(const Path *aPath,
1067 : const Pattern &aPattern,
1068 : const StrokeOptions &aStrokeOptions = StrokeOptions(),
1069 : const DrawOptions &aOptions = DrawOptions()) = 0;
1070 :
1071 : /**
1072 : * Fill a path on the draw target with a certain source pattern.
1073 : *
1074 : * @param aPath Path that is to be filled
1075 : * @param aPattern Pattern that should be used for the fill
1076 : * @param aOptions Draw options used for this operation
1077 : */
1078 : virtual void Fill(const Path *aPath,
1079 : const Pattern &aPattern,
1080 : const DrawOptions &aOptions = DrawOptions()) = 0;
1081 :
1082 : /**
1083 : * Fill a series of glyphs on the draw target with a certain source pattern.
1084 : */
1085 : virtual void FillGlyphs(ScaledFont *aFont,
1086 : const GlyphBuffer &aBuffer,
1087 : const Pattern &aPattern,
1088 : const DrawOptions &aOptions = DrawOptions(),
1089 : const GlyphRenderingOptions *aRenderingOptions = nullptr) = 0;
1090 :
1091 : /**
1092 : * Stroke a series of glyphs on the draw target with a certain source pattern.
1093 : */
1094 : virtual void StrokeGlyphs(ScaledFont* aFont,
1095 : const GlyphBuffer& aBuffer,
1096 : const Pattern& aPattern,
1097 : const StrokeOptions& aStrokeOptions = StrokeOptions(),
1098 : const DrawOptions& aOptions = DrawOptions(),
1099 : const GlyphRenderingOptions* aRenderingOptions = nullptr);
1100 :
1101 : /**
1102 : * This takes a source pattern and a mask, and composites the source pattern
1103 : * onto the destination surface using the alpha channel of the mask pattern
1104 : * as a mask for the operation.
1105 : *
1106 : * @param aSource Source pattern
1107 : * @param aMask Mask pattern
1108 : * @param aOptions Drawing options
1109 : */
1110 : virtual void Mask(const Pattern &aSource,
1111 : const Pattern &aMask,
1112 : const DrawOptions &aOptions = DrawOptions()) = 0;
1113 :
1114 : /**
1115 : * This takes a source pattern and a mask, and composites the source pattern
1116 : * onto the destination surface using the alpha channel of the mask source.
1117 : * The operation is bound by the extents of the mask.
1118 : *
1119 : * @param aSource Source pattern
1120 : * @param aMask Mask surface
1121 : * @param aOffset a transformed offset that the surface is masked at
1122 : * @param aOptions Drawing options
1123 : */
1124 : virtual void MaskSurface(const Pattern &aSource,
1125 : SourceSurface *aMask,
1126 : Point aOffset,
1127 : const DrawOptions &aOptions = DrawOptions()) = 0;
1128 :
1129 : /**
1130 : * Draw aSurface using the 3D transform aMatrix. The DrawTarget's transform
1131 : * and clip are applied after the 3D transform.
1132 : *
1133 : * If the transform fails (i.e. because aMatrix is singular), false is returned and nothing is drawn.
1134 : */
1135 : virtual bool Draw3DTransformedSurface(SourceSurface* aSurface,
1136 : const Matrix4x4& aMatrix);
1137 :
1138 : /**
1139 : * Push a clip to the DrawTarget.
1140 : *
1141 : * @param aPath The path to clip to
1142 : */
1143 : virtual void PushClip(const Path *aPath) = 0;
1144 :
1145 : /**
1146 : * Push an axis-aligned rectangular clip to the DrawTarget. This rectangle
1147 : * is specified in user space.
1148 : *
1149 : * @param aRect The rect to clip to
1150 : */
1151 : virtual void PushClipRect(const Rect &aRect) = 0;
1152 :
1153 : /**
1154 : * Push a clip region specifed by the union of axis-aligned rectangular
1155 : * clips to the DrawTarget. These rectangles are specified in device space.
1156 : * This must be balanced by a corresponding call to PopClip within a layer.
1157 : *
1158 : * @param aRects The rects to clip to
1159 : * @param aCount The number of rectangles
1160 : */
1161 : virtual void PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount);
1162 :
1163 : /** Pop a clip from the DrawTarget. A pop without a corresponding push will
1164 : * be ignored.
1165 : */
1166 : virtual void PopClip() = 0;
1167 :
1168 : /**
1169 : * Push a 'layer' to the DrawTarget, a layer is a temporary surface that all
1170 : * drawing will be redirected to, this is used for example to support group
1171 : * opacity or the masking of groups. Clips must be balanced within a layer,
1172 : * i.e. between a matching PushLayer/PopLayer pair there must be as many
1173 : * PushClip(Rect) calls as there are PopClip calls.
1174 : *
1175 : * @param aOpaque Whether the layer will be opaque
1176 : * @param aOpacity Opacity of the layer
1177 : * @param aMask Mask applied to the layer
1178 : * @param aMaskTransform Transform applied to the layer mask
1179 : * @param aBounds Optional bounds in device space to which the layer is
1180 : * limited in size.
1181 : * @param aCopyBackground Whether to copy the background into the layer, this
1182 : * is only supported when aOpaque is true.
1183 : */
1184 0 : virtual void PushLayer(bool aOpaque, Float aOpacity,
1185 : SourceSurface* aMask,
1186 : const Matrix& aMaskTransform,
1187 : const IntRect& aBounds = IntRect(),
1188 0 : bool aCopyBackground = false) { MOZ_CRASH("GFX: PushLayer"); }
1189 :
1190 : /**
1191 : * This balances a call to PushLayer and proceeds to blend the layer back
1192 : * onto the background. This blend will blend the temporary surface back
1193 : * onto the target in device space using POINT sampling and operator over.
1194 : */
1195 0 : virtual void PopLayer() { MOZ_CRASH("GFX: PopLayer"); }
1196 :
1197 : /**
1198 : * Create a SourceSurface optimized for use with this DrawTarget from
1199 : * existing bitmap data in memory.
1200 : *
1201 : * The SourceSurface does not take ownership of aData, and may be freed at any time.
1202 : */
1203 : virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
1204 : const IntSize &aSize,
1205 : int32_t aStride,
1206 : SurfaceFormat aFormat) const = 0;
1207 :
1208 : /**
1209 : * Create a SourceSurface optimized for use with this DrawTarget from an
1210 : * arbitrary SourceSurface type supported by this backend. This may return
1211 : * aSourceSurface or some other existing surface.
1212 : */
1213 : virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const = 0;
1214 0 : virtual already_AddRefed<SourceSurface> OptimizeSourceSurfaceForUnknownAlpha(SourceSurface *aSurface) const {
1215 0 : return OptimizeSourceSurface(aSurface);
1216 : }
1217 :
1218 : /**
1219 : * Create a SourceSurface for a type of NativeSurface. This may fail if the
1220 : * draw target does not know how to deal with the type of NativeSurface passed
1221 : * in. If this succeeds, the SourceSurface takes the ownersip of the NativeSurface.
1222 : */
1223 : virtual already_AddRefed<SourceSurface>
1224 : CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const = 0;
1225 :
1226 : /**
1227 : * Create a DrawTarget whose snapshot is optimized for use with this DrawTarget.
1228 : */
1229 : virtual already_AddRefed<DrawTarget>
1230 : CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const = 0;
1231 :
1232 : /**
1233 : * Create a DrawTarget that captures the drawing commands and can be replayed
1234 : * onto a compatible DrawTarget afterwards.
1235 : *
1236 : * @param aSize Size of the area this DT will capture.
1237 : */
1238 : virtual already_AddRefed<DrawTargetCapture> CreateCaptureDT(const IntSize& aSize);
1239 :
1240 : /**
1241 : * Create a draw target optimized for drawing a shadow.
1242 : *
1243 : * Note that aSigma is the blur radius that must be used when we draw the
1244 : * shadow. Also note that this doesn't affect the size of the allocated
1245 : * surface, the caller is still responsible for including the shadow area in
1246 : * its size.
1247 : */
1248 : virtual already_AddRefed<DrawTarget>
1249 0 : CreateShadowDrawTarget(const IntSize &aSize, SurfaceFormat aFormat,
1250 : float aSigma) const
1251 : {
1252 0 : return CreateSimilarDrawTarget(aSize, aFormat);
1253 : }
1254 :
1255 : /**
1256 : * Create a path builder with the specified fillmode.
1257 : *
1258 : * We need the fill mode up front because of Direct2D.
1259 : * ID2D1SimplifiedGeometrySink requires the fill mode
1260 : * to be set before calling BeginFigure().
1261 : */
1262 : virtual already_AddRefed<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
1263 :
1264 : /**
1265 : * Create a GradientStops object that holds information about a set of
1266 : * gradient stops, this object is required for linear or radial gradient
1267 : * patterns to represent the color stops in the gradient.
1268 : *
1269 : * @param aStops An array of gradient stops
1270 : * @param aNumStops Number of stops in the array aStops
1271 : * @param aExtendNone This describes how to extend the stop color outside of the
1272 : * gradient area.
1273 : */
1274 : virtual already_AddRefed<GradientStops>
1275 : CreateGradientStops(GradientStop *aStops,
1276 : uint32_t aNumStops,
1277 : ExtendMode aExtendMode = ExtendMode::CLAMP) const = 0;
1278 :
1279 : /**
1280 : * Create a FilterNode object that can be used to apply a filter to various
1281 : * inputs.
1282 : *
1283 : * @param aType Type of filter node to be created.
1284 : */
1285 : virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) = 0;
1286 :
1287 609 : Matrix GetTransform() const { return mTransform; }
1288 :
1289 : /*
1290 : * Get the metrics of a glyph, including any additional spacing that is taken
1291 : * during rasterization to this backends (for example because of antialiasing
1292 : * filters.
1293 : *
1294 : * aScaledFont The scaled font used when drawing.
1295 : * aGlyphIndices An array of indices for the glyphs whose the metrics are wanted
1296 : * aNumGlyphs The amount of elements in aGlyphIndices
1297 : * aGlyphMetrics The glyph metrics
1298 : */
1299 0 : virtual void GetGlyphRasterizationMetrics(ScaledFont *aScaledFont, const uint16_t* aGlyphIndices,
1300 : uint32_t aNumGlyphs, GlyphMetrics* aGlyphMetrics)
1301 : {
1302 0 : aScaledFont->GetGlyphDesignMetrics(aGlyphIndices, aNumGlyphs, aGlyphMetrics);
1303 0 : }
1304 :
1305 : /**
1306 : * Set a transform on the surface, this transform is applied at drawing time
1307 : * to both the mask and source of the operation.
1308 : *
1309 : * Performance note: For some backends it is expensive to change the current
1310 : * transform (because transforms affect a lot of the parts of the pipeline,
1311 : * so new transform change can result in a pipeline flush). To get around
1312 : * this, DrawTarget implementations buffer transform changes and try to only
1313 : * set the current transform on the backend when required. That tracking has
1314 : * its own performance impact though, and ideally callers would be smart
1315 : * enough not to require it. At a future date this method may stop this
1316 : * doing transform buffering so, if you're a consumer, please try to be smart
1317 : * about calling this method as little as possible. For example, instead of
1318 : * concatenating a translation onto the current transform then calling
1319 : * FillRect, try to integrate the translation into FillRect's aRect
1320 : * argument's x/y offset.
1321 : */
1322 0 : virtual void SetTransform(const Matrix &aTransform)
1323 0 : { mTransform = aTransform; mTransformDirty = true; }
1324 :
1325 : inline void ConcatTransform(const Matrix &aTransform)
1326 : { SetTransform(aTransform * Matrix(GetTransform())); }
1327 :
1328 93 : SurfaceFormat GetFormat() const { return mFormat; }
1329 :
1330 : /** Tries to get a native surface for a DrawTarget, this may fail if the
1331 : * draw target cannot convert to this surface type.
1332 : */
1333 0 : virtual void *GetNativeSurface(NativeSurfaceType aType) { return nullptr; }
1334 :
1335 0 : virtual bool IsDualDrawTarget() const { return false; }
1336 0 : virtual bool IsTiledDrawTarget() const { return false; }
1337 33 : virtual bool SupportsRegionClipping() const { return true; }
1338 :
1339 3 : void AddUserData(UserDataKey *key, void *userData, void (*destroy)(void*)) {
1340 3 : mUserData.Add(key, userData, destroy);
1341 3 : }
1342 940 : void *GetUserData(UserDataKey *key) const {
1343 940 : return mUserData.Get(key);
1344 : }
1345 0 : void *RemoveUserData(UserDataKey *key) {
1346 0 : return mUserData.Remove(key);
1347 : }
1348 :
1349 : /** Within this rectangle all pixels will be opaque by the time the result of
1350 : * this DrawTarget is first used for drawing. Either by the underlying surface
1351 : * being used as an input to external drawing, or Snapshot() being called.
1352 : * This rectangle is specified in device space.
1353 : */
1354 4 : void SetOpaqueRect(const IntRect &aRect) {
1355 4 : mOpaqueRect = aRect;
1356 4 : }
1357 :
1358 123 : const IntRect &GetOpaqueRect() const {
1359 123 : return mOpaqueRect;
1360 : }
1361 :
1362 84 : virtual bool IsCurrentGroupOpaque() {
1363 84 : return GetFormat() == SurfaceFormat::B8G8R8X8;
1364 : }
1365 :
1366 242 : virtual void SetPermitSubpixelAA(bool aPermitSubpixelAA) {
1367 242 : mPermitSubpixelAA = aPermitSubpixelAA;
1368 242 : }
1369 :
1370 94 : bool GetPermitSubpixelAA() {
1371 94 : return mPermitSubpixelAA;
1372 : }
1373 :
1374 : /**
1375 : * Ensures that no snapshot is still pointing to this DrawTarget's surface data.
1376 : *
1377 : * This can be useful if the DrawTarget is wrapped around data that it does not
1378 : * own, and for some reason the owner of the data has to make it temporarily
1379 : * unavailable without the DrawTarget knowing about it.
1380 : * This can cause costly surface copies, so it should not be used without a
1381 : * a good reason.
1382 : */
1383 : virtual void DetachAllSnapshots() = 0;
1384 :
1385 : #ifdef USE_SKIA_GPU
1386 0 : virtual bool InitWithGrContext(GrContext* aGrContext,
1387 : const IntSize &aSize,
1388 : SurfaceFormat aFormat)
1389 : {
1390 0 : MOZ_CRASH("GFX: InitWithGrContext");
1391 : }
1392 : #endif
1393 :
1394 : protected:
1395 : UserData mUserData;
1396 : Matrix mTransform;
1397 : IntRect mOpaqueRect;
1398 : bool mTransformDirty : 1;
1399 : bool mPermitSubpixelAA : 1;
1400 :
1401 : SurfaceFormat mFormat;
1402 : };
1403 :
1404 0 : class DrawTargetCapture : public DrawTarget
1405 : {
1406 : public:
1407 0 : virtual bool IsCaptureDT() const { return true; }
1408 :
1409 : /**
1410 : * Returns true if the recording only contains FillGlyph calls with
1411 : * a single font and color. Returns the list of Glyphs along with
1412 : * the font and color as outparams if so.
1413 : */
1414 : virtual bool ContainsOnlyColoredGlyphs(RefPtr<ScaledFont>& aScaledFont,
1415 : Color& aColor,
1416 : std::vector<Glyph>& aGlyphs) = 0;
1417 : };
1418 :
1419 0 : class DrawEventRecorder : public RefCounted<DrawEventRecorder>
1420 : {
1421 : public:
1422 0 : MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
1423 : virtual void Finish() = 0;
1424 0 : virtual ~DrawEventRecorder() { }
1425 : };
1426 :
1427 0 : struct Tile
1428 : {
1429 : RefPtr<DrawTarget> mDrawTarget;
1430 : IntPoint mTileOrigin;
1431 : };
1432 :
1433 : struct TileSet
1434 : {
1435 : Tile* mTiles;
1436 : size_t mTileCount;
1437 : };
1438 :
1439 : struct Config {
1440 : LogForwarder* mLogForwarder;
1441 : int32_t mMaxTextureSize;
1442 : int32_t mMaxAllocSize;
1443 :
1444 3 : Config()
1445 3 : : mLogForwarder(nullptr)
1446 : , mMaxTextureSize(8192)
1447 3 : , mMaxAllocSize(52000000)
1448 3 : {}
1449 : };
1450 :
1451 : class GFX2D_API Factory
1452 : {
1453 : public:
1454 : static void Init(const Config& aConfig);
1455 : static void ShutDown();
1456 :
1457 : static bool HasSSE2();
1458 :
1459 : /**
1460 : * Returns false if any of the following are true:
1461 : *
1462 : * - the width/height of |sz| are less than or equal to zero
1463 : * - the width/height of |sz| are greater than |limit|
1464 : * - the number of bytes that need to be allocated for the surface is too
1465 : * big to fit in an int32_t, or bigger than |allocLimit|, if specifed
1466 : *
1467 : * To calculate the number of bytes that need to be allocated for the surface
1468 : * this function makes the conservative assumption that there need to be
1469 : * 4 bytes-per-pixel, and the stride alignment is 16 bytes.
1470 : *
1471 : * The reason for using int32_t rather than uint32_t is again to be
1472 : * conservative; some code has in the past and may in the future use signed
1473 : * integers to store buffer lengths etc.
1474 : */
1475 : static bool CheckSurfaceSize(const IntSize &sz,
1476 : int32_t limit = 0,
1477 : int32_t allocLimit = 0);
1478 :
1479 : /**
1480 : * Make sure that the given buffer size doesn't exceed the allocation limit.
1481 : */
1482 : static bool CheckBufferSize(int32_t bufSize);
1483 :
1484 : /** Make sure the given dimension satisfies the CheckSurfaceSize and is
1485 : * within 8k limit. The 8k value is chosen a bit randomly.
1486 : */
1487 : static bool ReasonableSurfaceSize(const IntSize &aSize);
1488 :
1489 : static bool AllowedSurfaceSize(const IntSize &aSize);
1490 :
1491 : static already_AddRefed<DrawTarget> CreateDrawTargetForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat* aFormat = nullptr);
1492 :
1493 : static already_AddRefed<SourceSurface> CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface, const IntSize& aSize, SurfaceFormat aFormat);
1494 :
1495 : static already_AddRefed<DrawTarget>
1496 : CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
1497 :
1498 : static already_AddRefed<DrawTarget>
1499 : CreateWrapAndRecordDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT);
1500 :
1501 : static already_AddRefed<DrawTarget>
1502 : CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT, IntSize aSize);
1503 :
1504 : static already_AddRefed<DrawTarget>
1505 : CreateDrawTargetForData(BackendType aBackend, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat, bool aUninitialized = false);
1506 :
1507 : static already_AddRefed<ScaledFont>
1508 : CreateScaledFontForNativeFont(const NativeFont &aNativeFont,
1509 : const RefPtr<UnscaledFont>& aUnscaledFont,
1510 : Float aSize);
1511 :
1512 : #ifdef MOZ_WIDGET_GTK
1513 : static already_AddRefed<ScaledFont>
1514 : CreateScaledFontForFontconfigFont(cairo_scaled_font_t* aScaledFont, FcPattern* aPattern,
1515 : const RefPtr<UnscaledFont>& aUnscaledFont, Float aSize);
1516 : #endif
1517 :
1518 : /**
1519 : * This creates a NativeFontResource from TrueType data.
1520 : *
1521 : * @param aData Pointer to the data
1522 : * @param aSize Size of the TrueType data
1523 : * @param aBackendType Type of the reference DrawTarget the font should be created for.
1524 : * @param aFontType Type of NativeFontResource that should be created.
1525 : * @param aFontContext Optional native font context to be used to create the NativeFontResource.
1526 : * @return a NativeFontResource of nullptr if failed.
1527 : */
1528 : static already_AddRefed<NativeFontResource>
1529 : CreateNativeFontResource(uint8_t *aData, uint32_t aSize, BackendType aBackendType, FontType aFontType, void* aFontContext = nullptr);
1530 :
1531 : /**
1532 : * This creates an unscaled font of the given type based on font descriptor
1533 : * data retrieved from ScaledFont::GetFontDescriptor.
1534 : */
1535 : static already_AddRefed<UnscaledFont>
1536 : CreateUnscaledFontFromFontDescriptor(FontType aType, const uint8_t* aData, uint32_t aDataLength);
1537 :
1538 : /**
1539 : * This creates a scaled font with an associated cairo_scaled_font_t, and
1540 : * must be used when using the Cairo backend. The NativeFont and
1541 : * cairo_scaled_font_t* parameters must correspond to the same font.
1542 : */
1543 : static already_AddRefed<ScaledFont>
1544 : CreateScaledFontWithCairo(const NativeFont &aNativeFont,
1545 : const RefPtr<UnscaledFont>& aUnscaledFont,
1546 : Float aSize,
1547 : cairo_scaled_font_t* aScaledFont);
1548 :
1549 : /**
1550 : * This creates a simple data source surface for a certain size. It allocates
1551 : * new memory for the surface. This memory is freed when the surface is
1552 : * destroyed. The caller is responsible for handing the case where nullptr
1553 : * is returned. The surface is not zeroed unless requested.
1554 : */
1555 : static already_AddRefed<DataSourceSurface>
1556 : CreateDataSourceSurface(const IntSize &aSize, SurfaceFormat aFormat, bool aZero = false);
1557 :
1558 : /**
1559 : * This creates a simple data source surface for a certain size with a
1560 : * specific stride, which must be large enough to fit all pixels.
1561 : * It allocates new memory for the surface. This memory is freed when
1562 : * the surface is destroyed. The caller is responsible for handling the case
1563 : * where nullptr is returned. The surface is not zeroed unless requested.
1564 : */
1565 : static already_AddRefed<DataSourceSurface>
1566 : CreateDataSourceSurfaceWithStride(const IntSize &aSize, SurfaceFormat aFormat, int32_t aStride, bool aZero = false);
1567 :
1568 : typedef void (*SourceSurfaceDeallocator)(void* aClosure);
1569 :
1570 : /**
1571 : * This creates a simple data source surface for some existing data. It will
1572 : * wrap this data and the data for this source surface.
1573 : *
1574 : * We can provide a custom destroying function for |aData|. This will be
1575 : * called in the surface dtor using |aDeallocator| and the |aClosure|. If
1576 : * there are errors during construction(return a nullptr surface), the caller
1577 : * is responsible for the deallocation.
1578 : *
1579 : * If there is no destroying function, the caller is responsible for
1580 : * deallocating the aData memory only after destruction of this
1581 : * DataSourceSurface.
1582 : */
1583 : static already_AddRefed<DataSourceSurface>
1584 : CreateWrappingDataSourceSurface(uint8_t *aData,
1585 : int32_t aStride,
1586 : const IntSize &aSize,
1587 : SurfaceFormat aFormat,
1588 : SourceSurfaceDeallocator aDeallocator = nullptr,
1589 : void* aClosure = nullptr);
1590 :
1591 : static void
1592 : CopyDataSourceSurface(DataSourceSurface* aSource,
1593 : DataSourceSurface* aDest);
1594 :
1595 :
1596 : static already_AddRefed<DrawEventRecorder>
1597 : CreateEventRecorderForFile(const char *aFilename);
1598 :
1599 : static void SetGlobalEventRecorder(DrawEventRecorder *aRecorder);
1600 :
1601 : static uint32_t GetMaxSurfaceSize(BackendType aType);
1602 :
1603 0 : static LogForwarder* GetLogForwarder() { return sConfig ? sConfig->mLogForwarder : nullptr; }
1604 :
1605 : private:
1606 : static Config* sConfig;
1607 : public:
1608 :
1609 : #ifdef USE_SKIA_GPU
1610 : static already_AddRefed<DrawTarget>
1611 : CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
1612 : const IntSize &aSize,
1613 : SurfaceFormat aFormat);
1614 : #endif
1615 :
1616 : static void PurgeAllCaches();
1617 :
1618 : static already_AddRefed<DrawTarget>
1619 : CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB);
1620 :
1621 : /*
1622 : * This creates a new tiled DrawTarget. When a tiled drawtarget is used the
1623 : * drawing is distributed over number of tiles which may each hold an
1624 : * individual offset. The tiles in the set must each have the same backend
1625 : * and format.
1626 : */
1627 : static already_AddRefed<DrawTarget> CreateTiledDrawTarget(const TileSet& aTileSet);
1628 :
1629 : static bool DoesBackendSupportDataDrawtarget(BackendType aType);
1630 :
1631 : #ifdef USE_SKIA
1632 : static already_AddRefed<DrawTarget> CreateDrawTargetWithSkCanvas(SkCanvas* aCanvas);
1633 : #endif
1634 :
1635 : #ifdef XP_DARWIN
1636 : static already_AddRefed<GlyphRenderingOptions>
1637 : CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor);
1638 : #endif
1639 :
1640 : #ifdef MOZ_ENABLE_FREETYPE
1641 : static void SetFTLibrary(FT_Library aFTLibrary);
1642 : static FT_Library GetFTLibrary();
1643 :
1644 : static FT_Library NewFTLibrary();
1645 : static void ReleaseFTLibrary(FT_Library aFTLibrary);
1646 :
1647 : static FT_Face NewFTFace(FT_Library aFTLibrary, const char* aFileName, int aFaceIndex);
1648 : static FT_Face NewFTFaceFromData(FT_Library aFTLibrary, const uint8_t* aData, size_t aDataSize, int aFaceIndex);
1649 : static void ReleaseFTFace(FT_Face aFace);
1650 :
1651 : private:
1652 : static FT_Library mFTLibrary;
1653 : static Mutex* mFTLock;
1654 : public:
1655 : #endif
1656 :
1657 : #ifdef WIN32
1658 : static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
1659 :
1660 : /*
1661 : * Attempts to create and install a D2D1 device from the supplied Direct3D11 device.
1662 : * Returns true on success, or false on failure and leaves the D2D1/Direct3D11 devices unset.
1663 : */
1664 : static bool SetDirect3D11Device(ID3D11Device *aDevice);
1665 : static ID3D11Device *GetDirect3D11Device();
1666 : static ID2D1Device *GetD2D1Device();
1667 : static uint32_t GetD2D1DeviceSeq();
1668 : static IDWriteFactory *GetDWriteFactory();
1669 : static IDWriteFactory* EnsureDWriteFactory();
1670 : static bool SupportsD2D1();
1671 :
1672 : static uint64_t GetD2DVRAMUsageDrawTarget();
1673 : static uint64_t GetD2DVRAMUsageSourceSurface();
1674 : static void D2DCleanup();
1675 :
1676 : static already_AddRefed<ScaledFont>
1677 : CreateScaledFontForDWriteFont(IDWriteFontFace* aFontFace,
1678 : const gfxFontStyle* aStyle,
1679 : const RefPtr<UnscaledFont>& aUnscaledFont,
1680 : Float aSize,
1681 : bool aUseEmbeddedBitmap,
1682 : bool aForceGDIMode,
1683 : IDWriteRenderingParams *aParams,
1684 : Float aGamma,
1685 : Float aContrast);
1686 :
1687 : static void UpdateSystemTextQuality();
1688 :
1689 : private:
1690 : static ID2D1Device *mD2D1Device;
1691 : static ID3D11Device *mD3D11Device;
1692 : static IDWriteFactory *mDWriteFactory;
1693 : static bool mDWriteFactoryInitialized;
1694 : static Mutex* mDWriteFactoryLock;
1695 : #endif
1696 :
1697 : static DrawEventRecorder *mRecorder;
1698 : };
1699 :
1700 : } // namespace gfx
1701 : } // namespace mozilla
1702 :
1703 : #endif // _MOZILLA_GFX_2D_H
|