2006-09-30 12:21:13 +00:00
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
/*
|
|
|
|
* CairoGState.m
|
|
|
|
|
|
|
|
* Copyright (C) 2003 Free Software Foundation, Inc.
|
|
|
|
* August 31, 2003
|
|
|
|
* Written by Banlu Kemiyatorn <object at gmail dot com>
|
2006-02-12 17:59:30 +00:00
|
|
|
* Rewrite: Fred Kiefer <fredkiefer@gmx.de>
|
|
|
|
* Date: Jan 2006
|
|
|
|
*
|
2004-08-02 21:50:17 +00:00
|
|
|
* 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
|
2005-05-26 22:51:53 +00:00
|
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
|
2004-08-02 21:50:17 +00:00
|
|
|
*/
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
#include <AppKit/NSAffineTransform.h>
|
2004-08-02 21:50:17 +00:00
|
|
|
#include <AppKit/NSBezierPath.h>
|
|
|
|
#include <AppKit/NSColor.h>
|
2004-09-08 22:08:15 +00:00
|
|
|
#include <AppKit/NSGraphics.h>
|
2004-08-02 21:50:17 +00:00
|
|
|
#include "cairo/CairoGState.h"
|
|
|
|
#include "cairo/CairoFontInfo.h"
|
|
|
|
#include "cairo/CairoSurface.h"
|
|
|
|
#include "cairo/CairoContext.h"
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#define FIXME() NSLog(@":::FIXME::: %@ %s", [self description], sel_get_name(_cmd))
|
|
|
|
|
|
|
|
@implementation CairoGState
|
|
|
|
|
|
|
|
+ (void) initialize
|
|
|
|
{
|
2004-08-23 12:28:16 +00:00
|
|
|
if (self == [CairoGState class])
|
|
|
|
{
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
- (void) dealloc
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
if (_ct)
|
|
|
|
{
|
|
|
|
cairo_destroy(_ct);
|
|
|
|
}
|
|
|
|
RELEASE(_surface);
|
|
|
|
|
|
|
|
[super dealloc];
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id) copyWithZone: (NSZone *)zone
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
CairoGState *copy = (CairoGState *)[super copyWithZone: zone];
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
if (_ct)
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_path_t *cpath;
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_status_t status;
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
2005-07-27 23:25:32 +00:00
|
|
|
|
|
|
|
// FIXME: Need some way to do a copy
|
|
|
|
//cairo_copy(copy->_ct, _ct);
|
|
|
|
copy->_ct = cairo_create(cairo_get_target(_ct));
|
|
|
|
cairo_get_matrix(_ct, &local_matrix);
|
|
|
|
cairo_set_matrix(copy->_ct, &local_matrix);
|
2006-10-03 23:29:53 +00:00
|
|
|
cpath = cairo_copy_path(_ct);
|
|
|
|
cairo_append_path(copy->_ct, cpath);
|
|
|
|
cairo_path_destroy(cpath);
|
2006-02-13 00:07:40 +00:00
|
|
|
|
|
|
|
cairo_set_operator(copy->_ct, cairo_get_operator(_ct));
|
|
|
|
cairo_set_source(copy->_ct, cairo_get_source(_ct));
|
|
|
|
cairo_set_tolerance(copy->_ct, cairo_get_tolerance(_ct));
|
|
|
|
cairo_set_antialias(copy->_ct, cairo_get_antialias(_ct));
|
|
|
|
cairo_set_line_width(copy->_ct, cairo_get_line_width(_ct));
|
|
|
|
cairo_set_line_cap(copy->_ct, cairo_get_line_cap(_ct));
|
|
|
|
cairo_set_line_join(copy->_ct, cairo_get_line_join(_ct));
|
|
|
|
cairo_set_miter_limit(copy->_ct, cairo_get_miter_limit(_ct));
|
2005-07-27 23:25:32 +00:00
|
|
|
//NSLog(@"copy gstate old %d new %d", _ct, copy->_ct);
|
|
|
|
|
|
|
|
status = cairo_status(copy->_ct);
|
|
|
|
if (status != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
NSLog(@"Cairo status %s in copy", cairo_status_to_string(status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
RETAIN(_surface);
|
|
|
|
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) GSCurrentDevice: (void **)device: (int *)x : (int *)y
|
|
|
|
{
|
|
|
|
if (x)
|
2006-10-03 23:29:53 +00:00
|
|
|
*x = offset.x;
|
2004-08-02 21:50:17 +00:00
|
|
|
if (y)
|
2006-10-03 23:29:53 +00:00
|
|
|
*y = offset.y;
|
2004-08-02 21:50:17 +00:00
|
|
|
if (device)
|
|
|
|
{
|
|
|
|
if (_surface)
|
|
|
|
{
|
|
|
|
*device = _surface->gsDevice;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*device = NULL;
|
|
|
|
NSLog(@":::FIXME::: surface isn't set. %@ %s", [self description],
|
|
|
|
sel_get_name(_cmd));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) GSSetDevice: (void *)device : (int)x : (int)y
|
|
|
|
{
|
2005-08-28 00:48:12 +00:00
|
|
|
DESTROY(_surface);
|
|
|
|
_surface = [[CairoSurface alloc] initWithDevice: device];
|
2006-10-03 23:29:53 +00:00
|
|
|
[self setOffset: NSMakePoint(x, y)];
|
2005-07-27 23:25:32 +00:00
|
|
|
[self DPSinitgraphics];
|
2004-08-23 12:28:16 +00:00
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Color operations
|
|
|
|
*/
|
2006-10-03 23:29:53 +00:00
|
|
|
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
device_color_t c;
|
2006-09-30 12:21:13 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
[super setColor: color state: cState];
|
|
|
|
if (_ct == NULL)
|
2006-09-30 12:21:13 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
/* Window device isn't set yet */
|
|
|
|
return;
|
2006-09-30 12:21:13 +00:00
|
|
|
}
|
2006-10-03 23:29:53 +00:00
|
|
|
c = *color;
|
|
|
|
gsColorToRGB(&c);
|
|
|
|
// FIXME: The underlying concept does not allow to determine if alpha is set or not.
|
|
|
|
if (c.field[AINDEX] > 0.0)
|
2006-09-30 12:21:13 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_set_source_rgba(_ct, c.field[0], c.field[1], c.field[2],
|
|
|
|
c.field[AINDEX]);
|
2006-09-30 12:21:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_set_source_rgb(_ct, c.field[0], c.field[1], c.field[2]);
|
2006-09-30 12:21:13 +00:00
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
/*
|
2004-08-02 21:50:17 +00:00
|
|
|
- (void) DPSsetalpha: (float)a
|
|
|
|
{
|
2006-02-12 17:59:30 +00:00
|
|
|
float r, g, b;
|
2005-07-27 23:25:32 +00:00
|
|
|
|
2006-09-30 12:21:13 +00:00
|
|
|
[self DPScurrentrgbcolor: &r: &g: &b];
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_set_source_rgba(_ct, r, g, b, a);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
2006-10-03 23:29:53 +00:00
|
|
|
*/
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Text operations
|
|
|
|
*/
|
|
|
|
|
|
|
|
- (void) DPScharpath: (const char *)s : (int)b
|
|
|
|
{
|
|
|
|
char *c = malloc(b + 1);
|
|
|
|
|
|
|
|
memcpy(c, s, b);
|
2006-10-03 23:29:53 +00:00
|
|
|
c[b] = 0;
|
2004-08-02 21:50:17 +00:00
|
|
|
cairo_text_path(_ct, c);
|
2005-08-28 00:48:12 +00:00
|
|
|
free(c);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSshow: (const char *)s
|
|
|
|
{
|
|
|
|
cairo_show_text(_ct, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) GSSetFont: (GSFontInfo *)fontref
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
[super GSSetFont: fontref];
|
|
|
|
{
|
|
|
|
cairo_matrix_t font_matrix;
|
|
|
|
const float *matrix;
|
|
|
|
|
|
|
|
matrix = [font matrix];
|
|
|
|
cairo_set_font_face(_ct, [((CairoFontInfo *)font)->_faceInfo fontFace]);
|
|
|
|
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
|
|
|
|
-matrix[3], matrix[4], matrix[5]);
|
|
|
|
cairo_set_font_matrix(_ct, &font_matrix);
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) GSSetFontSize: (float)size
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_font_size(_ct, size);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) GSShowText: (const char *)string : (size_t)length
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
char *c = malloc(length + 1);
|
|
|
|
|
|
|
|
memcpy(c, string, length);
|
|
|
|
c[length] = 0;
|
|
|
|
cairo_show_text(_ct, c);
|
|
|
|
free(c);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) GSShowGlyphs: (const NSGlyph *)glyphs : (size_t)length
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
[(CairoFontInfo *)font drawGlyphs: glyphs
|
|
|
|
length: length
|
|
|
|
on: _ct];
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* GState operations
|
|
|
|
*/
|
|
|
|
|
|
|
|
- (void) DPSinitgraphics
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_status_t status;
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
[super DPSinitgraphics];
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
if (_ct)
|
|
|
|
{
|
|
|
|
cairo_destroy(_ct);
|
|
|
|
}
|
2005-07-27 23:25:32 +00:00
|
|
|
if (!_surface)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_ct = cairo_create([_surface surface]);
|
|
|
|
status = cairo_status(_ct);
|
|
|
|
if (status != CAIRO_STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
NSLog(@"Cairo status %s in DPSinitgraphics", cairo_status_to_string(status));
|
|
|
|
}
|
2006-10-03 23:29:53 +00:00
|
|
|
[self DPSinitmatrix];
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
/* Cairo's default line width is 2.0 */
|
2004-08-02 21:50:17 +00:00
|
|
|
cairo_set_line_width(_ct, 1.0);
|
2006-02-13 00:07:40 +00:00
|
|
|
cairo_set_operator(_ct, CAIRO_OPERATOR_OVER);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurrentflat: (float *)flatness
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
*flatness = cairo_get_tolerance(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurrentlinecap: (int *)linecap
|
|
|
|
{
|
|
|
|
cairo_line_cap_t lc;
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
lc = cairo_get_line_cap(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
*linecap = lc;
|
|
|
|
/*
|
|
|
|
switch (lc)
|
|
|
|
{
|
|
|
|
case CAIRO_LINE_CAP_BUTT:
|
|
|
|
*linecap = 0;
|
|
|
|
break;
|
|
|
|
case CAIRO_LINE_CAP_ROUND:
|
|
|
|
*linecap = 1;
|
|
|
|
break;
|
|
|
|
case CAIRO_LINE_CAP_SQUARE:
|
|
|
|
*linecap = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
NSLog(@"ERROR Line cap unknown");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurrentlinejoin: (int *)linejoin
|
|
|
|
{
|
|
|
|
cairo_line_join_t lj;
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
lj = cairo_get_line_join(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
*linejoin = lj;
|
|
|
|
/*
|
|
|
|
switch (lj)
|
|
|
|
{
|
|
|
|
case CAIRO_LINE_JOIN_MITER:
|
|
|
|
*linejoin = 0;
|
|
|
|
break;
|
|
|
|
case CAIRO_LINE_JOIN_ROUND:
|
|
|
|
*linejoin = 1;
|
|
|
|
break;
|
|
|
|
case CAIRO_LINE_JOIN_BEVEL:
|
|
|
|
*linejoin = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
NSLog(@"ERROR Line join unknown");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurrentlinewidth: (float *)width
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
*width = cairo_get_line_width(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurrentmiterlimit: (float *)limit
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
*limit = cairo_get_miter_limit(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
- (NSPoint) currentPoint
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
double dx, dy;
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_get_current_point(_ct, &dx, &dy);
|
2006-10-03 23:29:53 +00:00
|
|
|
return NSMakePoint(dx, dy);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurrentstrokeadjust: (int *)b
|
|
|
|
{
|
|
|
|
FIXME();
|
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
- (void) DPSsetdash: (const float *)pat : (int)size : (float)doffset
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
double *dpat;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = size;
|
|
|
|
dpat = malloc(sizeof(double) * size);
|
|
|
|
while (i)
|
|
|
|
{
|
|
|
|
i--;
|
|
|
|
dpat[i] = pat[i];
|
|
|
|
}
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_set_dash(_ct, dpat, size, doffset);
|
2004-08-02 21:50:17 +00:00
|
|
|
free(dpat);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSsetflat: (float)flatness
|
|
|
|
{
|
|
|
|
cairo_set_tolerance(_ct, flatness);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSsetlinecap: (int)linecap
|
|
|
|
{
|
|
|
|
cairo_set_line_cap(_ct, (cairo_line_cap_t)linecap);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSsetlinejoin: (int)linejoin
|
|
|
|
{
|
|
|
|
cairo_set_line_join(_ct, (cairo_line_join_t)linejoin);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSsetlinewidth: (float)width
|
|
|
|
{
|
|
|
|
cairo_set_line_width(_ct, width);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSsetmiterlimit: (float)limit
|
|
|
|
{
|
|
|
|
cairo_set_miter_limit(_ct, limit);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSsetstrokeadjust: (int)b
|
|
|
|
{
|
|
|
|
FIXME();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Matrix operations
|
|
|
|
*/
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
// FIXME: All matrix and path operations need to call the super implemantion
|
|
|
|
// to get the complex methods of the super class to work correctly.
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
- (void) DPSconcat: (const float *)m
|
|
|
|
{
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_matrix_init(&local_matrix, m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
|
|
cairo_transform(_ct, &local_matrix);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSinitmatrix
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_identity_matrix(_ct);
|
2006-10-03 23:29:53 +00:00
|
|
|
if (!viewIsFlipped)
|
|
|
|
{
|
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
|
|
|
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
|
|
|
|
|
|
|
if (_surface != nil)
|
|
|
|
{
|
|
|
|
cairo_matrix_translate(&local_matrix, -offset.x, -offset.y);
|
|
|
|
}
|
|
|
|
cairo_set_matrix(_ct, &local_matrix);
|
|
|
|
}
|
|
|
|
else if (_surface != nil)
|
2006-03-07 00:59:30 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
|
|
|
cairo_matrix_init_translate(&local_matrix, -offset.x,
|
|
|
|
offset.y - [_surface size].height);
|
|
|
|
cairo_set_matrix(_ct, &local_matrix);
|
2006-03-07 00:59:30 +00:00
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrotate: (float)angle
|
|
|
|
{
|
|
|
|
cairo_rotate(_ct, angle);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSscale: (float)x : (float)y
|
|
|
|
{
|
|
|
|
cairo_scale(_ct, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPStranslate: (float)x : (float)y
|
|
|
|
{
|
|
|
|
cairo_translate(_ct, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSAffineTransform *) GSCurrentCTM
|
|
|
|
{
|
|
|
|
NSAffineTransform *transform;
|
|
|
|
NSAffineTransformStruct tstruct;
|
2005-11-07 00:11:09 +00:00
|
|
|
cairo_matrix_t flip_matrix;
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
transform = [NSAffineTransform transform];
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_get_matrix(_ct, &local_matrix);
|
2005-11-07 00:11:09 +00:00
|
|
|
/*
|
|
|
|
NSLog(@"Before flip %f %f, %f, %f, %f, %f", local_matrix.xx, local_matrix.yx,
|
|
|
|
local_matrix.xy, local_matrix.yy, local_matrix.x0, local_matrix.y0);
|
|
|
|
*/
|
2006-10-03 23:29:53 +00:00
|
|
|
if (!viewIsFlipped)
|
2006-03-07 00:59:30 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
if (_surface)
|
|
|
|
{
|
|
|
|
cairo_matrix_init_translate(&flip_matrix, 0, -[_surface size].height);
|
|
|
|
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
|
|
|
|
}
|
|
|
|
cairo_matrix_init_scale(&flip_matrix, 1, -1);
|
|
|
|
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
|
2006-03-07 00:59:30 +00:00
|
|
|
}
|
2005-11-07 00:11:09 +00:00
|
|
|
/*
|
|
|
|
NSLog(@"After flip %f %f, %f, %f, %f, %f", local_matrix.xx, local_matrix.yx,
|
|
|
|
local_matrix.xy, local_matrix.yy, local_matrix.x0, local_matrix.y0);
|
|
|
|
*/
|
2005-07-27 23:25:32 +00:00
|
|
|
tstruct.m11 = local_matrix.xx;
|
|
|
|
tstruct.m12 = local_matrix.yx;
|
|
|
|
tstruct.m21 = local_matrix.xy;
|
|
|
|
tstruct.m22 = local_matrix.yy;
|
|
|
|
tstruct.tX = local_matrix.x0;
|
|
|
|
tstruct.tY = local_matrix.y0;
|
2004-08-02 21:50:17 +00:00
|
|
|
[transform setTransformStruct:tstruct];
|
|
|
|
return transform;
|
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
- (void) GSSetCTM: (NSAffineTransform *)newCtm
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
[self DPSinitmatrix];
|
|
|
|
[self GSConcatCTM: newCtm];
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
- (void) GSConcatCTM: (NSAffineTransform *)newCtm
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
NSAffineTransformStruct tstruct;
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
tstruct = [newCtm transformStruct];
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_matrix_init(&local_matrix,
|
|
|
|
tstruct.m11, tstruct.m12,
|
|
|
|
tstruct.m21, tstruct.m22,
|
|
|
|
tstruct.tX, tstruct.tY);
|
|
|
|
cairo_transform(_ct, &local_matrix);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Paint operations
|
|
|
|
*/
|
|
|
|
|
|
|
|
- (void) DPSarc: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
|
|
|
|
{
|
|
|
|
cairo_arc(_ct, x, y, r, angle1 * M_PI / 180, angle2 * M_PI / 180);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSarcn: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
|
|
|
|
{
|
|
|
|
cairo_arc_negative(_ct, x, y, r, angle1 * M_PI / 180, angle2 * M_PI / 180);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSclip
|
|
|
|
{
|
|
|
|
cairo_clip(_ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSclosepath
|
|
|
|
{
|
|
|
|
cairo_close_path(_ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPScurveto: (float)x1 : (float)y1 : (float)x2
|
|
|
|
: (float)y2 : (float)x3 : (float)y3
|
|
|
|
{
|
|
|
|
cairo_curve_to(_ct, x1, y1, x2, y2, x3, y3);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSeoclip
|
|
|
|
{
|
|
|
|
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
|
|
|
|
cairo_clip(_ct);
|
|
|
|
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_WINDING);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSeofill
|
|
|
|
{
|
|
|
|
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
|
|
|
|
cairo_fill(_ct);
|
|
|
|
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_WINDING);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSfill
|
|
|
|
{
|
|
|
|
cairo_fill(_ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSflattenpath
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_path_t *cpath;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cpath = cairo_copy_path_flat(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
cairo_new_path(_ct);
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_append_path(_ct, cpath);
|
|
|
|
cairo_path_destroy(cpath);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSinitclip
|
|
|
|
{
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_reset_clip(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSlineto: (float)x : (float)y
|
|
|
|
{
|
|
|
|
cairo_line_to(_ct, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSmoveto: (float)x : (float)y
|
|
|
|
{
|
|
|
|
cairo_move_to(_ct, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSnewpath
|
|
|
|
{
|
|
|
|
cairo_new_path(_ct);
|
|
|
|
}
|
|
|
|
|
2006-03-12 21:50:17 +00:00
|
|
|
- (NSBezierPath *) bezierPath
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
cairo_path_t *cpath;
|
|
|
|
cairo_path_data_t *data;
|
2006-10-03 23:29:53 +00:00
|
|
|
NSBezierPath *bpath =[NSBezierPath bezierPath];
|
2006-03-12 21:50:17 +00:00
|
|
|
|
|
|
|
cpath = cairo_copy_path(_ct);
|
|
|
|
|
|
|
|
for (i=0; i < cpath->num_data; i += cpath->data[i].header.length)
|
|
|
|
{
|
|
|
|
data = &cpath->data[i];
|
|
|
|
switch (data->header.type)
|
|
|
|
{
|
|
|
|
case CAIRO_PATH_MOVE_TO:
|
2006-10-03 23:29:53 +00:00
|
|
|
[bpath moveToPoint: NSMakePoint(data[1].point.x, data[1].point.y)];
|
2006-03-12 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case CAIRO_PATH_LINE_TO:
|
2006-10-03 23:29:53 +00:00
|
|
|
[bpath lineToPoint: NSMakePoint(data[1].point.x, data[1].point.y)];
|
2006-03-12 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case CAIRO_PATH_CURVE_TO:
|
2006-10-03 23:29:53 +00:00
|
|
|
[bpath curveToPoint: NSMakePoint(data[1].point.x, data[1].point.y)
|
|
|
|
controlPoint1: NSMakePoint(data[2].point.x, data[2].point.y)
|
|
|
|
controlPoint2: NSMakePoint(data[3].point.x, data[3].point.y)];
|
2006-03-12 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case CAIRO_PATH_CLOSE_PATH:
|
2006-10-03 23:29:53 +00:00
|
|
|
[bpath closePath];
|
2006-03-12 21:50:17 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cairo_path_destroy(cpath);
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
return bpath;
|
2006-03-12 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
- (void) DPSpathbbox: (float *)llx : (float *)lly : (float *)urx : (float *)ury
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
NSBezierPath *bpath = [self bezierPath];
|
|
|
|
NSRect rect = [bpath controlPointBounds];
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
if (llx)
|
|
|
|
*llx = NSMinX(rect);
|
|
|
|
if (lly)
|
|
|
|
*lly = NSMinY(rect);
|
|
|
|
if (urx)
|
|
|
|
*urx = NSMaxX(rect);
|
|
|
|
if (ury)
|
|
|
|
*ury = NSMaxY(rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrcurveto: (float)x1 : (float)y1 : (float)x2
|
|
|
|
: (float)y2 : (float)x3 : (float)y3
|
|
|
|
{
|
|
|
|
cairo_rel_curve_to(_ct, x1, y1, x2, y2, x3, y3);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrectclip: (float)x : (float)y : (float)w : (float)h
|
|
|
|
{
|
|
|
|
cairo_new_path(_ct);
|
|
|
|
cairo_move_to(_ct, x, y);
|
|
|
|
cairo_rel_line_to(_ct, w, 0);
|
|
|
|
cairo_rel_line_to(_ct, 0, h);
|
|
|
|
cairo_rel_line_to(_ct, -w, 0);
|
|
|
|
cairo_close_path(_ct);
|
|
|
|
cairo_clip(_ct);
|
|
|
|
cairo_new_path(_ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrectfill: (float)x : (float)y : (float)w : (float)h
|
|
|
|
{
|
|
|
|
cairo_save(_ct);
|
|
|
|
cairo_new_path(_ct);
|
|
|
|
cairo_move_to(_ct, x, y);
|
|
|
|
cairo_rel_line_to(_ct, w, 0);
|
|
|
|
cairo_rel_line_to(_ct, 0, h);
|
|
|
|
cairo_rel_line_to(_ct, -w, 0);
|
|
|
|
cairo_close_path(_ct);
|
|
|
|
cairo_fill(_ct);
|
|
|
|
cairo_restore(_ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrectstroke: (float)x : (float)y : (float)w : (float)h
|
|
|
|
{
|
|
|
|
cairo_save(_ct);
|
|
|
|
cairo_new_path(_ct);
|
|
|
|
cairo_move_to(_ct, x, y);
|
|
|
|
cairo_rel_line_to(_ct, w, 0);
|
|
|
|
cairo_rel_line_to(_ct, 0, h);
|
|
|
|
cairo_rel_line_to(_ct, -w, 0);
|
|
|
|
cairo_close_path(_ct);
|
|
|
|
cairo_stroke(_ct);
|
|
|
|
cairo_restore(_ct);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSreversepath
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
NSBezierPath *bpath = [self bezierPath];
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
bpath = [bpath bezierPathByReversingPath];
|
|
|
|
[self GSSendBezierPath: bpath];
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrlineto: (float)x : (float)y
|
|
|
|
{
|
|
|
|
cairo_rel_line_to(_ct, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSrmoveto: (float)x : (float)y
|
|
|
|
{
|
|
|
|
cairo_rel_move_to(_ct, x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSstroke
|
|
|
|
{
|
|
|
|
cairo_stroke(_ct);
|
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
- (void) GSSendBezierPath: (NSBezierPath *)bpath
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
2006-03-12 21:50:17 +00:00
|
|
|
int i, n;
|
|
|
|
int count = 10;
|
|
|
|
float dash_pattern[10];
|
|
|
|
float phase;
|
|
|
|
NSPoint pts[3];
|
|
|
|
NSBezierPathElement e;
|
|
|
|
SEL elmsel = @selector(elementAtIndex: associatedPoints:);
|
2006-10-03 23:29:53 +00:00
|
|
|
IMP elmidx = [bpath methodForSelector: elmsel];
|
2006-03-12 21:50:17 +00:00
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
cairo_new_path(_ct);
|
2006-03-12 21:50:17 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
n = [bpath elementCount];
|
2006-03-12 21:50:17 +00:00
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
e = (NSBezierPathElement)(*elmidx)(bpath, elmsel, i, pts);
|
2006-03-12 21:50:17 +00:00
|
|
|
switch (e)
|
|
|
|
{
|
|
|
|
case NSMoveToBezierPathElement:
|
|
|
|
cairo_move_to(_ct, pts[0].x, pts[0].y);
|
|
|
|
break;
|
|
|
|
case NSLineToBezierPathElement:
|
|
|
|
cairo_line_to(_ct, pts[0].x, pts[0].y);
|
|
|
|
break;
|
|
|
|
case NSCurveToBezierPathElement:
|
|
|
|
cairo_curve_to(_ct, pts[0].x, pts[0].y, pts[1].x, pts[1].y,
|
|
|
|
pts[2].x, pts[2].y);
|
|
|
|
break;
|
|
|
|
case NSClosePathBezierPathElement:
|
|
|
|
cairo_close_path(_ct);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_set_line_width(_ct, [bpath lineWidth]);
|
|
|
|
cairo_set_line_join(_ct, (cairo_line_join_t)[bpath lineJoinStyle]);
|
|
|
|
cairo_set_line_cap(_ct, (cairo_line_cap_t)[bpath lineCapStyle]);
|
|
|
|
cairo_set_miter_limit(_ct, [bpath miterLimit]);
|
2006-03-12 21:50:17 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
[bpath getLineDash: dash_pattern count: &count phase: &phase];
|
2006-03-12 21:50:17 +00:00
|
|
|
[self DPSsetdash: dash_pattern : count : phase];
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_set_op(cairo_t * ct, NSCompositingOperation op)
|
|
|
|
{
|
|
|
|
switch (op)
|
|
|
|
{
|
|
|
|
case NSCompositeClear:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_CLEAR);
|
|
|
|
break;
|
|
|
|
case NSCompositeCopy:
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
|
2004-08-02 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case NSCompositeSourceOver:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_OVER);
|
|
|
|
break;
|
|
|
|
case NSCompositeSourceIn:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_IN);
|
|
|
|
break;
|
|
|
|
case NSCompositeSourceOut:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_OUT);
|
|
|
|
break;
|
|
|
|
case NSCompositeSourceAtop:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_ATOP);
|
|
|
|
break;
|
|
|
|
case NSCompositeDestinationOver:
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_DEST_OVER);
|
2004-08-02 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case NSCompositeDestinationIn:
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_DEST_IN);
|
2004-08-02 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case NSCompositeDestinationOut:
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_DEST_OUT);
|
2004-08-02 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case NSCompositeDestinationAtop:
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_DEST_ATOP);
|
2004-08-02 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case NSCompositeXOR:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_XOR);
|
|
|
|
break;
|
|
|
|
case NSCompositePlusDarker:
|
2005-07-27 23:25:32 +00:00
|
|
|
// FIXME
|
2004-08-02 21:50:17 +00:00
|
|
|
break;
|
|
|
|
case NSCompositeHighlight:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_SATURATE);
|
|
|
|
break;
|
|
|
|
case NSCompositePlusLighter:
|
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_ADD);
|
|
|
|
break;
|
|
|
|
default:
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_set_operator(ct, CAIRO_OPERATOR_SOURCE);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) DPSimage: (NSAffineTransform *)matrix : (int)pixelsWide
|
|
|
|
: (int)pixelsHigh : (int)bitsPerSample
|
|
|
|
: (int)samplesPerPixel : (int)bitsPerPixel
|
|
|
|
: (int)bytesPerRow : (BOOL)isPlanar
|
|
|
|
: (BOOL)hasAlpha : (NSString *)colorSpaceName
|
|
|
|
: (const unsigned char *const[5])data
|
|
|
|
{
|
|
|
|
cairo_format_t format;
|
|
|
|
NSAffineTransformStruct tstruct;
|
2004-09-08 22:08:15 +00:00
|
|
|
cairo_surface_t *surface;
|
2005-08-20 00:10:35 +00:00
|
|
|
unsigned char *tmp;
|
|
|
|
int i = 0;
|
2005-08-28 00:48:12 +00:00
|
|
|
int j;
|
2006-02-11 00:32:21 +00:00
|
|
|
int index;
|
2005-08-20 00:10:35 +00:00
|
|
|
unsigned int pixels = pixelsHigh * pixelsWide;
|
|
|
|
const unsigned char *bits = data[0];
|
2006-02-11 00:32:21 +00:00
|
|
|
unsigned char *rowData;
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
2005-08-20 00:10:35 +00:00
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
/*
|
|
|
|
NSLog(@"%@ DPSimage %dx%d (%p)", self, pixelsWide, pixelsHigh,
|
|
|
|
cairo_current_target_surface (_ct));
|
|
|
|
*/
|
2004-09-08 22:08:15 +00:00
|
|
|
if (isPlanar || !([colorSpaceName isEqualToString: NSDeviceRGBColorSpace] ||
|
|
|
|
[colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]))
|
|
|
|
{
|
|
|
|
NSLog(@"Image format not support");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-02-11 00:32:21 +00:00
|
|
|
// default is 8 bit grayscale
|
|
|
|
if (!bitsPerSample)
|
|
|
|
bitsPerSample = 8;
|
|
|
|
if (!samplesPerPixel)
|
|
|
|
samplesPerPixel = 1;
|
|
|
|
|
|
|
|
// FIXME - does this work if we are passed a planar image but no hints ?
|
|
|
|
if (!bitsPerPixel)
|
|
|
|
bitsPerPixel = bitsPerSample * samplesPerPixel;
|
|
|
|
if (!bytesPerRow)
|
|
|
|
bytesPerRow = (bitsPerPixel * pixelsWide) / 8;
|
|
|
|
|
|
|
|
/* make sure its sane - also handles row padding if hint missing */
|
|
|
|
while ((bytesPerRow * 8) < (bitsPerPixel * pixelsWide))
|
|
|
|
bytesPerRow++;
|
|
|
|
|
|
|
|
switch (bitsPerPixel)
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
case 32:
|
2006-02-11 00:32:21 +00:00
|
|
|
rowData = (unsigned char *)bits;
|
2005-08-20 00:10:35 +00:00
|
|
|
tmp = objc_malloc(pixels * 4);
|
2006-02-11 00:32:21 +00:00
|
|
|
index = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < pixelsHigh; i++)
|
|
|
|
{
|
|
|
|
unsigned char *d = rowData;
|
|
|
|
|
|
|
|
for (j = 0; j < pixelsWide; j++)
|
|
|
|
{
|
|
|
|
tmp[index++] = d[2];
|
|
|
|
tmp[index++] = d[1];
|
|
|
|
tmp[index++] = d[0];
|
|
|
|
tmp[index++] = d[3];
|
|
|
|
d += 4;
|
|
|
|
}
|
|
|
|
rowData += bytesPerRow;
|
2005-08-20 00:10:35 +00:00
|
|
|
}
|
|
|
|
bits = tmp;
|
2004-08-02 21:50:17 +00:00
|
|
|
format = CAIRO_FORMAT_ARGB32;
|
|
|
|
break;
|
|
|
|
case 24:
|
2006-02-11 00:32:21 +00:00
|
|
|
rowData = (unsigned char *)bits;
|
2005-08-28 00:48:12 +00:00
|
|
|
tmp = objc_malloc(pixels * 4);
|
2006-02-11 00:32:21 +00:00
|
|
|
index = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < pixelsHigh; i++)
|
|
|
|
{
|
|
|
|
unsigned char *d = rowData;
|
|
|
|
|
|
|
|
for (j = 0; j < pixelsWide; j++)
|
|
|
|
{
|
|
|
|
tmp[index++] = d[2];
|
|
|
|
tmp[index++] = d[1];
|
|
|
|
tmp[index++] = d[0];
|
|
|
|
tmp[index++] = 0;
|
|
|
|
d += 3;
|
|
|
|
}
|
|
|
|
rowData += bytesPerRow;
|
2005-08-28 00:48:12 +00:00
|
|
|
}
|
|
|
|
bits = tmp;
|
2004-08-02 21:50:17 +00:00
|
|
|
format = CAIRO_FORMAT_RGB24;
|
|
|
|
break;
|
|
|
|
default:
|
2004-09-08 22:08:15 +00:00
|
|
|
NSLog(@"Image format not support");
|
|
|
|
return;
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
2005-08-20 00:10:35 +00:00
|
|
|
surface = cairo_image_surface_create_for_data((void*)bits,
|
2005-07-27 23:25:32 +00:00
|
|
|
format,
|
|
|
|
pixelsWide,
|
|
|
|
pixelsHigh,
|
2006-02-11 00:32:21 +00:00
|
|
|
pixelsWide * 4);
|
2005-08-20 00:10:35 +00:00
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
if (surface == NULL)
|
|
|
|
{
|
|
|
|
NSLog(@"Image surface could not be created");
|
2006-02-11 00:32:21 +00:00
|
|
|
if (bits != data[0])
|
|
|
|
{
|
|
|
|
objc_free((unsigned char *)bits);
|
|
|
|
}
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
return;
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_save(_ct);
|
|
|
|
cairo_set_operator(_ct, CAIRO_OPERATOR_SOURCE);
|
|
|
|
tstruct = [matrix transformStruct];
|
|
|
|
|
|
|
|
cairo_matrix_init(&local_matrix,
|
|
|
|
tstruct.m11, tstruct.m12,
|
|
|
|
tstruct.m21, tstruct.m22,
|
|
|
|
tstruct.tX, tstruct.tY);
|
|
|
|
cairo_transform(_ct, &local_matrix);
|
2006-10-03 23:29:53 +00:00
|
|
|
if (viewIsFlipped)
|
2005-11-07 00:11:09 +00:00
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_t *cpattern;
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cpattern = cairo_pattern_create_for_surface (surface);
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
|
|
|
cairo_matrix_translate(&local_matrix, 0, -2*pixelsHigh);
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
|
|
|
cairo_set_source(_ct, cpattern);
|
|
|
|
cairo_pattern_destroy(cpattern);
|
2006-03-07 00:59:30 +00:00
|
|
|
|
|
|
|
cairo_rectangle(_ct, 0, pixelsHigh, pixelsWide, pixelsHigh);
|
2005-11-07 00:11:09 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_t *cpattern;
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cpattern = cairo_pattern_create_for_surface (surface);
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
|
|
|
cairo_matrix_translate(&local_matrix, 0, -pixelsHigh);
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
|
|
|
cairo_set_source(_ct, cpattern);
|
|
|
|
cairo_pattern_destroy(cpattern);
|
2006-03-07 00:59:30 +00:00
|
|
|
|
2005-11-07 00:11:09 +00:00
|
|
|
cairo_rectangle(_ct, 0, 0, pixelsWide, pixelsHigh);
|
|
|
|
}
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_fill(_ct);
|
2004-09-08 22:08:15 +00:00
|
|
|
cairo_surface_destroy(surface);
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_restore(_ct);
|
2006-02-11 00:32:21 +00:00
|
|
|
|
|
|
|
if (bits != data[0])
|
|
|
|
{
|
|
|
|
objc_free((unsigned char *)bits);
|
|
|
|
}
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) compositerect: (NSRect)aRect op: (NSCompositingOperation)op
|
|
|
|
{
|
2006-02-13 00:07:40 +00:00
|
|
|
cairo_save(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
_set_op(_ct, op);
|
|
|
|
cairo_rectangle(_ct, NSMinX(aRect), NSMinY(aRect), NSWidth(aRect),
|
|
|
|
NSHeight(aRect));
|
|
|
|
cairo_fill(_ct);
|
2006-02-13 00:07:40 +00:00
|
|
|
cairo_restore(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) compositeGState: (CairoGState *)source
|
|
|
|
fromRect: (NSRect)aRect
|
|
|
|
toPoint: (NSPoint)aPoint
|
|
|
|
op: (NSCompositingOperation)op
|
2004-09-08 22:08:15 +00:00
|
|
|
fraction: (float)delta
|
2004-08-02 21:50:17 +00:00
|
|
|
{
|
|
|
|
cairo_surface_t *src;
|
2005-07-27 23:25:32 +00:00
|
|
|
double minx, miny;
|
|
|
|
double width, height;
|
2004-08-02 21:50:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
NSLog(NSStringFromRect(aRect));
|
2005-11-07 00:11:09 +00:00
|
|
|
NSLog(NSStringFromPoint(aPoint));
|
2005-07-27 23:25:32 +00:00
|
|
|
NSLog(@"src %p(%p,%@) des %p(%p,%@)",
|
|
|
|
source,cairo_get_target(source->_ct),NSStringFromSize([source->_surface size]),
|
|
|
|
self,cairo_get_target(_ct),NSStringFromSize([_surface size]));
|
2004-08-02 21:50:17 +00:00
|
|
|
*/
|
2005-07-27 23:25:32 +00:00
|
|
|
|
2004-09-08 22:08:15 +00:00
|
|
|
cairo_save(_ct);
|
|
|
|
_set_op(_ct, op);
|
2005-07-27 23:25:32 +00:00
|
|
|
|
|
|
|
src = cairo_get_target(source->_ct);
|
2006-02-12 17:59:30 +00:00
|
|
|
if (src == cairo_get_target(_ct))
|
|
|
|
{
|
|
|
|
//NSLog(@"Copy onto self");
|
|
|
|
}
|
|
|
|
|
2005-07-27 23:25:32 +00:00
|
|
|
minx = NSMinX(aRect);
|
|
|
|
miny = NSMinY(aRect);
|
|
|
|
width = NSWidth(aRect);
|
|
|
|
height = NSHeight(aRect);
|
|
|
|
/*
|
|
|
|
cairo_user_to_device(source->_ct, &minx, &miny);
|
|
|
|
cairo_user_to_device_distance(source->_ct, &width, &height);
|
2005-11-07 00:11:09 +00:00
|
|
|
cairo_device_to_user(_ct, &minx, &miny);
|
2005-07-27 23:25:32 +00:00
|
|
|
cairo_device_to_user_distance(_ct, &width, &height);
|
|
|
|
NSLog(@"Rect %@ = %f, %f, %f, %f", NSStringFromRect(aRect), minx, miny, width, height);
|
|
|
|
*/
|
2006-10-03 23:29:53 +00:00
|
|
|
if (viewIsFlipped)
|
2006-02-12 17:59:30 +00:00
|
|
|
{
|
2006-03-12 21:50:17 +00:00
|
|
|
/*
|
2006-10-03 23:29:53 +00:00
|
|
|
if (!source->viewIsFlipped)
|
2006-03-12 21:50:17 +00:00
|
|
|
{
|
|
|
|
// Undo flipping of the source coordinate system
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_t *cpattern;
|
2006-03-12 21:50:17 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cpattern = cairo_pattern_create_for_surface(src);
|
2006-03-12 21:50:17 +00:00
|
|
|
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
|
|
|
cairo_matrix_translate(&local_matrix, -aPoint.x + minx, -aPoint.y + miny);
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
|
|
|
cairo_set_source(_ct, cpattern);
|
|
|
|
cairo_pattern_destroy(cpattern);
|
2006-03-12 21:50:17 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
cairo_set_source_surface(_ct, src, aPoint.x - minx, aPoint.y - miny - height);
|
|
|
|
}
|
2006-02-13 00:07:40 +00:00
|
|
|
cairo_rectangle (_ct, aPoint.x, aPoint.y - height, width, height);
|
2006-02-12 17:59:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
if (!source->viewIsFlipped)
|
2006-03-07 00:59:30 +00:00
|
|
|
{
|
|
|
|
// Undo flipping of the source coordinate system
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_t *cpattern;
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_matrix_t local_matrix;
|
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cpattern = cairo_pattern_create_for_surface(src);
|
2006-03-07 00:59:30 +00:00
|
|
|
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
|
|
|
cairo_matrix_translate(&local_matrix, -aPoint.x + minx, -aPoint.y + miny - height);
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
|
|
|
cairo_set_source(_ct, cpattern);
|
|
|
|
cairo_pattern_destroy(cpattern);
|
2006-03-07 00:59:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cairo_set_source_surface(_ct, src, aPoint.x - minx, aPoint.y - miny);
|
|
|
|
}
|
2006-02-12 17:59:30 +00:00
|
|
|
cairo_rectangle (_ct, aPoint.x, aPoint.y, width, height);
|
|
|
|
}
|
2005-07-27 23:25:32 +00:00
|
|
|
|
|
|
|
if (delta < 1.0)
|
|
|
|
{
|
2006-10-03 23:29:53 +00:00
|
|
|
cairo_pattern_t *cpattern;
|
2005-07-27 23:25:32 +00:00
|
|
|
|
2006-10-03 23:29:53 +00:00
|
|
|
cpattern = cairo_pattern_create_rgba(1.0, 1.0, 1.0, delta);
|
|
|
|
cairo_mask(_ct, cpattern);
|
|
|
|
cairo_pattern_destroy(cpattern);
|
2005-07-27 23:25:32 +00:00
|
|
|
}
|
|
|
|
cairo_fill(_ct);
|
2004-08-02 21:50:17 +00:00
|
|
|
cairo_restore(_ct);
|
|
|
|
}
|
|
|
|
|
2004-09-08 22:08:15 +00:00
|
|
|
- (void) compositeGState: (CairoGState *)source
|
|
|
|
fromRect: (NSRect)aRect
|
|
|
|
toPoint: (NSPoint)aPoint
|
|
|
|
op: (NSCompositingOperation)op
|
|
|
|
{
|
|
|
|
[self compositeGState: source
|
|
|
|
fromRect: aRect
|
|
|
|
toPoint: aPoint
|
|
|
|
op: op
|
|
|
|
fraction: 1.0];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dissolveGState: (CairoGState *)source
|
|
|
|
fromRect: (NSRect)aRect
|
|
|
|
toPoint: (NSPoint)aPoint
|
|
|
|
delta: (float)delta
|
|
|
|
{
|
|
|
|
[self compositeGState: source
|
|
|
|
fromRect: aRect
|
|
|
|
toPoint: aPoint
|
|
|
|
op: NSCompositeSourceOver
|
|
|
|
fraction: delta];
|
|
|
|
}
|
|
|
|
|
2004-08-02 21:50:17 +00:00
|
|
|
@end
|