зеркало из https://github.com/mozilla/pjs.git
Bug 716802 - Implement new 2D API functions. r=gwright
This commit is contained in:
Родитель
92e358da8e
Коммит
f00139a76c
|
@ -65,8 +65,9 @@ SkColor ColorToSkColor(const Color &color, Float aAlpha)
|
|||
class GradientStopsSkia : public GradientStops
|
||||
{
|
||||
public:
|
||||
GradientStopsSkia(const std::vector<GradientStop>& aStops, uint32_t aNumStops)
|
||||
GradientStopsSkia(const std::vector<GradientStop>& aStops, uint32_t aNumStops, ExtendMode aExtendMode)
|
||||
: mCount(aNumStops)
|
||||
, mExtendMode(aExtendMode)
|
||||
{
|
||||
if (mCount == 0) {
|
||||
return;
|
||||
|
@ -103,6 +104,7 @@ public:
|
|||
std::vector<SkColor> mColors;
|
||||
std::vector<SkScalar> mPositions;
|
||||
int mCount;
|
||||
ExtendMode mExtendMode;
|
||||
};
|
||||
|
||||
SkXfermode::Mode
|
||||
|
@ -208,12 +210,89 @@ ExtendModeToTileMode(ExtendMode aMode)
|
|||
return SkShader::kClamp_TileMode;
|
||||
}
|
||||
|
||||
void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0)
|
||||
{
|
||||
switch (aPattern.GetType()) {
|
||||
case PATTERN_COLOR: {
|
||||
Color color = static_cast<const ColorPattern&>(aPattern).mColor;
|
||||
aPaint.setColor(ColorToSkColor(color, aAlpha));
|
||||
break;
|
||||
}
|
||||
case PATTERN_LINEAR_GRADIENT: {
|
||||
const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
|
||||
GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
|
||||
SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);
|
||||
|
||||
if (stops->mCount >= 2) {
|
||||
SkPoint points[2];
|
||||
points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y));
|
||||
points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y));
|
||||
|
||||
SkShader* shader = SkGradientShader::CreateLinear(points,
|
||||
&stops->mColors.front(),
|
||||
&stops->mPositions.front(),
|
||||
stops->mCount,
|
||||
mode);
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
|
||||
shader->setLocalMatrix(mat);
|
||||
SkSafeUnref(aPaint.setShader(shader));
|
||||
} else {
|
||||
aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PATTERN_RADIAL_GRADIENT: {
|
||||
const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
|
||||
GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
|
||||
SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);
|
||||
|
||||
if (stops->mCount >= 2) {
|
||||
SkPoint points[2];
|
||||
points[0] = SkPoint::Make(SkFloatToScalar(pat.mCenter1.x), SkFloatToScalar(pat.mCenter1.y));
|
||||
points[1] = SkPoint::Make(SkFloatToScalar(pat.mCenter2.x), SkFloatToScalar(pat.mCenter2.y));
|
||||
|
||||
SkShader* shader = SkGradientShader::CreateTwoPointRadial(points[0],
|
||||
SkFloatToScalar(pat.mRadius1),
|
||||
points[1],
|
||||
SkFloatToScalar(pat.mRadius2),
|
||||
&stops->mColors.front(),
|
||||
&stops->mPositions.front(),
|
||||
stops->mCount,
|
||||
mode);
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
|
||||
shader->setLocalMatrix(mat);
|
||||
SkSafeUnref(aPaint.setShader(shader));
|
||||
} else {
|
||||
aPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PATTERN_SURFACE: {
|
||||
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
|
||||
const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(pat.mSurface.get())->GetBitmap();
|
||||
|
||||
SkShader::TileMode mode = ExtendModeToTileMode(pat.mExtendMode);
|
||||
SkShader* shader = SkShader::CreateBitmapShader(bitmap, mode, mode);
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
|
||||
shader->setLocalMatrix(mat);
|
||||
SkSafeUnref(aPaint.setShader(shader));
|
||||
if (pat.mFilter == FILTER_POINT) {
|
||||
aPaint.setFilterBitmap(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AutoPaintSetup {
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern)
|
||||
: mNeedsRestore(false), mAlpha(1.0)
|
||||
{
|
||||
Init(aCanvas, aOptions);
|
||||
SetPattern(aPattern);
|
||||
SetPaintPattern(mPaint, aPattern, mAlpha);
|
||||
}
|
||||
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions)
|
||||
|
@ -261,60 +340,6 @@ struct AutoPaintSetup {
|
|||
mPaint.setFilterBitmap(true);
|
||||
}
|
||||
|
||||
void SetPattern(const Pattern& aPattern)
|
||||
{
|
||||
if (aPattern.GetType() == PATTERN_COLOR) {
|
||||
Color color = static_cast<const ColorPattern&>(aPattern).mColor;
|
||||
mPaint.setColor(ColorToSkColor(color, mAlpha));
|
||||
} else if (aPattern.GetType() == PATTERN_LINEAR_GRADIENT) {
|
||||
const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
|
||||
GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
|
||||
|
||||
if (stops->mCount >= 2) {
|
||||
SkPoint points[2];
|
||||
points[0] = SkPoint::Make(SkFloatToScalar(pat.mBegin.x), SkFloatToScalar(pat.mBegin.y));
|
||||
points[1] = SkPoint::Make(SkFloatToScalar(pat.mEnd.x), SkFloatToScalar(pat.mEnd.y));
|
||||
|
||||
SkShader* shader = SkGradientShader::CreateLinear(points,
|
||||
&stops->mColors.front(),
|
||||
&stops->mPositions.front(),
|
||||
stops->mCount,
|
||||
SkShader::kClamp_TileMode);
|
||||
SkSafeUnref(mPaint.setShader(shader));
|
||||
} else {
|
||||
mPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
|
||||
}
|
||||
} else if (aPattern.GetType() == PATTERN_RADIAL_GRADIENT) {
|
||||
const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
|
||||
GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
|
||||
|
||||
if (stops->mCount >= 2) {
|
||||
SkPoint points[2];
|
||||
points[0] = SkPoint::Make(SkFloatToScalar(pat.mCenter1.x), SkFloatToScalar(pat.mCenter1.y));
|
||||
points[1] = SkPoint::Make(SkFloatToScalar(pat.mCenter2.x), SkFloatToScalar(pat.mCenter2.y));
|
||||
|
||||
SkShader* shader = SkGradientShader::CreateTwoPointRadial(points[0],
|
||||
SkFloatToScalar(pat.mRadius1),
|
||||
points[1],
|
||||
SkFloatToScalar(pat.mRadius2),
|
||||
&stops->mColors.front(),
|
||||
&stops->mPositions.front(),
|
||||
stops->mCount,
|
||||
SkShader::kClamp_TileMode);
|
||||
SkSafeUnref(mPaint.setShader(shader));
|
||||
} else {
|
||||
mPaint.setColor(SkColorSetARGB(0, 0, 0, 0));
|
||||
}
|
||||
} else {
|
||||
const SurfacePattern& pat = static_cast<const SurfacePattern&>(aPattern);
|
||||
const SkBitmap& bitmap = static_cast<SourceSurfaceSkia*>(pat.mSurface.get())->GetBitmap();
|
||||
|
||||
SkShader::TileMode mode = ExtendModeToTileMode(pat.mExtendMode);
|
||||
SkShader* shader = SkShader::CreateBitmapShader(bitmap, mode, mode);
|
||||
SkSafeUnref(mPaint.setShader(shader));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Maybe add an operator overload to access this easier?
|
||||
SkPaint mPaint;
|
||||
bool mNeedsRestore;
|
||||
|
@ -542,6 +567,36 @@ DrawTargetSkia::FillGlyphs(ScaledFont *aFont,
|
|||
mCanvas->drawPosText(&indices.front(), aBuffer.mNumGlyphs*2, &offsets.front(), paint.mPaint);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource);
|
||||
|
||||
SkPaint maskPaint;
|
||||
SetPaintPattern(maskPaint, aMask);
|
||||
|
||||
SkLayerRasterizer *raster = new SkLayerRasterizer();
|
||||
raster->addLayer(maskPaint);
|
||||
SkSafeUnref(paint.mPaint.setRasterizer(raster));
|
||||
|
||||
// Skia only uses the mask rasterizer when we are drawing a path/rect.
|
||||
// Take our destination bounds and convert them into user space to use
|
||||
// as the path to draw.
|
||||
SkPath path;
|
||||
path.addRect(SkRect::MakeWH(mSize.width, mSize.height));
|
||||
|
||||
Matrix temp = mTransform;
|
||||
temp.Invert();
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(temp, mat);
|
||||
path.transform(mat);
|
||||
|
||||
mCanvas->drawPath(path, paint.mPaint);
|
||||
}
|
||||
|
||||
TemporaryRef<SourceSurface>
|
||||
DrawTargetSkia::CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
|
@ -624,6 +679,21 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
|
||||
{
|
||||
mBitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
|
||||
mBitmap.setPixels(aData);
|
||||
|
||||
SkAutoTUnref<SkDevice> device(new SkDevice(mBitmap));
|
||||
SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
|
||||
mSize = aSize;
|
||||
|
||||
mDevice = device.get();
|
||||
mCanvas = canvas.get();
|
||||
mFormat = aFormat;
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::SetTransform(const Matrix& aTransform)
|
||||
{
|
||||
|
@ -665,6 +735,15 @@ DrawTargetSkia::PushClip(const Path *aPath)
|
|||
mCanvas->clipPath(skiaPath->GetPath());
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::PushClipRect(const Rect& aRect)
|
||||
{
|
||||
SkRect rect = RectToSkRect(aRect);
|
||||
|
||||
mCanvas->save(SkCanvas::kClip_SaveFlag);
|
||||
mCanvas->clipRect(rect);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::PopClip()
|
||||
{
|
||||
|
@ -681,7 +760,7 @@ DrawTargetSkia::CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, Ex
|
|||
}
|
||||
std::stable_sort(stops.begin(), stops.end());
|
||||
|
||||
return new GradientStopsSkia(stops, aNumStops);
|
||||
return new GradientStopsSkia(stops, aNumStops, aExtendMode);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -101,10 +101,9 @@ public:
|
|||
const DrawOptions &aOptions = DrawOptions());
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions())
|
||||
{ return; }
|
||||
const DrawOptions &aOptions = DrawOptions());
|
||||
virtual void PushClip(const Path *aPath);
|
||||
virtual void PushClipRect(const Rect &aRect) { }
|
||||
virtual void PushClipRect(const Rect& aRect);
|
||||
virtual void PopClip();
|
||||
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
|
@ -120,6 +119,7 @@ public:
|
|||
virtual void SetTransform(const Matrix &aTransform);
|
||||
|
||||
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
|
||||
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
|
||||
|
||||
operator std::string() const {
|
||||
std::stringstream stream;
|
||||
|
@ -138,7 +138,6 @@ private:
|
|||
SkRefPtr<SkCanvas> mCanvas;
|
||||
SkRefPtr<SkDevice> mDevice;
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
SurfaceFormat mFormat;
|
||||
vector<SourceSurfaceSkia*> mSnapshots;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче