зеркало из https://github.com/mozilla/gecko-dev.git
Bug 347245 - Remove nsSVGCairoGlyphGeometry. r=longson, sr=roc
This commit is contained in:
Родитель
d271fb2657
Коммит
534787a02a
|
@ -112,6 +112,25 @@ nsSVGGeometryFrame::InitSVG()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGeometryFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
mContent = aContent;
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
|
||||
if (mContent) {
|
||||
mContent->SetMayHaveFrame(PR_TRUE);
|
||||
}
|
||||
|
||||
InitSVG();
|
||||
DidSetStyleContext();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGeometryFrame::DidSetStyleContext()
|
||||
{
|
||||
|
|
|
@ -62,6 +62,9 @@ public:
|
|||
virtual void Destroy();
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow);
|
||||
NS_IMETHOD DidSetStyleContext();
|
||||
|
||||
// nsISupports interface:
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
#include "nsSVGPoint.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsISVGCairoCanvas.h"
|
||||
#include "cairo.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
@ -81,7 +84,6 @@ nsSVGGlyphFrame::nsSVGGlyphFrame(nsStyleContext* aContext)
|
|||
// nsISupports methods
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGGlyphFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphGeometrySource)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphFragmentLeaf)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphFragmentNode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGChildFrame)
|
||||
|
@ -90,43 +92,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGGlyphFrameBase)
|
|||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
// rv = nsSVGGlyphFrameBase::Init(aPresContext, aContent, aParent, aPrevInFlow);
|
||||
|
||||
mContent = aContent;
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
|
||||
if (mContent) {
|
||||
mContent->SetMayHaveFrame(PR_TRUE);
|
||||
}
|
||||
|
||||
// construct our glyphmetrics & glyphgeometry objects:
|
||||
nsSVGOuterSVGFrame* outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
|
||||
if (!outerSVGFrame) {
|
||||
NS_ERROR("No outerSVGFrame");
|
||||
DidSetStyleContext();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsISVGRenderer> renderer;
|
||||
outerSVGFrame->GetRenderer(getter_AddRefs(renderer));
|
||||
if (renderer) {
|
||||
renderer->CreateGlyphGeometry(getter_AddRefs(mGeometry));
|
||||
}
|
||||
|
||||
nsSVGGlyphFrameBase::InitSVG();
|
||||
DidSetStyleContext();
|
||||
|
||||
if (!renderer || !mGeometry)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::CharacterDataChanged(nsPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
|
@ -230,16 +195,112 @@ nsSVGGlyphFrame::IsFrameOfType(PRUint32 aFlags) const
|
|||
//----------------------------------------------------------------------
|
||||
// nsISVGChildFrame methods
|
||||
|
||||
static void
|
||||
LoopCharacters(cairo_t *aCtx, nsAString &aText, nsSVGCharacterPosition *aCP,
|
||||
void (*aFunc)(cairo_t *cr, const char *utf8))
|
||||
{
|
||||
if (!aCP) {
|
||||
aFunc(aCtx, NS_ConvertUTF16toUTF8(aText).get());
|
||||
} else {
|
||||
for (PRUint32 i = 0; i < aText.Length(); i++) {
|
||||
/* character actually on the path? */
|
||||
if (aCP[i].draw == PR_FALSE)
|
||||
continue;
|
||||
cairo_matrix_t matrix;
|
||||
cairo_get_matrix(aCtx, &matrix);
|
||||
cairo_move_to(aCtx, aCP[i].x, aCP[i].y);
|
||||
cairo_rotate(aCtx, aCP[i].angle);
|
||||
aFunc(aCtx, NS_ConvertUTF16toUTF8(Substring(aText, i, 1)).get());
|
||||
cairo_set_matrix(aCtx, &matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::PaintSVG(nsISVGRendererCanvas* canvas, nsRect *aDirtyRect)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
//printf("nsSVGGlyphFrame(%p)::Paint\n", this);
|
||||
#endif
|
||||
if (!GetStyleVisibility()->IsVisible())
|
||||
return NS_OK;
|
||||
|
||||
mGeometry->Render(this, canvas);
|
||||
nsCOMPtr<nsISVGCairoCanvas> cairoCanvas = do_QueryInterface(canvas);
|
||||
NS_ASSERTION(cairoCanvas, "wrong svg render context for geometry!");
|
||||
if (!cairoCanvas) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString text;
|
||||
GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
cairo_t *ctx = cairoCanvas->GetContext();
|
||||
|
||||
SelectFont(ctx);
|
||||
|
||||
nsresult rv = GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
|
||||
PRUint16 renderMode;
|
||||
cairo_matrix_t matrix;
|
||||
canvas->GetRenderMode(&renderMode);
|
||||
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL) {
|
||||
/* save/pop the state so we don't screw up the xform */
|
||||
cairo_save(ctx);
|
||||
}
|
||||
else {
|
||||
cairo_get_matrix(ctx, &matrix);
|
||||
}
|
||||
|
||||
rv = GetGlobalTransform(ctx, cairoCanvas);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL)
|
||||
cairo_restore(ctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!cp)
|
||||
cairo_move_to(ctx, mX, mY);
|
||||
|
||||
if (renderMode != nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL) {
|
||||
if (GetClipRule() == NS_STYLE_FILL_RULE_EVENODD)
|
||||
cairo_set_fill_rule(ctx, CAIRO_FILL_RULE_EVEN_ODD);
|
||||
else
|
||||
cairo_set_fill_rule(ctx, CAIRO_FILL_RULE_WINDING);
|
||||
|
||||
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_CLIP_MASK) {
|
||||
cairo_set_antialias(ctx, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_source_rgba(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
LoopCharacters(ctx, text, cp, cairo_show_text);
|
||||
} else {
|
||||
LoopCharacters(ctx, text, cp, cairo_text_path);
|
||||
}
|
||||
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void *closure;
|
||||
if (HasFill() && NS_SUCCEEDED(SetupCairoFill(canvas, ctx, &closure))) {
|
||||
LoopCharacters(ctx, text, cp, cairo_show_text);
|
||||
CleanupCairoFill(ctx, closure);
|
||||
}
|
||||
|
||||
if (HasStroke() && NS_SUCCEEDED(SetupCairoStroke(canvas, ctx, &closure))) {
|
||||
cairo_new_path(ctx);
|
||||
if (!cp)
|
||||
cairo_move_to(ctx, mX, mY);
|
||||
LoopCharacters(ctx, text, cp, cairo_text_path);
|
||||
cairo_stroke(ctx);
|
||||
CleanupCairoStroke(ctx, closure);
|
||||
cairo_new_path(ctx);
|
||||
}
|
||||
|
||||
cairo_restore(ctx);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -252,7 +313,7 @@ nsSVGGlyphFrame::GetFrameForPointSVG(float x, float y, nsIFrame** hit)
|
|||
// test for hit:
|
||||
*hit = nsnull;
|
||||
|
||||
if (!mRect.Contains(x, y))
|
||||
if (!mRect.Contains(nscoord(x), nscoord(y)))
|
||||
return NS_OK;
|
||||
|
||||
PRBool events = PR_FALSE;
|
||||
|
@ -289,8 +350,7 @@ nsSVGGlyphFrame::GetFrameForPointSVG(float x, float y, nsIFrame** hit)
|
|||
if (!events)
|
||||
return NS_OK;
|
||||
|
||||
PRBool isHit;
|
||||
mGeometry->ContainsPoint(this, x, y, &isHit);
|
||||
PRBool isHit = ContainsPoint(x, y);
|
||||
if (isHit)
|
||||
*hit = this;
|
||||
|
||||
|
@ -306,7 +366,85 @@ nsSVGGlyphFrame::GetCoveredRegion()
|
|||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::UpdateCoveredRegion()
|
||||
{
|
||||
mGeometry->GetCoveredRegion(this, &mRect);
|
||||
mRect.Empty();
|
||||
|
||||
PRBool hasFill = HasFill();
|
||||
PRBool hasStroke = HasStroke();
|
||||
|
||||
if (!hasFill && !hasStroke) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString text;
|
||||
GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
nsSVGAutoGlyphHelperContext ctx(this);
|
||||
|
||||
nsresult rv = GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetGlobalTransform(ctx, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!cp)
|
||||
cairo_move_to(ctx, mX, mY);
|
||||
|
||||
if (!cp) {
|
||||
if (hasStroke) {
|
||||
cairo_text_path(ctx, NS_ConvertUTF16toUTF8(text).get());
|
||||
} else {
|
||||
cairo_text_extents_t extent;
|
||||
cairo_text_extents(ctx,
|
||||
NS_ConvertUTF16toUTF8(text).get(),
|
||||
&extent);
|
||||
cairo_rectangle(ctx, mX + extent.x_bearing, mY + extent.y_bearing,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
} else {
|
||||
cairo_matrix_t matrix;
|
||||
for (PRUint32 i=0; i<text.Length(); i++) {
|
||||
/* character actually on the path? */
|
||||
if (cp[i].draw == PR_FALSE)
|
||||
continue;
|
||||
cairo_get_matrix(ctx, &matrix);
|
||||
cairo_move_to(ctx, cp[i].x, cp[i].y);
|
||||
cairo_rotate(ctx, cp[i].angle);
|
||||
if (hasStroke) {
|
||||
cairo_text_path(ctx, NS_ConvertUTF16toUTF8(Substring(text, i, 1)).get());
|
||||
} else {
|
||||
cairo_text_extents_t extent;
|
||||
cairo_text_extents(ctx,
|
||||
NS_ConvertUTF16toUTF8(Substring(text, i, 1)).get(),
|
||||
&extent);
|
||||
cairo_rel_move_to(ctx, extent.x_bearing, extent.y_bearing);
|
||||
cairo_rel_line_to(ctx, extent.width, 0);
|
||||
cairo_rel_line_to(ctx, 0, extent.height);
|
||||
cairo_rel_line_to(ctx, -extent.width, 0);
|
||||
cairo_close_path(ctx);
|
||||
}
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
}
|
||||
}
|
||||
|
||||
double xmin, ymin, xmax, ymax;
|
||||
|
||||
if (hasStroke) {
|
||||
SetupCairoStrokeGeometry(ctx);
|
||||
cairo_stroke_extents(ctx, &xmin, &ymin, &xmax, &ymax);
|
||||
} else {
|
||||
cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax);
|
||||
}
|
||||
|
||||
cairo_user_to_device(ctx, &xmin, &ymin);
|
||||
cairo_user_to_device(ctx, &xmax, &ymax);
|
||||
|
||||
mRect = nsSVGUtils::ToBoundingPixelRect(xmin, ymin, xmax, ymax);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -348,9 +486,35 @@ nsSVGGlyphFrame::GetBBox(nsIDOMSVGRect **_retval)
|
|||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
if (mGeometry)
|
||||
return mGeometry->GetBoundingBox(this, _retval);
|
||||
return NS_ERROR_FAILURE;
|
||||
nsAutoString text;
|
||||
GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
nsSVGAutoGlyphHelperContext ctx(this);
|
||||
|
||||
nsresult rv = GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetGlobalTransform(ctx, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!cp)
|
||||
cairo_move_to(ctx, mX, mY);
|
||||
|
||||
LoopCharacters(ctx, text, cp, cairo_text_path);
|
||||
|
||||
double xmin, ymin, xmax, ymax;
|
||||
|
||||
cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax);
|
||||
|
||||
cairo_user_to_device(ctx, &xmin, &ymin);
|
||||
cairo_user_to_device(ctx, &xmax, &ymax);
|
||||
|
||||
return NS_NewSVGRect(_retval, xmin, ymin, xmax - xmin, ymax - ymin);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -453,37 +617,11 @@ nsSVGGlyphFrame::GetCharacterPosition(cairo_t *ctx,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGGlyphGeometrySource methods:
|
||||
|
||||
/* readonly attribute float x; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::GetX(float *aX)
|
||||
{
|
||||
*aX = mX;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute float y; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::GetY(float *aY)
|
||||
{
|
||||
*aY = mY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute boolean hasHighlight; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::GetHasHighlight(PRBool *aHasHighlight)
|
||||
{
|
||||
*aHasHighlight = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// Utilities for converting from indices in the uncompressed content
|
||||
// element strings to compressed frame string and back:
|
||||
int CompressIndex(int index, const nsTextFragment*fragment)
|
||||
static int
|
||||
CompressIndex(int index, const nsTextFragment*fragment)
|
||||
{
|
||||
int ci=0;
|
||||
if (fragment->Is2b()) {
|
||||
|
@ -522,23 +660,24 @@ int CompressIndex(int index, const nsTextFragment*fragment)
|
|||
return ci;
|
||||
}
|
||||
|
||||
int UncompressIndex(int index, PRBool bRightAffinity, const nsTextFragment*fragment)
|
||||
static int
|
||||
UncompressIndex(int index, PRBool bRightAffinity, const nsTextFragment*fragment)
|
||||
{
|
||||
// XXX
|
||||
return index;
|
||||
}
|
||||
|
||||
/* [noscript] void getHighlight (out unsigned long charnum, out unsigned long nchars, out nscolor foreground, out nscolor background); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::GetHighlight(PRUint32 *charnum, PRUint32 *nchars, nscolor *foreground, nscolor *background)
|
||||
nsresult
|
||||
nsSVGGlyphFrame::GetHighlight(PRUint32 *charnum, PRUint32 *nchars,
|
||||
nscolor *foreground, nscolor *background)
|
||||
{
|
||||
*foreground = NS_RGB(255,255,255);
|
||||
*background = NS_RGB(0,0,0);
|
||||
*charnum=0;
|
||||
*nchars=0;
|
||||
|
||||
PRBool hasHighlight;
|
||||
GetHasHighlight(&hasHighlight);
|
||||
PRBool hasHighlight =
|
||||
(mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
|
||||
|
||||
if (!hasHighlight) {
|
||||
NS_ERROR("nsSVGGlyphFrame::GetHighlight() called by renderer when there is no highlight");
|
||||
|
@ -1232,7 +1371,7 @@ void nsSVGGlyphFrame::UpdateGeometry(PRBool bRedraw,
|
|||
return;
|
||||
|
||||
outerSVGFrame->InvalidateRect(mRect);
|
||||
mGeometry->GetCoveredRegion(this, &mRect);
|
||||
UpdateCoveredRegion();
|
||||
|
||||
nsRect filterRect;
|
||||
filterRect = nsSVGUtils::FindFilterInvalidation(this);
|
||||
|
@ -1276,6 +1415,92 @@ nsSVGGlyphFrame::GetTextFrame()
|
|||
return containerFrame->GetTextFrame();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGGlyphFrame::ContainsPoint(float x, float y)
|
||||
{
|
||||
nsAutoString text;
|
||||
GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty())
|
||||
return PR_FALSE;
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
nsSVGAutoGlyphHelperContext ctx(this);
|
||||
|
||||
nsresult rv = GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
rv = GetGlobalTransform(ctx, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
float xx = 0, yy = 0;
|
||||
if (!cp) {
|
||||
xx = mX;
|
||||
yy = mY;
|
||||
}
|
||||
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
for (PRUint32 i = 0; i < text.Length(); i++) {
|
||||
/* character actually on the path? */
|
||||
if (cp && cp[i].draw == PR_FALSE)
|
||||
continue;
|
||||
|
||||
cairo_get_matrix(ctx, &matrix);
|
||||
|
||||
if (cp) {
|
||||
cairo_move_to(ctx, cp[i].x, cp[i].y);
|
||||
cairo_rotate(ctx, cp[i].angle);
|
||||
} else {
|
||||
cairo_move_to(ctx, xx, yy);
|
||||
}
|
||||
|
||||
cairo_text_extents_t extent;
|
||||
cairo_text_extents(ctx,
|
||||
NS_ConvertUTF16toUTF8(Substring(text, i, 1)).get(),
|
||||
&extent);
|
||||
cairo_rel_move_to(ctx, extent.x_bearing, extent.y_bearing);
|
||||
cairo_rel_line_to(ctx, extent.width, 0);
|
||||
cairo_rel_line_to(ctx, 0, extent.height);
|
||||
cairo_rel_line_to(ctx, -extent.width, 0);
|
||||
cairo_close_path(ctx);
|
||||
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
|
||||
if (!cp) {
|
||||
xx += extent.x_advance;
|
||||
yy += extent.y_advance;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_identity_matrix(ctx);
|
||||
return cairo_in_fill(ctx, x, y);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGGlyphFrame::GetGlobalTransform(cairo_t *ctx,
|
||||
nsISVGCairoCanvas* aCanvas)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> ctm;
|
||||
GetCanvasTM(getter_AddRefs(ctm));
|
||||
NS_ASSERTION(ctm, "graphic source didn't specify a ctm");
|
||||
|
||||
cairo_matrix_t matrix = NS_ConvertSVGMatrixToCairo(ctm);
|
||||
if (aCanvas) {
|
||||
aCanvas->AdjustMatrixForInitialTransform(&matrix);
|
||||
}
|
||||
|
||||
cairo_matrix_t inverse = matrix;
|
||||
if (cairo_matrix_invert(&inverse)) {
|
||||
cairo_identity_matrix(ctx);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// helper class
|
||||
|
||||
|
|
|
@ -40,13 +40,12 @@
|
|||
#define __NS_SVGGLYPHFRAME_H__
|
||||
|
||||
#include "nsSVGGeometryFrame.h"
|
||||
#include "nsISVGGlyphGeometrySource.h"
|
||||
#include "nsISVGGlyphFragmentLeaf.h"
|
||||
#include "nsISVGChildFrame.h"
|
||||
#include "nsISVGRendererGlyphGeometry.h"
|
||||
|
||||
class nsSVGTextFrame;
|
||||
class nsSVGGlyphFrame;
|
||||
class nsISVGCairoCanvas;
|
||||
|
||||
struct nsSVGCharacterPosition {
|
||||
PRBool draw;
|
||||
|
@ -77,7 +76,6 @@ private:
|
|||
typedef nsSVGGeometryFrame nsSVGGlyphFrameBase;
|
||||
|
||||
class nsSVGGlyphFrame : public nsSVGGlyphFrameBase,
|
||||
public nsISVGGlyphGeometrySource,
|
||||
public nsISVGGlyphFragmentLeaf, // : nsISVGGlyphFragmentNode
|
||||
public nsISVGChildFrame
|
||||
{
|
||||
|
@ -94,11 +92,6 @@ public:
|
|||
NS_IMETHOD_(nsrefcnt) Release() { return 1; }
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD
|
||||
Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD CharacterDataChanged(nsPresContext* aPresContext,
|
||||
nsIContent* aChild,
|
||||
PRBool aAppend);
|
||||
|
@ -146,9 +139,6 @@ public:
|
|||
NS_IMETHOD GetCanvasTM(nsIDOMSVGMatrix * *aCTM);
|
||||
virtual nsresult UpdateGraphic(PRBool suppressInvalidation = PR_FALSE);
|
||||
|
||||
// nsISVGGlyphGeometrySource interface:
|
||||
NS_DECL_NSISVGGLYPHGEOMETRYSOURCE
|
||||
|
||||
// nsISVGGlyphFragmentLeaf interface:
|
||||
NS_IMETHOD GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
|
||||
NS_IMETHOD GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
|
||||
|
@ -190,8 +180,11 @@ protected:
|
|||
void UpdateMetrics();
|
||||
void UpdateFragmentTree();
|
||||
nsSVGTextFrame *GetTextFrame();
|
||||
|
||||
nsCOMPtr<nsISVGRendererGlyphGeometry> mGeometry;
|
||||
PRBool ContainsPoint(float x, float y);
|
||||
nsresult GetGlobalTransform(cairo_t *ctx, nsISVGCairoCanvas *aCanvas);
|
||||
nsresult GetHighlight(PRUint32 *charnum, PRUint32 *nchars,
|
||||
nscolor *foreground, nscolor *background);
|
||||
|
||||
float mX, mY;
|
||||
PRUint8 mWhitespaceHandling;
|
||||
PRPackedBool mFragmentTreeDirty;
|
||||
|
|
|
@ -121,25 +121,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGPathGeometryFrameBase)
|
|||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPathGeometryFrame::Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow)
|
||||
{
|
||||
mContent = aContent;
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
|
||||
if (mContent) {
|
||||
mContent->SetMayHaveFrame(PR_TRUE);
|
||||
}
|
||||
|
||||
InitSVG();
|
||||
DidSetStyleContext();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPathGeometryFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
|
|
@ -72,11 +72,6 @@ public:
|
|||
NS_IMETHOD_(nsrefcnt) Release() { return 1; }
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD
|
||||
Init(nsIContent* aContent,
|
||||
nsIFrame* aParent,
|
||||
nsIFrame* aPrevInFlow);
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
|
|
@ -45,10 +45,8 @@ MODULE = layout
|
|||
XPIDL_MODULE = gksvgrenderer
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsISVGGlyphGeometrySource.idl \
|
||||
nsISVGRenderer.idl \
|
||||
nsISVGRendererCanvas.idl \
|
||||
nsISVGRendererGlyphGeometry.idl \
|
||||
nsISVGRendererSurface.idl \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -1,79 +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
|
||||
* Crocodile Clips Ltd.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex@croczilla.com> (original author)
|
||||
*
|
||||
* 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.idl"
|
||||
|
||||
native nscolor(nscolor);
|
||||
|
||||
/**
|
||||
* \addtogroup rendering_backend_interfaces Rendering Backend Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstracts a description of a 'composite glyph' (character string
|
||||
* with associated font and styling information) in the SVG rendering
|
||||
* backend for use by a rendering engine's nsISVGRendererGlyphGeometry
|
||||
* objects. This interface contains absolute positioning and other
|
||||
* information, such as e.g. individual character highlighting,
|
||||
* which doesn't affect the actual metrics of the glyph.
|
||||
*
|
||||
* @nosubgrouping
|
||||
*/
|
||||
[uuid(2d27485b-b147-4601-b0c4-fcd440145cab)]
|
||||
interface nsISVGGlyphGeometrySource : nsISupports
|
||||
{
|
||||
/**
|
||||
* @name Glyph start position
|
||||
* @{
|
||||
*/
|
||||
readonly attribute float x; // start position of glyph *before* applying CanvasTM
|
||||
readonly attribute float y;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Partial highlighting for selection feedback
|
||||
* @{
|
||||
*/
|
||||
readonly attribute boolean hasHighlight;
|
||||
void getHighlight(out unsigned long charnum, out unsigned long nchars,
|
||||
out nscolor foreground, out nscolor background);
|
||||
/** @} */
|
||||
};
|
||||
|
||||
/** @} */
|
|
@ -44,8 +44,6 @@ struct nsRect;
|
|||
|
||||
[ref] native nsRectRef(nsRect);
|
||||
|
||||
|
||||
interface nsISVGRendererGlyphGeometry;
|
||||
interface nsISVGRendererCanvas;
|
||||
interface nsISVGRendererSurface;
|
||||
interface nsIRenderingContext;
|
||||
|
@ -70,18 +68,11 @@ interface nsPresContext;
|
|||
* cross-platform libart engine
|
||||
* ("@mozilla.org/svg/renderer;1?tech=LIBART").
|
||||
*/
|
||||
[uuid(A128A973-FE67-49be-8AEA-2C4FECF3DA34)]
|
||||
[uuid(6f9315c2-f06d-47d7-bef1-4ad7ad0b1558)]
|
||||
interface nsISVGRenderer : nsISupports
|
||||
{
|
||||
// void Init(in nsPresContext presContext);
|
||||
|
||||
/**
|
||||
* Create a rendering engine-native glyph geometry object.
|
||||
*
|
||||
* @return A rendering engine-native glyph geometry object.
|
||||
*/
|
||||
nsISVGRendererGlyphGeometry createGlyphGeometry();
|
||||
|
||||
/**
|
||||
* Create a rendering engine-native canvas object for the
|
||||
* Mozilla-native rendering context 'ctx' and presentation context
|
||||
|
|
|
@ -1,108 +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
|
||||
* Crocodile Clips Ltd.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* 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.idl"
|
||||
|
||||
%{C++
|
||||
struct nsRect;
|
||||
%}
|
||||
|
||||
native nsRect(nsRect);
|
||||
|
||||
interface nsISVGRendererRegion;
|
||||
interface nsISVGRendererCanvas;
|
||||
interface nsIDOMSVGRect;
|
||||
interface nsSVGGlyphFrame;
|
||||
|
||||
/**
|
||||
* \addtogroup renderer_interfaces Rendering Engine Interfaces
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* One of a number of interfaces (all starting with nsISVGRenderer*)
|
||||
* to be implemented by an SVG rendering engine. See nsISVGRenderer
|
||||
* for more details.
|
||||
*
|
||||
* The SVG rendering backend uses this interface to communicate to the
|
||||
* rendering engine-native glyph objects.
|
||||
*
|
||||
* A glyph object is instantiated by the rendering backend for a given
|
||||
* nsISVGGlyphGeometrySource object with a call to
|
||||
* nsISVGRenderer::createGlyphGeometry(). The glyph object is assumed
|
||||
* to store a reference to its associated source object and provide
|
||||
* glyph rendering and hit-testing for the (composite) glyph described
|
||||
* by the nsISVGGlyphGeometrySource members.
|
||||
*/
|
||||
[uuid(80cb7a0d-0f0b-4624-8e03-e7ca932a2321)]
|
||||
interface nsISVGRendererGlyphGeometry : nsISupports
|
||||
{
|
||||
/**
|
||||
* Paint this object.
|
||||
*
|
||||
* @param canvas The canvas to render to.
|
||||
*/
|
||||
void render(in nsSVGGlyphFrame source, in nsISVGRendererCanvas canvas);
|
||||
|
||||
/**
|
||||
* Get a region object describing the area covered with paint by
|
||||
* this glyph geometry.
|
||||
*
|
||||
* @return Covered region.
|
||||
*/
|
||||
void getCoveredRegion(in nsSVGGlyphFrame source, out nsRect rect);
|
||||
|
||||
/**
|
||||
* Hit-testing method. Does this glyph geometry (with all relevant
|
||||
* transformations applied) contain the point x,y? Should work on a
|
||||
* character-cell basis, rather than the actual character outline.
|
||||
*
|
||||
* @param x X-coordinate of test point. @param y Y-coordinate of
|
||||
* test point.
|
||||
* @return PR_TRUE if the glyph geometry contains the point,
|
||||
* PR_FALSE otherwise.
|
||||
*/
|
||||
boolean containsPoint(in nsSVGGlyphFrame source, in float x, in float y);
|
||||
|
||||
/**
|
||||
* Transformed bounding box (does not include stroke width)
|
||||
*/
|
||||
void getBoundingBox(in nsSVGGlyphFrame source, out nsIDOMSVGRect box);
|
||||
};
|
||||
|
||||
/** @} */
|
|
@ -74,7 +74,6 @@ REQUIRES = \
|
|||
CPPSRCS = \
|
||||
nsSVGRendererCairo.cpp \
|
||||
nsSVGCairoCanvas.cpp \
|
||||
nsSVGCairoGlyphGeometry.cpp \
|
||||
nsSVGCairoSurface.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -1,457 +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.
|
||||
*
|
||||
* 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/gdiplus/nsSVGGDIPlusGlyphGeometry.cpp
|
||||
*
|
||||
* 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 "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsSVGCairoGlyphGeometry.h"
|
||||
#include "nsISVGRendererGlyphGeometry.h"
|
||||
#include "nsISVGCairoCanvas.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "nsPromiseFlatString.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsMemory.h"
|
||||
#include <cairo.h>
|
||||
|
||||
#include "nsIDOMSVGRect.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsSVGGlyphFrame.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
/**
|
||||
* \addtogroup cairo_renderer cairo Rendering Engine
|
||||
* @{
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* cairo glyph geometry implementation
|
||||
*/
|
||||
class nsSVGCairoGlyphGeometry : public nsISVGRendererGlyphGeometry
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGCairoGlyphGeometry(nsISVGRendererGlyphGeometry **result);
|
||||
|
||||
nsresult GetGlobalTransform(nsSVGGlyphFrame *aSource,
|
||||
cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
||||
|
||||
public:
|
||||
// nsISupports interface:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsISVGRendererGlyphGeometry interface:
|
||||
NS_DECL_NSISVGRENDERERGLYPHGEOMETRY
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// implementation:
|
||||
|
||||
nsresult
|
||||
NS_NewSVGCairoGlyphGeometry(nsISVGRendererGlyphGeometry **result)
|
||||
{
|
||||
*result = new nsSVGCairoGlyphGeometry;
|
||||
if (!*result) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISupports methods:
|
||||
|
||||
NS_IMPL_ADDREF(nsSVGCairoGlyphGeometry)
|
||||
NS_IMPL_RELEASE(nsSVGCairoGlyphGeometry)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGCairoGlyphGeometry)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGRendererGlyphGeometry)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGRendererGlyphGeometry methods:
|
||||
|
||||
static void
|
||||
LoopCharacters(cairo_t *aCtx, nsAString &aText, nsSVGCharacterPosition *aCP,
|
||||
void (*aFunc)(cairo_t *cr, const char *utf8))
|
||||
{
|
||||
if (!aCP) {
|
||||
aFunc(aCtx, NS_ConvertUTF16toUTF8(aText).get());
|
||||
} else {
|
||||
for (PRUint32 i = 0; i < aText.Length(); i++) {
|
||||
/* character actually on the path? */
|
||||
if (aCP[i].draw == PR_FALSE)
|
||||
continue;
|
||||
cairo_matrix_t matrix;
|
||||
cairo_get_matrix(aCtx, &matrix);
|
||||
cairo_move_to(aCtx, aCP[i].x, aCP[i].y);
|
||||
cairo_rotate(aCtx, aCP[i].angle);
|
||||
aFunc(aCtx, NS_ConvertUTF16toUTF8(Substring(aText, i, 1)).get());
|
||||
cairo_set_matrix(aCtx, &matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Implements void render(in nsISVGRendererCanvas canvas); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGCairoGlyphGeometry::Render(nsSVGGlyphFrame *aSource,
|
||||
nsISVGRendererCanvas *canvas)
|
||||
{
|
||||
nsCOMPtr<nsISVGCairoCanvas> cairoCanvas = do_QueryInterface(canvas);
|
||||
NS_ASSERTION(cairoCanvas, "wrong svg render context for geometry!");
|
||||
if (!cairoCanvas) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsAutoString text;
|
||||
aSource->GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
cairo_t *ctx = cairoCanvas->GetContext();
|
||||
|
||||
aSource->SelectFont(ctx);
|
||||
|
||||
nsresult rv = aSource->GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
|
||||
PRUint16 renderMode;
|
||||
cairo_matrix_t matrix;
|
||||
canvas->GetRenderMode(&renderMode);
|
||||
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL) {
|
||||
/* save/pop the state so we don't screw up the xform */
|
||||
cairo_save(ctx);
|
||||
}
|
||||
else {
|
||||
cairo_get_matrix(ctx, &matrix);
|
||||
}
|
||||
|
||||
rv = GetGlobalTransform(aSource, ctx, cairoCanvas);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL)
|
||||
cairo_restore(ctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
float x,y;
|
||||
if (!cp) {
|
||||
aSource->GetX(&x);
|
||||
aSource->GetY(&y);
|
||||
cairo_move_to(ctx, x, y);
|
||||
}
|
||||
|
||||
if (renderMode != nsISVGRendererCanvas::SVG_RENDER_MODE_NORMAL) {
|
||||
if (aSource->GetClipRule() == NS_STYLE_FILL_RULE_EVENODD)
|
||||
cairo_set_fill_rule(ctx, CAIRO_FILL_RULE_EVEN_ODD);
|
||||
else
|
||||
cairo_set_fill_rule(ctx, CAIRO_FILL_RULE_WINDING);
|
||||
|
||||
if (renderMode == nsISVGRendererCanvas::SVG_RENDER_MODE_CLIP_MASK) {
|
||||
cairo_set_antialias(ctx, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_source_rgba(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
|
||||
LoopCharacters(ctx, text, cp, cairo_show_text);
|
||||
} else {
|
||||
LoopCharacters(ctx, text, cp, cairo_text_path);
|
||||
}
|
||||
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void *closure;
|
||||
if (aSource->HasFill() &&
|
||||
NS_SUCCEEDED(aSource->SetupCairoFill(canvas, ctx, &closure))) {
|
||||
LoopCharacters(ctx, text, cp, cairo_show_text);
|
||||
aSource->CleanupCairoFill(ctx, closure);
|
||||
}
|
||||
|
||||
if (aSource->HasStroke() &&
|
||||
NS_SUCCEEDED(aSource->SetupCairoStroke(canvas, ctx, &closure))) {
|
||||
cairo_new_path(ctx);
|
||||
if (!cp)
|
||||
cairo_move_to(ctx, x, y);
|
||||
LoopCharacters(ctx, text, cp, cairo_text_path);
|
||||
cairo_stroke(ctx);
|
||||
aSource->CleanupCairoStroke(ctx, closure);
|
||||
cairo_new_path(ctx);
|
||||
}
|
||||
|
||||
cairo_restore(ctx);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGCairoGlyphGeometry::GetCoveredRegion(nsSVGGlyphFrame *aSource,
|
||||
nsRect *aRect)
|
||||
{
|
||||
aRect->Empty();
|
||||
|
||||
PRBool hasFill = aSource->HasFill();
|
||||
PRBool hasStroke = aSource->HasStroke();
|
||||
|
||||
if (!hasFill && !hasStroke) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString text;
|
||||
aSource->GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
nsSVGAutoGlyphHelperContext ctx(aSource);
|
||||
|
||||
nsresult rv = aSource->GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetGlobalTransform(aSource, ctx, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
float x,y;
|
||||
if (!cp) {
|
||||
aSource->GetX(&x);
|
||||
aSource->GetY(&y);
|
||||
cairo_move_to(ctx, x, y);
|
||||
} else {
|
||||
x = 0.0, y = 0.0;
|
||||
}
|
||||
|
||||
if (!cp) {
|
||||
if (hasStroke) {
|
||||
cairo_text_path(ctx, NS_ConvertUTF16toUTF8(text).get());
|
||||
} else {
|
||||
cairo_text_extents_t extent;
|
||||
cairo_text_extents(ctx,
|
||||
NS_ConvertUTF16toUTF8(text).get(),
|
||||
&extent);
|
||||
cairo_rectangle(ctx, x + extent.x_bearing, y + extent.y_bearing,
|
||||
extent.width, extent.height);
|
||||
}
|
||||
} else {
|
||||
cairo_matrix_t matrix;
|
||||
for (PRUint32 i=0; i<text.Length(); i++) {
|
||||
/* character actually on the path? */
|
||||
if (cp[i].draw == PR_FALSE)
|
||||
continue;
|
||||
cairo_get_matrix(ctx, &matrix);
|
||||
cairo_move_to(ctx, cp[i].x, cp[i].y);
|
||||
cairo_rotate(ctx, cp[i].angle);
|
||||
if (hasStroke) {
|
||||
cairo_text_path(ctx, NS_ConvertUTF16toUTF8(Substring(text, i, 1)).get());
|
||||
} else {
|
||||
cairo_text_extents_t extent;
|
||||
cairo_text_extents(ctx,
|
||||
NS_ConvertUTF16toUTF8(Substring(text, i, 1)).get(),
|
||||
&extent);
|
||||
cairo_rel_move_to(ctx, extent.x_bearing, extent.y_bearing);
|
||||
cairo_rel_line_to(ctx, extent.width, 0);
|
||||
cairo_rel_line_to(ctx, 0, extent.height);
|
||||
cairo_rel_line_to(ctx, -extent.width, 0);
|
||||
cairo_close_path(ctx);
|
||||
}
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
}
|
||||
}
|
||||
|
||||
double xmin, ymin, xmax, ymax;
|
||||
|
||||
if (hasStroke) {
|
||||
aSource->SetupCairoStrokeGeometry(ctx);
|
||||
cairo_stroke_extents(ctx, &xmin, &ymin, &xmax, &ymax);
|
||||
} else {
|
||||
cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax);
|
||||
}
|
||||
|
||||
cairo_user_to_device(ctx, &xmin, &ymin);
|
||||
cairo_user_to_device(ctx, &xmax, &ymax);
|
||||
|
||||
*aRect = nsSVGUtils::ToBoundingPixelRect(xmin, ymin, xmax, ymax);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** Implements boolean containsPoint(in float x, in float y); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGCairoGlyphGeometry::ContainsPoint(nsSVGGlyphFrame *aSource,
|
||||
float x, float y, PRBool *_retval)
|
||||
{
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
nsAutoString text;
|
||||
aSource->GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
nsSVGAutoGlyphHelperContext ctx(aSource);
|
||||
|
||||
nsresult rv = aSource->GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetGlobalTransform(aSource, ctx, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
float xx, yy;
|
||||
if (!cp) {
|
||||
aSource->GetX(&xx);
|
||||
aSource->GetY(&yy);
|
||||
}
|
||||
|
||||
cairo_matrix_t matrix;
|
||||
|
||||
for (PRUint32 i=0; i<text.Length(); i++) {
|
||||
/* character actually on the path? */
|
||||
if (cp && cp[i].draw == PR_FALSE)
|
||||
continue;
|
||||
|
||||
cairo_get_matrix(ctx, &matrix);
|
||||
|
||||
if (cp) {
|
||||
cairo_move_to(ctx, cp[i].x, cp[i].y);
|
||||
cairo_rotate(ctx, cp[i].angle);
|
||||
} else {
|
||||
cairo_move_to(ctx, xx, yy);
|
||||
}
|
||||
|
||||
cairo_text_extents_t extent;
|
||||
cairo_text_extents(ctx,
|
||||
NS_ConvertUTF16toUTF8(Substring(text, i, 1)).get(),
|
||||
&extent);
|
||||
cairo_rel_move_to(ctx, extent.x_bearing, extent.y_bearing);
|
||||
cairo_rel_line_to(ctx, extent.width, 0);
|
||||
cairo_rel_line_to(ctx, 0, extent.height);
|
||||
cairo_rel_line_to(ctx, -extent.width, 0);
|
||||
cairo_close_path(ctx);
|
||||
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
|
||||
if (!cp) {
|
||||
xx += extent.x_advance;
|
||||
yy += extent.y_advance;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_identity_matrix(ctx);
|
||||
*_retval = cairo_in_fill(ctx, x, y);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsSVGCairoGlyphGeometry::GetGlobalTransform(nsSVGGlyphFrame *aSource,
|
||||
cairo_t *ctx,
|
||||
nsISVGCairoCanvas* aCanvas)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGMatrix> ctm;
|
||||
aSource->GetCanvasTM(getter_AddRefs(ctm));
|
||||
NS_ASSERTION(ctm, "graphic source didn't specify a ctm");
|
||||
|
||||
cairo_matrix_t matrix = NS_ConvertSVGMatrixToCairo(ctm);
|
||||
if (aCanvas) {
|
||||
aCanvas->AdjustMatrixForInitialTransform(&matrix);
|
||||
}
|
||||
|
||||
cairo_matrix_t inverse = matrix;
|
||||
if (cairo_matrix_invert(&inverse)) {
|
||||
cairo_identity_matrix(ctx);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
cairo_set_matrix(ctx, &matrix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGCairoGlyphGeometry::GetBoundingBox(nsSVGGlyphFrame *aSource,
|
||||
nsIDOMSVGRect * *aBoundingBox)
|
||||
{
|
||||
*aBoundingBox = nsnull;
|
||||
|
||||
nsAutoString text;
|
||||
aSource->GetCharacterData(text);
|
||||
|
||||
if (text.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoArrayPtr<nsSVGCharacterPosition> cp;
|
||||
|
||||
nsSVGAutoGlyphHelperContext ctx(aSource);
|
||||
|
||||
nsresult rv = aSource->GetCharacterPosition(ctx, getter_Transfers(cp));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = GetGlobalTransform(aSource, ctx, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
float x,y;
|
||||
if (!cp) {
|
||||
aSource->GetX(&x);
|
||||
aSource->GetY(&y);
|
||||
cairo_move_to(ctx, x, y);
|
||||
}
|
||||
|
||||
LoopCharacters(ctx, text, cp, cairo_text_path);
|
||||
|
||||
double xmin, ymin, xmax, ymax;
|
||||
|
||||
cairo_fill_extents(ctx, &xmin, &ymin, &xmax, &ymax);
|
||||
|
||||
cairo_user_to_device(ctx, &xmin, &ymin);
|
||||
cairo_user_to_device(ctx, &xmax, &ymax);
|
||||
|
||||
return NS_NewSVGRect(aBoundingBox, xmin, ymin, xmax - xmin, ymax - ymin);
|
||||
}
|
|
@ -98,13 +98,6 @@ NS_IMPL_ISUPPORTS1(nsSVGRendererCairo, nsISVGRenderer)
|
|||
//----------------------------------------------------------------------
|
||||
// nsISVGRenderer methods
|
||||
|
||||
/** Implements nsISVGRendererGlyphGeometry createGlyphGeometry; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGRendererCairo::CreateGlyphGeometry(nsISVGRendererGlyphGeometry **_retval)
|
||||
{
|
||||
return NS_NewSVGCairoGlyphGeometry(_retval);
|
||||
}
|
||||
|
||||
/** Implements [noscript] nsISVGRendererCanvas createCanvas(in nsIRenderingContext ctx,
|
||||
in nsPresContext presContext, const in nsRectRef dirtyRect); */
|
||||
NS_IMETHODIMP
|
||||
|
|
Загрузка…
Ссылка в новой задаче