diff options
author | Ben Murdoch <benm@google.com> | 2011-05-24 11:24:40 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-06-02 09:53:15 +0100 |
commit | 81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch) | |
tree | 7a9e5ed86ff429fd347a25153107221543909b19 /Source/WebCore/platform/graphics/skia | |
parent | 94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff) | |
download | external_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')
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())) { |