Canvas & CGContext
Canvas & CGContext
Is it possible to get a CGContextRef for a PureBasic canvas inside StartDrawing(CanvasOutput( )).
It would be great if it were possible to use OS X drawing functions to draw curves etc.
It would be great if it were possible to use OS X drawing functions to draw curves etc.
Re: Canvas & CGContext
There is no CGContext. The drawing is done by direct pixel manipulation in memory.
quidquid Latine dictum sit altum videtur
Re: Canvas & CGContext
Thanks for the answer.
I hoped it would be possible. I guess the only workaround is to create a cgimage and draw that onto the canvas.
I hoped it would be possible. I guess the only workaround is to create a cgimage and draw that onto the canvas.
Re: Canvas & CGContext
Is it allowed to create a context like this ?
Code: Select all
Structure ColorComponents
r.f
g.f
b.f
a.f
EndStructure
ImportC ""
; colorspace functions
CGColorSpaceCreateDeviceRGB()
CGColorSpaceRelease(colorspace)
; bitmapcontext functions
CGBitmapContextCreate(*bdata, width, height, bitsPerComponent, bytesPerRow, colorspace, bitmapInfo)
CGContextRelease(context)
; cgcontext functions to init and restore / release some things
CGContextSaveGState(context)
CGContextRestoreGState(context)
CGContextScaleCTM(context, sx.f, sy.f)
CGContextTranslateCTM(context, tx.f, ty.f)
CGContextSetStrokeColorSpace(context, colorspace)
CGContextSetFillColorSpace(context, colorspace)
; cgcontext drawing related functions
CGContextSetStrokeColor(context, color)
CGContextSetFillColor(context, color)
CGContextClearRect(context, x.f, y.f, w.f, h.f)
CGContextBeginPath(context)
CGContextMoveToPoint(context, x.f, y.f)
CGContextAddLineToPoint(context, x.f, y.f)
CGContextAddArc(context, x.f, y.f, radius.f, startAngle.f, endAngle.f, clockwise)
CGContextClosePath(context)
CGContextStrokePath(context)
CGContextFillPath(context)
CGContextSetShadow(context, x_offset.f, y_offset.f, blur.f)
CGContextFillRect(context, x.f, y.f, w.f, h.f)
EndImport
Procedure RenderOnCanvas(canvas)
Protected cv_w, cv_h, csRGB, ctx
Protected color.ColorComponents
If StartDrawing(CanvasOutput(canvas))
; init some things
cv_w = OutputWidth()
cv_h = OutputHeight()
csRGB = CGColorSpaceCreateDeviceRGB()
ctx = CGBitmapContextCreate(DrawingBuffer(), cv_w, cv_h, 8, cv_w << 2, csRGB, 1)
CGContextScaleCTM(ctx, 1, -1)
CGContextTranslateCTM(ctx, 0, -cv_h)
CGContextSetStrokeColorSpace(ctx, csRGB)
CGContextSetFillColorSpace(ctx, csRGB)
; actual drawing
CGContextSetShadow(ctx, 2, -2, 2)
color\r = 1
color\g = 0.5
color\b = 0
color\a = 1
CGContextSetFillColor(ctx, color)
CGContextFillRect(ctx, 5, 5, 50, 50)
color\r = 0.5
color\g = 1
color\b = 0
color\a = 1
CGContextSetFillColor(ctx, color)
CGContextBeginPath(ctx)
CGContextAddArc(ctx, 80, 80, 25, 0, #PI, #True)
CGContextFillPath(ctx)
; release some things
CGContextRelease(ctx)
CGColorSpaceRelease(csRGB)
StopDrawing()
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 320, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 10, 10, 300, 200)
RenderOnCanvas(0)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Last edited by wilbert on Sat Aug 27, 2011 5:46 pm, edited 2 times in total.
Re: Canvas & CGContext
Awesome wilbert! I was just reading about this earlier. Thanks!
www.posemotion.com
PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef
Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT
Even the vine knows it surroundings but the man with eyes does not.
PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef
Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT
Even the vine knows it surroundings but the man with eyes does not.
Re: Canvas & CGContext
The fact that StartDrawing() returns the pixel data pointer for the canvas on OSX is not documented. While i don't think this will really change, its not good to rely on it. If you use the DrawingBuffer() command, you will get the same pointer but it will be more future proof.wilbert wrote:Is it allowed to create a context like this ?
Nice work btw.
quidquid Latine dictum sit altum videtur
Re: Canvas & CGContext
Thanks Freak.
I changed it so it's compatible now
It also works on images if you use ImageOutput instead of CanvasOutput.
A little note ...
The coordinate space of a CGContext is vertically flipped comparing to that of PureBasic.
To make it in line with what PureBasic uses, I used CGContextScaleCTM and CGContextTranslateCTM.
This doesn't affect the shadow so the y_offset of the shadow is a bit illogical now.
I changed it so it's compatible now
It also works on images if you use ImageOutput instead of CanvasOutput.
A little note ...
The coordinate space of a CGContext is vertically flipped comparing to that of PureBasic.
To make it in line with what PureBasic uses, I used CGContextScaleCTM and CGContextTranslateCTM.
This doesn't affect the shadow so the y_offset of the shadow is a bit illogical now.
Re: Canvas & CGContext
I simplified some things and added some more imports
cgcontext.pbi
test code
cgcontext.pbi
Code: Select all
Enumeration
#kCGLineJoinMiter
#kCGLineJoinRound
#kCGLineJoinBevel
EndEnumeration
Enumeration
#kCGLineCapButt
#kCGLineCapRound
#kCGLineCapSquare
EndEnumeration
Enumeration
#kCGPathFill
#kCGPathEOFill
#kCGPathStroke
#kCGPathFillStroke
#kCGPathEOFillStroke
EndEnumeration
Enumeration
#kCGBlendModeNormal
#kCGBlendModeMultiply
#kCGBlendModeScreen
#kCGBlendModeOverlay
#kCGBlendModeDarken
#kCGBlendModeLighten
#kCGBlendModeColorDodge
#kCGBlendModeColorBurn
#kCGBlendModeSoftLight
#kCGBlendModeHardLight
#kCGBlendModeDifference
#kCGBlendModeExclusion
#kCGBlendModeHue
#kCGBlendModeSaturation
#kCGBlendModeColor
#kCGBlendModeLuminosity
EndEnumeration
ImportC ""
; colorspace functions
CGColorSpaceCreateDeviceRGB()
CGColorSpaceRelease(colorspace)
; bitmapcontext functions
CGBitmapContextCreate(*bdata, width, height, bitsPerComponent, bytesPerRow, colorspace, bitmapInfo)
CGContextRelease(context)
; cgcontext functions to init and restore / release some things
CGContextSaveGState(context)
CGContextRestoreGState(context)
CGContextScaleCTM(context, sx.f, sy.f)
CGContextTranslateCTM(context, tx.f, ty.f)
CGContextSetStrokeColorSpace(context, colorspace)
CGContextSetFillColorSpace(context, colorspace)
CGContextSetStrokeColor(context, color)
CGContextSetFillColor(context, color)
; cgcontext drawing related functions
CGContextAddArc(context, x.f, y.f, radius.f, startAngle.f, endAngle.f, clockwise)
CGContextAddArcToPoint(context, x1.f, y1.f, x2.f, y2.f, radius.f)
CGContextAddCurveToPoint(context, cp1x.f, cp1y.f, cp2x.f, cp2y.f, x.f, y.f)
CGContextAddEllipseInRect(context, x.f, y.f, w.f, h.f)
CGContextAddLineToPoint(context, x.f, y.f)
CGContextAddQuadCurveToPoint(context, cpx.f, cpy.f, x.f, y.f)
CGContextAddRect(context, x.f, y.f, w.f, h.f)
CGContextBeginPath(context)
CGContextClearRect(context, x.f, y.f, w.f, h.f)
CGContextClosePath(context)
CGContextDrawImage(context, x.f, y.f, w.f, h.f, image)
CGContextDrawPath(context, mode)
CGContextDrawTiledImage(context, x.f, y.f, w.f, h.f, image)
CGContextFillEllipseInRect(context, x.f, y.f, w.f, h.f)
CGContextFillPath(context)
CGContextFillRect(context, x.f, y.f, w.f, h.f)
CGContextMoveToPoint(context, x.f, y.f)
CGContextSetAlpha(context, alpha.f)
CGContextSetBlendMode(context, mode)
CGContextSetLineCap(context, cap)
CGContextSetLineJoin(context, join)
CGContextSetLineWidth(context, width.f)
CGContextSetMiterLimit(context, limit.f)
CGContextSetShadow(context, x_offset.f, y_offset.f, blur.f)
CGContextSetShadowWithColor(context, x_offset.f, y_offset.f, blur.f, cgcolor)
CGContextStrokeEllipseInRect(context, x.f, y.f, w.f, h.f)
CGContextStrokePath(context)
CGContextStrokeRect(context, x.f, y.f, w.f, h.f)
CGContextStrokeRectWithWidth(context, x.f, y.f, w.f, h.f, width.f)
EndImport
Procedure CGContextCreate(flipped = #True)
Protected w, h, csRGB, ctx
w = OutputWidth()
h = OutputHeight()
csRGB = CGColorSpaceCreateDeviceRGB()
ctx = CGBitmapContextCreate(DrawingBuffer(), w, h, 8, w << 2, csRGB, 1)
If flipped
CGContextScaleCTM(ctx, 1, -1)
CGContextTranslateCTM(ctx, 0, -h)
EndIf
CGContextSetStrokeColorSpace(ctx, csRGB)
CGContextSetFillColorSpace(ctx, csRGB)
CGColorSpaceRelease(csRGB)
ProcedureReturn ctx
EndProcedure
Procedure CGContextSetStrokeColorRGB(ctx, r.f, g.f, b.f, a.f = 1.0)
CGContextSetStrokeColor(ctx, @r)
EndProcedure
Procedure CGContextSetFillColorRGB(ctx, r.f, g.f, b.f, a.f = 1.0)
CGContextSetFillColor(ctx, @r)
EndProcedure
Procedure CGContextClearShadow(ctx)
CGContextSetShadowWithColor(ctx, 0, 0, 0, #Null)
EndProcedure
Code: Select all
IncludeFile "cgcontext.pbi"
Procedure RenderOnCanvas(canvas)
Protected ctx
If StartDrawing(CanvasOutput(canvas))
; create a context
ctx = CGContextCreate()
; drawing
CGContextSetShadow(ctx, 2, -2, 2)
CGContextSetFillColorRGB(ctx, 1, 0.5, 0)
CGContextFillRect(ctx, 5, 5, 50, 50)
CGContextFillRect(ctx, 105, 105, 50, 50)
CGContextSetStrokeColorRGB(ctx, 0.9, 0.9, 0)
CGContextSetFillColorRGB(ctx, 0.5, 1, 0)
CGContextSetLineWidth(ctx, 2)
CGContextClearShadow(ctx)
CGContextBeginPath(ctx)
CGContextAddArc(ctx, 80, 80, 25, #PI, 0, #True)
CGContextAddQuadCurveToPoint(ctx, 130, 120, 105, 140)
CGContextAddQuadCurveToPoint(ctx, 80, 160, 40, 140)
CGContextDrawPath(ctx, #kCGPathFillStroke)
; release context and stop drawing
CGContextRelease(ctx)
StopDrawing()
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 320, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 10, 10, 300, 200)
RenderOnCanvas(0)
Repeat
Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
EndIf
Last edited by wilbert on Sun Aug 28, 2011 8:03 am, edited 2 times in total.
- netmaestro
- PureBasic Bullfrog
- Posts: 8433
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Canvas & CGContext
I wish I had a mac so I could see how this looks. Any chance you could post a screenshot?
BERESHEIT
Re: Canvas & CGContext
It doesn't show much Netmaestro.
I made it a little more complicated so it shows at least some curves.
The advantage of CGContext functions is that you can draw arcs, curves, use blend modes, transparency and that everything is antialiased.
It should make it easier to create better looking canvas examples.
I made it a little more complicated so it shows at least some curves.
The advantage of CGContext functions is that you can draw arcs, curves, use blend modes, transparency and that everything is antialiased.
It should make it easier to create better looking canvas examples.
Last edited by wilbert on Wed May 31, 2017 3:13 pm, edited 1 time in total.
Re: Canvas & CGContext
Hi there,
I compiled this code (PB 5.51), but it only shows a blank canvas. Is it supposed to work still or do internal changes in PB made since 2011 make it impossible?
I compiled this code (PB 5.51), but it only shows a blank canvas. Is it supposed to work still or do internal changes in PB made since 2011 make it impossible?
Re: Canvas & CGContext
The drawing function imports in its current form are only working on the 32 bit version of PureBasic.
Making it work on x64 isn't straightforward and would require a lot of changes.
If it has enough functionality for you, I recommend using the PureBasic VectorDrawing library.
It wasn't available when the code was created but serves more or less the same purpose and has the advantage of being cross platform.
Making it work on x64 isn't straightforward and would require a lot of changes.
If it has enough functionality for you, I recommend using the PureBasic VectorDrawing library.
It wasn't available when the code was created but serves more or less the same purpose and has the advantage of being cross platform.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: Canvas & CGContext
Thanks Wilbert.
Actually I was not to much in the Path-Function. I was rather looking for a way to make the CanvasGadget display in Retina resolution. Thought that the CGContext* functions might be a possibility, when adjusting the NSSize of the image (as suggested in http://www.purebasic.fr/english/viewtop ... 11#p442611, which works perfectly for a ImageGadget) and drawing the image it directly on the canvas CGContextRef.
Actually I was not to much in the Path-Function. I was rather looking for a way to make the CanvasGadget display in Retina resolution. Thought that the CGContext* functions might be a possibility, when adjusting the NSSize of the image (as suggested in http://www.purebasic.fr/english/viewtop ... 11#p442611, which works perfectly for a ImageGadget) and drawing the image it directly on the canvas CGContextRef.