Add opal to gnustep/libs/

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/opal/trunk@29208 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ericwa 2010-01-04 23:28:16 +00:00
commit cabbe42812
45 changed files with 6527 additions and 0 deletions

64
CGAffineTransform.c Normal file
View File

@ -0,0 +1,64 @@
/** <title>CGAffineTransform</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define IN_CGAFFINETRANSFORM_C
#include "CGAffineTransform.h"
#undef IN_CGAFFINETRANSFORM_C
#include <math.h>
#include "opal.h"
const CGAffineTransform CGAffineTransformIdentity = {1,0,0,1,0,0};
CGAffineTransform CGAffineTransformMakeRotation(float angle)
{
CGAffineTransform matrix;
float cosa = cos(angle);
float sina = sin(angle);
matrix.a = matrix.d = cosa;
matrix.b = sina;
matrix.c = -sina;
matrix.tx = matrix.ty = 0;
return matrix;
}
CGAffineTransform CGAffineTransformInvert(CGAffineTransform t)
{
CGAffineTransform inv;
float det;
det = t.a * t.d - t.b *t.c;
if (det == 0) {
errlog("%s:%d: Cannot invert matrix, determinant is 0\n",
__FILE__, __LINE__);
return t;
}
inv.a = t.d / det;
inv.b = -t.b / det;
inv.c = -t.c / det;
inv.d = t.a / det;
inv.tx = (t.c * t.ty - t.d * t.tx) / det;
inv.ty = (t.b * t.tx - t.a * t.ty) / det;
return inv;
}

216
CGAffineTransform.h Normal file
View File

@ -0,0 +1,216 @@
/** <title>CGAffineTransform</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGAffineTransform_h
#define OPAL_CGAffineTransform_h
#include <stddef.h>
#include <CGGeometry.h>
/* Data Types */
typedef struct CGAffineTransform
{
float a;
float b;
float c;
float d;
float tx;
float ty;
} CGAffineTransform;
/* Constants */
extern const CGAffineTransform CGAffineTransformIdentity;
/* Functions */
/* All but the most complex functions are declared static inline in this
* header file so that they are maximally efficient. In order to provide
* true functions (for code modules that don't have this header) this
* header is included in CGAffineTransform.c where the functions are no longer
* declared inline.
*/
#ifdef IN_CGAFFINETRANSFORM_C
#define GS_AFTR_SCOPE extern
#define GS_AFTR_ATTR
#else
#define GS_AFTR_SCOPE static inline
#define GS_AFTR_ATTR __attribute__((unused))
#endif
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformMake(
float a,
float b,
float c,
float d,
float tx,
float ty
) GS_AFTR_ATTR;
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformMakeTranslation(
float tx,
float ty
) GS_AFTR_ATTR;
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformMakeScale(
float sx,
float sy
) GS_AFTR_ATTR;
CGAffineTransform CGAffineTransformMakeRotation(float angle);
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformConcat(
CGAffineTransform t1,
CGAffineTransform t2
) GS_AFTR_ATTR;
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformTranslate(
CGAffineTransform t,
float tx,
float ty
) GS_AFTR_ATTR;
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformScale(
CGAffineTransform t,
float sx,
float sy
) GS_AFTR_ATTR;
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformRotate(
CGAffineTransform t,
float angle
) GS_AFTR_ATTR;
CGAffineTransform CGAffineTransformInvert(CGAffineTransform t);
GS_AFTR_SCOPE CGPoint CGPointApplyAffineTransform(
CGPoint point,
CGAffineTransform t
) GS_AFTR_ATTR;
GS_AFTR_SCOPE CGSize CGSizeApplyAffineTransform(
CGSize size,
CGAffineTransform t
) GS_AFTR_ATTR;
/* Inlined functions */
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformMake(
float a, float b, float c, float d, float tx, float ty)
{
CGAffineTransform matrix;
matrix.a = a;
matrix.b = b;
matrix.c = c;
matrix.d = d;
matrix.tx = tx;
matrix.ty = ty;
return matrix;
}
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformMakeTranslation(
float tx, float ty)
{
CGAffineTransform matrix;
matrix = CGAffineTransformIdentity;
matrix.tx = tx;
matrix.ty = ty;
return matrix;
}
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformMakeScale(float sx, float sy)
{
CGAffineTransform matrix;
matrix = CGAffineTransformIdentity;
matrix.a = sx;
matrix.d = sy;
return matrix;
}
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformConcat(
CGAffineTransform t1, CGAffineTransform t2)
{
CGAffineTransform t;
t.a = t1.a * t2.a + t1.b * t2.c;
t.b = t1.a * t2.b + t1.b * t2.d;
t.c = t1.c * t2.a + t1.d * t2.c;
t.d = t1.c * t2.b + t1.d * t2.d;
t.tx = t1.tx * t2.a + t1.ty * t2.c + t2.tx;
t.ty = t1.tx * t2.b + t1.ty * t2.d + t2.ty;
return t;
}
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformTranslate(
CGAffineTransform t, float tx, float ty)
{
t.tx += tx * t.a + ty * t.c;
t.ty += tx * t.b + ty * t.d;
return t;
}
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformScale(
CGAffineTransform t, float sx, float sy)
{
t.a *= sx;
t.b *= sx;
t.c *= sy;
t.d *= sy;
return t;
}
GS_AFTR_SCOPE CGAffineTransform CGAffineTransformRotate(
CGAffineTransform t, float angle)
{
return CGAffineTransformConcat(CGAffineTransformMakeRotation(angle), t);
}
GS_AFTR_SCOPE CGPoint CGPointApplyAffineTransform(
CGPoint point, CGAffineTransform t)
{
return CGPointMake(t.a * point.x + t.c * point.y + t.tx,
t.b * point.x + t.d * point.y + t.ty);
}
GS_AFTR_SCOPE CGSize CGSizeApplyAffineTransform(
CGSize size, CGAffineTransform t)
{
CGSize r;
r = CGSizeMake(t.a * size.width + t.c * size.height,
t.b * size.width + t.d * size.height);
if (r.width < 0) r.width = -r.width;
if (r.height < 0) r.height = -r.height;
return r;
}
#endif /* OPAL_CGAffineTransform_h */

36
CGBase.h Normal file
View File

@ -0,0 +1,36 @@
/** <title>CGBase</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2009 Eric Wasylishen <ewasylishen@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGBase_h
#define OPAL_CGBase_h
#include <float.h>
#define CGFLOAT_DEFINED 1
#define CGFLOAT_TYPE double
#define CGFLOAT_IS_DOUBLE 1
#define CGFLOAT_MIN DBL_MIN
#define CGFLOAT_MAX DBL_MAX
typedef CGFLOAT_TYPE CGFloat;
#endif

57
CGBitmapContext.h Normal file
View File

@ -0,0 +1,57 @@
/** <title>CGBitmapContext</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGBitMapContext_h
#define OPAL_CGBitMapContext_h
#include <CGContext.h>
/* Functions */
CGContextRef CGBitmapContextCreate(
void *data,
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bytesPerRow,
CGColorSpaceRef colorspace,
CGImageAlphaInfo alphaInfo
);
CGImageAlphaInfo CGBitmapContextGetAlphaInfo(CGContextRef ctx);
size_t CGBitmapContextGetBitsPerComponent (CGContextRef ctx);
size_t CGBitmapContextGetBitsPerPixel (CGContextRef ctx);
size_t CGBitmapContextGetBytesPerRow (CGContextRef ctx);
CGColorSpaceRef CGBitmapContextGetColorSpace(CGContextRef ctx);
void *CGBitmapContextGetData(CGContextRef ctx);
size_t CGBitmapContextGetHeight(CGContextRef ctx);
size_t CGBitmapContextGetWidth(CGContextRef ctx);
CGImageRef CGBitmapContextCreateImage(CGContextRef ctx);
#endif /* OPAL_CGBitMapContext_h */

109
CGColor.c Normal file
View File

@ -0,0 +1,109 @@
/** <title>CGColor</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <CGContext.h>
#include "opal.h"
#include "stdlib.h"
typedef struct CGColor
{
struct objbase base;
CGColorSpaceRef cspace;
float *comps;
} CGColor;
CGColorRef CGColorCreate(CGColorSpaceRef colorspace, const float components[])
{
CGColorRef clr;
size_t nc, i;
clr = opal_obj_alloc("CGColor", sizeof(CGColor));
if (!clr) return NULL;
nc = CGColorSpaceGetNumberOfComponents(colorspace);
clr->comps = malloc((nc+1)*sizeof(float));
if (!clr->comps) {
errlog("%s:%d: malloc failed\n", __FILE__, __LINE__);
free(clr);
return NULL;
}
clr->cspace = colorspace;
CGColorSpaceRetain(colorspace);
for (i=0; i<=nc; i++)
clr->comps[i] = components[i];
return clr;
}
void opal_dealloc_CGColor(void *clr)
{
CGColorRef c = clr;
CGColorSpaceRelease(c->cspace);
free(c->comps);
free(c);
}
CGColorRef CGColorRetain(CGColorRef clr)
{
return (clr ? opal_obj_retain(clr) : clr);
}
void CGColorRelease(CGColorRef clr)
{
if(clr) opal_obj_release(clr);
}
CGColorRef CGColorCreateCopy(CGColorRef clr)
{
return CGColorCreate(clr->cspace, clr->comps);
}
CGColorRef CGColorCreateCopyWithAlpha(CGColorRef clr, float alpha)
{
CGColorRef newclr;
newclr = CGColorCreate(clr->cspace, clr->comps);
if (!newclr) return NULL;
newclr->comps[CGColorSpaceGetNumberOfComponents(newclr->cspace)] = alpha;
return newclr;
}
float CGColorGetAlpha(CGColorRef clr)
{
return clr->comps[CGColorSpaceGetNumberOfComponents(clr->cspace)];
}
CGColorSpaceRef CGColorGetColorSpace(CGColorRef clr)
{
return clr->cspace;
}
const float *CGColorGetComponents(CGColorRef clr)
{
return clr->comps;
}
size_t CGColorGetNumberOfComponents(CGColorRef clr)
{
return CGColorSpaceGetNumberOfComponents(clr->cspace);
}

60
CGColor.h Normal file
View File

@ -0,0 +1,60 @@
/** <title>CGColor</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGColor_h
#define OPAL_CGColor_h
#include <CGColorSpace.h>
#include <CGPattern.h>
/* Data Types */
typedef struct CGColor * CGColorRef;
/* Functions */
CGColorRef CGColorCreate(CGColorSpaceRef colorspace, const float components[]);
CGColorRef CGColorCreateCopy(CGColorRef clr);
CGColorRef CGColorCreateCopyWithAlpha(CGColorRef clr, float alpha);
CGColorRef CGColorCreateWithPattern(
CGColorSpaceRef colorspace,
CGPatternRef pattern,
const float components[]
);
float CGColorGetAlpha(CGColorRef clr);
CGColorSpaceRef CGColorGetColorSpace(CGColorRef clr);
const float *CGColorGetComponents(CGColorRef clr);
size_t CGColorGetNumberOfComponents(CGColorRef clr);
CGPatternRef CGColorGetPattern(CGColorRef clr);
void CGColorRelease(CGColorRef clr);
CGColorRef CGColorRetain(CGColorRef clr);
#endif /* OPAL_CGColor_h */

116
CGColorSpace.c Normal file
View File

@ -0,0 +1,116 @@
/** <title>CGColorSpace</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* FIXME: Color Management is not implemented yet. Consequently, color spaces
* are usually ignored and assumed to be deviceRGB. With most current equipment
* supporting the sRGB color space, this may be OK in most cases, though.
*/
#include "CGColorSpace.h"
#include "opal.h"
typedef struct CGColorSpace
{
struct objbase base;
int numcomps;
void (*todevice)(double *dest, const float comps[]);
} CGColorSpace;
static void opal_todev_rgb(double *dest, const float comps[]);
static void opal_todev_gray(double *dest, const float comps[]);
/* Return these for everything now */
static CGColorSpace deviceRGB =
{
{"CGColorSpace", NULL, -1},
3,
opal_todev_rgb
};
static CGColorSpace deviceGray =
{
{"CGColorSpace", NULL, -1},
1,
opal_todev_gray
};
CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void)
{
return &deviceRGB;
}
CGColorSpaceRef CGColorSpaceCreateDeviceGray(void)
{
return &deviceGray;
}
CGColorSpaceRef CGColorSpaceCreateWithName(opal_GenericColorSpaceNames name)
{
switch (name) {
case kCGColorSpaceGenericGray:
return CGColorSpaceCreateDeviceGray();
case kCGColorSpaceGenericRGB:
return CGColorSpaceCreateDeviceRGB();
case kCGColorSpaceGenericCMYK:
default:
errlog("%s:%d: Unknown colorspace name\n", __FILE__, __LINE__);
return NULL;
}
}
CGColorSpaceRef CGColorSpaceRetain(CGColorSpaceRef cs)
{
/* NOP */
return cs;
}
void CGColorSpaceRelease(CGColorSpaceRef cs)
{
/* NOP */
}
size_t CGColorSpaceGetNumberOfComponents(CGColorSpaceRef cs)
{
return cs->numcomps;
}
static void opal_todev_rgb(double *dest, const float comps[])
{
dest[0] = comps[0];
dest[1] = comps[1];
dest[2] = comps[2];
dest[3] = comps[3];
}
static void opal_todev_gray(double *dest, const float comps[])
{
dest[0] = comps[0];
dest[1] = comps[0];
dest[2] = comps[0];
dest[3] = comps[1];
}
/* FIXME: This sould really convert to the color space of the device,
* but Cairo only knows about RGBA, so we convert to that */
void opal_cspace_todev(CGColorSpaceRef cs, double *dest, const float comps[])
{
cs->todevice(dest, comps);
}

101
CGColorSpace.h Normal file
View File

@ -0,0 +1,101 @@
/** <title>CGColorSpace</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGColorSpace_h
#define OPAL_CGColorSpace_h
#include <CGDataProvider.h>
/* Data Types */
typedef struct CGColorSpace * CGColorSpaceRef;
/* Constants */
typedef enum CGColorRenderingIntent {
kCGRenderingIntentDefault = 0,
kCGRenderingIntentAbsoluteColorimetric = 1,
kCGRenderingIntentRelativeColorimetric = 2,
kCGRenderingIntentPerceptual = 3,
kCGRenderingIntentSaturation = 4
} CGColorRenderingIntent;
typedef enum opal_GenericColorSpaceNames {
kCGColorSpaceGenericGray = 0,
kCGColorSpaceGenericRGB = 1,
kCGColorSpaceGenericCMYK = 2
} opal_GenericColorSpaceNames;
/* Functions */
CGColorSpaceRef CGColorSpaceCreateDeviceGray(void);
CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
CGColorSpaceRef CGColorSpaceCreateDeviceCMYK(void);
CGColorSpaceRef CGColorSpaceCreateCalibratedGray(
const float *whitePoint,
const float *blackPoint,
float gamma
);
CGColorSpaceRef CGColorSpaceCreateCalibratedRGB(
const float *whitePoint,
const float *blackPoint,
const float *gamma,
const float *matrix
);
CGColorSpaceRef CGColorSpaceCreateLab(
const float *whitePoint,
const float *blackPoint,
const float *range
);
CGColorSpaceRef CGColorSpaceCreateICCBased(
size_t nComponents,
const float *range,
CGDataProviderRef profile,
CGColorSpaceRef alternateSpace
);
CGColorSpaceRef CGColorSpaceCreateIndexed(
CGColorSpaceRef baseSpace,
size_t lastIndex,
const unsigned char *colorTable
);
CGColorSpaceRef CGColorSpaceCreateWithPlatformColorSpace(
void *platformColorSpace
);
CGColorSpaceRef CGColorSpaceCreateWithName(opal_GenericColorSpaceNames name);
CGColorSpaceRef CGColorSpaceCreatePattern(CGColorSpaceRef baseSpace);
size_t CGColorSpaceGetNumberOfComponents(CGColorSpaceRef cs);
CGColorSpaceRef CGColorSpaceRetain(CGColorSpaceRef cs);
void CGColorSpaceRelease(CGColorSpaceRef cs);
#endif /* OPAL_CGColorSpace_h */

53
CGContext-private.h Normal file
View File

@ -0,0 +1,53 @@
/** <title>CGContext</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGContext_private_h
#define OPAL_CGContext_private_h
#include <CGContext.h>
#include <cairo.h>
#include "opal.h"
typedef struct ct_additions ct_additions;
struct ct_additions
{
ct_additions *next; /* for Save/Restore */
double alpha;
CGColorRef fill_color;
cairo_pattern_t *fill_cp;
CGColorRef stroke_color;
cairo_pattern_t *stroke_cp;
};
typedef struct CGContext
{
struct objbase base;
cairo_t *ct; /* A Cairo context -- destination of this CGContext */
ct_additions *add; /* Additional things not in Cairo's gstate */
struct {
double x;
double y;
} txtpos;
} CGContext;
CGContextRef opal_new_CGContext(cairo_surface_t *target);
#endif

838
CGContext.c Normal file
View File

