Bug 267195 - implement svg opacity property. r=scooter

This commit is contained in:
tor%cs.brown.edu 2004-11-19 22:52:15 +00:00
parent 21eb480fc8
commit 5ebe551c2f
21 changed files with 1021 additions and 7 deletions

View File

@ -38,6 +38,12 @@
#include "nsIDOMSVGTransformable.h"
#include "nsSVGDefsFrame.h"
#include "nsISVGRenderer.h"
#include "nsISVGRendererSurface.h"
#include "nsISVGOuterSVGFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsIFrame.h"
#include <math.h>
typedef nsSVGDefsFrame nsSVGGFrameBase;
@ -83,6 +89,36 @@ NS_NewSVGGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame** aNewF
NS_IMETHODIMP
nsSVGGFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectTwips)
{
nsCOMPtr<nsISVGRendererSurface> surface;
const nsStyleDisplay *display = mStyleContext->GetStyleDisplay();
if (display->mOpacity == 0.0)
return NS_OK;
if (display->mOpacity != 1.0) {
nsISVGOuterSVGFrame* outerSVGFrame = GetOuterSVGFrame();
if (outerSVGFrame) {
nsIFrame *frame = nsnull;
CallQueryInterface(outerSVGFrame, &frame);
if (frame) {
nsSize size = frame->GetSize();
float p2t = GetPresContext()->ScaledPixelsToTwips();
PRUint32 width = (PRUint32)ceil(size.width/p2t);
PRUint32 height = (PRUint32)ceil(size.height/p2t);
nsCOMPtr<nsISVGRenderer> renderer;
outerSVGFrame->GetRenderer(getter_AddRefs(renderer));
if (renderer)
renderer->CreateSurface(width, height, getter_AddRefs(surface));
if (surface) {
if (NS_FAILED(canvas->PushSurface(surface)))
surface = nsnull;
}
}
}
}
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsISVGChildFrame* SVGFrame=nsnull;
@ -91,6 +127,11 @@ nsSVGGFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectTwips)
SVGFrame->Paint(canvas, dirtyRectTwips);
}
if (surface) {
canvas->PopSurface();
canvas->CompositeSurface(surface, 0, 0, display->mOpacity);
}
return NS_OK;
}

View File

@ -469,7 +469,8 @@ nsSVGGlyphFrame::GetCanvasTM(nsIDOMSVGMatrix * *aCTM)
NS_IMETHODIMP
nsSVGGlyphFrame::GetStrokeOpacity(float *aStrokeOpacity)
{
*aStrokeOpacity = ((const nsStyleSVG*) mStyleContext->GetStyleData(eStyleStruct_SVG))->mStrokeOpacity;
*aStrokeOpacity =
GetStyleSVG()->mStrokeOpacity * GetStyleDisplay()->mOpacity;
return NS_OK;
}
@ -538,7 +539,8 @@ nsSVGGlyphFrame::GetStrokeMiterlimit(float *aStrokeMiterlimit)
NS_IMETHODIMP
nsSVGGlyphFrame::GetFillOpacity(float *aFillOpacity)
{
*aFillOpacity = ((const nsStyleSVG*) mStyleContext->GetStyleData(eStyleStruct_SVG))->mFillOpacity;
*aFillOpacity =
GetStyleSVG()->mFillOpacity * GetStyleDisplay()->mOpacity;
return NS_OK;
}

View File

@ -316,7 +316,8 @@ nsSVGPathGeometryFrame::GetCanvasTM(nsIDOMSVGMatrix * *aCTM)
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetStrokeOpacity(float *aStrokeOpacity)
{
*aStrokeOpacity = ((const nsStyleSVG*) mStyleContext->GetStyleData(eStyleStruct_SVG))->mStrokeOpacity;
*aStrokeOpacity =
GetStyleSVG()->mStrokeOpacity * GetStyleDisplay()->mOpacity;
return NS_OK;
}
@ -385,7 +386,8 @@ nsSVGPathGeometryFrame::GetStrokeMiterlimit(float *aStrokeMiterlimit)
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetFillOpacity(float *aFillOpacity)
{
*aFillOpacity = ((const nsStyleSVG*) mStyleContext->GetStyleData(eStyleStruct_SVG))->mFillOpacity;
*aFillOpacity =
GetStyleSVG()->mFillOpacity * GetStyleDisplay()->mOpacity;
return NS_OK;
}

