Initial cairo foreignObject and font support.

This commit is contained in:
tor%cs.brown.edu 2004-03-16 21:40:09 +00:00
Родитель 40bf3cffa8
Коммит ad24d82e95
9 изменённых файлов: 907 добавлений и 25 удалений

Просмотреть файл

@ -68,6 +68,8 @@ CPPSRCS = \
nsSVGCairoPathGeometry.cpp \
nsSVGCairoPathBuilder.cpp \
nsSVGCairoRegion.cpp \
nsSVGCairoGlyphMetrics.cpp \
nsSVGCairoGlyphGeometry.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.

Просмотреть файл

@ -0,0 +1,73 @@
/* -*- 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 the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#ifndef __NS_ISVGCAIRO_GLYPHMETRICS_H__
#define __NS_ISVGCAIRO_GLYPHMETRICS_H__
#include "nsISVGRendererGlyphMetrics.h"
#include <cairo.h>
// 193e2d48-3898-4bf3-b6bf-d7c00a8aba1f
#define NS_ISVGCAIROGLYPHMETRICS_IID \
{ 0x193e2d48, 0x3898, 0x4bf3, { 0xb6, 0xbf, 0xd7, 0xc0, 0x0a, 0x8a, 0xba, 0x1f } }
/**
* \addtogroup gdiplus_renderer Cairo Rendering Engine
* @{
*/
/**
* 'Private' rendering engine interface
*/
class nsISVGCairoGlyphMetrics : public nsISVGRendererGlyphMetrics
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISVGCAIROGLYPHMETRICS_IID)
NS_IMETHOD_(void) GetSubBoundingBox(PRUint32 charoffset, PRUint32 count, nsIDOMSVGRect * *aBoundingBox)=0;
NS_IMETHOD_(cairo_font_t*) GetFont() = 0;
};
/** @} */
#endif // __NS_ISVGCAIRO_GLYPHMETRICS_H__

Просмотреть файл

