summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/android
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/android')
-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)