SVG-виджеты для tcl/tk. Поддержка SVG-файлов. Часть III

Вот и наступил тот момент, когда стало возможным при разработке gui на tcl/tk простое использование в качестве иконок графических изображений, хранящихся в svg-файлах:

5c9984c633068f49a680f0e2d58c922c.png

SVG-файлы представляют собой текстовый файл с расширением .svg, содержащий xml-код, описывающий изображения в виде геометрических примитивов: линий, кривых, фигур, текста и т. д. Во второй половине 2000-х (2005–2008 г.г.) Матсом Бенгтссоном для tcl/tk был разработан пакет tkpath, который позволил создавать на холсте изображения векторной графики. Тогда же Матс Бенгтссон в рамках проект Coccinella приступил и к реализации пакета для работы с svg-файлами (с svg-xml кодом.). Пакет получил название svg2can. Из его названия следует, что он предназначался для размещения векторного графического изображения, описываемого xml-кодом, на холсте виджета tkp: canvas. К сожалению эта работа была прервана в самом начале, 29 ноября 2008 года Матс Бенгтссон покинул наш бренный мир:

aed4f95d8ecb2894a314cd65ddcab614.png

Незадолго до своей кончины Матс Бенгтссон написал:

SVG графика в Tk
Чт, 17 июля 2008 — 13:31
Только что выпущен пакет tkpath версии 0.3.0, который впервые добавляет в Tcl/Tk новый виджет холста, более соответствующей «современной» модели 2D-рисования на SVG .
Моя мотивация создания около 43 тысяч строк кода C только для этого виджета заключается в том, что он необходим для добавления SVG-графики на доску в Coccinella. Он (новый виджет холста) не претендует на звание полнофункционального средства просмотра SVG. На самом деле, пока нет поддержки перевода svg на tkpath, но поскольку я тщательно разработал виджет с учетом SVG, написать такой код не должно быть слишком сложно. SVG-графика действительно большая, и я не утверждаю, что поддерживаются (в tkpath) все ее возможности. Например, обрезка пока не поддерживается. Помните, что это все еще версия 0.3.0.
Для любопытных вы можете посетить страницу SourceForge, где можно найти несколько скриншотов и просмотреть полные исходные коды.

В этом послании для меня ключевой фразой стали слова «пока нет поддержки перевода svg на tkpath». И я взял на себя смелость устранить этот пробел. Это стало возможный, в первую очередь, из-за продуманности реализации svg-виджета холста tkp: canvas. Я еще раз повторю, слова написанные Матсом, с которыми я полностью согласен:

…пока нет поддержки перевода svg на tkpath, но поскольку я тщательно разработал виджет с учетом SVG, написать такой код сценария не должно быть слишком сложно.

И вот сегодня этот код для перевода xml-кода векторной графики в примитивы пакета tkpah написан. Это пакет svg2can версии 2.0.
Сразу оговорюсь, что рассматриваемые примеры, а также пакет svgwidgets, пакет svg2can и интерпретаторы tcl/tk для платформ Linux, Windows и Android с необходимыми пакетами можно найти на github-е. После выхода первой статьи все они претерпели изменения.
В начале статьи я употребил выражение «при разработке gui на tcl/tk стало возможным простое использование картинок/иконки, хранящихся в svg-файлах». Посудите сами. После запуска интерпретатора tcl/tk и загрузки пакета svg2can достаточно выполнить несколько команд, чтобы на холсте появилось изображение из svg-файла DocCat.svg:

d87e0f537bc433a6e95c6ed60801d68d.png

Вот эти команды tcl/tk:

%#Загружвем пакет svg2can
% package require svg2can
#Создаем окно проекта
% toplevel .t –bg cyan
.t
#Создаем холст tkp::canvas
% tkp::canvas .t.c -bg yellow -width 500 -height 450
.t.c
#Размещаем холст в окне
% pack .t.c -fill both 
#Размещаем на холсте картинку из svg-файла
%svg2can::SVGFileToCanvas .t.c svgimages/DogCat.svg
1
% winfo class .win.c
PathCanvas
#Координаты картинки на холсте
%.t.c bbox 1
-2 -1 459 358
%