@ -0,0 +1,838 @@
/** <title>CGContext</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGContext-private.h"
#include <stdlib.h>
#include <math.h>
#include <cairo.h>
#include "opal.h"
/* The default (opaque black) color in a Cairo context,
* used if no other color is set on the context yet */
static cairo_pattern_t *default_cp;
extern void opal_surface_flush(cairo_surface_t *target);
extern void opal_cspace_todev(CGColorSpaceRef cs, double *dest, const float comps[]);
extern CGFontRef opal_FontCreateWithName(const char *name);
void opal_dealloc_CGContext(void *c)
{
CGContextRef ctx = c;
ct_additions *ctadd, *next;
ctadd = ctx->add;
while (ctadd) {
CGColorRelease(ctadd->fill_color);
cairo_pattern_destroy(ctadd->fill_cp);
CGColorRelease(ctadd->stroke_color);
cairo_pattern_destroy(ctadd->stroke_cp);
next = ctadd->next;
free(ctadd);
ctadd = next;
}
cairo_destroy(ctx->ct);
free(ctx);
}
CGContextRef opal_new_CGContext(cairo_surface_t *target)
{
CGContextRef ctx;
cairo_status_t cret;
ctx = opal_obj_alloc("CGContext", sizeof(CGContext));
if (!ctx) return NULL;
ctx->add = NULL;
ctx->ct = cairo_create(target);
cret = cairo_status(ctx->ct);
if (cret) {
errlog("%s:%d: cairo_create status: %s\n",
__FILE__, __LINE__, cairo_status_to_string(cret));
opal_dealloc_CGContext(ctx);
return NULL;
}
ctx->add = calloc(1, sizeof(struct ct_additions));
if (!ctx->add) {
errlog("%s:%d: calloc failed\n", __FILE__, __LINE__);
opal_dealloc_CGContext(ctx);
return NULL;
}
ctx->add->alpha = 1;
if (!default_cp) {
default_cp = cairo_get_source(ctx->ct);
cairo_pattern_reference(default_cp);
}
/* Cairo defaults to line width 2.0 (see http://cairographics.org/FAQ) */
cairo_set_line_width(ctx->ct, 1);
return ctx;
}
CGContextRef CGContextRetain(CGContextRef ctx)
{
return (ctx ? opal_obj_retain(ctx) : NULL);
}
void CGContextRelease(CGContextRef ctx)
{
if(ctx) opal_obj_release(ctx);
}
void CGContextFlush(CGContextRef ctx)
{
cairo_surface_t *target;
target = cairo_get_target(ctx->ct);
/* FIXME: This doesn't work for most Cairo backends (including Xlib) */
/* cairo_surface_flush(target); */
/* So now we have to do it directly instead */
opal_surface_flush(target);
}
void CGContextSynchronize(CGContextRef ctx)
{
/* FIXME: Could do cairo_surface_mark_dirty here, but that does nothing */
/* NOP */
}
void CGContextBeginPage(CGContextRef ctx, const CGRect *mediaBox)
{
/* FIXME: should we reset gstate?, mediaBox is ignored */
cairo_copy_page(ctx->ct);
}
void CGContextEndPage(CGContextRef ctx)
{
cairo_show_page(ctx->ct);
}
void CGContextScaleCTM(CGContextRef ctx, float sx, float sy)
{
cairo_scale(ctx->ct, sx, sy);
}
void CGContextTranslateCTM(CGContextRef ctx, float tx, float ty)
{
cairo_translate(ctx->ct, tx, ty);
}
void CGContextRotateCTM(CGContextRef ctx, float angle)
{
cairo_rotate(ctx->ct, angle);
}
void CGContextConcatCTM(CGContextRef ctx, CGAffineTransform transform)
{
cairo_matrix_t cmat;
cmat.xx = transform.a;
cmat.xy = transform.b;
cmat.yx = transform.c;
cmat.yy = transform.d;
cmat.x0 = transform.tx;
cmat.y0 = transform.ty;
cairo_transform(ctx->ct, &cmat);
}
CGAffineTransform CGContextGetCTM(CGContextRef ctx)
{
cairo_matrix_t cmat;
cairo_get_matrix(ctx->ct, &cmat);
return CGAffineTransformMake(cmat.xx, -cmat.yx, cmat.xy, -cmat.yy, cmat.x0, -cmat.y0);
/* return CGAffineTransformMake(cmat.xx, cmat.xy, cmat.yx, cmat.yy, cmat.x0, cmat.y0); */
}
void CGContextSaveGState(CGContextRef ctx)
{
ct_additions *ctadd;
cairo_status_t cret;
ctadd = calloc(1, sizeof(struct ct_additions));
if (!ctadd) {
errlog("%s:%d: calloc failed\n", __FILE__, __LINE__);
return;
}
cairo_save(ctx->ct);
cret = cairo_status(ctx->ct);
if (cret) {
errlog("%s:%d: cairo_save status: %s\n",
__FILE__, __LINE__, cairo_status_to_string(cret));
free(ctadd);
return;
}
*ctadd = *ctx->add;
CGColorRetain(ctadd->fill_color);
cairo_pattern_reference(ctadd->fill_cp);
CGColorRetain(ctadd->stroke_color);
cairo_pattern_reference(ctadd->stroke_cp);
ctadd->next = ctx->add;
ctx->add = ctadd;
}
void CGContextRestoreGState(CGContextRef ctx)
{
ct_additions *ctadd;
if (!ctx->add) return;
CGColorRelease(ctx->add->fill_color);
cairo_pattern_destroy(ctx->add->fill_cp);
CGColorRelease(ctx->add->stroke_color);
cairo_pattern_destroy(ctx->add->stroke_cp);
ctadd = ctx->add->next;
free(ctx->add);
ctx->add = ctadd;
cairo_restore(ctx->ct);
}
void CGContextSetShouldAntialias(CGContextRef ctx, int shouldAntialias)
{
cairo_set_antialias(ctx->ct,
(shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE));
}
void CGContextSetLineWidth(CGContextRef ctx, float width)
{
cairo_set_line_width(ctx->ct, width);
}
void CGContextSetLineJoin(CGContextRef ctx, CGLineJoin join)
{
cairo_set_line_join(ctx->ct, join);
}
void CGContextSetMiterLimit(CGContextRef ctx, float limit)
{
cairo_set_miter_limit(ctx->ct, limit);
}
void CGContextSetLineCap(CGContextRef ctx, CGLineCap cap)
{
cairo_set_line_cap(ctx->ct, cap);
}
void CGContextSetLineDash(
CGContextRef ctx,
float phase,
const float lengths[],
size_t count)
{
double dashes[count]; /* C99 allows this */
size_t i;
for (i=0; i<count; i++)
dashes[i] = lengths[i];
cairo_set_dash(ctx->ct, dashes, count, phase);
}
void CGContextSetFlatness(CGContextRef ctx, float flatness)
{
cairo_set_tolerance(ctx->ct, flatness);
}
void CGContextSetShadow(
CGContextRef ctx,
CGSize offset,
CGFloat radius)
{
// FIXME: Implement
}
void CGContextSetShadowWithColor(
CGContextRef ctx,
CGSize offset,
CGFloat radius,
CGColorRef color)
{
// FIXME: Implement
}
void CGContextBeginPath(CGContextRef ctx)
{
cairo_new_path(ctx->ct);
}
void CGContextClosePath(CGContextRef ctx)
{
cairo_close_path(ctx->ct);
}
void CGContextMoveToPoint(CGContextRef ctx, float x, float y)
{
cairo_move_to(ctx->ct, x, y);
}
void CGContextAddLineToPoint(CGContextRef ctx, float x, float y)
{
cairo_line_to(ctx->ct, x, y);
}
void CGContextAddLines(CGContextRef ctx, const CGPoint points[], size_t count)
{
size_t i;
if (count <= 0) return;
CGContextMoveToPoint(ctx, points[0].x, points[0].y);
for (i=1; i<count; i++)
CGContextAddLineToPoint(ctx, points[i].x, points[i].y);
}
void CGContextAddCurveToPoint(
CGContextRef ctx,
float cp1x,
float cp1y,
float cp2x,
float cp2y,
float x,
float y)
{
cairo_curve_to(ctx->ct, cp1x, cp1y, cp2x, cp2y, x, y);
}
void CGContextAddRect(CGContextRef ctx, CGRect rect)
{
cairo_rectangle(ctx->ct, rect.origin.x, rect.origin.y,
rect.size.width, rect.size.height);
}
void CGContextAddRects(CGContextRef ctx, const CGRect rects[], size_t count)
{
size_t i;
for (i=0; i<count; i++)
CGContextAddRect(ctx, rects[i]);
}
void CGContextAddArc(
CGContextRef ctx,
float x,
float y,
float radius,
float startAngle,
float endAngle,
int clockwise)
{
if (clockwise)
cairo_arc_negative(ctx->ct, x, y, radius, startAngle, endAngle);
else
cairo_arc(ctx->ct, x, y, radius, startAngle, endAngle);
}
void CGContextAddArcToPoint(
CGContextRef ctx,
float x1,
float y1,
float x2,
float y2,
float radius)
{
double x0, y0;
double dx0, dy0, dx2, dy2, xl0, xl2;
double san, n0x, n0y, n2x, n2y, t;
cairo_get_current_point(ctx->ct, &x0, &y0);
dx0 = x0 - x1;
dy0 = y0 - y1;
xl0 = sqrt(dx0*dx0 + dy0*dy0);
if (xl0 == 0) return;
dx2 = x2 - x1;
dy2 = y2 - y1;
xl2 = sqrt(dx2*dx2 + dy2*dy2);
san = dx2*dy0 - dx0*dy2;
if (san == 0) {
CGContextAddLineToPoint(ctx, x1, y1);
return;
}
if (san < 0) {
n0x = -dy0 / xl0;
n0y = dx0 / xl0;
n2x = dy2 / xl2;
n2y = -dx2 / xl2;
} else {
n0x = dy0 / xl0;
n0y = -dx0 / xl0;
n2x = -dy2 / xl2;
n2y = dx2 / xl2;
}
t = (dx2*n2y - dx2*n0y - dy2*n2x + dy2*n0x) / san;
CGContextAddArc(ctx,
x1 + radius * (t * dx0 + n0x), y1 + radius * (t * dy0 + n0y),
radius, atan2(-n0y, -n0x), atan2(-n2y, -n2x), (san < 0));
}
void CGContextStrokePath(CGContextRef ctx)
{
cairo_status_t cret;
if(ctx->add->stroke_cp)
cairo_set_source(ctx->ct, ctx->add->stroke_cp);
else
cairo_set_source(ctx->ct, default_cp);
cairo_stroke(ctx->ct);
cret = cairo_status(ctx->ct);
if (cret)
errlog("%s:%d: cairo_stroke status: %s\n",
__FILE__, __LINE__, cairo_status_to_string(cret));
}
static void fill_path(CGContextRef ctx, int eorule, int preserve)
{
cairo_status_t cret;
if(ctx->add->fill_cp)
cairo_set_source(ctx->ct, ctx->add->fill_cp);
else
cairo_set_source(ctx->ct, default_cp);
if (eorule) cairo_set_fill_rule(ctx->ct, CAIRO_FILL_RULE_EVEN_ODD);
cairo_fill_preserve(ctx->ct);
if (eorule) cairo_set_fill_rule(ctx->ct, CAIRO_FILL_RULE_WINDING);
if (!preserve) cairo_new_path(ctx->ct);
cret = cairo_status(ctx->ct);
if (cret)
errlog("%s:%d: cairo_fill status: %s\n",
__FILE__, __LINE__, cairo_status_to_string(cret));
}
void CGContextFillPath(CGContextRef ctx)
{
fill_path(ctx, 0, 0);
}
void CGContextEOFillPath(CGContextRef ctx)
{
fill_path(ctx, 1, 0);
}
void CGContextDrawPath(CGContextRef ctx, CGPathDrawingMode mode)
{
switch (mode) {
case kCGPathFill:
case kCGPathEOFill:
fill_path(ctx, (mode == kCGPathEOFill), 0);
break;
case kCGPathFillStroke:
case kCGPathEOFillStroke:
fill_path(ctx, (mode == kCGPathEOFillStroke), 1);
/* fall through */
case kCGPathStroke:
CGContextStrokePath(ctx);
break;
default:
errlog("%s:%d: CGContextDrawPath invalid CGPathDrawingMode: %d\n",
__FILE__, __LINE__, mode);
}
}
void CGContextStrokeRect(CGContextRef ctx, CGRect rect)
{
CGContextBeginPath(ctx);
CGContextAddRect(ctx, rect);
CGContextStrokePath(ctx);
}
void CGContextStrokeRectWithWidth(CGContextRef ctx, CGRect rect, float width)
{
CGContextSetLineWidth(ctx, width);
CGContextStrokeRect(ctx, rect);
/* Line width is not restored (see Technical QA1045) */
}
void CGContextFillRect(CGContextRef ctx, CGRect rect)
{
CGContextBeginPath(ctx);
CGContextAddRect(ctx, rect);
CGContextFillPath(ctx);
}
void CGContextFillRects(CGContextRef ctx, const CGRect rects[], size_t count)
{
CGContextBeginPath(ctx);
CGContextAddRects(ctx, rects, count);
CGContextFillPath(ctx);
}
void CGContextStrokeLineSegments(
CGContextRef ctx,
const CGPoint points[],
size_t count)
{
size_t i;
CGContextBeginPath(ctx);
for (i=1; i<count; i+=2) {
CGContextMoveToPoint(ctx, points[i-1].x, points[i-1].y);
CGContextAddLineToPoint(ctx, points[i].x, points[i].y);
}
CGContextStrokePath(ctx);
}
CGPoint CGContextGetPathCurrentPoint(CGContextRef ctx)
{
double x, y;
cairo_get_current_point(ctx->ct, &x, &y);
return CGPointMake(x, y);
}
void CGContextClip(CGContextRef ctx)
{
cairo_clip(ctx->ct);
}
void CGContextEOClip(CGContextRef ctx)
{
cairo_set_fill_rule(ctx->ct, CAIRO_FILL_RULE_EVEN_ODD);
CGContextClip(ctx);
cairo_set_fill_rule(ctx->ct, CAIRO_FILL_RULE_WINDING);
}
void CGContextClipToRect(CGContextRef ctx, CGRect rect)
{
CGContextBeginPath(ctx);
CGContextAddRect(ctx, rect);
CGContextClip(ctx);
}
void CGContextClipToRects(CGContextRef ctx, const CGRect rects[], size_t count)
{
CGContextBeginPath(ctx);
CGContextAddRects(ctx, rects, count);
CGContextClip(ctx);
}
static inline void set_color(cairo_pattern_t **cp, CGColorRef clr, double alpha)
{
double cc[4];
cairo_pattern_t *newcp;
cairo_status_t cret;
opal_cspace_todev(CGColorGetColorSpace(clr), cc, CGColorGetComponents(clr));
newcp = cairo_pattern_create_rgba(cc[0], cc[1], cc[2], cc[3]*alpha);
cret = cairo_pattern_status(newcp);
if (cret) {
errlog("%s:%d: cairo_pattern_create_rgba status: %s\n",
__FILE__, __LINE__, cairo_status_to_string(cret));
return;
}
cairo_pattern_destroy(*cp);
*cp = newcp;
}
void CGContextSetFillColorWithColor(CGContextRef ctx, CGColorRef color)
{
CGColorRelease(ctx->add->fill_color);
ctx->add->fill_color = color;
CGColorRetain(color);
set_color(&ctx->add->fill_cp, color, ctx->add->alpha);
}
void CGContextSetStrokeColorWithColor(CGContextRef ctx, CGColorRef color)
{
CGColorRelease(ctx->add->stroke_color);
ctx->add->stroke_color = color;
CGColorRetain(color);
set_color(&ctx->add->stroke_cp, color, ctx->add->alpha);
}
void CGContextSetAlpha(CGContextRef ctx, float alpha)
{
if (alpha < 0)
alpha = 0;
else if (alpha > 1)
alpha = 1;
ctx->add->alpha = alpha;
// FIXME: Should we really check that these are non-null?
if (ctx->add->stroke_color)
set_color(&ctx->add->stroke_cp, ctx->add->stroke_color, ctx->add->alpha);
if (ctx->add->fill_color)
set_color(&ctx->add->fill_cp, ctx->add->fill_color, ctx->add->alpha);
}
void CGContextSetFillColorSpace(CGContextRef ctx, CGColorSpaceRef colorspace)
{
float *components;
CGColorRef color;
size_t nc;
nc = CGColorSpaceGetNumberOfComponents(colorspace);
components = calloc(nc+1, sizeof(float));
if (components) {
errlog("%s:%d: calloc failed\n", __FILE__, __LINE__);
return;
}
/* Default is an opaque, zero intensity color (usually black) */
components[nc] = 1;
color = CGColorCreate(colorspace, components);
free(components);
CGContextSetFillColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetStrokeColorSpace(CGContextRef ctx, CGColorSpaceRef colorspace)
{
float *components;
CGColorRef color;
size_t nc;
nc = CGColorSpaceGetNumberOfComponents(colorspace);
components = calloc(nc+1, sizeof(float));
if (components) {
errlog("%s:%d: calloc failed\n", __FILE__, __LINE__);
return;
}
/* Default is an opaque, zero intensity color (usually black) */
components[nc] = 1;
color = CGColorCreate(colorspace, components);
free(components);
CGContextSetStrokeColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetFillColor(CGContextRef ctx, const float components[])
{
CGColorSpaceRef cs;
CGColorRef color;
cs = CGColorGetColorSpace(ctx->add->fill_color);
color = CGColorCreate(cs, components);
CGContextSetFillColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetStrokeColor(CGContextRef ctx, const float components[])
{
CGColorSpaceRef cs;
CGColorRef color;
cs = CGColorGetColorSpace(ctx->add->stroke_color);
color = CGColorCreate(cs, components);
CGContextSetStrokeColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetGrayFillColor(CGContextRef ctx, float gray, float alpha)
{
float comps[2];
CGColorSpaceRef cs;
CGColorRef color;
comps[0] = gray;
comps[1] = alpha;
cs = CGColorSpaceCreateDeviceGray();
color = CGColorCreate(cs, comps);
CGColorSpaceRelease(cs);
CGContextSetFillColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetGrayStrokeColor(CGContextRef ctx, float gray, float alpha)
{
float comps[2];
CGColorSpaceRef cs;
CGColorRef color;
comps[0] = gray;
comps[1] = alpha;
cs = CGColorSpaceCreateDeviceGray();
color = CGColorCreate(cs, comps);
CGColorSpaceRelease(cs);
CGContextSetStrokeColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetRGBFillColor(CGContextRef ctx,
float r, float g, float b, float alpha)
{
float comps[4];
CGColorSpaceRef cs;
CGColorRef color;
comps[0] = r;
comps[1] = g;
comps[2] = b;
comps[3] = alpha;
cs = CGColorSpaceCreateDeviceRGB();
color = CGColorCreate(cs, comps);
CGColorSpaceRelease(cs);
CGContextSetFillColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetRGBStrokeColor(CGContextRef ctx,
float r, float g, float b, float alpha)
{
float comps[4];
CGColorSpaceRef cs;
CGColorRef color;
comps[0] = r;
comps[1] = g;
comps[2] = b;
comps[3] = alpha;
cs = CGColorSpaceCreateDeviceRGB();
color = CGColorCreate(CGColorSpaceCreateDeviceRGB(), comps);
CGColorSpaceRelease(cs);
CGContextSetStrokeColorWithColor(ctx, color);
CGColorRelease(color);
}
void CGContextSetFont(CGContextRef ctx, CGFontRef font)
{
if (!font) {
errlog("%s:%d: CGContextSetFont got NULL\n", __FILE__, __LINE__);
return;
}
cairo_set_font_face(ctx->ct, (cairo_font_face_t *)font);
}
void CGContextSetFontSize(CGContextRef ctx, float size)
{
cairo_matrix_t fm;
/* The 10 * 96/72 factor is a heuristic. 1/96 is the cairo default unit,
* 1/72 is the default in Postscript and PDF but why is *10 needed?
* Nevertheless, it seems to produce about the right results. */
cairo_matrix_init_scale(&fm, size * 10 * 96.0/72.0, -size * 10 * 96.0/72.0);
cairo_set_font_matrix(ctx->ct, &fm);
}
void CGContextSelectFont(
CGContextRef ctx,
const char *name,
float size,
CGTextEncoding textEncoding)
{
/* FIXME: textEncoding is ignored */
CGContextSetFont(ctx, opal_FontCreateWithName(name));
CGContextSetFontSize(ctx, size);
}
void CGContextSetTextPosition(CGContextRef ctx, float x, float y)
{
ctx->txtpos.x = x;
ctx->txtpos.y = y;
}
CGPoint CGContextGetTextPosition(CGContextRef ctx)
{
return CGPointMake(ctx->txtpos.x, ctx->txtpos.y);
}
void CGContextShowText(CGContextRef ctx, const char *cstring, size_t length)
{
double x, y;
cairo_get_current_point(ctx->ct, &x, &y);
cairo_move_to(ctx->ct, ctx->txtpos.x, ctx->txtpos.y);
/* FIXME: All text is currently drawn with fill color.
* Should support other text drawing modes. */
if(ctx->add->fill_cp)
cairo_set_source(ctx->ct, ctx->add->fill_cp);
else
cairo_set_source(ctx->ct, default_cp);
/* FIXME: length is ignored, \0 terminated string is assumed */
cairo_show_text(ctx->ct, cstring);
cairo_get_current_point(ctx->ct, &ctx->txtpos.x, &ctx->txtpos.y);
cairo_move_to(ctx->ct, x, y);
}
void CGContextShowTextAtPoint(
CGContextRef ctx,
float x,
float y,
const char *cstring,
size_t length)
{
CGContextSetTextPosition(ctx, x, y);
CGContextShowText(ctx, cstring, length);
}
void CGContextBeginTransparencyLayer(
CGContextRef ctx,
CFDictionaryRef auxiliaryInfo)
{
// Save cairo state, to match CGContextBeginTransparencyLayerWithRect
cairo_save(ctx->ct);
// Save Opal state, and set alpha to 1 and shadows off (within the
// transparency layer)
CGContextSaveGState(ctx);
CGContextSetAlpha(ctx, 1.0);
CGContextSetShadowWithColor(ctx, CGSizeMake(0,0), 0, NULL);
cairo_push_group(ctx->ct);
}
void CGContextBeginTransparencyLayerWithRect(
CGContextRef ctx,
CGRect rect,
CFDictionaryRef auxiliaryInfo)
{
// Save cairo state because we are goint to clip to the given rect
cairo_save(ctx->ct);
cairo_new_path(ctx->ct);
CGContextAddRect(ctx, rect);
cairo_clip(ctx->ct);
// Save Opal state, and set alpha to 1 and shadows off (within the
// transparency layer)
CGContextSaveGState(ctx);
CGContextSetAlpha(ctx, 1.0);
CGContextSetShadowWithColor(ctx, CGSizeMake(0,0), 0, NULL);
cairo_push_group(ctx->ct);
}
void CGContextEndTransparencyLayer(CGContextRef ctx)
{
cairo_pop_group_to_source(ctx->ct);
// Paint the contents of the transparency layer. Note that we look at the
// Opal state beneath the current one for the alpha value because
// we want the alpha value before CGContextSaveGState was called
// in CGContextBeginTransparencyLayer
cairo_paint_with_alpha(ctx->ct, ctx->add->next->alpha);
// Now undo the change to alpha and shadow state
CGContextRestoreGState(ctx);
// Undo the clipping (if any)
cairo_restore(ctx->ct);
}

428
CGContext.h Normal file
View File

@ -0,0 +1,428 @@
/** <title>CGContext</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGContext_h
#define OPAL_CGContext_h
/* Data Types */
typedef struct CGContext * CGContextRef;
#include <CGAffineTransform.h>
#include <CGColor.h>
#include <CGFont.h>
#include <CGImage.h>
#include <CGPath.h>
#include <CGBase.h>
#include <CoreFoundation.h>
/* Constants */
typedef enum CGBlendMode {
kCGBlendModeNormal = 0,
kCGBlendModeMultiply = 1,
kCGBlendModeScreen = 2,
kCGBlendModeOverlay = 3,
kCGBlendModeDarken = 4,
kCGBlendModeLighten = 5,
kCGBlendModeColorDodge = 6,
kCGBlendModeColorBurn = 7,
kCGBlendModeSoftLight = 8,
kCGBlendModeHardLight = 9,
kCGBlendModeDifference = 10,
kCGBlendModeExclusion = 11,
kCGBlendModeHue = 12,
kCGBlendModeSaturation = 13,
kCGBlendModeColor = 14,
kCGBlendModeLuminosity = 15
} CGBlendMode;
typedef enum CGInterpolationQuality {
kCGInterpolationDefault = 0,
kCGInterpolationNone = 1,
kCGInterpolationLow = 2,
kCGInterpolationHigh = 3
} CGInterpolationQuality;
typedef enum CGLineCap {
kCGLineCapButt = 0,
kCGLineCapRound = 1,
kCGLineCapSquare = 2
} CGLineCap;
typedef enum CGLineJoin {
kCGLineJoinMiter = 0,
kCGLineJoinRound = 1,
kCGLineJoinBevel = 2
} CGLineJoin;
typedef enum CGTextDrawingMode {
kCGTextFill = 0,
kCGTextStroke = 1,
kCGTextFillStroke = 2,
kCGTextInvisible = 3,
kCGTextFillClip = 4,
kCGTextStrokeClip = 5,
kCGTextFillStrokeClip = 6,
kCGTextClip = 7
} CGTextDrawingMode;
typedef enum CGTextEncoding {
kCGEncodingFontSpecific = 0,
kCGEncodingMacRoman = 1
} CGTextEncoding;
/* Functions */
/* Managing Graphics Contexts */
CGContextRef CGContextRetain(CGContextRef ctx);
void CGContextRelease(CGContextRef ctx);
void CGContextFlush(CGContextRef ctx);
void CGContextSynchronize(CGContextRef ctx);
/* Defining Pages */
void CGContextBeginPage(CGContextRef ctx, const CGRect *mediaBox);
void CGContextEndPage(CGContextRef ctx);
/* Transforming the Coordinate Space of the Page */
void CGContextScaleCTM(CGContextRef ctx, float sx, float sy);
void CGContextTranslateCTM(CGContextRef ctx, float tx, float ty);
void CGContextRotateCTM(CGContextRef ctx, float angle);
void CGContextConcatCTM(CGContextRef ctx, CGAffineTransform transform);
CGAffineTransform CGContextGetCTM(CGContextRef ctx);
/* Saving and Restoring the Graphics State */
void CGContextSaveGState(CGContextRef ctx);
void CGContextRestoreGState(CGContextRef ctx);
/* Setting Graphics State Attributes */
void CGContextSetShouldAntialias(CGContextRef ctx, int shouldAntialias);
void CGContextSetLineWidth(CGContextRef ctx, float width);
void CGContextSetLineJoin(CGContextRef ctx, CGLineJoin join);
void CGContextSetMiterLimit(CGContextRef ctx, float limit);
void CGContextSetLineCap(CGContextRef ctx, CGLineCap cap);
void CGContextSetLineDash(
CGContextRef ctx,
float phase,
const float lengths[],
size_t count
);
void CGContextSetFlatness(CGContextRef ctx, float flatness);
CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef ctx);
void CGContextSetInterpolationQuality(
CGContextRef ctx,
CGInterpolationQuality quality
);
void CGContextSetPatternPhase (CGContextRef ctx, CGSize phase);
void CGContextSetFillPattern(
CGContextRef ctx,
CGPatternRef pattern,
const float components[]
);
void CGContextSetStrokePattern(
CGContextRef ctx,
CGPatternRef pattern,
const float components[]
);
void CGContextSetShouldSmoothFonts(CGContextRef ctx, int shouldSmoothFonts);
void CGContextSetBlendMode(CGContextRef ctx, CGBlendMode mode);
void CGContextSetAllowsAntialiasing(CGContextRef ctx, int allowsAntialiasing);
void CGContextSetShadow(
CGContextRef ctx,
CGSize offset,
CGFloat radius
);
void CGContextSetShadowWithColor(
CGContextRef ctx,
CGSize offset,
CGFloat radius,
CGColorRef color
);
/* Constructing Paths */
void CGContextBeginPath(CGContextRef ctx);
void CGContextClosePath(CGContextRef ctx);
void CGContextMoveToPoint(CGContextRef ctx, float x, float y);
void CGContextAddLineToPoint(CGContextRef ctx, float x, float y);
void CGContextAddLines(CGContextRef ctx, const CGPoint points[], size_t count);
void CGContextAddCurveToPoint(
CGContextRef ctx,
float cp1x,
float cp1y,
float cp2x,
float cp2y,
float x,
float y
);
void CGContextAddQuadCurveToPoint(
CGContextRef ctx,
float cpx,
float cpy,
float x,
float y
);
void CGContextAddRect(CGContextRef ctx, CGRect rect);
void CGContextAddRects(CGContextRef ctx, const CGRect rects[], size_t count);
void CGContextAddArc(
CGContextRef ctx,
float x,
float y,
float radius,
float startAngle,
float endAngle,
int clockwise
);
void CGContextAddArcToPoint(
CGContextRef ctx,
float x1,
float y1,
float x2,
float y2,
float radius
);
void CGContextAddPath(CGContextRef ctx, CGPathRef path);
void CGContextAddEllipseInRect(CGContextRef ctx, CGRect rect);
/* Painting Paths */
void CGContextStrokePath(CGContextRef ctx);
void CGContextFillPath(CGContextRef ctx);
void CGContextEOFillPath(CGContextRef ctx);
void CGContextDrawPath(CGContextRef ctx, CGPathDrawingMode mode);
void CGContextStrokeRect(CGContextRef ctx, CGRect rect);
void CGContextStrokeRectWithWidth(CGContextRef ctx, CGRect rect, float width);
void CGContextFillRect(CGContextRef ctx, CGRect rect);
void CGContextFillRects(CGContextRef ctx, const CGRect rects[], size_t count);
void CGContextClearRect(CGContextRef c, CGRect rect);
void CGContextFillEllipseInRect(CGContextRef ctx, CGRect rect);
void CGContextStrokeEllipseInRect(CGContextRef ctx, CGRect rect);
void CGContextStrokeLineSegments(
CGContextRef ctx,
const CGPoint points[],
size_t count
);
/* Obtaining Path Information */
int CGContextIsPathEmpty(CGContextRef ctx);
CGPoint CGContextGetPathCurrentPoint(CGContextRef ctx);
CGRect CGContextGetPathBoundingBox(CGContextRef ctx);
/* Clipping Paths */
void CGContextClip(CGContextRef ctx);
void CGContextEOClip(CGContextRef ctx);
void CGContextClipToRect(CGContextRef ctx, CGRect rect);
void CGContextClipToRects(CGContextRef ctx, const CGRect rects[], size_t count);
/* Setting the Color Space and Colors */
void CGContextSetFillColorWithColor(CGContextRef ctx, CGColorRef color);
void CGContextSetStrokeColorWithColor(CGContextRef ctx, CGColorRef color);
void CGContextSetAlpha(CGContextRef ctx, float alpha);
void CGContextSetFillColorSpace(CGContextRef ctx, CGColorSpaceRef colorspace);
void CGContextSetStrokeColorSpace(CGContextRef ctx, CGColorSpaceRef colorspace);
void CGContextSetFillColor(CGContextRef ctx, const float components[]);
void CGContextSetStrokeColor(CGContextRef ctx, const float components[]);
void CGContextSetGrayFillColor(CGContextRef ctx, float gray, float alpha);
void CGContextSetGrayStrokeColor(CGContextRef ctx, float gray, float alpha);
void CGContextSetRGBFillColor(
CGContextRef ctx,
float r,
float g,
float b,
float alpha
);
void CGContextSetRGBStrokeColor(
CGContextRef ctx,
float r,
float g,
float b,
float alpha
);
void CGContextSetCMYKFillColor(
CGContextRef ctx,
float c,
float m,
float y,
float k,
float alpha
);
void CGContextSetCMYKStrokeColor(
CGContextRef ctx,
float c,
float m,
float y,
float k,
float alpha
);
void CGContextSetRenderingIntent(CGContextRef ctx, CGColorRenderingIntent intent);
/* Drawing Images */
void CGContextDrawImage(CGContextRef ctx, CGRect rect, CGImageRef image);
/* Drawing PDF Documents */
#if 0
void CGContextDrawPDFDocument(
CGContextRef ctx,
CGRect rect,
CGPDFDocumentRef document,
int page
);
void CGContextDrawPDFPage(CGContextRef ctx, CGPDFPageRef page);
#endif
/* Drawing Text */
void CGContextSetFont(CGContextRef ctx, CGFontRef font);
void CGContextSetFontSize(CGContextRef ctx, float size);
void CGContextSelectFont(
CGContextRef ctx,
const char *name,
float size,
CGTextEncoding textEncoding
);
void CGContextSetCharacterSpacing(CGContextRef ctx, float spacing);
void CGContextSetTextDrawingMode(CGContextRef ctx, CGTextDrawingMode mode);
void CGContextSetTextPosition(CGContextRef ctx, float x, float y);
CGPoint CGContextGetTextPosition(CGContextRef ctx);
void CGContextSetTextMatrix(CGContextRef ctx, CGAffineTransform transform);
CGAffineTransform CGContextGetTextMatrix(CGContextRef ctx);
void CGContextShowText(CGContextRef ctx, const char *cstring, size_t length);
void CGContextShowTextAtPoint(
CGContextRef ctx,
float x,
float y,
const char *cstring,
size_t length
);
void CGContextShowGlyphs(CGContextRef ctx, const CGGlyph *g, size_t count);
void CGContextShowGlyphsAtPoint(
CGContextRef ctx,
float x,
float y,
const CGGlyph *g,
size_t count
);
/* Transparency Layers */
void CGContextBeginTransparencyLayer(
CGContextRef ctx,
CFDictionaryRef auxiliaryInfo
);
void CGContextBeginTransparencyLayerWithRect(
CGContextRef ctx,
CGRect rect,
CFDictionaryRef auxiliaryInfo
);
void CGContextEndTransparencyLayer(CGContextRef ctx);
#endif /* OPAL_CGContext_h */

62
CGDataConsumer.h Normal file
View File

@ -0,0 +1,62 @@
/** <title>CGDataConsumer</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGDataConsumer_h
#define OPAL_CGDataConsumer_h
#include <unistd.h>
/* Data Types */
typedef void * CGDataConsumerRef;
/* Callbacks */
typedef size_t (*CGDataConsumerPutBytesCallback)(
void *info,
const void *buffer,
size_t count
);
typedef void (*CGDataConsumerReleaseInfoCallback)(void *info);
typedef struct CGDataConsumerCallbacks
{
CGDataConsumerPutBytesCallback putBytes;
CGDataConsumerReleaseInfoCallback releaseConsumer;
} CGDataConsumerCallbacks;
/* Functions */
CGDataConsumerRef CGDataConsumerCreate(
void *info,
const CGDataConsumerCallbacks *callbacks
);
/* CGDataConsumerRef CGDataConsumerCreateWithCFData(CFMutableDataRef data); */
/* CGDataConsumerRef CGDataConsumerCreateWithURL(CFURLRef url); */
void CGDataConsumerRelease(CGDataConsumerRef consumer);
CGDataConsumerRef CGDataConsumerRetain(CGDataConsumerRef consumer);
#endif /* OPAL_CGDataConsumer_h */

45
CGDataProvider-private.h Normal file
View File

@ -0,0 +1,45 @@
/** <title>CGDataProvider</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGDataProvider.h"
#include "opal.h"
typedef struct CGDataProvider
{
struct objbase base;
CGDataProviderCallbacks cb;
void *info;
} CGDataProvider;
static inline size_t opal_DataProviderRead(CGDataProviderRef dp, void *buffer, size_t count)
{
return dp->cb.getBytes(dp->info, buffer, count);
}
static inline void opal_DataProviderSkip(CGDataProviderRef dp, size_t count)
{
return dp->cb.skipBytes(dp->info, count);
}
static inline void opal_DataProviderRewind(CGDataProviderRef dp)
{
return dp->cb.rewind(dp->info);
}

177
CGDataProvider.c Normal file
View File

@ -0,0 +1,177 @@
/** <title>CGDataProvider</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGDataProvider-private.h"
#include <stdlib.h>
#include <string.h>
typedef struct DirectInfo {
size_t offset;
CGDataProviderDirectAccessCallbacks cb;
void *info;
size_t size;
const void *data;
void (*releaseData)(void *info, const void *data, size_t size);
} DirectInfo;
static size_t opal_DirectGetBytes(void *info, void *buffer, size_t count)
{
DirectInfo *i = info;
if (i->data) {
if (i->offset + count > i->size) count = i->size - i->offset;
if (count) memcpy(buffer, i->data + i->offset, count);
} else {
count = i->cb.getBytes(i->info, buffer, i->offset, count);
}
i->offset += count;
return count;
}
static void opal_DirectSkipBytes(void *info, size_t count)
{
((DirectInfo *)info)->offset += count;
}
static void opal_DirectRewind(void *info)
{
((DirectInfo *)info)->offset = 0;
}
static void opal_DirectReleaseInfo(void *info)
{
DirectInfo *i = info;
if (i->releaseData) i->releaseData(i->info, i->data, i->size);
if (i->cb.releaseProvider) i->cb.releaseProvider(i->info);
free(i);
}
static CGDataProviderCallbacks opal_DirectCallbacks = {
opal_DirectGetBytes,
opal_DirectSkipBytes,
opal_DirectRewind,
opal_DirectReleaseInfo
};
static void opal_DirectReleaseData(void *info, const void *data, size_t size)
{
DirectInfo *i = info;
if (i->cb.releaseBytePointer) i->cb.releaseBytePointer(i->info, i->data);
}
void opal_dealloc_CGDataProvider(void *d)
{
CGDataProviderRef dp = d;
if (dp->cb.releaseProvider) dp->cb.releaseProvider(dp->info);
free(dp);
}
CGDataProviderRef CGDataProviderCreate(
void *info, const CGDataProviderCallbacks *callbacks)
{
CGDataProviderRef dp;
if (!(callbacks && callbacks->getBytes &&
callbacks->skipBytes && callbacks->rewind))
return NULL;
dp = opal_obj_alloc("CGDataProvider", sizeof(CGDataProvider));
if (!dp) return NULL;
dp->cb = *callbacks;
dp->info = info;
return dp;
}
static inline CGDataProviderRef opal_CreateDirectAccess(
void *info, size_t size, const CGDataProviderDirectAccessCallbacks *callbacks)
{
CGDataProviderRef dp;
DirectInfo *i;
i = calloc(1, sizeof(DirectInfo));
if (!i) {
errlog("%s:%d: calloc failed\n", __FILE__, __LINE__);
return NULL;
}
dp = CGDataProviderCreate(i, &opal_DirectCallbacks);
if (!dp) {
free(i);
return NULL;
}
if (callbacks) i->cb = *callbacks;
i->info = info;
i->size = size;
if (i->cb.getBytePointer) {
i->data = i->cb.getBytePointer(info);
if (i->data) i->releaseData = opal_DirectReleaseData;
}
return dp;
}
CGDataProviderRef CGDataProviderCreateDirectAccess(
void *info, size_t size, const CGDataProviderDirectAccessCallbacks *callbacks)
{
if (!size) return NULL;
if (!(callbacks && (callbacks->getBytes || callbacks->getBytePointer)))
return NULL;
return opal_CreateDirectAccess(info, size, callbacks);
}
CGDataProviderRef CGDataProviderCreateWithData(
void *info,
const void *data,
size_t size,
void (*releaseData)(void *info, const void *data, size_t size))
{
CGDataProviderRef dp;
DirectInfo *i;
if (!size || !data) return NULL;
dp = opal_CreateDirectAccess(info, size, NULL);
if (!dp) return NULL;
i = dp->info;
i->data = data;
i->releaseData = releaseData;
return dp;
}
CGDataProviderRef CGDataProviderRetain(CGDataProviderRef provider)
{
return (provider ? opal_obj_retain(provider) : NULL);
}
void CGDataProviderRelease(CGDataProviderRef provider)
{
if(provider) opal_obj_release(provider);
}

109
CGDataProvider.h Normal file
View File

@ -0,0 +1,109 @@
/** <title>CGDataProvider</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGDataProvider_h
#define OPAL_CGDataProvider_h
#include <unistd.h>
/* Data Types */
typedef struct CGDataProvider * CGDataProviderRef;
/* Callbacks */
typedef void *(*CGDataProviderGetBytePointerCallback)(void *info);
typedef size_t (*CGDataProviderGetBytesAtOffsetCallback)(
void *info,
void *buffer,
size_t offset,
size_t count
);
typedef size_t (*CGDataProviderGetBytesCallback)(
void *info,
void *buffer,
size_t count
);
typedef void (*CGDataProviderSkipBytesCallback)(void *info, size_t count);
typedef void (*CGDataProviderReleaseBytePointerCallback)(
void *info,
const void *pointer
);
typedef void (*CGDataProviderReleaseDataCallback)(
void *info,
const void *data,
size_t size
);
typedef void (*CGDataProviderReleaseInfoCallback)(void *info);
typedef void (*CGDataProviderRewindCallback)(void *info);
typedef struct CGDataProviderCallbacks
{
CGDataProviderGetBytesCallback getBytes;
CGDataProviderSkipBytesCallback skipBytes;
CGDataProviderRewindCallback rewind;
CGDataProviderReleaseInfoCallback releaseProvider;
} CGDataProviderCallbacks;
typedef struct CGDataProviderDirectAccessCallbacks
{
CGDataProviderGetBytePointerCallback getBytePointer;
CGDataProviderReleaseBytePointerCallback releaseBytePointer;
CGDataProviderGetBytesAtOffsetCallback getBytes;
CGDataProviderReleaseInfoCallback releaseProvider;
} CGDataProviderDirectAccessCallbacks;
/* Functions */
CGDataProviderRef CGDataProviderCreate(
void *info,
const CGDataProviderCallbacks *callbacks
);
CGDataProviderRef CGDataProviderCreateDirectAccess(
void *info,
size_t size,
const CGDataProviderDirectAccessCallbacks *callbacks
);
CGDataProviderRef CGDataProviderCreateWithData(
void *info,
const void *data,
size_t size,
void (*releaseData)(void *info, const void *data, size_t size)
);
/* CGDataProviderRef CGDataProviderCreateWithCFData(CFDataRef data); */
/* CGDataProviderRef CGDataProviderCreateWithURL(CFURLRef url); */
CGDataProviderRef CGDataProviderRetain(CGDataProviderRef provider);
void CGDataProviderRelease(CGDataProviderRef provider);
#endif /* OPAL_CGDataProvider_h */

212
CGFont.c Normal file
View File

@ -0,0 +1,212 @@
/** <title>CGFont</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGFont.h"
#include <stdlib.h>
#include <string.h>
#include "cairo-ft.h"
#include FT_LIST_H
#include "opal.h"
/* We just return a (cairo_font_face_t *) as a (CGFontRef) */
static FcPattern *opal_FcPatternCreateFromName(const char *name);
/* We keep an LRU cache of patterns looked up by name to avoid calling
* fontconfig too frequently (like when refreshing a window repeatedly) */
/* But we cache patterns and let cairo handle FT_Face objects because of
* memory management problems (lack of reference counting on FT_Face) */
/* We can't use Freetype's Cache Manager to implement our cache because its API
* seems to be in a flux (for other than Face, CMap, Image and SBit at least) */
/* Number of entries to keep in the cache */
#define CACHE_SIZE 10
static FT_ListRec pattern_cache;
typedef struct cache_entry {
FT_ListNodeRec node;
unsigned int hash;
FcPattern *pat;
} cache_entry;
typedef struct iter_state {
unsigned int hash;
FcPattern *pat;
int cnt;
} iter_state;
static FT_Error cache_iterator(FT_ListNode node, void *user)
{
cache_entry *entry = (cache_entry *)node;
iter_state *state = user;
state->cnt++;
if (!node) return 1;
if (entry->hash == state->hash) {
state->pat = entry->pat;
FT_List_Up(&pattern_cache, node);
return 2;
}
return 0;
}
static unsigned int hash_string(const char *str)
{
unsigned int hash;
for (hash = 0; *str != '\0'; str++)
hash = 31 * hash + *str;
return hash;
}
static FcPattern *opal_FcPatternCacheLookup(const char *name)
{
iter_state state;
state.cnt = 0;
state.pat = NULL;
state.hash = hash_string(name);
FT_List_Iterate(&pattern_cache, cache_iterator, &state);
if (state.pat)
return state.pat;
state.pat = opal_FcPatternCreateFromName(name);
if (!state.pat) return NULL;
if (state.cnt >= CACHE_SIZE) { /* Remove last entry from the cache */
FT_ListNode node;
node = pattern_cache.tail;
FT_List_Remove(&pattern_cache, node);
FcPatternDestroy(((cache_entry *)node)->pat);
free(node);
}
/* Add new entry to the cache */
{
cache_entry *entry;
entry = calloc(1, sizeof(*entry));
if (!entry) {
errlog("%s:%d: calloc failed\n", __FILE__, __LINE__);
return state.pat;
}
entry->hash = state.hash;
entry->pat = state.pat;
FT_List_Insert(&pattern_cache, (FT_ListNode)entry);
}
return state.pat;
}
/* End of cache related things */
CGFontRef opal_FontCreateWithName(const char *name)
{
FcPattern *pat;
pat = opal_FcPatternCacheLookup(name);
if(pat)
return (CGFontRef)cairo_ft_font_face_create_for_pattern(pat);
else
return NULL;
}
CGFontRef CGFontCreateWithPlatformFont(void *platformFontReference)
{
cairo_font_face_t *cfont;
cairo_status_t cret;
/* FIXME: The FT_Face should not be freed until cairo is done with it */
cfont = cairo_ft_font_face_create_for_ft_face(platformFontReference,
FT_LOAD_DEFAULT);
cret = cairo_font_face_status(cfont);
if (cret) {
errlog("%s:%d: cairo_ft_font_face_create status: %s\n",
__FILE__, __LINE__, cairo_status_to_string(cret));
cairo_font_face_destroy(cfont);
return NULL;
}
return (CGFontRef)cfont;
}
CGFontRef CGFontRetain(CGFontRef font)
{
return (CGFontRef)cairo_font_face_reference((cairo_font_face_t *)font);
}
void CGFontRelease(CGFontRef font)
{
cairo_font_face_destroy((cairo_font_face_t *)font);
}
static FcPattern *opal_FcPatternCreateFromName(const char *name)
{
char *family, *traits;
FcPattern *pat;
FcResult fcres;
FcBool success;
if (!name) return NULL;
family = strdup(name);
pat = FcPatternCreate();
if (!family || !pat) goto error;
/* Try to parse a Postscript font name and make a corresponding pattern */
/* Consider everything up to the first dash to be the family name */
traits = strchr(family, '-');
if (traits) {
*traits = '\0';
traits++;
}
success = FcPatternAddString(pat, FC_FAMILY, (FcChar8 *)family);
if (!success) goto error;
if (traits) {
/* FIXME: The following is incomplete and may also be wrong */
/* Fontconfig assumes Medium Roman Regular so don't care about theese */
if (strstr(traits, "Bold"))
success |= FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD);
if (strstr(traits, "Italic"))
success |= FcPatternAddInteger(pat, FC_SLANT, FC_SLANT_ITALIC);
if (strstr(traits, "Oblique"))
success |= FcPatternAddInteger(pat, FC_SLANT, FC_SLANT_OBLIQUE);
if (strstr(traits, "Condensed"))
success |= FcPatternAddInteger(pat, FC_WIDTH, FC_WIDTH_CONDENSED);
if (!success) goto error;
}
success = FcConfigSubstitute(NULL, pat, FcMatchPattern);
if (!success) goto error;
FcDefaultSubstitute(pat);
pat = FcFontMatch(NULL, pat, &fcres);
if (!pat) goto error;
free(family);
return pat;
error:
errlog("%s:%d: opal_FcPatternCreateFromName failed\n", __FILE__, __LINE__);
if (family) free (family);
if (pat) FcPatternDestroy(pat);
return NULL;
}

49
CGFont.h Normal file
View File

@ -0,0 +1,49 @@
/** <title>CGFont</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGFont_h
#define OPAL_CGFont_h
/* Data Types */
typedef struct CGFont * CGFontRef;
typedef unsigned short CGGlyph;
typedef unsigned short CGFontIndex;
/* Constants */
enum {
kCGFontIndexMax = ((1 << 16) - 2),
kCGFontIndexInvalid = ((1 << 16) - 1),
kCGGlyphMax = kCGFontIndexMax
};
/* Functions */
CGFontRef CGFontCreateWithPlatformFont(void *platformFontReference);
CGFontRef CGFontRetain(CGFontRef font);
void CGFontRelease(CGFontRef font);
#endif /* OPAL_CGFont_h */

60
CGFunction.h Normal file
View File

@ -0,0 +1,60 @@
/** <title>CGFunction</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGFunction_h
#define OPAL_CGFunction_h
/* Data Types */
typedef struct CGFunction *CGFunctionRef;
/* Callbacks */
typedef void (*CGFunctionEvaluateCallback)(
void *info,
const float *inData,
float *outData
);
typedef void (*CGFunctionReleaseInfoCallback)(void *info);
typedef struct CGFunctionCallbacks {
unsigned int version;
CGFunctionEvaluateCallback evaluate;
CGFunctionReleaseInfoCallback releaseInfo
} CGFunctionCallbacks;
/* Functions */
CGFunctionRef CGFunctionCreate(
void *info,
size_t domainDimension,
const float *domain,
size_t rangeDimension,
const float *range,
const CGFunctionCallbacks *callbacks
);
CGFunctionRef CGFunctionRetain(CGFunctionRef function);
void CGFunctionRelease(CGFunctionRef function);
#endif /* OPAL_CGFunction_h */

208
CGGeometry.c Normal file
View File

@ -0,0 +1,208 @@
/** <title>CGGeometry</title>
<abstract>C Interface to graphics drawing library
- geometry routines</abstract>
Copyright (C) 1995,2002 Free Software Foundation, Inc.
Author: Adam Fedor <fedor@gnu.org>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Define IN_CGGEOMETRY_C so that the header can provide non-inline
* versions of the function implementations for us.
*/
#define IN_CGGEOMETRY_C
#include <CGGeometry.h>
#undef IN_CGGEOMETRY_C
#define _ISOC99_SOURCE
#include <math.h>
/* Constants */
const CGPoint CGPointZero = {0,0};
const CGSize CGSizeZero = {0,0};
const CGRect CGRectZero = {{0,0},{0,0}};
const CGRect CGRectNull = {{NAN,NAN},{NAN,NAN}};
const CGRect CGRectInfinite = {{INFINITY,INFINITY},{INFINITY,INFINITY}};
/* Functions */
int CGRectIsNull(CGRect rect)
{
return (isnan(rect.origin.x) || isnan(rect.origin.y) ||
isnan(rect.size.width) || isnan(rect.size.height)) ? 1 : 0;
}
int CGRectIsInfinite(CGRect rect)
{
return (isinf(rect.origin.x) || isinf(rect.origin.y) ||
isinf(rect.size.width) || isinf(rect.size.height)) ? 1 : 0;
}
CGRect CGRectIntegral(CGRect rect)
{
rect = CGRectStandardize(rect);
/* The order of the following is relevant: we change values we already used */
rect.size.width = ceil(rect.origin.x + rect.size.width);
rect.size.height = ceil(rect.origin.y + rect.size.height);
rect.origin.x = floor(rect.origin.x);
rect.origin.y = floor(rect.origin.y);
rect.size.width -= rect.origin.x;
rect.size.height -= rect.origin.y;
return rect;
}
CGRect CGRectIntersection(CGRect r1, CGRect r2)
{
CGRect rect;
/* If both of them are empty we can return r2 as an empty rect,
so this covers all cases: */
if (CGRectIsEmpty(r1))
return r2;
else if (CGRectIsEmpty(r2))
return r1;
r1 = CGRectStandardize(r1);
r2 = CGRectStandardize(r2);
if (r1.origin.x + r1.size.width <= r2.origin.x ||
r2.origin.x + r2.size.width <= r1.origin.x ||
r1.origin.y + r1.size.height <= r2.origin.y ||
r2.origin.y + r2.size.height <= r1.origin.y)
return CGRectNull;
rect.origin.x = (r1.origin.x > r2.origin.x ? r1.origin.x : r2.origin.x);
rect.origin.y = (r1.origin.y > r2.origin.y ? r1.origin.y : r2.origin.y);
if (r1.origin.x + r1.size.width < r2.origin.x + r2.size.width)
rect.size.width = r1.origin.x + r1.size.width - rect.origin.x;
else
rect.size.width = r2.origin.x + r2.size.width - rect.origin.x;
if (r1.origin.y + r1.size.height < r2.origin.y + r2.size.height)
rect.size.width = r1.origin.y + r1.size.height - rect.origin.y;
else
rect.size.width = r2.origin.y + r2.size.height - rect.origin.y;
return rect;
}
void CGRectDivide(CGRect rect, CGRect *slice, CGRect *remainder,
float amount, CGRectEdge edge)
{
static CGRect srect;
static CGRect rrect;
if (!slice)
slice = &srect;
if (!remainder)
remainder = &rrect;
if (amount < 0)
amount = 0;
rect = CGRectStandardize(rect);
*slice = rect;
*remainder = rect;
switch (edge) {
case CGRectMinXEdge:
remainder->origin.x += amount;
if (amount < rect.size.width) {
slice->size.width = amount;
remainder->size.width -= amount;
} else {
remainder->size.width = 0;
}
break;
case CGRectMinYEdge:
remainder->origin.y += amount;
if (amount < rect.size.height) {
slice->size.height = amount;
remainder->size.height -= amount;
} else {
remainder->size.height = 0;
}
break;
case CGRectMaxXEdge:
if (amount < rect.size.width) {
slice->origin.x += rect.size.width - amount;
slice->size.width = amount;
remainder->size.width -= amount;
} else {
remainder->size.width = 0;
}
break;
case CGRectMaxYEdge:
if (amount < rect.size.height) {
slice->origin.y += rect.size.height - amount;
slice->size.height = amount;
remainder->size.height -= amount;
} else {
remainder->size.height = 0;
}
break;
default:
break;
}
}
#ifndef MAX
#define MAX(a,b) \
({typeof(a) _MAX_a = (a); typeof(b) _MAX_b = (b); \
_MAX_a > _MAX_b ? _MAX_a : _MAX_b; })
#define GS_DEFINED_MAX
#endif
#ifndef MIN
#define MIN(a,b) \
({typeof(a) _MIN_a = (a); typeof(b) _MIN_b = (b); \
_MIN_a < _MIN_b ? _MIN_a : _MIN_b; })
#define GS_DEFINED_MIN
#endif
CGRect CGRectUnion(CGRect r1, CGRect r2)
{
CGRect rect;
/* If both of them are empty we can return r2 as an empty rect,
so this covers all cases: */
if (CGRectIsEmpty(r1))
return r2;
else if (CGRectIsEmpty(r2))
return r1;
r1 = CGRectStandardize(r1);
r2 = CGRectStandardize(r2);
rect.origin.x = MIN(r1.origin.x, r2.origin.x);
rect.origin.y = MIN(r1.origin.y, r2.origin.y);
rect.size.width = MAX(r1.origin.x + r1.size.width, r2.origin.x + r2.size.width);
rect.size.height = MAX(r1.origin.y + r1.size.height, r2.origin.y + r2.size.height);
return rect;
}
#ifdef GS_DEFINED_MAX
#undef GS_DEFINED_MAX
#undef MAX
#endif
#ifdef GS_DEFINED_MIN
#undef GS_DEFINED_MIN
#undef MIN
#endif

350
CGGeometry.h Normal file
View File

@ -0,0 +1,350 @@
/** <title>CGGeometry</title>
<abstract>C Interface to graphics drawing library
- geometry routines</abstract>
Copyright (C) 1995,2002 Free Software Foundation, Inc.
Author: Adam Fedor <fedor@gnu.org>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGGeometry_h
#define OPAL_CGGeometry_h
/* Data Types */
typedef struct CGPoint
{
float x;
float y;
} CGPoint;
typedef struct CGSize
{
float width;
float height;
} CGSize;
typedef struct CGRect
{
CGPoint origin;
CGSize size;
} CGRect;
/* Constants */
typedef enum CGRectEdge
{
CGRectMinXEdge = 0,
CGRectMinYEdge = 1,
CGRectMaxXEdge = 2,
CGRectMaxYEdge = 3
} CGRectEdge;
/** Point at 0,0 */
extern const CGPoint CGPointZero;
/** Zero size */
extern const CGSize CGSizeZero;
/** Zero-size rectangle at 0,0 */
extern const CGRect CGRectZero;
/** An invalid rectangle */
extern const CGRect CGRectNull;
/** A rectangle with infinite extent */
extern const CGRect CGRectInfinite;
/* Functions */
/* All but the most complex functions are declared static inline in this
* header file so that they are maximally efficient. In order to provide
* true functions (for code modules that don't have this header) this
* header is included in CGGeometry.c where the functions are no longer
* declared inline.
*/
#ifdef IN_CGGEOMETRY_C
#define GS_GEOM_SCOPE extern
#define GS_GEOM_ATTR
#else
#define GS_GEOM_SCOPE static inline
#define GS_GEOM_ATTR __attribute__((unused))
#endif
/* Creating and modifying Geometric Forms */
/** Returns a CGPoint having x-coordinate x and y-coordinate y. */
GS_GEOM_SCOPE CGPoint CGPointMake(float x, float y) GS_GEOM_ATTR;
/** Returns a CGSize having width width and height height. */
GS_GEOM_SCOPE CGSize CGSizeMake(float width, float height) GS_GEOM_ATTR;
/** Returns a CGRect having point of origin (x, y) and size (width, height). */
GS_GEOM_SCOPE CGRect CGRectMake(float x, float y, float width, float height) GS_GEOM_ATTR;
/** Returns an equivalent rect which has positive width and heght. */
GS_GEOM_SCOPE CGRect CGRectStandardize(CGRect rect) GS_GEOM_ATTR;
/** Returns the rectangle obtained by translating rect
* horizontally by dx and vertically by dy. */
GS_GEOM_SCOPE CGRect CGRectOffset(CGRect rect, float dx, float dy) GS_GEOM_ATTR;
/** Returns the rectangle obtained by moving each of rect's
* horizontal sides inward by dy and each of rect's vertical
* sides inward by dx with the center point preserved. A larger
* rectangle can be created by using negative values. */
GS_GEOM_SCOPE CGRect CGRectInset(CGRect rect, float dx, float dy) GS_GEOM_ATTR;
/** Returns a rectangle obtained by expanding rect minimally
* so that all four of its defining components are integers. */
CGRect CGRectIntegral(CGRect rect);
/** Returns the smallest rectangle which contains both r1 and r2
* (modulo a set of measure zero). If either of r1 or r2
* is an empty rectangle, then the other rectangle is returned.
* If both are empty, then the empty rectangle is returned. */
CGRect CGRectUnion(CGRect r1, CGRect r2);
/** Returns the largest rectangle which lies in both r1 and r2.
* If r1 and r2 have empty intersection (or, rather, intersection
* of measure zero, since this includes having their intersection
* be only a point or a line), then the empty rectangle is returned. */
CGRect CGRectIntersection(CGRect r1, CGRect r2);
/** Divides rect into two rectangles (namely slice and remainder) by
* "cutting" rect---parallel to, and a distance amount from the given edge
* of rect. You may pass 0 in as either of slice or remainder to avoid
* obtaining either of the created rectangles. */
void CGRectDivide(CGRect rect, CGRect *slice, CGRect *remainder,
float amount, CGRectEdge edge);
/* Accessing Geometric Attributes */
/** Returns the least x-coordinate value still inside rect. */
GS_GEOM_SCOPE float CGRectGetMinX(CGRect rect) GS_GEOM_ATTR;
/** Returns the x-coordinate of rect's middle point. */
GS_GEOM_SCOPE float CGRectGetMidX(CGRect rect) GS_GEOM_ATTR;
/** Returns the greatest x-coordinate value still inside rect. */
GS_GEOM_SCOPE float CGRectGetMaxX(CGRect rect) GS_GEOM_ATTR;
/** Returns the least y-coordinate value still inside rect. */
GS_GEOM_SCOPE float CGRectGetMinY(CGRect rect) GS_GEOM_ATTR;
/** Returns the y-coordinate of rect's middle point. */
GS_GEOM_SCOPE float CGRectGetMidY(CGRect rect) GS_GEOM_ATTR;
/** Returns the greatest y-coordinate value still inside rect. */
GS_GEOM_SCOPE float CGRectGetMaxY(CGRect rect) GS_GEOM_ATTR;
/** Returns rect's width. */
GS_GEOM_SCOPE float CGRectGetWidth(CGRect rect) GS_GEOM_ATTR;
/** Returns rect's height. */
GS_GEOM_SCOPE float CGRectGetHeight(CGRect rect) GS_GEOM_ATTR;
/** Returns 1 iff the rect is invalid. */
int CGRectIsNull(CGRect rect);
/** Returns 1 iff the area of rect is zero (i.e., iff either
* of rect's width or height is zero or is an invalid rectangle). */
GS_GEOM_SCOPE int CGRectIsEmpty(CGRect rect) GS_GEOM_ATTR;
/** Returns 1 iff the rect is infinite. */
int CGRectIsInfinite(CGRect rect);
/** Returns 1 iff rect1 and rect2 are intersecting. */
GS_GEOM_SCOPE int CGRectIntersectsRect(CGRect rect1, CGRect rect2) GS_GEOM_ATTR;
/** Returns 1 iff rect1 contains rect2. */
GS_GEOM_SCOPE int CGRectContainsRect(CGRect rect1, CGRect rect2) GS_GEOM_ATTR;
/** Returns 1 iff point is inside rect. */
GS_GEOM_SCOPE int CGRectContainsPoint(CGRect rect, CGPoint point) GS_GEOM_ATTR;
/** Returns 1 iff rect1's and rect2's origin and size are the same. */
GS_GEOM_SCOPE int CGRectEqualToRect(CGRect rect1, CGRect rect2) GS_GEOM_ATTR;
/** Returns 1 iff size1's and size2's width and height are the same. */
GS_GEOM_SCOPE int CGSizeEqualToSize(CGSize size1, CGSize size2) GS_GEOM_ATTR;
/** Returns 1 iff point1's and point2's x- and y-coordinates are the same. */
GS_GEOM_SCOPE int CGPointEqualToPoint(CGPoint point1, CGPoint point2) GS_GEOM_ATTR;
/* Inlined functions */
GS_GEOM_SCOPE float CGRectGetMinX(CGRect rect)
{
if (rect.size.width < 0)
return rect.origin.x + rect.size.width;
else
return rect.origin.x;
}
GS_GEOM_SCOPE float CGRectGetMidX(CGRect rect)
{
return rect.origin.x + (rect.size.width / 2.0);
}
GS_GEOM_SCOPE float CGRectGetMaxX(CGRect rect)
{
if (rect.size.width < 0)
return rect.origin.x;
else
return rect.origin.x + rect.size.width;
}
GS_GEOM_SCOPE float CGRectGetMinY(CGRect rect)
{
if (rect.size.height < 0)
return rect.origin.y + rect.size.height;
else
return rect.origin.y;
}
GS_GEOM_SCOPE float CGRectGetMidY(CGRect rect)
{
return rect.origin.y + (rect.size.height / 2.0);
}
GS_GEOM_SCOPE float CGRectGetMaxY(CGRect rect)
{
if (rect.size.height < 0)
return rect.origin.y;
else
return rect.origin.y + rect.size.height;
}
GS_GEOM_SCOPE float CGRectGetWidth(CGRect rect)
{
return rect.size.width;
}
GS_GEOM_SCOPE float CGRectGetHeight(CGRect rect)
{
return rect.size.height;
}
GS_GEOM_SCOPE int CGRectIsEmpty(CGRect rect)
{
if (CGRectIsNull(rect))
return 1;
return ((rect.size.width == 0) || (rect.size.height == 0)) ? 1 : 0;
}
GS_GEOM_SCOPE int CGRectIntersectsRect(CGRect rect1, CGRect rect2)
{
return (CGRectIsNull(CGRectIntersection(rect1, rect2)) ? 0 : 1);
}
GS_GEOM_SCOPE int CGRectContainsRect(CGRect rect1, CGRect rect2)
{
return CGRectEqualToRect(rect1, CGRectUnion(rect1, rect2));
}
GS_GEOM_SCOPE int CGRectContainsPoint(CGRect rect, CGPoint point)
{
rect = CGRectStandardize(rect);
return ((point.x >= rect.origin.x) &&
(point.y >= rect.origin.y) &&
(point.x <= rect.origin.x + rect.size.width) &&
(point.y <= rect.origin.y + rect.size.height)) ? 1 : 0;
}
GS_GEOM_SCOPE int CGRectEqualToRect(CGRect rect1, CGRect rect2)
{
/* FIXME: It is not clear from the docs if {{0,0},{1,1}} and {{1,1},{-1,-1}}
are equal or not. (The text seem to imply that they aren't.) */
return ((rect1.origin.x == rect2.origin.x) &&
(rect1.origin.y == rect2.origin.y) &&
(rect1.size.width == rect2.size.width) &&
(rect1.size.height == rect2.size.height)) ? 1 : 0;
}
GS_GEOM_SCOPE int CGSizeEqualToSize(CGSize size1, CGSize size2)
{
return ((size1.width == size2.width) &&
(size1.height == size2.height)) ? 1 : 0;
}
GS_GEOM_SCOPE int CGPointEqualToPoint(CGPoint point1, CGPoint point2)
{
return ((point1.x == point2.x) && (point1.y == point2.y)) ? 1 : 0;
}
GS_GEOM_SCOPE CGPoint CGPointMake(float x, float y)
{
CGPoint point;
point.x = x;
point.y = y;
return point;
}
GS_GEOM_SCOPE CGSize CGSizeMake(float width, float height)
{
CGSize size;
size.width = width;
size.height = height;
return size;
}
GS_GEOM_SCOPE CGRect CGRectMake(float x, float y, float width, float height)
{
CGRect rect;
rect.origin.x = x;
rect.origin.y = y;
rect.size.width = width;
rect.size.height = height;
return rect;
}
GS_GEOM_SCOPE CGRect CGRectStandardize(CGRect rect)
{
if (rect.size.width < 0) {
rect.origin.x += rect.size.width;
rect.size.width = -rect.size.width;
}
if (rect.size.height < 0) {
rect.origin.y += rect.size.height;
rect.size.height = -rect.size.height;
}
return rect;
}
GS_GEOM_SCOPE CGRect CGRectOffset(CGRect rect, float dx, float dy)
{
rect.origin.x += dx;
rect.origin.y += dy;
return rect;
}
GS_GEOM_SCOPE CGRect CGRectInset(CGRect rect, float dx, float dy)
{
rect = CGRectStandardize(rect);
rect.origin.x += dx;
rect.origin.y += dy;
rect.size.width -= (2 * dx);
rect.size.height -= (2 * dy);
return rect;
}
#endif /* OPAL_CGGeometry_h */

279
CGImage.c Normal file
View File

@ -0,0 +1,279 @@
/** <title>CGImage</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "CGImage.h"
#include "CGDataProvider-private.h"
#include <stdlib.h>
#include <cairo.h>
#include "opal.h"
typedef struct CGImage
{
struct objbase base;
int ismask;
size_t width;
size_t height;
size_t bitsPerComponent;
size_t bitsPerPixel;
size_t bytesPerRow;
CGDataProviderRef dp;
float *decode;
int shouldInterpolate;
/* alphaInfo is always AlphaNone for mask */
CGImageAlphaInfo alphaInfo;
/* cspace and intent are only set for image */
CGColorSpaceRef cspace;
CGColorRenderingIntent intent;
} CGImage;
void opal_dealloc_CGImage(void *i)
{
CGImageRef img = i;
CGColorSpaceRelease(img->cspace);
CGDataProviderRelease(img->dp);
if (img->decode) free(img->decode);
free(i);
}
static inline CGImageRef opal_CreateImage(
size_t width, size_t height,
size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow,
CGDataProviderRef provider, const float *decode, int shouldInterpolate,
size_t numComponents, int hasAlpha)
{
CGImageRef img;
if (bitsPerComponent != 8 && bitsPerComponent != 4 &&
bitsPerComponent != 2 && bitsPerComponent != 1) {
errlog("%s:%d: Invalid bitsPerComponent (allowed: 1,2,4,8)\n",
__FILE__, __LINE__);
return NULL;
}
if (bitsPerPixel != 32 && bitsPerPixel != 16 &&
bitsPerPixel != 8) {
errlog("%s:%d: Unsupported bitsPerPixel (allowed: 8, 16, 32)\n",
__FILE__, __LINE__);
return NULL;
}
if (bitsPerPixel < bitsPerComponent * (numComponents + (hasAlpha ? 1 : 0))) {
errlog("%s:%d: Too few bitsPerPixel for bitsPerComponent\n",
__FILE__, __LINE__);
return NULL;
}
img = opal_obj_alloc("CGImage", sizeof(CGImage));
if (!img) return NULL;
if(decode && numComponents) {
size_t i;
img->decode = malloc(2*numComponents*sizeof(float));
if (!img->decode) {
errlog("%s:%d: malloc failed\n", __FILE__, __LINE__);
free(img);
return NULL;
}
for(i=0; i<2*numComponents; i++) img->decode[i] = decode[i];
}
img->width = width;
img->height = height;
img->bitsPerComponent = bitsPerComponent;
img->bitsPerPixel = bitsPerPixel;
img->bytesPerRow = bytesPerRow;
img->dp = CGDataProviderRetain(provider);
img->shouldInterpolate = shouldInterpolate;
return img;
}
CGImageRef CGImageCreate(
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bitsPerPixel,
size_t bytesPerRow,
CGColorSpaceRef colorspace,
CGImageAlphaInfo alphaInfo,
CGDataProviderRef provider,
const float *decode,
int shouldInterpolate,
CGColorRenderingIntent intent)
{
CGImageRef img;
size_t numComponents;
int hasAlpha;
if (alphaInfo == kCGImageAlphaOnly)
numComponents = 0;
else
numComponents = CGColorSpaceGetNumberOfComponents(colorspace);
hasAlpha = (alphaInfo == kCGImageAlphaPremultipliedLast) ||
(alphaInfo == kCGImageAlphaPremultipliedFirst) ||
(alphaInfo == kCGImageAlphaLast) ||
(alphaInfo == kCGImageAlphaFirst) ||
(alphaInfo == kCGImageAlphaOnly);
if (!provider || !colorspace) return NULL;
img = opal_CreateImage(width, height,
bitsPerComponent, bitsPerPixel, bytesPerRow,
provider, decode, shouldInterpolate,
numComponents, hasAlpha);
if (!img) return NULL;
img->alphaInfo = alphaInfo;
img->cspace = CGColorSpaceRetain(colorspace);
img->intent = intent;
return img;
}
CGImageRef CGImageMaskCreate(
size_t width, size_t height,
size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow,
CGDataProviderRef provider, const float *decode, int shouldInterpolate)
{
CGImageRef img;
if (!provider) return NULL;
img = opal_CreateImage(width, height,
bitsPerComponent, bitsPerPixel, bytesPerRow,
provider, decode, shouldInterpolate, 0, 1);
if (!img) return NULL;
img->ismask = 1;
return img;
}
CGImageRef CGImageRetain(CGImageRef image)
{
return (image ? opal_obj_retain(image) : NULL);
}
void CGImageRelease(CGImageRef image)
{
if(image) opal_obj_release(image);
}
int CGImageIsMask(CGImageRef image)
{
return image->ismask;
}
size_t CGImageGetWidth(CGImageRef image)
{
return image->width;
}
size_t CGImageGetHeight(CGImageRef image)
{
return image->height;
}
size_t CGImageGetBitsPerComponent(CGImageRef image)
{
return image->bitsPerComponent;
}
size_t CGImageGetBitsPerPixel(CGImageRef image)
{
return image->bitsPerPixel;
}
size_t CGImageGetBytesPerRow(CGImageRef image)
{
return image->bytesPerRow;
}
CGColorSpaceRef CGImageGetColorSpace(CGImageRef image)
{
return image->cspace;
}
CGImageAlphaInfo CGImageGetAlphaInfo(CGImageRef image)
{
return image->alphaInfo;
}
CGDataProviderRef CGImageGetDataProvider(CGImageRef image)
{
return image->dp;
}
const float *CGImageGetDecode(CGImageRef image)
{
return image->decode;
}
int CGImageGetShouldInterpolate(CGImageRef image)
{
return image->shouldInterpolate;
}
CGColorRenderingIntent CGImageGetRenderingIntent(CGImageRef image)
{
return image->intent;
}
cairo_surface_t *opal_CGImageCreateSurfaceForImage(CGImageRef img)
{
cairo_surface_t *surf;
cairo_format_t cformat;
unsigned char *data;
size_t datalen;
size_t numComponents = 0;
int alphaLast = 0;
int mask;
/* The target is always 8 BPC 32 BPP for Cairo so should convert to this */
/* (see also QA1037) */
if (img->cspace)
numComponents = CGColorSpaceGetNumberOfComponents(img->cspace);
switch (img->alphaInfo) {
case kCGImageAlphaNone:
case kCGImageAlphaNoneSkipLast:
alphaLast = 1;
case kCGImageAlphaNoneSkipFirst:
break;
case kCGImageAlphaLast:
alphaLast = 1;
case kCGImageAlphaFirst:
numComponents++;
break;
case kCGImageAlphaPremultipliedLast:
case kCGImageAlphaPremultipliedFirst:
errlog("%s:%d: FIXME: premultiplied alpha is not supported\n",
__FILE__, __LINE__);
return NULL;
break;
case kCGImageAlphaOnly:
numComponents = 1;
}
/* FIXME: implement this */
/* datalen = */
mask = (1 << img->bitsPerComponent) - 1;
}

100
CGImage.h Normal file
View File

@ -0,0 +1,100 @@
/** <title>CGImage</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGImage_h
#define OPAL_CGImage_h
#include <CGColorSpace.h>
/* Data Types */
typedef struct CGImage * CGImageRef;
/* Constants */
typedef enum CGImageAlphaInfo
{
kCGImageAlphaNone = 0,
kCGImageAlphaPremultipliedLast = 1,
kCGImageAlphaPremultipliedFirst = 2,
kCGImageAlphaLast = 3,
kCGImageAlphaFirst = 4,
kCGImageAlphaNoneSkipLast = 5,
kCGImageAlphaNoneSkipFirst = 6,
kCGImageAlphaOnly = 7
} CGImageAlphaInfo;
/* Drawing Images */
CGImageRef CGImageCreate(
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bitsPerPixel,
size_t bytesPerRow,
CGColorSpaceRef colorspace,
CGImageAlphaInfo alphaInfo,
CGDataProviderRef provider,
const float *decode,
int shouldInterpolate,
CGColorRenderingIntent intent
);
CGImageRef CGImageMaskCreate(
size_t width,
size_t height,
size_t bitsPerComponent,
size_t bitsPerPixel,
size_t bytesPerRow,
CGDataProviderRef provider,
const float *decode,
int shouldInterpolate
);
CGImageRef CGImageRetain(CGImageRef image);
void CGImageRelease(CGImageRef image);
int CGImageIsMask(CGImageRef image);
size_t CGImageGetWidth(CGImageRef image);
size_t CGImageGetHeight(CGImageRef image);
size_t CGImageGetBitsPerComponent(CGImageRef image);
size_t CGImageGetBitsPerPixel(CGImageRef image);
size_t CGImageGetBytesPerRow(CGImageRef image);
CGColorSpaceRef CGImageGetColorSpace(CGImageRef image);
CGImageAlphaInfo CGImageGetAlphaInfo(CGImageRef image);
CGDataProviderRef CGImageGetDataProvider(CGImageRef image);
const float *CGImageGetDecode(CGImageRef image);
int CGImageGetShouldInterpolate(CGImageRef image);
CGColorRenderingIntent CGImageGetRenderingIntent(CGImageRef image);
#endif /* OPAL_CGImage_h */

153
CGLayer.c Normal file
View File

@ -0,0 +1,153 @@
/** <title>CGLayer</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2009 Eric Wasylishen <ewasylishen@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdlib.h>
#include <math.h>
#include <CGLayer.h>
#include "CGContext-private.h"
#include "opal.h"
typedef struct CGLayer
{
struct objbase base;
CGContextRef ctxt;
CGSize size;
} CGLayer;
void opal_dealloc_CGLayer(void *l)
{
CGLayerRef layer = l;
CGContextRelease(layer->ctxt);
free(layer);
}
CGLayerRef CGLayerCreateWithContext(
CGContextRef referenceCtxt,
CGSize size,
CFDictionaryRef auxInfo)
{
CGLayerRef layer = opal_obj_alloc("CGLayer", sizeof(CGLayer));
if (!layer) return NULL;
// size is in user-space units of referenceCtxt, so transform it to device
// space.
double w = size.width, h = size.height;
cairo_user_to_device_distance(referenceCtxt->ct, &w, &h);
cairo_surface_t *layerSurface =
cairo_surface_create_similar(cairo_get_target(referenceCtxt->ct),
CAIRO_CONTENT_COLOR_ALPHA,
ceil(fabs(w)),
ceil(fabs(h)));
cairo_surface_set_device_offset(layerSurface, 0, ceil(fabs(h)));
layer->ctxt = opal_new_CGContext(layerSurface);
CGContextScaleCTM(layer->ctxt, 1.0, -1.0);
layer->size = size;
return layer;
}
CGLayerRef CGLayerRetain(CGLayerRef layer)
{
return (layer ? opal_obj_retain(layer) : NULL);
}
void CGLayerRelease(CGLayerRef layer)
{
if (layer) opal_obj_release(layer);
}
CGSize CGLayerGetSize(CGLayerRef layer)
{
return layer->size;
}
CGContextRef CGLayerGetContext(CGLayerRef layer)
{
return layer->ctxt;
}
void CGContextDrawLayerInRect(
CGContextRef destCtxt,
CGRect rect,
CGLayerRef layer)
{
cairo_t *destCairo = destCtxt->ct;
cairo_save(destCairo);
cairo_pattern_t *pattern =
cairo_pattern_create_for_surface(cairo_get_target(layer->ctxt->ct));
// Horrible code.. but sort-of works. Fix this up ASAP.
cairo_matrix_t patternMatrix;
cairo_matrix_init_identity(&patternMatrix);
cairo_matrix_translate(&patternMatrix, 0, layer->size.height);
cairo_matrix_translate(&patternMatrix, rect.origin.x, rect.origin.y);
cairo_matrix_scale(&patternMatrix, 1, -1);
cairo_matrix_scale(&patternMatrix,
rect.size.width / layer->size.width,
rect.size.height / layer->size.height);
cairo_matrix_translate(&patternMatrix, 0, -layer->size.height);
cairo_matrix_invert(&patternMatrix);
cairo_pattern_set_matrix(pattern, &patternMatrix);
// cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD);
cairo_set_source(destCairo, pattern);
//cairo_set_source_surface(destCairo, cairo_get_target(layer->ctxt->ct), 20, 20);
cairo_pattern_destroy(pattern);
cairo_set_operator(destCairo, CAIRO_OPERATOR_OVER);
//cairo_rectangle(destCairo, rect.origin.x, rect.origin.y,
// rect.size.width, rect.size.height);
//cairo_fill(destCairo);
cairo_paint(destCairo);
cairo_restore(destCairo);
}
void CGContextDrawLayerAtPoint(
CGContextRef destCtxt,
CGPoint point,
CGLayerRef layer)
{
CGContextDrawLayerInRect(destCtxt,
CGRectMake(point.x, point.y, layer->size.width, layer->size.height),
layer);
}
#if 0
CFTypeID CGLayerGetTypeID()
{
}
#endif

60
CGLayer.h Normal file
View File

@ -0,0 +1,60 @@
/** <title>CGLayer</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2009 Eric Wasylishen <ewasylishen@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGLayer_h
#define OPAL_CGLayer_h
#include <CGContext.h>
#include <CoreFoundation.h>
typedef struct CGLayer *CGLayerRef;
CGLayerRef CGLayerCreateWithContext(
CGContextRef referenceCtxt,
CGSize size,
CFDictionaryRef auxInfo
);
CGLayerRef CGLayerRetain(CGLayerRef layer);
void CGLayerRelease(CGLayerRef layer);
CGSize CGLayerGetSize(CGLayerRef layer);
CGContextRef CGLayerGetContext(CGLayerRef layer);
void CGContextDrawLayerInRect(
CGContextRef destCtxt,
CGRect rect,
CGLayerRef layer
);
void CGContextDrawLayerAtPoint(
CGContextRef destCtxt,
CGPoint point,
CGLayerRef layer
);
#if 0
CFTypeID CGLayerGetTypeID();
#endif
#endif

35
CGPDFContext.h Normal file
View File

@ -0,0 +1,35 @@
/** <title>CGPDFContext</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGPDFContext_h
#define OPAL_CGPDFContext_h
#include <CGContext.h>
/* Functions */
CGContextRef CGPDFContextCreate(
CGDataConsumerRef consumer,
const CGRect *mediaBox,
/* CFDictionaryRef */ void *auxiliaryInfo /* ignored */
);
#endif /* OPAL_CGPDFContext_h */

70
CGPDFDocument.h Normal file
View File

@ -0,0 +1,70 @@
/** <title>CGPDFDocument</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGPDFDocument_h
#define OPAL_CGPDFDocument_h
#include <CGGeometry.h>
#include <CGDataProvider.h>
/* Data Types */
typedef void * CGPDFDocumentRef;
/* Functions */
CGPDFDocumentRef CGPDFDocumentCreateWithProvider(CGDataProviderRef provider);
#if 0
CGPDFDocumentRef CGPDFDocumentCreateWithURL(CFURLRef url);
CGContextRef CGPDFContextCreate(
CGDataConsumerRef consumer,
const CGRect *mediaBox,
CFDictionaryRef auxiliaryInfo
);
CGContextRef CGPDFContextCreateWithURL(
CFURLRef url,
const CGRect *mediaBox,
CFDictionaryRef auxiliaryInfo
);
#endif
CGPDFDocumentRef CGPDFDocumentRetain(CGPDFDocumentRef document);
void CGPDFDocumentRelease(CGPDFDocumentRef document);
int CGPDFDocumentGetNumberOfPages(CGPDFDocumentRef document);
CGRect CGPDFDocumentGetMediaBox(CGPDFDocumentRef document, int page);
CGRect CGPDFDocumentGetCropBox(CGPDFDocumentRef document, int page);
CGRect CGPDFDocumentGetBleedBox(CGPDFDocumentRef document, int page);
CGRect CGPDFDocumentGetTrimBox(CGPDFDocumentRef document, int page);
CGRect CGPDFDocumentGetArtBox(CGPDFDocumentRef document, int page);
int CGPDFDocumentGetRotationAngle(CGPDFDocumentRef document, int page);
#endif /* OPAL_CGPDFDocument_h */

183
CGPath.h Normal file
View File

@ -0,0 +1,183 @@
/** <title>CGPath</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGPath_h
#define OPAL_CGPath_h
/* Constants */
typedef enum CGPathElementType {
kCGPathElementMoveToPoint = 0,
kCGPathElementAddLineToPoint = 1,
kCGPathElementAddQuadCurveToPoint = 2,
kCGPathElementAddCurveToPoint = 3,
kCGPathElementCloseSubpath = 4
} CGPathElementType;
typedef enum CGPathDrawingMode
{
kCGPathFill = 0,
kCGPathEOFill = 1,
kCGPathStroke = 2,
kCGPathFillStroke = 3,
kCGPathEOFillStroke = 4
} CGPathDrawingMode;
/* Data Types */
typedef const struct CGPath * CGPathRef;
typedef struct CGPath * CGMutablePathRef;
typedef struct CGPathElement {
CGPathElementType type;
CGPoint *points;
} CGPathElement;
/* Callbacks */
typedef void (*CGPathApplierFunction)(void *info, const CGPathElement *element);
/* Functions */
CGPathRef CGPathCreateCopy(CGPathRef path);
CGMutablePathRef CGPathCreateMutable(void);
CGMutablePathRef CGPathCreateMutableCopy(CGPathRef path);
CGPathRef CGPathRetain(CGPathRef path);
void CGPathRelease(CGPathRef path);
int CGPathIsEmpty(CGPathRef path);
int CGPathEqualToPath(CGPathRef path1, CGPathRef path2);
int CGPathIsRect(CGPathRef path, CGRect *rect);
CGRect CGPathGetBoundingBox(CGPathRef path);
CGPoint CGPathGetCurrentPoint(CGPathRef path);
int CGPathContainsPoint(
CGPathRef path,
const CGAffineTransform *m,
CGPoint point,
int eoFill
);
void CGPathAddArc(
CGMutablePathRef path,
const CGAffineTransform *m,
float x,
float y,
float r,
float startAngle,
float endAngle,
int clockwise
);
void CGPathAddArcToPoint(
CGMutablePathRef path,
const CGAffineTransform *m,
float x1,
float y1,
float x2,
float y2,
float r
);
void CGPathAddCurveToPoint(
CGMutablePathRef path,
const CGAffineTransform *m,
float cx1,
float cy1,
float cx2,
float cy2,
float x,
float y
);
void CGPathAddLines(
CGMutablePathRef path,
const CGAffineTransform *m,
const CGPoint points[],
size_t count
);
void CGPathAddLineToPoint (
CGMutablePathRef path,
const CGAffineTransform *m,
float x,
float y
);
void CGPathAddPath(
CGMutablePathRef path1,
const CGAffineTransform *m,
CGPathRef path2
);
void CGPathAddQuadCurveToPoint(
CGMutablePathRef path,
const CGAffineTransform *m,
float cx,
float cy,
float x,
float y
);
void CGPathAddRect(
CGMutablePathRef path,
const CGAffineTransform *m,
CGRect rect
);
void CGPathAddRects(
CGMutablePathRef path,
const CGAffineTransform *m,
const CGRect rects[],
size_t count
);
void CGPathApply(
CGPathRef path,
void *info,
CGPathApplierFunction function
);
void CGPathMoveToPoint(
CGMutablePathRef path,
const CGAffineTransform *m,
float x,
float y
);
void CGPathCloseSubpath(CGMutablePathRef path);
void CGPathAddEllipseInRect(
CGMutablePathRef path,
const CGAffineTransform *m,
CGRect rect
);
#endif /* OPAL_CGPath_h */

67
CGPattern.h Normal file
View File

@ -0,0 +1,67 @@
/** <title>CGPattern</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGPattern_h
#define OPAL_CGPattern_h
/* Data Types */
typedef void * CGPatternRef;
/* Constants */
typedef enum CGPatternTiling
{
kCGPatternTilingNoDistortion = 0,
kCGPatternTilingConstantSpacingMinimalDistortion = 1,
kCGPatternTilingConstantSpacing = 2
} CGPatternTiling;
/* Callbacks */
typedef void(*CGPatternDrawPatternCallback)(void *info, CGContextRef ctx);
typedef void(*CGPatternReleaseInfoCallback)(void *info);
typedef struct CGPatternCallbacks {
unsigned int version;
CGPatternDrawPatternCallback drawPattern;
CGPatternReleaseInfoCallback releaseInfo;
} CGPatternCallbacks;
/* Functions */
CGPatternRef CGPatternCreate(
void *info,
CGRect bounds,
CGAffineTransform matrix,
float xStep,
float yStep,
CGPatternTiling tiling,
int isColored,
const CGPatternCallbacks *callbacks
);
void CGPatternRelease(CGPatternRef pattern);
CGPatternRef CGPatternRetain(CGPatternRef pattern);
#endif /* OPAL_CGPattern_h */

57
CGShading.h Normal file
View File

@ -0,0 +1,57 @@
/** <title>CGShading</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 BALATON Zoltan <balaton@eik.bme.hu>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CGShading_h
#define OPAL_CGShading_h
#include <CGFunction.h>
/* Data Types */
typedef struct CGShading * CGShadingRef;
/* Functions */
CGShadingRef CGShadingCreateAxial (
CGColorSpaceRef colorspace,
CGPoint start,
CGPoint end,
CGFunctionRef function,
int extendStart,
int extendEnd
);
CGShadingRef CGShadingCreateRadial(
CGColorSpaceRef colorspace,
CGPoint start,
float startRadius,
CGPoint end,
float endRadius,
CGFunctionRef function,
int extendStart,
int extendEnd
);
CGShadingRef CGShadingRetain(CGShadingRef shading);
void CGShadingRelease(CGShadingRef shading);
#endif /* OPAL_CGShading_h */

515
COPYING Normal file
View File

@ -0,0 +1,515 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
^L
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
^L
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
^L
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
^L
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
^L
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
^L
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
^L
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
^L
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms
of the ordinary General Public License).
To apply these terms, attach the following notices to the library.
It is safest to attach them to the start of each source file to most
effectively convey the exclusion of warranty; and each file should
have at least the "copyright" line and a pointer to where the full
notice is found.
<one line to give the library's name and a brief idea of what it
does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper
mail.
You should also get your employer (if you work as a programmer) or
your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James
Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

33
CoreFoundation.h Normal file
View File

@ -0,0 +1,33 @@
/** <title>CoreFoundation</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2009 Eric Wasylishen <ewasylishen@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef OPAL_CoreFoundation_h
#define OPAL_CoreFoundation_h
# ifdef __OBJC__
@class NSDictionary;
typedef NSDictionary* CFDictionaryRef;
# else
typedef struct cf_dictionary *CFDictionaryRef;
# endif
#endif

59
Makefile Normal file
View File

@ -0,0 +1,59 @@
# Simple Makefile to build libopal.a and some examples
# This should be replaced with a proper build system
CFLAGS=-Wall -g
CPPFLAGS=-I. -I/usr/local/include -I/usr/local/include/cairo
# Get the Cairo sources and compile libcairo.a, then set CAIROSRC below.
# Once we start using private Cairo APIs static lib is needed because
# private API functions are not exported in the dynamic lib.
# For release version of cairo
#CAIROSRC=$(PWD)/cairo-1.4.10/src
#CAIROLIBS=$(CAIROSRC)/.libs/libcairo.a
# For development version of Cairo
#CAIROSRC=$(PWD)/git/cairo/src
#CAIROLIBS=$(CAIROSRC)/.libs/libcairo.a \
$(CAIROSRC)/../../pixman/installed/lib/libpixman-1.a
CAIROSRC=/usr/local/include/cairo
CAIROLIBS=/usr/local/lib/libcairo.a /usr/local/lib/libpixman-1.a
# Portable parts of libopal.a
OPAL_OBJS=CGAffineTransform.o CGColor.o CGColorSpace.o CGContext.o \
CGDataProvider.o CGFont.o CGImage.o CGLayer.o opal.o
# System specific parts of libopal.a
OPAL-X11_OBJS=opal-x11.o
EXAMPLES=test test1 test2 test3 test4 cgtest1 texttest arclock qeb2 shapes layers
LOADLIBES=$(CAIROLIBS) $(shell pkg-config --libs freetype2) \
-lfontconfig -lX11 -lXrender -lm
libopal.a: libopal.a($(OPAL_OBJS)) libopal.a($(OPAL-X11_OBJS))
CGContext.o: CPPFLAGS+=-I$(CAIROSRC)
CGFont.o: CPPFLAGS+=-I$(CAIROSRC) $(shell pkg-config --cflags freetype2)
CGImage.o: CPPFLAGS+=-I$(CAIROSRC)
opal-x11.o: CPPFLAGS+=-I$(CAIROSRC)
examples: $(EXAMPLES)
test: libopal.a
test1: libopal.a
test2: libopal.a
test3: libopal.a
test4: libopal.a
cgtest1: libopal.a
texttest: libopal.a
arclock: libopal.a
qeb2: qeb2-draw.o libopal.a
shapes: arcs.o ovals.o rects.o libopal.a
layers: layers.o libopal.a
clean:
rm -f *.o *~
distclean: clean
rm -f libopal.a $(EXAMPLES)
.PHONY: clean distclean

24
README Normal file
View File

@ -0,0 +1,24 @@
====
Opal
====
What is Opal?
-------------
Opal is a vector drawing library with an API similar to
Quartz 2D <http://www.cocoadev.com/index.pl?CoreGraphics>.
Opal is built on top of Cairo <http://www.cairographics.org>.
Opal is also a gemstone consisting of amorphous hydrated
silicon dioxide (SiO2 · nH2O) which is sometimes included
in the quartz group of minerals.
There is a homepage (which may not be updated too frequently) at
<http://goliat.eik.bme.hu/~balaton/gnustep/opal>
The sources are available from the Étoile project repository at
<http://gna.org/projects/etoile/>
*** Warning! *** This version is not yet suitable for general use.
It may be interesting for developers only, contributions are much welcome!
For more information see the TODO file.

28
TODO Normal file
View File

@ -0,0 +1,28 @@
There's a lot to do, really.
- Add proper build system
- Port to other platforms (Windows anyone?)
- Try different Cairo surfaces (ps, pdf, png, OpenGL, etc.)
- Implement TextMatrix in CGContext (may need to use internal Cairo APIs)
- Implement missing glyph drawing functions and finish ShowText
- Implement Image drawing
- Implement Patterns and Shading
- Implement Path handling functions
- Implement color management (could use lcms?)
- Fix device transform in Cairo and get rid of CTM patching hacks
Design principles to follow:
============================
- Build on public Cairo APIs as much as possible, use private APIs only if
there is no appropriate public one or would simplifiy implementation a lot
- Avoid duplicate representatation of the same thing (should not store a copy
of what Cairo already stores to avoid getting out of sync or too many
conversions). Choose between Quartz or Cairo representation and convert to
that and then stick to it.
- Keep performance in mind. This is a low level part of the system that
should be fast, small and stable so follow K.I.S.S.
- Keep dependencies clean, only #include what you need and put functions
that depend on the same thing in one file.

155
arcs.c Normal file
View File

@ -0,0 +1,155 @@
/*
File: arcs.c
Abstract: // These are the functions that implement equivalents to the QuickDraw arc drawing APIs,
// FrameArc and PaintArc.
// See DrawProcs.c for sample usage
Version: 1.0
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Computer, Inc. ("Apple") in consideration of your agreement to the
following terms, and your use, installation, modification or
redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use,
install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Computer,
Inc. may be used to endorse or promote products derived from the Apple
Software without specific prior written permission from Apple. Except
as expressly stated in this notice, no other rights or licenses, express
or implied, are granted by Apple herein, including but not limited to
any patent rights that may be infringed by your derivative works or by
other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright © 2005 Apple Computer, Inc., All Rights Reserved
*/
#define _BSD_SOURCE
#include <math.h>
#include <stdbool.h>
#include "CGContext.h"
/*
pathForArc : Adds an arc (a segment of an oval) fitting inside a rectangle to the path.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the arc's boundary..
startAngle : The angle indicating the start of the arc.
arcAngle : The angle indicating the arcÕs extent.
*/
void pathForArc(CGContextRef context, CGRect r, int startAngle, int arcAngle)
{
float start, end;
CGAffineTransform matrix;
// Save the context's state because we are going to scale it
CGContextSaveGState(context);
// Create a transform to scale the context so that a radius of 1 maps to the bounds
// of the rectangle, and transform the origin of the context to the center of
// the bounding rectangle.
matrix = CGAffineTransformMake(r.size.width/2, 0,
0, r.size.height/2,
r.origin.x + r.size.width/2,
r.origin.y + r.size.height/2);
// Apply the transform to the context
CGContextConcatCTM(context, matrix);
// Calculate the start and ending angles
if (arcAngle > 0) {
start = (90 - startAngle - arcAngle) * M_PI / 180;
end = (90 - startAngle) * M_PI / 180;
} else {
start = (90 - startAngle) * M_PI / 180;
end = (90 - startAngle - arcAngle) * M_PI / 180;
}
// Add the Arc to the path
CGContextAddArc(context, 0, 0, 1, start, end, false);
// Restore the context's state. This removes the translation and scaling
// but leaves the path, since the path is not part of the graphics state.
CGContextRestoreGState(context);
}
/*
frameArc : Draws an arc of the oval that fits inside a rectangle.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the arc's boundary..
startAngle : The angle indicating the start of the arc.
arcAngle : The angle indicating the arcÕs extent.
*/
void frameArc(CGContextRef context, CGRect r, int startAngle, int arcAngle)
{
// Signal the start of a path
CGContextBeginPath(context);
// Add to the path the arc of the oval that fits inside the rectangle.
pathForArc(context,r,startAngle,arcAngle);
// Stroke the path
CGContextStrokePath(context);
}
/*
paintArc : Paints a wedge of the oval that fits inside a rectangle.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the arc's boundary..
startAngle : The angle indicating the start of the arc.
arcAngle : The angle indicating the arcÕs extent.
*/
void paintArc(CGContextRef context, CGRect r, int startAngle, int arcAngle)
{
float start, end;
// Signal the start of a path
CGContextBeginPath(context);
// Set the start of the path to the arcs focal point
CGContextMoveToPoint(context, r.origin.x + r.size.width/2, r.origin.y + r.size.height/2);
// Add to the path the arc of the oval that fits inside the rectangle.
pathForArc(context,r,startAngle,arcAngle);
// Complete the path closing the arc at the focal point
CGContextClosePath(context);
// Fill the path
CGContextFillPath(context);
}

153
layers.c Normal file
View File

@ -0,0 +1,153 @@
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <CGContext.h>
#include <CGLayer.h>
#define pi 3.14159265358979323846
Display *d;
Window win;
CGContextRef ctx;
extern CGContextRef opal_XWindowContextCreate(Display *d, Window w);
CGLayerRef makeSampleLayer(CGContextRef ctx){
CGRect layerBounds = CGRectMake(0,0,50, 50);
CGLayerRef layer = CGLayerCreateWithContext(ctx, layerBounds.size, NULL);
CGContextRef layerCtx = CGLayerGetContext(layer);
CGContextSetRGBFillColor(layerCtx, 1, 1, 0, 0.5);
CGContextFillRect(layerCtx, layerBounds);
CGContextSetRGBStrokeColor(layerCtx, 0, 0, 0, 0.7);
CGContextStrokeRect(layerCtx, layerBounds);
// Draw a smiley
CGContextAddArc(layerCtx, 10, 35, 4, 0, 2 * pi, 1); CGContextClosePath(layerCtx);
CGContextAddArc(layerCtx, 40, 35, 4, 0, 2 * pi, 1); CGContextClosePath(layerCtx);
CGContextAddArc(layerCtx, 12, 15, 4, 0, 2 * pi, 1);CGContextClosePath(layerCtx);
CGContextAddArc(layerCtx, 19, 10, 4, 0, 2 * pi, 1);CGContextClosePath(layerCtx);
CGContextAddArc(layerCtx, 25, 8, 4, 0, 2 * pi, 1);CGContextClosePath(layerCtx);
CGContextAddArc(layerCtx, 31, 10, 4, 0, 2 * pi, 1);CGContextClosePath(layerCtx);
CGContextAddArc(layerCtx, 38, 15, 4, 0, 2 * pi, 1);CGContextClosePath(layerCtx);
CGContextSetRGBFillColor(layerCtx, 0, 0, 0, 0.7);
CGContextFillPath(layerCtx);
CGContextSetRGBStrokeColor(layerCtx, 0, 0, 0, 1);
CGContextStrokePath(layerCtx);
return layer;
}
void draw(CGContextRef ctx, CGRect r)
{
CGContextSetRGBFillColor(ctx, 0, 0, 1, 0.5);
CGContextSetRGBStrokeColor(ctx, 0, 0, 0, 1);
CGContextFillRect(ctx, CGRectMake(10,10,r.size.width - 20, r.size.height - 20));
CGContextStrokeRect(ctx, CGRectMake(10,10,r.size.width - 20, r.size.height - 20));
// Draw some copies of a layer
CGLayerRef layer = makeSampleLayer(ctx);
// Draw some rotated faces
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 225, 125);
int i;
for (i = 0; i < 3; i++) {
CGContextRotateCTM(ctx, 0.06);
CGContextDrawLayerInRect(ctx, CGRectMake(-145,-110,290,220), layer);
}
CGContextRestoreGState(ctx);
CGContextDrawLayerInRect(ctx, CGRectMake(80,15,290,220), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(100, 170), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(300, 170), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(100, 60), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(150, 16), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(200, 10), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(250, 16), layer);
CGContextDrawLayerAtPoint(ctx, CGPointMake(300, 60), layer);
CGLayerRelease(layer);
}
int main(int argc, char **argv)
{
int ret;
CGRect cr;
XSetWindowAttributes wa;
XEvent e;
d = XOpenDisplay(NULL);
if (!d) {
fprintf(stderr,"Cannot open display: %s\n", XDisplayName(NULL));
exit(EXIT_FAILURE);
}
printf("Opened display %s\n", DisplayString(d));
cr = CGRectMake(0,0,500,250);
wa.background_pixel = WhitePixel(d, DefaultScreen(d));
wa.event_mask = ExposureMask | ButtonReleaseMask;
/* Create a window */
win = XCreateWindow(d, /* Display */
DefaultRootWindow(d), /* Parent */
cr.origin.x, cr.origin.y, /* x, y */
cr.size.width, cr.size.height, /* width, height */
0, /* border_width */
CopyFromParent, /* depth */
InputOutput, /* class */
CopyFromParent, /* visual */
CWBackPixel | CWEventMask, /* valuemask */
&wa); /* attributes */
printf("XCreateWindow returned: %lx\n", win);
/* Map the window */
ret = XMapRaised(d, win);
printf("XMapRaised returned: %x\n", ret);
/* Create a CGContext */
ctx = opal_XWindowContextCreate(d, win);
if (!ctx) {
fprintf(stderr,"Cannot create context\n");
exit(EXIT_FAILURE);
}
printf("Created context\n");
while(1)
{
XNextEvent(d,&e);
switch(e.type)
{
case Expose:
/* Dispose multiple events */
while (XCheckTypedEvent(d, Expose, &e));
/* Draw window contents */
if(e.xexpose.count == 0) {
CGContextSaveGState(ctx);
XClearWindow(d, win);
draw(ctx, cr);
CGContextRestoreGState(ctx);
}
break;
case ButtonRelease:
/* Finish program */
CGContextRelease(ctx);
XCloseDisplay(d);
exit(EXIT_SUCCESS);
break;
}
}
return(EXIT_SUCCESS);
}

83
opal-x11.c Normal file
View File

@ -0,0 +1,83 @@
/** <title>opal-x11</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 Free Software Foundation, Inc.
Author: BALATON Zoltan <balaton@eik.bme.hu>
Date: 2006
This file is part of GNUstep
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
*/
#include <stdlib.h>
#include <cairo-xlib.h>
#include <CGContext.h>
#include "opal.h"
/* Internal cairo API, declare it here to avoid dependencies of cairoint.h */
extern void _cairo_surface_set_device_scale(cairo_surface_t *surface,
double sx, double sy);
/* Keys we use to attach additional data to Xlib surfaces */
static cairo_user_data_key_t XWindow;
extern CGContextRef opal_new_CGContext(cairo_surface_t *target);
CGContextRef opal_XWindowContextCreate(Display *d, Window w)
{
CGContextRef ctx;
XWindowAttributes wa;
cairo_surface_t *target;
int ret;
ret = XGetWindowAttributes(d, w, &wa);
if (!ret) {
errlog("%s:%d: XGetWindowAttributes returned %d\n", __FILE__, __LINE__, ret);
return NULL;
}
target = cairo_xlib_surface_create(d, w, wa.visual, wa.width, wa.height);
/* May not need this but left here for reference */
ret = cairo_surface_set_user_data(target, &XWindow, (void *)w, NULL);
if (ret) {
errlog("%s:%d: cairo_surface_set_user_data %d\n",
__FILE__, __LINE__, cairo_status_to_string(CAIRO_STATUS_NO_MEMORY));
cairo_surface_destroy(target);
return NULL;
}
/* Flip coordinate system */
cairo_surface_set_device_offset(target, 0, wa.height);
/* FIXME: The scale part of device transform does not work correctly in
* cairo so for now we have to patch the CTM! This should really be fixed
* in cairo and then the ScaleCTM call below and the hacks in GetCTM in
* CGContext should be removed in favour of the following line: */
/* _cairo_surface_set_device_scale(target, 1.0, -1.0); */
ctx = opal_new_CGContext(target);
CGContextScaleCTM(ctx, 1.0, -1.0);
cairo_surface_destroy(target);
return ctx;
}
void opal_surface_flush(cairo_surface_t *target)
{
XFlush(cairo_xlib_surface_get_display(target));
}

91
opal.c Normal file
View File

@ -0,0 +1,91 @@
/** <title>opal</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 Free Software Foundation, Inc.
Author: BALATON Zoltan <balaton@eik.bme.hu>
Date: 2006
This file is part of GNUstep
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "opal.h"
extern void opal_dealloc_CGContext(void *);
extern void opal_dealloc_CGLayer(void *);
extern void opal_dealloc_CGColor(void *);
extern void opal_dealloc_CGImage(void *);
extern void opal_dealloc_CGDataProvider(void *);
static struct objbase objtypes[] = {
{"CGContext", opal_dealloc_CGContext},
{"CGLayer", opal_dealloc_CGLayer},
{"CGColor", opal_dealloc_CGColor},
{"CGImage", opal_dealloc_CGImage},
{"CGDataProvider", opal_dealloc_CGDataProvider},
{NULL}
};
void errlog(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void *opal_obj_alloc(const char *name, size_t size)
{
int typeidx;
struct objbase *obj;
for (typeidx=0; objtypes[typeidx].name; typeidx++)
if (strcmp(objtypes[typeidx].name, name) == 0) break;
if (!objtypes[typeidx].name) {
errlog("obj_alloc: Failed to create an unknown object: %s\n", name);
return NULL;
}
obj = calloc(1, size);
if (!obj) {
errlog("obj_alloc: calloc failed for %s\n", name);
return NULL;
}
*obj = objtypes[typeidx];
obj->rc = 1;
return obj;
}
void *opal_obj_retain(void *obj)
{
((struct objbase *)obj)->rc++;
return obj;
}
void opal_obj_release(void *obj)
{
struct objbase *o = obj;
if (--o->rc == 0) o->dealloc(obj);
}

46
opal.h Normal file
View File

@ -0,0 +1,46 @@
/** <title>opal</title>
<abstract>C Interface to graphics drawing library</abstract>
Copyright (C) 2006 Free Software Foundation, Inc.
Author: BALATON Zoltan <balaton@eik.bme.hu>
Date: 2006
This file is part of GNUstep
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
*/
/* This file is private for Opal and should not be included by clients! */
#ifndef OPAL_OPAL_H
#define OPAL_OPAL_H
#include <stddef.h>
struct objbase
{
char *name;
void (*dealloc)(void *);
unsigned long int rc; /* reference counter */
};
extern void errlog(const char *fmt, ...);
extern void *opal_obj_alloc(const char *name, size_t size);
extern void *opal_obj_retain(void *obj);
extern void opal_obj_release(void *obj);
#endif /* OPAL_OPAL_H */

131
ovals.c Normal file
View File

@ -0,0 +1,131 @@
/*
File: ovals.c
Abstract: // These are the functions that implement equivalents to the QuickDraw oval
// drawing APIs, FrameOval and PaintOval.
// See DrawProcs.c for sample usage
Version: 1.0
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Computer, Inc. ("Apple") in consideration of your agreement to the
following terms, and your use, installation, modification or
redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use,
install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Computer,
Inc. may be used to endorse or promote products derived from the Apple
Software without specific prior written permission from Apple. Except
as expressly stated in this notice, no other rights or licenses, express
or implied, are granted by Apple herein, including but not limited to
any patent rights that may be infringed by your derivative works or by
other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright © 2005 Apple Computer, Inc., All Rights Reserved
*/
#define _BSD_SOURCE
#include <math.h>
#include <stdbool.h>
#include "CGContext.h"
/*
addOvalToPath : Adds to the context a path for an oval just inside the bounding rectangle that you specify.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the ovalÕs boundary.
*/
void addOvalToPath(CGContextRef context, CGRect r)
{
CGAffineTransform matrix;
// Save the context's state because we are going to transform and scale it
CGContextSaveGState(context);
// Create a transform to scale the context so that a radius of 1
// is equal to the bounds of the rectangle, and transform the origin
// of the context to the center of the bounding rectangle. The
// center of the bounding rectangle will now be the center of
// the oval.
matrix = CGAffineTransformMake((r.size.width)/2, 0,
0, (r.size.height)/2,
r.origin.x + (r.size.width)/2,
r.origin.y + (r.size.height)/2);
// Apply the transform to the context
CGContextConcatCTM(context, matrix);
// Signal the start of a path
CGContextBeginPath(context);
// Add a circle to the path. After the circle is transformed by the
// context's transformation matrix, it will become an oval lying
// just inside the bounding rectangle.
CGContextAddArc(context, 0, 0, 1, 0, 2*M_PI, true);
// Restore the context's state. This removes the translation and scaling but leaves
// the path, since the path is not part of the graphics state.
CGContextRestoreGState(context);
}
/*
paintOval : Paints the interior of an oval just inside the bounding rectangle that you specify.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the ovalÕs boundary.
*/
void paintOval(CGContextRef context, CGRect r)
{
// Add a path for the oval to this context
addOvalToPath(context,r);
// Fill the oval
CGContextFillPath(context);
}
/*
frameOval : Draws an outline of an oval just inside the bounding rectangle that you specify.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the ovalÕs boundary.
*/
void frameOval(CGContextRef context, CGRect r)
{
// Add a path for the oval to this context
addOvalToPath(context,r);
// Stroke the path
CGContextStrokePath(context);
}

185
qeb2-draw.c Normal file
View File

@ -0,0 +1,185 @@
/*
File: myDraw.m
Description: Quartz 2D early bird sample from WWDC 2001
Author: DH
Copyright: © Copyright 2000 Apple Computer, Inc. All rights reserved.
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
("Apple") in consideration of your agreement to the following terms, and your
use, installation, modification or redistribution of this Apple software
constitutes acceptance of these terms. If you do not agree with these terms,
please do not use, install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and subject
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
copyrights in this original Apple software (the "Apple Software"), to use,
reproduce, modify and redistribute the Apple Software, with or without
modifications, in source and/or binary forms; provided that if you redistribute
the Apple Software in its entirety and without modifications, you must retain
this notice and the following text and disclaimers in all such redistributions of
the Apple Software. Neither the name, trademarks, service marks or logos of
Apple Computer, Inc. may be used to endorse or promote products derived from the
Apple Software without specific prior written permission from Apple. Except as
expressly stated in this notice, no other rights or licenses, express or implied,
are granted by Apple herein, including but not limited to any patent rights that
may be infringed by your derivative works or by other works in which the Apple
Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Change History (most recent first):
*/
/*
* myDraw.m
*
* Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
*
*/
#include <CGContext.h>
#include <stdlib.h>
#define kNumOfExamples 4
#define PI 3.14159265358979323846
/*
* myDraw is called whenever the view is updated.
* context - CG context to draw into
* windowRect - rectangle defining the window rectangle
*/
void drawRandomPaths(CGContextRef context, int w, int h)
{
int i;
for (i = 0; i < 20; i++) {
int numberOfSegments = rand() % 8;
int j;
float sx, sy;
CGContextBeginPath(context);
sx = rand()%w; sy = rand()%h;
CGContextMoveToPoint(context, rand()%w, rand()%h);
for (j = 0; j < numberOfSegments; j++) {
if (j % 2) {
CGContextAddLineToPoint(context, rand()%w, rand()%h);
}
else {
CGContextAddCurveToPoint(context, rand()%w, rand()%h,
rand()%w, rand()%h, rand()%h, rand()%h);
}
}
if(i % 2) {
CGContextAddCurveToPoint(context, rand()%w, rand()%h,
rand()%w, rand()%h, sx, sy);
CGContextClosePath(context);
CGContextSetRGBFillColor(context, (float)(rand()%256)/255,
(float)(rand()%256)/255, (float)(rand()%256)/255,
(float)(rand()%256)/255);
CGContextFillPath(context);
}
else {
CGContextSetLineWidth(context, (rand()%10)+2);
CGContextSetRGBStrokeColor(context, (float)(rand()%256)/255,
(float)(rand()%256)/255, (float)(rand()%256)/255,
(float)(rand()%256)/255);
CGContextStrokePath(context);
}
}
}
void myDraw(CGContextRef context, CGRect* contextRect)
{
int i;
int w, h;
static int n = 0;
w = contextRect->size.width;
h = contextRect->size.height;
switch (n) {
case 0:
// Draw random rectangles (some stroked some filled)
for (i = 0; i < 20; i++) {
if(i % 2) {
CGContextSetRGBFillColor(context, (float)(rand()%256)/255,
(float)(rand()%256)/255, (float)(rand()%256)/255,
(float)(rand()%256)/255);
CGContextFillRect(context, CGRectMake(rand()%w, rand()%h, rand()%w, rand()%h));
}
else {
CGContextSetLineWidth(context, (rand()%10)+2);
CGContextSetRGBStrokeColor(context, (float)(rand()%256)/255,
(float)(rand()%256)/255, (float)(rand()%256)/255,
(float)(rand()%256)/255);
CGContextStrokeRect(context, CGRectMake(rand()%w, rand()%h, rand()%w, rand()%h));
}
}
break;
case 1:
// Draw random circles (some stroked, some filled)
for (i = 0; i < 20; i++) {
CGContextBeginPath(context);
CGContextAddArc(context, rand()%w, rand()%h, rand()%((w>h) ? h : w), 0, 2*PI, 0);
CGContextClosePath(context);
if(i % 2) {
CGContextSetRGBFillColor(context, (float)(rand()%256)/255,
(float)(rand()%256)/255, (float)(rand()%256)/255,
(float)(rand()%256)/255);
CGContextFillPath(context);
}
else {
CGContextSetLineWidth(context, (rand()%10)+2);
CGContextSetRGBStrokeColor(context, (float)(rand()%256)/255,
(float)(rand()%256)/255, (float)(rand()%256)/255,
(float)(rand()%256)/255);
CGContextStrokePath(context);
}
}
break;
case 2:
drawRandomPaths(context, w, h);
break;
case 3:
/* Clipping example - draw random path through a circular clip */
CGContextBeginPath(context);
CGContextAddArc(context, w/2, h/2, ((w>h) ? h : w)/2, 0, 2*PI, 0);
CGContextClosePath(context);
CGContextClip(context);
// Draw something into the clip
drawRandomPaths(context, w, h);
// Draw an clip path on top as a black stroked circle.
CGContextBeginPath(context);
CGContextAddArc(context, w/2, h/2, ((w>h) ? h : w)/2, 0, 2*PI, 0);
CGContextClosePath(context);
CGContextSetLineWidth(context, 1);
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1);
CGContextStrokePath(context);
break;
default:
break;
}
n = ((n+1) % kNumOfExamples);
}

81
qeb2.c Normal file
View File

@ -0,0 +1,81 @@
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <CGContext.h>
Display *d;
Window win;
CGContextRef ctx;
extern CGContextRef opal_XWindowContextCreate(Display *d, Window w);
extern void myDraw(CGContextRef context, CGRect* contextRect);
int main(int argc, char **argv)
{
int ret;
CGRect cr;
XSetWindowAttributes wa;
XEvent e;
d = XOpenDisplay(NULL);
if (!d) {
fprintf(stderr,"Cannot open display: %s\n", XDisplayName(NULL));
exit(EXIT_FAILURE);
}
printf("Opened display %s\n", DisplayString(d));
cr = CGRectMake(0,0,545,391);
wa.background_pixel = WhitePixel(d, DefaultScreen(d));
wa.event_mask = ExposureMask | ButtonReleaseMask;
/* Create a window */
win = XCreateWindow(d, /* Display */
DefaultRootWindow(d), /* Parent */
cr.origin.x, cr.origin.y, /* x, y */
cr.size.width, cr.size.height, /* width, height */
0, /* border_width */
CopyFromParent, /* depth */
InputOutput, /* class */
CopyFromParent, /* visual */
CWBackPixel | CWEventMask, /* valuemask */
&wa); /* attributes */
printf("XCreateWindow returned: %lx\n", win);
/* Map the window */
ret = XMapRaised(d, win);
printf("XMapRaised returned: %x\n", ret);
/* Create a CGContext */
ctx = opal_XWindowContextCreate(d, win);
if (!ctx) {
fprintf(stderr,"Cannot create context\n");
exit(EXIT_FAILURE);
}
printf("Created context\n");
while(1)
{
XNextEvent(d,&e);
switch(e.type)
{
case Expose:
/* Dispose multiple events */
while (XCheckTypedEvent(d, Expose, &e));
/* Draw window contents */
if(e.xexpose.count == 0) {
CGContextSaveGState(ctx);
XClearWindow(d, win);
myDraw(ctx, &cr);
CGContextRestoreGState(ctx);
}
break;
case ButtonRelease:
/* Finish program */
CGContextRelease(ctx);
XCloseDisplay(d);
exit(EXIT_SUCCESS);
break;
}
}
}

171
rects.c Normal file
View File

@ -0,0 +1,171 @@
/*
File: rects.c
Abstract: // These are the functions that implement equivalents to the QuickDraw rect,
// drawing APIs, FrameRect, PaintRect.
// See DrawProcs.c for sample usage
Version: 1.0
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
Computer, Inc. ("Apple") in consideration of your agreement to the
following terms, and your use, installation, modification or
redistribution of this Apple software constitutes acceptance of these
terms. If you do not agree with these terms, please do not use,
install, modify or redistribute this Apple software.
In consideration of your agreement to abide by the following terms, and
subject to these terms, Apple grants you a personal, non-exclusive
license, under Apple's copyrights in this original Apple software (the
"Apple Software"), to use, reproduce, modify and redistribute the Apple
Software, with or without modifications, in source and/or binary forms;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Computer,
Inc. may be used to endorse or promote products derived from the Apple
Software without specific prior written permission from Apple. Except
as expressly stated in this notice, no other rights or licenses, express
or implied, are granted by Apple herein, including but not limited to
any patent rights that may be infringed by your derivative works or by
other works in which the Apple Software may be incorporated.
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
Copyright © 2005 Apple Computer, Inc., All Rights Reserved
*/
#include "CGContext.h"
/*
frameRect : Draws the outline of a rectangle.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the rectangle's boundary.
*/
void frameRect(CGContextRef context, CGRect r)
{
CGContextStrokeRect(context, r);
}
/*
paintRect : Paints the interior of an rectangle.
Parameter Descriptions
context : The CG context to render to.
r : The CG rectangle that defines the rectangle's boundary.
*/
void paintRect(CGContextRef context, CGRect r)
{
CGContextFillRect(context, r);
}
/*
addRoundedRectToPath : Adds a rectangle with rounded courners to the current CG path
Parameter Descriptions
rect : The CG rectangle that defines the rectangle's boundary.
ovalWidth : The width of the CG rectangle that encloses the rounded corners
ovalHeight : The height of the CG rectangle that encloses the rounded corners
context : The CG context to render to.
*/
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth,
float ovalHeight)
{
float fw, fh;
// If the width or height of the corner oval is zero, then it reduces to a right angle,
// so instead of a rounded rectangle we have an ordinary one.
if (ovalWidth == 0 || ovalHeight == 0) {
CGContextAddRect(context, rect);
return;
}
// Save the context's state so that the translate and scale can be undone with a call
// to CGContextRestoreGState.
CGContextSaveGState(context);
// Translate the origin of the contex to the lower left corner of the rectangle.
CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
//Normalize the scale of the context so that the width and height of the arcs are 1.0
CGContextScaleCTM(context, ovalWidth, ovalHeight);
// Calculate the width and height of the rectangle in the new coordinate system.
fw = CGRectGetWidth(rect) / ovalWidth;
fh = CGRectGetHeight(rect) / ovalHeight;
// CGContextAddArcToPoint adds an arc of a circle to the context's path (creating the rounded
// corners). It also adds a line from the path's last point to the begining of the arc, making
// the sides of the rectangle.
CGContextMoveToPoint(context, fw, fh/2); // Start at lower right corner
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); // Top right corner
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); // Top left corner
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); // Lower left corner
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); // Back to lower right
// Close the path
CGContextClosePath(context);
// Restore the context's state. This removes the translation and scaling
// but leaves the path, since the path is not part of the graphics state.
CGContextRestoreGState(context);
}
/*
fillRoundedRect : fills a rounded rectangle with the current fill color
Parameter Descriptions
rect : The CG rectangle that defines the rectangle's boundary.
ovalWidth : The width of the CG rectangle that encloses the rounded corners
ovalHeight : The height of the CG rectangle that encloses the rounded corners
context : The CG context to render to.
*/
void fillRoundedRect(CGContextRef context, CGRect rect, float ovalWidth, float
ovalHeight)
{
// Signal the start of a path
CGContextBeginPath(context);
// Add a rounded rect to the path
addRoundedRectToPath(context, rect, ovalWidth, ovalHeight);
// Fill the path
CGContextFillPath(context);
}
/*
strokeRoundedRect : Draws a rounded rectangle with the current stroke color
Parameter Descriptions
rect : The CG rectangle that defines the rectangle's boundary.
ovalWidth : The width of the CG rectangle that encloses the rounded corners
ovalHeight : The height of the CG rectangle that encloses the rounded corners
context : The CG context to render to.
*/
void strokeRoundedRect(CGContextRef context, CGRect rect, float ovalWidth,
float ovalHeight)
{
// Signal the start of a path
CGContextBeginPath(context);
// Add a rounded rect to the path
addRoundedRectToPath(context, rect, ovalWidth, ovalHeight);
// Stroke the path
CGContextStrokePath(context);
}

