mirror of
https://github.com/darlinghq/darling-coregraphics.git
synced 2024-11-23 04:09:42 +00:00
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:
commit
cabbe42812
64
CGAffineTransform.c
Normal file
64
CGAffineTransform.c
Normal 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
216
CGAffineTransform.h
Normal 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
36
CGBase.h
Normal 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
57
CGBitmapContext.h
Normal 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
109
CGColor.c
Normal 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
60
CGColor.h
Normal 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
116
CGColorSpace.c
Normal 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
101
CGColorSpace.h
Normal 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
53
CGContext-private.h
Normal 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
838
CGContext.c
Normal 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
428
CGContext.h
Normal 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
62
CGDataConsumer.h
Normal 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
45
CGDataProvider-private.h
Normal 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
177
CGDataProvider.c
Normal 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
109
CGDataProvider.h
Normal 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
212
CGFont.c
Normal 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
49
CGFont.h
Normal 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
60
CGFunction.h
Normal 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
208
CGGeometry.c
Normal 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
350
CGGeometry.h
Normal 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
279
CGImage.c
Normal 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
100
CGImage.h
Normal 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
153
CGLayer.c
Normal 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
60
CGLayer.h
Normal 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
35
CGPDFContext.h
Normal 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
70
CGPDFDocument.h
Normal 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
183
CGPath.h
Normal 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
67
CGPattern.h
Normal 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
57
CGShading.h
Normal 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
515
COPYING
Normal 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
33
CoreFoundation.h
Normal 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
59
Makefile
Normal 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
24
README
Normal 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
28
TODO
Normal 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
155
arcs.c
Normal 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
153
layers.c
Normal 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
83
opal-x11.c
Normal 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
91
opal.c
Normal 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
46
opal.h
Normal 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
131
ovals.c
Normal 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
185
qeb2-draw.c
Normal 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
81
qeb2.c
Normal 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
171
rects.c
Normal 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
312
shapes.c
Normal 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
106
texttest.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user