В данном примере для отображения на холсте картинки используется команда svg2can: SVGFileToCanvas из пакета svg2can.

Команда svg2can: SVGFileToCanvas имеет следующий формат:

svg2can::SVGFileToCanvas <путь к svg-файлу>

В хранилище проекта на github-е добавлена папка svgimages, где лежит несколько тестовых svg-файлов и, в частности изображение щенка с котенком (файл svgimages/DogCat.svg). Xml-код картинки необязательно должен храниться в файле, его можно задавать явно в виде константы или как значение tcl-переменной. В этом случае используется команда следующего вида:

svg2can::SVGXmlToCanvas

Команды svg2can: SVGFileToCanvas и svg2can: SVGXmlToCanvas при успешном выполнении возвращают идентификатор группы (далее просто группа), в которой сгруппированы все элементы картинки. Напомним, чтобы получить все элементы картинки, достаточно выполнить команду:

<холст с картинкой> children <идентификатор группы>

Очевидно, что рисунок на холсте должен быть расположен в определенном месте и иметь определенные размеры. Для размещения картинку в соответствующих координатах служит команда клонирования группы:

svg2can::copy <холст с картинкой> <новый холст> <группа> [<параметры>]

Эта команда клонирует заданную картинку (<холст с картинкой> и <группа>) на указанный холст (<новый холст>) и возвращает идентификатор группы на новом холсте. Естественно, что клонирование может производиться и в рамках одного холста. После клонирование, оригинал может быть (если он больше не потребуется) уничтожен:

<холст с картинкой> delete <идентификатор группы>

Координаты клона на заданном холсте задается списком параметров:

-x <координата по оси X>
-y <координата по оси Y>
-width <ширина картинки>
-height <высота картинки>

Для примера клонируем нашу картинку, при этом уменьшим ее размеры в два раза и расположим справа от эталона. Характеристики оригиналы определим выполнив команду bbox:

<холст с картинкой> bbox <идентификатор группы>:

d26cca7874bc000c99f74ae1d122ca33.png

Использование svg-изображений в качестве иконок в svg-виджетах ibutton и cbutton (тип rect) рассматривалось в первой части статьи.

В качестве примера можно посмотреть тестовую утилиту svgTestOrigToSVGWIDGET_Pack.tcl, после запуска которой можно выбрать один из svg-файлов из папки svgimages:

e8e7c6b939addabbdb73c469a84962b4.png

На моем компьютере в папке /usr/share/icons можно найти много svg-файлов. Для их просмотра была написана с использованием пакетов svgwidgets и svg2can тестовая утилита examples/svgtesttocan.tcl:

b35c480943ad2c00fed8c0c2dd7a5aff.png

Пакет svg2can тестировался на платформах Linux, Windows и Android:

6f2eae2b76b0bda7a81680d5aa209a8c.png

Пример examples/svgFileToCan.tcl демонстрирует применение трансформаций (перемещение, масштабирование, поворот, смешение по осям X и Y) к загруженной svg-картинке:

4d07610e0f5d32902c8fcf084454c95d.png

Есть еще одна команда для работы с svg-файлами:

svg2can::SVGFileToCmds <путь к svg-файлу>

Эта команда может использоваться при отладке, она ничего не размещает на холсте, а возвращает список генерируемых команд пакета tkpath, которые используются для отображения на холсте картинки из svg-файла.

В заключение можно сказать, что перевод svg-файлов на tcl/tk, о котором писал Матс Бенгтссон, теперь есть.

Содержание

Часть I. SVG-виджеты для tcl/tk.

Часть II. SVG-виджеты для tcl/tk. Градиентная заливка и прозрачность.

Часть III. SVG-виджеты для tcl/tk. Поддержка SVG-файлов.

© Habrahabr.ru