View File

@ -58,6 +58,7 @@ XPIDLSRCS = \
nsISVGRendererPathBuilder.idl \
nsISVGRendererPathGeometry.idl \
nsISVGRendererRegion.idl \
nsISVGRendererSurface.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -52,6 +52,7 @@ interface nsISVGRendererPathGeometry;
interface nsISVGRendererGlyphMetrics;
interface nsISVGRendererGlyphGeometry;
interface nsISVGRendererCanvas;
interface nsISVGRendererSurface;
interface nsIRenderingContext;
interface nsISVGRendererRegion;
interface nsPresContext;
@ -75,7 +76,7 @@ interface nsPresContext;
* cross-platform libart engine
* ("@mozilla.org/svg/renderer;1?tech=LIBART").
*/
[scriptable, uuid(8a1398db-fb25-4711-85fc-4f5665ea7d17)]
[scriptable, uuid(14e914e0-f283-4fd0-9d71-d3e842927007)]
interface nsISVGRenderer : nsISupports
{
// void Init(in nsPresContext presContext);
@ -136,6 +137,16 @@ interface nsISVGRenderer : nsISupports
* @return A rendering engine-native region object.
*/
nsISVGRendererRegion createRectRegion(in float x, in float y, in float width, in float height);
/**
* 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

@ -50,6 +50,7 @@ typedef PRUint32 nscolor;
interface nsIRenderingContext;
interface nsPresContext;
interface nsIDOMSVGMatrix;
interface nsISVGRendererSurface;
/**
* \addtogroup renderer_interfaces Rendering Engine Interfaces
@ -68,7 +69,7 @@ interface nsIDOMSVGMatrix;
* Mozilla-native rendering object with a call to
* nsISVGRenderer::createCanvas().
*/
[scriptable, uuid(90be3072-6a88-4dc3-a3f0-c8f2907078d8)]
[scriptable, uuid(2e64a227-de4b-4a69-ab82-5dda1579e90f)]
interface nsISVGRendererCanvas : nsISupports
{
/**
@ -117,6 +118,23 @@ interface nsISVGRendererCanvas : nsISupports
*/
void setClipRect(in nsIDOMSVGMatrix canvasTM, in float x, in float y,
in float width, in float height);
/**
* Push/Pop surface as primary drawing surface.
*/
void pushSurface(in nsISVGRendererSurface surface);
void popSurface();
/**
* Surface composition.
*/
void compositeSurface(in nsISVGRendererSurface surface,
in unsigned long x, in unsigned long y,
in float opacity);
void compositeSurfaceMatrix(in nsISVGRendererSurface surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity);
};
/** @} */

View File

@ -0,0 +1,64 @@
/* -*- 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 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 "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

@ -72,6 +72,7 @@ CPPSRCS = \
nsSVGCairoGlyphMetrics.cpp \
nsSVGCairoGlyphGeometry.cpp \
nsSVGCairoGradient.cpp \
nsSVGCairoSurface.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.

View File

@ -0,0 +1,64 @@
/* -*- 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_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGCAIROSURFACE_IID)
NS_IMETHOD_(cairo_surface_t*) GetSurface() = 0;
};
/** @} */
#endif //__NS_ISVGCAIRO_SURFACE_H__

View File

@ -49,6 +49,7 @@
#include "nsPresContext.h"
#include "nsRect.h"
#include "nsRenderingContextGTK.h"
#include "nsISVGCairoSurface.h"
#include <gdk/gdkx.h>
#include <cairo.h>
@ -82,6 +83,8 @@ private:
nsCOMPtr<nsPresContext> mPresContext;
cairo_t *mCR;
PRUint32 mWidth, mHeight;
nsVoidArray mSurfaceStack;
};
@ -304,3 +307,115 @@ nsSVGCairoCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
return NS_OK;
}
/** Implements pushSurface(in nsISVGRendereerSurface surface); */
NS_IMETHODIMP
nsSVGCairoCanvas::PushSurface(nsISVGRendererSurface *aSurface)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
if (!cairoSurface)
return NS_ERROR_FAILURE;
mSurfaceStack.AppendElement((void *)cairo_current_target_surface(mCR));
cairo_save(mCR);
cairo_default_matrix(mCR);
cairo_set_target_surface(mCR, cairoSurface->GetSurface());
return NS_OK;
}
/** Implements popSurface(); */
NS_IMETHODIMP
nsSVGCairoCanvas::PopSurface()
{
PRUint32 count = mSurfaceStack.Count();
if (count != 0) {
cairo_set_target_surface(mCR, (cairo_surface_t *)mSurfaceStack[count - 1]);
mSurfaceStack.RemoveElementAt(count - 1);
}
cairo_restore(mCR);
return NS_OK;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in unsigned long x, in unsigned long y,
in float opacity); */
NS_IMETHODIMP
nsSVGCairoCanvas::CompositeSurface(nsISVGRendererSurface *aSurface,
PRUint32 aX, PRUint32 aY, float aOpacity)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
if (!cairoSurface)
return NS_ERROR_FAILURE;
cairo_save(mCR);
cairo_translate(mCR, aX, aY);
cairo_set_alpha(mCR, aOpacity);
PRUint32 width, height;
aSurface->GetWidth(&width);
aSurface->GetHeight(&height);
cairo_show_surface(mCR, cairoSurface->GetSurface(), width, height);
cairo_restore(mCR);
return NS_OK;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity); */
NS_IMETHODIMP
nsSVGCairoCanvas::CompositeSurfaceMatrix(nsISVGRendererSurface *aSurface,
nsIDOMSVGMatrix *aCTM, float aOpacity)
{
nsCOMPtr<nsISVGCairoSurface> cairoSurface = do_QueryInterface(aSurface);
if (!cairoSurface)
return NS_ERROR_FAILURE;
cairo_save(mCR);
float m[6];
float val;
aCTM->GetA(&val);
m[0] = val;
aCTM->GetB(&val);
m[1] = val;
aCTM->GetC(&val);
m[2] = val;
aCTM->GetD(&val);
m[3] = val;
aCTM->GetE(&val);
m[4] = val;
aCTM->GetF(&val);
m[5] = val;
cairo_matrix_t *matrix = cairo_matrix_create();
if (!matrix) {
cairo_restore(mCR);
return NS_ERROR_FAILURE;
}
cairo_matrix_set_affine(matrix, m[0], m[1], m[2], m[3], m[4], m[5]);
cairo_concat_matrix(mCR, matrix);
cairo_matrix_destroy(matrix);
PRUint32 width, height;
aSurface->GetWidth(&width);
aSurface->GetHeight(&height);
cairo_set_alpha(mCR, aOpacity);
cairo_show_surface(mCR, cairoSurface->GetSurface(), width, height);
cairo_restore(mCR);
return NS_OK;
}

