Bug 331130 - switch group opacity, complex clipPath, and mask over to

the cairo push/pop group API.  r+sr=roc
This commit is contained in:
tor%cs.brown.edu 2006-09-28 15:08:41 +00:00
parent f4e43f6d10
commit 71a8050866
21 changed files with 111 additions and 620 deletions

View File

@ -40,7 +40,6 @@
#include "nsSVGClipPathFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsIDOMSVGAnimatedEnum.h"
#include "nsISVGRendererSurface.h"
#include "nsSVGAtoms.h"
#include "nsSVGUtils.h"
#include "nsSVGGraphicElement.h"
@ -107,7 +106,6 @@ nsSVGClipPathFrame::InitSVG()
NS_IMETHODIMP
nsSVGClipPathFrame::ClipPaint(nsISVGRendererCanvas* canvas,
nsISVGRendererSurface* aClipSurface,
nsISVGChildFrame* aParent,
nsCOMPtr<nsIDOMSVGMatrix> aMatrix)
{
@ -131,12 +129,9 @@ nsSVGClipPathFrame::ClipPaint(nsISVGRendererCanvas* canvas,
if (isTrivial)
rv = canvas->SetRenderMode(nsISVGRendererCanvas::SVG_RENDER_MODE_CLIP);
else {
else
rv = canvas->SetRenderMode(nsISVGRendererCanvas::SVG_RENDER_MODE_CLIP_MASK);
canvas->PushSurface(aClipSurface, PR_TRUE);
}
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
@ -150,9 +145,6 @@ nsSVGClipPathFrame::ClipPaint(nsISVGRendererCanvas* canvas,
}
}
if (!isTrivial)
canvas->PopSurface();
canvas->SetRenderMode(nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL);
mInUse = PR_FALSE;

View File

@ -39,8 +39,6 @@
#include "nsSVGContainerFrame.h"
class nsISVGRendererSurface;
typedef nsSVGContainerFrame nsSVGClipPathFrameBase;
class nsSVGClipPathFrame : public nsSVGClipPathFrameBase
@ -55,7 +53,6 @@ class nsSVGClipPathFrame : public nsSVGClipPathFrameBase
// nsSVGClipPathFrame methods:
NS_IMETHOD ClipPaint(nsISVGRendererCanvas* canvas,
nsISVGRendererSurface* aClipSurface,
nsISVGChildFrame* aParent,
nsCOMPtr<nsIDOMSVGMatrix> aMatrix);

View File

@ -368,7 +368,7 @@ nsSVGFilterFrame::FilterPaint(nsISVGRendererCanvas *aCanvas,
return NS_OK;
}
aCanvas->PushCairoSurface(surface, PR_FALSE);
aCanvas->PushSurface(surface, PR_FALSE);
aTarget->PaintSVG(aCanvas, nsnull);
aCanvas->PopSurface();

View File

@ -59,7 +59,6 @@
#include "nsSVGMatrix.h"
#include "nsINameSpaceManager.h"
#include "nsGkAtoms.h"
#include "nsISVGRendererSurface.h"
#include "nsSVGForeignObjectElement.h"
#include "nsSVGContainerFrame.h"

View File

@ -39,7 +39,6 @@
#include "nsIDOMSVGTransformable.h"
#include "nsSVGGFrame.h"
#include "nsISVGRenderer.h"
#include "nsISVGRendererSurface.h"
#include "nsISVGRendererCanvas.h"
#include "nsIFrame.h"
#include "nsSVGMatrix.h"

View File

@ -39,9 +39,9 @@
#include "nsISVGRendererCanvas.h"
#include "nsIDOMSVGAnimatedEnum.h"
#include "nsSVGContainerFrame.h"
#include "nsISVGRendererSurface.h"
#include "nsSVGMaskElement.h"
#include "nsIDOMSVGMatrix.h"
#include "nsISVGCairoCanvas.h"
//----------------------------------------------------------------------
// Implementation
@ -135,17 +135,16 @@ static unsigned char rgb2lin[256] = {
239, 241, 243, 245, 248, 250, 252, 255
};
nsresult
nsSVGMaskFrame::MaskPaint(nsISVGRendererCanvas* aCanvas,
nsISVGRendererSurface* aSurface,
nsISVGChildFrame* aParent,
nsCOMPtr<nsIDOMSVGMatrix> aMatrix,
float aOpacity)
cairo_pattern_t *
nsSVGMaskFrame::ComputeMaskAlpha(nsISVGRendererCanvas* aCanvas,
nsISVGChildFrame* aParent,
nsIDOMSVGMatrix* aMatrix,
float aOpacity)
{
nsRect dirty;
nsCOMPtr<nsISVGCairoCanvas> cairoCanvas = do_QueryInterface(aCanvas);
cairo_t *ctx = cairoCanvas->GetContext();
if (NS_FAILED(aCanvas->PushSurface(aSurface, PR_TRUE)))
return NS_ERROR_FAILURE;
cairo_push_group(ctx);
{
nsIFrame *frame;
@ -175,7 +174,7 @@ nsSVGMaskFrame::MaskPaint(nsISVGRendererCanvas* aCanvas,
aParent->NotifyCanvasTMChanged(PR_TRUE);
if (!bbox)
return NS_OK;
return nsnull;
#ifdef DEBUG_tor
bbox->GetX(&x);
@ -214,22 +213,49 @@ nsSVGMaskFrame::MaskPaint(nsISVGRendererCanvas* aCanvas,
nsSVGUtils::PaintChildWithEffects(aCanvas, nsnull, kid);
}
aCanvas->PopSurface();
cairo_pattern_t *pattern = cairo_pop_group(ctx);
if (!pattern)
return nsnull;
/* Now convert to intensity (sRGB -> linearRGB -> intensity)
and store in alpha channel */
cairo_matrix_t patternMatrix;
cairo_pattern_get_matrix(pattern, &patternMatrix);
PRUint32 width, height, length;
PRUint8 *data;
PRInt32 stride;
cairo_surface_t *surface = nsnull;
cairo_pattern_get_surface(pattern, &surface);
double x1, y1, x2, y2;
cairo_clip_extents(ctx, &x1, &y1, &x2, &y2);
PRUint32 clipWidth = PRUint32(ceil(x2) - floor(x1));
PRUint32 clipHeight = PRUint32(ceil(y2) - floor(y1));
cairo_surface_t *image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
clipWidth, clipHeight);
if (!image)
return nsnull;
cairo_t *transferCtx = cairo_create(image);
if (!transferCtx)
return nsnull;
cairo_set_source_surface(transferCtx, surface, 0, 0);
cairo_paint(transferCtx);
cairo_destroy(transferCtx);
cairo_pattern_destroy(pattern);
/* Now convert to intensity (sRGB -> linearRGB -> intensity) and
store in alpha channel. Reuse the transfer image instead of
allocating another CAIRO_FORMAT_A8 image. */
PRUint32 width = cairo_image_surface_get_width(image);
PRUint32 height = cairo_image_surface_get_height(image);
PRUint8 *data = cairo_image_surface_get_data(image);
PRInt32 stride = cairo_image_surface_get_stride(image);
aSurface->Lock();
aSurface->GetWidth(&width);
aSurface->GetHeight(&height);
aSurface->GetData(&data, &length, &stride);
for (PRUint32 y = 0; y < height; y++)
for (PRUint32 x = 0; x < width; x++) {
PRUint32 a;
PRUint32 a;
float r, g, b, intensity;
/* un-premultiply and sRGB -> linearRGB conversion */
@ -251,9 +277,13 @@ nsSVGMaskFrame::MaskPaint(nsISVGRendererCanvas* aCanvas,
data[stride * y + 4 * x + 3] = (unsigned char)(intensity * 255);
}
aSurface->Unlock();
cairo_pattern_t *retval = cairo_pattern_create_for_surface(image);
cairo_surface_destroy(image);
return NS_OK;
if (retval)
cairo_pattern_set_matrix(retval, &patternMatrix);
return retval;
}
nsIAtom *

View File

@ -38,8 +38,7 @@
#define __NS_SVGMASKFRAME_H__
#include "nsSVGContainerFrame.h"
class nsISVGRendererSurface;
#include "cairo.h"
typedef nsSVGContainerFrame nsSVGMaskFrameBase;
@ -54,11 +53,10 @@ class nsSVGMaskFrame : public nsSVGMaskFrameBase
nsSVGMaskFrame(nsStyleContext* aContext) : nsSVGMaskFrameBase(aContext) {}
// nsSVGMaskFrame method:
nsresult MaskPaint(nsISVGRendererCanvas* aCanvas,
nsISVGRendererSurface* aSurface,
nsISVGChildFrame* aParent,
nsCOMPtr<nsIDOMSVGMatrix> aMatrix,
float aOpacity = 1.0f);
cairo_pattern_t *ComputeMaskAlpha(nsISVGRendererCanvas* aCanvas,
nsISVGChildFrame* aParent,
nsIDOMSVGMatrix* aMatrix,
float aOpacity = 1.0f);
/**
* Get the "type" of the frame

View File

@ -57,7 +57,6 @@
#include "nsSVGUtils.h"
#include "nsSVGFilterFrame.h"
#include "nsSVGMaskFrame.h"
#include "nsISVGRendererSurface.h"
#include "nsINameSpaceManager.h"
#include "nsSVGGraphicElement.h"
#include "nsSVGOuterSVGFrame.h"

View File

@ -57,7 +57,6 @@
#include "nsSVGGeometryFrame.h"
#include "nsSVGPatternFrame.h"
#include "nsISVGCairoCanvas.h"
#include "nsISVGCairoSurface.h"
#ifdef DEBUG_scooter
static void printCTM(char *msg, nsIDOMSVGMatrix *aCTM);
@ -290,7 +289,7 @@ nsSVGPatternFrame::PaintPattern(nsISVGRendererCanvas* canvas,
return NS_ERROR_FAILURE;
// Push the surface
if (NS_FAILED(canvas->PushCairoSurface(patternSurface, PR_FALSE))) {
if (NS_FAILED(canvas->PushSurface(patternSurface, PR_FALSE))) {
cairo_surface_destroy(patternSurface);
return NS_ERROR_FAILURE; //?
}

View File

@ -71,7 +71,6 @@
#include "nsSVGFilterFrame.h"
#include "nsSVGClipPathFrame.h"
#include "nsSVGMaskFrame.h"
#include "nsISVGRendererSurface.h"
#include "nsSVGContainerFrame.h"
#include "nsSVGLength2.h"
#include "nsGenericElement.h"
@ -79,6 +78,7 @@
#include "nsSVGGeometryFrame.h"
#include "nsIScriptError.h"
#include "cairo.h"
#include "nsISVGCairoCanvas.h"
struct nsSVGFilterProperty {
nsRect mFilterRect;
@ -329,22 +329,6 @@ nsSVGUtils::TransformPoint(nsIDOMSVGMatrix *matrix,
xfpoint->GetY(y);
}
nsresult
nsSVGUtils::GetSurface(nsSVGOuterSVGFrame *aOuterSVGFrame,
nsISVGRendererCanvas *aCanvas,
nsISVGRendererSurface **aSurface)
{
PRUint32 width, height;
aCanvas->GetSurfaceSize(&width, &height);
nsCOMPtr<nsISVGRenderer> renderer;
aOuterSVGFrame->GetRenderer(getter_AddRefs(renderer));
if (renderer)
return renderer->CreateSurface(width, height, aSurface);
else
return NS_ERROR_FAILURE;
}
float
nsSVGUtils::AngleBisect(float a1, float a2)
{
@ -583,10 +567,10 @@ AddEffectProperties(nsIFrame *aFrame)
}
}
static already_AddRefed<nsISVGRendererSurface>
static cairo_pattern_t *
GetComplexClipSurface(nsISVGRendererCanvas *aCanvas, nsIFrame *aFrame)
{
nsISVGRendererSurface *surface = nsnull;
cairo_pattern_t *pattern = nsnull;
if (aFrame->GetStateBits() & NS_STATE_SVG_CLIPPED_COMPLEX) {
nsISVGChildFrame *svgChildFrame;
@ -596,26 +580,27 @@ GetComplexClipSurface(nsISVGRendererCanvas *aCanvas, nsIFrame *aFrame)
clip = NS_STATIC_CAST(nsSVGClipPathFrame *,
aFrame->GetProperty(nsGkAtoms::clipPath));
nsSVGUtils::GetSurface(nsSVGUtils::GetOuterSVGFrame(aFrame),
aCanvas, &surface);
if (surface) {
nsCOMPtr<nsIDOMSVGMatrix> matrix = nsSVGUtils::GetCanvasTM(aFrame);
if (NS_FAILED(clip->ClipPaint(aCanvas, surface, svgChildFrame,
matrix))) {
delete surface;
surface = nsnull;
}
nsCOMPtr<nsISVGCairoCanvas> cairoCanvas = do_QueryInterface(aCanvas);
cairo_t *ctx = cairoCanvas->GetContext();
cairo_push_group(ctx);
nsCOMPtr<nsIDOMSVGMatrix> matrix = nsSVGUtils::GetCanvasTM(aFrame);
nsresult rv = clip->ClipPaint(aCanvas, svgChildFrame, matrix);
pattern = cairo_pop_group(ctx);
if (NS_FAILED(rv) && pattern) {
cairo_pattern_destroy(pattern);
pattern = nsnull;
}
}
return surface;
return pattern;
}
static already_AddRefed<nsISVGRendererSurface>
static cairo_pattern_t *
GetMaskSurface(nsISVGRendererCanvas *aCanvas, nsIFrame *aFrame, float opacity)
{
nsISVGRendererSurface *surface = nsnull;
if (aFrame->GetStateBits() & NS_STATE_SVG_MASKED) {
nsISVGChildFrame *svgChildFrame;
CallQueryInterface(aFrame, &svgChildFrame);
@ -624,19 +609,11 @@ GetMaskSurface(nsISVGRendererCanvas *aCanvas, nsIFrame *aFrame, float opacity)
mask = NS_STATIC_CAST(nsSVGMaskFrame *,
aFrame->GetProperty(nsGkAtoms::mask));
nsSVGUtils::GetSurface(nsSVGUtils::GetOuterSVGFrame(aFrame),
aCanvas, &surface);
if (surface) {
nsCOMPtr<nsIDOMSVGMatrix> matrix = nsSVGUtils::GetCanvasTM(aFrame);
if (NS_FAILED(mask->MaskPaint(aCanvas, surface, svgChildFrame,
matrix, opacity))) {
delete surface;
surface = nsnull;
}
}
nsCOMPtr<nsIDOMSVGMatrix> matrix = nsSVGUtils::GetCanvasTM(aFrame);
return mask->ComputeMaskAlpha(aCanvas, svgChildFrame, matrix, opacity);
}
return surface;
return nsnull;
}
@ -653,7 +630,6 @@ nsSVGUtils::PaintChildWithEffects(nsISVGRendererCanvas *aCanvas,
if (!svgChildFrame)
return;
nsSVGOuterSVGFrame* outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(aFrame);
float opacity = aFrame->GetStyleDisplay()->mOpacity;
/* Properties are added lazily and may have been removed by a restyle,
@ -687,19 +663,16 @@ nsSVGUtils::PaintChildWithEffects(nsISVGRendererCanvas *aCanvas,
* + Merge opacity and masking if both used together.
*/
nsCOMPtr<nsISVGRendererSurface> offscreenSurface;
cairo_t *ctx = nsnull;
/* Check if we need to do additional operations on this child's
* rendering, which necessitates rendering into another surface. */
if (opacity != 1.0 ||
state & (NS_STATE_SVG_CLIPPED_COMPLEX | NS_STATE_SVG_MASKED)) {
nsSVGUtils::GetSurface(outerSVGFrame,
aCanvas, getter_AddRefs(offscreenSurface));
if (offscreenSurface) {
aCanvas->PushSurface(offscreenSurface, PR_TRUE);
} else {
return;
}
nsCOMPtr<nsISVGCairoCanvas> cairoCanvas = do_QueryInterface(aCanvas);
ctx = cairoCanvas->GetContext();
cairo_save(ctx);
cairo_push_group(ctx);
}
/* If this frame has only a trivial clipPath, set up cairo's clipping now so
@ -712,7 +685,7 @@ nsSVGUtils::PaintChildWithEffects(nsISVGRendererCanvas *aCanvas,
aCanvas->PushClip();
nsCOMPtr<nsIDOMSVGMatrix> matrix = GetCanvasTM(aFrame);
clip->ClipPaint(aCanvas, nsnull, svgChildFrame, matrix);
clip->ClipPaint(aCanvas, svgChildFrame, matrix);
}
/* Paint the child */
@ -724,49 +697,43 @@ nsSVGUtils::PaintChildWithEffects(nsISVGRendererCanvas *aCanvas,
} else {
svgChildFrame->PaintSVG(aCanvas, aDirtyRect);
}
if (state & NS_STATE_SVG_CLIPPED_TRIVIAL) {
aCanvas->PopClip();
}
/* No more effects, we're done. */
if (!offscreenSurface)
if (!ctx)
return;
aCanvas->PopSurface();
cairo_pop_group_to_source(ctx);
nsCOMPtr<nsISVGRendererSurface> clipMaskSurface, maskSurface;
clipMaskSurface = GetComplexClipSurface(aCanvas, aFrame);
maskSurface = GetMaskSurface(aCanvas, aFrame, opacity);
nsCOMPtr<nsISVGRendererSurface> clippedSurface;
cairo_pattern_t *maskSurface = GetMaskSurface(aCanvas, aFrame, opacity);
cairo_pattern_t *clipMaskSurface = GetComplexClipSurface(aCanvas, aFrame);
if (clipMaskSurface) {
// Still more set after clipping, so clip to another surface
if (maskSurface || opacity != 1.0) {
nsSVGUtils::GetSurface(outerSVGFrame, aCanvas,
getter_AddRefs(clippedSurface));
if (clippedSurface) {
aCanvas->PushSurface(clippedSurface, PR_TRUE);
aCanvas->CompositeSurfaceWithMask(offscreenSurface, clipMaskSurface);
aCanvas->PopSurface();
}
cairo_push_group(ctx);
cairo_mask(ctx, clipMaskSurface);
cairo_pop_group_to_source(ctx);
} else {
aCanvas->CompositeSurfaceWithMask(offscreenSurface, clipMaskSurface);
cairo_mask(ctx, clipMaskSurface);
}
}
// No clipping or out of memory creating clip dest surface (skip clipping)
if (!clippedSurface) {
clippedSurface = offscreenSurface;
if (maskSurface) {
cairo_mask(ctx, maskSurface);
} else if (opacity != 1.0) {
cairo_paint_with_alpha(ctx, opacity);
}
cairo_restore(ctx);
if (maskSurface)
aCanvas->CompositeSurfaceWithMask(clippedSurface, maskSurface);
else if (opacity != 1.0)
aCanvas->CompositeSurface(clippedSurface, opacity);
cairo_pattern_destroy(maskSurface);
if (clipMaskSurface)
cairo_pattern_destroy(clipMaskSurface);
}
void

View File

@ -59,7 +59,6 @@ class nsIDOMSVGLength;
class nsIDOMSVGMatrix;
class nsIURI;
class nsSVGOuterSVGFrame;
class nsISVGRendererSurface;
class nsIPresShell;
class nsISVGRendererCanvas;
class nsIDOMSVGAnimatedPreserveAspectRatio;
@ -163,11 +162,6 @@ public:
static float
AngleBisect(float a1, float a2);
/* Generate a new rendering surface the size of the current surface */
static nsresult GetSurface(nsSVGOuterSVGFrame *aOuterSVGFrame,
nsISVGRendererCanvas *aCanvas,
nsISVGRendererSurface **aSurface);
/* Find the outermost SVG frame of the passed frame */
static nsSVGOuterSVGFrame *
GetOuterSVGFrame(nsIFrame *aFrame);

View File

@ -47,7 +47,6 @@ XPIDL_MODULE = gksvgrenderer
XPIDLSRCS = \
nsISVGRenderer.idl \
nsISVGRendererCanvas.idl \
nsISVGRendererSurface.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -45,7 +45,6 @@ struct nsRect;
[ref] native nsRectRef(nsRect);
interface nsISVGRendererCanvas;
interface nsISVGRendererSurface;
interface nsIRenderingContext;
interface nsPresContext;
@ -68,7 +67,7 @@ interface nsPresContext;
* cross-platform libart engine
* ("@mozilla.org/svg/renderer;1?tech=LIBART").
*/
[uuid(6f9315c2-f06d-47d7-bef1-4ad7ad0b1558)]
[uuid(9a015ea6-bcb5-4626-b98c-5df708c1fcf0)]
interface nsISVGRenderer : nsISupports
{
// void Init(in nsPresContext presContext);
@ -86,16 +85,6 @@ interface nsISVGRenderer : nsISupports
[noscript] nsISVGRendererCanvas createCanvas(in nsIRenderingContext ctx,
in nsPresContext presContext,
[const] in nsRectRef dirtyRect);
/**
* Create a rendering engine-native surface object.
*
* @param width Width of rectangle (pixels).
* @param height Height of rectangle (pixels).
*
* @return A rendering engine-native surface object.
*/
[noscript] nsISVGRendererSurface createSurface(in unsigned long width, in unsigned long height);
};
/** @} */

View File

@ -52,7 +52,6 @@ typedef PRUint32 nscolor;
interface nsIRenderingContext;
interface nsPresContext;
interface nsIDOMSVGMatrix;
interface nsISVGRendererSurface;
/**
* \addtogroup renderer_interfaces Rendering Engine Interfaces
@ -71,7 +70,7 @@ interface nsISVGRendererSurface;
* Mozilla-native rendering object with a call to
* nsISVGRenderer::createCanvas().
*/
[uuid(e20d952c-ed16-4beb-a3f5-e995f0688bff)]
[uuid(8ba10d8f-9245-4aa3-af9c-9ccf456b53f1)]
interface nsISVGRendererCanvas : nsISupports
{
/**
@ -137,23 +136,12 @@ interface nsISVGRendererCanvas : nsISupports
* the "root" surface in terms of transformation correction
* or as an absolute surface.
*/
void pushSurface(in nsISVGRendererSurface surface, in boolean isSubSurface);
void pushCairoSurface(in cairo_surface_t surface, in boolean isSubSurface);
void pushSurface(in cairo_surface_t surface, in boolean isSubSurface);
void popSurface();
/**
* Get the current drawing surface dimensions.
*/
void getSurfaceSize(out unsigned long width, out unsigned long height);
/**
* Surface composition.
*/
void compositeSurface(in nsISVGRendererSurface surface,
in float opacity);
void compositeSurfaceWithMask(in nsISVGRendererSurface surface,
in nsISVGRendererSurface mask);
void compositeSurfaceMatrix(in cairo_surface_t surface,
in nsIDOMSVGMatrix canvasTM,

View File

@ -1,65 +0,0 @@
/* -*- Mode: IDL; 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 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.
*
* 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 ***** */
#include "nsISupports.idl"
/**
* \addtogroup rendering_backend_interfaces Rendering Backend Interfaces
* @{
*/
/**
* One of a number of interfaces (all starting with nsISVGRenderer*)
* to be implemented by an SVG rendering engine. See nsISVGRenderer
* for more details.
*
* This interface abstracts a rendering engine-native surface object.
*/
[uuid(0b3c88dc-2e37-4c20-902f-34f470adf711)]
interface nsISVGRendererSurface : nsISupports
{
readonly attribute unsigned long width;
readonly attribute unsigned long height;
void getData([array, size_is(length)] out PRUint8 bits, out unsigned long length, out long stride);
void lock();
void unlock();
};
/** @} */

View File

@ -74,7 +74,6 @@ REQUIRES = \
CPPSRCS = \
nsSVGRendererCairo.cpp \
nsSVGCairoCanvas.cpp \
nsSVGCairoSurface.cpp \
$(NULL)
# **********************************************************************

View File

@ -1,66 +0,0 @@
/* -*- 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.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 ***** */
#ifndef __NS_ISVGCAIRO_SURFACE_H__
#define __NS_ISVGCAIRO_SURFACE_H__
#include "nsISVGRendererSurface.h"
#include <cairo.h>
#define NS_ISVGCAIROSURFACE_IID \
{ 0xc3a6c8d8, 0x36af, 0x47b1, { 0xac, 0xaf, 0xb3, 0x32, 0x32, 0x11, 0xbf, 0x39 } }
/**
* \addtogroup cairo_renderer Cairo Rendering Engine
* @{
*/
//////////////////////////////////////////////////////////////////////
/**
* 'Private' rendering engine interface
*/
class nsISVGCairoSurface : public nsISVGRendererSurface
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISVGCAIROSURFACE_IID)
NS_IMETHOD_(cairo_surface_t*) GetSurface() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGCairoSurface, NS_ISVGCAIROSURFACE_IID)
/** @} */
#endif //__NS_ISVGCAIRO_SURFACE_H__

View File

@ -48,7 +48,6 @@
#include "nsTransform2D.h"
#include "nsPresContext.h"
#include "nsRect.h"
#include "nsISVGCairoSurface.h"
#include <cairo.h>
#include "nsSVGUtils.h"
@ -720,21 +719,10 @@ struct ctxEntry {
PRUint32 mHeight;
};
/** Implements pushSurface(in nsISVGRendererSurface surface); */
/** Implements pushSurface(in cairo_surface_t surface); */
NS_IMETHODIMP
nsSVGCairoCanvas::PushSurface(nsISVGRendererSurface *aSurface,
nsSVGCairoCanvas::PushSurface(cairo_surface_t *aSurface,
PRBool isSubSurface)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
if (!cairoSurface)
return NS_ERROR_FAILURE;
return PushCairoSurface(cairoSurface->GetSurface(), isSubSurface);
}
NS_IMETHODIMP
nsSVGCairoCanvas::PushCairoSurface(cairo_surface_t *aSurface,
PRBool isSubSurface)
{
ctxEntry *ctx = new ctxEntry;
if (!ctx)
@ -778,57 +766,6 @@ nsSVGCairoCanvas::PopSurface()
return NS_OK;
}
NS_IMETHODIMP
nsSVGCairoCanvas::GetSurfaceSize(PRUint32 *aWidth, PRUint32 *aHeight)
{
*aWidth = mWidth;
*aHeight = mHeight;
return NS_OK;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in float opacity); */
NS_IMETHODIMP
nsSVGCairoCanvas::CompositeSurface(nsISVGRendererSurface *aSurface,
float aOpacity)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
if (!cairoSurface)
return NS_ERROR_FAILURE;
cairo_save(mCR);
if (mSubSurfaceDepth == mContextStack.Count())
cairo_translate(mCR, -mInitialTransform.x0, -mInitialTransform.y0);
cairo_set_source_surface(mCR, cairoSurface->GetSurface(), 0.0, 0.0);
cairo_paint_with_alpha(mCR, aOpacity);
cairo_restore(mCR);
return NS_OK;
}
/** Implements void compositeSurfaceWithMask(in nsISVGRendererSurface surface,
in nsISVGRendererSurface mask); */
NS_IMETHODIMP
nsSVGCairoCanvas::CompositeSurfaceWithMask(nsISVGRendererSurface *aSurface,
nsISVGRendererSurface *aMask)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
nsCOMPtr<nsISVGCairoSurface> maskSurface = do_QueryInterface(aMask);
if (!cairoSurface || !maskSurface)
return NS_ERROR_FAILURE;
cairo_save(mCR);
if (mSubSurfaceDepth == mContextStack.Count())
cairo_translate(mCR, -mInitialTransform.x0, -mInitialTransform.y0);
cairo_set_source_surface(mCR, cairoSurface->GetSurface(), 0.0, 0.0);
cairo_mask_surface(mCR, maskSurface->GetSurface(), 0.0, 0.0);
cairo_restore(mCR);
return NS_OK;
}
/** Implements void compositeSurface(in cairo_surface_t surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity); */

View File

@ -1,209 +0,0 @@
/* -*- 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.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 ***** */
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsSVGCairoSurface.h"
#include "nsISVGCairoSurface.h"
#include "prmem.h"
#include <cairo.h>
/**
* \addtogroup cairo_renderer Cairo Rendering Engine
* @{
*/
//////////////////////////////////////////////////////////////////////
/**
* Cairo surface implementation
*/
class nsSVGCairoSurface : public nsISVGCairoSurface
{
public:
nsSVGCairoSurface();
~nsSVGCairoSurface();
nsresult Init(PRUint32 width, PRUint32 height);
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsISVGRendererSurface interface:
NS_DECL_NSISVGRENDERERSURFACE
// nsISVGCairoSurface interface:
NS_IMETHOD_(cairo_surface_t*) GetSurface() { return mSurface; }
private:
PRUint8 *mData;
cairo_surface_t *mSurface;
PRUint32 mWidth, mHeight;
};
/** @} */
//----------------------------------------------------------------------
// implementation:
nsSVGCairoSurface::nsSVGCairoSurface() : mData(nsnull), mSurface(nsnull)
{
}
nsSVGCairoSurface::~nsSVGCairoSurface()
{
if (mSurface) {
cairo_surface_destroy(mSurface);
mSurface = nsnull;
}
if (mData) {
PR_Free(mData);
mData = nsnull;
}
}
static PRBool
CheckSaneImageSize(PRUint32 width, PRUint32 height)
{
if (width <= 0 || height <= 0)
return PR_FALSE;
/* check to make sure we don't overflow a 32-bit */
PRUint32 tmp = width * height;
if (tmp / height != width)
return PR_FALSE;
tmp = tmp * 4;
if (tmp / 4 != width * height)
return PR_FALSE;
/* reject over-wide or over-tall images */
const PRUint32 k64KLimit = 0x0000FFFF;
if (width > k64KLimit || height > k64KLimit)
return PR_FALSE;
return PR_TRUE;
}
nsresult
nsSVGCairoSurface::Init(PRUint32 width, PRUint32 height)
{
mWidth = width;
mHeight = height;
if (!CheckSaneImageSize(width, height))
return NS_ERROR_FAILURE;
mData = (PRUint8 *)PR_Malloc(4*width*height);
if (!mData)
return NS_ERROR_OUT_OF_MEMORY;
memset(mData, 0, 4*width*height);
mSurface = cairo_image_surface_create_for_data(mData, CAIRO_FORMAT_ARGB32,
mWidth, mHeight, 4*mWidth);
if (!mSurface)
return NS_ERROR_FAILURE;
return NS_OK;
}
nsresult
NS_NewSVGCairoSurface(nsISVGRendererSurface **result,
PRUint32 width, PRUint32 height)
{
nsSVGCairoSurface* surf = new nsSVGCairoSurface();
if (!surf)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(surf);
nsresult rv = surf->Init(width, height);
if (NS_FAILED(rv)) {
NS_RELEASE(surf);
return rv;
}
*result = surf;
return rv;
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGCairoSurface)
NS_IMPL_RELEASE(nsSVGCairoSurface)
NS_INTERFACE_MAP_BEGIN(nsSVGCairoSurface)
NS_INTERFACE_MAP_ENTRY(nsISVGRendererSurface)
NS_INTERFACE_MAP_ENTRY(nsISVGCairoSurface)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsSVGCairoSurface::GetWidth(PRUint32 *aWidth)
{
*aWidth = mWidth;
return NS_OK;
}
NS_IMETHODIMP
nsSVGCairoSurface::GetHeight(PRUint32 *aHeight)
{
*aHeight = mHeight;
return NS_OK;
}
NS_IMETHODIMP
nsSVGCairoSurface::GetData(PRUint8 **aData, PRUint32 *length, PRInt32 *stride)
{
*aData = mData;
*length = 4*mWidth*mHeight;
*stride = 4*mWidth;
return NS_OK;
}
NS_IMETHODIMP
nsSVGCairoSurface::Lock()
{
return NS_OK;
}
NS_IMETHODIMP
nsSVGCairoSurface::Unlock()
{
return NS_OK;
}

View File

@ -1,46 +0,0 @@
/* -*- 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.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of 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 ***** */
#ifndef __NS_SVGCAIRO_SURFACE_H__
#define __NS_SVGCAIRO_SURFACE_H__
class nsISVGRendererSurface;
nsresult
NS_NewSVGCairoSurface(nsISVGRendererSurface **result,
PRUint32 width, PRUint32 height);
#endif // __NS_SVGCAIRO_SURFACE_H__

View File

@ -42,7 +42,6 @@
#include "nsCOMPtr.h"
#include "nsISVGRenderer.h"
#include "nsSVGCairoCanvas.h"
#include "nsSVGCairoSurface.h"
#include <cairo.h>
/**
@ -107,11 +106,3 @@ nsSVGRendererCairo::CreateCanvas(nsIRenderingContext *ctx,
{
return NS_NewSVGCairoCanvas(_retval, ctx, presContext, dirtyRect);
}
/** Implements nsISVGRendererSurface createSurface(in float width, in float height); */
NS_IMETHODIMP
nsSVGRendererCairo::CreateSurface(PRUint32 width, PRUint32 height,
nsISVGRendererSurface **_retval)
{
return NS_NewSVGCairoSurface(_retval, width, height);
}