'''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 <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.
**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 Tlk 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 ...
<<categories>>Graphics | PDF | SVG