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
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 <cairo-features.h> #include <cairo.h> #include <cairo-version.h> #include <cairo-pdf.h> #include <cairo-ps.h> #include <cairo-svg.h> %} %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.
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
Please discuss here ...