@ -0,0 +1,369 @@
/* -*- 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 the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#include "nsCOMPtr.h"
#include "nsSVGCairoGlyphGeometry.h"
#include "nsISVGRendererGlyphGeometry.h"
#include "nsISVGCairoCanvas.h"
#include "nsIDOMSVGMatrix.h"
#include "nsSVGCairoRegion.h"
#include "nsISVGRendererRegion.h"
#include "nsISVGGlyphGeometrySource.h"
#include "nsPromiseFlatString.h"
#include "nsSVGCairoGlyphMetrics.h"
#include "nsISVGCairoGlyphMetrics.h"
#include "nsIPresContext.h"
#include "nsMemory.h"
#include <cairo.h>
/**
* \addtogroup cairo_renderer cairo Rendering Engine
* @{
*/
////////////////////////////////////////////////////////////////////////
/**
* cairo glyph geometry implementation
*/
class nsSVGCairoGlyphGeometry : public nsISVGRendererGlyphGeometry
{
protected:
friend nsresult NS_NewSVGCairoGlyphGeometry(nsISVGRendererGlyphGeometry **result,
nsISVGGlyphGeometrySource *src);
nsSVGCairoGlyphGeometry();
~nsSVGCairoGlyphGeometry();
nsresult Init(nsISVGGlyphGeometrySource* src);
void GetGlobalTransform(cairo_t *ctx);
public:
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsISVGRendererGlyphGeometry interface:
NS_DECL_NSISVGRENDERERGLYPHGEOMETRY
protected:
nsCOMPtr<nsISVGGlyphGeometrySource> mSource;
};
/** @} */
//----------------------------------------------------------------------
// implementation:
nsSVGCairoGlyphGeometry::nsSVGCairoGlyphGeometry()
{
}
nsSVGCairoGlyphGeometry::~nsSVGCairoGlyphGeometry()
{
}
nsresult
nsSVGCairoGlyphGeometry::Init(nsISVGGlyphGeometrySource* src)
{
mSource = src;
return NS_OK;
}
nsresult
NS_NewSVGCairoGlyphGeometry(nsISVGRendererGlyphGeometry **result,
nsISVGGlyphGeometrySource *src)
{
*result = nsnull;
nsSVGCairoGlyphGeometry* gg = new nsSVGCairoGlyphGeometry();
if (!gg) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(gg);
nsresult rv = gg->Init(src);
if (NS_FAILED(rv)) {
NS_RELEASE(gg);
return rv;
}
*result = gg;
return rv;
}
//----------------------------------------------------------------------
// 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:
/** Implements void render(in nsISVGRendererCanvas canvas); */
NS_IMETHODIMP
nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
{
nsCOMPtr<nsISVGCairoCanvas> cairoCanvas = do_QueryInterface(canvas);
NS_ASSERTION(cairoCanvas, "wrong svg render context for geometry!");
if (!cairoCanvas) return NS_ERROR_FAILURE;
cairo_t *ctx = cairoCanvas->GetContext();
/* get the metrics */
nsCOMPtr<nsISVGCairoGlyphMetrics> metrics;
{
nsCOMPtr<nsISVGRendererGlyphMetrics> xpmetrics;
mSource->GetMetrics(getter_AddRefs(xpmetrics));
metrics = do_QueryInterface(xpmetrics);
NS_ASSERTION(metrics, "wrong metrics object!");
if (!metrics)
return NS_ERROR_FAILURE;
}
cairo_font_t *font = metrics->GetFont();
/* save/pop the state so we don't screw up the xform */
cairo_save(ctx);
cairo_set_font(ctx, font);
GetGlobalTransform(ctx);
float x,y;
mSource->GetX(&x);
mSource->GetY(&y);
cairo_move_to(ctx, x, y);
PRBool hasFill = PR_FALSE;
{
PRUint16 filltype;
mSource->GetFillPaintType(&filltype);
if (filltype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR)
hasFill = PR_TRUE;
}
PRBool hasStroke = PR_FALSE;
{
PRUint16 stroketype;
mSource->GetStrokePaintType(&stroketype);
if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR)
hasStroke = PR_TRUE;
}
if (!hasFill && !hasStroke) return NS_OK; // nothing to paint
if (hasFill) {
nscolor rgb;
mSource->GetFillPaint(&rgb);
float opacity;
mSource->GetFillOpacity(&opacity);
cairo_set_rgb_color(ctx,
NS_GET_R(rgb)/255.0,
NS_GET_G(rgb)/255.0,
NS_GET_B(rgb)/255.0);
cairo_set_alpha(ctx, double(opacity));
nsAutoString text;
mSource->GetCharacterData(text);
cairo_show_text(ctx, (unsigned char*)NS_ConvertUCS2toUTF8(text).get());
}
if (hasStroke) {
nscolor rgb;
mSource->GetStrokePaint(&rgb);
float opacity;
mSource->GetStrokeOpacity(&opacity);
cairo_set_rgb_color(ctx,
NS_GET_R(rgb)/255.0,
NS_GET_G(rgb)/255.0,
NS_GET_B(rgb)/255.0);
cairo_set_alpha(ctx, double(opacity));
float width;
mSource->GetStrokeWidth(&width);
cairo_set_line_width(ctx, double(width));
PRUint16 capStyle;
mSource->GetStrokeLinecap(&capStyle);
switch (capStyle) {
case nsISVGGeometrySource::STROKE_LINECAP_BUTT:
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_BUTT);
break;
case nsISVGGeometrySource::STROKE_LINECAP_ROUND:
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_ROUND);
break;
case nsISVGGeometrySource::STROKE_LINECAP_SQUARE:
cairo_set_line_cap(ctx, CAIRO_LINE_CAP_SQUARE);
break;
}
float miterlimit;
mSource->GetStrokeMiterlimit(&miterlimit);
cairo_set_miter_limit(ctx, double(miterlimit));
PRUint16 joinStyle;
mSource->GetStrokeLinejoin(&joinStyle);
switch(joinStyle) {
case nsISVGGeometrySource::STROKE_LINEJOIN_MITER:
cairo_set_line_join(ctx, CAIRO_LINE_JOIN_MITER);
break;
case nsISVGGeometrySource::STROKE_LINEJOIN_ROUND:
cairo_set_line_join(ctx, CAIRO_LINE_JOIN_ROUND);
break;
case nsISVGGeometrySource::STROKE_LINEJOIN_BEVEL:
cairo_set_line_join(ctx, CAIRO_LINE_JOIN_BEVEL);
break;
}
float *dashArray, offset;
PRUint32 count;
mSource->GetStrokeDashArray(&dashArray, &count);
if (count > 0) {
double *dashes = new double[count];
for (unsigned i=0; i<count; i++)
dashes[i] = dashArray[i];
mSource->GetStrokeDashoffset(&offset);
cairo_set_dash(ctx, dashes, count, double(offset));
nsMemory::Free(dashArray);
delete [] dashes;
}
nsAutoString text;
mSource->GetCharacterData(text);
cairo_text_path(ctx, (unsigned char*)NS_ConvertUCS2toUTF8(text).get());
cairo_stroke(ctx);
}
cairo_restore(ctx);
return NS_OK;
}
/** Implements nsISVGRendererRegion update(in unsigned long updatemask); */
NS_IMETHODIMP
nsSVGCairoGlyphGeometry::Update(PRUint32 updatemask, nsISVGRendererRegion **_retval)
{
*_retval = nsnull;
return NS_OK;
}
/** Implements nsISVGRendererRegion getCoveredRegion(); */
NS_IMETHODIMP
nsSVGCairoGlyphGeometry::GetCoveredRegion(nsISVGRendererRegion **_retval)
{
return NS_NewSVGCairoRectRegion(_retval, -10000, -10000, 20000, 20000);
}
/** Implements boolean containsPoint(in float x, in float y); */
NS_IMETHODIMP
nsSVGCairoGlyphGeometry::ContainsPoint(float x, float y, PRBool *_retval)
{
*_retval = PR_FALSE;
/* get the metrics */
nsCOMPtr<nsISVGCairoGlyphMetrics> metrics;
{
nsCOMPtr<nsISVGRendererGlyphMetrics> xpmetrics;
mSource->GetMetrics(getter_AddRefs(xpmetrics));
metrics = do_QueryInterface(xpmetrics);
NS_ASSERTION(metrics, "wrong metrics object!");
if (!metrics)
return NS_ERROR_FAILURE;
}
cairo_font_t *font = metrics->GetFont();
cairo_t *ctx = cairo_create();
cairo_set_font(ctx, font);
GetGlobalTransform(ctx);
nsAutoString text;
mSource->GetCharacterData(text);
cairo_text_path(ctx, (unsigned char*)NS_ConvertUCS2toUTF8(text).get());
cairo_default_matrix(ctx);
*_retval = cairo_in_fill(ctx, x, y);
cairo_destroy(ctx);
return NS_OK;
}
void
nsSVGCairoGlyphGeometry::GetGlobalTransform(cairo_t *ctx)
{
nsCOMPtr<nsIDOMSVGMatrix> ctm;
mSource->GetCTM(getter_AddRefs(ctm));
NS_ASSERTION(ctm, "graphic source didn't specify a ctm");
float m[6];
float val;
ctm->GetA(&val);
m[0] = val;
ctm->GetB(&val);
m[1] = val;
ctm->GetC(&val);
m[2] = val;
ctm->GetD(&val);
m[3] = val;
ctm->GetE(&val);
m[4] = val;
ctm->GetF(&val);
m[5] = val;
cairo_matrix_t *matrix = cairo_matrix_create();
cairo_matrix_set_affine(matrix, m[0], m[1], m[2], m[3], m[4], m[5]);
cairo_concat_matrix(ctx, matrix);
}

