Should I pixel align in a View subclass in method -initWithFrame:frame?

  • This is a continuation of my previous issue stroking a bezier path.
    In my sub-class -initWithFrame:frame I do the following:
        self = [super initWithFrame:frame];
        if (self) {
            // Initialization code here.
            frame.size.width = 200.0;
            frame.size.height = 200.0;
            frame.origin.x = 50.0;
            frame.origin.y = 50.0;

    Should I be pixel aligning it? And is this the correct way?
    frame = [self convertRectToBacking: frame];
    frame = [self convertRectFromBacking: frame];

    [self setFrame:frame];
    [self setNeedsDisplay:YES];
      … ….

    Thanks….
  • On May 8, 2012, at 3:16 PM, Peter Teeson <pteeson...> wrote:

    > This is a continuation of my previous issue stroking a bezier path.

    Hi Peter, I'm not sure what issue you were having.
    WRT:

    > In my sub-class -initWithFrame:frame I do the following:
    > self = [super initWithFrame:frame];
    > if (self) {
    > // Initialization code here.
    > frame.size.width = 200.0;
    > frame.size.height = 200.0;
    > frame.origin.x = 50.0;
    > frame.origin.y = 50.0;
    >
    > Should I be pixel aligning it?

    Your code above is already point aligned, there for it is pixel aligned. If the frame was say 200.2 or 200.5, then you should pixel align it.

    > And is this the correct way?
    > frame = [self convertRectToBacking: frame];
    > frame = [self convertRectFromBacking: frame];

    The above code doesn't do anything except convert back and forth. Say you have a frame origin of 200.5 that you want to be pixel aligned, you would do this:

    > frame = [self convertRectToBacking: frame];

    Floor in "pixel space".
    frame.origin.x = floor(frame.origin.x);

    > frame = [self convertRectFromBacking: frame];

    Now frame is pixel aligned and is back in "point space".

    corbin

    >
    > [self setFrame:frame];
    > [self setNeedsDisplay:YES];
    > … ….
    >
    >
    > Thanks….
  • On May 8, 2012, at 3:16 PM, Peter Teeson wrote:

    > This is a continuation of my previous issue stroking a bezier path.
    > In my sub-class -initWithFrame:frame I do the following:
    > self = [super initWithFrame:frame];
    > if (self) {
    > // Initialization code here.
    > frame.size.width = 200.0;
    > frame.size.height = 200.0;
    > frame.origin.x = 50.0;
    > frame.origin.y = 50.0;
    >
    > Should I be pixel aligning it? And is this the correct way?

    No, you should treat the view coordinate system as abstract and only pixel align (using -centerScanRect:) when you need to.

    Since Quartz coordinates refer to the infinitely-thin space between pixels, the area bounded by a rectangle defined by four points is already pixel aligned. You only need to shift your coordinates if you want a _line segment_ defined by two points to cover whole pixels. This is why you were having issues before, since strokes are applied to line segments while fills are applied to the area bounded by line segments.

    This terminology starts to break down a bit when HiDPI gets involved. Where you see "pixel" in the above paragraph, think of an idealized "device-independent pixel" which maps directly to real device pixels at 1x (normal) scale factor. "Pixel" is actually a misnomer here, but there's no real good alternative term for "a unit square 1pt on each side," since the term "point" also refers to the infinitely-small location in the coordinate space that is identified by a coordinate.

    And thankfully we only have 1x and 2x scale factors now. Previously we had 1.25x and 1.5x factors as well, which made dealing with fractional coordinates even more confusing.

    --Kyle Sluder
  • On May 8, 2012, at 3:44 PM, Kyle Sluder <kyle...> wrote:

    > On May 8, 2012, at 3:16 PM, Peter Teeson wrote:
    >
    >> This is a continuation of my previous issue stroking a bezier path.
    >> In my sub-class -initWithFrame:frame I do the following:
    >> self = [super initWithFrame:frame];
    >> if (self) {
    >> // Initialization code here.
    >> frame.size.width = 200.0;
    >> frame.size.height = 200.0;
    >> frame.origin.x = 50.0;
    >> frame.origin.y = 50.0;
    >>
    >> Should I be pixel aligning it? And is this the correct way?
    >
    > No, you should treat the view coordinate system as abstract and only pixel align (using -centerScanRect:) when you need to.

    Or the more modern:

    - (NSRect)backingAlignedRect:(NSRect)aRect options:(NSAlignmentOptions)options

    corbin

    > Since Quartz coordinates refer to the infinitely-thin space between pixels, the area bounded by a rectangle defined by four points is already pixel aligned. You only need to shift your coordinates if you want a _line segment_ defined by two points to cover whole pixels. This is why you were having issues before, since strokes are applied to line segments while fills are applied to the area bounded by line segments.
    >
    > This terminology starts to break down a bit when HiDPI gets involved. Where you see "pixel" in the above paragraph, think of an idealized "device-independent pixel" which maps directly to real device pixels at 1x (normal) scale factor. "Pixel" is actually a misnomer here, but there's no real good alternative term for "a unit square 1pt on each side," since the term "point" also refers to the infinitely-small location in the coordinate space that is identified by a coordinate.
    >
    > And thankfully we only have 1x and 2x scale factors now. Previously we had 1.25x and 1.5x factors as well, which made dealing with fractional coordinates even more confusing.
    >
    > --Kyle Sluder
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today