From 7e0c97ce9fee368099be163003b85c3ba9531426 Mon Sep 17 00:00:00 2001 From: "tor%cs.brown.edu" Date: Tue, 10 Feb 2004 20:18:09 +0000 Subject: [PATCH] SVG Cairo Renderer (not part of build) --- layout/svg/renderer/src/cairo/Makefile.in | 93 +++++ .../renderer/src/cairo/nsISVGCairoCanvas.h | 70 ++++ .../renderer/src/cairo/nsSVGCairoCanvas.cpp | 219 ++++++++++++ .../svg/renderer/src/cairo/nsSVGCairoCanvas.h | 56 +++ .../src/cairo/nsSVGCairoPathBuilder.cpp | 271 ++++++++++++++ .../src/cairo/nsSVGCairoPathBuilder.h | 53 +++ .../src/cairo/nsSVGCairoPathGeometry.cpp | 332 ++++++++++++++++++ .../src/cairo/nsSVGCairoPathGeometry.h | 54 +++ .../renderer/src/cairo/nsSVGCairoRegion.cpp | 116 ++++++ .../svg/renderer/src/cairo/nsSVGCairoRegion.h | 48 +++ .../renderer/src/cairo/nsSVGRendererCairo.cpp | 170 +++++++++ 11 files changed, 1482 insertions(+) create mode 100644 layout/svg/renderer/src/cairo/Makefile.in create mode 100644 layout/svg/renderer/src/cairo/nsISVGCairoCanvas.h create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoCanvas.cpp create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoCanvas.h create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.cpp create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.h create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.cpp create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.h create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoRegion.cpp create mode 100644 layout/svg/renderer/src/cairo/nsSVGCairoRegion.h create mode 100644 layout/svg/renderer/src/cairo/nsSVGRendererCairo.cpp diff --git a/layout/svg/renderer/src/cairo/Makefile.in b/layout/svg/renderer/src/cairo/Makefile.in new file mode 100644 index 000000000000..c20317dad78b --- /dev/null +++ b/layout/svg/renderer/src/cairo/Makefile.in @@ -0,0 +1,93 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Mozilla SVG Cairo Renderer project. +# +# The Initial Developer of the Original Code is IBM Corporation. +# Portions created by the Initial Developer are Copyright (C) 2004 +# the Initial Developer. All Rights Reserved. +# +# Parts of this file contain code derived from the following files(s) +# of the Mozilla SVG project (these parts are Copyright (C) by their +# respective copyright-holders): +# layout/svg/renderer/src/libart/Makefile.in +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE = layout +LIBRARY_NAME = gksvgrenderercairo_s +REQUIRES = \ + xpcom \ + widget \ + pref \ + gfx \ + imglib2 \ + string \ + dom \ + content \ + necko \ + util \ + uconv \ + windowwatcher \ + $(NULL) + +CPPSRCS = \ + nsSVGRendererCairo.cpp \ + nsSVGCairoCanvas.cpp \ + nsSVGCairoPathGeometry.cpp \ + nsSVGCairoPathBuilder.cpp \ + nsSVGCairoRegion.cpp \ + $(NULL) + +# we don't want the shared lib, but we want to force the creation of a static lib. +FORCE_STATIC_LIB = 1 + +# ********************************************************************** + +include $(topsrcdir)/config/rules.mk +# include $(topsrcdir)/config/config.mk + +CFLAGS += $(MOZ_CAIRO_CFLAGS) +CXXFLAGS += $(MOZ_CAIRO_CFLAGS) + +CFLAGS += $(MOZ_GTK_CFLAGS) $(MOZ_GTK2_CFLAGS) +CXXFLAGS += $(MOZ_GTK_CFLAGS) $(MOZ_GTK2_CFLAGS) + +LOCAL_INCLUDES = \ + -I$(topsrcdir)/gfx/src \ + -I$(topsrcdir)/gfx/src/gtk \ + $(NULL) + + + diff --git a/layout/svg/renderer/src/cairo/nsISVGCairoCanvas.h b/layout/svg/renderer/src/cairo/nsISVGCairoCanvas.h new file mode 100644 index 000000000000..12fb0a17d59f --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsISVGCairoCanvas.h @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsISVGLibartCanvas.h + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#ifndef __NS_ISVGCAIRO_CANVAS_H__ +#define __NS_ISVGCAIRO_CANVAS_H__ + +#include "nsISVGRendererCanvas.h" +#include + +// {590fdf19-7c06-4719-a17a-3706e2523fbc} +#define NS_ISVGCAIROCANVAS_IID \ +{ 0x590fdf19, 0x7c06, 0x4719, { 0xa1, 0x7a, 0x37, 0x06, 0xe2, 0x52, 0x3f, 0xbc } } + +/** + * \addtogroup cairo_renderer Cairo Rendering Engine + * @{ + */ +////////////////////////////////////////////////////////////////////// +/** + * 'Private' rendering engine interface + */ +class nsISVGCairoCanvas : public nsISVGRendererCanvas +{ +public: + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGCAIROCANVAS_IID) + + NS_IMETHOD_(cairo_t*) GetContext() = 0; +}; + +/** @} */ + +#endif //__NS_ISVGCAIRO_CANVAS_H__ diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoCanvas.cpp b/layout/svg/renderer/src/cairo/nsSVGCairoCanvas.cpp new file mode 100644 index 000000000000..66a7b01fbc8d --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoCanvas.cpp @@ -0,0 +1,219 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGLibartCanvas.cpp + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#include "nsCOMPtr.h" +#include "nsSVGCairoCanvas.h" +#include "nsISVGCairoCanvas.h" +#include "nsIRenderingContext.h" +#include "nsIDeviceContext.h" +#include "nsTransform2D.h" +#include "nsIPresContext.h" +#include "nsRect.h" +#include "nsRenderingContextGTK.h" +#include +#include + +/** + * \addtogroup cairo_renderer Cairo Rendering Engine + * @{ + */ +////////////////////////////////////////////////////////////////////// +/** + * Cairo canvas implementation + */ +class nsSVGCairoCanvas : public nsISVGCairoCanvas +{ +public: + nsSVGCairoCanvas(); + ~nsSVGCairoCanvas(); + nsresult Init(nsIRenderingContext* ctx, nsIPresContext* presContext, + const nsRect & dirtyRect); + + // nsISupports interface: + NS_DECL_ISUPPORTS + + // nsISVGRendererCanvas interface: + NS_DECL_NSISVGRENDERERCANVAS + + // nsISVGCairoCanvas interface: + NS_IMETHOD_(cairo_t*) GetContext() { return mCR; } + +private: + nsCOMPtr mMozContext; + nsCOMPtr mPresContext; + cairo_t *mCR; + PRUint32 mWidth, mHeight; +}; + + +/** @} */ + +//---------------------------------------------------------------------- +// implementation: + +nsSVGCairoCanvas::nsSVGCairoCanvas() +{ +} + +nsSVGCairoCanvas::~nsSVGCairoCanvas() +{ + mMozContext = nsnull; + mPresContext = nsnull; + + cairo_destroy(mCR); +} + +nsresult +nsSVGCairoCanvas::Init(nsIRenderingContext *ctx, + nsIPresContext *presContext, + const nsRect &dirtyRect) +{ + mPresContext = presContext; + mMozContext = ctx; + NS_ASSERTION(mMozContext, "empty rendering context"); + + nsDrawingSurfaceGTK *surface; + ctx->GetDrawingSurface((nsDrawingSurface*)&surface); + surface->GetSize(&mWidth, &mHeight); + GdkDrawable *drawable = surface->GetDrawable(); + + mCR = cairo_create(); + cairo_set_target_drawable(mCR, + GDK_WINDOW_XDISPLAY(drawable), + GDK_WINDOW_XWINDOW(drawable)); + + // get the translation set on the rendering context. It will be in + // displayunits (i.e. pixels*scale), *not* pixels: + nsTransform2D* xform; + mMozContext->GetCurrentTransform(xform); + float dx, dy; + xform->GetTranslation(&dx, &dy); + cairo_translate(mCR, dx, dy); + + return NS_OK; +} + +nsresult +NS_NewSVGCairoCanvas(nsISVGRendererCanvas **result, + nsIRenderingContext *ctx, + nsIPresContext *presContext, + const nsRect & dirtyRect) +{ + nsSVGCairoCanvas* pg = new nsSVGCairoCanvas(); + if (!pg) return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pg); + + nsresult rv = pg->Init(ctx, presContext, dirtyRect); + + if (NS_FAILED(rv)) { + NS_RELEASE(pg); + return rv; + } + + *result = pg; + return rv; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ADDREF(nsSVGCairoCanvas) +NS_IMPL_RELEASE(nsSVGCairoCanvas) + +NS_INTERFACE_MAP_BEGIN(nsSVGCairoCanvas) +NS_INTERFACE_MAP_ENTRY(nsISVGRendererCanvas) +NS_INTERFACE_MAP_ENTRY(nsISVGCairoCanvas) +NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +//---------------------------------------------------------------------- +// nsISVGRendererCanvas methods: + +/** Implements [noscript] nsIRenderingContext lockRenderingContext(const in nsRectRef rect); */ +NS_IMETHODIMP +nsSVGCairoCanvas::LockRenderingContext(const nsRect & rect, + nsIRenderingContext **_retval) +{ + // XXX do we need to flush? + Flush(); + + *_retval = mMozContext; + NS_ADDREF(*_retval); + return NS_OK; +} + +/** Implements void unlockRenderingContext(); */ +NS_IMETHODIMP +nsSVGCairoCanvas::UnlockRenderingContext() +{ + return NS_OK; +} + +/** Implements nsIPresContext getPresContext(); */ +NS_IMETHODIMP +nsSVGCairoCanvas::GetPresContext(nsIPresContext **_retval) +{ + *_retval = mPresContext; + NS_IF_ADDREF(*_retval); + return NS_OK; +} + +/** Implements void clear(in nscolor color); */ +NS_IMETHODIMP +nsSVGCairoCanvas::Clear(nscolor color) +{ + cairo_set_rgb_color(mCR, + NS_GET_R(color)/255.0, + NS_GET_G(color)/255.0, + NS_GET_B(color)/255.0); + cairo_rectangle(mCR, 0, 0, mWidth, mHeight); + cairo_fill(mCR); + + return NS_OK; +} + +/** Implements void flush(); */ +NS_IMETHODIMP +nsSVGCairoCanvas::Flush() +{ + return NS_OK; +} diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoCanvas.h b/layout/svg/renderer/src/cairo/nsSVGCairoCanvas.h new file mode 100644 index 000000000000..acf33f34856b --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoCanvas.h @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGLibartCanvas.h + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#ifndef __NS_SVGCAIRO_CANVAS_H__ +#define __NS_SVGCAIRO_CANVAS_H__ + +class nsIRenderingContext; +class nsISVGRendererCanvas; +class nsIPresContext; +struct nsRect; + +nsresult +NS_NewSVGCairoCanvas(nsISVGRendererCanvas **result, + nsIRenderingContext *ctx, + nsIPresContext *presContext, + const nsRect & dirtyRect); + +#endif // __NS_SVGCAIRO_CANVAS_H__ diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.cpp b/layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.cpp new file mode 100644 index 000000000000..9523a0a18858 --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.cpp @@ -0,0 +1,271 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGLibartBPathBuilder.cpp + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#include "nsCOMPtr.h" +#include "nsISVGRendererPathBuilder.h" +#include "nsSVGCairoPathBuilder.h" +#include +#include + +/** + * \addtogroup cairo_renderer Cairo Rendering Engine + * @{ + */ +//////////////////////////////////////////////////////////////////////// +/** + * Libart path builder implementation + */ +class nsSVGCairoPathBuilder : public nsISVGRendererPathBuilder +{ +protected: + friend nsresult NS_NewSVGCairoPathBuilder(nsISVGRendererPathBuilder **result, + cairo_t *ctx); + + nsSVGCairoPathBuilder(cairo_t *ctx); + +public: + // nsISupports interface: + NS_DECL_ISUPPORTS + + // nsISVGRendererPathBuilder interface: + NS_DECL_NSISVGRENDERERPATHBUILDER + +private: + + cairo_t *mCR; +}; + +/** @} */ + +//---------------------------------------------------------------------- +// implementation: + +nsSVGCairoPathBuilder::nsSVGCairoPathBuilder(cairo_t *ctx) + : mCR(ctx) +{ + cairo_new_path(mCR); +} + +nsresult +NS_NewSVGCairoPathBuilder(nsISVGRendererPathBuilder **result, + cairo_t *ctx) +{ + *result = new nsSVGCairoPathBuilder(ctx); + if (!result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*result); + + return NS_OK; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ADDREF(nsSVGCairoPathBuilder) +NS_IMPL_RELEASE(nsSVGCairoPathBuilder) + +NS_INTERFACE_MAP_BEGIN(nsSVGCairoPathBuilder) +NS_INTERFACE_MAP_ENTRY(nsISVGRendererPathBuilder) +NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +//---------------------------------------------------------------------- +// nsISVGRendererPathBuilder methods: + +/** Implements void moveto(in float x, in float y); */ +NS_IMETHODIMP +nsSVGCairoPathBuilder::Moveto(float x, float y) +{ + cairo_move_to(mCR, x, y); + return NS_OK; +} + +/** Implements void lineto(in float x, in float y); */ +NS_IMETHODIMP +nsSVGCairoPathBuilder::Lineto(float x, float y) +{ + cairo_line_to(mCR, x, y); + return NS_OK; +} + +/** Implements void curveto(in float x, in float y, in float x1, in float y1, in float x2, in float y2); */ +NS_IMETHODIMP +nsSVGCairoPathBuilder::Curveto(float x, float y, float x1, float y1, float x2, float y2) +{ + cairo_curve_to(mCR, x1, y1, x2, y2, x, y); + return NS_OK; +} + +/* helper for Arcto : */ +static inline double CalcVectorAngle(double ux, double uy, double vx, double vy) +{ + double ta = atan2(uy, ux); + double tb = atan2(vy, vx); + if (tb >= ta) + return tb-ta; + return 6.28318530718 - (ta-tb); +} + + +/** Implements void arcto(in float x, in float y, in float r1, in float r2, in float angle, in boolean largeArcFlag, in boolean sweepFlag); */ +NS_IMETHODIMP +nsSVGCairoPathBuilder::Arcto(float x2, float y2, float rx, float ry, float angle, PRBool largeArcFlag, PRBool sweepFlag) +{ + const double pi = 3.14159265359; + const double radPerDeg = pi/180.0; + + double x1=0.0, y1=0.0; + cairo_current_point(mCR, &x1, &y1); + + // 1. Treat out-of-range parameters as described in + // http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes + + // If the endpoints (x1, y1) and (x2, y2) are identical, then this + // is equivalent to omitting the elliptical arc segment entirely + if (x1 == x2 && y1 == y2) return NS_OK; + + // If rX = 0 or rY = 0 then this arc is treated as a straight line + // segment (a "lineto") joining the endpoints. + if (rx == 0.0f || ry == 0.0f) { + Lineto(x2, y2); + return NS_OK; + } + + // If rX or rY have negative signs, these are dropped; the absolute + // value is used instead. + if (rx<0.0) rx = -rx; + if (ry<0.0) ry = -ry; + + // 2. convert to center parameterization as shown in + // http://www.w3.org/TR/SVG/implnote.html + double sinPhi = sin(angle*radPerDeg); + double cosPhi = cos(angle*radPerDeg); + + double x1dash = cosPhi * (x1-x2)/2.0 + sinPhi * (y1-y2)/2.0; + double y1dash = -sinPhi * (x1-x2)/2.0 + cosPhi * (y1-y2)/2.0; + + double root; + double numerator = rx*rx*ry*ry - rx*rx*y1dash*y1dash - ry*ry*x1dash*x1dash; + + if (numerator < 0.0) { + // If rX , rY and are such that there is no solution (basically, + // the ellipse is not big enough to reach from (x1, y1) to (x2, + // y2)) then the ellipse is scaled up uniformly until there is + // exactly one solution (until the ellipse is just big enough). + + // -> find factor s, such that numerator' with rx'=s*rx and + // ry'=s*ry becomes 0 : + float s = (float)sqrt(1.0 - numerator/(rx*rx*ry*ry)); + + rx *= s; + ry *= s; + root = 0.0; + + } + else { + root = (largeArcFlag == sweepFlag ? -1.0 : 1.0) * + sqrt( numerator/(rx*rx*y1dash*y1dash+ry*ry*x1dash*x1dash) ); + } + + double cxdash = root*rx*y1dash/ry; + double cydash = -root*ry*x1dash/rx; + + double cx = cosPhi * cxdash - sinPhi * cydash + (x1+x2)/2.0; + double cy = sinPhi * cxdash + cosPhi * cydash + (y1+y2)/2.0; + double theta1 = CalcVectorAngle(1.0, 0.0, (x1dash-cxdash)/rx, (y1dash-cydash)/ry); + double dtheta = CalcVectorAngle((x1dash-cxdash)/rx, (y1dash-cydash)/ry, + (-x1dash-cxdash)/rx, (-y1dash-cydash)/ry); + if (!sweepFlag && dtheta>0) + dtheta -= 2.0*pi; + else if (sweepFlag && dtheta<0) + dtheta += 2.0*pi; + + // 3. convert into cubic bezier segments <= 90deg + int segments = (int)ceil(fabs(dtheta/(pi/2.0))); + double delta = dtheta/segments; + double t = 8.0/3.0 * sin(delta/4.0) * sin(delta/4.0) / sin(delta/2.0); + + for (int i = 0; i < segments; ++i) { + double cosTheta1 = cos(theta1); + double sinTheta1 = sin(theta1); + double theta2 = theta1 + delta; + double cosTheta2 = cos(theta2); + double sinTheta2 = sin(theta2); + + // a) calculate endpoint of the segment: + double xe = cosPhi * rx*cosTheta2 - sinPhi * ry*sinTheta2 + cx; + double ye = sinPhi * rx*cosTheta2 + cosPhi * ry*sinTheta2 + cy; + + // b) calculate gradients at start/end points of segment: + double dx1 = t * ( - cosPhi * rx*sinTheta1 - sinPhi * ry*cosTheta1); + double dy1 = t * ( - sinPhi * rx*sinTheta1 + cosPhi * ry*cosTheta1); + + double dxe = t * ( cosPhi * rx*sinTheta2 + sinPhi * ry*cosTheta2); + double dye = t * ( sinPhi * rx*sinTheta2 - cosPhi * ry*cosTheta2); + + // c) draw the cubic bezier: + Curveto((float)xe, (float)ye, (float)(x1+dx1), (float)(y1+dy1), + (float)(xe+dxe), (float)(ye+dye)); + + // do next segment + theta1 = theta2; + x1 = (float)xe; + y1 = (float)ye; + } + + return NS_OK; +} + +/** Implements void closePath(out float newX, out float newY); */ +NS_IMETHODIMP +nsSVGCairoPathBuilder::ClosePath(float *newX, float *newY) +{ + cairo_close_path(mCR); + return NS_OK; +} + +/** Implements void endPath(); */ +NS_IMETHODIMP +nsSVGCairoPathBuilder::EndPath() +{ + return NS_OK; +} diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.h b/layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.h new file mode 100644 index 000000000000..fc552c28d0e2 --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoPathBuilder.h @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGLibartBPathBuilder.h + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#ifndef __NS_SVGCAIRO_PATHBUILDER_H__ +#define __NS_SVGCAIRO_PATHBUILDER_H__ + +#include + +class nsISVGRendererPathBuilder; +class nsISVGPathGeometrySource; + +nsresult NS_NewSVGCairoPathBuilder(nsISVGRendererPathBuilder **result, + cairo_t* ctx); + +#endif // __NS_SVGCAIRO_PATHBUILDER_H__ diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.cpp b/layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.cpp new file mode 100644 index 000000000000..ae5fb909b3af --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.cpp @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGLibartPathGeometry.cpp + * + * Contributor(s): + * Alex Fritze + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#include "nsCOMPtr.h" +#include "nsSVGCairoPathGeometry.h" +#include "nsISVGRendererPathGeometry.h" +#include "nsISVGCairoCanvas.h" +#include "nsIDOMSVGMatrix.h" +#include "nsISVGRendererRegion.h" +#include "nsISVGPathGeometrySource.h" +#include "nsISVGRendererPathBuilder.h" +#include "nsSVGCairoPathBuilder.h" +#include "nsMemory.h" +#include +#include "nsSVGCairoRegion.h" + +/** + * \addtogroup cairo_renderer Cairo Rendering Engine + * @{ + */ +//////////////////////////////////////////////////////////////////////// +/** + * Cairo path geometry implementation + */ +class nsSVGCairoPathGeometry : public nsISVGRendererPathGeometry +{ +protected: + friend nsresult NS_NewSVGCairoPathGeometry(nsISVGRendererPathGeometry **result, + nsISVGPathGeometrySource *src); + + nsSVGCairoPathGeometry(); + ~nsSVGCairoPathGeometry(); + nsresult Init(nsISVGPathGeometrySource* src); + +public: + // nsISupports interface: + NS_DECL_ISUPPORTS + + // nsISVGRendererPathGeometry interface: + NS_DECL_NSISVGRENDERERPATHGEOMETRY + +private: + nsCOMPtr mSource; + nsCOMPtr mCoveredRegion; + + void GeneratePath(cairo_t *ctx); +}; + +/** @} */ + + +//---------------------------------------------------------------------- +// implementation: + +nsSVGCairoPathGeometry::nsSVGCairoPathGeometry() +{ +} + +nsSVGCairoPathGeometry::~nsSVGCairoPathGeometry() +{ +} + +nsresult nsSVGCairoPathGeometry::Init(nsISVGPathGeometrySource* src) +{ + mSource = src; + return NS_OK; +} + + +nsresult +NS_NewSVGCairoPathGeometry(nsISVGRendererPathGeometry **result, + nsISVGPathGeometrySource *src) +{ + nsSVGCairoPathGeometry* pg = new nsSVGCairoPathGeometry(); + if (!pg) return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(pg); + + nsresult rv = pg->Init(src); + + if (NS_FAILED(rv)) { + NS_RELEASE(pg); + return rv; + } + + *result = pg; + return rv; +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ADDREF(nsSVGCairoPathGeometry) +NS_IMPL_RELEASE(nsSVGCairoPathGeometry) + +NS_INTERFACE_MAP_BEGIN(nsSVGCairoPathGeometry) +NS_INTERFACE_MAP_ENTRY(nsISVGRendererPathGeometry) +NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +//---------------------------------------------------------------------- + +void +nsSVGCairoPathGeometry::GeneratePath(cairo_t *ctx) +{ + nsCOMPtr ctm; + mSource->GetCTM(getter_AddRefs(ctm)); + NS_ASSERTION(ctm, "graphic source didn't specify a ctm"); + + float m[6]; + float val; + ctm->GetA(&val); + m[0] = val; + + ctm->GetB(&val); + m[1] = val; + + ctm->GetC(&val); + m[2] = val; + + ctm->GetD(&val); + m[3] = val; + + ctm->GetE(&val); + m[4] = val; + + ctm->GetF(&val); + m[5] = val; + + cairo_matrix_t *matrix = cairo_matrix_create(); + cairo_matrix_set_affine(matrix, m[0], m[1], m[2], m[3], m[4], m[5]); + cairo_concat_matrix(ctx, matrix); + + nsCOMPtr builder; + NS_NewSVGCairoPathBuilder(getter_AddRefs(builder), ctx); + mSource->ConstructPath(builder); + builder->EndPath(); +} + + +//---------------------------------------------------------------------- +// nsISVGRendererPathGeometry methods: + +/** Implements void render(in nsISVGRendererCanvas canvas); */ +NS_IMETHODIMP +nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas) +{ + nsCOMPtr cairoCanvas = do_QueryInterface(canvas); + NS_ASSERTION(cairoCanvas, "wrong svg render context for geometry!"); + if (!cairoCanvas) return NS_ERROR_FAILURE; + + cairo_t *ctx = cairoCanvas->GetContext(); + + /* save/pop the state so we don't screw up the xform */ + cairo_save(ctx); + + GeneratePath(ctx); + + PRUint16 type; + + PRBool bStroking = PR_FALSE; + mSource->GetStrokePaintType(&type); + if (type == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) + bStroking = PR_TRUE; + + mSource->GetFillPaintType(&type); + if (type == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) { + if (bStroking) + cairo_save(ctx); + + nscolor rgb; + mSource->GetFillPaint(&rgb); + float opacity; + mSource->GetFillOpacity(&opacity); + + cairo_set_rgb_color(ctx, + NS_GET_R(rgb)/255.0, + NS_GET_G(rgb)/255.0, + NS_GET_B(rgb)/255.0); + cairo_set_alpha(ctx, double(opacity)); + + cairo_fill(ctx); + + if (bStroking) + cairo_restore(ctx); + } + + if (bStroking) { + nscolor rgb; + mSource->GetStrokePaint(&rgb); + float opacity; + mSource->GetStrokeOpacity(&opacity); + cairo_set_rgb_color(ctx, + NS_GET_R(rgb)/255.0, + NS_GET_G(rgb)/255.0, + NS_GET_B(rgb)/255.0); + cairo_set_alpha(ctx, double(opacity)); + + float width; + mSource->GetStrokeWidth(&width); + cairo_set_line_width(ctx, double(width)); + + PRUint16 capStyle; + mSource->GetStrokeLinecap(&capStyle); + switch (capStyle) { + case nsISVGGeometrySource::STROKE_LINECAP_BUTT: + cairo_set_line_cap(ctx, CAIRO_LINE_CAP_BUTT); + break; + case nsISVGGeometrySource::STROKE_LINECAP_ROUND: + cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND); + break; + case nsISVGGeometrySource::STROKE_LINECAP_SQUARE: + cairo_set_line_cap(ctx, CAIRO_LINE_CAP_SQUARE); + break; + } + + float miterlimit; + mSource->GetStrokeMiterlimit(&miterlimit); + cairo_set_miter_limit(ctx, double(miterlimit)); + + PRUint16 joinStyle; + mSource->GetStrokeLinejoin(&joinStyle); + switch(joinStyle) { + case nsISVGGeometrySource::STROKE_LINEJOIN_MITER: + cairo_set_line_join(ctx, CAIRO_LINE_JOIN_MITER); + break; + case nsISVGGeometrySource::STROKE_LINEJOIN_ROUND: + cairo_set_line_join(ctx, CAIRO_LINE_JOIN_ROUND); + break; + case nsISVGGeometrySource::STROKE_LINEJOIN_BEVEL: + cairo_set_line_join(ctx, CAIRO_LINE_JOIN_BEVEL); + break; + } + + float *dashArray, offset; + PRUint32 count; + mSource->GetStrokeDashArray(&dashArray, &count); + if (count > 0) { + double *dashes = new double[count]; + for (unsigned i=0; iGetStrokeDashoffset(&offset); + cairo_set_dash(ctx, dashes, count, double(offset)); + nsMemory::Free(dashArray); + delete [] dashes; + } + + cairo_stroke(ctx); + } + + cairo_restore(ctx); + + return NS_OK; +} + +/** Implements nsISVGRendererRegion update(in unsigned long updatemask); */ +NS_IMETHODIMP +nsSVGCairoPathGeometry::Update(PRUint32 updatemask, nsISVGRendererRegion **_retval) +{ + // XXX just return a large region for now: + return NS_NewSVGCairoRectRegion(_retval, -10000, -10000, 20000, 20000); +} + +/** Implements nsISVGRendererRegion getCoveredRegion(); */ +NS_IMETHODIMP +nsSVGCairoPathGeometry::GetCoveredRegion(nsISVGRendererRegion **_retval) +{ + // XXX just return a large region for now: + return NS_NewSVGCairoRectRegion(_retval, -10000, -10000, 20000, 20000); +} + +/** Implements boolean containsPoint(in float x, in float y); */ +NS_IMETHODIMP +nsSVGCairoPathGeometry::ContainsPoint(float x, float y, PRBool *_retval) +{ + *_retval = PR_FALSE; + + cairo_t *ctx = cairo_create(); + + GeneratePath(ctx); + cairo_default_matrix(ctx); + + PRUint16 mask = 0; + mSource->GetHittestMask(&mask); + if (mask & nsISVGPathGeometrySource::HITTEST_MASK_FILL) + *_retval = cairo_in_fill(ctx, x, y); + if (!*_retval & mask & nsISVGPathGeometrySource::HITTEST_MASK_STROKE) + *_retval = cairo_in_stroke(ctx, x, y); + + cairo_destroy(ctx); + + return NS_OK; +} diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.h b/layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.h new file mode 100644 index 000000000000..eccce4054a1b --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoPathGeometry.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGLibartPathGeometry.h + * + * Contributor(s): + * Alex Fritze (original author) + * Tim Rowley + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#ifndef __NS_SVGCAIRO_PATHGEOMETRY_H__ +#define __NS_SVGCAIRO_PATHGEOMETRY_H__ + +class nsISVGRendererPathGeometry; +class nsISVGPathGeometrySource; + +nsresult +NS_NewSVGCairoPathGeometry(nsISVGRendererPathGeometry **result, + nsISVGPathGeometrySource *src); + +#endif // __NS_SVGCAIRO_PATHGEOMETRY_H__ diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoRegion.cpp b/layout/svg/renderer/src/cairo/nsSVGCairoRegion.cpp new file mode 100644 index 000000000000..9d19a603db51 --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoRegion.cpp @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is Crocodile Clips Ltd.. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#include "nsCOMPtr.h" +#include "nsISVGRendererRegion.h" +#include "nsISVGRectangleSink.h" +#include "nsSVGCairoRegion.h" + +class nsSVGCairoRectRegion : public nsISVGRendererRegion +{ +protected: + friend nsresult NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result, + int x, int y, + int width, int height); + nsSVGCairoRectRegion(int x, int y, int w, int h); + +public: + // nsISupports interface: + NS_DECL_ISUPPORTS + + // nsISVGRendererRegion interface: + NS_DECL_NSISVGRENDERERREGION + +private: + int mX, mY, mWidth, mHeight; +}; + +//---------------------------------------------------------------------- +// implementation: + +nsresult +NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result, int x, int y, + int width, int height) +{ + *result = new nsSVGCairoRectRegion(x, y, width, height); + + if (!*result) return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*result); + return NS_OK; +} + +nsSVGCairoRectRegion::nsSVGCairoRectRegion(int x, int y, int w, int h) : + mX(x), mY(y), mWidth(w), mHeight(h) +{ +} + +//---------------------------------------------------------------------- +// nsISupports methods: + +NS_IMPL_ADDREF(nsSVGCairoRectRegion) +NS_IMPL_RELEASE(nsSVGCairoRectRegion) + +NS_INTERFACE_MAP_BEGIN(nsSVGCairoRectRegion) + NS_INTERFACE_MAP_ENTRY(nsISVGRendererRegion) + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +//---------------------------------------------------------------------- +// nsISVGRendererRegion methods: + +/** Implements nsISVGRendererRegion combine(in nsISVGRendererRegion other); */ +NS_IMETHODIMP +nsSVGCairoRectRegion::Combine(nsISVGRendererRegion *other, + nsISVGRendererRegion **_retval) +{ + nsSVGCairoRectRegion *_other = static_cast(other); // ok, i know i'm being bad + + int x1 = PR_MIN(mX, _other->mX); + int y1 = PR_MIN(mY, _other->mY); + int x2 = PR_MAX(mX+mWidth, _other->mX+_other->mWidth); + int y2 = PR_MAX(mY+mHeight, _other->mHeight+_other->mHeight); + + return NS_NewSVGCairoRectRegion(_retval, x1, y1, x2-x1, y2-y1); +} + +/** Implements void getRectangleScans(in nsISVGRectangleSink sink); */ +NS_IMETHODIMP +nsSVGCairoRectRegion::GetRectangleScans(nsISVGRectangleSink *sink) +{ + sink->SinkRectangle(mX, mY, mWidth, mHeight); + return NS_OK; +} diff --git a/layout/svg/renderer/src/cairo/nsSVGCairoRegion.h b/layout/svg/renderer/src/cairo/nsSVGCairoRegion.h new file mode 100644 index 000000000000..1cdbc816644a --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGCairoRegion.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is Crocodile Clips Ltd.. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#ifndef __NS_SVGCAIRO_REGION_H__ +#define __NS_SVGCAIRO_REGION_H__ + +class nsISVGRendererRegion; + +//---------------------------------------------------------------------- +// region constructors: + +nsresult NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result, + int x, int y, int width, int height); + +#endif // __NS_SVGCAIRO_REGION_H__ diff --git a/layout/svg/renderer/src/cairo/nsSVGRendererCairo.cpp b/layout/svg/renderer/src/cairo/nsSVGRendererCairo.cpp new file mode 100644 index 000000000000..b067b792475b --- /dev/null +++ b/layout/svg/renderer/src/cairo/nsSVGRendererCairo.cpp @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ----- BEGIN LICENSE BLOCK ----- + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Mozilla SVG Cairo Renderer project. + * + * The Initial Developer of the Original Code is IBM Corporation. + * Portions created by the Initial Developer are Copyright (C) 2004 + * the Initial Developer. All Rights Reserved. + * + * Parts of this file contain code derived from the following files(s) + * of the Mozilla SVG project (these parts are Copyright (C) by their + * respective copyright-holders): + * layout/svg/renderer/src/libart/nsSVGRendererLibart.cpp + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ----- END LICENSE BLOCK ----- */ + +#include + +#include "nsCOMPtr.h" +#include "nsISVGRenderer.h" +#include "nsSVGCairoPathGeometry.h" +//#include "nsSVGCairoGlyphGeometry.h" +//#include "nsSVGCairoGlyphMetrics.h" +#include "nsSVGCairoCanvas.h" +//#include "nsSVGCairoRegion.h" + +void NS_InitSVGCairoGlyphMetricsGlobals(); +void NS_FreeSVGCairoGlyphMetricsGlobals(); + +/** + * \addtogroup cairo_renderer Cairo Rendering Engine + * @{ + */ +//////////////////////////////////////////////////////////////////////// +/** + * Cairo renderer factory + */ +class nsSVGRendererCairo : public nsISVGRenderer +{ +protected: + friend nsresult NS_NewSVGRendererCairo(nsISVGRenderer** aResult); + friend void NS_InitSVGRendererCairoGlobals(); + friend void NS_FreeSVGRendererCairoGlobals(); + + nsSVGRendererCairo(); + +public: + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsISVGRenderer interface + NS_DECL_NSISVGRENDERER +private: + +}; + +/** @} */ + +//---------------------------------------------------------------------- +// implementation: + +nsSVGRendererCairo::nsSVGRendererCairo() +{ +} + +nsresult +NS_NewSVGRendererCairo(nsISVGRenderer** aResult) +{ + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; + + nsSVGRendererCairo* result = new nsSVGRendererCairo(); + if (! result) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(result); + *aResult = result; + return NS_OK; +} + +void NS_InitSVGRendererCairoGlobals() +{ +} + +void NS_FreeSVGRendererCairoGlobals() +{ +} + +//---------------------------------------------------------------------- +// nsISupports methods + +NS_IMPL_ISUPPORTS1(nsSVGRendererCairo, nsISVGRenderer); + +//---------------------------------------------------------------------- +// nsISVGRenderer methods + +/** Implements nsISVGRendererPathGeometry createPathGeometry(in nsISVGPathGeometrySource src); */ +NS_IMETHODIMP +nsSVGRendererCairo::CreatePathGeometry(nsISVGPathGeometrySource *src, + nsISVGRendererPathGeometry **_retval) +{ + return NS_NewSVGCairoPathGeometry(_retval, src); +} + +/** Implements nsISVGRendererGlyphMetrics createGlyphMetrics(in nsISVGGlyphMetricsSource src); */ +NS_IMETHODIMP +nsSVGRendererCairo::CreateGlyphMetrics(nsISVGGlyphMetricsSource *src, + nsISVGRendererGlyphMetrics **_retval) +{ + fprintf(stderr, "CreateGlyphMetric (unimplemented)\n"); +// return NS_NewSVGCairoGlyphMetrics(_retval, src); + return NS_OK; +} + +/** Implements nsISVGRendererGlyphGeometry createGlyphGeometry(in nsISVGGlyphGeometrySource src); */ +NS_IMETHODIMP +nsSVGRendererCairo::CreateGlyphGeometry(nsISVGGlyphGeometrySource *src, + nsISVGRendererGlyphGeometry **_retval) +{ + fprintf(stderr, "CreateGlyphGeometry (unimplemented)\n"); +// return NS_NewSVGCairoGlyphGeometry(_retval, src); + return NS_OK; +} + +/** Implements [noscript] nsISVGRendererCanvas createCanvas(in nsIRenderingContext ctx, + in nsIPresContext presContext, const in nsRectRef dirtyRect); */ +NS_IMETHODIMP +nsSVGRendererCairo::CreateCanvas(nsIRenderingContext *ctx, + nsIPresContext *presContext, + const nsRect & dirtyRect, + nsISVGRendererCanvas **_retval) +{ + return NS_NewSVGCairoCanvas(_retval, ctx, presContext, dirtyRect); +} + +/** Implements nsISVGRendererRegion createRectRegion(in float x, in float y, in float width, in float height); */ +NS_IMETHODIMP +nsSVGRendererCairo::CreateRectRegion(float x, float y, float width, float height, + nsISVGRendererRegion **_retval) +{ + fprintf(stderr, "CreateRectRegion (unimplemented)\n"); +// return NS_NewSVGCairoRectRegion(_retval, x, y, width, height); + return NS_OK; +}