From 85f09693e0cd9cb38d390b70ee42afbb2760eb7a Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 10 Jun 2015 19:57:08 +0200 Subject: [PATCH] Bug 1083101 - Part 3: Extend DrawCommand storage functionality and fix a bug with dashed stroke patterns. r=jrmuizel --- gfx/2d/DrawCommand.h | 88 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/gfx/2d/DrawCommand.h b/gfx/2d/DrawCommand.h index bad569c8b0c0..76ae32f8dfc1 100644 --- a/gfx/2d/DrawCommand.h +++ b/gfx/2d/DrawCommand.h @@ -6,6 +6,10 @@ #ifndef MOZILLA_GFX_DRAWCOMMAND_H_ #define MOZILLA_GFX_DRAWCOMMAND_H_ + +#define _USE_MATH_DEFINES +#include + #include "2D.h" #include "Filters.h" #include @@ -31,7 +35,8 @@ enum class CommandType : int8_t { PUSHCLIP, PUSHCLIPRECT, POPCLIP, - SETTRANSFORM + SETTRANSFORM, + FLUSH }; class DrawingCommand @@ -41,6 +46,8 @@ public: virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix* aTransform = nullptr) = 0; + virtual bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) { return false; } + protected: explicit DrawingCommand(CommandType aType) : mType(aType) @@ -231,6 +238,12 @@ public: aDT->FillRect(mRect, mPattern, mOptions); } + bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) + { + aDeviceRect = aTransform.TransformBounds(mRect); + return true; + } + private: Rect mRect; StoredPattern mPattern; @@ -250,6 +263,11 @@ public: , mStrokeOptions(aStrokeOptions) , mOptions(aOptions) { + if (aStrokeOptions.mDashLength) { + mDashes.resize(aStrokeOptions.mDashLength); + mStrokeOptions.mDashPattern = &mDashes.front(); + memcpy(&mDashes.front(), aStrokeOptions.mDashPattern, mStrokeOptions.mDashLength * sizeof(Float)); + } } virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) @@ -262,6 +280,7 @@ private: StoredPattern mPattern; StrokeOptions mStrokeOptions; DrawOptions mOptions; + std::vector mDashes; }; class StrokeLineCommand : public DrawingCommand @@ -312,12 +331,53 @@ public: aDT->Fill(mPath, mPattern, mOptions); } + bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) + { + aDeviceRect = mPath->GetBounds(aTransform); + return true; + } + private: RefPtr mPath; StoredPattern mPattern; DrawOptions mOptions; }; +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 +#endif + +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.707106781186547524400844362104849039 +#endif + +// The logic for this comes from _cairo_stroke_style_max_distance_from_path +static Rect +PathExtentsToMaxStrokeExtents(const StrokeOptions &aStrokeOptions, + const Rect &aRect, + const Matrix &aTransform) +{ + double styleExpansionFactor = 0.5f; + + if (aStrokeOptions.mLineCap == CapStyle::SQUARE) { + styleExpansionFactor = M_SQRT1_2; + } + + if (aStrokeOptions.mLineJoin == JoinStyle::MITER && + styleExpansionFactor < M_SQRT2 * aStrokeOptions.mMiterLimit) { + styleExpansionFactor = M_SQRT2 * aStrokeOptions.mMiterLimit; + } + + styleExpansionFactor *= aStrokeOptions.mLineWidth; + + double dx = styleExpansionFactor * hypot(aTransform._11, aTransform._21); + double dy = styleExpansionFactor * hypot(aTransform._22, aTransform._12); + + Rect result = aRect; + result.Inflate(dx, dy); + return result; +} + class StrokeCommand : public DrawingCommand { public: @@ -331,6 +391,11 @@ public: , mStrokeOptions(aStrokeOptions) , mOptions(aOptions) { + if (aStrokeOptions.mDashLength) { + mDashes.resize(aStrokeOptions.mDashLength); + mStrokeOptions.mDashPattern = &mDashes.front(); + memcpy(&mDashes.front(), aStrokeOptions.mDashPattern, mStrokeOptions.mDashLength * sizeof(Float)); + } } virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) @@ -338,11 +403,18 @@ public: aDT->Stroke(mPath, mPattern, mStrokeOptions, mOptions); } + bool GetAffectedRect(Rect& aDeviceRect, const Matrix& aTransform) + { + aDeviceRect = PathExtentsToMaxStrokeExtents(mStrokeOptions, mPath->GetBounds(aTransform), aTransform); + return true; + } + private: RefPtr mPath; StoredPattern mPattern; StrokeOptions mStrokeOptions; DrawOptions mOptions; + std::vector mDashes; }; class FillGlyphsCommand : public DrawingCommand @@ -502,6 +574,20 @@ private: Matrix mTransform; }; +class FlushCommand : public DrawingCommand +{ +public: + explicit FlushCommand() + : DrawingCommand(CommandType::FLUSH) + { + } + + virtual void ExecuteOnDT(DrawTarget* aDT, const Matrix*) + { + aDT->Flush(); + } +}; + } // namespace gfx } // namespace mozilla