Cairo unter Autoit nutzen

  • Cairo scheint eine schicke 2D Grafikbibliothek zu sein, die auch auf anderen Plattformen wie Linux läuft. Ich habe einige Beispiele in Freebasic gesehen und dachte mir, warum auch nicht in Autoit.

    Ein Manual gibt es hier: https://www.cairographics.org/manual/

    Die Cairo UDF: Cairo.au3


    Beispiel:


    Soweit funktioniert das Beispiel, nur wenn ich die Position über eine Variable in der cairo_rectangle Funktion hinzufüge, dann passiert nichts mehr.

    Ich habe nicht herausgefunden, was man tun muss, damit auch Animationen möglich sind. Somit könnte man Cairo mit GDI / GDI+ vergleichen.

    Die benötigten DLLs sind im Anhang zu finden.


    Hat jemand eine Idee?

  • nur wenn ich die Position über eine Variable in der cairo_rectangle Funktion hinzufüge, dann passiert nichts mehr.

    Ich verstehe noch nicht ganz die Problemlage.
    Du verwendest doch bereits Variablen für die Positionsparameter.
    Und augenscheinlich funtkionieren diese bei mir auch.

    Hab es auch mal so angepasst, dass sie sich ändern und das ganze daher animiert wird:

    Auch das funktioniert bei mir wunderbar.
    Ich habe dein Problem also offensichtlich noch nicht ganz verstanden.

  • Hallo AspirinJunkie,

    danke für dein Feedback.

    Wenn du einfach die Zeile durch diese ersetzt,

    Code
    DllCall($g_hCairoDLL, "none:cdecl", "cairo_rectangle", "ptr",  $pContext, "double", $t + $iW / 4, "double", $iH / 4, "double", $iW / 2, "double", $iH / 2)

    dann sollte die Grafik gelöscht werden und weiter passiert nichts. Eigentlich sollte das Viereck nach rechts wandern.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Moin UEZ

    ich bin nicht sicher, meinst Du so etwas?

  • Velted Moin.

    Genau, das meine ich, aber warum funktioniert nicht das, wenn ich dies im DllCall eintrage.

    Hmmm...

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Wenn ich Round($t + $iW / 4) eintrage, dann geht es wieder.
    Offensichtlich dürfen dort nur ganzzahlige Werte eingetragen werden.
    Das widerspricht aber bisschen dem Double-Typ.
    Da hätte man ja gleich einen Integer dafür nehmen können.
    Vielleicht verstehen wir da was prinzipielles noch nicht.

  • Genau das habe ich auch eben getestet - Integer funktioniert, Gleitkommazahlen nicht! Laut Definition sollte es aber Double sein!?!!??!

    Code
    void
    cairo_rectangle (cairo_t *cr,
                     double x,
                     double y,
                     double width,
                     double height);

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    Einmal editiert, zuletzt von UEZ (24. März 2024 um 18:08)

  • Ja du übergibst es ja auch als Double.
    Integer 5 ist anders kodiert als 5.0 Double.
    Und DllCall übergibt eben als Double.
    Integer zu übergeben wird daher nicht funktionieren.

    Das heißt im Grunde, man kann nur ganzzahlige Werte übergeben aber dennoch als Double kodiert.
    Was für ein Unsinn.

  • Was für ein Unsinn.

    Und DllCall($g_hCairoDLL, "none:cdecl", "cairo_set_line_width", "ptr", $pContext, "double", $iH / 10) scheint nur mit ganzen geraden Zahlen zu funktionieren...:huh:


    Wie auch immer, danke für euer Feedback. Gehe jetzt aber mal in die Mucki Bude mich abreagieren...:)

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Irgendwie schaffe ich es nicht eine Linie zu ziehen oder einen Kreis zu zeichnen, das angezeigt wird.

    Hat jemand eine Idee, woran das liegen könnte?

    Kreis:

    Code
    DllCall($g_hCairoDLL, "none:cdecl", "cairo_arc", "ptr", $pContext, "double", ($iW / 2), "double", ($iH / 2), "double", 100, "double", 0, "double", 2 * $fPi)
    		DllCall($g_hCairoDLL, "none:cdecl", "cairo_fill", "ptr", $pContext)

    Linie:

    Code
    		DllCall($g_hCairoDLL, "none:cdecl", "cairo_move_to", "ptr", $pSurface, "double", $x, "double", $y)
    		DllCall($g_hCairoDLL, "none:cdecl", "cairo_line_to", "ptr", $pSurface, "double", $iW, "double", $iH)
    		DllCall($g_hCairoDLL, "none:cdecl", "cairo_stroke", "ptr", $pContext)


    Danke.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Moin,

    ich habe mich gestern lange und intensiv mit den Beipielen beschäftigt. Dabei hatte ich immer wieder Rückschläge, die ich mir nicht erklären konnte. Kurz vor dem endgültigem Aufgeben entstand dann aber doch noch eine (überwiegend) funktionierende Lösung. Nach verdienter Nachtruhe habe ich die noch etwas aufgebohrt und bin jetzt recht zufrieden damit.

    Ich wollte von vornherein ohne Umwege über Bitmaps/BitBlts direkt mit dem DC arbeiten. Nach vielem Try&Error habe ich dann folgendes in der Cairo-Doku gelesen:

    Zitat

    The resulting surface will always be of format CAIRO_FORMAT_RGB24; should you need another surface format, you will need to create one through cairo_win32_surface_create_with_format() or cairo_win32_surface_create_with_dib().

    Windows unterstützt seit Version 8 nur noch 32-Bit (A)RGB. Das scheint nicht so recht zu cairo_win32_surface_create () passen. Ich habe deshalb für Win 10 die Funktion Cairo_CreateWin32SurfaceWithFormat mit $CAIRO_FORMAT_ARGB32 aufgerufen, und siehe, alles lief deutlich besser. Beim Versuch, ein Control als Zeichenfläche zu nutzen, musste ich zunächst feststellen, dass Cairo den gesamten Clientbereich des Elternfensters übermalt. Die Erklärung fand sich hier:

    Zitat

    The DC will be queried for its initial clip extents, and this will be used as the size of the cairo surface.

    Ich habe einfach mal vermutet, dass da etwas nicht passt, und eine passende Clipping-Region gesetzt. Das hatte tatsächlich den gewünschten Erfolg.

    Lange Rede, kurzer Sinn, hier kommt das Ergebnis all meiner Mühe. Es läuft hier stabil mit den DLLs aus dem ersten Beitrag mit 32 und 64 Bit:

  • Nachschlag für UEZ

    Code
            DllCall($g_hCairoDLL, "none:cdecl", "cairo_move_to", "ptr", $pSurface, "double", $x, "double", $y)
            DllCall($g_hCairoDLL, "none:cdecl", "cairo_line_to", "ptr", $pSurface, "double", $iW, "double", $iH)
            DllCall($g_hCairoDLL, "none:cdecl", "cairo_stroke", "ptr", $pContext)

    Das kann nicht funktionieren, weil Du versuchst, auf $pSurface zu zeichnen.

  • Danke Velted fürs Nachforschen und das Erstellen des Beispiels :thumbup:. Die ursprünglichen zwei DLLs funktionieren, und machen keine Probleme. Das Problem war anscheinend mein Code.

    Nachschlag für UEZ

    Code
            DllCall($g_hCairoDLL, "none:cdecl", "cairo_move_to", "ptr", $pSurface, "double", $x, "double", $y)
            DllCall($g_hCairoDLL, "none:cdecl", "cairo_line_to", "ptr", $pSurface, "double", $iW, "double", $iH)
            DllCall($g_hCairoDLL, "none:cdecl", "cairo_stroke", "ptr", $pContext)

    Das kann nicht funktionieren, weil Du versuchst, auf $pSurface zu zeichnen.

    Ich Idiot und ich suche mir einen Wolf, warum das nicht funzt.

    Hier der Code, welches auch bei mir funzt:

    Ich werde weitere Möglichkeiten checken, wie man Cairo unter Windows noch initiieren kann.

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Ich habe weitere Funktionen portiert (siehe Anhang).

    Hier ein weiteres Beispiel.


    Ich habe massiv die UDF geändert, d.h. die UDF im 1. Post wird nicht funktionieren und die UDF im Anhang unten kann noch viele Copy/Paste oder andere Fehler beinhalten! Die DLL kann im 1. Post heruntergeladen werden.


    Habt ihr Lust Beispiele zu erstellen? Dann bitte hier Posten. :)


    Etliche Funktionen sind noch nicht portiert, aber ich arbeite daran...


    Happy Ostern!