Просмотреть файл

@ -0,0 +1,52 @@
/* -*- 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.h
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#ifndef __NS_SVGCAIRO_GLYPHGEOMETRY_H__
#define __NS_SVGCAIRO_GLYPHGEOMETRY_H__
class nsISVGRendererGlyphGeometry;
class nsISVGGlyphGeometrySource;
nsresult
NS_NewSVGCairoGlyphGeometry(nsISVGRendererGlyphGeometry **result,
nsISVGGlyphGeometrySource *src);
#endif // __NS_SVGCAIRO_GLYPHGEOMETRY_H__

Просмотреть файл

@ -0,0 +1,341 @@
/* -*- 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/nsSVGGDIPlusGlyphMetrics.h
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#include "nsCOMPtr.h"
#include "nsISVGGlyphMetricsSource.h"
#include "nsPromiseFlatString.h"
#include "nsFont.h"
#include "nsIPresContext.h"
#include "nsISVGCairoGlyphMetrics.h"
#include "nsSVGCairoGlyphMetrics.h"
#include "nsIDOMSVGMatrix.h"
#include "nsIDOMSVGRect.h"
#include "nsSVGTypeCIDs.h"
#include "nsIComponentManager.h"
#include <cairo.h>
/**
* \addtogroup gdiplus_renderer Cairo Rendering Engine
* @{
*/
/**
* \addtogroup gdiplus_renderer Cairo Rendering Engine
* @{
*/
////////////////////////////////////////////////////////////////////////
/**
* Cairo glyph metrics implementation
*/
class nsSVGCairoGlyphMetrics : public nsISVGCairoGlyphMetrics
{
protected:
friend nsresult NS_NewSVGCairoGlyphMetrics(nsISVGRendererGlyphMetrics **result,
nsISVGGlyphMetricsSource *src);
nsSVGCairoGlyphMetrics(nsISVGGlyphMetricsSource *src);
~nsSVGCairoGlyphMetrics();
public:
// nsISupports interface:
NS_DECL_ISUPPORTS
// nsISVGRendererGlyphMetrics interface:
NS_DECL_NSISVGRENDERERGLYPHMETRICS
NS_IMETHOD_(void) GetSubBoundingBox(PRUint32 charoffset, PRUint32 count,
nsIDOMSVGRect * *aBoundingBox);
NS_IMETHOD_(cairo_font_t*)GetFont() { return mFont; }
private:
cairo_t *mCT;
cairo_font_t *mFont;
cairo_text_extents_t mExtents;
nsCOMPtr<nsISVGGlyphMetricsSource> mSource;
};
/** @} */
//----------------------------------------------------------------------
// implementation:
nsSVGCairoGlyphMetrics::nsSVGCairoGlyphMetrics(nsISVGGlyphMetricsSource *src)
: mFont(NULL), mSource(src)
{
mCT = cairo_create();
}
nsSVGCairoGlyphMetrics::~nsSVGCairoGlyphMetrics()
{
// don't delete mFont because the cairo_destroy takes it down
cairo_destroy(mCT);
}
nsresult
NS_NewSVGCairoGlyphMetrics(nsISVGRendererGlyphMetrics **result,
nsISVGGlyphMetricsSource *src)
{
*result = new nsSVGCairoGlyphMetrics(src);
if (!*result) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*result);
return NS_OK;
}
//----------------------------------------------------------------------
// nsISupports methods:
NS_IMPL_ADDREF(nsSVGCairoGlyphMetrics)
NS_IMPL_RELEASE(nsSVGCairoGlyphMetrics)
NS_INTERFACE_MAP_BEGIN(nsSVGCairoGlyphMetrics)
NS_INTERFACE_MAP_ENTRY(nsISVGRendererGlyphMetrics)
NS_INTERFACE_MAP_ENTRY(nsISVGCairoGlyphMetrics)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// nsISVGRendererGlyphMetrics methods:
/** Implements float getBaselineOffset(in unsigned short baselineIdentifier); */
NS_IMETHODIMP
nsSVGCairoGlyphMetrics::GetBaselineOffset(PRUint16 baselineIdentifier, float *_retval)
{
switch (baselineIdentifier) {
case BASELINE_TEXT_BEFORE_EDGE:
*_retval = mExtents.y_bearing;
break;
case BASELINE_TEXT_AFTER_EDGE:
*_retval = (float)(PRUint16)(mExtents.y_bearing + mExtents.height + 0.5);
break;
case BASELINE_CENTRAL:
case BASELINE_MIDDLE:
*_retval = (float)(PRUint16)(mExtents.y_bearing + mExtents.height/2.0 + 0.5);
break;
case BASELINE_ALPHABETIC:
default:
{
// xxxx
*_retval = 0.0;
#if 0
FontFamily family;
GetFont()->GetFamily(&family);
INT style = GetFont()->GetStyle();
// alternatively to rounding here, we could set the
// pixeloffsetmode to 'PixelOffsetModeHalf' on painting
*_retval = (float)(UINT16)(GetBoundingRect()->Y
+ GetFont()->GetSize()
*family.GetCellAscent(style)/family.GetEmHeight(style)
+ 0.5);
#endif
}
break;
}
return NS_OK;
}
/** Implements readonly attribute float #advance; */
NS_IMETHODIMP
nsSVGCairoGlyphMetrics::GetAdvance(float *aAdvance)
{
*aAdvance = mExtents.x_advance;
return NS_OK;
}
// XXX
NS_IMETHODIMP_(void)
nsSVGCairoGlyphMetrics::GetSubBoundingBox(PRUint32 charoffset, PRUint32 count,
nsIDOMSVGRect * *aBoundingBox)
{
*aBoundingBox = nsnull;
nsCOMPtr<nsIDOMSVGRect> rect = do_CreateInstance(NS_SVGRECT_CONTRACTID);
NS_ASSERTION(rect, "could not create rect");
if (!rect) {
*aBoundingBox = NULL;
return;
}
cairo_text_extents_t extents;
nsAutoString text;
mSource->GetCharacterData(text);
cairo_text_extents(mCT,
(unsigned char *)NS_ConvertUCS2toUTF8(Substring(text,
charoffset,
count)).get(),
&extents);
rect->SetX(extents.x_bearing);
rect->SetY(extents.y_bearing);
rect->SetWidth(extents.width);
rect->SetHeight(extents.height);
*aBoundingBox = rect;
NS_ADDREF(*aBoundingBox);
}
/** Implements readonly attribute nsIDOMSVGRect #boundingBox; */
NS_IMETHODIMP
nsSVGCairoGlyphMetrics::GetBoundingBox(nsIDOMSVGRect * *aBoundingBox)
{
*aBoundingBox = nsnull;
nsCOMPtr<nsIDOMSVGRect> rect = do_CreateInstance(NS_SVGRECT_CONTRACTID);
NS_ASSERTION(rect, "could not create rect");
if (!rect) return NS_ERROR_FAILURE;
rect->SetX(mExtents.x_bearing);
rect->SetY(mExtents.y_bearing);
rect->SetWidth(mExtents.width);
rect->SetHeight(mExtents.height);
*aBoundingBox = rect;
NS_ADDREF(*aBoundingBox);
return NS_OK;
}
/** Implements nsIDOMSVGRect getExtentOfChar(in unsigned long charnum); */
NS_IMETHODIMP
nsSVGCairoGlyphMetrics::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
{
*_retval = nsnull;
cairo_glyph_t glyph;
cairo_text_extents_t extent;
glyph.x = glyph.y = 0;
nsAutoString text;
mSource->GetCharacterData(text);
glyph.index = text[charnum];
cairo_set_font(mCT, mFont);
cairo_glyph_extents(mCT, &glyph, 1, &extent);
nsCOMPtr<nsIDOMSVGRect> rect = do_CreateInstance(NS_SVGRECT_CONTRACTID);
NS_ASSERTION(rect, "could not create rect");
if (!rect) return NS_ERROR_FAILURE;
rect->SetX(extent.x_bearing);
rect->SetY(extent.y_bearing);
rect->SetWidth(extent.width);
rect->SetHeight(extent.height);
*_retval = rect;
NS_ADDREF(*_retval);
return NS_OK;
}
/** Implements boolean update(in unsigned long updatemask); */
NS_IMETHODIMP
nsSVGCairoGlyphMetrics::Update(PRUint32 updatemask, PRBool *_retval)
{
*_retval = PR_FALSE;
if (updatemask & nsISVGGlyphMetricsSource::UPDATEMASK_CHARACTER_DATA) {
*_retval = PR_TRUE;
}
if (updatemask & nsISVGGlyphMetricsSource::UPDATEMASK_FONT) {
if (mFont) {
// don't delete mFont because we're just pointing at the ctx copy
mFont = NULL;
}
*_retval = PR_TRUE;
}
if (!mFont) {
nsFont font;
mSource->GetFont(&font);
cairo_font_slant_t slant;
cairo_font_weight_t weight = CAIRO_FONT_WEIGHT_NORMAL;
switch (font.style) {
case NS_FONT_STYLE_NORMAL:
slant = CAIRO_FONT_SLANT_NORMAL;
break;
case NS_FONT_STYLE_ITALIC:
slant = CAIRO_FONT_SLANT_ITALIC;
break;
case NS_FONT_STYLE_OBLIQUE:
slant = CAIRO_FONT_SLANT_OBLIQUE;
break;
}
if (font.weight % 100 == 0) {
if (font.weight >= 600)
weight = CAIRO_FONT_WEIGHT_BOLD;
} else if (font.weight % 100 < 50) {
weight = CAIRO_FONT_WEIGHT_BOLD;
}
nsString family;
font.GetFirstFamily(family);
char *f = ToNewCString(family);
cairo_select_font(mCT, f, slant, weight);
free(f);
mFont = cairo_current_font(mCT);
nsCOMPtr<nsIPresContext> presContext;
mSource->GetPresContext(getter_AddRefs(presContext));
float pxPerTwips;
pxPerTwips = presContext->TwipsToPixels();
cairo_scale_font(mCT, font.size*pxPerTwips);
nsAutoString text;
mSource->GetCharacterData(text);
cairo_text_extents(mCT,
(unsigned char*)NS_ConvertUCS2toUTF8(text).get(),
&mExtents);
}
return NS_OK;
}

