summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/skia
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2009-08-11 17:01:47 +0100
committerBen Murdoch <benm@google.com>2009-08-11 18:21:02 +0100
commit0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5 (patch)
tree2943df35f62d885c89d01063cc528dd73b480fea /WebCore/platform/graphics/skia
parent7e7a70bfa49a1122b2597a1e6367d89eb4035eca (diff)
downloadexternal_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.zip
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.gz
external_webkit-0bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5.tar.bz2
Merge in WebKit r47029.
Diffstat (limited to 'WebCore/platform/graphics/skia')
-rw-r--r--WebCore/platform/graphics/skia/GradientSkia.cpp16
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h2
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp109
-rw-r--r--WebCore/platform/graphics/skia/ImageBufferSkia.cpp22
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp6
-rw-r--r--WebCore/platform/graphics/skia/ImageSourceSkia.cpp33
-rw-r--r--WebCore/platform/graphics/skia/ImageSourceSkia.h60
-rw-r--r--WebCore/platform/graphics/skia/PathSkia.cpp21
-rw-r--r--WebCore/platform/graphics/skia/PatternSkia.cpp8
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp120
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h8
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.cpp24
-rw-r--r--WebCore/platform/graphics/skia/SkiaUtils.cpp52
-rw-r--r--WebCore/platform/graphics/skia/SkiaUtils.h8
14 files changed, 244 insertions, 245 deletions
diff --git a/WebCore/platform/graphics/skia/GradientSkia.cpp b/WebCore/platform/graphics/skia/GradientSkia.cpp
index ac7366c..3bdddb2 100644
--- a/WebCore/platform/graphics/skia/GradientSkia.cpp
+++ b/WebCore/platform/graphics/skia/GradientSkia.cpp
@@ -158,15 +158,21 @@ SkShader* Gradient::platformGradient()
// circle" (m_p1/m_r1).
// See http://webkit.org/blog/175/introducing-css-gradients/ for a
// description of the expected behavior.
+
+ // The radius we give to Skia must be positive (and non-zero). If
+ // we're given a zero radius, just ask for a very small radius so
+ // Skia will still return an object.
+ SkScalar radius = m_r1 > 0 ? WebCoreFloatToSkScalar(m_r1) : SK_ScalarMin;
m_gradient = SkGradientShader::CreateRadial(m_p1,
- WebCoreFloatToSkScalar(m_r1), colors, pos,
- static_cast<int>(countUsed), tile);
+ radius, colors, pos, static_cast<int>(countUsed), tile);
} else {
SkPoint pts[2] = { m_p0, m_p1 };
m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
static_cast<int>(countUsed), tile);
}
+ ASSERT(m_gradient);
+
SkMatrix matrix = m_gradientSpaceTransformation;
m_gradient->setLocalMatrix(matrix);
@@ -179,4 +185,10 @@ void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
context->fillRect(rect);
}
+void Gradient::setPlatformGradientSpaceTransform(const TransformationMatrix& matrix)
+{
+ if (m_gradient)
+ m_gradient->setLocalMatrix(m_gradientSpaceTransformation);
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h b/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h
index 29738f4..5e12ad6 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h
+++ b/WebCore/platform/graphics/skia/GraphicsContextPlatformPrivate.h
@@ -38,7 +38,7 @@ class PlatformContextSkia;
namespace WebCore {
// This class just holds onto a PlatformContextSkia for GraphicsContext.
-class GraphicsContextPlatformPrivate : Noncopyable {
+class GraphicsContextPlatformPrivate : public Noncopyable {
public:
GraphicsContextPlatformPrivate(PlatformContextSkia* platformContext)
: m_context(platformContext) { }
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 33ca23a..bbb42c9 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -331,7 +331,7 @@ void GraphicsContext::clearRect(const FloatRect& rect)
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
- paint.setPorterDuffXfermode(SkPorterDuff::kClear_Mode);
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
platformContext()->canvas()->drawRect(r, paint);
}
@@ -503,7 +503,7 @@ void GraphicsContext::drawFocusRing(const Color& color)
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStroke_Style);
- paint.setColor(focusRingColor().rgb());
+ paint.setColor(color.rgb());
paint.setStrokeWidth(focusRingOutset * 2);
paint.setPathEffect(new SkCornerPathEffect(focusRingOutset * 2))->unref();
focusRingRegion.getBoundaryPath(&path);
@@ -530,16 +530,48 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
// probably worth the speed up of no square root, which also won't be exact.
SkPoint disp = pts[1] - pts[0];
int length = SkScalarRound(disp.fX + disp.fY);
- int width = roundf(
- platformContext()->setupPaintForStroking(&paint, 0, length));
+ platformContext()->setupPaintForStroking(&paint, 0, length);
+ int width = roundf(strokeThickness());
+ bool isVerticalLine = pts[0].fX == pts[1].fX;
+
+ if (strokeStyle() == DottedStroke || strokeStyle() == DashedStroke) {
+ // Do a rect fill of our endpoints. This ensures we always have the
+ // appearance of being a border. We then draw the actual dotted/dashed line.
+
+ SkRect r1, r2;
+ r1.set(pts[0].fX, pts[0].fY, pts[0].fX + width, pts[0].fY + width);
+ r2.set(pts[1].fX, pts[1].fY, pts[1].fX + width, pts[1].fY + width);
+
+ if (isVerticalLine) {
+ r1.offset(-width / 2, 0);
+ r2.offset(-width / 2, -width);
+ } else {
+ r1.offset(0, -width / 2);
+ r2.offset(-width, -width / 2);
+ }
+ SkPaint fillPaint;
+ fillPaint.setColor(paint.getColor());
+ platformContext()->canvas()->drawRect(r1, fillPaint);
+ platformContext()->canvas()->drawRect(r2, fillPaint);
+
+ // Since we've already rendered the endcaps, adjust the endpoints to
+ // exclude them from the line itself.
+ if (isVerticalLine) {
+ pts[0].fY += width;
+ pts[1].fY -= width;
+ } else {
+ pts[0].fX += width;
+ pts[1].fX -= width;
+ }
+ }
// "Borrowed" this comment and idea from GraphicsContextCG.cpp
+ //
// For odd widths, we add in 0.5 to the appropriate x/y so that the float
// arithmetic works out. For example, with a border width of 3, KHTML will
// pass us (y1+y2)/2, e.g., (50+53)/2 = 103/2 = 51 when we want 51.5. It is
// always true that an even width gave us a perfect position, but an odd
// width gave us a position that is off by exactly 0.5.
- bool isVerticalLine = pts[0].fX == pts[1].fX;
if (width & 1) { // Odd.
if (isVerticalLine) {
@@ -687,13 +719,6 @@ void GraphicsContext::fillPath()
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
- if (colorSpace == PatternColorSpace) {
- SkShader* pat = state.fillPattern->createPlatformPattern(getCTM());
- paint.setShader(pat);
- pat->unref();
- } else if (colorSpace == GradientColorSpace)
- paint.setShader(state.fillGradient->platformGradient());
-
platformContext()->canvas()->drawPath(path, paint);
}
@@ -713,14 +738,6 @@ void GraphicsContext::fillRect(const FloatRect& rect)
SkPaint paint;
platformContext()->setupPaintForFilling(&paint);
-
- if (colorSpace == PatternColorSpace) {
- SkShader* pat = state.fillPattern->createPlatformPattern(getCTM());
- paint.setShader(pat);
- pat->unref();
- } else if (colorSpace == GradientColorSpace)
- paint.setShader(state.fillGradient->platformGradient());
-
platformContext()->canvas()->drawRect(r, paint);
}
@@ -858,7 +875,7 @@ void GraphicsContext::setCompositeOperation(CompositeOperator op)
{
if (paintingDisabled())
return;
- platformContext()->setPorterDuffMode(WebCoreCompositeToSkiaComposite(op));
+ platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op));
}
void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
@@ -947,6 +964,24 @@ void GraphicsContext::setPlatformFillColor(const Color& color)
platformContext()->setFillColor(color.rgb());
}
+void GraphicsContext::setPlatformFillGradient(Gradient* gradient)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->setFillShader(gradient->platformGradient());
+}
+
+void GraphicsContext::setPlatformFillPattern(Pattern* pattern)
+{
+ if (paintingDisabled())
+ return;
+
+ SkShader* pat = pattern->createPlatformPattern(getCTM());
+ platformContext()->setFillShader(pat);
+ pat->safeUnref();
+}
+
void GraphicsContext::setPlatformShadow(const IntSize& size,
int blurInt,
const Color& color)
@@ -1015,6 +1050,24 @@ void GraphicsContext::setPlatformStrokeThickness(float thickness)
platformContext()->setStrokeThickness(thickness);
}
+void GraphicsContext::setPlatformStrokeGradient(Gradient* gradient)
+{
+ if (paintingDisabled())
+ return;
+
+ platformContext()->setStrokeShader(gradient->platformGradient());
+}
+
+void GraphicsContext::setPlatformStrokePattern(Pattern* pattern)
+{
+ if (paintingDisabled())
+ return;
+
+ SkShader* pat = pattern->createPlatformPattern(getCTM());
+ platformContext()->setStrokeShader(pat);
+ pat->safeUnref();
+}
+
void GraphicsContext::setPlatformTextDrawingMode(int mode)
{
if (paintingDisabled())
@@ -1077,13 +1130,6 @@ void GraphicsContext::strokePath()
SkPaint paint;
platformContext()->setupPaintForStroking(&paint, 0, 0);
- if (colorSpace == PatternColorSpace) {
- SkShader* pat = state.strokePattern->createPlatformPattern(getCTM());
- paint.setShader(pat);
- pat->unref();
- } else if (colorSpace == GradientColorSpace)
- paint.setShader(state.strokeGradient->platformGradient());
-
platformContext()->canvas()->drawPath(path, paint);
}
@@ -1102,13 +1148,6 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth)
platformContext()->setupPaintForStroking(&paint, 0, 0);
paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth));
- if (colorSpace == PatternColorSpace) {
- SkShader* pat = state.strokePattern->createPlatformPattern(getCTM());
- paint.setShader(pat);
- pat->unref();
- } else if (colorSpace == GradientColorSpace)
- paint.setShader(state.strokeGradient->platformGradient());
-
platformContext()->canvas()->drawRect(rect, paint);
}
diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
index 600882d..7935ff1 100644
--- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -53,7 +54,7 @@ ImageBufferData::ImageBufferData(const IntSize& size)
{
}
-ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
+ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, bool& success)
: m_data(size)
, m_size(size)
{
@@ -71,7 +72,7 @@ ImageBuffer::ImageBuffer(const IntSize& size, bool grayScale, bool& success)
// Make the background transparent. It would be nice if this wasn't
// required, but the canvas is currently filled with the magic transparency
// color. Can we have another way to manage this?
- m_data.m_canvas.drawARGB(0, 0, 0, 0, SkPorterDuff::kClear_Mode);
+ m_data.m_canvas.drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
success = true;
}
@@ -100,6 +101,23 @@ Image* ImageBuffer::image() const
return m_image.get();
}
+void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable)
+{
+ const SkBitmap& bitmap = *context()->platformContext()->bitmap();
+ ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
+ SkAutoLockPixels bitmapLock(bitmap);
+ for (int y = 0; y < m_size.height(); ++y) {
+ uint32_t* srcRow = bitmap.getAddr32(0, y);
+ for (int x = 0; x < m_size.width(); ++x) {
+ SkColor color = SkPMColorToColor(srcRow[x]);
+ srcRow[x] = SkPreMultiplyARGB(lookUpTable[SkColorGetA(color)],
+ lookUpTable[SkColorGetR(color)],
+ lookUpTable[SkColorGetG(color)],
+ lookUpTable[SkColorGetB(color)]);
+ }
+ }
+}
+
PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect& rect) const
{
ASSERT(context());
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index cb089bb..45c3dcd 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -220,10 +220,10 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
}
}
-static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkIRect& srcRect, const SkRect& destRect, const SkPorterDuff::Mode& compOp)
+static void paintSkBitmap(PlatformContextSkia* platformContext, const NativeImageSkia& bitmap, const SkIRect& srcRect, const SkRect& destRect, const SkXfermode::Mode& compOp)
{
SkPaint paint;
- paint.setPorterDuffXfermode(compOp);
+ paint.setXfermodeMode(compOp);
paint.setFilterBitmap(true);
int alpha = roundf(platformContext->getAlpha() * 256);
if (alpha > 255)
@@ -379,7 +379,7 @@ void Image::drawPattern(GraphicsContext* context,
SkPaint paint;
paint.setShader(shader)->unref();
- paint.setPorterDuffXfermode(WebCoreCompositeToSkiaComposite(compositeOp));
+ paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp));
paint.setFilterBitmap(resampling == RESAMPLE_LINEAR);
context->platformContext()->paintSkPaint(destRect, paint);
diff --git a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp b/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
index b5f7e1d..1647b86 100644
--- a/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSourceSkia.cpp
@@ -30,21 +30,21 @@
#include "config.h"
-#include "ImageSourceSkia.h"
+#include "ImageSource.h"
#include "SharedBuffer.h"
#include "GIFImageDecoder.h"
+#include "ICOImageDecoder.h"
#include "JPEGImageDecoder.h"
#include "PNGImageDecoder.h"
#include "BMPImageDecoder.h"
#include "XBMImageDecoder.h"
-#include "ICOImageDecoder.h"
#include "SkBitmap.h"
namespace WebCore {
-ImageDecoder* createDecoder(const Vector<char>& data, const IntSize& preferredIconSize)
+ImageDecoder* createDecoder(const Vector<char>& data)
{
// We need at least 4 bytes to figure out what kind of image we're dealing with.
int length = data.size();
@@ -79,7 +79,7 @@ ImageDecoder* createDecoder(const Vector<char>& data, const IntSize& preferredIc
// CURs begin with 2-byte 0 followed by 2-byte 2.
if (!memcmp(contents, "\000\000\001\000", 4) ||
!memcmp(contents, "\000\000\002\000", 4))
- return new ICOImageDecoder(preferredIconSize);
+ return new ICOImageDecoder();
// XBMs require 8 bytes of info.
if (length >= 8 && strncmp(contents, "#define ", 8) == 0)
@@ -124,7 +124,7 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
// If insufficient bytes are available to determine the image type, no decoder plugin will be
// made.
if (!m_decoder)
- m_decoder = createDecoder(data->buffer(), IntSize());
+ m_decoder = createDecoder(data->buffer());
// CreateDecoder will return NULL if the decoder could not be created. Plus,
// we should not send more data to a decoder which has already decided it
@@ -150,10 +150,12 @@ IntSize ImageSource::size() const
return m_decoder->size();
}
-IntSize ImageSource::frameSizeAtIndex(size_t) const
+IntSize ImageSource::frameSizeAtIndex(size_t index) const
{
- // TODO(brettw) do we need anything here?
- return size();
+ if (!m_decoder)
+ return IntSize();
+
+ return m_decoder->frameSizeAtIndex(index);
}
int ImageSource::repetitionCount()
@@ -185,9 +187,8 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index)
return 0;
// Copy the bitmap. The pixel data is refcounted internally by SkBitmap, so
- // this doesn't cost much. This pointer will be owned by the BitmapImage
- // and freed in FrameData::clear().
- return new NativeImageSkia(buffer->bitmap());
+ // this doesn't cost much.
+ return buffer->asNewNativeImage();
}
bool ImageSource::frameIsCompleteAtIndex(size_t index)
@@ -229,16 +230,6 @@ bool ImageSource::frameHasAlphaAtIndex(size_t index)
return buffer->hasAlpha();
}
-void ImageSourceSkia::setData(SharedBuffer* data,
- bool allDataReceived,
- const IntSize& preferredIconSize)
-{
- if (!m_decoder)
- m_decoder = createDecoder(data->buffer(), preferredIconSize);
-
- ImageSource::setData(data, allDataReceived);
-}
-
String ImageSource::filenameExtension() const
{
return m_decoder ? m_decoder->filenameExtension() : String();
diff --git a/WebCore/platform/graphics/skia/ImageSourceSkia.h b/WebCore/platform/graphics/skia/ImageSourceSkia.h
deleted file mode 100644
index 9cb4a95..0000000
--- a/WebCore/platform/graphics/skia/ImageSourceSkia.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2008, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ImageSource.h"
-
-namespace WebCore {
-
-class ImageSourceSkia : public ImageSource {
-public:
- // FIXME: This class is a hack to support Chromium's ICO decoder
- // Currently our ICO decoder decodes all data during setData() instead of
- // being lazy. In addition, it only decodes one frame (closest to the size
- // passed to the decoder during createDecoder, called from setData) and
- // discards all other data in the file.
- //
- // To fix this will require fixing the ICO decoder to be lazy, or to decode
- // all frames. Apple's decoders (ImageIO) decode all frames, and return
- // them all sorted in decreasing size. WebCore always draws the first frame.
- //
- // This is a special-purpose routine for the favicon decoder, which is used
- // to specify a particular icon size for the ICOImageDecoder to prefer
- // decoding. Note that not all favicons are ICOs, so this won't
- // necessarily do anything differently than ImageSource::setData().
- //
- // Passing an empty IntSize for |preferredIconSize| here is exactly
- // equivalent to just calling ImageSource::setData(). See also comments in
- // ICOImageDecoder.cpp.
- void setData(SharedBuffer* data,
- bool allDataReceived,
- const IntSize& preferredIconSize);
-};
-
-}
diff --git a/WebCore/platform/graphics/skia/PathSkia.cpp b/WebCore/platform/graphics/skia/PathSkia.cpp
index 9d9df52..5ac14b9 100644
--- a/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -68,6 +68,11 @@ bool Path::isEmpty() const
return m_path->isEmpty();
}
+bool Path::hasCurrentPoint() const
+{
+ return m_path->getPoints(NULL, 0) != 0;
+}
+
bool Path::contains(const FloatPoint& point, WindRule rule) const
{
return SkPathContainsPoint(m_path, point,
@@ -81,15 +86,7 @@ void Path::translate(const FloatSize& size)
FloatRect Path::boundingRect() const
{
- // FIXME: This #ifdef can go away once we're firmly using the new Skia.
- // During the transition, this makes the code compatible with both versions.
-#ifdef SK_USE_OLD_255_TO_256
return m_path->getBounds();
-#else
- SkRect rect;
- m_path->computeBounds(&rect, SkPath::kExact_BoundsType);
- return rect;
-#endif
}
void Path::moveTo(const FloatPoint& point)
@@ -281,15 +278,7 @@ static FloatRect boundingBoxForCurrentStroke(const GraphicsContext* context)
context->platformContext()->setupPaintForStroking(&paint, 0, 0);
SkPath boundingPath;
paint.getFillPath(context->platformContext()->currentPathInLocalCoordinates(), &boundingPath);
- // FIXME: This #ifdef can go away once we're firmly using the new Skia.
- // During the transition, this makes the code compatible with both versions.
-#ifdef SK_USE_OLD_255_TO_256
return boundingPath.getBounds();
-#else
- SkRect r;
- boundingPath.computeBounds(&r, SkPath::kExact_BoundsType);
- return r;
-#endif
}
FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier)
diff --git a/WebCore/platform/graphics/skia/PatternSkia.cpp b/WebCore/platform/graphics/skia/PatternSkia.cpp
index be8eb8a..11b5cf1 100644
--- a/WebCore/platform/graphics/skia/PatternSkia.cpp
+++ b/WebCore/platform/graphics/skia/PatternSkia.cpp
@@ -33,8 +33,10 @@
#include "NativeImageSkia.h"
#include "TransformationMatrix.h"
-#include "SkShader.h"
#include "SkCanvas.h"
+#include "SkColor.h"
+#include "SkColorShader.h"
+#include "SkShader.h"
namespace WebCore {
@@ -49,6 +51,10 @@ PlatformPatternPtr Pattern::createPlatformPattern(const TransformationMatrix& pa
// LayoutTests/svg/W3C-SVG-1.1/pservers-grad-06-b.svg
SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame();
+ // If we don't have a bitmap, return a transparent shader.
+ if (!bm)
+ return new SkColorShader(SkColorSetARGB(0, 0, 0, 0));
+
if (m_repeatX && m_repeatY)
return SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 74b2bfe..e0a292c 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -57,18 +57,18 @@ struct PlatformContextSkia::State {
// Common shader state.
float m_alpha;
- SkPorterDuff::Mode m_porterDuffMode;
- SkShader* m_gradient;
- SkShader* m_pattern;
+ SkXfermode::Mode m_xferMode;
bool m_useAntialiasing;
SkDrawLooper* m_looper;
// Fill.
SkColor m_fillColor;
+ SkShader* m_fillShader;
// Stroke.
WebCore::StrokeStyle m_strokeStyle;
SkColor m_strokeColor;
+ SkShader* m_strokeShader;
float m_strokeThickness;
int m_dashRatio; // Ratio of the length of a dash to its width.
float m_miterLimit;
@@ -98,15 +98,15 @@ private:
// Note: Keep theses default values in sync with GraphicsContextState.
PlatformContextSkia::State::State()
: m_alpha(1)
- , m_porterDuffMode(SkPorterDuff::kSrcOver_Mode)
- , m_gradient(0)
- , m_pattern(0)
+ , m_xferMode(SkXfermode::kSrcOver_Mode)
, m_useAntialiasing(true)
, m_looper(0)
, m_fillColor(0xFF000000)
+ , m_fillShader(0)
, m_strokeStyle(WebCore::SolidStroke)
, m_strokeColor(WebCore::Color::black)
, m_strokeThickness(0)
+ , m_strokeShader(0)
, m_dashRatio(3)
, m_miterLimit(4)
, m_lineCap(SkPaint::kDefault_Cap)
@@ -118,15 +118,15 @@ PlatformContextSkia::State::State()
PlatformContextSkia::State::State(const State& other)
: m_alpha(other.m_alpha)
- , m_porterDuffMode(other.m_porterDuffMode)
- , m_gradient(other.m_gradient)
- , m_pattern(other.m_pattern)
+ , m_xferMode(other.m_xferMode)
, m_useAntialiasing(other.m_useAntialiasing)
, m_looper(other.m_looper)
, m_fillColor(other.m_fillColor)
+ , m_fillShader(other.m_fillShader)
, m_strokeStyle(other.m_strokeStyle)
, m_strokeColor(other.m_strokeColor)
, m_strokeThickness(other.m_strokeThickness)
+ , m_strokeShader(other.m_strokeShader)
, m_dashRatio(other.m_dashRatio)
, m_miterLimit(other.m_miterLimit)
, m_lineCap(other.m_lineCap)
@@ -141,16 +141,16 @@ PlatformContextSkia::State::State(const State& other)
// Up the ref count of these. saveRef does nothing if 'this' is NULL.
m_looper->safeRef();
m_dash->safeRef();
- m_gradient->safeRef();
- m_pattern->safeRef();
+ m_fillShader->safeRef();
+ m_strokeShader->safeRef();
}
PlatformContextSkia::State::~State()
{
m_looper->safeUnref();
m_dash->safeUnref();
- m_gradient->safeUnref();
- m_pattern->safeUnref();
+ m_fillShader->safeUnref();
+ m_strokeShader->safeUnref();
}
SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
@@ -170,7 +170,6 @@ SkColor PlatformContextSkia::State::applyAlpha(SkColor c) const
// Danger: canvas can be NULL.
PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
: m_canvas(canvas)
- , m_stateStack(sizeof(State))
#if PLATFORM(WIN_OS)
, m_drawingToImageBuffer(false)
#endif
@@ -274,8 +273,11 @@ void PlatformContextSkia::drawRect(SkRect rect)
(m_state->m_strokeColor & 0xFF000000)) {
// We do a fill of four rects to simulate the stroke of a border.
SkColor oldFillColor = m_state->m_fillColor;
- if (oldFillColor != m_state->m_strokeColor)
- setFillColor(m_state->m_strokeColor);
+
+ // setFillColor() will set the shader to NULL, so save a ref to it now.
+ SkShader* oldFillShader = m_state->m_fillShader;
+ oldFillShader->safeRef();
+ setFillColor(m_state->m_strokeColor);
setupPaintForFilling(&paint);
SkRect topBorder = { rect.fLeft, rect.fTop, rect.fRight, rect.fTop + 1 };
canvas()->drawRect(topBorder, paint);
@@ -285,8 +287,9 @@ void PlatformContextSkia::drawRect(SkRect rect)
canvas()->drawRect(leftBorder, paint);
SkRect rightBorder = { rect.fRight - 1, rect.fTop + 1, rect.fRight, rect.fBottom - 1 };
canvas()->drawRect(rightBorder, paint);
- if (oldFillColor != m_state->m_strokeColor)
- setFillColor(oldFillColor);
+ setFillColor(oldFillColor);
+ setFillShader(oldFillShader);
+ oldFillShader->safeUnref();
}
}
@@ -300,19 +303,15 @@ void PlatformContextSkia::setupPaintCommon(SkPaint* paint) const
#endif
paint->setAntiAlias(m_state->m_useAntialiasing);
- paint->setPorterDuffXfermode(m_state->m_porterDuffMode);
+ paint->setXfermodeMode(m_state->m_xferMode);
paint->setLooper(m_state->m_looper);
-
- if (m_state->m_gradient)
- paint->setShader(m_state->m_gradient);
- else if (m_state->m_pattern)
- paint->setShader(m_state->m_pattern);
}
void PlatformContextSkia::setupPaintForFilling(SkPaint* paint) const
{
setupPaintCommon(paint);
paint->setColor(m_state->applyAlpha(m_state->m_fillColor));
+ paint->setShader(m_state->m_fillShader);
}
float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, int length) const
@@ -321,6 +320,7 @@ float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
float width = m_state->m_strokeThickness;
paint->setColor(m_state->applyAlpha(m_state->m_strokeColor));
+ paint->setShader(m_state->m_strokeShader);
paint->setStyle(SkPaint::kStroke_Style);
paint->setStrokeWidth(SkFloatToScalar(width));
paint->setStrokeCap(m_state->m_lineCap);
@@ -338,20 +338,27 @@ float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
width = m_state->m_dashRatio * width;
// Fall through.
case WebCore::DottedStroke:
- SkScalar dashLength;
- if (length) {
- // Determine about how many dashes or dots we should have.
- float roundedWidth = roundf(width);
- int numDashes = roundedWidth ? (length / roundedWidth) : length;
- if (!(numDashes & 1))
- numDashes++; // Make it odd so we end on a dash/dot.
- // Use the number of dashes to determine the length of a
- // dash/dot, which will be approximately width
- dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(numDashes));
- } else
- dashLength = SkFloatToScalar(width);
- SkScalar intervals[2] = { dashLength, dashLength };
- paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();
+ // Truncate the width, since we don't want fuzzy dots or dashes.
+ int dashLength = static_cast<int>(width);
+ // Subtract off the endcaps, since they're rendered separately.
+ int distance = length - 2 * static_cast<int>(m_state->m_strokeThickness);
+ int phase = 1;
+ if (dashLength > 1) {
+ // Determine how many dashes or dots we should have.
+ int numDashes = distance / dashLength;
+ int remainder = distance % dashLength;
+ // Adjust the phase to center the dashes within the line.
+ if (numDashes % 2 == 0) {
+ // Even: shift right half a dash, minus half the remainder
+ phase = (dashLength - remainder) / 2;
+ } else {
+ // Odd: shift right a full dash, minus half the remainder
+ phase = dashLength - remainder / 2;
+ }
+ }
+ SkScalar dashLengthSk = SkIntToScalar(dashLength);
+ SkScalar intervals[2] = { dashLengthSk, dashLengthSk };
+ paint->setPathEffect(new SkDashPathEffect(intervals, 2, SkIntToScalar(phase)))->unref();
}
}
@@ -383,14 +390,15 @@ void PlatformContextSkia::setLineJoin(SkPaint::Join lj)
m_state->m_lineJoin = lj;
}
-void PlatformContextSkia::setPorterDuffMode(SkPorterDuff::Mode pdm)
+void PlatformContextSkia::setXfermodeMode(SkXfermode::Mode pdm)
{
- m_state->m_porterDuffMode = pdm;
+ m_state->m_xferMode = pdm;
}
void PlatformContextSkia::setFillColor(SkColor color)
{
m_state->m_fillColor = color;
+ setFillShader(NULL);
}
SkDrawLooper* PlatformContextSkia::getDrawLooper() const
@@ -411,6 +419,7 @@ void PlatformContextSkia::setStrokeStyle(WebCore::StrokeStyle strokeStyle)
void PlatformContextSkia::setStrokeColor(SkColor strokeColor)
{
m_state->m_strokeColor = strokeColor;
+ setStrokeShader(NULL);
}
float PlatformContextSkia::getStrokeThickness() const
@@ -423,6 +432,15 @@ void PlatformContextSkia::setStrokeThickness(float thickness)
m_state->m_strokeThickness = thickness;
}
+void PlatformContextSkia::setStrokeShader(SkShader* strokeShader)
+{
+ if (strokeShader != m_state->m_strokeShader) {
+ m_state->m_strokeShader->safeUnref();
+ m_state->m_strokeShader = strokeShader;
+ m_state->m_strokeShader->safeRef();
+ }
+}
+
int PlatformContextSkia::getTextDrawingMode() const
{
return m_state->m_textDrawingMode;
@@ -471,7 +489,8 @@ SkPath PlatformContextSkia::currentPathInLocalCoordinates() const
SkPath localPath = m_path;
const SkMatrix& matrix = m_canvas->getTotalMatrix();
SkMatrix inverseMatrix;
- matrix.invert(&inverseMatrix);
+ if (!matrix.invert(&inverseMatrix))
+ return SkPath();
localPath.transform(inverseMatrix);
return localPath;
}
@@ -481,19 +500,12 @@ void PlatformContextSkia::setFillRule(SkPath::FillType fr)
m_path.setFillType(fr);
}
-void PlatformContextSkia::setGradient(SkShader* gradient)
-{
- if (gradient != m_state->m_gradient) {
- m_state->m_gradient->safeUnref();
- m_state->m_gradient = gradient;
- }
-}
-
-void PlatformContextSkia::setPattern(SkShader* pattern)
+void PlatformContextSkia::setFillShader(SkShader* fillShader)
{
- if (pattern != m_state->m_pattern) {
- m_state->m_pattern->safeUnref();
- m_state->m_pattern = pattern;
+ if (fillShader != m_state->m_fillShader) {
+ m_state->m_fillShader->safeUnref();
+ m_state->m_fillShader = fillShader;
+ m_state->m_fillShader->safeRef();
}
}
@@ -527,7 +539,7 @@ void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, con
// NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we
// only look at the alpha when compositing. I'm not 100% sure this is what WebKit expects for image clipping.
SkPaint paint;
- paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode);
+ paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint);
}
#endif
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 25495aa..0c87fc2 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -60,7 +60,7 @@
// responsible for managing the painting state which is store in separate
// SkPaint objects. This class provides the adaptor that allows the painting
// state to be pushed and popped along with the bitmap.
-class PlatformContextSkia : Noncopyable {
+class PlatformContextSkia : public Noncopyable {
public:
// For printing, there shouldn't be any canvas. canvas can be NULL. If you
// supply a NULL canvas, you can also call setCanvas later.
@@ -115,15 +115,15 @@ public:
void setLineCap(SkPaint::Cap);
void setLineJoin(SkPaint::Join);
void setFillRule(SkPath::FillType);
- void setPorterDuffMode(SkPorterDuff::Mode);
+ void setXfermodeMode(SkXfermode::Mode);
void setFillColor(SkColor);
+ void setFillShader(SkShader*);
void setStrokeStyle(WebCore::StrokeStyle);
void setStrokeColor(SkColor);
void setStrokeThickness(float thickness);
+ void setStrokeShader(SkShader*);
void setTextDrawingMode(int mode);
void setUseAntialiasing(bool enable);
- void setGradient(SkShader*);
- void setPattern(SkShader*);
void setDashPathEffect(SkDashPathEffect*);
SkDrawLooper* getDrawLooper() const;
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index 7f12508..f1c5cdc 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -267,21 +267,11 @@ static bool skiaDrawText(HFONT hfont,
SkCanvas* canvas,
const SkPoint& point,
SkPaint* paint,
- const TransformationMatrix& transformationMatrix,
- Gradient* gradient,
- Pattern* pattern,
const WORD* glyphs,
const int* advances,
const GOFFSET* offsets,
int numGlyphs)
{
- SkShader* shader = NULL;
- if (gradient)
- shader = gradient->platformGradient();
- else if (pattern)
- shader = pattern->createPlatformPattern(transformationMatrix);
-
- paint->setShader(shader);
float x = point.fX, y = point.fY;
for (int i = 0; i < numGlyphs; i++) {
@@ -326,14 +316,7 @@ bool paintSkiaText(GraphicsContext* context,
bool didFill = false;
if ((textMode & cTextFill) && SkColorGetA(paint.getColor())) {
- Gradient* fillGradient = 0;
- Pattern* fillPattern = 0;
- if (context->fillColorSpace() == GradientColorSpace)
- fillGradient = context->fillGradient();
- else if (context->fillColorSpace() == PatternColorSpace)
- fillPattern = context->fillPattern();
if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
- context->getCTM(), fillGradient, fillPattern,
&glyphs[0], &advances[0], &offsets[0], numGlyphs))
return false;
didFill = true;
@@ -360,14 +343,7 @@ bool paintSkiaText(GraphicsContext* context,
paint.setLooper(0)->safeUnref();
}
- Gradient* strokeGradient = 0;
- Pattern* strokePattern = 0;
- if (context->strokeColorSpace() == GradientColorSpace)
- strokeGradient = context->strokeGradient();
- else if (context->strokeColorSpace() == PatternColorSpace)
- strokePattern = context->strokePattern();
if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
- context->getCTM(), strokeGradient, strokePattern,
&glyphs[0], &advances[0], &offsets[0], numGlyphs))
return false;
}
diff --git a/WebCore/platform/graphics/skia/SkiaUtils.cpp b/WebCore/platform/graphics/skia/SkiaUtils.cpp
index a7a266d..dbbbdbf 100644
--- a/WebCore/platform/graphics/skia/SkiaUtils.cpp
+++ b/WebCore/platform/graphics/skia/SkiaUtils.cpp
@@ -42,6 +42,7 @@
namespace WebCore {
+#ifdef MANUAL_MERGE_REQUIRED
static const struct CompositOpToSkiaMode {
uint8_t mCompositOp;
uint8_t mMode;
@@ -77,36 +78,39 @@ SkXfermode::Mode WebCoreCompositeToSkiaMode(CompositeOperator op)
}
static const struct CompositOpToPorterDuffMode {
+#else // MANUAL_MERGE_REQUIRED
+static const struct CompositOpToXfermodeMode {
+#endif // MANUAL_MERGE_REQUIRED
uint8_t mCompositOp;
- uint8_t mPorterDuffMode;
-} gMapCompositOpsToPorterDuffModes[] = {
- { CompositeClear, SkPorterDuff::kClear_Mode },
- { CompositeCopy, SkPorterDuff::kSrc_Mode },
- { CompositeSourceOver, SkPorterDuff::kSrcOver_Mode },
- { CompositeSourceIn, SkPorterDuff::kSrcIn_Mode },
- { CompositeSourceOut, SkPorterDuff::kSrcOut_Mode },
- { CompositeSourceAtop, SkPorterDuff::kSrcATop_Mode },
- { CompositeDestinationOver, SkPorterDuff::kDstOver_Mode },
- { CompositeDestinationIn, SkPorterDuff::kDstIn_Mode },
- { CompositeDestinationOut, SkPorterDuff::kDstOut_Mode },
- { CompositeDestinationAtop, SkPorterDuff::kDstATop_Mode },
- { CompositeXOR, SkPorterDuff::kXor_Mode },
- { CompositePlusDarker, SkPorterDuff::kDarken_Mode },
- { CompositeHighlight, SkPorterDuff::kSrcOver_Mode }, // TODO
- { CompositePlusLighter, SkPorterDuff::kAdd_Mode }
+ uint8_t m_xfermodeMode;
+} gMapCompositOpsToXfermodeModes[] = {
+ { CompositeClear, SkXfermode::kClear_Mode },
+ { CompositeCopy, SkXfermode::kSrc_Mode },
+ { CompositeSourceOver, SkXfermode::kSrcOver_Mode },
+ { CompositeSourceIn, SkXfermode::kSrcIn_Mode },
+ { CompositeSourceOut, SkXfermode::kSrcOut_Mode },
+ { CompositeSourceAtop, SkXfermode::kSrcATop_Mode },
+ { CompositeDestinationOver, SkXfermode::kDstOver_Mode },
+ { CompositeDestinationIn, SkXfermode::kDstIn_Mode },
+ { CompositeDestinationOut, SkXfermode::kDstOut_Mode },
+ { CompositeDestinationAtop, SkXfermode::kDstATop_Mode },
+ { CompositeXOR, SkXfermode::kXor_Mode },
+ { CompositePlusDarker, SkXfermode::kDarken_Mode },
+ { CompositeHighlight, SkXfermode::kSrcOver_Mode }, // TODO
+ { CompositePlusLighter, SkXfermode::kPlus_Mode }
};
-SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(CompositeOperator op)
+SkXfermode::Mode WebCoreCompositeToSkiaComposite(CompositeOperator op)
{
- const CompositOpToPorterDuffMode* table = gMapCompositOpsToPorterDuffModes;
+ const CompositOpToXfermodeMode* table = gMapCompositOpsToXfermodeModes;
- for (unsigned i = 0; i < SK_ARRAY_COUNT(gMapCompositOpsToPorterDuffModes); i++) {
+ for (unsigned i = 0; i < SK_ARRAY_COUNT(gMapCompositOpsToXfermodeModes); i++) {
if (table[i].mCompositOp == op)
- return (SkPorterDuff::Mode)table[i].mPorterDuffMode;
+ return (SkXfermode::Mode)table[i].m_xfermodeMode;
}
SkDEBUGF(("GraphicsContext::setCompositeOperation uknown CompositeOperator %d\n", op));
- return SkPorterDuff::kSrcOver_Mode; // fall-back
+ return SkXfermode::kSrcOver_Mode; // fall-back
}
Color SkPMColorToWebCoreColor(SkPMColor pm)
@@ -168,8 +172,12 @@ bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::
SkPath scaledPath;
int scale = 1;
+#ifdef MANUAL_MERGE_REQUIRED
SkRect bounds;
bounds = originalPath->getBounds();
+#else // MANUAL_MERGE_REQUIRED
+ SkRect bounds = originalPath->getBounds();
+#endif // MANUAL_MERGE_REQUIRED
// We can immediately return false if the point is outside the bounding rect
if (!bounds.contains(SkFloatToScalar(point.x()), SkFloatToScalar(point.y())))
@@ -208,7 +216,7 @@ GraphicsContext* scratchContext()
{
static ImageBuffer* scratch = 0;
if (!scratch)
- scratch = ImageBuffer::create(IntSize(1, 1), false).release();
+ scratch = ImageBuffer::create(IntSize(1, 1)).release();
// We don't bother checking for failure creating the ImageBuffer, since our
// ImageBuffer initializer won't fail.
return scratch->context();
diff --git a/WebCore/platform/graphics/skia/SkiaUtils.h b/WebCore/platform/graphics/skia/SkiaUtils.h
index aa4cd4d..a210cd3 100644
--- a/WebCore/platform/graphics/skia/SkiaUtils.h
+++ b/WebCore/platform/graphics/skia/SkiaUtils.h
@@ -36,16 +36,24 @@
#include <wtf/MathExtras.h>
#include "GraphicsContext.h"
#include "SkPath.h"
+#ifdef MANUAL_MERGE_REQUIRED
#include "SkPorterDuff.h"
#include "SkXfermode.h"
+#else // MANUAL_MERGE_REQUIRED
+#include "SkXfermode.h"
+#endif // MANUAL_MERGE_REQUIRED
class SkCanvas;
class SkRegion;
namespace WebCore {
+#ifdef MANUAL_MERGE_REQUIRED
SkXfermode::Mode WebCoreCompositeToSkiaMode(CompositeOperator);
SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(CompositeOperator);
+#else // MANUAL_MERGE_REQUIRED
+SkXfermode::Mode WebCoreCompositeToSkiaComposite(CompositeOperator);
+#endif // MANUAL_MERGE_REQUIRED
// move this guy into SkColor.h
SkColor SkPMColorToColor(SkPMColor);