18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org>
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2008 Nuanti Ltd.
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch * Copyright (C) 2010, 2011 Igalia S.L.
8f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch * Copyright (C) Research In Motion Limited 2010. All rights reserved.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "GraphicsContext.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if USE(CAIRO)
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
375e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "AffineTransform.h"
38bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen#include "CairoUtilities.h"
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "ContextShadow.h"
4081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "FloatConversion.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FloatRect.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Font.h"
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "GraphicsContextPlatformPrivateCairo.h"
4468513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "OwnPtrCairo.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "IntRect.h"
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "NotImplemented.h"
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Path.h"
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Pattern.h"
492bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "PlatformContextCairo.h"
502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "PlatformPathCairo.h"
5128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu#include "RefPtrCairo.h"
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SimpleFontData.h"
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <cairo.h>
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <math.h>
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <stdio.h>
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/MathExtras.h>
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(GTK)
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <gdk/gdk.h>
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <pango/pango.h>
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#elif PLATFORM(WIN)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <cairo-win32.h>
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
65e8b154fd68f9b33be40a3590e58347f353835f5cSteve Blockusing namespace std;
66e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef M_PI
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define M_PI 3.14159265358979323846
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic inline void setPlatformFill(GraphicsContext* context, cairo_t* cr)
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
756c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    cairo_pattern_t* pattern = 0;
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_save(cr);
77f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    const GraphicsContextState& state = context->state();
79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (state.fillPattern) {
808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        AffineTransform affine;
81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        pattern = state.fillPattern->createPlatformPattern(affine);
826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        cairo_set_source(cr, pattern);
83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    } else if (state.fillGradient)
84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        cairo_set_source(cr, state.fillGradient->platformGradient());
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else
86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, context->fillColor());
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_clip_preserve(cr);
88f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_paint_with_alpha(cr, state.globalAlpha);
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_restore(cr);
906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (pattern)
916c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        cairo_pattern_destroy(pattern);
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
94f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic inline void setPlatformStroke(GraphicsContext* context, cairo_t* cr)
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    cairo_pattern_t* pattern = 0;
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_save(cr);
98f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    const GraphicsContextState& state = context->state();
100f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (state.strokePattern) {
1018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        AffineTransform affine;
102f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        pattern = state.strokePattern->createPlatformPattern(affine);
1036c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        cairo_set_source(cr, pattern);
104f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    } else if (state.strokeGradient)
105f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        cairo_set_source(cr, state.strokeGradient->platformGradient());
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else  {
107f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        Color strokeColor = colorWithOverrideAlpha(context->strokeColor().rgb(), context->strokeColor().alpha() / 255.f * state.globalAlpha);
108f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, strokeColor);
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
110f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (state.globalAlpha < 1.0f && (state.strokePattern || state.strokeGradient)) {
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        cairo_push_group(cr);
112f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        cairo_paint_with_alpha(cr, state.globalAlpha);
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        cairo_pop_group_to_source(cr);
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_stroke_preserve(cr);
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_restore(cr);
1176c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (pattern)
1186c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        cairo_pattern_destroy(pattern);
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// A fillRect helper
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const Color& col)
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
124f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setSourceRGBAFromColor(cr, col);
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill(cr);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
130db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockstatic void addConvexPolygonToContext(cairo_t* context, size_t numPoints, const FloatPoint* points)
131db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{
132db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_move_to(context, points[0].x(), points[0].y());
133db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    for (size_t i = 1; i < numPoints; i++)
134db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        cairo_line_to(context, points[i].x(), points[i].y());
135db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_close_path(context);
136db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block}
137db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochenum PathDrawingStyle {
139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Fill = 1,
140a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Stroke = 2,
141a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    FillAndStroke = Fill + Stroke
142a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch};
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic inline void drawPathShadow(GraphicsContext* context, PathDrawingStyle drawingStyle)
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
146a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ContextShadow* shadow = context->contextShadow();
147a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ASSERT(shadow);
148a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (shadow->m_type == ContextShadow::NoShadow)
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return;
15068513a70bcd92384395513322f1b801e7bf9c729Steve Block
151a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Calculate the extents of the rendered solid paths.
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cairoContext = context->platformContext()->cr();
153f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    OwnPtr<cairo_path_t> path(cairo_copy_path(cairoContext));
154a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
155a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    FloatRect solidFigureExtents;
156a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    double x0 = 0;
157a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    double x1 = 0;
158a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    double y0 = 0;
159a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    double y1 = 0;
160a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (drawingStyle & Stroke) {
161a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cairo_stroke_extents(cairoContext, &x0, &y0, &x1, &y1);
162a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        solidFigureExtents = FloatRect(x0, y0, x1 - x0, y1 - y0);
163a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
164a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (drawingStyle & Fill) {
165a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        cairo_fill_extents(cairoContext, &x0, &y0, &x1, &y1);
166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        FloatRect fillExtents(x0, y0, x1 - x0, y1 - y0);
167a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        solidFigureExtents.unite(fillExtents);
168a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
16968513a70bcd92384395513322f1b801e7bf9c729Steve Block
170cad810f21b803229eb11403f9209855525a25d57Steve Block    cairo_t* shadowContext = shadow->beginShadowLayer(context, solidFigureExtents);
171a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (!shadowContext)
172a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
174a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // It's important to copy the context properties to the new shadow
175a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // context to preserve things such as the fill rule and stroke width.
176a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    copyContextProperties(cairoContext, shadowContext);
177f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_append_path(shadowContext, path.get());
178643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
179a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (drawingStyle & Fill)
180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setPlatformFill(context, shadowContext);
181a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (drawingStyle & Stroke)
182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setPlatformStroke(context, shadowContext);
183643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
184cad810f21b803229eb11403f9209855525a25d57Steve Block    shadow->endShadowLayer(context);
185643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
187f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic void fillCurrentCairoPath(GraphicsContext* context, cairo_t* cairoContext)
188db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{
189db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_set_fill_rule(cairoContext, context->fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
190f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    drawPathShadow(context, Fill);
191db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
192f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPlatformFill(context, cairoContext);
193db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_new_path(cairoContext);
194db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block}
195db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic void strokeCurrentCairoPath(GraphicsContext* context,  cairo_t* cairoContext)
197db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{
198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    drawPathShadow(context, Stroke);
199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPlatformStroke(context, cairoContext);
200db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_new_path(cairoContext);
201db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block}
202db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
2032bde8e466a4451c7319e3a072d118917957d6554Steve BlockGraphicsContext::GraphicsContext(cairo_t* cr)
2042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : m_updatingControlTints(false)
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_data = new GraphicsContextPlatformPrivateToplevel(new PlatformContextCairo(cr));
2072bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2082bde8e466a4451c7319e3a072d118917957d6554Steve Block
2092bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid GraphicsContext::platformInit(PlatformContextCairo* platformContext)
2102bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2112bde8e466a4451c7319e3a072d118917957d6554Steve Block    m_data = new GraphicsContextPlatformPrivate(platformContext);
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (platformContext)
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block        m_data->syncContext(platformContext->cr());
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block    else
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block        setPaintingDisabled(true);
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GraphicsContext::platformDestroy()
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    delete m_data;
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockAffineTransform GraphicsContext::getCTM() const
2245e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
2265e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    cairo_matrix_t m;
2275e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    cairo_get_matrix(cr, &m);
2285e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return AffineTransform(m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
2295e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block}
2305e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
2312bde8e466a4451c7319e3a072d118917957d6554Steve BlockPlatformContextCairo* GraphicsContext::platformContext() const
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2332bde8e466a4451c7319e3a072d118917957d6554Steve Block    return m_data->platformContext;
2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::savePlatformState()
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    platformContext()->save();
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->save();
240a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_data->shadowStack.append(m_data->shadow);
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::restorePlatformState()
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
245a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (m_data->shadowStack.isEmpty())
246a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadow = ContextShadow();
247a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    else {
248a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadow = m_data->shadowStack.last();
249a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadowStack.removeLast();
250a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
25181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
2522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    platformContext()->restore();
25381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_data->restore();
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Draws a filled rectangle with a stroked border.
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::drawRect(const IntRect& rect)
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fillColor().alpha())
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        fillRectSourceOver(cr, rect, fillColor());
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (strokeStyle() != NoStroke) {
269f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, strokeColor());
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        FloatRect r(rect);
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        r.inflate(-.5f);
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_line_width(cr, 1.0);
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_stroke(cr);
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This is only used to draw borders.
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    StrokeStyle style = strokeStyle();
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (style == NoStroke)
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float width = strokeThickness();
2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (width < 1)
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        width = 1;
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatPoint p1 = point1;
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatPoint p2 = point2;
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool isVerticalLine = (p1.x() == p2.x());
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    adjustLineToPixelBoundaries(p1, p2, width, style);
3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_line_width(cr, width);
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int patWidth = 0;
3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (style) {
3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case NoStroke:
3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case SolidStroke:
3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case DottedStroke:
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        patWidth = static_cast<int>(width);
3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case DashedStroke:
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        patWidth = 3*static_cast<int>(width);
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
317f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setSourceRGBAFromColor(cr, strokeColor());
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (patWidth) {
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Do a rect fill of our endpoints.  This ensures we always have the
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // appearance of being a border.  We then draw the actual dotted/dashed line.
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isVerticalLine) {
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());
3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Example: 80 pixels with a width of 30 pixels.
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Remainder is 20.  The maximum pixels of line we could paint
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // will be 50 pixels.
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int remainder = distance%patWidth;
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int coverage = distance-remainder;
3388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int numSegments = coverage/patWidth;
3398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        float patternOffset = 0;
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Special case 1px dotted borders for speed.
3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (patWidth == 1)
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            patternOffset = 1.0;
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            bool evenNumberOfSegments = !(numSegments % 2);
3468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (remainder)
3478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                evenNumberOfSegments = !evenNumberOfSegments;
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (evenNumberOfSegments) {
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (remainder) {
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    patternOffset += patWidth - remainder;
351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    patternOffset += remainder / 2;
352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                } else
353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    patternOffset = patWidth / 2;
354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            } else if (!evenNumberOfSegments) {
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (remainder)
356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    patternOffset = (patWidth - remainder) / 2;
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        double dash = patWidth;
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_dash(cr, &dash, 1, patternOffset);
3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_move_to(cr, p1.x(), p1.y());
3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_line_to(cr, p2.x(), p2.y());
3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_stroke(cr);
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// This method is only used to draw the little circles used in lists.
3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::drawEllipse(const IntRect& rect)
3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3772bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float yRadius = .5 * rect.height();
3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float xRadius = .5 * rect.width();
3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_translate(cr, rect.x() + xRadius, rect.y() + yRadius);
3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_scale(cr, xRadius, yRadius);
3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI);
3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fillColor().alpha()) {
387f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, fillColor());
3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_fill_preserve(cr);
3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (strokeStyle() != NoStroke) {
392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, strokeColor());
3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_line_width(cr, strokeThickness());
3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_stroke(cr);
395db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    } else
396db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        cairo_new_path(cr);
3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled() || strokeStyle() == NoStroke)
4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int x = rect.x();
4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int y = rect.y();
4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float w = rect.width();
4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float h = rect.height();
4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float scaleFactor = h / w;
4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float reverseScaleFactor = w / h;
4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float hRadius = w / 2;
4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float vRadius = h / 2;
4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float fa = startAngle;
4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float falen =  fa + angleSpan;
4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4162bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (w != h)
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_scale(cr, 1., scaleFactor);
421231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_arc_negative(cr, x + hRadius, (y + vRadius) * reverseScaleFactor, hRadius, -fa * M_PI/180, -falen * M_PI/180);
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (w != h)
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_scale(cr, 1., reverseScaleFactor);
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    float width = strokeThickness();
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int patWidth = 0;
429231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (strokeStyle()) {
431231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case DottedStroke:
432231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        patWidth = static_cast<int>(width / 2);
433231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
434231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case DashedStroke:
435231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        patWidth = 3 * static_cast<int>(width / 2);
436231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
437231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    default:
438231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
441f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setSourceRGBAFromColor(cr, strokeColor());
4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (patWidth) {
4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Example: 80 pixels with a width of 30 pixels.
4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Remainder is 20.  The maximum pixels of line we could paint
4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // will be 50 pixels.
4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int distance;
4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (hRadius == vRadius)
4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            distance = static_cast<int>((M_PI * hRadius) / 2.0);
4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else // We are elliptical and will have to estimate the distance
4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            distance = static_cast<int>((M_PI * sqrtf((hRadius * hRadius + vRadius * vRadius) / 2.0)) / 2.0);
452231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int remainder = distance % patWidth;
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int coverage = distance - remainder;
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        int numSegments = coverage / patWidth;
4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        float patternOffset = 0.0;
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Special case 1px dotted borders for speed.
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (patWidth == 1)
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            patternOffset = 1.0;
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else {
462231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            bool evenNumberOfSegments = !(numSegments % 2);
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (remainder)
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                evenNumberOfSegments = !evenNumberOfSegments;
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (evenNumberOfSegments) {
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (remainder) {
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    patternOffset += patWidth - remainder;
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    patternOffset += remainder / 2.0;
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                } else
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    patternOffset = patWidth / 2.0;
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            } else {
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                if (remainder)
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    patternOffset = (patWidth - remainder) / 2.0;
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        double dash = patWidth;
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_dash(cr, &dash, 1, patternOffset);
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_stroke(cr);
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
4888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (npoints <= 1)
4918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
4928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4932bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
4948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
4968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
497db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    addConvexPolygonToContext(cr, npoints, points);
4988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (fillColor().alpha()) {
500f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, fillColor());
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_fill_preserve(cr);
5038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
5048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (strokeStyle() != NoStroke) {
506f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setSourceRGBAFromColor(cr, strokeColor());
5078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_line_width(cr, strokeThickness());
5088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_stroke(cr);
509db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    } else
510db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block        cairo_new_path(cr);
5118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
5138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5150617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialiased)
516ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{
517ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (paintingDisabled())
518ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
519ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
520ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    if (numPoints <= 1)
521ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return;
522db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
5232bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
524db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
525db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_new_path(cr);
526db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
527db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_antialias_t savedAntialiasRule = cairo_get_antialias(cr);
528db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
5295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    cairo_set_antialias(cr, antialiased ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
530db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
531db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    addConvexPolygonToContext(cr, numPoints, points);
532db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_clip(cr);
533db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block
534db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_set_antialias(cr, savedAntialiasRule);
535db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    cairo_set_fill_rule(cr, savedFillRule);
536ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block}
537ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
538f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GraphicsContext::fillPath(const Path& path)
5398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
5418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5432bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
544f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPathOnCairoContext(cr, path.platformPath()->context());
545f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    fillCurrentCairoPath(this, cr);
5468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
548f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GraphicsContext::strokePath(const Path& path)
5498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
5518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5532bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
554f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPathOnCairoContext(cr, path.platformPath()->context());
555f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    strokeCurrentCairoPath(this, cr);
556d06194330da2bb8da887d2e1adeacb3a5c1504b2Steve Block}
557d06194330da2bb8da887d2e1adeacb3a5c1504b2Steve Block
5588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::fillRect(const FloatRect& rect)
5598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
5618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5632bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
564e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    cairo_save(cr);
5658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
566f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    fillCurrentCairoPath(this, cr);
567e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    cairo_restore(cr);
5688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
570a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace)
5718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
5738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
575cad810f21b803229eb11403f9209855525a25d57Steve Block    if (hasShadow())
576a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadow.drawRectShadow(this, enclosingIntRect(rect));
577a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
5788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (color.alpha())
5792bde8e466a4451c7319e3a072d118917957d6554Steve Block        fillRectSourceOver(platformContext()->cr(), rect, color);
5808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::clip(const FloatRect& rect)
5838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
5848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
5858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
5868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5872bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
5888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
5898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
5908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
5918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip(cr);
5928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, savedFillRule);
5938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->clip(rect);
5948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
596f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GraphicsContext::clipPath(const Path& path, WindRule clipRule)
597635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
598635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (paintingDisabled())
599635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return;
600635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
6012bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
602f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPathOnCairoContext(cr, path.platformPath()->context());
603635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    cairo_set_fill_rule(cr, clipRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
604635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    cairo_clip(cr);
605635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
606635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
607f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic inline void adjustFocusRingColor(Color& color)
608d0825bca7fe65beaee391d30da42e937db621564Steve Block{
609f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if !PLATFORM(GTK)
610f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // Force the alpha to 50%.  This matches what the Mac does with outline rings.
611f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    color.setRGB(makeRGBA(color.red(), color.green(), color.blue(), 127));
612f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
613f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
614f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
615f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic inline void adjustFocusRingLineWidth(int& width)
616f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
617f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if PLATFORM(GTK)
618f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    width = 2;
619f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
620f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
621f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
622f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic inline StrokeStyle focusRingStrokeStyle()
623f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
624f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if PLATFORM(GTK)
625f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return DottedStroke;
626f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#else
627f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return SolidStroke;
628f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
629f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
630f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
631f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GraphicsContext::drawFocusRing(const Path& path, int width, int /* offset */, const Color& color)
632f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
633f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // FIXME: We should draw paths that describe a rectangle with rounded corners
634f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    // so as to be consistent with how we draw rectangular focus rings.
635f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Color ringColor = color;
636f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    adjustFocusRingColor(ringColor);
637f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    adjustFocusRingLineWidth(width);
638f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
6392bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
640f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_save(cr);
641f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    appendWebCorePathToCairoContext(cr, path);
642f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setSourceRGBAFromColor(cr, ringColor);
643f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_set_line_width(cr, width);
644f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPlatformStrokeStyle(focusRingStrokeStyle());
645f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_stroke(cr);
646f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_restore(cr);
647d0825bca7fe65beaee391d30da42e937db621564Steve Block}
648d0825bca7fe65beaee391d30da42e937db621564Steve Block
649d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int /* offset */, const Color& color)
6508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
6518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
6528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
6538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned rectCount = rects.size();
6558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6562bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
6578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
6588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_push_group(cr);
6598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_new_path(cr);
6608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(GTK)
662ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#ifdef GTK_API_VERSION_2
6638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    GdkRegion* reg = gdk_region_new();
664ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#else
665ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    cairo_region_t* reg = cairo_region_create();
666ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#endif
667ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
6688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < rectCount; i++) {
669ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#ifdef GTK_API_VERSION_2
6708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        GdkRectangle rect = rects[i];
6718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        gdk_region_union_with_rect(reg, &rect);
672ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#else
673ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        cairo_rectangle_int_t rect = rects[i];
674ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        cairo_region_union_rectangle(reg, &rect);
675ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#endif
6768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
6778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    gdk_cairo_region(cr, reg);
678ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#ifdef GTK_API_VERSION_2
6798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    gdk_region_destroy(reg);
680ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#else
681ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    cairo_region_destroy(reg);
682ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#endif
6838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
684d0825bca7fe65beaee391d30da42e937db621564Steve Block    int radius = (width - 1) / 2;
685a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Path path;
686a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    for (unsigned i = 0; i < rectCount; ++i) {
687a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        if (i > 0)
688a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            path.clear();
689a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        path.addRoundedRect(rects[i], FloatSize(radius, radius));
690a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        appendWebCorePathToCairoContext(cr, path);
691a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    }
6928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
693f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Color ringColor = color;
694f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    adjustFocusRingColor(ringColor);
695f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    adjustFocusRingLineWidth(width);
696f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setSourceRGBAFromColor(cr, ringColor);
697f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    cairo_set_line_width(cr, width);
698f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setPlatformStrokeStyle(focusRingStrokeStyle());
6998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
7018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_stroke_preserve(cr);
7028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
7048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
7058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill(cr);
7068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_pop_group_to_source(cr);
7088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
7098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_paint(cr);
7108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
7118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
71381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing)
7148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
7168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
71881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    FloatPoint endPoint = origin + FloatSize(width, 0);
71981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
72081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // FIXME: Loss of precision here. Might consider rounding.
72181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    drawLine(IntPoint(origin.x(), origin.y()), IntPoint(endPoint.x(), endPoint.y()));
7228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
724ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#if !PLATFORM(GTK)
725ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "DrawErrorUnderline.h"
726ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#endif
727ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
72881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float width, TextCheckingLineStyle style)
7298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
7318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7332bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
7348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
7358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    switch (style) {
7375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    case TextCheckingSpellingLineStyle:
7388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        cairo_set_source_rgb(cr, 1, 0, 0);
7395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        break;
7405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    case TextCheckingGrammarLineStyle:
7415ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        cairo_set_source_rgb(cr, 0, 1, 0);
7425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        break;
7435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    default:
7445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        cairo_restore(cr);
7455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return;
7465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
7478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(GTK)
7498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We ignore most of the provided constants in favour of the platform style
7508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);
7518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else
752ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    drawErrorUnderline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);
7538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
7548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
7568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochFloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect, RoundingMode)
7598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatRect result;
7618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double x = frect.x();
7628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double y = frect.y();
7632bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
7648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_user_to_device(cr, &x, &y);
7658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    x = round(x);
7668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    y = round(y);
7678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_device_to_user(cr, &x, &y);
76881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    result.setX(narrowPrecisionToFloat(x));
76981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    result.setY(narrowPrecisionToFloat(y));
77081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
77181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // We must ensure width and height are at least 1 (or -1) when
77281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    // we're given float values in the range between 0 and 1 (or -1 and 0).
77381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    double width = frect.width();
77481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    double height = frect.height();
77581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    cairo_user_to_device_distance(cr, &width, &height);
77681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (width > -1 && width < 0)
77781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        width = -1;
77881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else if (width > 0 && width < 1)
77981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        width = 1;
78081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
78181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        width = round(width);
78281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (height > -1 && width < 0)
78381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        height = -1;
78481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else if (height > 0 && height < 1)
78581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        height = 1;
78681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    else
78781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        height = round(height);
78881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    cairo_device_to_user_distance(cr, &width, &height);
78981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    result.setWidth(narrowPrecisionToFloat(width));
79081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    result.setHeight(narrowPrecisionToFloat(height));
79181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
7928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
7938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
7948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::translate(float x, float y)
7968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
7978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
7988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
7998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8002bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
8018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_translate(cr, x, y);
8028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->translate(x, y);
8038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
805643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid GraphicsContext::setPlatformFillColor(const Color& col, ColorSpace colorSpace)
8068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Cairo contexts can't hold separate fill and stroke colors
8088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // so we set them just before we actually fill or stroke
8098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
811643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid GraphicsContext::setPlatformStrokeColor(const Color& col, ColorSpace colorSpace)
8128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Cairo contexts can't hold separate fill and stroke colors
8148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // so we set them just before we actually fill or stroke
8158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setPlatformStrokeThickness(float strokeThickness)
8188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
8208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8222bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_line_width(platformContext()->cr(), strokeThickness);
8238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
825cad810f21b803229eb11403f9209855525a25d57Steve Blockvoid GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
8268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static double dashPattern[] = {5.0, 5.0};
8288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static double dotPattern[] = {1.0, 1.0};
8298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
8318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (strokeStyle) {
8348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case NoStroke:
8358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // FIXME: is it the right way to emulate NoStroke?
8362bde8e466a4451c7319e3a072d118917957d6554Steve Block        cairo_set_line_width(platformContext()->cr(), 0);
8378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
8388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case SolidStroke:
8392bde8e466a4451c7319e3a072d118917957d6554Steve Block        cairo_set_dash(platformContext()->cr(), 0, 0, 0);
8408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
8418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case DottedStroke:
8422bde8e466a4451c7319e3a072d118917957d6554Steve Block        cairo_set_dash(platformContext()->cr(), dotPattern, 2, 0);
8438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
8448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    case DashedStroke:
8452bde8e466a4451c7319e3a072d118917957d6554Steve Block        cairo_set_dash(platformContext()->cr(), dashPattern, 2, 0);
8468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
8478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
8488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
8518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    notImplemented();
8538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8555e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid GraphicsContext::concatCTM(const AffineTransform& transform)
8565e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{
8575e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    if (paintingDisabled())
8585e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block        return;
8595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
8602bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
8615e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    const cairo_matrix_t matrix = cairo_matrix_t(transform);
8625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    cairo_transform(cr, &matrix);
8635e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    m_data->concatCTM(transform);
8645e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block}
8655e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block
86681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid GraphicsContext::setCTM(const AffineTransform& transform)
86781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
86881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    if (paintingDisabled())
86981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        return;
87081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8712bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
87281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    const cairo_matrix_t matrix = cairo_matrix_t(transform);
87381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    cairo_set_matrix(cr, &matrix);
87481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_data->setCTM(transform);
87581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
87681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
8778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
8788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
8798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
8808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
8818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8822bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
8838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    clip(rect);
8848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Path p;
8868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    FloatRect r(rect);
8878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add outer ellipse
8888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    p.addEllipse(r);
8898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Add inner ellipse
8908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    r.inflate(-thickness);
8918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    p.addEllipse(r);
892db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    appendWebCorePathToCairoContext(cr, p);
8938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
8948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
8958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
8968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip(cr);
8978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, savedFillRule);
8988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
8998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
900a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid GraphicsContext::setPlatformShadow(FloatSize const& size, float blur, Color const& color, ColorSpace)
9018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
902a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // Cairo doesn't support shadows natively, they are drawn manually in the draw* functions
903f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (m_state.shadowsIgnoreTransforms) {
904643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Meaning that this graphics context is associated with a CanvasRenderingContext
905643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // We flip the height since CG and HTML5 Canvas have opposite Y axis
906f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_state.shadowOffset = FloatSize(size.width(), -size.height());
907a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height()));
908a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else
909a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height()));
910f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
911f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_data->shadow.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms);
912643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
913643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
914a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochContextShadow* GraphicsContext::contextShadow()
915643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
916a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return &m_data->shadow;
9178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::clearPlatformShadow()
9208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
921a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_data->shadow.clear();
9228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::beginTransparencyLayer(float opacity)
9258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
9278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9292bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
9308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_push_group(cr);
9318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->layers.append(opacity);
9328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->beginTransparencyLayer();
9338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::endTransparencyLayer()
9368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
9388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9402bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
9418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_pop_group_to_source(cr);
9438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_paint_with_alpha(cr, m_data->layers.last());
9448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->layers.removeLast();
9458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->endTransparencyLayer();
9468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::clearRect(const FloatRect& rect)
9498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
9518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9532bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
9548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
9568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
9578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
9588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill(cr);
9598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
9608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::strokeRect(const FloatRect& rect, float width)
9638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
9658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9672bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
9688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
9698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
9708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_line_width(cr, width);
971f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    strokeCurrentCairoPath(this, cr);
9728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
9738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setLineCap(LineCap lineCap)
9768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
9788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
9798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT;
9818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (lineCap) {
982231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case ButtCap:
983231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // no-op
984231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
985231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case RoundCap:
986231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        cairoCap = CAIRO_LINE_CAP_ROUND;
987231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
988231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case SquareCap:
989231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        cairoCap = CAIRO_LINE_CAP_SQUARE;
990231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
9918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
9922bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_line_cap(platformContext()->cr(), cairoCap);
9938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
9968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
9972bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_dash(platformContext()->cr(), dashes.data(), dashes.size(), dashOffset);
9988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
9998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setLineJoin(LineJoin lineJoin)
10018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER;
10068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    switch (lineJoin) {
1007231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case MiterJoin:
1008231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // no-op
1009231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
1010231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case RoundJoin:
1011231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        cairoJoin = CAIRO_LINE_JOIN_ROUND;
1012231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
1013231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    case BevelJoin:
1014231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        cairoJoin = CAIRO_LINE_JOIN_BEVEL;
1015231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        break;
10168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
10172bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_line_join(platformContext()->cr(), cairoJoin);
10188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setMiterLimit(float miter)
10218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10252bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_miter_limit(platformContext()->cr(), miter);
10268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setAlpha(float alpha)
10298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1030f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_state.globalAlpha = alpha;
10318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectfloat GraphicsContext::getAlpha()
10348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1035f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return m_state.globalAlpha;
10368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
10398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10432bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_operator(platformContext()->cr(), toCairoOperator(op));
10448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::clip(const Path& path)
10478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10512bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
1052bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    OwnPtr<cairo_path_t> p(cairo_copy_path(path.platformPath()->context()));
1053bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    cairo_append_path(cr, p.get());
10548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
10558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
10568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip(cr);
10578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, savedFillRule);
10588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->clip(path);
10598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1061cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Blockvoid GraphicsContext::canvasClip(const Path& path)
1062cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block{
1063cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block    clip(path);
1064cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block}
1065cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block
10668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::clipOut(const Path& path)
10678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10712bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
10728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double x1, y1, x2, y2;
10738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
10748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
1075db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block    appendWebCorePathToCairoContext(cr, path);
10768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
10788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
10798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip(cr);
10808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, savedFillRule);
10818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::rotate(float radians)
10848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10882bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_rotate(platformContext()->cr(), radians);
10898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->rotate(radians);
10908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
10918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::scale(const FloatSize& size)
10938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
10958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
10968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10972bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_scale(platformContext()->cr(), size.width(), size.height());
10988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->scale(size);
10998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::clipOut(const IntRect& r)
11028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
11048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11062bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
11078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    double x1, y1, x2, y2;
11088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
1109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
11108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
11118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
11128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
11138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_clip(cr);
11148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_set_fill_rule(cr, savedFillRule);
11158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenstatic inline FloatPoint getPhase(const FloatRect& dest, const FloatRect& tile)
11185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
11195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    FloatPoint phase = dest.location();
11205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    phase.move(-tile.x(), -tile.y());
11215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
11225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return phase;
11235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
11245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1125643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
11268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
11288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1130cad810f21b803229eb11403f9209855525a25d57Steve Block    if (hasShadow())
1131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_data->shadow.drawRectShadow(this, r, topLeft, topRight, bottomLeft, bottomRight);
1132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
11332bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_t* cr = platformContext()->cr();
11348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_save(cr);
1135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    Path path;
1136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    path.addRoundedRect(r, topLeft, topRight, bottomLeft, bottomRight);
1137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    appendWebCorePathToCairoContext(cr, path);
1138f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    setSourceRGBAFromColor(cr, color);
11398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_fill(cr);
11408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    cairo_restore(cr);
11418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if PLATFORM(GTK)
11448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setGdkExposeEvent(GdkEventExpose* expose)
11458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_data->expose = expose;
11478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectGdkEventExpose* GraphicsContext::gdkExposeEvent() const
11508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_data->expose;
11528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1154f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochGdkWindow* GraphicsContext::gdkWindow() const
11558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_data->expose)
11578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
11588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1159f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    return m_data->expose->window;
11608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
11628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid GraphicsContext::setPlatformShouldAntialias(bool enable)
11648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (paintingDisabled())
11668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
11678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // When true, use the default Cairo backend antialias mode (usually this
11698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // enables standard 'grayscale' antialiasing); false to explicitly disable
11708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // antialiasing. This is the same strategy as used in drawConvexPolygon().
11712bde8e466a4451c7319e3a072d118917957d6554Steve Block    cairo_set_antialias(platformContext()->cr(), enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
11728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
11758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectInterpolationQuality GraphicsContext::imageInterpolationQuality() const
11798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
11808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return InterpolationDefault;
11818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
11828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore
11848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
11852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif // USE(CAIRO)
1186