Просмотреть файл

@ -0,0 +1,51 @@
/* -*- 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/nsSVGGDIPlusGlyphMetrics.h
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ----- END LICENSE BLOCK ----- */
#ifndef __NS_SVGCAIRO_GLYPHMETRICS_H__
#define __NS_SVGCAIRO_GLYPHMETRICS_H__
class nsISVGRendererGlyphMetrics;
class nsISVGGlyphMetricsSource;
nsresult NS_NewSVGCairoGlyphMetrics(nsISVGRendererGlyphMetrics **result,
nsISVGGlyphMetricsSource *src);
#endif // __NS_SVGCAIRO_GLYPHMETRICS_H__

Просмотреть файл

@ -43,9 +43,9 @@ class nsSVGCairoRectRegion : public nsISVGRendererRegion
{
protected:
friend nsresult NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result,
int x, int y,
int width, int height);
nsSVGCairoRectRegion(int x, int y, int w, int h);
float x, float y,
float width, float height);
nsSVGCairoRectRegion(float x, float y, float w, float h);
public:
// nsISupports interface:
@ -55,15 +55,15 @@ public:
NS_DECL_NSISVGRENDERERREGION
private:
int mX, mY, mWidth, mHeight;
float mX, mY, mWidth, mHeight;
};
//----------------------------------------------------------------------
// implementation:
nsresult
NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result, int x, int y,
int width, int height)
NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result, float x, float y,
float width, float height)
{
*result = new nsSVGCairoRectRegion(x, y, width, height);
@ -73,7 +73,7 @@ NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result, int x, int y,
return NS_OK;
}
nsSVGCairoRectRegion::nsSVGCairoRectRegion(int x, int y, int w, int h) :
nsSVGCairoRectRegion::nsSVGCairoRectRegion(float x, float y, float w, float h) :
mX(x), mY(y), mWidth(w), mHeight(h)
{
}
@ -99,10 +99,10 @@ nsSVGCairoRectRegion::Combine(nsISVGRendererRegion *other,
{
nsSVGCairoRectRegion *_other = static_cast<nsSVGCairoRectRegion*>(other); // ok, i know i'm being bad
int x1 = PR_MIN(mX, _other->mX);
int y1 = PR_MIN(mY, _other->mY);
int x2 = PR_MAX(mX+mWidth, _other->mX+_other->mWidth);
int y2 = PR_MAX(mY+mHeight, _other->mHeight+_other->mHeight);
float x1 = PR_MIN(mX, _other->mX);
float y1 = PR_MIN(mY, _other->mY);
float x2 = PR_MAX(mX+mWidth, _other->mX+_other->mWidth);
float y2 = PR_MAX(mY+mHeight, _other->mHeight+_other->mHeight);
return NS_NewSVGCairoRectRegion(_retval, x1, y1, x2-x1, y2-y1);
}

Просмотреть файл

@ -43,6 +43,6 @@ class nsISVGRendererRegion;
// region constructors:
nsresult NS_NewSVGCairoRectRegion(nsISVGRendererRegion** result,
int x, int y, int width, int height);
float x, float y, float width, float height);
#endif // __NS_SVGCAIRO_REGION_H__

