mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
Corrected handling of flipped state in matrix operations and image
drawing. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@24754 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
60815aa29b
commit
f11c2117f3
2 changed files with 48 additions and 95 deletions
|
@ -1,3 +1,10 @@
|
|||
2007-03-02 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/cairo/CairoGState.m (-DPSinitmatrix, -GSCurrentCTM):
|
||||
Don't consider flipped state.
|
||||
* Source/cairo/CairoGState.m (-compositeGState:...fraction:):
|
||||
Simplified the code and now use cairo_paint and cairo_paint_with_alpha.
|
||||
|
||||
2007-03-01 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/cairo/CairoGState.m (-DPSinitgraphics): Set more cairo state.
|
||||
|
|
|
@ -285,6 +285,7 @@
|
|||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
{
|
||||
NSLog(@"Cairo status %s in DPSinitgraphics", cairo_status_to_string(status));
|
||||
return;
|
||||
}
|
||||
[self DPSinitmatrix];
|
||||
// Changes from super call go to the old _ct
|
||||
|
@ -466,7 +467,7 @@
|
|||
* Matrix operations
|
||||
*/
|
||||
|
||||
// FIXME: All matrix and path operations need to call the super implemantion
|
||||
// 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
|
||||
|
@ -482,22 +483,18 @@
|
|||
|
||||
- (void) DPSinitmatrix
|
||||
{
|
||||
if (_ct)
|
||||
// This safety check is not really needed, when _ct is set, there is a surface.
|
||||
if (_ct && _surface)
|
||||
{
|
||||
cairo_identity_matrix(_ct);
|
||||
if (!viewIsFlipped)
|
||||
{
|
||||
cairo_matrix_t local_matrix;
|
||||
cairo_matrix_t local_matrix;
|
||||
|
||||
// cairo draws the other way around.
|
||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
||||
|
||||
if (_surface != nil)
|
||||
{
|
||||
cairo_matrix_translate(&local_matrix, 0, -[_surface size].height);
|
||||
}
|
||||
cairo_set_matrix(_ct, &local_matrix);
|
||||
}
|
||||
// cairo draws the other way around.
|
||||
// At this point in time viewIsFlipped has not been set, but it is
|
||||
// OK to ignore this here, as in that case the matrix will later
|
||||
// get flipped by GUI,
|
||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
||||
cairo_matrix_translate(&local_matrix, 0, -[_surface size].height);
|
||||
cairo_set_matrix(_ct, &local_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,27 +525,21 @@
|
|||
- (NSAffineTransform *) GSCurrentCTM
|
||||
{
|
||||
NSAffineTransform *transform;
|
||||
NSAffineTransformStruct tstruct;
|
||||
cairo_matrix_t flip_matrix;
|
||||
cairo_matrix_t local_matrix;
|
||||
|
||||
transform = [NSAffineTransform transform];
|
||||
if (_ct)
|
||||
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
|
||||
if (!viewIsFlipped)
|
||||
{
|
||||
cairo_matrix_init_scale(&flip_matrix, 1, -1);
|
||||
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
|
||||
|
||||
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);
|
||||
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;
|
||||
|
@ -1164,12 +1155,13 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
tstruct.m21, tstruct.m22,
|
||||
tstruct.tX, tstruct.tY);
|
||||
cairo_transform(_ct, &local_matrix);
|
||||
|
||||
if (viewIsFlipped)
|
||||
{
|
||||
cairo_pattern_t *cpattern;
|
||||
cairo_matrix_t local_matrix;
|
||||
|
||||
cpattern = cairo_pattern_create_for_surface (surface);
|
||||
cpattern = cairo_pattern_create_for_surface(surface);
|
||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
||||
cairo_matrix_translate(&local_matrix, 0, -2*pixelsHigh);
|
||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
||||
|
@ -1183,7 +1175,7 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
cairo_pattern_t *cpattern;
|
||||
cairo_matrix_t local_matrix;
|
||||
|
||||
cpattern = cairo_pattern_create_for_surface (surface);
|
||||
cpattern = cairo_pattern_create_for_surface(surface);
|
||||
cairo_matrix_init_scale(&local_matrix, 1, -1);
|
||||
cairo_matrix_translate(&local_matrix, 0, -pixelsHigh);
|
||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
||||
|
@ -1224,8 +1216,6 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
cairo_surface_t *src;
|
||||
double minx, miny;
|
||||
double width, height;
|
||||
double dh;
|
||||
NSSize size;
|
||||
double x, y;
|
||||
|
||||
if (!_ct || !source->_ct)
|
||||
|
@ -1233,25 +1223,22 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
return;
|
||||
}
|
||||
|
||||
size = [source->_surface size];
|
||||
dh = size.height;
|
||||
|
||||
cairo_save(_ct);
|
||||
cairo_new_path(_ct);
|
||||
_set_op(_ct, op);
|
||||
|
||||
src = cairo_get_target(source->_ct);
|
||||
if (src == cairo_get_target(_ct))
|
||||
{
|
||||
/*
|
||||
NSLog(@"Copy onto self");
|
||||
if (src == cairo_get_target(_ct))
|
||||
{
|
||||
NSLog(@"Copy onto self");
|
||||
NSLog(NSStringFromRect(aRect));
|
||||
NSLog(NSStringFromPoint(aPoint));
|
||||
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]));
|
||||
*/
|
||||
}
|
||||
*/
|
||||
x = aPoint.x;
|
||||
y = aPoint.y;
|
||||
minx = NSMinX(aRect);
|
||||
|
@ -1264,72 +1251,31 @@ _set_op(cairo_t *ct, NSCompositingOperation op)
|
|||
|
||||
if (viewIsFlipped)
|
||||
{
|
||||
if (!source->viewIsFlipped)
|
||||
{
|
||||
/*
|
||||
FIXME: My findings with a test applications would suggest that the following
|
||||
commented out code it the correct implementation for this case, but the palette
|
||||
images in Gorm look up side down with it.
|
||||
*/
|
||||
// cairo_set_source_surface(_ct, src, x - minx, y + miny - 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);
|
||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
||||
cairo_set_source(_ct, cpattern);
|
||||
cairo_pattern_destroy(cpattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Both flipped
|
||||
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);
|
||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
||||
cairo_set_source(_ct, cpattern);
|
||||
cairo_pattern_destroy(cpattern);
|
||||
}
|
||||
cairo_set_source_surface(_ct, src, x - minx, y + miny - 2*height);
|
||||
cairo_rectangle(_ct, x, y - height, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!source->viewIsFlipped)
|
||||
{
|
||||
// Both non-flipped.
|
||||
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);
|
||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
||||
cairo_set_source(_ct, cpattern);
|
||||
cairo_pattern_destroy(cpattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_set_source_surface(_ct, src, x - minx, y + miny);
|
||||
}
|
||||
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);
|
||||
cairo_pattern_set_matrix(cpattern, &local_matrix);
|
||||
cairo_set_source(_ct, cpattern);
|
||||
cairo_pattern_destroy(cpattern);
|
||||
cairo_rectangle(_ct, x, y, width, height);
|
||||
}
|
||||
|
||||
cairo_clip(_ct);
|
||||
if (delta < 1.0)
|
||||
{
|
||||
cairo_pattern_t *cpattern;
|
||||
|
||||
cpattern = cairo_pattern_create_rgba(1.0, 1.0, 1.0, delta);
|
||||
cairo_mask(_ct, cpattern);
|
||||
cairo_pattern_destroy(cpattern);
|
||||
cairo_paint_with_alpha(_ct, delta);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_fill(_ct);
|
||||
cairo_paint(_ct);
|
||||
}
|
||||
cairo_restore(_ct);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue