Adding more utility functions to thebes from vlad. Cleaning up some coding style inconsistencies.

This commit is contained in:
pavlov%pavlov.net 2005-06-30 04:58:27 +00:00
parent 92b3f50a1c
commit 11d9ea1f2c
14 changed files with 289 additions and 48 deletions

View File

@ -26,4 +26,8 @@ ifeq ($(MOZ_GFX_TOOLKIT),windows)
EXPORTS += gfxWindowsSurface.h
endif
ifeq ($(MOZ_GFX_TOOLKIT),gtk2)
EXPORTS += gfxXlibSurface.h
endif
include $(topsrcdir)/config/rules.mk

View File

@ -43,22 +43,37 @@
#include "gfxTypes.h"
class gfxASurface {
THEBES_DECL_REFCOUNTING
THEBES_DECL_REFCOUNTING_ABSTRACT
public:
/*** this DOES NOT addref the surface */
cairo_surface_t *CairoSurface() { return mSurface; }
cairo_surface_t* CairoSurface() { return mSurface; }
protected:
void Init(cairo_surface_t* surface) {
void Init(cairo_surface_t *surface) {
mDestroyed = PR_FALSE;
mSurface = surface;
}
virtual ~gfxASurface() {
void Destroy() {
if (mDestroyed) {
NS_WARNING("Calling Destroy on an already-destroyed surface!");
return;
}
cairo_surface_destroy(mSurface);
mDestroyed = PR_TRUE;
}
cairo_surface_t* mSurface;
virtual ~gfxASurface() {
if (!mDestroyed) {
NS_WARNING("gfxASurface::~gfxASurface called, but cairo surface was not destroyed! (Did someone forget to call Destroy()?)");
}
}
protected:
cairo_surface_t *mSurface;
PRBool mDestroyed;
};
#endif /* GFX_ASURFACE_H */

View File

@ -46,22 +46,23 @@
#include "gfxPoint.h"
#include "gfxRect.h"
#include "gfxTypes.h"
#include "gfxMatrix.h"
#include "gfxPattern.h"
class gfxMatrix;
class gfxRegion;
class gfxFilter;
class gfxTextRun;
class gfxPattern;
class gfxContext {
THEBES_DECL_REFCOUNTING
public:
gfxContext(gfxASurface* surface);
gfxContext(gfxASurface *surface);
~gfxContext();
// this does not addref
gfxASurface* CurrentSurface();
cairo_t* GetCairo() { return mCairo; }
/**
** State
@ -93,8 +94,10 @@ public:
void NegativeArc(gfxPoint center, gfxFloat radius,
gfxFloat angle1, gfxFloat angle2);
// path helpers
void Line(gfxPoint start, gfxPoint end); // XXX snapToPixels option?
void Rectangle(gfxRect rect, PRBool snapToPixels = PR_FALSE);
void Ellipse(gfxPoint center, gfxSize dimensions);
void Polygon(const gfxPoint *points, PRUint32 numPoints);
/**
@ -119,6 +122,7 @@ public:
void Multiply(const gfxMatrix& other);
void SetMatrix(const gfxMatrix& matrix);
void IdentityMatrix();
gfxMatrix CurrentMatrix() const;
gfxPoint DeviceToUser(gfxPoint point) const;
@ -131,8 +135,8 @@ public:
**/
void SetColor(const gfxRGBA& c);
void SetPattern(gfxPattern* pattern);
void SetSource(gfxASurface* surface) {
void SetPattern(gfxPattern *pattern);
void SetSource(gfxASurface *surface) {
SetSource(surface, gfxPoint(0, 0));
}
void SetSource(gfxASurface* surface, gfxPoint origin);
@ -148,13 +152,20 @@ public:
// Creates a new path with a rectangle from 0,0 to size.w,size.h
// and calls cairo_fill
void DrawSurface(gfxASurface* surface, gfxSize size);
void DrawSurface(gfxASurface *surface, gfxSize size);
/**
** Line Properties
**/
void SetDash(gfxFloat* dashes, int ndash, gfxFloat offset);
typedef enum {
gfxLineSolid,
gfxLineDashed,
gfxLineDotted
} gfxLineType;
void SetDash(gfxLineType ltype);
void SetDash(gfxFloat *dashes, int ndash, gfxFloat offset);
//void getDash() const;
void SetLineWidth(gfxFloat width);

View File

@ -47,17 +47,25 @@ class gfxImageSurface : public gfxASurface {
THEBES_DECL_ISUPPORTS_INHERITED
public:
gfxImageSurface(int format, long width, long height);
typedef enum {
ImageFormatARGB32,
ImageFormatRGB24,
ImageFormatA8,
ImageFormatA1
} gfxImageFormat;
gfxImageSurface(gfxImageFormat format, long width, long height);
virtual ~gfxImageSurface();
// ImageSurface methods
int Format() const { return 0; }
int Format() const { return mFormat; }
long Width() const { return mWidth; }
long Height() const { return mHeight; }
unsigned char* GetData() { return mData; } // delete this data under us and die.
long Stride() const;
unsigned char* Data() { return mData; } // delete this data under us and die.
private:
unsigned char* mData;
unsigned char *mData;
int mFormat;
long mWidth;
long mHeight;

View File

@ -38,10 +38,9 @@
#ifndef GFX_MATRIX_H
#define GFX_MATRIX_H
#include <math.h>
#include <cairo.h>
#include "gfxPoint.h"
#include "gfxTypes.h"
// XX - I don't think this class should use gfxFloat at all,
@ -89,6 +88,7 @@ public:
*xx = mat.xx;
*yx = mat.yx;
*xy = mat.xy;
*yy = mat.yy;
*x0 = mat.x0;
*y0 = mat.y0;
}
@ -135,6 +135,18 @@ public:
void TransformPoint(gfxFloat *x, gfxFloat *y) const {
cairo_matrix_transform_point(&mat, x, y);
}
gfxSize GetScale() const {
return gfxSize(mat.xx, mat.yy);
}
gfxPoint GetTranslate() const {
return gfxPoint(mat.x0, mat.y0);
}
bool HasShear() const {
return ((mat.xy != 0.0) || (mat.yx != 0.0));
}
};
#endif /* GFX_MATRIX_H */

View File

@ -46,6 +46,8 @@
#include "gfxTypes.h"
class gfxPattern {
THEBES_DECL_REFCOUNTING
public:
// from another surface
gfxPattern(gfxASurface* surface) {
@ -64,7 +66,7 @@ public:
cx1, cy1, radius1);
}
~gfxPattern() {
virtual ~gfxPattern() {
cairo_pattern_destroy(mPattern);
}

View File

@ -83,6 +83,12 @@ struct gfxPoint {
gfxPoint operator+(const gfxSize& s) const {
return gfxPoint(x + s.width, y + s.height);
}
gfxPoint operator-(const gfxPoint& p) const {
return gfxPoint(x - p.x, y - p.y);
}
gfxPoint operator-(const gfxSize& s) const {
return gfxPoint(x - s.width, y - s.height);
}
gfxPoint& round() {
x = ::floor(x + 0.5);
y = ::floor(y + 0.5);

View File

@ -55,9 +55,18 @@ typedef double gfxFloat;
#include "nsAutoPtr.h"
#define THEBES_IMPL_REFCOUNTING(_class) \
NS_IMPL_ADDREF(_class) \
NS_IMPL_ADDREF(_class) \
NS_IMPL_RELEASE(_class)
#define THEBES_DECL_REFCOUNTING_ABSTRACT \
public: \
NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; \
NS_IMETHOD_(nsrefcnt) Release(void) = 0; \
protected: \
nsAutoRefCnt mRefCnt; \
NS_DECL_OWNINGTHREAD \
public:
#define THEBES_DECL_REFCOUNTING \
public: \

View File

@ -39,7 +39,6 @@
#define GFX_WINDOWSSURFACE_H
#include "gfxASurface.h"
#include "gfxPoint.h"
#include <cairo-win32.h>

View File

@ -46,9 +46,35 @@ class gfxXlibSurface : public gfxASurface {
THEBES_DECL_ISUPPORTS_INHERITED
public:
gfxXlibSurface(Display *dpy, Drawable drawable,
Visual *visual);
// create a surface for the specified dpy/drawable/visual.
// Will use XGetGeometry to query the window/pixmap size.
gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual);
// create a surface for the specified dpy/drawable/visual,
// with explicitly provided width/height.
gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, unsigned long width, unsigned long height);
// create a new Pixmap on the display dpy, with
// the root window as the parent and the default depth
// for the default screen, and attach the given visual
gfxXlibSurface(Display *dpy, Visual *visual, unsigned long width, unsigned long height);
virtual ~gfxXlibSurface();
unsigned long Width() { return mWidth; }
unsigned long Height() { return mHeight; }
Display* XDisplay() { return mDisplay; }
Drawable XDrawable() { return mDrawable; }
protected:
PRBool mOwnsPixmap;
Display *mDisplay;
Drawable mDrawable;
unsigned long mWidth;
unsigned long mHeight;
};
#endif /* GFX_XLIBSURFACE_H */

View File

@ -7,7 +7,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = thebes
LIBRARY_NAME = libthebes
LIBRARY_NAME = thebes
LIBXUL_LIBRARY = 1
REQUIRES = \
@ -18,13 +18,19 @@ REQUIRES = \
CPPSRCS = \
gfxContext.cpp \
gfxImageSurface.cpp
gfxImageSurface.cpp \
gfxPattern.cpp \
$(NULL)
ifeq ($(MOZ_GFX_TOOLKIT),windows)
CPPSRCS += gfxWindowsSurface.cpp
endif
ifeq ($(MOZ_GFX_TOOLKIT),gtk2)
CPPSRCS += gfxXlibSurface.cpp
endif
FORCE_STATIC_LIB = 1
# This library is used by other shared libs in a static build
FORCE_USE_PIC = 1

View File

@ -35,6 +35,11 @@
*
* ***** END LICENSE BLOCK ***** */
#ifdef _MSC_VER
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include "gfxContext.h"
#include "gfxColor.h"
@ -42,19 +47,20 @@
#include "gfxASurface.h"
#include "gfxPattern.h"
THEBES_IMPL_REFCOUNTING(gfxContext)
gfxContext::gfxContext(gfxASurface* surface)
gfxContext::gfxContext(gfxASurface *surface) :
mSurface(surface)
{
mCairo = cairo_create(surface->CairoSurface());
mSurface = surface;
}
gfxContext::~gfxContext()
{
cairo_destroy(mCairo);
}
gfxASurface* gfxContext::CurrentSurface()
gfxASurface *gfxContext::CurrentSurface()
{
return mSurface;
}
@ -108,14 +114,20 @@ void gfxContext::Arc(gfxPoint center, gfxFloat radius,
cairo_arc(mCairo, center.x, center.y, radius, angle1, angle2);
}
void gfxContext::Line(gfxPoint start, gfxPoint end)
{
MoveTo(start);
LineTo(end);
}
void gfxContext::Rectangle(gfxRect rect, PRBool snapToPixels)
{
if (snapToPixels) {
gfxPoint p1 = UserToDevice (rect.pos);
gfxPoint p2 = UserToDevice (rect.pos + rect.size);
gfxPoint p1 = UserToDevice(rect.pos);
gfxPoint p2 = UserToDevice(rect.pos + rect.size);
gfxPoint p3 = UserToDevice (rect.pos + gfxSize(rect.size.width, 0.0));
gfxPoint p4 = UserToDevice (rect.pos + gfxSize(0.0, rect.size.height));
gfxPoint p3 = UserToDevice(rect.pos + gfxSize(rect.size.width, 0.0));
gfxPoint p4 = UserToDevice(rect.pos + gfxSize(0.0, rect.size.height));
if (p1.x != p4.x ||
p2.x != p3.x ||
@ -145,14 +157,49 @@ dontsnap:
cairo_rectangle(mCairo, rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
}
void gfxContext::Ellipse(gfxPoint center, gfxSize dimensions)
{
// circle?
if (dimensions.width == dimensions.height) {
double radius = dimensions.width / 2.0;
cairo_arc(mCairo, center.x, center.y, radius, 0, 2.0 * M_PI);
} else {
double x = center.x;
double y = center.y;
double w = dimensions.width;
double h = dimensions.height;
cairo_new_path(mCairo);
cairo_move_to(mCairo, x + w/2.0, y);
cairo_rel_curve_to(mCairo,
0, 0,
w / 2.0, 0,
w / 2.0, h / 2.0);
cairo_rel_curve_to(mCairo,
0, 0,
0, h / 2.0,
- w / 2.0, h / 2.0);
cairo_rel_curve_to(mCairo,
0, 0,
- w / 2.0, 0,
- w / 2.0, - h / 2.0);
cairo_rel_curve_to(mCairo,
0, 0,
0, - h / 2.0,
w / 2.0, - h / 2.0);
}
}
void gfxContext::Polygon(const gfxPoint *points, PRUint32 numPoints)
{
if (numPoints == 0)
return;
cairo_move_to(mCairo, (gfxFloat)points[0].x, (gfxFloat)points[0].y);
for (unsigned long i = 1; i < numPoints; ++i) {
cairo_line_to(mCairo, (gfxFloat)points[i].x, (gfxFloat)points[i].y);
cairo_move_to(mCairo, points[0].x, points[0].y);
for (PRUint32 i = 1; i < numPoints; ++i) {
cairo_line_to(mCairo, points[i].x, points[i].y);
}
}
@ -194,6 +241,11 @@ void gfxContext::SetMatrix(const gfxMatrix& matrix)
cairo_set_matrix(mCairo, &mat);
}
void gfxContext::IdentityMatrix()
{
cairo_identity_matrix(mCairo);
}
gfxMatrix gfxContext::CurrentMatrix() const
{
cairo_matrix_t mat;
@ -239,7 +291,26 @@ gfxContext::AntialiasMode gfxContext::CurrentAntialiasMode()
return MODE_COVERAGE;
}
void gfxContext::SetDash(gfxFloat* dashes, int ndash, gfxFloat offset)
void gfxContext::SetDash(gfxLineType ltype)
{
static double dash[] = {5.0, 5.0};
static double dot[] = {1.0, 1.0};
switch (ltype) {
case gfxLineDashed:
SetDash(dash, 2, 0.0);
break;
case gfxLineDotted:
SetDash(dot, 2, 0.0);
break;
case gfxLineSolid:
default:
SetDash(nsnull, 0, 0.0);
break;
}
}
void gfxContext::SetDash(gfxFloat *dashes, int ndash, gfxFloat offset)
{
cairo_set_dash(mCairo, dashes, ndash, offset);
}
@ -321,7 +392,7 @@ void gfxContext::SetColor(const gfxRGBA& c)
cairo_set_source_rgba(mCairo, c.r, c.g, c.b, c.a);
}
void gfxContext::SetPattern(gfxPattern* pattern)
void gfxContext::SetPattern(gfxPattern *pattern)
{
cairo_set_source(mCairo, pattern->CairoPattern());
}

View File

@ -35,24 +35,55 @@
*
* ***** END LICENSE BLOCK ***** */
#include <stdio.h>
#include "gfxImageSurface.h"
THEBES_IMPL_REFCOUNTING(gfxImageSurface)
gfxImageSurface::gfxImageSurface(int format, long width, long height) :
gfxImageSurface::gfxImageSurface(gfxImageFormat format, long width, long height) :
mFormat(format), mWidth(width), mHeight(height)
{
mData = new unsigned char[width * height * 4];
long stride = Stride();
mData = new unsigned char[height * stride];
Init(cairo_image_surface_create_for_data((unsigned char*)mData,
CAIRO_FORMAT_ARGB32,
width,
height,
width * 4));
//memset(mData, 0xff, height*stride);
cairo_surface_t *surface =
cairo_image_surface_create_for_data((unsigned char*)mData,
(cairo_format_t)format,
width,
height,
stride);
Init(surface);
}
gfxImageSurface::~gfxImageSurface()
{
Destroy();
delete[] mData;
}
long
gfxImageSurface::Stride() const
{
long stride;
if (mFormat == ImageFormatARGB32)
stride = mWidth * 4;
else if (mFormat == ImageFormatRGB24)
stride = mWidth * 3;
else if (mFormat == ImageFormatA8)
stride = mWidth;
else if (mFormat == ImageFormatA1) {
stride = (mWidth + 7) / 8;
} else {
NS_WARNING("Unknown format specified to gfxImageSurface!");
stride = mWidth * 4;
}
stride = ((stride + 3) / 4) * 4;
return stride;
}

View File

@ -20,6 +20,7 @@
*
* Contributor(s):
* Stuart Parmenter <pavlov@pavlov.net>
* Vladimir Vukicevic <vladimir@pobox.com>
*
* 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
@ -39,12 +40,52 @@
THEBES_IMPL_REFCOUNTING(gfxXlibSurface)
gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable,
Visual *visual)
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual) :
mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable)
{
Init(cairo_xlib_surface_create(display, drawable, visual, CAIRO_FORMAT_ARGB32);
// figure out width/height/depth
Window root_ignore;
int x_ignore, y_ignore;
unsigned int bwidth_ignore, width, height, depth;
XGetGeometry(dpy,
drawable,
&root_ignore, &x_ignore, &y_ignore,
&width, &height,
&bwidth_ignore, &depth);
mWidth = width;
mHeight = height;
cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, width, height);
Init(surf);
}
gfxXlibSurface::gfxXlibSurface(Display* dpy, Drawable drawable, Visual* visual,
unsigned long width, unsigned long height) :
mOwnsPixmap(PR_FALSE), mDisplay(dpy), mDrawable(drawable), mWidth(width), mHeight(height)
{
cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, width, height);
Init(surf);
}
gfxXlibSurface::gfxXlibSurface(Display* dpy, Visual* visual, unsigned long width, unsigned long height) :
mOwnsPixmap(PR_TRUE), mDisplay(dpy), mWidth(width), mHeight(height)
{
mDrawable = (Drawable)XCreatePixmap(dpy,
RootWindow(dpy, DefaultScreen(dpy)),
width, height,
DefaultDepth(dpy, DefaultScreen(dpy)));
cairo_surface_t *surf = cairo_xlib_surface_create(dpy, pixmap, visual, width, height);
Init(surf);
}
gfxXlibSurface::~gfxXlibSurface()
{
Destroy();
if (mOwnsPixmap)
XFreePixmap(mDisplay, mDrawable);
}