diff options
author | Derek Sollenberger <djsollen@google.com> | 2011-04-28 14:02:20 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-04-28 14:02:20 -0700 |
commit | cef717ff0869605896b43ea1c86b5c0fa96c2c81 (patch) | |
tree | 871e0757f900c5c02fcfff1b9eae5d222948c94e | |
parent | e8c7a7791b9238a5b89df8c6c1455684328291f3 (diff) | |
parent | 909b5bb7002f48ae08c3c0157f5df3ee828e5d18 (diff) | |
download | external_webkit-cef717ff0869605896b43ea1c86b5c0fa96c2c81.zip external_webkit-cef717ff0869605896b43ea1c86b5c0fa96c2c81.tar.gz external_webkit-cef717ff0869605896b43ea1c86b5c0fa96c2c81.tar.bz2 |
Merge "Fix CSS shadows and provide better support for HTML5 Canvas shadows."
4 files changed, 70 insertions, 14 deletions
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp index 52312a4..d80b365 100644 --- a/WebCore/platform/graphics/GraphicsContext.cpp +++ b/WebCore/platform/graphics/GraphicsContext.cpp @@ -288,6 +288,11 @@ void GraphicsContext::setShadowsIgnoreTransforms(bool ignoreTransforms) m_common->state.shadowsIgnoreTransforms = ignoreTransforms; } +bool GraphicsContext::shadowsIgnoreTransforms() const +{ + return m_common->state.shadowsIgnoreTransforms; +} + bool GraphicsContext::updatingControlTints() const { return m_common->m_updatingControlTints; diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h index 1029c90..0ea717b 100644 --- a/WebCore/platform/graphics/GraphicsContext.h +++ b/WebCore/platform/graphics/GraphicsContext.h @@ -197,6 +197,7 @@ namespace WebCore { Gradient* fillGradient() const; void setShadowsIgnoreTransforms(bool); + bool shadowsIgnoreTransforms() const; void setShouldAntialias(bool); bool shouldAntialias() const; diff --git a/WebCore/platform/graphics/android/FontAndroid.cpp b/WebCore/platform/graphics/android/FontAndroid.cpp index e896a46..520af5d 100644 --- a/WebCore/platform/graphics/android/FontAndroid.cpp +++ b/WebCore/platform/graphics/android/FontAndroid.cpp @@ -35,6 +35,7 @@ #include "IntRect.h" #include "PlatformGraphicsContext.h" #include "SkCanvas.h" +#include "SkColorFilter.h" #include "SkLayerDrawLooper.h" #include "SkPaint.h" #include "SkTemplates.h" @@ -89,29 +90,53 @@ static bool setupForText(SkPaint* paint, GraphicsContext* gc, SkLayerDrawLooper* looper = new SkLayerDrawLooper; paint->setLooper(looper)->unref(); - // we clear the looper, in case we have a shadow + // Specify the behavior of the looper + SkLayerDrawLooper::LayerInfo info; + info.fPaintBits = SkLayerDrawLooper::kEntirePaint_Bits; + info.fColorMode = SkXfermode::kSrc_Mode; + + // The paint is only valid until the looper receives another call to + // addLayer(). Therefore, we must cache certain state for later use. + bool hasFillPaint = false; + bool hasStrokePaint = false; + SkScalar strokeWidth; - SkPaint* fillP = 0; - SkPaint* strokeP = 0; if ((mode & cTextStroke) && gc->willStroke()) { - strokeP = setupStroke(looper->addLayer(), gc, font); - strokeP->setLooper(0); + strokeWidth = setupStroke(looper->addLayer(info), gc, font)->getStrokeWidth(); + hasStrokePaint = true; } if ((mode & cTextFill) && gc->willFill()) { - fillP = setupFill(looper->addLayer(), gc, font); - fillP->setLooper(0); + setupFill(looper->addLayer(info), gc, font); + hasFillPaint = true; } if (hasShadow) { SkPaint shadowPaint; SkPoint offset; if (gc->setupShadowPaint(&shadowPaint, &offset)) { - SkPaint* p = looper->addLayer(offset.fX, offset.fY); + + // add an offset to the looper when creating a shadow layer + info.fOffset.set(offset.fX, offset.fY); + + SkPaint* p = looper->addLayer(info); *p = shadowPaint; - if (strokeP && !fillP) { + + // Currently, only GraphicsContexts associated with the + // HTMLCanvasElement have shadows ignore transforms set. This + // allows us to distinguish between CSS and Canvas shadows which + // have different rendering specifications. + if (gc->shadowsIgnoreTransforms()) { + SkColorFilter* cf = SkColorFilter::CreateModeFilter(p->getColor(), + SkXfermode::kSrcIn_Mode); + p->setColorFilter(cf)->unref(); + } else { // in CSS + p->setShader(NULL); + } + + if (hasStrokePaint && !hasFillPaint) { // stroke the shadow if we have stroke but no fill p->setStyle(SkPaint::kStroke_Style); - p->setStrokeWidth(strokeP->getStrokeWidth()); + p->setStrokeWidth(strokeWidth); } updateForFont(p, font); } diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp index 64b6ad3..c5da517 100644 --- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp +++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp @@ -183,13 +183,24 @@ public: shadow.color = c; } - bool setupShadowPaint(SkPaint* paint, SkPoint* offset) + bool setupShadowPaint(GraphicsContext* ctx, SkPaint* paint, SkPoint* offset) { paint->setAntiAlias(true); paint->setDither(true); paint->setXfermodeMode(mode); paint->setColor(shadow.color); offset->set(shadow.dx, shadow.dy); + + // Currently, only GraphicsContexts associated with the + // HTMLCanvasElement have shadows ignore transforms set. This + // allows us to distinguish between CSS and Canvas shadows which + // have different rendering specifications. + uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag; + if (ctx->shadowsIgnoreTransforms()) { + offset->fY = -offset->fY; + flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag; + } + if (shadow.blur > 0) { paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur, SkBlurMaskFilter::kNormal_BlurStyle))->unref(); @@ -289,10 +300,24 @@ public: paint->setDither(true); paint->setXfermodeMode(m_state->mode); if (SkColorGetA(m_state->shadow.color) > 0) { + + // Currently, only GraphicsContexts associated with the + // HTMLCanvasElement have shadows ignore transforms set. This + // allows us to distinguish between CSS and Canvas shadows which + // have different rendering specifications. + SkScalar dy = m_state->shadow.dy; + uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag; + if (m_parentGfxCtx->shadowsIgnoreTransforms()) { + dy = -dy; + flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag; + flags |= SkBlurDrawLooper::kOverrideColor_BlurFlag; + } + SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur, m_state->shadow.dx, - m_state->shadow.dy, - m_state->shadow.color); + dy, + m_state->shadow.color, + flags); paint->setLooper(looper)->unref(); } } @@ -953,7 +978,7 @@ void GraphicsContext::setupStrokePaint(SkPaint* paint) bool GraphicsContext::setupShadowPaint(SkPaint* paint, SkPoint* offset) { - return m_data->getState()->setupShadowPaint(paint, offset); + return m_data->getState()->setupShadowPaint(this, paint, offset); } void GraphicsContext::setPlatformStrokeColor(const Color& c, ColorSpace) |