Don't use cairo transformations, use the super class implementation

instead. 


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@24896 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2007-03-18 17:50:58 +00:00
parent 452d7fb89f
commit b2d624ad91
4 changed files with 104 additions and 376 deletions

View file

@ -1,3 +1,12 @@
2007-03-18 Fred Kiefer <FredKiefer@gmx.de>
* Source/cairo/CairoGState.m: A complete rewrite, now path and
transformation handling from the super class get used.
* Source/cairo/CairoFontInfo.m (-setupAttributes:,
-drawGlyphs:length:on:): Don't invert the font matrix.
* Source/gsc/GSGState.m (-DPSrectclip::::, -DPSrectfill::::,
-DPSrectstroke::::): Use NSBezierPath to get correct results when rotated.
2007-03-11 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGDragView.m (GSActionForDragOperation,

View file

@ -83,7 +83,7 @@
* xHeight, pix_width, pix_height
*/
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
-matrix[3], matrix[4], matrix[5]);
matrix[3], matrix[4], matrix[5]);
cairo_matrix_init_identity(&ctm);
// FIXME: Should get default font options from somewhere
options = cairo_font_options_create();
@ -295,7 +295,7 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph,
}
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
-matrix[3], matrix[4], matrix[5]);
matrix[3], matrix[4], matrix[5]);
cairo_set_font_matrix(ct, &font_matrix);
if (cairo_status(ct) != CAIRO_STATUS_SUCCESS)
{

View file

@ -171,34 +171,25 @@
[super GSSetPatterColor: image];
}
- (NSPoint) pointInMatrixSpace: (NSPoint)aPoint
{
// FIXME: Use cairo_user_to_device
return [[self GSCurrentCTM] pointInMatrixSpace: aPoint];
}
- (NSPoint) deltaPointInMatrixSpace: (NSPoint)aPoint
{
// FIXME: Use cairo_user_to_device_distance
return [[self GSCurrentCTM] deltaPointInMatrixSpace: aPoint];
}
- (NSRect) rectInMatrixSpace: (NSRect)rect
{
// FIXME: Use the two above methods
return [[self GSCurrentCTM] rectInMatrixSpace: rect];
}
/*
* Text operations
*/
- (void) _setPoint
{
NSPoint p;
p = [path currentPoint];
cairo_move_to(_ct, p.x, p.y);
}
- (void) DPScharpath: (const char *)s : (int)b
{
if (_ct)
{
char *c = malloc(b + 1);
[self _setPoint];
memcpy(c, s, b);
c[b] = 0;
cairo_text_path(_ct, c);
@ -210,6 +201,7 @@
{
if (_ct)
{
[self _setPoint];
cairo_show_text(_ct, s);
}
}
@ -226,7 +218,7 @@
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]);
matrix[3], matrix[4], matrix[5]);
cairo_set_font_matrix(_ct, &font_matrix);
}
}
@ -245,6 +237,7 @@
{
char *c = malloc(length + 1);
[self _setPoint];
memcpy(c, string, length);
c[length] = 0;
cairo_show_text(_ct, c);
@ -256,6 +249,7 @@
{
if (_ct)
{
[self _setPoint];
[(CairoFontInfo *)font drawGlyphs: glyphs
length: length
on: _ct];
@ -377,22 +371,6 @@
}
}
- (NSPoint) currentPoint
{
double dx, dy;
if (_ct)
{
cairo_get_current_point(_ct, &dx, &dy);
}
else
{
dx = 0.0;
dy = 0.0;
}
return NSMakePoint(dx, dy);
}
- (void) DPScurrentstrokeadjust: (int *)b
{
FIXME();
@ -420,6 +398,7 @@
- (void) DPSsetflat: (float)flatness
{
[super DPSsetflat: flatness];
if (_ct)
{
cairo_set_tolerance(_ct, flatness);
@ -467,22 +446,10 @@
* Matrix operations
*/
// FIXME: All matrix and path operations need to call the super implementation
// to get the complex methods of the super class to work correctly.
- (void) DPSconcat: (const float *)m
{
cairo_matrix_t local_matrix;
if (_ct)
{
cairo_matrix_init(&local_matrix, m[0], m[1], m[2], m[3], m[4], m[5]);
cairo_transform(_ct, &local_matrix);
}
}
- (void) DPSinitmatrix
{
[super DPSinitmatrix];
// This safety check is not really needed, when _ct is set, there is a surface.
if (_ct && _surface)
{
@ -498,139 +465,55 @@
}
}
- (void) DPSrotate: (float)angle
- (void) _setPath
{
if (_ct)
unsigned count = [path elementCount];
unsigned i;
SEL elmsel = @selector(elementAtIndex:associatedPoints:);
IMP elmidx = [path methodForSelector: elmsel];
for (i = 0; i < count; i++)
{
cairo_rotate(_ct, angle);
}
}
NSBezierPathElement type;
NSPoint points[3];
- (void) DPSscale: (float)x : (float)y
{
if (_ct)
type = (NSBezierPathElement)(*elmidx)(path, elmsel, i, points);
switch(type)
{
cairo_scale(_ct, x, y);
case NSMoveToBezierPathElement:
cairo_move_to(_ct, points[0].x, points[0].y);
break;
case NSLineToBezierPathElement:
cairo_line_to(_ct, points[0].x, points[0].y);
break;
case NSCurveToBezierPathElement:
cairo_curve_to(_ct, points[0].x, points[0].y,
points[1].x, points[1].y,
points[2].x, points[2].y);
break;
case NSClosePathBezierPathElement:
cairo_close_path(_ct);
break;
default:
break;
}
}
- (void) DPStranslate: (float)x : (float)y
{
if (_ct)
{
cairo_translate(_ct, x, y);
}
}
- (NSAffineTransform *) GSCurrentCTM
{
NSAffineTransform *transform;
transform = [NSAffineTransform transform];
if (_ct && _surface)
{
NSAffineTransformStruct tstruct;
cairo_matrix_t flip_matrix;
cairo_matrix_t local_matrix;
cairo_get_matrix(_ct, &local_matrix);
// Undo changes in DPSinitmatrix
cairo_matrix_init_scale(&flip_matrix, 1, -1);
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
cairo_matrix_init_translate(&flip_matrix, 0, [_surface size].height);
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
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;
[transform setTransformStruct: tstruct];
}
return transform;
}
- (void) GSSetCTM: (NSAffineTransform *)newCtm
{
[self DPSinitmatrix];
[self GSConcatCTM: newCtm];
}
- (void) GSConcatCTM: (NSAffineTransform *)newCtm
{
NSAffineTransformStruct tstruct;
cairo_matrix_t local_matrix;
if (_ct)
{
tstruct = [newCtm transformStruct];
cairo_matrix_init(&local_matrix,
tstruct.m11, tstruct.m12,
tstruct.m21, tstruct.m22,
tstruct.tX, tstruct.tY);
cairo_transform(_ct, &local_matrix);
}
}
/*
* Paint operations
*/
- (void) DPSarc: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
{
if (_ct)
{
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
{
if (_ct)
{
cairo_arc_negative(_ct, x, y, r, angle1 * M_PI / 180, angle2 * M_PI / 180);
}
}
- (void)DPSarct: (float)x1 : (float)y1 : (float)x2 : (float)y2 : (float)r
{
// FIXME: Still missing in cairo
//cairo_arc_to(_ct, x1, y1, x2, y2, r);
FIXME();
}
- (void) DPSclip
{
if (_ct)
{
[self _setPath];
cairo_clip(_ct);
}
}
- (void) DPSclosepath
{
if (_ct)
{
cairo_close_path(_ct);
}
}
- (void) DPScurveto: (float)x1 : (float)y1 : (float)x2
: (float)y2 : (float)x3 : (float)y3
{
if (_ct)
{
cairo_curve_to(_ct, x1, y1, x2, y2, x3, y3);
}
}
- (void) DPSeoclip
{
if (_ct)
{
[self _setPath];
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
cairo_clip(_ct);
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_WINDING);
@ -641,6 +524,7 @@
{
if (_ct)
{
[self _setPath];
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
cairo_fill(_ct);
cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_WINDING);
@ -651,23 +535,11 @@
{
if (_ct)
{
[self _setPath];
cairo_fill(_ct);
}
}
- (void) DPSflattenpath
{
cairo_path_t *cpath;
if (_ct)
{
cpath = cairo_copy_path_flat(_ct);
cairo_new_path(_ct);
cairo_append_path(_ct, cpath);
cairo_path_destroy(cpath);
}
}
- (void) DPSinitclip
{
if (_ct)
@ -676,197 +548,15 @@
}
}
- (void) DPSlineto: (float)x : (float)y
{
if (_ct)
{
cairo_line_to(_ct, x, y);
}
}
- (void) DPSmoveto: (float)x : (float)y
{
if (_ct)
{
cairo_move_to(_ct, x, y);
}
}
- (void) DPSnewpath
{
if (_ct)
{
cairo_new_path(_ct);
}
}
- (NSBezierPath *) bezierPath
{
int i;
cairo_path_t *cpath;
cairo_path_data_t *data;
NSBezierPath *bpath =[NSBezierPath bezierPath];
if (!_ct)
{
return bpath;
}
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:
[bpath moveToPoint: NSMakePoint(data[1].point.x, data[1].point.y)];
break;
case CAIRO_PATH_LINE_TO:
[bpath lineToPoint: NSMakePoint(data[1].point.x, data[1].point.y)];
break;
case CAIRO_PATH_CURVE_TO:
[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)];
break;
case CAIRO_PATH_CLOSE_PATH:
[bpath closePath];
break;
}
}
cairo_path_destroy(cpath);
return bpath;
}
- (void) DPSrcurveto: (float)x1 : (float)y1 : (float)x2
: (float)y2 : (float)x3 : (float)y3
{
if (_ct)
{
cairo_rel_curve_to(_ct, x1, y1, x2, y2, x3, y3);
}
}
- (void) DPSrectclip: (float)x : (float)y : (float)w : (float)h
{
if (_ct)
{
cairo_new_path(_ct);
cairo_rectangle(_ct, x, y, w, h);
cairo_clip(_ct);
cairo_new_path(_ct);
}
}
- (void) DPSrectfill: (float)x : (float)y : (float)w : (float)h
{
if (_ct)
{
cairo_save(_ct);
cairo_new_path(_ct);
cairo_rectangle(_ct, x, y, w, h);
cairo_fill(_ct);
cairo_restore(_ct);
}
}
- (void) DPSrectstroke: (float)x : (float)y : (float)w : (float)h
{
if (_ct)
{
cairo_save(_ct);
cairo_new_path(_ct);
cairo_rectangle(_ct, x, y, w, h);
cairo_stroke(_ct);
cairo_restore(_ct);
}
}
- (void) DPSreversepath
{
NSBezierPath *bpath = [self bezierPath];
bpath = [bpath bezierPathByReversingPath];
[self GSSendBezierPath: bpath];
}
- (void) DPSrlineto: (float)x : (float)y
{
if (_ct)
{
cairo_rel_line_to(_ct, x, y);
}
}
- (void) DPSrmoveto: (float)x : (float)y
{
if (_ct)
{
cairo_rel_move_to(_ct, x, y);
}
}
- (void) DPSstroke
{
if (_ct)
{
[self _setPath];
cairo_stroke(_ct);
}
}
- (void) GSSendBezierPath: (NSBezierPath *)bpath
{
int i, n;
int count = 10;
float dash_pattern[10];
float phase;
NSPoint pts[3];
NSBezierPathElement e;
SEL elmsel = @selector(elementAtIndex: associatedPoints:);
IMP elmidx = [bpath methodForSelector: elmsel];
if (!_ct)
{
return;
}
cairo_new_path(_ct);
n = [bpath elementCount];
for (i = 0; i < n; i++)
{
e = (NSBezierPathElement)(*elmidx)(bpath, elmsel, i, pts);
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;
}
}
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]);
cairo_set_tolerance(_ct, [bpath flatness]);
[bpath getLineDash: dash_pattern count: &count phase: &phase];
[self DPSsetdash: dash_pattern : count : phase];
}
- (NSDictionary *) GSReadRect: (NSRect)r
{
NSMutableDictionary *dict;
@ -888,9 +578,10 @@
return nil;
}
r = [ctm rectInMatrixSpace: r];
x = NSWidth(r);
y = NSHeight(r);
cairo_user_to_device_distance(_ct, &x, &y);
// cairo_user_to_device_distance(_ct, &x, &y);
ix = abs(floor(x));
iy = abs(floor(y));
ssize = NSMakeSize(ix, iy);
@ -1148,8 +839,17 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
cairo_save(_ct);
cairo_set_operator(_ct, CAIRO_OPERATOR_SOURCE);
tstruct = [matrix transformStruct];
// Set the basic transformation
tstruct = [ctm transformStruct];
cairo_matrix_init(&local_matrix,
tstruct.m11, tstruct.m12,
tstruct.m21, tstruct.m22,
tstruct.tX, tstruct.tY);
cairo_transform(_ct, &local_matrix);
// add the local tranformation
tstruct = [matrix transformStruct];
cairo_matrix_init(&local_matrix,
tstruct.m11, tstruct.m12,
tstruct.m21, tstruct.m22,
@ -1198,10 +898,14 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
{
if (_ct)
{
NSBezierPath *oldPath = path;
cairo_save(_ct);
_set_op(_ct, op);
cairo_rectangle(_ct, NSMinX(aRect), NSMinY(aRect), NSWidth(aRect),
NSHeight(aRect));
path = [NSBezierPath bezierPathWithRect: aRect];
[path transformUsingAffineTransform: ctm];
[self _setPath];
path = oldPath;
cairo_fill(_ct);
cairo_restore(_ct);
}
@ -1239,22 +943,37 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
self,cairo_get_target(_ct),NSStringFromSize([_surface size]));
}
*/
aRect = [source->ctm rectInMatrixSpace: aRect];
aPoint = [ctm pointInMatrixSpace: aPoint];
x = aPoint.x;
y = aPoint.y;
minx = NSMinX(aRect);
miny = NSMinY(aRect);
width = NSWidth(aRect);
height = NSHeight(aRect);
// NSLog(@"Old values %g, %g, %g , %g", minx, miny, width, height);
// FIXME: Why is this needed?
cairo_user_to_device(source->_ct, &minx, &miny);
// NSLog(@"New values %g, %g, %g , %g", minx, miny, width, height);
if (viewIsFlipped)
/*
if (source->viewIsFlipped)
{
cairo_set_source_surface(_ct, src, x - minx, y + miny - 2*height);
cairo_pattern_t *cpattern;
cairo_matrix_t local_matrix;
cpattern = cairo_pattern_create_for_surface(src);
cairo_matrix_init_scale(&local_matrix, 1, -1);
cairo_matrix_translate(&local_matrix, -x + minx, -y - miny - height);
cairo_pattern_set_matrix(cpattern, &local_matrix);
cairo_set_source(_ct, cpattern);
cairo_pattern_destroy(cpattern);
cairo_rectangle(_ct, x, y - height, width, height);
}
else
*/
{
cairo_pattern_t *cpattern;
cairo_matrix_t local_matrix;

View file

@ -931,10 +931,10 @@ typedef enum {
- (void) DPSrectclip: (float)x : (float)y : (float)w : (float)h
{
NSRect rect = [ctm rectInMatrixSpace: NSMakeRect(x, y, w, h)];
NSBezierPath *oldPath = path;
path = [NSBezierPath bezierPathWithRect: rect];
path = [NSBezierPath bezierPathWithRect: NSMakeRect(x, y, w, h)];
[path transformUsingAffineTransform: ctm];
[self DPSclip];
path = oldPath;
if (path)
@ -943,20 +943,20 @@ typedef enum {
- (void) DPSrectfill: (float)x : (float)y : (float)w : (float)h
{
NSRect rect = [ctm rectInMatrixSpace: NSMakeRect(x, y, w, h)];
NSBezierPath *oldPath = path;
path = [NSBezierPath bezierPathWithRect: rect];
path = [NSBezierPath bezierPathWithRect: NSMakeRect(x, y, w, h)];
[path transformUsingAffineTransform: ctm];
[self DPSfill];
path = oldPath;
}
- (void) DPSrectstroke: (float)x : (float)y : (float)w : (float)h
{
NSRect rect = [ctm rectInMatrixSpace: NSMakeRect(x, y, w, h)];
NSBezierPath *oldPath = path;
path = [NSBezierPath bezierPathWithRect: rect];
path = [NSBezierPath bezierPathWithRect: NSMakeRect(x, y, w, h)];
[path transformUsingAffineTransform: ctm];
[self DPSstroke];
path = oldPath;
}