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
AutoIt: Cairo.au3
;Ported to Autoit by UEZ build 2024-03-24
#include-once
#Region enums and constants
;cairo_status as long
Global Enum $CAIRO_STATUS_SUCCESS = 0, $CAIRO_STATUS_NO_MEMORY, $CAIRO_STATUS_INVALID_RESTORE, $CAIRO_STATUS_INVALID_POP_GROUP, $CAIRO_STATUS_NO_CURRENT_POINT, $CAIRO_STATUS_INVALID_MATRIX, _
$CAIRO_STATUS_INVALID_STATUS, $CAIRO_STATUS_NULL_POINTER, $CAIRO_STATUS_INVALID_STRING, $CAIRO_STATUS_INVALID_PATH_DATA, $CAIRO_STATUS_READ_ERROR, $CAIRO_STATUS_WRITE_ERROR, _
$CAIRO_STATUS_SURFACE_FINISHED, $CAIRO_STATUS_SURFACE_TYPE_MISMATCH, $CAIRO_STATUS_PATTERN_TYPE_MISMATCH, $CAIRO_STATUS_INVALID_CONTENT, $CAIRO_STATUS_INVALID_FORMAT, $CAIRO_STATUS_INVALID_VISUAL, _
$CAIRO_STATUS_FILE_NOT_FOUND, $CAIRO_STATUS_INVALID_DASH, $CAIRO_STATUS_INVALID_DSC_COMMENT, $CAIRO_STATUS_INVALID_INDEX, $CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, $CAIRO_STATUS_TEMP_FILE_ERROR, _
$CAIRO_STATUS_INVALID_STRIDE, $CAIRO_STATUS_FONT_TYPE_MISMATCH, $CAIRO_STATUS_USER_FONT_IMMUTABLE, $CAIRO_STATUS_USER_FONT_ERROR, $CAIRO_STATUS_NEGATIVE_COUNT, $CAIRO_STATUS_INVALID_CLUSTERS, _
$CAIRO_STATUS_INVALID_SLANT, $CAIRO_STATUS_INVALID_WEIGHT, $CAIRO_STATUS_INVALID_SIZE, $CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, $CAIRO_STATUS_DEVICE_TYPE_MISMATCH, $CAIRO_STATUS_DEVICE_ERROR, _
$CAIRO_STATUS_INVALID_MESH_CONSTRUCTION, $CAIRO_STATUS_DEVICE_FINISHED, $CAIRO_STATUS_JBIG2_GLOBAL_MISSING, $CAIRO_STATUS_LAST_STATUS
Global Const $g_aCairoStatus[] = ["CAIRO_STATUS_SUCCESS", "CAIRO_STATUS_NO_MEMORY", "CAIRO_STATUS_INVALID_RESTORE", "CAIRO_STATUS_INVALID_POP_GROUP", "CAIRO_STATUS_NO_CURRENT_POINT", "CAIRO_STATUS_INVALID_MATRIX", _
"CAIRO_STATUS_INVALID_STATUS", "CAIRO_STATUS_NULL_POINTER", "CAIRO_STATUS_INVALID_STRING", "CAIRO_STATUS_INVALID_PATH_DATA", "CAIRO_STATUS_READ_ERROR", "CAIRO_STATUS_WRITE_ERROR", _
"CAIRO_STATUS_SURFACE_FINISHED", "CAIRO_STATUS_SURFACE_TYPE_MISMATCH", "CAIRO_STATUS_PATTERN_TYPE_MISMATCH", "CAIRO_STATUS_INVALID_CONTENT", "CAIRO_STATUS_INVALID_FORMAT", "CAIRO_STATUS_INVALID_VISUAL", _
"CAIRO_STATUS_FILE_NOT_FOUND", "CAIRO_STATUS_INVALID_DASH", "CAIRO_STATUS_INVALID_DSC_COMMENT", "CAIRO_STATUS_INVALID_INDEX", "CAIRO_STATUS_CLIP_NOT_REPRESENTABLE", "CAIRO_STATUS_TEMP_FILE_ERROR", _
"CAIRO_STATUS_INVALID_STRIDE", "CAIRO_STATUS_FONT_TYPE_MISMATCH", "CAIRO_STATUS_USER_FONT_IMMUTABLE", "CAIRO_STATUS_USER_FONT_ERROR", "CAIRO_STATUS_NEGATIVE_COUNT", "CAIRO_STATUS_INVALID_CLUSTERS", _
"CAIRO_STATUS_INVALID_SLANT", "CAIRO_STATUS_INVALID_WEIGHT", "CAIRO_STATUS_INVALID_SIZE", "CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED", "CAIRO_STATUS_DEVICE_TYPE_MISMATCH", "CAIRO_STATUS_DEVICE_ERROR", _
"CAIRO_STATUS_INVALID_MESH_CONSTRUCTION", "CAIRO_STATUS_DEVICE_FINISHED", "CAIRO_STATUS_JBIG2_GLOBAL_MISSING", "CAIRO_STATUS_LAST_STATUS"]
;cairo_format as long
Global Enum $CAIRO_FORMAT_INVALID = -1, $CAIRO_FORMAT_ARGB32, $CAIRO_FORMAT_RGB24, $CAIRO_FORMAT_A8, $CAIRO_FORMAT_A1, $CAIRO_FORMAT_RGB16_565, $CAIRO_FORMAT_RGB30
;cairo_operator as long
Global Enum $CAIRO_OPERATOR_CLEAR, $CAIRO_OPERATOR_SOURCE, $CAIRO_OPERATOR_OVER, $CAIRO_OPERATOR_IN, $CAIRO_OPERATOR_OUT, $CAIRO_OPERATOR_ATOP, $CAIRO_OPERATOR_DEST, $CAIRO_OPERATOR_DEST_OVER, $CAIRO_OPERATOR_DEST_IN, _
$CAIRO_OPERATOR_DEST_OUT, $CAIRO_OPERATOR_DEST_ATOP, $CAIRO_OPERATOR_XOR, $CAIRO_OPERATOR_ADD, $CAIRO_OPERATOR_SATURATE, $CAIRO_OPERATOR_MULTIPLY, $CAIRO_OPERATOR_SCREEN, $CAIRO_OPERATOR_OVERLAY, _
$CAIRO_OPERATOR_DARKEN, $CAIRO_OPERATOR_LIGHTEN, $CAIRO_OPERATOR_COLOR_DODGE, $CAIRO_OPERATOR_COLOR_BURN, $CAIRO_OPERATOR_HARD_LIGHT, $CAIRO_OPERATOR_SOFT_LIGHT, $CAIRO_OPERATOR_DIFFERENCE, _
$CAIRO_OPERATOR_EXCLUSION, $CAIRO_OPERATOR_HSL_HUE, $CAIRO_OPERATOR_HSL_SATURATION, $CAIRO_OPERATOR_HSL_COLOR, $CAIRO_OPERATOR_HSL_LUMINOSITY
;cairo_antialias as long
Global Enum $CAIRO_ANTIALIAS_DEFAULT, $CAIRO_ANTIALIAS_NONE, $CAIRO_ANTIALIAS_GRAY, $CAIRO_ANTIALIAS_SUBPIXEL, $CAIRO_ANTIALIAS_FAST, $CAIRO_ANTIALIAS_GOOD, $CAIRO_ANTIALIAS_BEST
;cairo_fill_rule as long
Global Enum $CAIRO_FILL_RULE_WINDING, $CAIRO_FILL_RULE_EVEN_ODD
;cairo_line_join as long
Global Enum $CAIRO_LINE_JOIN_MITER, $CAIRO_LINE_JOIN_ROUND, $CAIRO_LINE_JOIN_BEVEL
;cairo_line_cap as long
Global Enum $CAIRO_LINE_CAP_BUTT, $CAIRO_LINE_CAP_ROUND, $CAIRO_LINE_CAP_SQUARE
;cairo_text_cluster_flags as long
Global Const $CAIRO_TEXT_CLUSTER_FLAG_BACKWARD = 0x00000001
;cairo_font_slant as long
Global Enum $CAIRO_FONT_SLANT_NORMAL, $CAIRO_FONT_SLANT_ITALIC, $CAIRO_FONT_SLANT_OBLIQUE
;cairo_font_weight as long
Global Enum $CAIRO_FONT_WEIGHT_NORMAL, $CAIRO_FONT_WEIGHT_BOLD
;cairo_subpixel_order as long
Global Enum $CAIRO_SUBPIXEL_ORDER_DEFAULT, $CAIRO_SUBPIXEL_ORDER_RGB, $CAIRO_SUBPIXEL_ORDER_BGR, $CAIRO_SUBPIXEL_ORDER_VRGB, $CAIRO_SUBPIXEL_ORDER_VBGR
;cairo_hint_style as long
Global Enum $CAIRO_HINT_STYLE_DEFAULT, $CAIRO_HINT_STYLE_NONE, $CAIRO_HINT_STYLE_SLIGHT, $CAIRO_HINT_STYLE_MEDIUM, $CAIRO_HINT_STYLE_FULL
;cairo_hint_metrics as long
Global Enum $CAIRO_HINT_METRICS_DEFAULT, $CAIRO_HINT_METRICS_OFF, $CAIRO_HINT_METRICS_ON
;cairo_font_type as long
Global Enum $CAIRO_FONT_TYPE_TOY, $CAIRO_FONT_TYPE_FT, $CAIRO_FONT_TYPE_WIN32, $CAIRO_FONT_TYPE_QUARTZ, $CAIRO_FONT_TYPE_USER
;cairo_path_data_type as long
Global Enum $CAIRO_PATH_MOVE_TO, $CAIRO_PATH_LINE_TO, $CAIRO_PATH_CURVE_TO, $CAIRO_PATH_CLOSE_PATH
;cairo_device_type as long
Global Enum $CAIRO_DEVICE_TYPE_DRM, $CAIRO_DEVICE_TYPE_GL, $CAIRO_DEVICE_TYPE_SCRIPT, $CAIRO_DEVICE_TYPE_XCB, $CAIRO_DEVICE_TYPE_XLIB, $CAIRO_DEVICE_TYPE_XML, $CAIRO_DEVICE_TYPE_COGL, _
$CAIRO_DEVICE_TYPE_WIN32, $CAIRO_DEVICE_TYPE_INVALID = -1
;cairo_surface_observer_mode_t as long
Global Enum $CAIRO_SURFACE_OBSERVER_NORMAL, $CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS
;cairo_surface_type as long
Global Enum $CAIRO_SURFACE_TYPE_IMAGE, $CAIRO_SURFACE_TYPE_PDF, $CAIRO_SURFACE_TYPE_PS, $CAIRO_SURFACE_TYPE_XLIB, $CAIRO_SURFACE_TYPE_XCB, $CAIRO_SURFACE_TYPE_GLITZ, $CAIRO_SURFACE_TYPE_QUARTZ,$CAIRO_SURFACE_TYPE_WIN32, _
$CAIRO_SURFACE_TYPE_BEOS, $CAIRO_SURFACE_TYPE_DIRECTFB, $CAIRO_SURFACE_TYPE_SVG, $CAIRO_SURFACE_TYPE_OS2, $CAIRO_SURFACE_TYPE_WIN32_PRINTING, $CAIRO_SURFACE_TYPE_QUARTZ_IMAGE, $CAIRO_SURFACE_TYPE_SCRIPT, _
$CAIRO_SURFACE_TYPE_QT, $CAIRO_SURFACE_TYPE_RECORDING, $CAIRO_SURFACE_TYPE_VG, $CAIRO_SURFACE_TYPE_GL, $CAIRO_SURFACE_TYPE_DRM, $CAIRO_SURFACE_TYPE_TEE, $CAIRO_SURFACE_TYPE_XML, $CAIRO_SURFACE_TYPE_SKIA, _
$CAIRO_SURFACE_TYPE_SUBSURFACE, $CAIRO_SURFACE_TYPE_COGL
;cairo_pattern_type as long
Global Enum $CAIRO_PATTERN_TYPE_SOLID, $CAIRO_PATTERN_TYPE_SURFACE, $CAIRO_PATTERN_TYPE_LINEAR, $CAIRO_PATTERN_TYPE_RADIAL, $CAIRO_PATTERN_TYPE_MESH, $CAIRO_PATTERN_TYPE_RASTER_SOURCE
;cairo_extend as long
Global Enum $CAIRO_EXTEND_NONE, $CAIRO_EXTEND_REPEAT, $CAIRO_EXTEND_REFLECT, $CAIRO_EXTEND_PAD
;cairo_filter as long
Global Enum $CAIRO_FILTER_FAST, $CAIRO_FILTER_GOOD, $CAIRO_FILTER_BEST, $CAIRO_FILTER_NEAREST, $CAIRO_FILTER_BILINEAR, $CAIRO_FILTER_GAUSSIAN
;cairo_region_overlap as long
Global Enum $CAIRO_REGION_OVERLAP_IN, $CAIRO_REGION_OVERLAP_OUT, $CAIRO_REGION_OVERLAP_PART
#EndRegion
#Region tag structs
;structs
Global Const $tagCairo_rectangle_int = "long x;long y;long width;long height;"
Global Const $tagCairo_rectangle_list = "long status;ptr rectangles;long num_rectangles;"
Global Const $tagCairo_matrix = "double xx;double yx;double xy;double yy;double x0;double y0;"
Global Const $tagCairo_glyph_t = (@AutoItX64 ? "uinteger" : "ulong") & " index;double x;double y;"
Global Const $tagCairo_text_cluster_t = "long num_bytes;long num_glyphs;"
Global Const $tagCairo_text_extents_t = "double x_bearing;double y_bearing;double width;double height;double x_advance;double y_advance;"
Global Const $tagCairo_font_extents_t = "double ascent;double descent;double height;double max_x_advance;double max_y_advance;"
Global Const $tagCairo_path_data_t_header = "long type;long length;"
Global Const $tagCairo_path_data_t_point = "double x;double y;"
Global Const $tagCairo_path_data_t = "ptr path;"
Global Const $tagCairo_path = "long status;ptr data;long num_data;"
#EndRegion
Global $g_hCairoDLL = 0
Func Cairo_Init($sPath = Default)
Local Const $sDLL = ($sPath = Default ? (@AutoItX64 ? (@ScriptDir & "\cairo64.dll") : (@ScriptDir & "\cairo.dll")) : $sPath)
If Not FileExists($sDLL) Then Return SetError(1, 0, 0)
$g_hCairoDLL = DllOpen($sDLL)
If $g_hCairoDLL = -1 Or @error Then Return SetError(2, 0, 0)
Return 1
EndFunc
Func Cairo_Close()
If $g_hCairoDLL Then Return DllClose($g_hCairoDLL)
Return 0
EndFunc
Func Cairo_GetStride($iW, $iFormat = $CAIRO_FORMAT_ARGB32)
Local Const $aStride = DllCall($g_hCairoDLL, "long:cdecl", "cairo_format_stride_for_width", "long", $iFormat, "long", $iW) ;BitShift($iW * 32 + 15, 4) * 2 * $iH
If @error Or Not IsArray($aStride) Then Return SetError(1, 0, 0)
If Not $aStride[0] Then Return SetError(2, 0, 0)
Return $aStride[0]
EndFunc
Func Cairo_CreateWin32Surface($hDC)
Local Const $aSurface = DllCall($g_hCairoDLL, "ptr:cdecl", "cairo_win32_surface_create", "ptr", $hDC)
If @error Or Not IsArray($aSurface) Then Return SetError(1, 0, 0)
If Not $aSurface[0] Then Return SetError(2, 0, 0)
Return $aSurface[0]
EndFunc
Func Cairo_CreateWin32SurfacePrinting($hDC)
Local Const $aSurface = DllCall($g_hCairoDLL, "ptr:cdecl", "cairo_win32_printing_surface_create", "ptr", $hDC)
If @error Or Not IsArray($aSurface) Then Return SetError(1, 0, 0)
If Not $aSurface[0] Then Return SetError(2, 0, 0)
Return $aSurface[0]
EndFunc
Func Cairo_CreateWin32SurfaceWithFormat($hDC, $iFormat = $CAIRO_FORMAT_ARGB32)
Local Const $aSurface = DllCall($g_hCairoDLL, "ptr:cdecl", "cairo_win32_surface_create_with_format", "ptr", $hDC, "long", $iFormat)
If @error Or Not IsArray($aSurface) Then Return SetError(1, 0, 0)
If Not $aSurface[0] Then Return SetError(2, 0, 0)
Return $aSurface[0]
EndFunc
Func Cairo_CreateWin32SurfaceWithDDB($hDC, $iW, $iH, $iFormat = $CAIRO_FORMAT_ARGB32)
Local Const $aSurface = DllCall($g_hCairoDLL, "ptr:cdecl", "cairo_win32_surface_create_with_ddb", "ptr", $hDC, "long", $iFormat, "long", $iw, "long", $ih)
If @error Or Not IsArray($aSurface) Then Return SetError(1, 0, 0)
If Not $aSurface[0] Then Return SetError(2, 0, 0)
Return $aSurface[0]
EndFunc
Func Cairo_CreateSurfaceImageData($pImageData, $iW, $iH, $iStride, $iFormat = $CAIRO_FORMAT_ARGB32)
Local Const $aSurface = DllCall($g_hCairoDLL, "ptr:cdecl", "cairo_image_surface_create_for_data", "ptr", $pImageData, "long", $iFormat, "long", $iW, "long", $iH, "long", $iStride)
If @error Or Not IsArray($aSurface) Then Return SetError(1, 0, 0)
If Not $aSurface[0] Then Return SetError(2, 0, 0)
Return $aSurface[0]
EndFunc
Func Cairo_CreateContext($pSurface)
Local Const $aContext = DllCall($g_hCairoDLL, "ptr:cdecl", "cairo_create", "ptr", $pSurface)
If @error Or Not IsArray($aContext) Then Return SetError(1, 0, 0)
If Not $aContext[0] Then Return SetError(2, 0, 0)
Return $aContext[0]
EndFunc
Func Cairo_DestroyContext($pContext)
If Not $pContext Then Return SetError(1, 0, 0)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_destroy", "ptr", $pContext)
Return 1
EndFunc
Func Cairo_DestroySurface($pSurface)
If Not $pSurface Then Return SetError(1, 0, 0)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_surface_destroy", "ptr", $pSurface)
Return 1
EndFunc
Func Cairo_ClearContext($pContext, $r = 0, $g = 0, $b = 0, $a = 1)
If Not $pContext Then Return SetError(1, 0, 0)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_set_source_rgb", "ptr", $pContext, "double", $r, "double", $g, "double", $b, "double", $a)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_paint", "ptr", $pContext)
EndFunc
Alles anzeigen
Beispiel:
C
#AutoIt3Wrapper_UseX64=n
#include <Array.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPIGdi.au3>
#include "Cairo.au3"
AutoItSetOption('MustDeclareVars', 1)
Global Const $fPi = ACos(-1), $fRad = $fPi / 180, $fDeg = 180 / $fPi, $f2PI = $fPi * 2
Global Const $iW = 600, $iH = 400, $sTitle = "Cairo Test / FPS: "
Global $hGUI, $iFPS = 0, $iShowFPS = 0, $bExit
AutoItSetOption("GUIOnEventMode", 1)
Cairo_Test()
AutoItSetOption("GUIOnEventMode", 0)
Func Cairo_Test()
Cairo_Init()
Local $iStride = Cairo_GetStride($iW)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $iStride = ' & $iStride & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
$hGUI = GUICreate($sTitle & "0", $iW, $iH)
Local Const $hDC = _WinAPI_GetDC($hGUI)
;~ Local $tBits = DllStructCreate("long[" & $iStride * $iH & "]")
;~ Local Const $hBitmapGDI = _WinAPI_CreateBitmap($iW, $iH, 1, 32, $tBits)
Local Const $hBitmapGDI = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH)
Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC)
Local Const $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI)
GUISetState(@SW_SHOW, $hGUI)
$bExit = False
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
AdlibRegister("CalcFPS", 1000)
Local $pSurface = Cairo_CreateWin32Surface($hGfxDC)
ConsoleWrite("Surface status: " & DllCall($g_hCairoDLL, "long:cdecl", "cairo_surface_status", "ptr", $pSurface)[0] & @CRLF)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $pSurface = ' & $pSurface & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
Local $pContext = Cairo_CreateContext($pSurface)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $pContext = ' & $pContext & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
ConsoleWrite(DllCall($g_hCairoDLL, "str:cdecl", "cairo_status_to_string")[0] & @CRLF)
Local $t, $tt = 1 / 60, $x, $y, $c
Local $tPAINTSTRUCT
Do
_WinAPI_BeginPaint($hGUI, $tPAINTSTRUCT)
$c = 0.5 + 0.5 * Sin($t)
Cairo_ClearContext($pContext, $c, $c, $c)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_set_source_rgba", "ptr", $pContext, "double", 0, "double", 0, "double", 0.5 + 0.5 * Cos($t), "double", 1.0)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_set_line_width", "ptr", $pContext, "double", $iH / 10)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_rectangle", "ptr", $pContext, "double", $iW / 4, "double", $iH / 4, "double", $iW / 2, "double", $iH / 2)
DllCall($g_hCairoDLL, "none:cdecl", "cairo_stroke", "ptr", $pContext)
_WinAPI_EndPaint($hGUI, $tPAINTSTRUCT)
$t += $tt
_WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $SRCCOPY)
$iFPS += 1
If $bExit Then ExitLoop
Until Not Sleep(10)
Cairo_DestroyContext($pContext)
Cairo_DestroySurface($pSurface)
_WinAPI_SelectObject($hGfxDC, $hObjOld)
_WinAPI_ReleaseDC($hGUI, $hDC)
_WinAPI_DeleteDC($hGfxDC)
_WinAPI_DeleteObject($hBitmapGDI)
GUIDelete($hGUI)
Cairo_Close()
EndFunc
Func _Exit()
$bExit = True
EndFunc ;==>_Exit_About
Func CalcFPS() ;display FPS
$iShowFPS = $iFPS
$iFPS = 0
WinSetTitle($hGUI, "", $sTitle & $iShowFPS)
EndFunc ;==>CalcFPS
Alles anzeigen
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?