gnustep-dev
[Top][All Lists]
Advanced

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

Re: Pixel-aligned autoresizing


From: Eric Wasylishen
Subject: Re: Pixel-aligned autoresizing
Date: Thu, 7 Jul 2011 02:16:24 -0600

On 2011-07-06, at 1:18 PM, Fred Kiefer wrote:

> On 06.07.2011 11:19, Eric Wasylishen wrote:
>> Hi Fred,
>> 
>> On 2011-07-06, at 2:32 AM, Fred Kiefer wrote:
>> 
>>> On 05.07.2011 22:15, Eric Wasylishen wrote:
>>>> Hi,
>>>> 
>>>> In the last month I was looking in to making GS's drawing output
>>>> match cocoa exactly, in particular, getting rid of rounding in the
>>>> backends.
>>>> 
>>>> One of the problems I encountered is GS can give autoresizing views
>>>> fractional positions/sizes, whereas when Cocoa autoresizes views it
>>>> only ever sizes them to pixel-aligned rects. The problem with GS's
>>>> current behaviour is it will make UI elements blurry if we get rid of
>>>> rounding in the backend.
>>>> 
>>>> Attached is a preliminary patch* which switches to Cocoa's behaviour.
>>>> I wanted to ask for feedback as to whether this is a reasonable patch
>>>> to apply.
>>>> 
>>>> The patch has to do a bit more than simply adding rounding to -
>>>> (void) resizeWithOldSuperviewSize: (NSSize)oldSize, because if we
>>>> just round _frame, we will lose track of where a view originally was.
>>>> I add a new ivar _autoresizingFrameError which stores the difference
>>>> between the rounded _frame, and what _frame would be without
>>>> rounding. The only slightly messy bit of the patch is that any parts
>>>> of the code that modify _frame directly should also set
>>>> _autoresizingFrameError to {0, 0}.
>>> 
>>> One result of this patch will be that calling -frame after a call to
>>> -setFrame: with fractional coordinates will return a different result
>>> than the one we provided.
>> 
>> Hm, that shouldn't be the case. -setFrame: still sets the _frame ivar to 
>> whatever it is passed, and -frame still returns _frame unmodified.
>> 
>> The only difference in -setFrame:'s behaviour (and all other methods that 
>> modified _frame directly) is that it will have the side effect of clearing 
>> the _autoresizingFrameError, but this isn't directly observable. The value 
>> of _autoresizingFrameError is only used inside -resizeWithOldSuperviewSize: 
>> to compute the new size.
> 
> Sorry, I was completely unclear in my previous mail. What I wanted to say was 
> that after setFrame: you may get back a different frame although the only 
> thing that happened was a call to super views setFrame: method with almost 
> identical values as it had before.

Hm, sorry, I still don't completely understand. :-( Could you show a code 
snippet if you have a chance?

> What I didn't realize was that this will get worse, when a rotation is 
> involved. The method -convertRectToBase: will return a much bigger rectangle 
> in that case and the call to -convertRectFromBase: will only make it worse.

Ah, good point. The rounding that I'm proposing for -resizeWithOldSuperviewSize 
should only be done if -[self isRotatedFromBase] is NO then.

>>> I just checked on Cocoa and as expected this
>>> isn't the case there. For this reason I am strongly against this patch,
>>> although I fully support the goal you are aiming at. We need to come up
>>> with a different way for it.
>> 
>> Assuming there isn't actually a problem I'm overlooking, the patch probably 
>> needs to add some extra documentation explaining what is going on :-)
>> 
>>> Basically wee need to ensure that all drawing operations that are
>>> initiated by the gui drawing code get pixel aligned. Somebody will have
>>> to test whether this is true for all drawing operations, that is, when I
>>> use an NSBezierPath with fractional coordinates to draw into a NSView,
>>> will the result be blurred? I expect this to be the case, which means that 
>>> we cannot put the pixel alignment directly into the backend, but need to do 
>>> it in our own drawing code. The next level would be the functions in 
>>> Functions.m. What will be the result if we feed them with fractional 
>>> coordinates? And so on to determine the level of intervention that is 
>>> needed.
>> 
>> Agreed. Most of that work is already done in GSTest's 
>> PixelExactDrawing-test, and you can toggle between what GS is rendering and 
>> a screen captures from OS X. Drawing with NSBezierPath and fractional 
>> coordinates should produce blurred output. Same for all of the ops in 
>> Functions.m which I've checked.
> 
> Thank you, I had forgotten about these new test cases. I will have to 
> recompile GSTest to see it.
> 
On a related note, I added a test case for autoresizing to 
Tests/gui/NSView/NSView_autoresize_and_rounding.m.

It looks like we have some differences from cocoa unrelated to rounding, but 
related to how extra space is divided between the lower margin, view size, and 
upper margin when NSViewMinXMargin or MaxXMargin is combined with 
NSViewWidthSizable.

> 
>>>> [*] One thing I would change in the patch is instead of rounding
>>>> using floor(), I would call -centerScanRect: so that the
>>>> pixel-alignment takes in to account the transformation matrix of the
>>>> current view.
>>> 
>>> Good point, this method seems to be better suited. Are you aware of the
>>> warnings in that method?
>> 
>> Yes. One thing we could do is simply return the passed rect unmodified if 
>> [[NSGraphicsContext currentContext] isDrawingToScreen] is NO. Not sure if 
>> Cocoa does that but it would make sense to, I think.
> 
> That would do.
> 
> _______________________________________________
> Gnustep-dev mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/gnustep-dev




reply via email to

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