Cairo is a 2D graphics library with support for multiple output devices. Currently supported output targets include the X Window System, Quartz, Win32, image buffers, PostScript, PDF, and SVG file output. Experimental backends include OpenGL (through glitz), XCB, BeOS, OS/2, and DirectFB.
Cairo is designed to produce consistent output on all output media while taking advantage of display hardware acceleration when available (eg. through the X Render Extension).
The cairo API provides operations similar to the drawing operators of PostScript and PDF. Operations in cairo including stroking and filling cubic Bézier splines, transforming and compositing translucent images, and antialiased text rendering. All drawing operations can be transformed by any affine transformation (scale, rotation, shear, etc.)
Cairo is implemented as a library written in the C programming language, but bindings are available for several different programming languages.
Cairo is free software and is available to be redistributed and/or modified under the terms of either the GNU Lesser General Public License (LGPL) version 2.1 or the Mozilla Public License (MPL) version 1.1 at your option.
Web Page: http://cairographics.org/
The attached file contains my translation of the GLib headers to PowerBASIC and the needed DLLs (Cairo has dependencies on libpng12-0.dll and zlib1.dll). To use them, add #INCLUDE "cairo_win32.inc" to your program.
The default library name used in the translation is "libcairo-2.dll".
#IF NOT %DEF($CAIRO_DLLNAME)
$CAIRO_DLLNAME = "libcairo-2.dll"
#ENDIF
If you use a different version or if you want to rename the .dll, change the value in the constant or define a different value for the constant before #INCLUDE "cairo_win32.inc", e.g.
$CAIRO_DLLNAME = "cairo.dll"
#INCLUDE "cairo_win32.inc"
The following example demonstrates how to use Cairo to draw an arc. All the Cairo code has been placed in the RenderScene procedure for easy examination.
SDK Version
' ========================================================================================
' Cairo example
' ========================================================================================
' SED_PBWIN
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "cairo_win32.inc"
' ========================================================================================
' Draw an arc using Cairo.
' ========================================================================================
SUB RenderScene (BYVAL hdc AS DWORD)
' // Create a cairo surface we can draw on directly
LOCAL cairo_surface AS DWORD ' cairo_surface_t*
cairo_surface = cairo_win32_surface_create(hdc)
' // create a cairo context with the surface as the target
LOCAL cairo_image AS DWORD ' cairo_t*
cairo_image = cairo_create(cairo_surface)
' // Draw the scene
LOCAL xc, yc, radius, angle1, angle2 AS DOUBLE
xc = 200.0
yc = 70.0
radius = 100.0
angle1 = 45.0 * (3.141592654 / 180.0) ' // angles are specified
angle2 = 180.0 * (3.141592654 / 180.0) ' // in radians
cairo_set_line_width(cairo_image, 10.0)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle2)
cairo_stroke(cairo_image)
' // draw helping lines
cairo_set_source_rgba(cairo_image, 1, 0.2, 0.2, 0.6)
cairo_set_line_width(cairo_image, 6.0)
cairo_arc (cairo_image, xc, yc, 10.0, 0, 2 * 3.141592654)
cairo_fill(cairo_image)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle1)
cairo_line_to(cairo_image, xc, yc)
cairo_arc(cairo_image, xc, yc, radius, angle2, angle2)
cairo_line_to(cairo_image, xc, yc)
cairo_stroke(cairo_image)
' // Tear down the cairo object now that we don't need it anymore.
cairo_destroy(cairo_image)
cairo_surface_destroy(cairo_surface)
END SUB
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL hr AS LONG
LOCAL hWndMain AS DWORD
LOCAL hCtl AS DWORD
LOCAL hFont AS DWORD
LOCAL wcex AS WndClassEx
LOCAL szClassName AS ASCIIZ * 80
LOCAL rc AS RECT
LOCAL szCaption AS ASCIIZ * 255
hFont = GetStockObject(%ANSI_VAR_FONT)
' Register the window class
szClassName = "MyClassName"
wcex.cbSize = SIZEOF(wcex)
wcex.style = 0 ' %CS_HREDRAW OR %CS_VREDRAW
wcex.lpfnWndProc = CODEPTR(WndProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hCursor = LoadCursor (%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = GetStockObject(%WHITE_BRUSH)
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szClassName)
wcex.hIcon = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Sample, if resource icon: LoadIcon(hInst, "APPICON")
wcex.hIconSm = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Remember to set small icon too..
RegisterClassEx wcex
' Window caption
szCaption = "Cairo Example"
' Create a window using the registered class
hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _ ' extended style
szClassName, _ ' window class name
szCaption, _ ' window caption
%WS_OVERLAPPEDWINDOW OR _
%WS_CLIPCHILDREN, _ ' window style
%CW_USEDEFAULT, _ ' initial x position
%CW_USEDEFAULT, _ ' initial y position
%CW_USEDEFAULT, _ ' initial x nSize
%CW_USEDEFAULT, _ ' initial y nSize
%NULL, _ ' parent window handle
0, _ ' window menu handle
hInstance, _ ' program instance handle
BYVAL %NULL) ' creation parameters
' Show the window
ShowWindow hWndMain, nCmdShow
UpdateWindow hWndMain
' Message handler loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
TranslateMessage uMsg
DispatchMessage uMsg
END IF
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL ps AS PAINTSTRUCT
SELECT CASE wMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
FUNCTION = 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_SYSCOMMAND
' Capture this message and send a WM_CLOSE message
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_PAINT
hDC = BeginPaint(hWnd, ps)
RenderScene hDC
EndPaint(hWnd, ps)
CASE %WM_DESTROY
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
CWindow Version
#COMPILE EXE
#DIM ALL
%UNICODE = 1
' // Include files for external files
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "cairo_win32.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
pWindow.CreateWindow(%NULL, "Cairo Example", 0, 0, 0, 0, -1, -1, CODEPTR(WindowProc))
' // Change the brush for the background
pWindow.Brush = GetStockObject(%WHITE_BRUSH)
' // Center the window
pWindow.CenterWindow
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL ps AS PAINTSTRUCT
' // Process window mesages
SELECT CASE uMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
' // If the Escape key has been pressed...
IF HI(WORD, wParam) = %BN_CLICKED THEN
' // ... close the application by sending a WM_CLOSE message
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_PAINT
hDC = BeginPaint(hWnd, ps)
RenderScene hDC
EndPaint(hWnd, ps)
CASE %WM_DESTROY
' // End the application
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Draw an arc using Cairo.
' ========================================================================================
SUB RenderScene (BYVAL hdc AS DWORD)
' // Create a cairo surface we can draw on directly
LOCAL cairo_surface AS DWORD ' cairo_surface_t*
cairo_surface = cairo_win32_surface_create(hdc)
' // create a cairo context with the surface as the target
LOCAL cairo_image AS DWORD ' cairo_t*
cairo_image = cairo_create(cairo_surface)
' // Draw the scene
LOCAL xc, yc, radius, angle1, angle2 AS DOUBLE
xc = 200.0
yc = 70.0
radius = 100.0
angle1 = 45.0 * (3.141592654 / 180.0) ' // angles are specified
angle2 = 180.0 * (3.141592654 / 180.0) ' // in radians
cairo_set_line_width(cairo_image, 10.0)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle2)
cairo_stroke(cairo_image)
' // draw helping lines
cairo_set_source_rgba(cairo_image, 1, 0.2, 0.2, 0.6)
cairo_set_line_width(cairo_image, 6.0)
cairo_arc (cairo_image, xc, yc, 10.0, 0, 2 * 3.141592654)
cairo_fill(cairo_image)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle1)
cairo_line_to(cairo_image, xc, yc)
cairo_arc(cairo_image, xc, yc, radius, angle2, angle2)
cairo_line_to(cairo_image, xc, yc)
cairo_stroke(cairo_image)
' // Tear down the cairo object now that we don't need it anymore.
cairo_destroy(cairo_image)
cairo_surface_destroy(cairo_surface)
END SUB
' ========================================================================================
Same as above, but using double buffering. All the code to create and render the double buffer has been placed under the WM_PAINT message.
SDK Version
' ========================================================================================
' Cairo example with double buffering
' ========================================================================================
' SED_PBWIN
#COMPILE EXE
#DIM ALL
#INCLUDE "cairo_win32.inc"
' ========================================================================================
' Draw an arc using Cairo.
' ========================================================================================
SUB RenderScene (BYVAL hdc AS DWORD)
' // Create a cairo surface we can draw on directly
LOCAL cairo_surface AS DWORD ' cairo_surface_t*
cairo_surface = cairo_win32_surface_create(hdc)
' // Create a cairo context with the surface as the target
LOCAL cairo_image AS DWORD ' cairo_t*
cairo_image = cairo_create(cairo_surface)
' // Draw the scene
LOCAL xc, yc, radius, angle1, angle2 AS DOUBLE
xc = 200.0
yc = 70.0
radius = 100.0
angle1 = 45.0 * (3.141592654 / 180.0) ' // angles are specified
angle2 = 180.0 * (3.141592654 / 180.0) ' // in radians
cairo_set_line_width(cairo_image, 10.0)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle2)
cairo_stroke(cairo_image)
' // Draw helping lines
cairo_set_source_rgba(cairo_image, 1, 0.2, 0.2, 0.6)
cairo_set_line_width(cairo_image, 6.0)
cairo_arc (cairo_image, xc, yc, 10.0, 0, 2 * 3.141592654)
cairo_fill(cairo_image)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle1)
cairo_line_to(cairo_image, xc, yc)
cairo_arc(cairo_image, xc, yc, radius, angle2, angle2)
cairo_line_to(cairo_image, xc, yc)
cairo_stroke(cairo_image)
' // Tear down the cairo object now that we don't need it anymore.
cairo_destroy(cairo_image)
cairo_surface_destroy(cairo_surface)
END SUB
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL hr AS LONG
LOCAL hWndMain AS DWORD
LOCAL hCtl AS DWORD
LOCAL hFont AS DWORD
LOCAL wcex AS WndClassEx
LOCAL szClassName AS ASCIIZ * 80
LOCAL rc AS RECT
LOCAL szCaption AS ASCIIZ * 255
hFont = GetStockObject(%ANSI_VAR_FONT)
' Register the window class
szClassName = "MyClassName"
wcex.cbSize = SIZEOF(wcex)
wcex.style = 0 ' %CS_HREDRAW OR %CS_VREDRAW
wcex.lpfnWndProc = CODEPTR(WndProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hCursor = LoadCursor (%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = GetStockObject(%WHITE_BRUSH)
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szClassName)
wcex.hIcon = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Sample, if resource icon: LoadIcon(hInst, "APPICON")
wcex.hIconSm = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Remember to set small icon too..
RegisterClassEx wcex
' Window caption
szCaption = "Cairo Example - Double Buffering"
' Create a window using the registered class
hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _ ' extended style
szClassName, _ ' window class name
szCaption, _ ' window caption
%WS_OVERLAPPEDWINDOW OR _
%WS_CLIPCHILDREN, _ ' window style
%CW_USEDEFAULT, _ ' initial x position
%CW_USEDEFAULT, _ ' initial y position
%CW_USEDEFAULT, _ ' initial x nSize
%CW_USEDEFAULT, _ ' initial y nSize
%NULL, _ ' parent window handle
0, _ ' window menu handle
hInstance, _ ' program instance handle
BYVAL %NULL) ' creation parameters
' Show the window
ShowWindow hWndMain, nCmdShow
UpdateWindow hWndMain
' Message handler loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
TranslateMessage uMsg
DispatchMessage uMsg
END IF
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL ps AS PAINTSTRUCT
SELECT CASE wMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
FUNCTION = 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_SYSCOMMAND
' Capture this message and send a WM_CLOSE message
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_PAINT
hDC = BeginPaint(hWnd, ps)
' // Get the client coordinates
LOCAL rc AS RECT
GetClientRect(hWnd, rc)
' // Create a double buffer for blitting to the screen to prevent screen flicker.
LOCAL hdcBuffer AS DWORD
hdcBuffer = CreateCompatibleDC(hdc)
LOCAL hbmpBuffer AS DWORD
hbmpBuffer = CreateCompatibleBitmap(hdc, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop)
SelectObject(hdcBuffer, hbmpBuffer)
' // Clear it using a white brush
LOCAL hBrush AS DWORD
LOCAL hOldDc AS DWORD
hBrush = CreateSolidBrush(%WHITE)
hOldDc = SelectObject(hdcBuffer, hBrush)
FillRect hdcBuffer, rc, hBrush
DeleteObject hBrush
IF hOldDc THEN SelectObject hdcBuffer, hOldDc
' // Draw the scene in the a cairo surface
RenderScene hdcBuffer
' // Now blit the object to the screen
BitBlt(hdc, 0, 0, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, hdcBuffer, 0, 0, %SRCCOPY)
' // Release resources
DeleteDC(hdcbuffer)
DeleteObject(hbmpBuffer)
EndPaint(hWnd, ps)
CASE %WM_DESTROY
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
CWindow Version
#COMPILE EXE
#DIM ALL
%UNICODE = 1
' // Include files for external files
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "cairo_win32.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
pWindow.CreateWindow(%NULL, "Cairo Example - Double Buffering", 0, 0, 0, 0, -1, -1, CODEPTR(WindowProc))
' // Change the brush for the background
pWindow.Brush = GetStockObject(%WHITE_BRUSH)
' // Center the window
pWindow.CenterWindow
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL ps AS PAINTSTRUCT
' // Process window mesages
SELECT CASE uMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
' // If the Escape key has been pressed...
IF HI(WORD, wParam) = %BN_CLICKED THEN
' // ... close the application by sending a WM_CLOSE message
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_PAINT
hDC = BeginPaint(hWnd, ps)
' // Get the client coordinates
LOCAL rc AS RECT
GetClientRect(hWnd, rc)
' // Create a double buffer for blitting to the screen to prevent screen flicker.
LOCAL hdcBuffer AS DWORD
hdcBuffer = CreateCompatibleDC(hdc)
LOCAL hbmpBuffer AS DWORD
hbmpBuffer = CreateCompatibleBitmap(hdc, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop)
SelectObject(hdcBuffer, hbmpBuffer)
' // Clear it using a white brush
LOCAL hBrush AS DWORD
LOCAL hOldDc AS DWORD
hBrush = CreateSolidBrush(%WHITE)
hOldDc = SelectObject(hdcBuffer, hBrush)
FillRect hdcBuffer, rc, hBrush
DeleteObject hBrush
IF hOldDc THEN SelectObject hdcBuffer, hOldDc
' // Draw the scene in the a cairo surface
RenderScene hdcBuffer
' // Now blit the object to the screen
BitBlt(hdc, 0, 0, rc.nRight - rc.nLeft, rc.nBottom - rc.nTop, hdcBuffer, 0, 0, %SRCCOPY)
' // Release resources
DeleteDC(hdcbuffer)
DeleteObject(hbmpBuffer)
EndPaint(hWnd, ps)
CASE %WM_DESTROY
' // End the application
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Draw an arc using Cairo.
' ========================================================================================
SUB RenderScene (BYVAL hdc AS DWORD)
' // Create a cairo surface we can draw on directly
LOCAL cairo_surface AS DWORD ' cairo_surface_t*
cairo_surface = cairo_win32_surface_create(hdc)
' // Create a cairo context with the surface as the target
LOCAL cairo_image AS DWORD ' cairo_t*
cairo_image = cairo_create(cairo_surface)
' // Draw the scene
LOCAL xc, yc, radius, angle1, angle2 AS DOUBLE
xc = 200.0
yc = 70.0
radius = 100.0
angle1 = 45.0 * (3.141592654 / 180.0) ' // angles are specified
angle2 = 180.0 * (3.141592654 / 180.0) ' // in radians
cairo_set_line_width(cairo_image, 10.0)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle2)
cairo_stroke(cairo_image)
' // Draw helping lines
cairo_set_source_rgba(cairo_image, 1, 0.2, 0.2, 0.6)
cairo_set_line_width(cairo_image, 6.0)
cairo_arc (cairo_image, xc, yc, 10.0, 0, 2 * 3.141592654)
cairo_fill(cairo_image)
cairo_arc(cairo_image, xc, yc, radius, angle1, angle1)
cairo_line_to(cairo_image, xc, yc)
cairo_arc(cairo_image, xc, yc, radius, angle2, angle2)
cairo_line_to(cairo_image, xc, yc)
cairo_stroke(cairo_image)
' // Tear down the cairo object now that we don't need it anymore.
cairo_destroy(cairo_image)
cairo_surface_destroy(cairo_surface)
END SUB
' ========================================================================================
A minimal program using Cairo. Draws an outlined "Hello, World", and saves it as a .png file.
' ========================================================================================
' A minimal program using Cairo.
' Draws an outlined "Hello, World", and saves it as a .png file
' ========================================================================================
' SED_PBWIN
#COMPILE EXE
#DIM ALL
#INCLUDE "cairo.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WINMAIN (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL cairo_surface AS DWORD
cairo_surface = cairo_image_surface_create (%CAIRO_FORMAT_ARGB32, 240, 80)
LOCAL cairo_image AS DWORD
cairo_image = cairo_create(cairo_surface)
cairo_select_font_face(cairo_image, "serif", %CAIRO_FONT_SLANT_NORMAL, %CAIRO_FONT_WEIGHT_BOLD)
cairo_set_font_size(cairo_image, 32.0)
cairo_set_source_rgb(cairo_image, 0.0, 0.0, 1.0)
cairo_move_to(cairo_image, 10.0, 50.0)
cairo_show_text(cairo_image, "Hello, world")
cairo_destroy(cairo_image)
cairo_surface_write_to_png(cairo_surface, "hello.png")
cairo_surface_destroy(cairo_surface)
END FUNCTION
' ========================================================================================
Gradient example.
SDK Version
' ========================================================================================
' Cairo example: Gradient
' ========================================================================================
' SED_PBWIN
#COMPILE EXE
#DIM ALL
#INCLUDE "cairo_win32.inc"
' ========================================================================================
' Render the scene
' ========================================================================================
SUB RenderScene (BYVAL hdc AS DWORD)
' // Create a cairo surface we can draw on directly
LOCAL cairo_surface AS DWORD ' cairo_surface_t*
cairo_surface = cairo_win32_surface_create(hdc)
' // Create a cairo context with the surface as the target
LOCAL cairo_image AS DWORD ' cairo_t*
cairo_image = cairo_create(cairo_surface)
' // Draw the scene
LOCAL pat AS DWORD ' cairo_pattern_t
pat = cairo_pattern_create_linear(0.0, 0.0, 0.0, 256.0)
cairo_pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 1)
cairo_pattern_add_color_stop_rgba(pat, 0, 1, 1, 1, 1)
cairo_rectangle(cairo_image, 0, 0, 256, 256)
cairo_set_source(cairo_image, pat)
cairo_fill(cairo_image)
cairo_pattern_destroy(pat)
pat = cairo_pattern_create_radial(115.2, 102.4, 25.6, 102.4, 102.4, 128.0)
cairo_pattern_add_color_stop_rgba(pat, 0, 1, 1, 1, 1)
cairo_pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 1)
cairo_set_source(cairo_image, pat)
cairo_arc(cairo_image, 128.0, 128.0, 76.8, 0, 2 * 3.141592654)
cairo_fill(cairo_image)
cairo_pattern_destroy(pat)
' // Tear down the cairo object now that we don't need it anymore.
cairo_destroy(cairo_image)
cairo_surface_destroy(cairo_surface)
END SUB
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
LOCAL hr AS LONG
LOCAL hWndMain AS DWORD
LOCAL hCtl AS DWORD
LOCAL hFont AS DWORD
LOCAL wcex AS WndClassEx
LOCAL szClassName AS ASCIIZ * 80
LOCAL rc AS RECT
LOCAL szCaption AS ASCIIZ * 255
hFont = GetStockObject(%ANSI_VAR_FONT)
' Register the window class
szClassName = "MyClassName"
wcex.cbSize = SIZEOF(wcex)
wcex.style = 0 ' %CS_HREDRAW OR %CS_VREDRAW
wcex.lpfnWndProc = CODEPTR(WndProc)
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hCursor = LoadCursor (%NULL, BYVAL %IDC_ARROW)
wcex.hbrBackground = GetStockObject(%WHITE_BRUSH)
wcex.lpszMenuName = %NULL
wcex.lpszClassName = VARPTR(szClassName)
wcex.hIcon = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Sample, if resource icon: LoadIcon(hInst, "APPICON")
wcex.hIconSm = LoadIcon (%NULL, BYVAL %IDI_APPLICATION) ' Remember to set small icon too..
RegisterClassEx wcex
' Window caption
szCaption = "Cairo Example: Gradient"
' Create a window using the registered class
hWndMain = CreateWindowEx(%WS_EX_CONTROLPARENT, _ ' extended style
szClassName, _ ' window class name
szCaption, _ ' window caption
%WS_OVERLAPPEDWINDOW OR _
%WS_CLIPCHILDREN, _ ' window style
%CW_USEDEFAULT, _ ' initial x position
%CW_USEDEFAULT, _ ' initial y position
%CW_USEDEFAULT, _ ' initial x nSize
%CW_USEDEFAULT, _ ' initial y nSize
%NULL, _ ' parent window handle
0, _ ' window menu handle
hInstance, _ ' program instance handle
BYVAL %NULL) ' creation parameters
' Show the window
ShowWindow hWndMain, nCmdShow
UpdateWindow hWndMain
' Message handler loop
LOCAL uMsg AS tagMsg
WHILE GetMessage(uMsg, %NULL, 0, 0)
IF ISFALSE IsDialogMessage(hWndMain, uMsg) THEN
TranslateMessage uMsg
DispatchMessage uMsg
END IF
WEND
FUNCTION = uMsg.wParam
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main Window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hWnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL ps AS PAINTSTRUCT
SELECT CASE wMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
IF HI(WORD, wParam) = %BN_CLICKED THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
FUNCTION = 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_SYSCOMMAND
' Capture this message and send a WM_CLOSE message
IF (wParam AND &HFFF0) = %SC_CLOSE THEN
SendMessage hWnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
CASE %WM_PAINT
hDC = BeginPaint(hWnd, ps)
RenderScene hDC
EndPaint(hWnd, ps)
CASE %WM_DESTROY
PostQuitMessage 0
EXIT FUNCTION
END SELECT
FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
CWindow Version
#COMPILE EXE
#DIM ALL
%UNICODE = 1
' // Include files for external files
#INCLUDE ONCE "CWindow.inc"
#INCLUDE ONCE "cairo_win32.inc"
' ========================================================================================
' Main
' ========================================================================================
FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
' // Create an instance of the class
LOCAL pWindow AS IWindow
pWindow = CLASS "CWindow"
IF ISNOTHING(pWindow) THEN EXIT FUNCTION
' // Create the main window
' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
pWindow.CreateWindow(%NULL, "Cairo Example: Gradient", 0, 0, 0, 0, -1, -1, CODEPTR(WindowProc))
' // Change the brush for the background
pWindow.Brush = GetStockObject(%WHITE_BRUSH)
' // Center the window
pWindow.CenterWindow
' // Default message pump (you can replace it with your own)
pWindow.DoEvents(nCmdShow)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main callback function.
' ========================================================================================
FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL uMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
LOCAL hDC AS DWORD
LOCAL ps AS PAINTSTRUCT
' // Process window mesages
SELECT CASE uMsg
CASE %WM_COMMAND
SELECT CASE LO(WORD, wParam)
CASE %IDCANCEL
' // If the Escape key has been pressed...
IF HI(WORD, wParam) = %BN_CLICKED THEN
' // ... close the application by sending a WM_CLOSE message
SendMessage hwnd, %WM_CLOSE, 0, 0
EXIT FUNCTION
END IF
END SELECT
CASE %WM_PAINT
hDC = BeginPaint(hWnd, ps)
RenderScene hDC
EndPaint(hWnd, ps)
CASE %WM_DESTROY
' // End the application
PostQuitMessage 0
EXIT FUNCTION
END SELECT
' // Pass unprocessed messages to Windows
FUNCTION = DefWindowProc(hwnd, uMsg, wParam, lParam)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Render the scene
' ========================================================================================
SUB RenderScene (BYVAL hdc AS DWORD)
' // Create a cairo surface we can draw on directly
LOCAL cairo_surface AS DWORD ' cairo_surface_t*
cairo_surface = cairo_win32_surface_create(hdc)
' // Create a cairo context with the surface as the target
LOCAL cairo_image AS DWORD ' cairo_t*
cairo_image = cairo_create(cairo_surface)
' // Draw the scene
LOCAL pat AS DWORD ' cairo_pattern_t
pat = cairo_pattern_create_linear(0.0, 0.0, 0.0, 256.0)
cairo_pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 1)
cairo_pattern_add_color_stop_rgba(pat, 0, 1, 1, 1, 1)
cairo_rectangle(cairo_image, 0, 0, 256, 256)
cairo_set_source(cairo_image, pat)
cairo_fill(cairo_image)
cairo_pattern_destroy(pat)
pat = cairo_pattern_create_radial(115.2, 102.4, 25.6, 102.4, 102.4, 128.0)
cairo_pattern_add_color_stop_rgba(pat, 0, 1, 1, 1, 1)
cairo_pattern_add_color_stop_rgba(pat, 1, 0, 0, 0, 1)
cairo_set_source(cairo_image, pat)
cairo_arc(cairo_image, 128.0, 128.0, 76.8, 0, 2 * 3.141592654)
cairo_fill(cairo_image)
cairo_pattern_destroy(pat)
' // Tear down the cairo object now that we don't need it anymore.
cairo_destroy(cairo_image)
cairo_surface_destroy(cairo_surface)
END SUB
' ========================================================================================