bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #27782] drawInRect:fromRect:operation:fraction: doesn't work correc


From: Quentin Mathé
Subject: [bug #27782] drawInRect:fromRect:operation:fraction: doesn't work correctly in a flipped view
Date: Thu, 15 Apr 2010 14:58:16 +0000
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.16) Gecko/2009121601 Ubuntu/9.04 (jaunty) Firefox/3.0.16

Follow-up Comment #11, bug #27782 (project gnustep):

Here is a new Gui + Cairo backend patch that corrects all the drawing issues
I have found until now. I'll upload some screenshots and examples later on.
This patch is currently untested with backends other than Cairo.

All flipping checks have been removed in the Cairo backend (some checks have
been removed in Gui too when possible). Image drawing methods should now
behave consistently even if:
- multiple flip/rotation/scaling transforms are combined 
- flip transforms are applied manually instead of overriding -isFlipped.
To guiding idea is that flipping is a Gui notion that doesn't need to exist
at the backend level. When the backend never checks -isFlipped or similar, it
becomes much easier to support the two previous points.

imo these checks must be removed all at once to get the drawing code correct.
They seem to work around each other in an unclear way. Since I had troubles to
figure out where the bugs really were, I started by removing all these checks
to be sure I was not going to introduce new workarounds.

-- About Composite methods --

This new patch keeps -compositeToPoint implementation exactly as is, but
corrects -compositeGState in the backend to match the Mac OS X behavior of
-compositeToPoint and NSCopyBits. When the destination is rotated, the content
is now composited at the right location.
In addition, it retains the old behavior that takes in account the source
ctm. I'm not exactly sure we should do that as discussed in my mail
PScomposite questions. The only visible difference with Mac OS X is that we
interpret the source rect relative the view coordinate space (rather than the
base coordinate space as Mac OS X does) when we do:
NSCopyBits([view gState], sourceRect, destPoint)

My previous patch was an attempt to cancel the effect of the destination ctm
on the composited content size. In other words, the destination point as it
was computed was dependent on the content size. After observing my previous
patch didn't work well with a rotated destination ctm and writing tests on Mac
OS X, I found that the destination ctm is only applied to the the destination
point but not to the content as whole.

// If r.origin is the destination point, it varies with aRect.size in the
code below
NSRect r = aRect;
aRect.origin = aPoint;
[ctm boundingRect: aRect result: &r];

// Now if we rewrite that as below, we get a valid destination point
// In the patch we don't use -boundingRect:result: but [ctm transformPoint:
aPoint]
NSRect r = aRect;
aRect.origin = aPoint;
aRect.size = NSZeroSize;
[ctm boundingRect: aRect result: &r];

This is the main fix to get -compositeToPoint works correctly. 
I also introduced dx and dy to ensure the content from a rotated source is
composited at the right location in the destination.
In the previous implementation, the distance between the composited rect
bottom left and the destination point was equal to the distance between the
source rect bottom left and its minimum bounding rect bottom left. With the
new destination point computation, the distance can vary. Hence this delta
adjustment is now required to support compositing with the same source and
target (the only compositing case really used that involves a rotated and/or
scaled source). 
In addition, I think the delta also ensures a valid destination point when
the source and the target are not the same unlike previously.

-- About Draw methods ---

For -drawInRect:, we have now two code paths. The old one that handles the
scaling in Gui but has several issues:
- draw at the wrong location in flipped coordinates
- draw at the wrong location when there is a scaling with inRect and
fromRect
- is slow when you want to draw a small image portion with a scaling or
rotation involved.

And a new Cairo-specific code path much simpler that corrects all the
previous issues.

Ultimately it is probably possible to reimplement -compositeGState on top of
-drawGState, but since the semantic differences are pretty important I don't
think it really matters that much. It was also easier to debug and to figure
out where the bugs really were once I introduced a distinct code path for
-drawInRect.
It's probably far from ideal, but when you consider the number of issues (or
changes required in each backend) and the fact we'll probably switch to Opal
in the long run, it sounds acceptable to me.


(file #20227)
    _______________________________________________________

Additional Item Attachment:

File name: gnustep-drawing-fixes.patch    Size:26 KB


    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?27782>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]