} // unnamed namespace
-struct GraphicsContext::DeferredSaveState {
- DeferredSaveState(unsigned mask, int count) : m_flags(mask), m_restoreCount(count) { }
+struct GraphicsContext::CanvasSaveState {
+ CanvasSaveState(unsigned mask, int count) : m_flags(mask), m_restoreCount(count) { }
unsigned m_flags;
int m_restoreCount;
GraphicsContext::GraphicsContext(SkCanvas* canvas)
: m_canvas(canvas)
- , m_deferredSaveFlags(0)
+ , m_paintStateStack()
+ , m_paintStateIndex(0)
+ , m_canvasSaveFlags(0)
, m_annotationMode(0)
#if !ASSERT_DISABLED
, m_annotationCount(0)
, m_isCertainlyOpaque(true)
, m_printing(false)
{
- m_stateStack.append(adoptPtr(new GraphicsContextState()));
- m_state = m_stateStack.last().get();
+ // FIXME: Do some tests to determine how many states are typically used, and allocate
+ // several here.
+ m_paintStateStack.append(GraphicsContextState::create());
+ m_paintState = m_paintStateStack.last().get();
}
GraphicsContext::~GraphicsContext()
{
- ASSERT(m_stateStack.size() == 1);
+ ASSERT(!m_paintStateIndex);
+ ASSERT(!m_paintState->m_saveCount);
ASSERT(!m_annotationCount);
ASSERT(!m_layerCount);
ASSERT(m_recordingStateStack.isEmpty());
if (paintingDisabled())
return;
- m_stateStack.append(m_state->clone());
- m_state = m_stateStack.last().get();
+ m_paintState->m_saveCount++;
- m_saveStateStack.append(DeferredSaveState(m_deferredSaveFlags, m_canvas->getSaveCount()));
- m_deferredSaveFlags |= SkCanvas::kMatrixClip_SaveFlag;
+ m_canvasStateStack.append(CanvasSaveState(m_canvasSaveFlags, m_canvas->getSaveCount()));
+ m_canvasSaveFlags |= SkCanvas::kMatrixClip_SaveFlag;
}
void GraphicsContext::restore()
if (paintingDisabled())
return;
- if (m_stateStack.size() == 1) {
+ if (!m_paintStateIndex && !m_paintState->m_saveCount) {
WTF_LOG_ERROR("ERROR void GraphicsContext::restore() stack is empty");
return;
}
- m_stateStack.removeLast();
- m_state = m_stateStack.last().get();
+ if (m_paintState->m_saveCount) {
+ m_paintState->m_saveCount--;
+ } else {
+ m_paintStateIndex--;
+ m_paintState = m_paintStateStack[m_paintStateIndex].get();
+ }
- DeferredSaveState savedState = m_saveStateStack.last();
- m_saveStateStack.removeLast();
- m_deferredSaveFlags = savedState.m_flags;
+ CanvasSaveState savedState = m_canvasStateStack.last();
+ m_canvasStateStack.removeLast();
+ m_canvasSaveFlags = savedState.m_flags;
m_canvas->restoreToCount(savedState.m_restoreCount);
}
if (paintingDisabled())
return;
- realizeSave(SkCanvas::kMatrixClip_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrixClip_SaveFlag);
m_canvas->saveLayer(bounds, paint, saveFlags);
if (bounds)
void GraphicsContext::setStrokeColor(const Color& color)
{
- m_state->m_strokeData.setColor(color);
- m_state->m_strokeData.clearGradient();
- m_state->m_strokeData.clearPattern();
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_strokeData.setColor(color);
+ stateToSet->m_strokeData.clearGradient();
+ stateToSet->m_strokeData.clearPattern();
}
void GraphicsContext::setStrokePattern(PassRefPtr<Pattern> pattern)
setStrokeColor(Color::black);
return;
}
- m_state->m_strokeData.clearGradient();
- m_state->m_strokeData.setPattern(pattern);
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_strokeData.clearGradient();
+ stateToSet->m_strokeData.setPattern(pattern);
}
void GraphicsContext::setStrokeGradient(PassRefPtr<Gradient> gradient)
setStrokeColor(Color::black);
return;
}
- m_state->m_strokeData.setGradient(gradient);
- m_state->m_strokeData.clearPattern();
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_strokeData.setGradient(gradient);
+ stateToSet->m_strokeData.clearPattern();
}
void GraphicsContext::setFillColor(const Color& color)
{
- m_state->m_fillColor = color;
- m_state->m_fillGradient.clear();
- m_state->m_fillPattern.clear();
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_fillColor = color;
+ stateToSet->m_fillGradient.clear();
+ stateToSet->m_fillPattern.clear();
}
void GraphicsContext::setFillPattern(PassRefPtr<Pattern> pattern)
setFillColor(Color::black);
return;
}
- m_state->m_fillGradient.clear();
- m_state->m_fillPattern = pattern;
+
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_fillGradient.clear();
+ stateToSet->m_fillPattern = pattern;
}
void GraphicsContext::setFillGradient(PassRefPtr<Gradient> gradient)
setFillColor(Color::black);
return;
}
- m_state->m_fillGradient = gradient;
- m_state->m_fillPattern.clear();
+
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_fillGradient = gradient;
+ stateToSet->m_fillPattern.clear();
}
void GraphicsContext::setShadow(const FloatSize& offset, float blur, const Color& color,
if (paintingDisabled())
return;
- m_state->m_looper = drawLooper.skDrawLooper();
+ mutableState()->m_looper = drawLooper.skDrawLooper();
}
void GraphicsContext::clearDrawLooper()
if (paintingDisabled())
return;
- m_state->m_looper.clear();
+ mutableState()->m_looper.clear();
}
bool GraphicsContext::hasShadow() const
{
- return !!m_state->m_looper;
+ return !!immutableState()->m_looper;
}
int GraphicsContext::getNormalizedAlpha() const
{
- int alpha = roundf(m_state->m_alpha * 256);
+ int alpha = roundf(immutableState()->m_alpha * 256);
if (alpha > 255)
alpha = 255;
else if (alpha < 0)
void GraphicsContext::setCompositeOperation(CompositeOperator compositeOperation, WebBlendMode blendMode)
{
- m_state->m_compositeOperator = compositeOperation;
- m_state->m_blendMode = blendMode;
- m_state->m_xferMode = WebCoreCompositeToSkiaComposite(compositeOperation, blendMode);
+ GraphicsContextState* stateToSet = mutableState();
+ stateToSet->m_compositeOperator = compositeOperation;
+ stateToSet->m_blendMode = blendMode;
+ stateToSet->m_xferMode = WebCoreCompositeToSkiaComposite(compositeOperation, blendMode);
}
SkColorFilter* GraphicsContext::colorFilter()
{
- return m_state->m_colorFilter.get();
+ return immutableState()->m_colorFilter.get();
}
void GraphicsContext::setColorFilter(ColorFilter colorFilter)
{
+ GraphicsContextState* stateToSet = mutableState();
+
// We only support one active color filter at the moment. If (when) this becomes a problem,
// we should switch to using color filter chains (Skia work in progress).
- ASSERT(!m_state->m_colorFilter);
- m_state->m_colorFilter = WebCoreColorFilterToSkiaColorFilter(colorFilter);
+ ASSERT(!stateToSet->m_colorFilter);
+ stateToSet->m_colorFilter = WebCoreColorFilterToSkiaColorFilter(colorFilter);
}
bool GraphicsContext::readPixels(SkBitmap* bitmap, int x, int y, SkCanvas::Config8888 config8888)
if (paintingDisabled())
return;
- realizeSave(SkCanvas::kMatrix_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrix_SaveFlag);
m_canvas->setMatrix(matrix);
}
if (paintingDisabled())
return false;
+
if (matrix.isIdentity())
return true;
- realizeSave(SkCanvas::kMatrix_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrix_SaveFlag);
return m_canvas->concat(matrix);
}
void GraphicsContext::beginTransparencyLayer(float opacity, const FloatRect* bounds)
{
- beginLayer(opacity, m_state->m_compositeOperator, bounds);
+ beginLayer(opacity, immutableState()->m_compositeOperator, bounds);
}
void GraphicsContext::beginLayer(float opacity, CompositeOperator op, const FloatRect* bounds, ColorFilter colorFilter, ImageFilter* imageFilter)
SkPaint layerPaint;
layerPaint.setAlpha(static_cast<unsigned char>(opacity * 255));
- layerPaint.setXfermode(WebCoreCompositeToSkiaComposite(op, m_state->m_blendMode).get());
+ layerPaint.setXfermode(WebCoreCompositeToSkiaComposite(op, m_paintState->m_blendMode).get());
layerPaint.setColorFilter(WebCoreColorFilterToSkiaColorFilter(colorFilter).get());
layerPaint.setImageFilter(imageFilter);
if (paintingDisabled() || displayList->bounds().isEmpty())
return;
- realizeSave(SkCanvas::kMatrixClip_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrixClip_SaveFlag);
const FloatRect& bounds = displayList->bounds();
if (bounds.x() || bounds.y())
setupPaintCommon(paint);
- setupShader(paint, m_state->m_fillGradient.get(), m_state->m_fillPattern.get(), m_state->m_fillColor.rgb());
+ setupShader(paint, immutableState()->m_fillGradient.get(), immutableState()->m_fillPattern.get(), immutableState()->m_fillColor.rgb());
}
float GraphicsContext::setupPaintForStroking(SkPaint* paint, int length) const
setupPaintCommon(paint);
- setupShader(paint, m_state->m_strokeData.gradient(), m_state->m_strokeData.pattern(),
- m_state->m_strokeData.color().rgb());
+ setupShader(paint, immutableState()->m_strokeData.gradient(), immutableState()->m_strokeData.pattern(),
+ immutableState()->m_strokeData.color().rgb());
- return m_state->m_strokeData.setupPaint(paint, length);
+ return immutableState()->m_strokeData.setupPaint(paint, length);
}
void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias)
SkRect skRect = rect;
SkPaint paint;
- int fillcolorNotTransparent = m_state->m_fillColor.rgb() & 0xFF000000;
+ int fillcolorNotTransparent = m_paintState->m_fillColor.rgb() & 0xFF000000;
if (fillcolorNotTransparent) {
setupPaintForFilling(&paint);
drawRect(skRect, paint);
}
- if (m_state->m_strokeData.style() != NoStroke && (m_state->m_strokeData.color().rgb() & 0xFF000000)) {
+ if (m_paintState->m_strokeData.style() != NoStroke && (m_paintState->m_strokeData.color().rgb() & 0xFF000000)) {
// We do a fill of four rects to simulate the stroke of a border.
paint.reset();
setupPaintForFilling(&paint);
if (paintingDisabled())
return;
- SkCanvas::DrawBitmapRectFlags flags = m_state->m_shouldClampToSourceRect ? SkCanvas::kNone_DrawBitmapRectFlag : SkCanvas::kBleed_DrawBitmapRectFlag;
+ SkCanvas::DrawBitmapRectFlags flags = m_paintState->m_shouldClampToSourceRect ? SkCanvas::kNone_DrawBitmapRectFlag : SkCanvas::kBleed_DrawBitmapRectFlag;
m_canvas->drawBitmapRectToRect(bitmap, src, dst, paint, flags);
SkPath& path = const_cast<SkPath&>(pathToFill.skPath());
SkPath::FillType previousFillType = path.getFillType();
- SkPath::FillType temporaryFillType = m_state->m_fillRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
+ SkPath::FillType temporaryFillType = m_paintState->m_fillRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
path.setFillType(temporaryFillType);
SkPaint paint;
if (paintingDisabled())
return false;
- realizeSave(SkCanvas::kClip_SaveFlag);
+ realizeCanvasSave(SkCanvas::kClip_SaveFlag);
return m_canvas->clipRect(rect, op, aa == AntiAliased);
}
if (paintingDisabled())
return false;
- realizeSave(SkCanvas::kClip_SaveFlag);
+ realizeCanvasSave(SkCanvas::kClip_SaveFlag);
return m_canvas->clipPath(path, op, aa == AntiAliased);
}
if (paintingDisabled())
return false;
- realizeSave(SkCanvas::kClip_SaveFlag);
+ realizeCanvasSave(SkCanvas::kClip_SaveFlag);
return m_canvas->clipRRect(rect, op, aa == AntiAliased);
}
if (paintingDisabled())
return;
- realizeSave(SkCanvas::kMatrix_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrix_SaveFlag);
m_canvas->rotate(WebCoreFloatToSkScalar(angleInRadians * (180.0f / 3.14159265f)));
}
if (!w && !h)
return;
- realizeSave(SkCanvas::kMatrix_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrix_SaveFlag);
m_canvas->translate(WebCoreFloatToSkScalar(w), WebCoreFloatToSkScalar(h));
}
if (size.width() == 1.0f && size.height() == 1.0f)
return;
- realizeSave(SkCanvas::kMatrix_SaveFlag);
+ realizeCanvasSave(SkCanvas::kMatrix_SaveFlag);
m_canvas->scale(WebCoreFloatToSkScalar(size.width()), WebCoreFloatToSkScalar(size.height()));
}
}
#endif
- paint->setAntiAlias(m_state->m_shouldAntialias);
+ paint->setAntiAlias(m_paintState->m_shouldAntialias);
- if (!SkXfermode::IsMode(m_state->m_xferMode.get(), SkXfermode::kSrcOver_Mode))
- paint->setXfermode(m_state->m_xferMode.get());
+ if (!SkXfermode::IsMode(m_paintState->m_xferMode.get(), SkXfermode::kSrcOver_Mode))
+ paint->setXfermode(m_paintState->m_xferMode.get());
- if (m_state->m_looper)
- paint->setLooper(m_state->m_looper.get());
+ if (m_paintState->m_looper)
+ paint->setLooper(m_paintState->m_looper.get());
- paint->setColorFilter(m_state->m_colorFilter.get());
+ paint->setColorFilter(m_paintState->m_colorFilter.get());
}
void GraphicsContext::drawOuterPath(const SkPath& path, SkPaint& paint, int width)
paint->setFilterBitmap(imageInterpolationQuality() != InterpolationNone);
}
- paint->setColor(m_state->applyAlpha(color));
+ paint->setColor(m_paintState->applyAlpha(color));
if (!shader)
return;