summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2010-09-30 15:32:21 -0700
committerTeng-Hui Zhu <ztenghui@google.com>2010-10-04 10:17:12 -0700
commit5abcebdcce80658b012cd1de400558035899457c (patch)
treed3289bf8e7d1fe66f5e963f9a7cbf97541ec128b /WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
parent740f5071cda344b465351484f5362492fef31b5b (diff)
downloadexternal_webkit-5abcebdcce80658b012cd1de400558035899457c.zip
external_webkit-5abcebdcce80658b012cd1de400558035899457c.tar.gz
external_webkit-5abcebdcce80658b012cd1de400558035899457c.tar.bz2
Add AA to the border radius
In order to enable AA for the border radius, add an extra layer for drawing and then clearing by using AA paint. The reason why clipping can't show AA is that it is 1-bit clip. Change-Id: Ic9fa99915fb908e502dcb90cfe1428bb4d8e136b http://b/3003023
Diffstat (limited to 'WebCore/platform/graphics/android/GraphicsContextAndroid.cpp')
-rw-r--r--WebCore/platform/graphics/android/GraphicsContextAndroid.cpp89
1 files changed, 75 insertions, 14 deletions
diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
index 5371e60..9304c4d 100644
--- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
+++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp
@@ -22,7 +22,6 @@
* (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 "config.h"
#include "GraphicsContext.h"
@@ -96,7 +95,10 @@ public:
SkColor mFillColor;
SkColor mStrokeColor;
bool mUseAA;
-
+ // This is a list of clipping paths which are currently active, in the
+ // order in which they were pushed.
+ WTF::Vector<SkPath> m_antiAliasClipPaths;
+
State() {
mPath = NULL; // lazily allocated
mPathEffect = 0;
@@ -113,8 +115,20 @@ public:
mStrokeColor = SK_ColorBLACK;
}
- State(const State& other) {
- memcpy(this, &other, sizeof(State));
+ State(const State& other)
+ : mPathEffect(other.mPathEffect)
+ , mMiterLimit(other.mMiterLimit)
+ , mAlpha(other.mAlpha)
+ , mStrokeThickness(other.mStrokeThickness)
+ , mLineCap(other.mLineCap)
+ , mLineJoin(other.mLineJoin)
+ , mMode(other.mMode)
+ , mDashRatio(other.mDashRatio)
+ , mShadow(other.mShadow)
+ , mFillColor(other.mFillColor)
+ , mStrokeColor(other.mStrokeColor)
+ , mUseAA(other.mUseAA)
+ {
mPath = deepCopyPtr<SkPath>(other.mPath);
mPathEffect->safeRef();
}
@@ -180,14 +194,19 @@ public:
while (mStateStack.count() > 0)
this->restore();
}
-
- void save() {
+
+ void save()
+ {
State* newState = (State*)mStateStack.push_back();
new (newState) State(*mState);
mState = newState;
}
- void restore() {
+ void restore()
+ {
+ if (!mState->m_antiAliasClipPaths.isEmpty())
+ applyAntiAliasedClipPaths(mState->m_antiAliasClipPaths);
+
mState->~State();
mStateStack.pop_back();
mState = (State*)mStateStack.back();
@@ -308,6 +327,46 @@ public:
return false;
}
+ void clipPathAntiAliased(const SkPath& clipPath)
+ {
+ // If we are currently tracking any anti-alias clip paths, then we already
+ // have a layer in place and don't need to add another.
+ bool haveLayerOutstanding = mState->m_antiAliasClipPaths.size();
+
+ // See comments in applyAntiAliasedClipPaths about how this works.
+ mState->m_antiAliasClipPaths.append(clipPath);
+ if (!haveLayerOutstanding) {
+ SkRect bounds = clipPath.getBounds();
+ if (mPgc && mPgc->mCanvas) {
+ mPgc->mCanvas->saveLayerAlpha(&bounds, 255,
+ static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag
+ | SkCanvas::kFullColorLayer_SaveFlag
+ | SkCanvas::kClipToLayer_SaveFlag));
+ } else
+ ASSERT(0);
+ }
+ }
+
+ void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
+ {
+ // Anti-aliased clipping:
+ //
+ // Refer to PlatformContextSkia.cpp's applyAntiAliasedClipPaths() for more details
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ if (mPgc && mPgc->mCanvas) {
+ for (size_t i = paths.size() - 1; i < paths.size(); --i) {
+ paths[i].setFillType(SkPath::kInverseWinding_FillType);
+ mPgc->mCanvas->drawPath(paths[i], paint);
+ }
+ mPgc->mCanvas->restore();
+ } else
+ ASSERT(0);
+ }
+
private:
// not supported yet
State& operator=(const State&);
@@ -385,10 +444,10 @@ void GraphicsContext::savePlatformState()
void GraphicsContext::restorePlatformState()
{
- // restore our native canvas
- GC2Canvas(this)->restore();
// restore our private State
m_data->restore();
+ // restore our native canvas
+ GC2Canvas(this)->restore();
}
bool GraphicsContext::willFill() const {
@@ -735,7 +794,7 @@ void GraphicsContext::clip(const Path& path)
// path.platformPath()->dump(false, "clip path");
- GC2Canvas(this)->clipPath(*path.platformPath());
+ m_data->clipPathAntiAliased(*path.platformPath());
}
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
@@ -750,12 +809,14 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
path.addOval(r, SkPath::kCW_Direction);
// only perform the inset if we won't invert r
- if (2*thickness < rect.width() && 2*thickness < rect.height())
- {
- r.inset(SkIntToScalar(thickness) ,SkIntToScalar(thickness));
+ if (2*thickness < rect.width() && 2*thickness < rect.height()) {
+ // Adding one to the thickness doesn't make the border too thick as
+ // it's painted over afterwards. But without this adjustment the
+ // border appears a little anemic after anti-aliasing.
+ r.inset(SkIntToScalar(thickness+1), SkIntToScalar(thickness+1));
path.addOval(r, SkPath::kCCW_Direction);
}
- GC2Canvas(this)->clipPath(path);
+ m_data->clipPathAntiAliased(path);
}
void GraphicsContext::canvasClip(const Path& path)