'''tclcairo''' [DDG] - 2012-03-07: Swig based binding for tcl for the [cairo] library. Can be used to produce, png, pdf, ps and svg files using the same API. Provided as a starkit for Tclkit 8.4, 8.5 and 8.6 with compiled binaries for Win32-x86 and Linux-x86 [DDG] - 2020-04-19: Updates for 64bit and Cairo 1.16 and snit wrapper widget added * Author: [DDG] * Where: * Version 0.1 for Cairo 1.10.2 ** https://bitbucket.org/mittelmark/tcl-code/downloads/tclcairo1.10.2.kit (Win32-x86, Linux-x86); ** https://bitbucket.org/mittelmark/tcl-code/downloads/tclwin32cairo1.10.2.kit (Win32-x86, Linux-x86) with [Ffidl] based loading of cairo, png and zlib-dlls on Windows * Version 0.2 for Cairo 1.16 with shared libraries for 64bit Windows and 64bit Linux ** https://chiselapp.com/user/dgroth/repository/tclcode/raw/tclcairo0.2.zip?name=28b33fd883808bc75d9ca2d6d4de423f980b4702%|%tclcairo0.2.zip%|% Example session: ====== usern@eibe(7:1441):mytcl$ tclkit-8.4.19 % source tclcairo1.10.2.kit % package require cairo 0.1 % glob tclcairo1.10.2.kit/lib/* tclcairo1.10.2.kit/lib/tclcairo1.10.2 glob tclcairo1.10.2.kit/lib/*/* tclcairo1.10.2.kit/lib/tclcairo1.10.2/cairo-test.tcl tclcairo1.10.2.kit/lib/tclcairo1.10.2/cairo.i tclcairo1.10.2.kit/lib/tclcairo1.10.2/libcairo.dll tclcairo1.10.2.kit/lib/tclcairo1.10.2/libcairo.so tclcairo1.10.2.kit/lib/tclcairo1.10.2/pkgIndex.tcl % lrange [lsort [info commands cairo::*]] 0 10 ::cairo::_cairo_path_data_t ::cairo::_cairo_path_data_t_header ::cairo::_cairo_path_data_t_header_get ::cairo::_cairo_path_data_t_header_length_get ::cairo::_cairo_path_data_t_header_length_set ::cairo::_cairo_path_data_t_header_type_get ::cairo::_cairo_path_data_t_header_type_set ::cairo::_cairo_path_data_t_point ::cairo::_cairo_path_data_t_point_get ::cairo::_cairo_path_data_t_point_x_get ::cairo::_cairo_path_data_t_point_x_set % source tclcairo1.10.2.kit/lib/tclcairo1.10.2/cairo-test.tcl % exit usern@eibe(7:1442):mytcl$ ls -lt | head insgesamt 55828 -rw-r--r-- 1 usern users 254 7. Mär 15:07 cairo-test2.png -rw-r--r-- 1 usern users 929 7. Mär 15:07 test.pdf -rw-r--r-- 1 usern users 2503 7. Mär 15:07 test.ps -rw-r--r-- 1 usern users 484 7. Mär 15:07 test.svg ====== If the library loading on windows fails try the larger windows starkit which contains as well cairo, zip and png shared libs. Ok let's create a PDF-file having a red rectangle: ====== package require cairo set surface [::cairo::cairo_pdf_surface_create test.pdf 300 300] set cr [::cairo::cairo_create $surface] ::cairo::cairo_rectangle $cr 10 10 40 40 ::cairo::cairo_set_source_rgb $cr 1 1 1 ::cairo::cairo_fill $cr ::cairo::cairo_rectangle $cr 20 20 20 20 ::cairo::cairo_set_source_rgb $cr 1 0 0 ::cairo::cairo_fill $cr ::cairo::cairo_show_page $cr ::cairo::cairo_surface_flush $surface ::cairo::cairo_surface_destroy $surface ::cairo::cairo_destroy $cr ====== If you would like to create the same as svg just a replacemment of the first line is needed: ====== set surface [::cairo::cairo_svg_surface_create test.svg 300 300] set cr [::cairo::cairo_create $surface] ::cairo::cairo_rectangle $cr 10 10 40 40 ::cairo::cairo_set_source_rgb $cr 1 1 1 ::cairo::cairo_fill $cr ::cairo::cairo_rectangle $cr 20 20 20 20 ::cairo::cairo_set_source_rgb $cr 1 0 0 ::cairo::cairo_fill $cr ::cairo::cairo_show_page $cr ::cairo::cairo_surface_flush $surface ::cairo::cairo_surface_destroy $surface ::cairo::cairo_destroy $cr ====== You have to use the C-API documentation provided here: http://cairographics.org/manual/ A tcl wrapper using an OO-framework like [Snit] or [Itcl] would be greet in making it more Tcl-ish. '''Swig wrapper''' file: cairo.i ====== %module cairo %{ #include #include #include #include #include #include %} %include "/usr/include/cairo/cairo-features.h" %include "/usr/include/cairo/cairo.h" %include "/usr/include/cairo/cairo-version.h" %include "/usr/include/cairo/cairo-pdf.h" %include "/usr/include/cairo/cairo-svg.h" %include "/usr/include/cairo/cairo-ps.h" ====== This file is translated into c-code using [swig] and compiled using [gcc] and compressed using [upx]: ====== $ swig -tcl -namespace cairo.i $ gcc -shared -fPIC -DUSE_TCL_STUBS \ -I/usr/include/cairo -I/opt/tcl/include cairo_wrap.c -o libcairo.so \ -lcairo -L/opt/tcl/lib -ltclstub8.4 $ upx libcairo.so ====== As I could not compile cairo on OSX-X the starkit does not contain libraries for OS-X. **Snit Widget** [DDG] - 2020-04-19: Here a snit wrapper widget for display dynamically the commands in a [ttk::label]. ====== package require snit snit::widget cimage { option -width 100 option -height 100 variable surface variable history [list] variable cr variable pngfile constructor {args} { $self configurelist $args pack [ttk::label $win.img -text "Hello"] ;# -in $win -width $options(-width) -height $options(-height) set surface [::cairo::cairo_image_surface_create 0 $options(-width) $options(-height)] set cr [::cairo::cairo_create $surface] set pngfile [file tempfile].png ::cairo::cairo_rectangle $cr 1 1 [expr {$options(-width)-2}] [expr {$options(-height)-2}] ::cairo::cairo_set_source_rgb $cr 1 1 1 ::cairo::cairo_fill $cr $self cairo update } method cairo {cmd args} { # these lists must be updated with more commands # doing automatic updates if {[lsearch [list update fill show_text] $cmd] >= 0} { if {[lsearch [list fill show_text] $cmd] >= 0} { ::cairo::cairo_$cmd $cr {*}$args lappend history [list $cmd $args] } ::cairo::cairo_show_page $cr ::cairo::cairo_surface_write_to_png $surface $pngfile catch rename imgPng "" image create photo imgPng -file $pngfile $win.img configure -image imgPng } else { ::cairo::cairo_$cmd $cr {*}$args lappend history [list $cmd $args] } } method save {filename} { set ext [string range [file extension $filename] 1 end] set isurface [::cairo::cairo_${ext}_surface_create $filename $options(-width) $options(-height)] set icr [::cairo::cairo_create $isurface] foreach h $history { foreach {cmd args} $h break ::cairo::cairo_$cmd $icr {*}$args } ::cairo::cairo_show_page $icr ::cairo::cairo_surface_flush $isurface ::cairo::cairo_surface_destroy $isurface ::cairo::cairo_destroy $icr } } ====== The *save* function allows to save the image which is displayed in the ''ttk::label'' as well as pdf, postscript (ps) or svg file. Below is an example: ====== pack [cimage .img] .img cairo rectangle 20 20 20 20 .img cairo set_source_rgb 1 0 0 .img cairo fill .img cairo rectangle 50 20 20 20 .img cairo fill .img cairo move_to 20 60 .img cairo set_source_rgb 0 0 0 .img cairo show_text "Hello World!" .img save test.svg .img save test.pdf ====== [tclcairo-image] **Todo** * extend lists for automatic updates * use xrender extension to direct display as Tl widget(?) * snit::type in addition to snit::widget to work as well without Tk * check for device specific commands such as outlines for pdf to only execute those commands in the save method **See also** * Cairo-API: https://www.cairographics.org/manual/index-all.html **Discussion** Please discuss here ... <>Graphics | PDF | Postscript