Просмотреть файл

@ -44,10 +44,10 @@
#include "nsCOMPtr.h"
#include "nsISVGRenderer.h"
#include "nsSVGCairoPathGeometry.h"
//#include "nsSVGCairoGlyphGeometry.h"
//#include "nsSVGCairoGlyphMetrics.h"
#include "nsSVGCairoGlyphGeometry.h"
#include "nsSVGCairoGlyphMetrics.h"
#include "nsSVGCairoCanvas.h"
//#include "nsSVGCairoRegion.h"
#include "nsSVGCairoRegion.h"
void NS_InitSVGCairoGlyphMetricsGlobals();
void NS_FreeSVGCairoGlyphMetricsGlobals();
@ -115,7 +115,7 @@ void NS_FreeSVGRendererCairoGlobals()
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_ISUPPORTS1(nsSVGRendererCairo, nsISVGRenderer);
NS_IMPL_ISUPPORTS1(nsSVGRendererCairo, nsISVGRenderer)
//----------------------------------------------------------------------
// nsISVGRenderer methods
@ -133,9 +133,7 @@ NS_IMETHODIMP
nsSVGRendererCairo::CreateGlyphMetrics(nsISVGGlyphMetricsSource *src,
nsISVGRendererGlyphMetrics **_retval)
{
fprintf(stderr, "CreateGlyphMetric (unimplemented)\n");
// return NS_NewSVGCairoGlyphMetrics(_retval, src);
return NS_OK;
return NS_NewSVGCairoGlyphMetrics(_retval, src);
}
/** Implements nsISVGRendererGlyphGeometry createGlyphGeometry(in nsISVGGlyphGeometrySource src); */
@ -143,9 +141,7 @@ NS_IMETHODIMP
nsSVGRendererCairo::CreateGlyphGeometry(nsISVGGlyphGeometrySource *src,
nsISVGRendererGlyphGeometry **_retval)
{
fprintf(stderr, "CreateGlyphGeometry (unimplemented)\n");
// return NS_NewSVGCairoGlyphGeometry(_retval, src);
return NS_OK;
return NS_NewSVGCairoGlyphGeometry(_retval, src);
}
/** Implements [noscript] nsISVGRendererCanvas createCanvas(in nsIRenderingContext ctx,
@ -164,7 +160,5 @@ NS_IMETHODIMP
nsSVGRendererCairo::CreateRectRegion(float x, float y, float width, float height,
nsISVGRendererRegion **_retval)
{
fprintf(stderr, "CreateRectRegion (unimplemented)\n");
// return NS_NewSVGCairoRectRegion(_retval, x, y, width, height);
return NS_OK;
return NS_NewSVGCairoRectRegion(_retval, x, y, width, height);
}