PlatformGraphicsContext.cpp revision 895fe04c32042264ad684bd498a0cd4729aae016
164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard/* 264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * Copyright 2006, The Android Open Source Project 364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * 464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * Redistribution and use in source and binary forms, with or without 564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * modification, are permitted provided that the following conditions 664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * are met: 764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * * Redistributions of source code must retain the above copyright 864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * notice, this list of conditions and the following disclaimer. 964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * * Redistributions in binary form must reproduce the above copyright 1064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * notice, this list of conditions and the following disclaimer in the 1164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * documentation and/or other materials provided with the distribution. 1264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * 1364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 1464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 1764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 2164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard */ 2564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 2664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#define LOG_TAG "PlatformGraphicsContext" 2764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#define LOG_NDEBUG 1 2864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 2964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "config.h" 3064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "PlatformGraphicsContext.h" 3164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 3264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "AndroidLog.h" 3364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkBlurDrawLooper.h" 3464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkBlurMaskFilter.h" 3564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkColorPriv.h" 3664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkDashPathEffect.h" 3764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkPaint.h" 3864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkShader.h" 3964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#include "SkiaUtils.h" 4064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 4164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardnamespace WebCore { 4264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 4364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 4464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// Helper functions 4564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 4664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 4764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardstatic int RoundToInt(float x) 4864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 4964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return (int)roundf(x); 5064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 5164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 5264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardtemplate <typename T> T* deepCopyPtr(const T* src) 5364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 5464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return src ? new T(*src) : 0; 5564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 5664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 5764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// Set a bitmap shader that mimics dashing by width-on, width-off. 5864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// Returns false if it could not succeed (e.g. there was an existing shader) 5964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardstatic bool setBitmapDash(SkPaint* paint, int width) { 6064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (width <= 0 || paint->getShader()) 6164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return false; 6264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 6364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkColor c = paint->getColor(); 6464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 6564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkBitmap bm; 6664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bm.setConfig(SkBitmap::kARGB_8888_Config, 2, 1); 6764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bm.allocPixels(); 6864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bm.lockPixels(); 6964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 7064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // set the ON pixel 7164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard *bm.getAddr32(0, 0) = SkPreMultiplyARGB(0xFF, SkColorGetR(c), 7264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkColorGetG(c), SkColorGetB(c)); 7364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // set the OFF pixel 7464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard *bm.getAddr32(1, 0) = 0; 7564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bm.unlockPixels(); 7664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 7764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkMatrix matrix; 7864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard matrix.setScale(SkIntToScalar(width), SK_Scalar1); 7964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 8064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkShader* s = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode, 8164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkShader::kClamp_TileMode); 8264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard s->setLocalMatrix(matrix); 8364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 8464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setShader(s)->unref(); 85895fe04c32042264ad684bd498a0cd4729aae016Derek Sollenberger paint->setFilterBitmap(true); 86895fe04c32042264ad684bd498a0cd4729aae016Derek Sollenberger paint->setAntiAlias(true); 8764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return true; 8864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 8964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 9064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 9164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// State implementation 9264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 9364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 9464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardPlatformGraphicsContext::State::State() 9564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard : pathEffect(0) 9664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , miterLimit(4) 9764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , alpha(1) 9864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeThickness(0) // Same as default in GraphicsContextPrivate.h 9964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , lineCap(SkPaint::kDefault_Cap) 10064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , lineJoin(SkPaint::kDefault_Join) 10164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , mode(SkXfermode::kSrcOver_Mode) 10264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , dashRatio(3) 10364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , fillColor(SK_ColorBLACK) 10464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , fillShader(0) 10564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeColor(SK_ColorBLACK) 10664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeShader(0) 10764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , useAA(true) 10864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeStyle(SolidStroke) 10964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 11064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 11164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 11264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardPlatformGraphicsContext::State::State(const State& other) 11364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard : pathEffect(other.pathEffect) 11464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , miterLimit(other.miterLimit) 11564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , alpha(other.alpha) 11664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeThickness(other.strokeThickness) 11764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , lineCap(other.lineCap) 11864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , lineJoin(other.lineJoin) 11964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , mode(other.mode) 12064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , dashRatio(other.dashRatio) 12164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , shadow(other.shadow) 12264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , fillColor(other.fillColor) 12364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , fillShader(other.fillShader) 12464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeColor(other.strokeColor) 12564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeShader(other.strokeShader) 12664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , useAA(other.useAA) 12764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard , strokeStyle(other.strokeStyle) 12864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 12964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeRef(pathEffect); 13064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeRef(fillShader); 13164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeRef(strokeShader); 13264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 13364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 13464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardPlatformGraphicsContext::State::~State() 13564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 13664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeUnref(pathEffect); 13764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeUnref(fillShader); 13864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeUnref(strokeShader); 13964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 14064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 14164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::State::setShadow(int radius, int dx, int dy, SkColor c) 14264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 14364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // Cut the radius in half, to visually match the effect seen in 14464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // safari browser 14564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard shadow.blur = SkScalarHalf(SkIntToScalar(radius)); 14664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard shadow.dx = SkIntToScalar(dx); 14764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard shadow.dy = SkIntToScalar(dy); 14864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard shadow.color = c; 14964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 15064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 15164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardbool PlatformGraphicsContext::State::setupShadowPaint(SkPaint* paint, SkPoint* offset, 15264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bool shadowsIgnoreTransforms) 15364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 15464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setAntiAlias(true); 15564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setDither(true); 15664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setXfermodeMode(mode); 15764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setColor(shadow.color); 15864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard offset->set(shadow.dx, shadow.dy); 15964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 16064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // Currently, only GraphicsContexts associated with the 16164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // HTMLCanvasElement have shadows ignore transforms set. This 16264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // allows us to distinguish between CSS and Canvas shadows which 16364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // have different rendering specifications. 16464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard uint32_t flags = SkBlurMaskFilter::kHighQuality_BlurFlag; 16564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (shadowsIgnoreTransforms) { 16664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard offset->fY = -offset->fY; 16764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard flags |= SkBlurMaskFilter::kIgnoreTransform_BlurFlag; 16864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 16964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 17064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (shadow.blur > 0) { 17164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setMaskFilter(SkBlurMaskFilter::Create(shadow.blur, 17264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkBlurMaskFilter::kNormal_BlurStyle))->unref(); 17364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 17464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return SkColorGetA(shadow.color) && (shadow.blur || shadow.dx || shadow.dy); 17564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 17664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 17764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardSkColor PlatformGraphicsContext::State::applyAlpha(SkColor c) const 17864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 17964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard int s = RoundToInt(alpha * 256); 18064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (s >= 256) 18164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return c; 18264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (s < 0) 18364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return 0; 18464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 18564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard int a = SkAlphaMul(SkColorGetA(c), s); 18664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return (c & 0x00FFFFFF) | (a << 24); 18764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 18864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 18964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// Returns a new State with all of this object's inherited properties copied. 19064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardPlatformGraphicsContext::State PlatformGraphicsContext::State::cloneInheritedProperties() 19164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 19264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return PlatformGraphicsContext::State(*this); 19364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 19464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 19564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 19664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// PlatformGraphicsContext 19764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 19864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 19964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardPlatformGraphicsContext::PlatformGraphicsContext() 20064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 20164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_stateStack.append(State()); 20264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state = &m_stateStack.last(); 20364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 20464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 20564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas RoardPlatformGraphicsContext::~PlatformGraphicsContext() 20664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 20764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 20864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 20964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 21064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// State management 21164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 21264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 21364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::save() 21464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 21564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_stateStack.append(m_state->cloneInheritedProperties()); 21664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state = &m_stateStack.last(); 21764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 21864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 21964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::restore() 22064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 22164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_stateStack.removeLast(); 22264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state = &m_stateStack.last(); 22364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 22464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 22564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 22664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// State setters 22764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 22864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 22964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setAlpha(float alpha) 23064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 23164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->alpha = alpha; 23264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 23364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 23464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setCompositeOperation(CompositeOperator op) 23564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 23664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->mode = WebCoreCompositeToSkiaComposite(op); 23764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 23864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 23964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setFillColor(const Color& c) 24064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 24164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->fillColor = c.rgb(); 24264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard setFillShader(0); 24364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 24464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 24564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setFillShader(SkShader* fillShader) 24664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 24764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (fillShader) 24864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->fillColor = Color::black; 24964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 25064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (fillShader != m_state->fillShader) { 25164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeUnref(m_state->fillShader); 25264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->fillShader = fillShader; 25364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeRef(m_state->fillShader); 25464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 25564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 25664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 25764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setLineCap(LineCap cap) 25864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 25964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard switch (cap) { 26064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case ButtCap: 26164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->lineCap = SkPaint::kButt_Cap; 26264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 26364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case RoundCap: 26464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->lineCap = SkPaint::kRound_Cap; 26564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 26664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case SquareCap: 26764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->lineCap = SkPaint::kSquare_Cap; 26864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 26964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard default: 27064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard ALOGD("PlatformGraphicsContextSkia::setLineCap: unknown LineCap %d\n", cap); 27164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 27264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 27364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 27464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 27564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setLineDash(const DashArray& dashes, float dashOffset) 27664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 27764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard size_t dashLength = dashes.size(); 27864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (!dashLength) 27964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return; 28064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 28164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard size_t count = !(dashLength % 2) ? dashLength : dashLength * 2; 28264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkScalar* intervals = new SkScalar[count]; 28364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 28464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard for (unsigned int i = 0; i < count; i++) 28564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard intervals[i] = SkFloatToScalar(dashes[i % dashLength]); 28664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkPathEffect **effectPtr = &m_state->pathEffect; 28764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeUnref(*effectPtr); 28864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard *effectPtr = new SkDashPathEffect(intervals, count, SkFloatToScalar(dashOffset)); 28964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 29064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard delete[] intervals; 29164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 29264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 29364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setLineJoin(LineJoin join) 29464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 29564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard switch (join) { 29664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case MiterJoin: 29764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->lineJoin = SkPaint::kMiter_Join; 29864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 29964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case RoundJoin: 30064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->lineJoin = SkPaint::kRound_Join; 30164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 30264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case BevelJoin: 30364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->lineJoin = SkPaint::kBevel_Join; 30464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 30564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard default: 30664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard ALOGD("PlatformGraphicsContextSkia::setLineJoin: unknown LineJoin %d\n", join); 30764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 30864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 30964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 31064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 31164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setMiterLimit(float limit) 31264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 31364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->miterLimit = limit; 31464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 31564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 31664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setShadow(int radius, int dx, int dy, SkColor c) 31764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 31864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->setShadow(radius, dx, dy, c); 31964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 32064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 32164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setShouldAntialias(bool useAA) 32264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 32364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->useAA = useAA; 32464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 32564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 32664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setStrokeColor(const Color& c) 32764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 32864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->strokeColor = c.rgb(); 32964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard setStrokeShader(0); 33064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 33164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 33264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setStrokeShader(SkShader* strokeShader) 33364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 33464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (strokeShader) 33564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->strokeColor = Color::black; 33664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 33764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (strokeShader != m_state->strokeShader) { 33864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeUnref(m_state->strokeShader); 33964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->strokeShader = strokeShader; 34064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkSafeRef(m_state->strokeShader); 34164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 34264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 34364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 34464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setStrokeStyle(StrokeStyle style) 34564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 34664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->strokeStyle = style; 34764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 34864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 34964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setStrokeThickness(float f) 35064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 35164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->strokeThickness = f; 35264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 35364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 35464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 35564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard// Paint setup 35664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard//************************************** 35764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 35864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setupPaintCommon(SkPaint* paint) const 35964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 36064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setAntiAlias(m_state->useAA); 36164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setDither(true); 36264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setXfermodeMode(m_state->mode); 36364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (SkColorGetA(m_state->shadow.color) > 0) { 36464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 36564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // Currently, only GraphicsContexts associated with the 36664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // HTMLCanvasElement have shadows ignore transforms set. This 36764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // allows us to distinguish between CSS and Canvas shadows which 36864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // have different rendering specifications. 36964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkScalar dy = m_state->shadow.dy; 37064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard uint32_t flags = SkBlurDrawLooper::kHighQuality_BlurFlag; 37164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (shadowsIgnoreTransforms()) { 37264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard dy = -dy; 37364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard flags |= SkBlurDrawLooper::kIgnoreTransform_BlurFlag; 37464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard flags |= SkBlurDrawLooper::kOverrideColor_BlurFlag; 37564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 37664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 37764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkDrawLooper* looper = new SkBlurDrawLooper(m_state->shadow.blur, 37864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->shadow.dx, 37964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard dy, 38064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard m_state->shadow.color, 38164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard flags); 38264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setLooper(looper)->unref(); 38364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 38464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setFilterBitmap(true); 38564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 38664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 38764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardvoid PlatformGraphicsContext::setupPaintFill(SkPaint* paint) const 38864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 38964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard this->setupPaintCommon(paint); 39064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setColor(m_state->applyAlpha(m_state->fillColor)); 39164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setShader(m_state->fillShader); 39264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 39364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 39464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardbool PlatformGraphicsContext::setupPaintShadow(SkPaint* paint, SkPoint* offset) const 39564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 39664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return m_state->setupShadowPaint(paint, offset, shadowsIgnoreTransforms()); 39764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 39864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 39964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roardbool PlatformGraphicsContext::setupPaintStroke(SkPaint* paint, SkRect* rect, 40064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bool isHLine) 40164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard{ 40264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard this->setupPaintCommon(paint); 40364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setColor(m_state->applyAlpha(m_state->strokeColor)); 40464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setShader(m_state->strokeShader); 40564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 40664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard float width = m_state->strokeThickness; 40764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 40864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // This allows dashing and dotting to work properly for hairline strokes 40964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // FIXME: Should we only do this for dashed and dotted strokes? 41064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (!width) 41164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard width = 1; 41264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 41364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setStyle(SkPaint::kStroke_Style); 41464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setStrokeWidth(SkFloatToScalar(width)); 41564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setStrokeCap(m_state->lineCap); 41664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setStrokeJoin(m_state->lineJoin); 41764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setStrokeMiter(SkFloatToScalar(m_state->miterLimit)); 41864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 41964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (rect && (RoundToInt(width) & 1)) 42064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard rect->inset(-SK_ScalarHalf, -SK_ScalarHalf); 42164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 42264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkPathEffect* pe = m_state->pathEffect; 42364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (pe) { 42464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setPathEffect(pe); 42564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return false; 42664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 42764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard switch (m_state->strokeStyle) { 42864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case NoStroke: 42964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case SolidStroke: 43064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard width = 0; 43164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 43264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case DashedStroke: 43364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard width = m_state->dashRatio * width; 43464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 43564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // No break 43664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard case DottedStroke: 43764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard break; 43864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 43964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 44064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (width > 0) { 44164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // Return true if we're basically a dotted dash of squares 44264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard bool justSqrs = RoundToInt(width) == RoundToInt(paint->getStrokeWidth()); 44364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 44464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard if (justSqrs || !isHLine || !setBitmapDash(paint, width)) { 44564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#if 0 44664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // this is slow enough that we just skip it for now 44764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard // see http://b/issue?id=4163023 44864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard SkScalar intervals[] = { width, width }; 44964e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard pe = new SkDashPathEffect(intervals, 2, 0); 45064e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard paint->setPathEffect(pe)->unref(); 45164e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard#endif 45264e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 45364e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return justSqrs; 45464e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard } 45564e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard return false; 45664e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} 45764e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard 45864e4b265f84573b97d408f7d3e5aa99a647be057Nicolas Roard} // WebCore 459