312
shapes.c Normal file
View File

@ -0,0 +1,312 @@
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <CGContext.h>
#define pi 3.14159265358979323846
Display *d;
Window win;
CGContextRef ctx;
extern CGContextRef opal_XWindowContextCreate(Display *d, Window w);
extern void frameArc(CGContextRef context, CGRect r, int startAngle, int arcAngle);
extern void paintArc(CGContextRef context, CGRect r, int startAngle, int arcAngle);
extern void frameOval(CGContextRef context, CGRect r);
extern void paintOval(CGContextRef context, CGRect r);
extern void frameRect(CGContextRef context, CGRect r);
extern void paintRect(CGContextRef context, CGRect r);
extern void fillRoundedRect(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight);
extern void strokeRoundedRect(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight);
void draw(CGContextRef ctx, CGRect r)
{
CGRect bounds = r;
double a, b;
int count, k;
CGContextSetRGBFillColor(ctx, 0, 0, 0, 1);
CGContextFillRect(ctx, CGRectMake(0, r.size.height / 2, r.size.width, r.size.height / 2));
// Use a transparency layer for the first shape
CGContextSetAlpha(ctx, 0.5);
CGContextBeginTransparencyLayer(ctx, NULL);
// Calculate the dimensions for an oval inside the bounding box
a = 0.9 * bounds.size.width/4;
b = 0.3 * bounds.size.height/2;
count = 5;
// Set the fill color to a partially transparent blue
CGContextSetRGBFillColor(ctx, 0, 0, 1, 1);
// Set the stroke color to an opaque black
CGContextSetRGBStrokeColor(ctx, 0, 0, 0, 1);
// Set the line width to be used, in user space units.
CGContextSetLineWidth(ctx, 3);
// Save the conexts state because we are going to be moving the origin and
// rotating context for drawing, but we would like to restore the current
// state before drawing the next image.
CGContextSaveGState(ctx);
// Move the origin to the middle of the first image (left side) to draw.
CGContextTranslateCTM(ctx, bounds.size.width/4, bounds.size.height/2);
// Draw "count" ovals, rotating the context around the newly translated origin
// 1/count radians after drawing each oval
for (k = 0; k < count; k++)
{
// Paint the oval with the fill color
paintOval(ctx, CGRectMake(-a, -b, 2 * a, 2 * b));
// Frame the oval with the stroke color
frameOval(ctx, CGRectMake(-a, -b, 2 * a, 2 * b));
// Rotate the context around the center of the image
CGContextRotateCTM(ctx, pi / count);
}
// Restore the saved state to a known state for dawing the next image
CGContextRestoreGState(ctx);
// End the transparency layer
CGContextEndTransparencyLayer(ctx);
// Calculate a bounding box for the rounded rect
a = 0.9 * bounds.size.width/4;
b = 0.3 * bounds.size.height/2;
count = 5;
// Set the fill color to a partially transparent red
CGContextSetRGBFillColor(ctx, 1, 0, 0, 0.5);
// Set the stroke color to an opaque black
CGContextSetRGBStrokeColor(ctx, 0, 0, 0, 1);
// Set the line width to be used, in user space units.
CGContextSetLineWidth(ctx, 3);
// Save the conexts state because we are going to be moving the origin and
// rotating context for drawing, but we would like to restore the current
// state before drawing the next image.
CGContextSaveGState(ctx);
// Move the origin to the middle of the second image (right side) to draw.
CGContextTranslateCTM(ctx, bounds.size.width/4 + bounds.size.width/2, bounds.size.height/2);
for (k = 0; k < count; k++)
{
// Fill then stroke the rounding rect, otherwise the fill would cover the stroke
fillRoundedRect(ctx, CGRectMake(-a, -b, 2 * a, 2 * b), 20, 20);
strokeRoundedRect(ctx, CGRectMake(-a, -b, 2 * a, 2 * b), 20, 20);
// Rotate the context for the next rounded rect
CGContextRotateCTM(ctx, pi / count);
}
CGContextRestoreGState(ctx);
}
int main(int argc, char **argv)
{
int ret;
CGRect cr;
XSetWindowAttributes wa;
XEvent e;
d = XOpenDisplay(NULL);
if (!d) {
fprintf(stderr,"Cannot open display: %s\n", XDisplayName(NULL));
exit(EXIT_FAILURE);
}
printf("Opened display %s\n", DisplayString(d));
cr = CGRectMake(0,0,500,250);
wa.background_pixel = WhitePixel(d, DefaultScreen(d));
wa.event_mask = ExposureMask | ButtonReleaseMask;
/* Create a window */
win = XCreateWindow(d, /* Display */
DefaultRootWindow(d), /* Parent */
cr.origin.x, cr.origin.y, /* x, y */
cr.size.width, cr.size.height, /* width, height */
0, /* border_width */
CopyFromParent, /* depth */
InputOutput, /* class */
CopyFromParent, /* visual */
CWBackPixel | CWEventMask, /* valuemask */
&wa); /* attributes */
printf("XCreateWindow returned: %lx\n", win);
/* Map the window */
ret = XMapRaised(d, win);
printf("XMapRaised returned: %x\n", ret);
/* Create a CGContext */
ctx = opal_XWindowContextCreate(d, win);
if (!ctx) {
fprintf(stderr,"Cannot create context\n");
exit(EXIT_FAILURE);
}
printf("Created context\n");
/* Flip coordinate system to match Quickdraw */
CGContextTranslateCTM(ctx, 0, cr.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
#if 0
/* Draw something */
// Draw the outer arcs in the left portion of the window
r.size.height = 210;
r.origin.x = 20;
r.origin.y = 20;
r.size.width = 210;
frameArc(ctx, r, 0, 135);
frameArc(ctx, r, 180 - 10, 20);
frameArc(ctx, r, 225, 45);
frameArc(ctx, r, 315 - 20, 40);
// Draw the inner arcs in the left portion of the window
r.size.height = 145;
r.origin.x = 75;
r.origin.y = 55;
r.size.width = 100;
frameArc(ctx, r, 0, 135);
frameArc(ctx, r, 180 - 10, 20);
frameArc(ctx, r, 225, 45);
frameArc(ctx, r, 315 - 20, 40);
/* Set the fill color to green. */
CGContextSetRGBFillColor(ctx, 0, 1, 0, 1);
// Draw and fill the outer arcs in the right portion of the window
r.size.height = 210;
r.origin.x = 270;
r.origin.y = 20;
r.size.width = 210;
paintArc(ctx, r, 0, 135);
paintArc(ctx, r, 180 - 10, 20);
paintArc(ctx, r, 225, 45);
paintArc(ctx, r, 315 - 20, 40);
/* Set the fill color to yellow. */
CGContextSetRGBFillColor(ctx, 1, 1, 0, 1);
// Draw and fill the inner arcs in the right portion of the window
r.size.height = 145;
r.origin.x = 325;
r.origin.y = 55;
r.size.width = 100;
paintArc(ctx, r, 0, 135);
paintArc(ctx, r, 180 - 10, 20);
paintArc(ctx, r, 225, 45);
paintArc(ctx, r, 315 - 20, 40);
CGContextFlush(ctx);
getchar();
XClearWindow(d, win);
// Draw the outer oval in the left portion of the window
r.size.height = 210;
r.origin.x = 20;
r.origin.y = 20;
r.size.width = 210;
frameOval(ctx, r);
// Draw the inner oval in the left portion of the window
r.size.height = 145;
r.origin.x = 75;
r.origin.y = 55;
r.size.width = 100;
frameOval(ctx, r);
/* Set the fill color to green. */
CGContextSetRGBFillColor(ctx, 0, 1, 0, 1);
// Draw and fill the outter oval in the right portion of the window
r.size.height = 210;
r.origin.x = 270;
r.origin.y = 20;
r.size.width = 210;
paintOval(ctx, r);
/* Set the fill color to yellow. */
CGContextSetRGBFillColor(ctx, 1, 1, 0, 1);
// Draw and fill the inner oval in the right portion of the window
r.size.height = 145;
r.origin.x = 325;
r.origin.y = 55;
r.size.width = 100;
paintOval(ctx, r);
CGContextFlush(ctx);
getchar();
XClearWindow(d, win);
/* Set the stroke color to black. */
CGContextSetRGBStrokeColor(ctx, 0, 0, 0, 1);
r.size.height = 210;
r.origin.x = 20;
r.origin.y = 20;
r.size.width = 210;
frameRect(ctx, r);
r.size.height = 145;
r.origin.x = 75;
r.origin.y = 55;
r.size.width = 100;
frameRect(ctx, r);
/* Set the fill color to green. */
CGContextSetRGBFillColor(ctx, 0, 1, 0, 1);
r.size.height = 210;
r.origin.x = 270;
r.origin.y = 20;
r.size.width = 210;
paintRect(ctx, r);
/* Set the fill color to yellow. */
CGContextSetRGBFillColor(ctx, 1, 1, 0, 1);
r.size.height = 145;
r.origin.x = 325;
r.origin.y = 55;
r.size.width = 100;
paintRect(ctx, r);
CGContextFlush(ctx);
getchar();
#endif
while(1)
{
XNextEvent(d,&e);
switch(e.type)
{
case Expose:
/* Dispose multiple events */
while (XCheckTypedEvent(d, Expose, &e));
/* Draw window contents */
if(e.xexpose.count == 0) {
CGContextSaveGState(ctx);
XClearWindow(d, win);
draw(ctx, cr);
CGContextRestoreGState(ctx);
}
break;
case ButtonRelease:
/* Finish program */
CGContextRelease(ctx);
XCloseDisplay(d);
exit(EXIT_SUCCESS);
break;
}
}
return(EXIT_SUCCESS);
}

106
texttest.c Normal file
View File

@ -0,0 +1,106 @@
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <CGContext.h>
Display *d;
Window win;
CGContextRef ctx;
static const char *fontName = "Times-Roman";
extern CGContextRef opal_XWindowContextCreate(Display *d, Window w);
void drawRect(CGContextRef currentContext, CGRect rect)
{
CGRect pageRect = CGRectMake( 0, 0, rect.size.width, rect.size.height );
CGContextBeginPage(currentContext, &pageRect);
CGContextSetGrayFillColor(currentContext, 0, 1);
CGContextSelectFont(currentContext, fontName, 1, kCGEncodingMacRoman);
CGContextShowTextAtPoint(currentContext, 40, 200, "1: M x", 6);
CGContextSelectFont(currentContext, fontName, 2, kCGEncodingMacRoman);
CGContextShowTextAtPoint(currentContext, 40, 150, "2: M x", 6);
CGContextSelectFont(currentContext, fontName, 3, kCGEncodingMacRoman);
CGContextShowTextAtPoint(currentContext, 40, 100, "3: M x", 6);
CGContextSelectFont(currentContext, fontName, 4, kCGEncodingMacRoman);
CGContextShowTextAtPoint(currentContext, 40, 50, "4: M x", 6);
CGContextEndPage(currentContext);
CGContextFlush(currentContext);
}
int main(int argc, char **argv)
{
int ret;
CGRect cr;
XSetWindowAttributes wa;
XEvent e;
d = XOpenDisplay(NULL);
if (!d) {
fprintf(stderr,"Cannot open display: %s\n", XDisplayName(NULL));
exit(EXIT_FAILURE);
}
printf("Opened display %s\n", DisplayString(d));
if (argc > 1)
{
fontName = argv[1];
}
cr = CGRectMake(0,0,480,360);
wa.background_pixel = WhitePixel(d, DefaultScreen(d));
wa.event_mask = ExposureMask | ButtonReleaseMask;
/* Create a window */
win = XCreateWindow(d, /* Display */
DefaultRootWindow(d), /* Parent */
cr.origin.x, cr.origin.y, /* x, y */
cr.size.width, cr.size.height, /* width, height */
0, /* border_width */
CopyFromParent, /* depth */
InputOutput, /* class */
CopyFromParent, /* visual */
CWBackPixel | CWEventMask, /* valuemask */
&wa); /* attributes */
printf("XCreateSimpleWindow returned: %lx\n", win);
/* Map the window */
ret = XMapRaised(d, win);
printf("XMapRaised returned: %x\n", ret);
/* Create a CGContext */
ctx = opal_XWindowContextCreate(d, win);
if (!ctx) {
fprintf(stderr,"Cannot create context\n");
exit(EXIT_FAILURE);
}
printf("Created context\n");
while(1)
{
XNextEvent(d,&e);
switch(e.type)
{
case Expose:
/* Draw window contents */
if(e.xexpose.count == 0) {
XClearWindow(d, win);
drawRect(ctx, cr);
}
break;
case ButtonRelease:
/* Finish program */
CGContextRelease(ctx);
XCloseDisplay(d);
exit(EXIT_SUCCESS);
break;
}
}
}