It is currently Thu Jun 20, 2013 7:31 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Canvas & CGContext
PostPosted: Fri Aug 26, 2011 12:07 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
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.


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Fri Aug 26, 2011 5:01 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5184
Location: Germany
There is no CGContext. The drawing is done by direct pixel manipulation in memory.

_________________
Perl – The only language that looks the same before and after RSA encryption.
-- Keith Bostic


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Fri Aug 26, 2011 7:30 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
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.


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sat Aug 27, 2011 8:22 am 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
Is it allowed to create a context like this ?

Code:
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.

Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sat Aug 27, 2011 8:59 am 
Offline
Addict
Addict
User avatar

Joined: Sun Apr 27, 2003 8:12 am
Posts: 1624
Location: USA
Awesome wilbert! I was just reading about this earlier. Thanks! ;)

_________________
AMD 64 4000+ / 1GB PC2700 / WIN XP Home SP3 / Nvidia GT220 x16 512MB / M-Audio Revolution 5.1
Macbook Air 11.6" - 2010 / OS X 10.8

http://www.posemotion.com
http://www.flashpulse.com


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sat Aug 27, 2011 10:13 am 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 5:21 pm
Posts: 5184
Location: Germany
wilbert wrote:
Is it allowed to create a context like this ?


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.

Nice work btw.

_________________
Perl – The only language that looks the same before and after RSA encryption.
-- Keith Bostic


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sat Aug 27, 2011 5:34 pm 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
Thanks Freak.
I changed it so it's compatible now :D
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.


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sun Aug 28, 2011 5:47 am 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
I simplified some things and added some more imports

cgcontext.pbi
Code:
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


test code
Code:
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.

Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sun Aug 28, 2011 7:18 am 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 6466
I wish I had a mac so I could see how this looks. Any chance you could post a screenshot?

_________________
Veni, vidi, vici.


Top
 Profile  
 
 Post subject: Re: Canvas & CGContext
PostPosted: Sun Aug 28, 2011 7:58 am 
Offline
Addict
Addict

Joined: Sun Aug 08, 2004 5:21 am
Posts: 1109
Location: Netherlands
It doesn't show much Netmaestro. :oops:
I made it a little more complicated so it shows at least some curves. :)
Image
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye