>From e6c08bd627006dfb3c505e7f5bd582b18af7ef56 Mon Sep 17 00:00:00 2001 From: Paul Chavent Date: Mon, 12 Sep 2011 23:47:06 +0200 Subject: [PATCH 2/2] Add sozi front end. --- objects/Misc/Makefile.am | 7 +- objects/Misc/libmisc.c | 2 + objects/Misc/pixmaps/sozi-frame.xpm | 196 +++++++++ objects/Misc/sozi-frame.c | 792 +++++++++++++++++++++++++++++++++++ objects/Misc/sozi.h | 222 ++++++++++ sheets/Misc.sheet.in | 3 + 6 files changed, 1219 insertions(+), 3 deletions(-) create mode 100644 objects/Misc/pixmaps/sozi-frame.xpm create mode 100644 objects/Misc/sozi-frame.c create mode 100644 objects/Misc/sozi.h diff --git a/objects/Misc/Makefile.am b/objects/Misc/Makefile.am index 306fae4..64e01ad 100644 --- a/objects/Misc/Makefile.am +++ b/objects/Misc/Makefile.am @@ -7,8 +7,8 @@ libmisc_objects_la_SOURCES = \ diagram_as_object.c \ grid_object.c \ measure.c \ - tree.c - + tree.c \ + sozi-frame.c libmisc_objects_la_LDFLAGS = -export-dynamic -module -avoid-version $(NO_UNDEFINED) @@ -23,7 +23,8 @@ EXTRA_DIST = \ pixmaps/grid_object.xpm \ pixmaps/measure.xpm \ pixmaps/newgroup.xpm \ - pixmaps/tree.xpm + pixmaps/tree.xpm \ + pixmaps/sozi-frame.xpm diff --git a/objects/Misc/libmisc.c b/objects/Misc/libmisc.c index e72ea9a..65b75a9 100644 --- a/objects/Misc/libmisc.c +++ b/objects/Misc/libmisc.c @@ -33,6 +33,7 @@ extern DiaObjectType grid_object_type; extern DiaObjectType tree_type; extern DiaObjectType measure_type; extern DiaObjectType diagram_as_element_type; +extern DiaObjectType sozi_frame_type; DIA_PLUGIN_CHECK_INIT @@ -48,6 +49,7 @@ dia_plugin_init(PluginInfo *info) object_register_type(&tree_type); object_register_type(&measure_type); object_register_type(&diagram_as_element_type); + object_register_type(&sozi_frame_type); return DIA_PLUGIN_INIT_OK; } diff --git a/objects/Misc/pixmaps/sozi-frame.xpm b/objects/Misc/pixmaps/sozi-frame.xpm new file mode 100644 index 0000000..e5f3ed3 --- /dev/null +++ b/objects/Misc/pixmaps/sozi-frame.xpm @@ -0,0 +1,196 @@ +/* XPM */ +static char * sozi_frame_xpm[] = { +"22 22 171 2", +" c #FFFFFF", +". c #FEFEFE", +"+ c #FDFDFD", +"@ c #F7F7F8", +"# c #D2D2D2", +"$ c #939393", +"% c #8A8A8A", +"& c #BEBEBE", +"* c #F2F2F2", +"= c #FCFCFC", +"- c #F3F3F3", +"; c #FBFBFB", +"> c #FEFEFF", +", c #FCFCFB", +"' c #FAF4F1", +") c #FAF1EB", +"! c #F8F5F2", +"~ c #BFBFBF", +"{ c #E4E4E4", +"] c #F1F1F1", +"^ c #ADADAD", +"/ c #F5F5F5", +"( c #BEBABE", +"_ c #99909A", +": c #EDEAED", +"< c #ECDCD2", +"[ c #C3682D", +"} c #C64500", +"| c #98562A", +"1 c #BBB6B2", +"2 c #F8F8F9", +"3 c #FBFCFB", +"4 c #FBFCFC", +"5 c #E8BC9E", +"6 c #F55A00", +"7 c #F05F00", +"8 c #E4BCA1", +"9 c #F3F8FC", +"0 c #F6F6F6", +"a c #DCDCDC", +"b c #CACACA", +"c c #CDCDCD", +"d c #CBCBC9", +"e c #D8D8D7", +"f c #FBFBFC", +"g c #E7B99A", +"h c #F25600", +"i c #DD7A39", +"j c #E7DDD6", +"k c #D0D0D0", +"l c #C8C8C8", +"m c #989898", +"n c #CACBCC", +"o c #A3A298", +"p c #BFB483", +"q c #EEE8D1", +"r c #FBFBFA", +"s c #FAFBFC", +"t c #E6BA9E", +"u c #EB5400", +"v c #ECA372", +"w c #F8FBFD", +"x c #ECECEC", +"y c #FBFCFE", +"z c #D3D1C7", +"A c #DDB617", +"B c #C4A423", +"C c #EFECE1", +"D c #FBFDFF", +"E c #E5C3AD", +"F c #DD5A03", +"G c #E8AD85", +"H c #F9FFFF", +"I c #E6E6E6", +"J c #E9E9EA", +"K c #CFCECD", +"L c #DEBF2D", +"M c #C99E00", +"N c #EDE9D1", +"O c #E4D5CC", +"P c #AE6636", +"Q c #E2BCA3", +"R c #FFFFFE", +"S c #E5E5E5", +"T c #C8C8C9", +"U c #D9DBE5", +"V c #DBBD39", +"W c #B79A21", +"X c #EDEADF", +"Y c #ECEAE9", +"Z c #A98C7A", +"` c #D3B8A6", +" . c #E3E3E3", +".. c #C7C7C7", +"+. c #F1F3FC", +"@. c #A5965C", +"#. c #BDB496", +"$. c #BEBBB8", +"%. c #B3ACA7", +"&. c #E9E7E7", +"*. c #B6B4B4", +"=. c #92939A", +"-. c #DFDFE3", +";. c #ADAEAF", +">. c #CCCDCE", +",. c #7D898D", +"'. c #DCDBDA", +"). c #EDEDED", +"!. c #DADADA", +"~. c #9B9B9B", +"{. c #DEDEDE", +"]. c #FFFEFE", +"^. c #B4CBD2", +"/. c #389CB5", +"(. c #6E9CA8", +"_. c #DDDDDD", +":. c #EAEAEA", +"<. c #CECECE", +"[. c #B6B6B6", +"}. c #E7E7E7", +"|. c #B2D0D8", +"1. c #1BB6DE", +"2. c #00A7D3", +"3. c #82AFBB", +"4. c #EEEEEE", +"5. c #999999", +"6. c #F0F0F0", +"7. c #E0E0E0", +"8. c #F9FCFC", +"9. c #1194B5", +"0. c #00CEFF", +"a. c #23BAE1", +"b. c #C3D0D4", +"c. c #D4D4D4", +"d. c #FAFCFC", +"e. c #2E8FA8", +"f. c #00BDEF", +"g. c #3AB4D3", +"h. c #F8F2F1", +"i. c #EBEBEB", +"j. c #C6C6C6", +"k. c #A8A8A8", +"l. c #F4F4F4", +"m. c #DBE7EB", +"n. c #6894A0", +"o. c #6C8288", +"p. c #A3A1A0", +"q. c #949494", +"r. c #8F8F8F", +"s. c #E2E2E2", +"t. c #BABABA", +"u. c #CBCACA", +"v. c #9A9898", +"w. c #F3F2F1", +"x. c #E9E9E9", +"y. c #E8E8E8", +"z. c #F9F9F9", +"A. c #F7F7F7", +"B. c #A9A9A9", +"C. c #C1C1C1", +"D. c #D7D7D7", +"E. c #F7F6F6", +"F. c #FAFAFA", +"G. c #5F5F5F", +"H. c #B2B2B2", +"I. c #F8F8F8", +"J. c #D8D8D8", +"K. c #909090", +"L. c #7D7D7D", +"M. c #858585", +"N. c #B4B4B4", +" . . . . . + + . . . . . ", +" . @ # $ % & * . = - ; . ", +" > , ' ) ! ~ { ] ^ / ( _ : ", +" < [ } | 1 2 . . * ~ 3 . . ", +" 4 5 6 7 8 9 = . 0 a b c ; d e > . ", +" f g h i j . 0 k l m n o p q r . . ", +" s t u v w . x y z A B C > . ", +" D E F G H . . = I J K L M N ", +" O P Q R . S T U V W X > ", +" . Y Z ` > . . + # 2 ", +" R $.%. . . . . &.*.c =.-. ", +" . n ;.= . . >.,.'.a ). . . ", +" . !.~.{. . . ].^./.(. . # _. ", +" . :.<.[.}. . + |.1.2.3. 4...5.= ", +" * 6.c 7.+ 8.9.0.a.b. . 6.<.+ ", +" . c.7.# - . . d.e.f.g.h. ", +" . i.j.k.l. > m.n.o.p.$ q.r.s.. ", +" . . I & t.0 ; ] u.v.w.).x.x.y.z.. . ", +" . + A.B.c C.<.D.E. . . ", +"F.G.H.i.I. 4.C./ z.; ; . . ", +". / J.~ K.L.M.N.l.. . . ", +" . . + + + . . . . . "}; diff --git a/objects/Misc/sozi-frame.c b/objects/Misc/sozi-frame.c new file mode 100644 index 0000000..1e340a4 --- /dev/null +++ b/objects/Misc/sozi-frame.c @@ -0,0 +1,792 @@ +/* Dia -- an diagram creation/manipulation program + * Copyright (C) 1999 Alexander Larsson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* standard libs*/ +#include +#include + +/* xpath for searching in the svg doc */ +#include + +/* dia stuff */ +#include "object.h" +#include "diarenderer.h" +#include "diasvgrenderer.h" +#include "properties.h" +#include "text.h" + +/* sozi stuff */ +#include "pixmaps/sozi-frame.xpm" +#include "sozi.h" + +# define M_2_PI 6.28318530718 + +/****************************************************************************** + * TODO: + * - make a static variable that hold the sequence of the frame (local to a + * file ?) + * - implement transition options + * - render sequence number and frame timeout for example + * - + *****************************************************************************/ + +typedef struct _SoziFrame +{ + /* dia object inheritance */ + + DiaObject object; + + /* geometry of the object */ + + Point center; + real width; + real height; + real angle; + + real cos_angle; + real sin_angle; + + real m[6]; /** transformation matrix of the unit square */ + + /* corners of the object */ + + Point corners[4]; + + /* sozi specific stuff */ + + int sequence; + + Text * title; + gboolean hide; + gboolean clip; + int timeout; + +} SoziFrame; + +/****************************************************************************** + * + *****************************************************************************/ + +static DiaObject * sozi_frame_create(Point *startpoint, + void *user_data, + Handle **handle1, + Handle **handle2); +static DiaObject * sozi_frame_load(ObjectNode obj_node, int version, const char *filename); +static void sozi_frame_save(SoziFrame *sozi_frame, ObjectNode obj_node, const char *filename); + +static ObjectTypeOps sozi_frame_type_ops = +{ + (CreateFunc) sozi_frame_create, /* create */ + (LoadFunc) sozi_frame_load, /* load (== object_load_using_properties ?) */ + (SaveFunc) sozi_frame_save, /* save (== object_save_using_properties ?) */ + (GetDefaultsFunc) NULL, + (ApplyDefaultsFunc) NULL, +}; + +DiaObjectType sozi_frame_type = +{ + "Misc - Sozi Frame", /* name */ + 0, /* version */ + (char **) sozi_frame_xpm, /* pixmap */ + &sozi_frame_type_ops, /* ops */ + NULL, /* pixmap_file */ + 0 /* default_user_data */ +}; + +/****************************************************************************** + * + *****************************************************************************/ + +static void sozi_frame_destroy(SoziFrame *sozi_frame); + +static void sozi_frame_draw(SoziFrame *sozi_frame, DiaRenderer *renderer); + +static real sozi_frame_distance_from(SoziFrame *sozi_frame, Point *point); + +static void sozi_frame_select(SoziFrame *sozi_frame, Point *clicked_point, + DiaRenderer *interactive_renderer); + +static DiaObject * sozi_frame_copy(SoziFrame *sozi_frame); + +static ObjectChange* sozi_frame_move(SoziFrame *sozi_frame, Point *to); + +static ObjectChange* sozi_frame_move_handle(SoziFrame *sozi_frame, Handle *handle, + Point *to, ConnectionPoint *cp, + HandleMoveReason reason, ModifierKeys modifiers); + +static PropDescription * sozi_frame_describe_props(SoziFrame *sozi_frame); + +static void sozi_frame_get_props(SoziFrame *sozi_frame, GPtrArray *props); + +static void sozi_frame_set_props(SoziFrame *sozi_frame, GPtrArray *props); + + +static ObjectOps sozi_frame_ops = +{ + (DestroyFunc) sozi_frame_destroy, + (DrawFunc) sozi_frame_draw, + (DistanceFunc) sozi_frame_distance_from, + (SelectFunc) sozi_frame_select, + (CopyFunc) sozi_frame_copy, + (MoveFunc) sozi_frame_move, + (MoveHandleFunc) sozi_frame_move_handle, + (GetPropertiesFunc) object_create_props_dialog, + (ApplyPropertiesDialogFunc) object_apply_props_from_dialog, + (ObjectMenuFunc) 0, + (DescribePropsFunc) sozi_frame_describe_props, + (GetPropsFunc) sozi_frame_get_props, + (SetPropsFunc) sozi_frame_set_props, + (TextEditFunc) 0, + (ApplyPropertiesListFunc) object_apply_props, +}; + +/****************************************************************************** + * unit square + *****************************************************************************/ +static const Handle default_handles[4] = +{ + {HANDLE_RESIZE_NW, HANDLE_MAJOR_CONTROL, { 0, 0}, HANDLE_NONCONNECTABLE, NULL}, + {HANDLE_RESIZE_SW, HANDLE_MAJOR_CONTROL, { 0, 1}, HANDLE_NONCONNECTABLE, NULL}, + {HANDLE_RESIZE_SE, HANDLE_MAJOR_CONTROL, { 1, 1}, HANDLE_NONCONNECTABLE, NULL}, + {HANDLE_RESIZE_NE, HANDLE_MAJOR_CONTROL, { 1, 0}, HANDLE_NONCONNECTABLE, NULL}, +}; + +static const real sozi_frame_line_width = 0.01; + +/****************************************************************************** + * + *****************************************************************************/ +static void +sozi_frame_init(SoziFrame *sozi_frame, Point *center) +{ + DiaObject *dia_object; + int i; + static int sequence = 0; + char sequence_str[8]; + + dia_object = &sozi_frame->object; + + dia_object->type = &sozi_frame_type; + dia_object->ops = &sozi_frame_ops; + dia_object->position = *center; + + /* dia_object->bounding_box is set in sozi_frame_update_data */ + + dia_object->num_handles = 4; + if(dia_object->handles == NULL) { + dia_object->handles = g_new0(Handle *, 4); + } + + for (i = 0; i < 4; i++) { + if(dia_object->handles[i] == NULL) { + dia_object->handles[i] = g_new0(Handle, 1); + } + *dia_object->handles[i] = default_handles[i]; + } + + dia_object->num_connections = 1; + if(dia_object->connections == NULL) { + dia_object->connections = g_new0(ConnectionPoint *, 1); + } + + for (i = 0; i < 1; i++) { + if(dia_object->connections[i] == NULL) { + dia_object->connections[i] = g_new0(ConnectionPoint, 1); + } + dia_object->connections[0]->object = dia_object; + dia_object->connections[0]->directions = DIR_ALL; + } + + /* dia_object->enclosing_box is set in sozi_frame_update_data */ + + sozi_frame->center = *center; + sozi_frame->width = 1; + sozi_frame->height = 1; + sozi_frame->angle = 0; + + /* sozi_frame->cos_angle is set in sozi_frame_update_data */ + /* sozi_frame->sin_angle is set in sozi_frame_update_data */ + /* sozi_frame->m is set in sozi_frame_update_data */ + + /* sozi_frame->corners are set in sozi_frame_update_data */ + + sozi_frame->sequence = sequence++; /* FIXME : it is broken */ + g_snprintf(sequence_str, sizeof(sequence_str), "%d", sozi_frame->sequence); + + if(sozi_frame->title == NULL) { + sozi_frame->title = new_text_default(&sozi_frame->center, &color_black, ALIGN_LEFT); + } + text_set_string(sozi_frame->title, sequence_str); + + sozi_frame->hide = TRUE; + sozi_frame->clip = TRUE; + sozi_frame->timeout = 0; + +} + +/****************************************************************************** + * + *****************************************************************************/ +static void +sozi_frame_update_data(SoziFrame *sozi_frame) +{ + DiaObject *dia_object; + Point title_pos; + Rectangle title_bb; + int i; + + dia_object = &sozi_frame->object; + + dia_object->position = sozi_frame->center; + + dia_object->bounding_box.left = G_MAXFLOAT; + dia_object->bounding_box.top = G_MAXFLOAT; + dia_object->bounding_box.right = -G_MAXFLOAT; + dia_object->bounding_box.bottom = -G_MAXFLOAT; + + if(sozi_frame->angle < 0) { + sozi_frame->angle += M_2_PI; + } + if(M_2_PI < sozi_frame->angle) { + sozi_frame->angle -= M_2_PI; + } + sozi_frame->cos_angle = cos(sozi_frame->angle); + sozi_frame->sin_angle = sin(sozi_frame->angle); + + /* + * + * translate(center.x,center.y) . rotate(angle) . scale(width,height) . translate(-0.5,-0.5) + * + * m + * = + * | 1 0 x | . | cos(a) sin(a) 0 | . | w 0 0 | . | 1 0 -0.5 | + * | 0 1 y | | -sin(a) cos(a) 0 | | 0 h 0 | | 0 1 -0.5 | + * | 0 0 1 | | 0 0 1 | | 0 0 1 | | 0 0 1 | + * = + * | w*cos(a) h*sin(a) x-0.5*w*cos(a)-0.5*h*sin(a) | + * | -w*sin(a) h*cos(a) y+0.5*w*sin(a)-0.5*h*cos(a) | + * | 0 0 1 | + */ + sozi_frame->m[0] = sozi_frame->width * sozi_frame->cos_angle ; + sozi_frame->m[1] = sozi_frame->height * sozi_frame->sin_angle ; + sozi_frame->m[2] = sozi_frame->center.x - 0.5 * sozi_frame->width * sozi_frame->cos_angle - 0.5 * sozi_frame->height * sozi_frame->sin_angle; + sozi_frame->m[3] = -sozi_frame->width * sozi_frame->sin_angle ; + sozi_frame->m[4] = sozi_frame->height * sozi_frame->cos_angle ; + sozi_frame->m[5] = sozi_frame->center.y + 0.5 * sozi_frame->width * sozi_frame->sin_angle - 0.5 * sozi_frame->height * sozi_frame->cos_angle; + + for (i = 0; i < 4; i++) { + + sozi_frame->corners[i].x = sozi_frame->m[0] * default_handles[i].pos.x + sozi_frame->m[1] * default_handles[i].pos.y + sozi_frame->m[2]; + sozi_frame->corners[i].y = sozi_frame->m[3] * default_handles[i].pos.x + sozi_frame->m[4] * default_handles[i].pos.y + sozi_frame->m[5]; + + dia_object->handles[i]->pos = sozi_frame->corners[i]; + + if(i == 0) { + dia_object->connections[0]->last_pos = dia_object->connections[0]->pos; + dia_object->connections[0]->pos = sozi_frame->corners[i]; + } + + if(sozi_frame->corners[i].x < dia_object->bounding_box.left) { + dia_object->bounding_box.left = sozi_frame->corners[i].x - sozi_frame_line_width; + } + if(dia_object->bounding_box.right < sozi_frame->corners[i].x) { + dia_object->bounding_box.right = sozi_frame->corners[i].x + sozi_frame_line_width; + } + if(sozi_frame->corners[i].y < dia_object->bounding_box.top) { + dia_object->bounding_box.top = sozi_frame->corners[i].y - sozi_frame_line_width; + } + if(dia_object->bounding_box.bottom < sozi_frame->corners[i].y) { + dia_object->bounding_box.bottom = sozi_frame->corners[i].y + sozi_frame_line_width; + } + } + + title_pos = sozi_frame->corners[0]; + title_pos.y += text_get_ascent(sozi_frame->title); + text_set_position(sozi_frame->title, &title_pos); + text_calc_boundingbox(sozi_frame->title, &title_bb); + rectangle_union(&dia_object->bounding_box, &title_bb); + + dia_object->enclosing_box = dia_object->bounding_box; +} + +/****************************************************************************** + * + *****************************************************************************/ +static DiaObject * +sozi_frame_create(Point *startpoint, + void *user_data, + Handle **handle1, + Handle **handle2) +{ + SoziFrame *sozi_frame; + + sozi_frame = g_new0(SoziFrame, 1); + + sozi_frame_init(sozi_frame, startpoint); + + sozi_frame_update_data(sozi_frame); + + *handle1 = NULL; + *handle2 = NULL; + + return &sozi_frame->object; +} + +/****************************************************************************** + * + *****************************************************************************/ +static DiaObject * +sozi_frame_load(ObjectNode obj_node, int version, const char *filename) +{ + return object_load_using_properties(&sozi_frame_type, obj_node, version, filename); +} + +/****************************************************************************** + * + *****************************************************************************/ +static void +sozi_frame_save(SoziFrame *sozi_frame, ObjectNode obj_node, const char *filename) +{ + object_save_using_properties(&sozi_frame->object, obj_node, filename); +} + +/****************************************************************************** + * + *****************************************************************************/ +static void +sozi_frame_destroy(SoziFrame *sozi_frame) +{ + int i; + + text_destroy(sozi_frame->title); + + object_unconnect_all(&sozi_frame->object); + + for (i = 0; i < 1; i++) { + if(sozi_frame->object.connections[i] != NULL) { + g_free(sozi_frame->object.connections[i]); + } + } + + for (i = 0; i < 4; i++) { + if(sozi_frame->object.handles[i] != NULL) { + g_free(sozi_frame->object.handles[i]); + } + } + + if (sozi_frame->object.connections) { + g_free(sozi_frame->object.connections); + sozi_frame->object.connections = NULL; + } + + if (sozi_frame->object.handles) { + g_free(sozi_frame->object.handles); + sozi_frame->object.handles = NULL; + } + + if (sozi_frame->object.meta) { + g_hash_table_destroy (sozi_frame->object.meta); + sozi_frame->object.meta = NULL; + } +} + +/****************************************************************************** + * + *****************************************************************************/ + +static int +find_sozi_elem(xmlDocPtr doc, const xmlChar *sozi_elem) +{ + /* static const xmlChar *sozi_elem = (xmlChar*) "//script[ id='sozi-script']"; */ + xmlXPathContextPtr context; + xmlXPathObjectPtr result; + + context = xmlXPathNewContext(doc); + if(context == NULL) { + fprintf(stderr, "Error in xmlXPathNewContext\n"); + return 0; + } + + result = xmlXPathEvalExpression(sozi_elem, context); + xmlXPathFreeContext(context); + if(result == NULL) { + fprintf(stderr, "Error in xmlXPathEvalExpression\n"); + return 0; + } + + if(xmlXPathNodeSetIsEmpty(result->nodesetval)) { + xmlXPathFreeObject(result); + return 0; + } + + xmlXPathFreeObject(result); + return 1; +} + +static void +sozi_frame_draw_svg(SoziFrame *sozi_frame, DiaSvgRenderer *svg_renderer) +{ + static xmlNs *sozi_name_space = NULL; + static unsigned refid_cnt = 0; + xmlNodePtr root; + xmlNodePtr node; + xmlChar * escaped; + /* buffers for storing attributes */ + gchar * refid; + gchar * sequence; + gchar * x; + gchar * y; + gchar * width; + gchar * height; + gchar * transform; + gchar * style; + gchar dtostr_buf[6][G_ASCII_DTOSTR_BUF_SIZE]; +# define dtostr(n,d) g_ascii_formatd(dtostr_buf[n], sizeof(dtostr_buf[n]), "%g", (d)) + + root = xmlDocGetRootElement(svg_renderer->doc); + + /* check that the sozi namespace, scripts and style are present */ + + if (!find_sozi_elem(svg_renderer->doc, (const xmlChar*) "//script[ id='sozi-script']")) { + + sozi_name_space = xmlNewNs(root, (const xmlChar *)"http://sozi.baierouge.fr", (const xmlChar *)"sozi"); + + node = xmlNewChild(root, NULL, (const xmlChar *)"script", NULL); + xmlSetProp(node, (const xmlChar *)"id", (const xmlChar *)"sozi-script"); + xmlSetProp(node, (const xmlChar *)"sozi:version", (const xmlChar *)sozi_version); + escaped = xmlEncodeEntitiesReentrant(svg_renderer->doc, (const xmlChar *)sozi_js); + xmlNodeSetContent(node, escaped); + xmlFree(escaped); + + node = xmlNewChild(root, NULL, (const xmlChar *)"style", NULL); + xmlSetProp(node, (const xmlChar *)"id", (const xmlChar *)"sozi-style"); + xmlSetProp(node, (const xmlChar *)"sozi:version", (const xmlChar *)sozi_version); + escaped = xmlEncodeEntitiesReentrant(svg_renderer->doc, (const xmlChar *)sozi_css); + xmlNodeSetContent(node, escaped); + xmlFree(escaped); + } + + assert(sozi_name_space != NULL); + + /* format attributes */ + refid = g_strdup_printf("sozi_frame_%d", refid_cnt++); + sequence = g_strdup_printf("%d", sozi_frame->sequence); + +#if 1 /* pure transformation */ + + x = g_strdup_printf("0"); + y = g_strdup_printf("0"); + width = g_strdup_printf("1"); + height = g_strdup_printf("1"); + transform = g_strdup_printf("matrix(%s,%s,%s,%s,%s,%s)", + dtostr(0, sozi_frame->m[0] * svg_renderer->scale), + dtostr(1, sozi_frame->m[3] * svg_renderer->scale), + dtostr(2, sozi_frame->m[1] * svg_renderer->scale), + dtostr(3, sozi_frame->m[4] * svg_renderer->scale), + dtostr(4, sozi_frame->m[2] * svg_renderer->scale), + dtostr(5, sozi_frame->m[5] * svg_renderer->scale)); + /* FIXME : Scaling problem on stroke width : http://dev.w3.org/SVG/modules/vectoreffects/master/SVGVectorEffects.html */ + style = g_strdup_printf("fill:none;stroke:#000000;stroke-width:%s", + dtostr(0, 0.1 / svg_renderer->scale)); + +#elif 0 /* decompose transformation */ + + x = g_strdup_printf("0"); + y = g_strdup_printf("0"); + width = g_strdup_printf("1"); + height = g_strdup_printf("1"); + transform = g_strdup_printf("scale(%s,%s),translate(%s,%s),rotate(%s),scale(%s,%s),translate(-0.5,-0.5)", + dtostr(0, svg_renderer->scale), + dtostr(1, svg_renderer->scale), + dtostr(2, sozi_frame->center.x), + dtostr(3, sozi_frame->center.y), + dtostr(4, 180 * sozi_frame->angle / M_PI), + dtostr(5, sozi_frame->width), + dtostr(6, sozi_frame->height)); + /* FIXME : Scaling problem on stroke width : http://dev.w3.org/SVG/modules/vectoreffects/master/SVGVectorEffects.html */ + style = g_strdup_printf("fill:none;stroke:#000000;stroke-width:%s", + dtostr(0, 0.1 / svg_renderer->scale)); + +#else /* no apply scale to transformation */ + + x = g_strdup_printf("%s", dtostr(0, sozi_frame->m[2] * svg_renderer->scale)); + y = g_strdup_printf("%s", dtostr(0, sozi_frame->m[5] * svg_renderer->scale)); + width = g_strdup_printf("%s", dtostr(0, sozi_frame->width * svg_renderer->scale)); + height = g_strdup_printf("%s", dtostr(0, sozi_frame->height * svg_renderer->scale)); + transform = g_strdup_printf("rotate(%s,%s,%s)", + dtostr(0, 180 * sozi_frame->angle / M_PI), + dtostr(1, sozi_frame->m[2] * svg_renderer->scale), + dtostr(2, sozi_frame->m[5] * svg_renderer->scale)); + + style = g_strdup_printf("fill:none;stroke:#000000;stroke-width:0.1"); + +#endif + + /* add a "classic" frame */ + + node = xmlNewChild(svg_renderer->root, svg_renderer->svg_name_space, (const xmlChar *)"rect", NULL); + + xmlSetProp(node, (const xmlChar *)"id" , (xmlChar *)refid); + xmlSetProp(node, (const xmlChar *)"x" , (xmlChar *)x); + xmlSetProp(node, (const xmlChar *)"y" , (xmlChar *)y); + xmlSetProp(node, (const xmlChar *)"width" , (xmlChar *)width); + xmlSetProp(node, (const xmlChar *)"height" , (xmlChar *)height); + xmlSetProp(node, (const xmlChar *)"transform", (xmlChar *)transform); + xmlSetProp(node, (const xmlChar *)"style" , (xmlChar *)style); + + /* add a "custom" frame for sozi */ + + node = xmlNewChild(root, sozi_name_space, (const xmlChar *)"frame", NULL); + xmlSetProp(node, (const xmlChar *)"sozi:refid" , (const xmlChar *)refid); + xmlSetProp(node, (const xmlChar *)"sozi:sequence" , (const xmlChar *)sequence); + xmlSetProp(node, (const xmlChar *)"sozi:title" , (const xmlChar *)text_get_line(sozi_frame->title, 0)); + xmlSetProp(node, (const xmlChar *)"sozi:hide" , (const xmlChar *)((sozi_frame->hide)?"true":"false")); + xmlSetProp(node, (const xmlChar *)"sozi:clip" , (const xmlChar *)((sozi_frame->clip)?"true":"false")); + xmlSetProp(node, (const xmlChar *)"sozi:timeout-enable" , (const xmlChar *)((sozi_frame->timeout)?"true":"false")); + xmlSetProp(node, (const xmlChar *)"sozi:timeout-ms" , (const xmlChar *)"5000"); + xmlSetProp(node, (const xmlChar *)"sozi:transition-profile" , (const xmlChar *)"linear"); + xmlSetProp(node, (const xmlChar *)"sozi:transition-zoom-percent", (const xmlChar *)"0"); + xmlSetProp(node, (const xmlChar *)"sozi:transition-duration-ms" , (const xmlChar *)"1000"); + + + /* free resources */ + g_free(refid); + g_free(sequence); + g_free(x); + g_free(y); + g_free(width); + g_free(height); + g_free(transform); + g_free(style); + +# undef dtostr +} + +/****************************************************************************** + * + *****************************************************************************/ + +#define DIA_IS_INTERACTIVE_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DIA_TYPE_INTERACTIVE_RENDERER)) + +static void +sozi_frame_draw(SoziFrame *sozi_frame, DiaRenderer *renderer) +{ + + if (DIA_IS_SVG_RENDERER(renderer)) { + sozi_frame_draw_svg(sozi_frame, DIA_SVG_RENDERER (renderer)); + } + else if(DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer) || + !sozi_frame->hide) { + DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); + + renderer_ops->set_linewidth(renderer, sozi_frame_line_width); + renderer_ops->set_linecaps(renderer, LINECAPS_BUTT); + renderer_ops->set_linejoin(renderer, LINEJOIN_MITER); + renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID); + + renderer_ops->draw_polygon(renderer, sozi_frame->corners, 4, &color_black); + + text_draw(sozi_frame->title, renderer); + } +} + +/****************************************************************************** + * + *****************************************************************************/ + +static real +sozi_frame_distance_from(SoziFrame *sozi_frame, Point *point) +{ + return distance_polygon_point(sozi_frame->corners, 4, sozi_frame_line_width, point); +} + +/****************************************************************************** + * + *****************************************************************************/ + +static void +sozi_frame_select(SoziFrame *sozi_frame, Point *clicked_point, + DiaRenderer *interactive_renderer) +{ + text_set_cursor(sozi_frame->title, clicked_point, interactive_renderer); + text_grab_focus(sozi_frame->title, &sozi_frame->object); + sozi_frame_update_data(sozi_frame); +} + +/****************************************************************************** + * + *****************************************************************************/ + +static DiaObject * +sozi_frame_copy(SoziFrame *sozi_frame) +{ + SoziFrame *new_sozi_frame; + + new_sozi_frame = g_new0(SoziFrame, 1); + + sozi_frame_init(new_sozi_frame, &sozi_frame->center); + + new_sozi_frame->width = sozi_frame->width; + new_sozi_frame->height = sozi_frame->height; + new_sozi_frame->angle = sozi_frame->angle; + + new_sozi_frame->hide = sozi_frame->hide; + new_sozi_frame->clip = sozi_frame->clip; + new_sozi_frame->timeout = sozi_frame->timeout; + + sozi_frame_update_data(new_sozi_frame); + + return &new_sozi_frame->object; +} + +/****************************************************************************** + * + *****************************************************************************/ + +static ObjectChange* +sozi_frame_move(SoziFrame *sozi_frame, Point *to) +{ + sozi_frame->center = *to; + + sozi_frame_update_data(sozi_frame); + + return NULL; +} + +/****************************************************************************** + * + *****************************************************************************/ + +static ObjectChange* +sozi_frame_move_handle(SoziFrame *sozi_frame, Handle *handle, + Point *to, ConnectionPoint *cp, + HandleMoveReason reason, ModifierKeys modifiers) +{ + if(reason == HANDLE_MOVE_USER) { + DiaObject * dia_object = &sozi_frame->object; + Point p2; + + int i; + for(i = 0; i < 4; i++) { + if(dia_object->handles[i] == handle) { + break; + } + } + assert(i < 4); + + p2 = *to; + point_sub(&p2, &sozi_frame->center); + + if(modifiers & MODIFIER_SHIFT) { + Point p1; + p1 = handle->pos; + point_sub(&p1, &sozi_frame->center); + + sozi_frame->angle += atan2(p2.x * p1.y - p2.y * p1.x, p2.x * p1.x + p2.y * p1.y); + } + else + { + /* the y axis is downward */ + sozi_frame->width = 2 * fabs(p2.x * sozi_frame->cos_angle - p2.y * sozi_frame->sin_angle); + sozi_frame->height = 2 * fabs(p2.x * sozi_frame->sin_angle + p2.y * sozi_frame->cos_angle); + } + + sozi_frame_update_data(sozi_frame); + } + + return NULL; +} + +/****************************************************************************** + * + *****************************************************************************/ + +static PropDescription sozi_frame_props[] = +{ + PROP_STD_NOTEBOOK_BEGIN, + + PROP_NOTEBOOK_PAGE("geometry",0,N_("Geometry")), + { "x" , PROP_TYPE_REAL , PROP_FLAG_VISIBLE, N_("Position x") , NULL, NULL }, + { "y" , PROP_TYPE_REAL , PROP_FLAG_VISIBLE, N_("Position y") , NULL, NULL }, + { "width" , PROP_TYPE_REAL , PROP_FLAG_VISIBLE, N_("Width") , NULL, NULL }, + { "height", PROP_TYPE_REAL , PROP_FLAG_VISIBLE, N_("Height") , NULL, NULL }, + { "angle" , PROP_TYPE_REAL , PROP_FLAG_VISIBLE, N_("Angle (rad)") , NULL, NULL }, + + PROP_NOTEBOOK_PAGE("sozi",0,N_("Sozi")), + { "frame sequence", PROP_TYPE_INT , PROP_FLAG_VISIBLE, N_("Frame sequence") , NULL, NULL }, + { "frame title" , PROP_TYPE_TEXT , PROP_FLAG_VISIBLE, N_("Frame title") , NULL, NULL }, + { "frame hide" , PROP_TYPE_BOOL , PROP_FLAG_VISIBLE, N_("Frame hide") , NULL, NULL }, + { "frame clip" , PROP_TYPE_BOOL , PROP_FLAG_VISIBLE, N_("Frame clip") , NULL, NULL }, + { "frame timeout" , PROP_TYPE_INT , PROP_FLAG_VISIBLE, N_("Frame timeout (ms)") , NULL, NULL }, + PROP_STD_NOTEBOOK_END, + + PROP_DESC_END +}; + +static PropOffset sozi_frame_offsets[] = +{ + PROP_OFFSET_STD_NOTEBOOK_BEGIN, + + PROP_OFFSET_NOTEBOOK_PAGE("geometry"), + { "x" , PROP_TYPE_REAL , offsetof(SoziFrame, center.x) }, + { "y" , PROP_TYPE_REAL , offsetof(SoziFrame, center.y) }, + { "width" , PROP_TYPE_REAL , offsetof(SoziFrame, width) }, + { "height", PROP_TYPE_REAL , offsetof(SoziFrame, height) }, + { "angle" , PROP_TYPE_REAL , offsetof(SoziFrame, angle) }, + + PROP_OFFSET_NOTEBOOK_PAGE("sozi"), + { "frame sequence" , PROP_TYPE_INT , offsetof(SoziFrame, sequence) }, + { "frame title" , PROP_TYPE_TEXT , offsetof(SoziFrame, title) }, + { "frame hide" , PROP_TYPE_BOOL , offsetof(SoziFrame, hide) }, + { "frame clip" , PROP_TYPE_BOOL , offsetof(SoziFrame, clip) }, + { "frame timeout" , PROP_TYPE_INT , offsetof(SoziFrame, timeout) }, + + PROP_OFFSET_STD_NOTEBOOK_END, + + { NULL, 0, 0 } +}; + +static PropDescription * +sozi_frame_describe_props(SoziFrame *sozi_frame) +{ + if (sozi_frame_props[0].quark == 0) + prop_desc_list_calculate_quarks(sozi_frame_props); + return sozi_frame_props; +} + +static void +sozi_frame_get_props(SoziFrame *sozi_frame, GPtrArray *props) +{ + object_get_props_from_offsets(&sozi_frame->object, sozi_frame_offsets, props); +} + +static void +sozi_frame_set_props(SoziFrame *sozi_frame, GPtrArray *props) +{ + object_set_props_from_offsets(&sozi_frame->object, sozi_frame_offsets, props); + sozi_frame_update_data(sozi_frame); +} + + + + + diff --git a/objects/Misc/sozi.h b/objects/Misc/sozi.h new file mode 100644 index 0000000..3132742 --- /dev/null +++ b/objects/Misc/sozi.h @@ -0,0 +1,222 @@ +#ifndef __sozi_h__ +#define __sozi_h__ + +static const char sozi_version[] = +"11.09-12231119"; + +static const char sozi_js[] = +"var sozi=sozi||{};(function(){var a=sozi.events=sozi.events||{},b={};a.listen=fu" +"nction(d,e){var c=b[d];if(!c){c=b[d]=[]}c.push(e)};a.fire=function(g){var d=b[g]" +",c,f,e=Array.prototype.slice.call(arguments,1);if(d){c=d.length;for(f=0;f=k.innerHeight*3/2){A-=k.innerHeight/2}else{if(A+j>k.innerHeight+2*d){A=" +"k.innerHeight-j-4*d}}c.setAttribute(\"transform\",\"translate(0,\"+A+\")\");B.stopProp" +"agation()}function s(A){var C=sozi.animation.profiles[g](A),B=1-C;z=y*C+b*B;m.se" +"tAttribute(\"transform\",\"translate(\"+z+\",0)\")}function x(){}function o(){var G=r." +"createElementNS(a,\"rect\"),A=r.createElementNS(a,\"path\"),E=r.createElementNS(a,\"p" +"ath\"),H=0,F,C=sozi.document.frames.length,B=sozi.location.getFrameIndex(),D,I;q=" +"r.documentElement;m=r.createElementNS(a,\"g\");m.setAttribute(\"id\",\"sozi-toc\");q.a" +"ppendChild(m);c=r.createElementNS(a,\"g\");m.appendChild(c);G.setAttribute(\"id\",\"s" +"ozi-toc-background\");G.setAttribute(\"x\",d);G.setAttribute(\"y\",d);G.setAttribute(" +"\"rx\",d);G.setAttribute(\"ry\",d);G.addEventListener(\"click\",l,false);G.addEventLis" +"tener(\"mousedown\",l,false);G.addEventListener(\"mouseout\",p,false);c.appendChild(" +"G);for(D=0;DH){H=F}I." +"setAttribute(\"x\",2*d);I.setAttribute(\"y\",j+d);I.addEventListener(\"click\",h(D),fa" +"lse);I.addEventListener(\"mousedown\",l,false)}A.setAttribute(\"class\",\"sozi-toc-ar" +"row\");A.setAttribute(\"d\",\"M\"+(H+3*d)+\",\"+(5*d)+\" l\"+(4*d)+\",0 l-\"+(2*d)+\",-\"+(3*" +"d)+\" z\");A.addEventListener(\"click\",t,false);A.addEventListener(\"mousedown\",l,fa" +"lse);m.appendChild(A);E.setAttribute(\"class\",\"sozi-toc-arrow\");E.setAttribute(\"d" +"\",\"M\"+(H+3*d)+\",\"+(7*d)+\" l\"+(4*d)+\",0 l-\"+(2*d)+\",\"+(3*d)+\" z\");E.addEventListe" +"ner(\"click\",e,false);E.addEventListener(\"mousedown\",l,false);m.appendChild(E);G." +"setAttribute(\"width\",H+7*d);G.setAttribute(\"height\",j+2*d);i=-H-9*d;u=0;z=y=i;m." +"setAttribute(\"transform\",\"translate(\"+i+\",0)\");v=new sozi.animation.Animator(s,x" +")}function n(A){var D=r.getElementsByClassName(\"sozi-toc-current\"),C=c.getElemen" +"tsByTagName(\"text\"),B;for(B=0;B0?s:1/s,z,B)}fu" +"nction w(y){t.stop();u.rotate(y>0?x:-x)}function r(){if(sozi.framelist.isVisible" +"()){sozi.framelist.hide();t.restart()}else{t.stop();sozi.framelist.show()}}funct" +"ion i(y){if(y.button===p){c=true;l=false;g=y.clientX;e=y.clientY}else{if(y.butto" +"n===v){r()}}y.stopPropagation()}function m(y){if(c){t.stop();l=true;sozi.events." +"fire(\"cleanup\");u.drag(y.clientX-g,y.clientY-e);g=y.clientX;e=y.clientY}y.stopPr" +"opagation()}function f(y){if(y.button===p){c=false}y.stopPropagation()}function " +"q(y){t.moveToPrevious();y.stopPropagation();y.preventDefault()}function h(y){if(" +"!l&&y.button!==v){t.moveToNext()}y.stopPropagation()}function k(y){var z=0;if(!y" +"){y=j.event}if(y.wheelDelta){z=y.wheelDelta;if(j.opera){z=-z}}else{if(y.detail){" +"z=-y.detail}}if(z!==0){if(y.shiftKey){w(z)}else{a(z,y.clientX,y.clientY)}}y.stop" +"Propagation();y.preventDefault()}function n(y){switch(y.charCode){case 43:a(1,j." +"innerWidth/2,j.innerHeight/2);break;case 45:a(-1,j.innerWidth/2,j.innerHeight/2)" +";break;case 61:t.moveToCurrent();break;case 70:case 102:t.showAll();break;case 8" +"4:case 116:r();break;case 82:w(-1);break;case 114:w(1);break}y.stopPropagation()" +"}function d(y){switch(y.keyCode){case 36:t.moveToFirst();break;case 35:t.moveToL" +"ast();break;case 38:t.jumpToPrevious();break;case 33:case 37:t.moveToPrevious();" +"break;case 40:t.jumpToNext();break;case 34:case 39:case 13:case 32:t.moveToNext(" +");break}y.stopPropagation()}function b(){var y=o.documentElement;y.addEventListe" +"ner(\"click\",h,false);y.addEventListener(\"mousedown\",i,false);y.addEventListener(" +"\"mouseup\",f,false);y.addEventListener(\"mousemove\",m,false);y.addEventListener(\"k" +"eypress\",n,false);y.addEventListener(\"keydown\",d,false);y.addEventListener(\"cont" +"extmenu\",q,false);y.addEventListener(\"DOMMouseScroll\",k,false);j.onmousewheel=k}" +"j.addEventListener(\"load\",b,false)}());var sozi=sozi||{};(function(){var e=sozi." +"animation=sozi.animation||{},h=this,j=40,d=[],b,i=h.mozRequestAnimationFrame||h." +"webkitRequestAnimationFrame||h.msRequestAnimationFrame||h.oRequestAnimationFrame" +";function c(){if(i){i(f)}else{b=h.setInterval(function(){f(Date.now())},j)}}func" +"tion f(l){var k;if(d.length>0){if(i){i(f)}for(k=0;k=this.durationMs){this.stop();this.onStep(1,this.data);this.onDone()}else{thi" +"s.onStep(k/this.durationMs,this.data)}};e.profiles={linear:function(k){return k}" +",accelerate:function(k){return Math.pow(k,3)},\"strong-accelerate\":function(k){re" +"turn Math.pow(k,5)},decelerate:function(k){return 1-Math.pow(1-k,3)},\"strong-dec" +"elerate\":function(k){return 1-Math.pow(1-k,5)},\"accelerate-decelerate\":function(" +"k){var l=k<=0.5?k:1-k,m=Math.pow(2*l,3)/2;return k<=0.5?m:1-m},\"strong-accelerat" +"e-decelerate\":function(k){var l=k<=0.5?k:1-k,m=Math.pow(2*l,5)/2;return k<=0.5?m" +":1-m},\"decelerate-accelerate\":function(k){var l=k<=0.5?k:1-k,m=(1-Math.pow(1-2*l" +",2))/2;return k<=0.5?m:1-m},\"strong-decelerate-accelerate\":function(k){var l=k<=" +"0.5?k:1-k,m=(1-Math.pow(1-2*l,3))/2;return k<=0.5?m:1-m}}}());var sozi=sozi||{};" +"(function(){var d=sozi.player=sozi.player||{},j=sozi.display=sozi.display||{},h=" +"this,c,k,e=500,q=-10,l=\"linear\",g=0,n=0,o=false,p=false;function f(t,w){var v=1-" +"t,u=w.profile(t),s=1-u,r,x;for(r in w.initialState){if(w.initialState.hasOwnProp" +"erty(r)){if(typeof w.initialState[r]===\"number\"&&typeof w.finalState[r]===\"numbe" +"r\"){j.geometry[r]=w.finalState[r]*u+w.initialState[r]*s}}}if(w.zoomWidth&&w.zoom" +"Width.k!==0){x=t-w.zoomWidth.ts;j.geometry.width=w.zoomWidth.k*x*x+w.zoomWidth.s" +"s}if(w.zoomHeight&&w.zoomHeight.k!==0){x=t-w.zoomHeight.ts;j.geometry.height=w.z" +"oomHeight.k*x*x+w.zoomHeight.ss}j.clip=w.finalState.clip;j.update()}function i()" +"{var r;if(sozi.document.frames[n].timeoutEnable){p=true;r=(n+1)%sozi.document.fr" +"ames.length;k=h.setTimeout(function(){d.moveToFrame(r)},sozi.document.frames[n]." +"timeoutMs)}}function m(){g=n;if(o){i()}}d.startFromIndex=function(r){o=true;p=fa" +"lse;g=r;n=r;j.showFrame(sozi.document.frames[r]);i()};d.restart=function(){d.sta" +"rtFromIndex(n)};d.stop=function(){c.stop();if(p){h.clearTimeout(k);p=false}o=fal" +"se;g=n};function b(r,B,z){var C={ss:((r<0)?Math.max(B,z):Math.min(B,z))*(100-r)/" +"100,ts:0.5,k:0},x,w,t,s,A,y;if(r!==0){x=B-z;w=B-C.ss;t=z-C.ss;if(x!==0){s=Math.s" +"qrt(w*t);A=(w-s)/x;y=(w+s)/x;C.ts=(A>0&&A<=1)?A:y}C.k=w/C.ts/C.ts}return C}d.jum" +"pToFrame=function(r){d.stop();sozi.events.fire(\"cleanup\");g=r;n=r;j.showFrame(so" +"zi.document.frames[r]);sozi.events.fire(\"framechange\",r)};d.previewFrame=functio" +"n(s){var u=sozi.document.frames[s].geometry,r,t;if(q!==0){r=b(q,j.geometry.width" +",u.width);t=b(q,j.geometry.height,u.height)}n=s;c.start(e,{initialState:j.getCur" +"rentGeometry(),finalState:u,profile:sozi.animation.profiles[l],zoomWidth:r,zoomH" +"eight:t});sozi.events.fire(\"framechange\",s)};d.moveToFrame=function(t){var s=e,w" +"=q,u=sozi.animation.profiles[l],r,v;if(p){h.clearTimeout(k);p=false}if(t===(n+1)" +"%sozi.document.frames.length){s=sozi.document.frames[t].transitionDurationMs;w=s" +"ozi.document.frames[t].transitionZoomPercent;u=sozi.document.frames[t].transitio" +"nProfile}sozi.events.fire(\"cleanup\");if(w!==0){r=b(w,j.geometry.width,sozi.docum" +"ent.frames[t].geometry.width);v=b(w,j.geometry.height,sozi.document.frames[t].ge" +"ometry.height)}o=true;n=t;c.start(s,{initialState:j.getCurrentGeometry(),finalSt" +"ate:sozi.document.frames[n].geometry,profile:u,zoomWidth:r,zoomHeight:v});sozi.e" +"vents.fire(\"framechange\",t)};d.moveToFirst=function(){d.moveToFrame(0)};d.jumpTo" +"Previous=function(){var r=n;if(!c.started||g<=n){r-=1}if(r>=0){d.jumpToFrame(r)}" +"};d.moveToPrevious=function(){var r=n,s;for(r-=1;r>=0;r-=1){s=sozi.document.fram" +"es[r];if(!s.timeoutEnable||s.timeoutMs!==0){d.moveToFrame(r);break}}};d.jumpToNe" +"xt=function(){var r=n;if(!c.started||g>=n){r+=1}if(r=sozi.document.frames.length){return sozi.document.frames." +"length-1}else{return g}}};function f(){var g=a.getFrameIndex();if(!c){sozi.playe" +"r.moveToFrame(g)}c=false}function d(g){c=true;e.location.hash=\"#\"+(g+1)}function" +" b(){sozi.events.listen(\"framechange\",d)}e.addEventListener(\"hashchange\",f,false" +");e.addEventListener(\"load\",b,false)}());"; + +static const char sozi_css[] = +"#sozi-toc text{fill:#eff;font-family:Verdana,sans-serif;font-size:12pt}#sozi-toc" +" text:hover{fill:#0cf;cursor:pointer}#sozi-toc text.sozi-toc-current{fill:#fa4}#" +"sozi-toc-background{stroke:#222;stroke-opacity:.1;stroke-width:10;fill:#222;fill" +"-opacity:.9}.sozi-toc-arrow{fill:#eff;fill-opacity:.75;stroke:none}.sozi-toc-arr" +"ow:hover{fill:#0cf}"; + +static const char sozi_extras_addvideo_js[] = +"this.addEventListener(\"load\",function(){var k=\"http://www.w3.org/2000/svg\",l=\"ht" +"tp://sozi.baierouge.fr\",q=\"http://www.w3.org/1999/xhtml\",m=this,o=m.document,c=o" +".getElementsByTagNameNS(l,\"video\"),d,g,e,p,a,h,f,b;function n(i){i.stopPropagati" +"on()}function r(i,j){sozi.events.listen(\"framechange\",function(s){if(s+1===j){i." +"play()}})}d=[];for(g=0;g <_description>New-style group object, for testing + + <_description>Sozi frame, for zooming ui + -- 1.7.4.4