Bug 1083101 - Extend DrawCommand storage functionality and fix a bug with dashed stroke patterns. r=jrmuizel

This commit is contained in:
Nicolas Silva 2015-06-10 19:57:08 +02:00
Родитель 9a89fcdfb3
Коммит c41df579c1
1 изменённых файлов: 87 добавлений и 1 удалений

Просмотреть файл

@ -6,6 +6,10 @@
#ifndef MOZILLA_GFX_DRAWCOMMAND_H_
#define MOZILLA_GFX_DRAWCOMMAND_H_
#define _USE_MATH_DEFINES
#include <math.h>
#include "2D.h"
#include "Filters.h"
#include <vector>
@ -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<Float> 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<Path> 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<Path> mPath;
StoredPattern mPattern;
StrokeOptions mStrokeOptions;
DrawOptions mOptions;
std::vector<Float> 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