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