But that’s precisely what’s happening. CG can render geometry with subpixel accuracy, so when the coordinates are clamped to integers it’s accurately rendering those warbled coordinates.
To be fair I was passing the float values directly to DrawLine which effectively Floors the value. By Rounding there’s less warble but it’s definitely still happening.
So wait, you do see the issue?
Maybe I misunderstand your point too. I thought it was along the lines of ‘you don’t lose anything with just integers’ so I’m trying to point out that CG does have the capability of floats and integers impose a slight limitation. I do wonder why Graphics uses integers. Did way back when one or the other OSes not support floats? Could Xojo add floats and be backwards compatible?
Here’s the smallest demo I could make. First some float coordinates are made, then drawn with Graphics, then CG, then CG again with rounded values to show it’s the same as Graphics. (Note there’s better ways to draw a curve in cg but this code is replicating individual DrawLines).
[code]Sub Paint(g As Graphics, areas() As REALbasic.Rect)
//create shape
dim x(), y() As CGFloat
for i As integer = 0 to 110
x.Append 10 + i * 1.72
y.Append 10 + (i/55)^2 * 30
next
//draw with integers
g.ForeColor = &c000000
g.PenWidth = 2
for i As integer = 0 to x.Ubound-1
'g.DrawLine x(i), y(i), x(i+1), y(i+1) //flooring
g.DrawLine Round(x(i)), Round(y(i)), Round(x(i+1)), Round(y(i+1))
next
//setup cg
const cglib = “CoreGraphics”
declare sub CGContextScaleCTM lib cglib (cntxt As Ptr, sx As CGFloat, sy As CGFloat)
declare sub CGContextTranslateCTM lib cglib (cntxt As Ptr, tx As CGFloat, ty As CGFloat)
declare sub CGContextSetRGBStrokeColor lib cglib (cntxt As Ptr, r As CGFloat, g As CGFloat, b As CGFloat, a As CGFloat)
declare sub CGContextSetLineWidth lib cglib (c As Ptr, width As CGFloat)
declare sub CGContextMoveToPoint lib cglib (context As Ptr, x As CGFloat, y As CGFloat)
declare sub CGContextAddLineToPoint lib cglib (context As Ptr, x As CGFloat, y As CGFloat)
declare sub CGContextStrokePath lib cglib (cntxt As Ptr)
dim cntxt As Ptr = Ptr( g.Handle(Graphics.HandleTypeCGContextRef) )
CGContextScaleCTM(cntxt, 1, -1)
CGContextTranslateCTM(cntxt, 0, -g.Height)
//draw with cg, shifted down 100 and float
CGContextSetRGBStrokeColor(cntxt, 0, 0, 0, 1)
CGContextSetLineWidth(cntxt, 2)
for i As integer = 0 to x.Ubound-1
CGContextMoveToPoint(cntxt, x(i), y(i) + 100)
CGContextAddLineToPoint(cntxt, x(i+1), y(i+1) + 100)
CGContextStrokePath(cntxt)
next
//draw with cg, shifted down 200 and clamped to integer
CGContextSetRGBStrokeColor(cntxt, 0, 0, 0, 1)
CGContextSetLineWidth(cntxt, 2)
for i As integer = 0 to x.Ubound-1
CGContextMoveToPoint(cntxt, Round(x(i)), Round(y(i)) + 200)
CGContextAddLineToPoint(cntxt, Round(x(i+1)), Round(y(i+1)) + 200)
CGContextStrokePath(cntxt)
next
End Sub[/code]
screencapture in retina mode…