Seite 1 von 1

[Erledigt] Cairo und CanvasGadget

Verfasst: 28.03.2013 00:15
von E-P-S
Hi zusammen,

ist es irgendwie möglich die CAIRO Funktionen gemeinsam mit einem CanvasGadget zu nutzen - also darauf zu zeichnen?

Im Cairo Beispiel wir der DC eines Fensters zum Zeichnen benutzt, was natürlich den Nachteil mit sich bringt das man dessen Events auswerten und bei einem WM_PAINT Ereignis den Inhalt erneuern muß. Das würde ich gerne umgehen und direkt in ein Canvas zeichnen, nur bekomme ich das überhaupt nicht hin.

Hat das schonmal jemand gemacht und könnte mir weiterhelfen?

Vielen Dank

Re: Cairo und CanvasGadget

Verfasst: 28.03.2013 00:21
von ts-soft
Keine Ahnung von Cairo, aber wenn Du dort den DC übergehen kannst, sollte dies hier helfen:

Code: Alles auswählen

hDC = StartDrawing(CanvasOutput(#canvas))

Re: Cairo und CanvasGadget

Verfasst: 28.03.2013 00:57
von E-P-S
Vielen Dank erstmal für die schnelle Antwort.

Nun ja, das ist so in etwa das Problem, denn man übergibt nicht direkt den DC, sondern aus dem DC wird ein Surface erstellt, welches wiederum dazu dient eine Cairo eigene "Struktur" anzulegen...

Beispiel:

Code: Alles auswählen

OpenWindow(1,10,10,600,620,"",#PB_Window_BorderLess)
  SetWindowColor(1,RGB(255,255,255))
  SetParent_(WindowID(1),WindowID(0))
  
  ; here you can create a surface for our cairo context
  ; in this Case it's the dc of our window 1, you can render
  ; in a gadget, window,  windowedscreen or a cairo surface.
  ; pdf , ps, png, svg files are supported too ;)
  
  su = cairo_win32_surface_create(GetDC_(WindowID(1))) 
  cr = cairo_create(su)
...
Das Problem ist das ich zwar mit deinem Code den DC bekomme, dieser aber bei jedem Aufruf anders ist, sprich - StartDrawing gibt jedesmal nen anderen Zeiger, Pointer was auch immer zurück. Somit stimmen auch SU und CR nicht mehr und müssen immer wieder neu erzeugt und/oder angelegt werden.

Prinzipiell geht das, ich finds nur irgendwie bescheuert und frage mich ob das nicht auch direkter geht.

Gibt es denn einen anderen Weg an den DC des Canvas Gadgets heranzukommen?

Re: Cairo und CanvasGadget

Verfasst: 28.03.2013 01:22
von Derren
Klappt das?

Code: Alles auswählen

su = cairo_win32_surface_create(GetDC_(GadgetID(#Canvas))) 
Ob damit dann aber nicht wieder direkt auf's Gadget gemalt wird, anstatt in den Puffer von PB (so habe ich das mit dem CanvasGadget und dem Vorteil gegenüber direkt aufs Fenster/ImageGadget malen verstanden), musst du mal testen.

Re: Cairo und CanvasGadget

Verfasst: 28.03.2013 01:33
von E-P-S
Klappt leider nicht.

Ich hab mal ein wenig in der Online Hilfe von Cairo geschmökert und - was ich vorher nicht wusste - es werden bei den beiden Funktionen lediglich Zeiger auf bestimmte Strukturen gesetzt, keine Images o.ä. angelegt (wie ich annahm).

Wie auch immer, mit dieser Erkenntnis hab ich mir dann zwei Prozeduren geschrieben die einfach vor und nach einer Cairo - Zeichenoperation aufgerufen werden. Sozusagen ein StartDrawing und StopDrawing Ersatz. Mit dieser Lösung kann ich durchaus leben.

Hier mal ein Codeschnipsel wie man das anwendet:

Code: Alles auswählen

XIncludeFile "cairo180.pbi"

Enumeration
  #Win
  #Canvas
EndEnumeration

;================================================================================
; Diese Prozedur ist vor jeder Cairo Zeichenoperation aufzurufen
;================================================================================
Procedure cairo_startdrawing( canvas )
  
  Protected su.i, cr.i
  su = cairo_win32_surface_create( StartDrawing( CanvasOutput( canvas ) ) )
  cr = cairo_create( su )
  cairo_surface_destroy( su ) 
  
  ProcedureReturn cr
  
EndProcedure

;================================================================================
; Diese Prozedur ist nach einer Cairo Zeichenoperation aufzurufen
;================================================================================
Procedure cairo_stopdrawing(cr)
  
  StopDrawing()
  cairo_destroy( cr )
  
EndProcedure

If OpenWindow( #Win, 0, 0, 800, 600, "Cairo-Canvas", #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
  
  CanvasGadget( #canvas, 0, 0, 640, 480 )
  
  ;Zeichne was
  cr = cairo_startdrawing( #canvas )
  
    ;cls
    cairo_set_source_rgb (cr, 1, 1, 1)
    cairo_paint (cr)

    cairo_set_source_rgb (cr, 0, 0, 0) 
    
    cairo_move_to (cr, 128.0, 25.6)
    cairo_line_to (cr, 230.4, 230.4)
    cairo_rel_line_to (cr, -102.4, 0.0)
    cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0)
    cairo_close_path (cr)
    
    cairo_move_to (cr, 64.0, 25.6)
    cairo_rel_line_to (cr, 51.2, 51.2)
    cairo_rel_line_to (cr, -51.2, 51.2)
    cairo_rel_line_to (cr, -51.2, -51.2)
    cairo_close_path (cr)
    
    cairo_set_line_width (cr, 10.0)
    cairo_set_source_rgb (cr, 0, 0, 1)
    cairo_fill_preserve (cr)
    cairo_set_source_rgb (cr, 0, 0, 0)
    cairo_stroke (cr)
  cairo_stopdrawing(cr)
  
  ;Zeichne nochmal was
  cr = cairo_startdrawing( #canvas )
    cairo_set_source_rgb (cr, 1, 0, 0) 
    xc = 128.0
    yc = 128.0
    
    Dim tdashes.d(4) 
    tdashes(0) = 50
    tdashes(1) = 10.0
    tdashes(2) = 10.0
    tdashes(3) = 10.0
    ndash  = 4
    offset = -50.0
    cairo_set_dash (cr, @tdashes(0), ndash, offset);
    cairo_set_line_width (cr, 2.0)
    cairo_move_to (cr, 428.5, 25.5)
    cairo_line_to (cr, 228.5, 128.5)
    cairo_rel_line_to (cr, -102.4, 0.0)
    cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0)
    cairo_stroke (cr)
  cairo_StopDrawing(cr)

Repeat
    events = WaitWindowEvent()
    Select events
      Case #PB_Event_Gadget
        Select EventGadget()
        EndSelect
      Case #PB_Event_CloseWindow  
        quit = 1
    EndSelect 
    
  Until quit = 1
    
EndIf
Vielen Dank.

Re: [Erledigt] Cairo und CanvasGadget

Verfasst: 28.03.2013 11:44
von Dadido3
Hallo,

Mal ne kleine Frage/Anmerkung zu dem Codeschnipsel:

Hab ich was übersehen, oder woher bekommt die Prozedur cairo_stopdrawing() die Variable cr?

Code: Alles auswählen

Procedure cairo_stopdrawing()
 
  StopDrawing()
  cairo_destroy( cr )
 
EndProcedure
Nicht dass sich leute, die den Code benutzen, sich später über Memoryleaks wundern ;)

Re: [Erledigt] Cairo und CanvasGadget

Verfasst: 28.03.2013 12:18
von E-P-S
upps...da hast du recht - hab es korrigiert. THX

Re: [Erledigt] Cairo und CanvasGadget

Verfasst: 28.03.2013 13:26
von Danilo
Aus einem alten Projekt:

Code: Alles auswählen

Procedure StartCanvasOutput(canvas)
  Shared CanvasOutput_hDC, CanvasOutput_su, CanvasOutput_cr
  CanvasOutput_hDC = StartDrawing( CanvasOutput( canvas ) )
  If CanvasOutput_hDC
    CanvasOutput_su = cairo_win32_surface_create(CanvasOutput_hDC)
    CanvasOutput_cr = cairo_create(CanvasOutput_su)
    ProcedureReturn CanvasOutput_cr
  EndIf
EndProcedure

Procedure StopCanvasOutput()
  Shared CanvasOutput_su, CanvasOutput_cr
  cairo_surface_destroy(CanvasOutput_su)
  cairo_destroy(CanvasOutput_cr)
  StopDrawing()
EndProcedure

Procedure StartSurfaceOutput(surface)
  ProcedureReturn cairo_create(surface)
EndProcedure

Procedure StopSurfaceOutput(cr)
  cairo_destroy(cr)
EndProcedure

Procedure Clear_cr_color(cr,r.f=1.0,g.f=1.0,b.f=1.0)
  cairo_set_source_rgb (cr, r, g, b)
  cairo_paint (cr)
EndProcedure

Procedure Clear_cr(cr)
  cairo_set_operator (cr, #CAIRO_OPERATOR_CLEAR)
  cairo_paint(cr)
EndProcedure