View File

@ -0,0 +1,184 @@
/* -*- 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 <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:
char *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) {
delete [] mData;
mData = nsnull;
}
}
nsresult
nsSVGCairoSurface::Init(PRUint32 width, PRUint32 height)
{
mWidth = width;
mHeight = height;
mData = new char[4*width*height];
if (!mData)
return NS_ERROR_OUT_OF_MEMORY;
memset(mData, 0, 4*width*height);
mSurface = cairo_surface_create_for_image(mData, CAIRO_FORMAT_ARGB32,
mWidth, mHeight, 4*mWidth);
if (!mSurface)
return NS_ERROR_FAILURE;
cairo_surface_set_filter(mSurface, CAIRO_FILTER_BEST);
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 = (PRUint8*)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

@ -0,0 +1,46 @@
/* -*- 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

@ -48,6 +48,7 @@
#include "nsSVGCairoGlyphMetrics.h"
#include "nsSVGCairoCanvas.h"
#include "nsSVGCairoRegion.h"
#include "nsSVGCairoSurface.h"
void NS_InitSVGCairoGlyphMetricsGlobals();
void NS_FreeSVGCairoGlyphMetricsGlobals();
@ -162,3 +163,11 @@ nsSVGRendererCairo::CreateRectRegion(float x, float y, float width, float height
{
return NS_NewSVGCairoRectRegion(_retval, x, y, width, height);
}
/** 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);
}

View File

@ -62,6 +62,7 @@ CPPSRCS = \
nsSVGGDIPlusPathBuilder.cpp \
nsSVGGDIPlusPathGeometry.cpp \
nsSVGGDIPlusRegion.cpp \
nsSVGGDIPlusSurface.cpp \
nsSVGRendererGDIPlus.cpp \
$(NULL)

View File

@ -0,0 +1,69 @@
/* -*- 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 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_ISVGGDIPLUS_SURFACE_H__
#define __NS_ISVGGDIPLUS_SURFACE_H__
#include <Gdiplus.h>
using namespace Gdiplus;
#include "nsISVGRendererSurface.h"
#define NS_ISVGGDIPLUSSURFACE_IID \
{ 0x7e37405a, 0xa4d3, 0x49da, { 0xab, 0x18, 0x0c, 0x89, 0xd8, 0xb3, 0x95, 0x9c } }
/**
* \addtogroup gdiplus_renderer GDI+ Rendering Engine
* @{
*/
/**
* 'Private' rendering engine interface
*/
class nsISVGGDIPlusSurface : public nsISVGRendererSurface
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGGDIPLUSSURFACE_IID)
/**
* Obtain the Gdiplus::Graphics object for this canvas.
*/
NS_IMETHOD_(Bitmap*) GetSurface()=0;
};
/** @} */
#endif //__NS_ISVGGDIPLUS_SURFACE_H__

View File

@ -54,6 +54,7 @@ using namespace Gdiplus;
#include "nsRect.h"
#include "nsIRenderingContextWin.h"
#include "nsIDOMSVGMatrix.h"
#include "nsISVGGDIPlusSurface.h"
/**
* \addtogroup gdiplus_renderer GDI+ Rendering Engine
@ -86,6 +87,7 @@ private:
nsCOMPtr<nsPresContext> mPresContext;
Graphics *mGraphics;
nsVoidArray mClipStack;
nsVoidArray mSurfaceStack;
#ifdef SVG_GDIPLUS_ENABLE_OFFSCREEN_BUFFER
Bitmap *mOffscreenBitmap;
@ -390,3 +392,102 @@ nsSVGGDIPlusCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
return NS_OK;
}
/** Implements pushSurface(in nsISVGRendereerSurface surface); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::PushSurface(nsISVGRendererSurface *aSurface)
{
nsCOMPtr<nsISVGGDIPlusSurface> gdiplusSurface = do_QueryInterface(aSurface);
if (!gdiplusSurface)
return NS_ERROR_FAILURE;
mSurfaceStack.AppendElement((void *)mGraphics);
mGraphics = new Graphics(gdiplusSurface->GetSurface());
if (!mGraphics) {
PopSurface();
return NS_ERROR_FAILURE;
}
mGraphics->Clear(Color(0,0,0,0));
return NS_OK;
}
/** Implements popSurface(); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::PopSurface()
{
PRUint32 count = mSurfaceStack.Count();
if (count != 0) {
delete mGraphics;
mGraphics = (Graphics *)mSurfaceStack[count - 1];
mSurfaceStack.RemoveElementAt(count - 1);
}
return NS_OK;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in unsigned long x, in unsigned long y,
in float opacity); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::CompositeSurface(nsISVGRendererSurface *aSurface,
PRUint32 aX, PRUint32 aY, float aOpacity)
{
nsCOMPtr<nsISVGGDIPlusSurface> gdiplusSurface = do_QueryInterface(aSurface);
if (!gdiplusSurface)
return NS_ERROR_FAILURE;
ColorMatrix cxform;
memset(&cxform, 0, sizeof(ColorMatrix));
cxform.m[0][0] = cxform.m[1][1] = cxform.m[2][2] = cxform.m[4][4] = 1.0f;
cxform.m[3][3] = aOpacity;
ImageAttributes attrib;
attrib.SetColorMatrix(&cxform);
PRUint32 width, height;
aSurface->GetWidth(&width);
aSurface->GetHeight(&height);
Rect rect(aX, aY, width, height);
mGraphics->DrawImage(gdiplusSurface->GetSurface(),
rect, 0, 0, width, height, UnitPixel, &attrib);
return NS_OK;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::CompositeSurfaceMatrix(nsISVGRendererSurface *aSurface,
nsIDOMSVGMatrix *aCTM, float aOpacity)
{
float m[6];
float val;
aCTM->GetA(&val);
m[0] = val;
aCTM->GetB(&val);
m[1] = val;
aCTM->GetC(&val);
m[2] = val;
aCTM->GetD(&val);
m[3] = val;
aCTM->GetE(&val);
m[4] = val;
aCTM->GetF(&val);
m[5] = val;
Matrix xform(m[0], m[1], m[2], m[3], m[4], m[5]), orig;
mGraphics->GetTransform(&orig);
mGraphics->MultiplyTransform(&xform);
CompositeSurface(aSurface, 0, 0, aOpacity);
mGraphics->SetTransform(&orig);
return NS_OK;
}

View File

@ -0,0 +1,183 @@
/* -*- 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 GDI+ 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 <windows.h>
#include <unknwn.h>
#include <Gdiplus.h>
using namespace Gdiplus;
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "nsSVGGDIPlusSurface.h"
#include "nsISVGGDIPlusSurface.h"
/**
* \addtogroup cairo_renderer GDI+ Rendering Engine
* @{
*/
//////////////////////////////////////////////////////////////////////
/**
* GDIPlus surface implementation
*/
class nsSVGGDIPlusSurface : public nsISVGGDIPlusSurface
{
public:
nsSVGGDIPlusSurface();
~nsSVGGDIPlusSurface();
nsresult Init(PRUint32 width, PRUint32 height);
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsISVGRendererSurface interface:
NS_DECL_NSISVGRENDERERSURFACE
// nsISVGGDIPlusSurface interface:
NS_IMETHOD_(Bitmap*) GetSurface() { return mSurface; }
private:
Bitmap *mSurface;
BitmapData mBitmapData;
PRUint32 mWidth, mHeight;
};
/** @} */
//----------------------------------------------------------------------
// implementation:
nsSVGGDIPlusSurface::nsSVGGDIPlusSurface() : mSurface(nsnull)
{
}
nsSVGGDIPlusSurface::~nsSVGGDIPlusSurface()
{
if (mSurface) {
delete mSurface;
mSurface = nsnull;
}
}
nsresult
nsSVGGDIPlusSurface::Init(PRUint32 width, PRUint32 height)
{
mWidth = width;
mHeight = height;
mSurface = new Bitmap(width, height, PixelFormat32bppPARGB);
if (!mSurface)
return NS_ERROR_FAILURE;
return NS_OK;
}
nsresult
NS_NewSVGGDIPlusSurface(nsISVGRendererSurface **result,
PRUint32 width, PRUint32 height)
{
nsSVGGDIPlusSurface* surf = new nsSVGGDIPlusSurface();
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(nsSVGGDIPlusSurface)
NS_IMPL_RELEASE(nsSVGGDIPlusSurface)
NS_INTERFACE_MAP_BEGIN(nsSVGGDIPlusSurface)
NS_INTERFACE_MAP_ENTRY(nsISVGRendererSurface)
NS_INTERFACE_MAP_ENTRY(nsISVGGDIPlusSurface)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsSVGGDIPlusSurface::GetWidth(PRUint32 *aWidth)
{
*aWidth = mWidth;
return NS_OK;
}
NS_IMETHODIMP
nsSVGGDIPlusSurface::GetHeight(PRUint32 *aHeight)
{
*aHeight = mHeight;
return NS_OK;
}
NS_IMETHODIMP
nsSVGGDIPlusSurface::GetData(PRUint8 **aData, PRUint32 *length, PRInt32 *stride)
{
*aData = (PRUint8 *)mBitmapData.Scan0;
*length = abs(mBitmapData.Stride) * mBitmapData.Height;
*stride = mBitmapData.Stride;
return NS_OK;
}
NS_IMETHODIMP
nsSVGGDIPlusSurface::Lock()
{
Rect rect(0, 0, mWidth, mHeight);
mSurface->LockBits(&rect,
ImageLockModeRead | ImageLockModeWrite,
PixelFormat32bppPARGB,
&mBitmapData);
return NS_OK;
}
NS_IMETHODIMP
nsSVGGDIPlusSurface::Unlock()
{
mSurface->UnlockBits(&mBitmapData);
return NS_OK;
}

View File

@ -0,0 +1,46 @@
/* -*- 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_SVGGDIPLUS_SURFACE_H__
#define __NS_SVGGDIPLUS_SURFACE_H__
class nsISVGRendererSurface;
nsresult
NS_NewSVGGDIPlusSurface(nsISVGRendererSurface **result,
PRUint32 width, PRUint32 height);
#endif // __NS_SVGGDIPLUS_SURFACE_H__

View File

@ -51,6 +51,7 @@ using namespace Gdiplus;
#include "nsSVGGDIPlusGlyphMetrics.h"
#include "nsSVGGDIPlusCanvas.h"
#include "nsSVGGDIPlusRegion.h"
#include "nsSVGGDIPlusSurface.h"
void NS_InitSVGGDIPlusGlyphMetricsGlobals();
void NS_FreeSVGGDIPlusGlyphMetricsGlobals();
@ -187,3 +188,10 @@ nsSVGRendererGDIPlus::CreateRectRegion(float x, float y, float width, float heig
return NS_NewSVGGDIPlusRectRegion(_retval, x, y, width, height);
}
/** Implements nsISVGRendererSurface createSurface(in float width, in float height); */
NS_IMETHODIMP
nsSVGRendererGDIPlus::CreateSurface(PRUint32 width, PRUint32 height,
nsISVGRendererSurface **_retval)
{
return NS_NewSVGGDIPlusSurface(_retval, width, height);
}

View File

@ -375,7 +375,46 @@ nsSVGLibartCanvas::PopClip()
in float width, in float height); */
NS_IMETHODIMP
nsSVGLibartCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
float aWidth, float aHeight)
float aWidth, float aHeight)
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
/** Implements pushSurface(in nsISVGRendereerSurface surface); */
NS_IMETHODIMP
nsSVGLibartCanvas::PushSurface(nsISVGRendererSurface *aSurface)
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
/** Implements popSurface(); */
NS_IMETHODIMP
nsSVGLibartCanvas::PopSurface()
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in unsigned long x, in unsigned long y,
in float opacity); */
NS_IMETHODIMP
nsSVGLibartCanvas::CompositeSurface(nsISVGRendererSurface *aSurface,
PRUint32 aX, PRUint32 aY, float aOpacity)
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
/** Implements void compositeSurface(in nsISVGRendererSurface surface,
in nsIDOMSVGMatrix canvasTM,
in float opacity); */
NS_IMETHODIMP
nsSVGLibartCanvas::CompositeSurfaceMatrix(nsISVGRendererSurface *aSurface,
nsIDOMSVGMatrix *aCTM, float aOpacity)
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;

View File

@ -201,6 +201,15 @@ nsSVGRendererLibart::CreateRectRegion(float x, float y, float width, float heigh
return NS_NewSVGLibartRectRegion(_retval, x, y, width, height);
}
/** Implements nsISVGRendererSurface createSurface(in float width, in float height); */
NS_IMETHODIMP
nsSVGRendererLibart::CreateSurface(PRUint32 width, PRUint32 height,
nsISVGRendererSurface **_retval)
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////
// module initialisation