/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef _MOZILLA_GFX_2D_H #define _MOZILLA_GFX_2D_H #include "Types.h" #include "Point.h" #include "Rect.h" #include "Matrix.h" #include "Quaternion.h" #include "UserData.h" #include "FontVariation.h" #include // GenericRefCountedBase allows us to hold on to refcounted objects of any type // (contrary to RefCounted which requires knowing the type T) and, in // particular, without having a dependency on that type. This is used for // DrawTargetSkia to be able to hold on to a GLContext. #include "mozilla/GenericRefCounted.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Path.h" // This RefPtr class isn't ideal for usage in Azure, as it doesn't allow T** // outparams using the &-operator. But it will have to do as there's no easy // solution. #include "mozilla/RefPtr.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPtr.h" #include "mozilla/ThreadSafeWeakPtr.h" #include "mozilla/Atomics.h" #include "mozilla/DebugOnly.h" #include "nsRegionFwd.h" #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GTK) # ifndef MOZ_ENABLE_FREETYPE # define MOZ_ENABLE_FREETYPE # endif #endif struct _cairo_surface; typedef _cairo_surface cairo_surface_t; struct _cairo_scaled_font; typedef _cairo_scaled_font cairo_scaled_font_t; struct FT_LibraryRec_; typedef FT_LibraryRec_* FT_Library; struct FT_FaceRec_; typedef FT_FaceRec_* FT_Face; typedef int FT_Error; struct _FcPattern; typedef _FcPattern FcPattern; struct ID3D11Texture2D; struct ID3D11Device; struct ID2D1Device; struct ID2D1DeviceContext; struct ID2D1Multithread; struct IDWriteFactory; struct IDWriteRenderingParams; struct IDWriteFontFace; struct IDWriteFontCollection; class SkCanvas; struct gfxFontStyle; struct CGContext; typedef struct CGContext* CGContextRef; struct CGFont; typedef CGFont* CGFontRef; namespace mozilla { class Mutex; namespace layers { class TextureData; } namespace wr { struct FontInstanceOptions; struct FontInstancePlatformOptions; } // namespace wr namespace gfx { class UnscaledFont; class ScaledFont; } // namespace gfx namespace gfx { class AlphaBoxBlur; class ScaledFont; class SourceSurface; class DataSourceSurface; class DrawTarget; class DrawEventRecorder; class FilterNode; class LogForwarder; struct NativeSurface { NativeSurfaceType mType; SurfaceFormat mFormat; gfx::IntSize mSize; void* mSurface; }; /** * This structure is used to send draw options that are universal to all drawing * operations. */ struct DrawOptions { /// For constructor parameter description, see member data documentation. explicit DrawOptions(Float aAlpha = 1.0f, CompositionOp aCompositionOp = CompositionOp::OP_OVER, AntialiasMode aAntialiasMode = AntialiasMode::DEFAULT) : mAlpha(aAlpha), mCompositionOp(aCompositionOp), mAntialiasMode(aAntialiasMode) {} Float mAlpha; /**< Alpha value by which the mask generated by this operation is multiplied. */ CompositionOp mCompositionOp; /**< The operator that indicates how the source and destination patterns are blended. */ AntialiasMode mAntialiasMode; /**< The AntiAlias mode used for this drawing operation. */ }; struct StoredStrokeOptions; /** * This structure is used to send stroke options that are used in stroking * operations. */ struct StrokeOptions { /// For constructor parameter description, see member data documentation. explicit StrokeOptions(Float aLineWidth = 1.0f, JoinStyle aLineJoin = JoinStyle::MITER_OR_BEVEL, CapStyle aLineCap = CapStyle::BUTT, Float aMiterLimit = 10.0f, size_t aDashLength = 0, const Float* aDashPattern = 0, Float aDashOffset = 0.f) : mLineWidth(aLineWidth), mMiterLimit(aMiterLimit), mDashPattern(aDashLength > 0 ? aDashPattern : 0), mDashLength(aDashLength), mDashOffset(aDashOffset), mLineJoin(aLineJoin), mLineCap(aLineCap) { MOZ_ASSERT(aDashLength == 0 || aDashPattern); } Float mLineWidth; //!< Width of the stroke in userspace. Float mMiterLimit; //!< Miter limit in units of linewidth const Float* mDashPattern; /**< Series of on/off userspace lengths defining dash. Owned by the caller; must live at least as long as this StrokeOptions. mDashPattern != null <=> mDashLength > 0. */ size_t mDashLength; //!< Number of on/off lengths in mDashPattern. Float mDashOffset; /**< Userspace offset within mDashPattern at which stroking begins. */ JoinStyle mLineJoin; //!< Join style used for joining lines. CapStyle mLineCap; //!< Cap style used for capping lines. StoredStrokeOptions* Clone() const; bool operator==(const StrokeOptions& aOther) const { return mLineWidth == aOther.mLineWidth && mMiterLimit == aOther.mMiterLimit && mDashLength == aOther.mDashLength && (!mDashLength || (mDashPattern && aOther.mDashPattern && !memcmp(mDashPattern, aOther.mDashPattern, mDashLength * sizeof(Float)))) && mDashOffset == aOther.mDashOffset && mLineJoin == aOther.mLineJoin && mLineCap == aOther.mLineCap; } }; /** * Heap-allocated variation of StrokeOptions that ensures dash patterns are * properly allocated and destroyed even if the source was stack-allocated. */ struct StoredStrokeOptions : public StrokeOptions { explicit StoredStrokeOptions(const StrokeOptions& aOptions) : StrokeOptions(aOptions) { if (mDashLength) { Float* pattern = new Float[mDashLength]; memcpy(pattern, mDashPattern, mDashLength * sizeof(Float)); mDashPattern = pattern; } } ~StoredStrokeOptions() { if (mDashPattern) { delete[] mDashPattern; } } }; inline StoredStrokeOptions* StrokeOptions::Clone() const { return new StoredStrokeOptions(*this); } /** * This structure supplies additional options for calls to DrawSurface. */ struct DrawSurfaceOptions { /// For constructor parameter description, see member data documentation. explicit DrawSurfaceOptions( SamplingFilter aSamplingFilter = SamplingFilter::LINEAR, SamplingBounds aSamplingBounds = SamplingBounds::UNBOUNDED) : mSamplingFilter(aSamplingFilter), mSamplingBounds(aSamplingBounds) {} SamplingFilter mSamplingFilter; /**< SamplingFilter used when resampling source surface region to the destination region. */ SamplingBounds mSamplingBounds; /**< This indicates whether the implementation is allowed to sample pixels outside the source rectangle as specified in DrawSurface on the surface. */ }; /** * ShadowOptions supplies options necessary for describing the appearance of a * a shadow in draw calls that use shadowing. */ struct ShadowOptions { explicit ShadowOptions(const DeviceColor& aColor = DeviceColor(0.0f, 0.0f, 0.0f), const Point& aOffset = Point(), Float aSigma = 0.0f) : mColor(aColor), mOffset(aOffset), mSigma(aSigma) {} DeviceColor mColor; /**< Color of the drawn shadow. */ Point mOffset; /**< Offset of the shadow. */ Float mSigma; /**< Sigma used for the Gaussian filter kernel. */ int32_t BlurRadius() const; }; /** * This class is used to store gradient stops, it can only be used with a * matching DrawTarget. Not adhering to this condition will make a draw call * fail. */ class GradientStops : public SupportsThreadSafeWeakPtr { public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops) virtual ~GradientStops() = default; virtual BackendType GetBackendType() const = 0; virtual bool IsValid() const { return true; } protected: GradientStops() = default; }; /** * This is the base class for 'patterns'. Patterns describe the pixels used as * the source for a masked composition operation that is done by the different * drawing commands. These objects are not backend specific, however for * example the gradient stops on a gradient pattern can be backend specific. */ class Pattern { public: virtual ~Pattern() = default; virtual PatternType GetType() const = 0; /** Instantiate a new clone with the same pattern type and values. Any * internal strong references will be converted to weak references. */ virtual Pattern* CloneWeak() const { return nullptr; } /** Whether the pattern holds an internal weak reference. */ virtual bool IsWeak() const { return false; } /** Whether any internal weak references still point to a target. */ virtual bool IsValid() const { return true; } /** Determine if the pattern type and values exactly match. */ virtual bool operator==(const Pattern& aOther) const = 0; bool operator!=(const Pattern& aOther) const { return !(*this == aOther); } protected: Pattern() = default; // Utility functions to check if a weak reference is still valid. template static inline bool IsRefValid(const RefPtr& aPtr) { // RefPtrs are always valid. return true; } template static inline bool IsRefValid(const ThreadSafeWeakPtr& aPtr) { // Weak refs are only valid if they aren't dead. return !aPtr.IsDead(); } }; class ColorPattern : public Pattern { public: // Explicit because consumers should generally use ToDeviceColor when // creating a ColorPattern. explicit ColorPattern(const DeviceColor& aColor) : mColor(aColor) {} PatternType GetType() const override { return PatternType::COLOR; } Pattern* CloneWeak() const override { return new ColorPattern(mColor); } bool operator==(const Pattern& aOther) const override { if (aOther.GetType() != PatternType::COLOR) { return false; } const ColorPattern& other = static_cast(aOther); return mColor == other.mColor; } DeviceColor mColor; }; /** * This class is used for Linear Gradient Patterns, the gradient stops are * stored in a separate object and are backend dependent. This class itself * may be used on the stack. */ template