summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/graphics/skia
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/platform/graphics/skia
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/WebCore/platform/graphics/skia')
-rw-r--r--Source/WebCore/platform/graphics/skia/GradientSkia.cpp29
-rw-r--r--Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp68
-rw-r--r--Source/WebCore/platform/graphics/skia/PathSkia.cpp3
-rw-r--r--Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp4
-rw-r--r--Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp51
5 files changed, 89 insertions, 66 deletions
diff --git a/Source/WebCore/platform/graphics/skia/GradientSkia.cpp b/Source/WebCore/platform/graphics/skia/GradientSkia.cpp
index a636d10..2aadc08 100644
--- a/Source/WebCore/platform/graphics/skia/GradientSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GradientSkia.cpp
@@ -110,23 +110,14 @@ static void fillStops(const Gradient::ColorStop* stopData,
}
}
-static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b)
-{
- return a.stop < b.stop;
-}
-
SkShader* Gradient::platformGradient()
{
if (m_gradient)
return m_gradient;
- // FIXME: This and compareStops() are also in Gradient.cpp and
- // CSSGradientValue.cpp; probably should refactor in WebKit.
- if (!m_stopsSorted) {
- if (m_stops.size())
- std::stable_sort(m_stops.begin(), m_stops.end(), compareStops);
- m_stopsSorted = true;
- }
+ sortStopsIfNecessary();
+ ASSERT(m_stopsSorted);
+
size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size());
ASSERT(countUsed >= 2);
ASSERT(countUsed >= m_stops.size());
@@ -167,17 +158,23 @@ SkShader* Gradient::platformGradient()
SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0;
m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile);
}
+
+ if (aspectRatio() != 1) {
+ // CSS3 elliptical gradients: apply the elliptical scaling at the
+ // gradient center point.
+ m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y());
+ m_gradientSpaceTransformation.scale(1, 1 / aspectRatio());
+ m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y());
+ ASSERT(m_p0 == m_p1);
+ }
} else {
SkPoint pts[2] = { m_p0, m_p1 };
- m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
- static_cast<int>(countUsed), tile);
+ m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile);
}
ASSERT(m_gradient);
-
SkMatrix matrix = m_gradientSpaceTransformation;
m_gradient->setLocalMatrix(matrix);
-
return m_gradient;
}
diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 9f2ed32..00afd07 100644
--- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -436,6 +436,17 @@ void GraphicsContext::concatCTM(const AffineTransform& affine)
platformContext()->canvas()->concat(affine);
}
+void GraphicsContext::setCTM(const AffineTransform& affine)
+{
+ if (paintingDisabled())
+ return;
+
+ if (platformContext()->useGPU())
+ platformContext()->gpuCanvas()->setCTM(affine);
+
+ platformContext()->canvas()->setMatrix(affine);
+}
+
void GraphicsContext::drawConvexPolygon(size_t numPoints,
const FloatPoint* points,
bool shouldAntialias)
@@ -595,7 +606,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint);
}
-void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, TextCheckingLineStyle style)
{
if (paintingDisabled())
return;
@@ -644,8 +655,8 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex
}
// Offset it vertically by 1 so that there's some space under the text.
- SkScalar originX = SkIntToScalar(pt.x());
- SkScalar originY = SkIntToScalar(pt.y()) + 1;
+ SkScalar originX = WebCoreFloatToSkScalar(pt.x());
+ SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1;
// Make a shader for the bitmap with an origin of the box we'll draw. This
// shader is refcounted and will have an initial refcount of 1.
@@ -667,13 +678,13 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex
SkRect rect;
rect.set(originX,
originY,
- originX + SkIntToScalar(width),
+ originX + WebCoreFloatToSkScalar(width),
originY + SkIntToScalar(misspellBitmap->height()));
platformContext()->canvas()->drawRect(rect, paint);
}
-void GraphicsContext::drawLineForText(const IntPoint& pt,
- int width,
+void GraphicsContext::drawLineForText(const FloatPoint& pt,
+ float width,
bool printing)
{
if (paintingDisabled())
@@ -686,9 +697,9 @@ void GraphicsContext::drawLineForText(const IntPoint& pt,
int thickness = SkMax32(static_cast<int>(strokeThickness()), 1);
SkRect r;
- r.fLeft = SkIntToScalar(pt.x());
- r.fTop = SkIntToScalar(pt.y());
- r.fRight = r.fLeft + SkIntToScalar(width);
+ r.fLeft = WebCoreFloatToSkScalar(pt.x());
+ r.fTop = WebCoreFloatToSkScalar(pt.y());
+ r.fRight = r.fLeft + WebCoreFloatToSkScalar(width);
r.fBottom = r.fTop + SkIntToScalar(thickness);
SkPaint paint;
@@ -720,6 +731,7 @@ void GraphicsContext::fillPath(const Path& pathToFill)
if (paintingDisabled())
return;
+ // FIXME: add support to GLES2Canvas for more than just solid fills.
if (platformContext()->useGPU() && platformContext()->canAccelerate()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillPath(pathToFill);
@@ -857,43 +869,7 @@ AffineTransform GraphicsContext::getCTM() const
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
{
- // This logic is copied from GraphicsContextCG, eseidel 5/05/08
-
- // It is not enough just to round to pixels in device space. The rotation
- // part of the affine transform matrix to device space can mess with this
- // conversion if we have a rotating image like the hands of the world clock
- // widget. We just need the scale, so we get the affine transform matrix and
- // extract the scale.
-
- const SkMatrix& deviceMatrix = platformContext()->canvas()->getTotalMatrix();
- if (deviceMatrix.isIdentity())
- return rect;
-
- float deviceScaleX = sqrtf(square(deviceMatrix.getScaleX())
- + square(deviceMatrix.getSkewY()));
- float deviceScaleY = sqrtf(square(deviceMatrix.getSkewX())
- + square(deviceMatrix.getScaleY()));
-
- FloatPoint deviceOrigin(rect.x() * deviceScaleX, rect.y() * deviceScaleY);
- FloatPoint deviceLowerRight((rect.x() + rect.width()) * deviceScaleX,
- (rect.y() + rect.height()) * deviceScaleY);
-
- deviceOrigin.setX(roundf(deviceOrigin.x()));
- deviceOrigin.setY(roundf(deviceOrigin.y()));
- deviceLowerRight.setX(roundf(deviceLowerRight.x()));
- deviceLowerRight.setY(roundf(deviceLowerRight.y()));
-
- // Don't let the height or width round to 0 unless either was originally 0
- if (deviceOrigin.y() == deviceLowerRight.y() && rect.height())
- deviceLowerRight.move(0, 1);
- if (deviceOrigin.x() == deviceLowerRight.x() && rect.width())
- deviceLowerRight.move(1, 0);
-
- FloatPoint roundedOrigin(deviceOrigin.x() / deviceScaleX,
- deviceOrigin.y() / deviceScaleY);
- FloatPoint roundedLowerRight(deviceLowerRight.x() / deviceScaleX,
- deviceLowerRight.y() / deviceScaleY);
- return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
+ return rect;
}
void GraphicsContext::scale(const FloatSize& size)
diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp
index 6318c21..0344086 100644
--- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -144,7 +144,8 @@ void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlo
// Move to the start position (0 sweep means we add a single point).
m_path->arcTo(oval, startDegrees, 0, false);
// Draw the circle.
- m_path->addOval(oval);
+ m_path->addOval(oval, anticlockwise ?
+ SkPath::kCCW_Direction : SkPath::kCW_Direction);
// Force a moveTo the end position.
m_path->arcTo(oval, startDegrees + sweepDegrees, 0, true);
} else {
diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 5e08b3c..eac5e4a 100644
--- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -688,7 +688,7 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
paint.setStyle(SkPaint::kFill_Style);
for (size_t i = paths.size() - 1; i < paths.size(); --i) {
- paths[i].setFillType(SkPath::kInverseWinding_FillType);
+ paths[i].toggleInverseFillType();
m_canvas->drawPath(paths[i], paint);
}
@@ -821,7 +821,7 @@ void PlatformContextSkia::syncSoftwareCanvas() const
if (!m_useGPU) {
#if ENABLE(SKIA_GPU)
if (m_gpuCanvas)
- m_gpuCanvas->bindFramebuffer();
+ m_gpuCanvas->context()->makeContextCurrent();
#endif
return;
}
diff --git a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index 5046c50..54aa35e 100644
--- a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -38,10 +38,17 @@
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkShader.h"
+#include "SkTemplates.h"
+#include "SkTypeface.h"
#include <wtf/ListHashSet.h>
#include <wtf/Vector.h>
+#if ENABLE(SKIA_TEXT)
+// FIXME: a future role of skia will have this in a proper header
+extern SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&);
+#endif
+
namespace WebCore {
struct CachedOutlineKey {
@@ -273,6 +280,23 @@ static bool skiaDrawText(HFONT hfont,
const GOFFSET* offsets,
int numGlyphs)
{
+#if ENABLE(SKIA_TEXT)
+ SkASSERT(sizeof(WORD) == sizeof(uint16_t));
+
+ // Reserve space for 64 glyphs on the stack. If numGlyphs is larger, the array
+ // will dynamically allocate it space for numGlyph glyphs.
+ static const size_t kLocalGlyphMax = 64;
+ SkAutoSTArray<kLocalGlyphMax, SkPoint> posStorage(numGlyphs);
+ SkPoint* pos = posStorage.get();
+ SkScalar x = point.fX;
+ SkScalar y = point.fY;
+ for (int i = 0; i < numGlyphs; i++) {
+ pos[i].set(x + (offsets ? offsets[i].du : 0),
+ y + (offsets ? offsets[i].dv : 0));
+ x += SkIntToScalar(advances[i]);
+ }
+ canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint);
+#else
float x = point.fX, y = point.fY;
for (int i = 0; i < numGlyphs; i++) {
@@ -292,10 +316,31 @@ static bool skiaDrawText(HFONT hfont,
x += advances[i];
}
-
+#endif
return true;
}
+#if ENABLE(SKIA_TEXT)
+static void setupPaintForFont(HFONT hfont, SkPaint* paint)
+{
+ // FIXME:
+ // Much of this logic could also happen in
+ // FontCustomPlatformData::fontPlatformData and be cached,
+ // allowing us to avoid talking to GDI at this point.
+ //
+ LOGFONT info;
+ GetObject(hfont, sizeof(info), &info);
+ int size = info.lfHeight;
+ if (size < 0)
+ size = -size; // We don't let GDI dpi-scale us (see SkFontHost_win.cpp).
+ paint->setTextSize(SkIntToScalar(size));
+
+ SkTypeface* face = SkCreateTypefaceFromLOGFONT(info);
+ paint->setTypeface(face);
+ SkSafeUnref(face);
+}
+#endif
+
bool paintSkiaText(GraphicsContext* context,
HFONT hfont,
int numGlyphs,
@@ -314,6 +359,10 @@ bool paintSkiaText(GraphicsContext* context,
SkPaint paint;
platformContext->setupPaintForFilling(&paint);
paint.setFlags(SkPaint::kAntiAlias_Flag);
+#if ENABLE(SKIA_TEXT)
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ setupPaintForFont(hfont, &paint);
+#endif
bool didFill = false;
if ((textMode & TextModeFill) && SkColorGetA(paint.getColor())) {