作図ソフト dia の改良版
Revisión | 4f108f6854cde9e7cb52cca733228f50044ebb1a (tree) |
---|---|
Tiempo | 2015-01-17 07:30:48 |
Autor | Paul Chavent <paul.chavent@fnac...> |
Commiter | Hans Breuer |
Fix Sozi presentation objects.
Allow undo of move_handle.
Fix coding style.
Mute messages.
Create function now return handle for resize.
Signed-off-by: Hans Breuer <hans@breuer.org>
@@ -189,18 +189,18 @@ sozi_frames_reorder(gpointer data, gpointer user_data) | ||
189 | 189 | { |
190 | 190 | /* see object.h for the description of the object structure */ |
191 | 191 | DiaObject *dia_object = (DiaObject *)data; |
192 | - if(strcmp(dia_object->type->name, sozi_frame_type.name) == 0) { | |
192 | + if (strcmp(dia_object->type->name, sozi_frame_type.name) == 0) { | |
193 | 193 | SoziFrame *sozi_frame = (SoziFrame *)dia_object; |
194 | 194 | struct sequence_pair * seq_pair = (struct sequence_pair *)user_data; |
195 | 195 | int this_seq = sozi_frame->sequence; |
196 | - if((seq_pair->new <= this_seq) && (this_seq < seq_pair->old)) { | |
196 | + if ((seq_pair->new <= this_seq) && (this_seq < seq_pair->old)) { | |
197 | 197 | /* fprintf(stdout, "old value %d ++ new value %d\n", sozi_frame->sequence, sozi_frame->sequence + 1); */ |
198 | 198 | sozi_frame->sequence++; |
199 | 199 | sozi_frame->old_sequence = sozi_frame->sequence; |
200 | 200 | /* FIXME : not sure it's the good way to redraw an object */ |
201 | 201 | /* sozi_frame_draw(sozi_frame); */ |
202 | 202 | } |
203 | - else if((seq_pair->old < this_seq) && (this_seq <= seq_pair->new)) { | |
203 | + else if ((seq_pair->old < this_seq) && (this_seq <= seq_pair->new)) { | |
204 | 204 | /* fprintf(stdout, "old value %d -- new value %d\n", sozi_frame->sequence, sozi_frame->sequence - 1); */ |
205 | 205 | sozi_frame->sequence--; |
206 | 206 | sozi_frame->old_sequence = sozi_frame->sequence; |
@@ -215,11 +215,11 @@ sozi_frames_count(gpointer data, gpointer user_data) | ||
215 | 215 | { |
216 | 216 | /* see object.h for the description of the object structure */ |
217 | 217 | DiaObject *dia_object = (DiaObject *)data; |
218 | - if(strcmp(dia_object->type->name, sozi_frame_type.name) == 0) { | |
218 | + if (strcmp(dia_object->type->name, sozi_frame_type.name) == 0) { | |
219 | 219 | SoziFrame *sozi_frame = (SoziFrame *)dia_object; |
220 | 220 | /* only object with old_sequence different of zero should be |
221 | 221 | taken into account */ |
222 | - if(sozi_frame->sequence) { | |
222 | + if (sozi_frame->sequence) { | |
223 | 223 | int * counter = (int *)user_data; |
224 | 224 | *counter = *counter + 1; |
225 | 225 | } |
@@ -236,7 +236,7 @@ sozi_frame_update(SoziFrame *sozi_frame) | ||
236 | 236 | |
237 | 237 | /* probably editing default configuration or loading object |
238 | 238 | -> do not care */ |
239 | - if(!sozi_frame->sozi_object.dia_object.parent_layer) { | |
239 | + if (!sozi_frame->sozi_object.dia_object.parent_layer) { | |
240 | 240 | return; |
241 | 241 | } |
242 | 242 |
@@ -246,7 +246,7 @@ sozi_frame_update(SoziFrame *sozi_frame) | ||
246 | 246 | sequence managment |
247 | 247 | We use exemples of data_foreach_object of diagramdata.h |
248 | 248 | */ |
249 | - if(!sozi_frame->sequence) { | |
249 | + if (!sozi_frame->sequence) { | |
250 | 250 | /* this condition is true iif the object have just been created */ |
251 | 251 | int frames_count = 0; |
252 | 252 | /* trig COUNTING of all frames */ |
@@ -255,7 +255,7 @@ sozi_frame_update(SoziFrame *sozi_frame) | ||
255 | 255 | /* fprintf(stdout, "seq must be initialized after object creation (%d frames)\n", frames_count); */ |
256 | 256 | sozi_frame->sequence = frames_count + 1; |
257 | 257 | } |
258 | - else if(sozi_frame->old_sequence && | |
258 | + else if (sozi_frame->old_sequence && | |
259 | 259 | (sozi_frame->old_sequence != sozi_frame->sequence)) { |
260 | 260 | /* this condition is true iif the object's sequence number |
261 | 261 | have just been changed (in sozi_frame_set_props for instance) */ |
@@ -277,7 +277,7 @@ sozi_frame_update(SoziFrame *sozi_frame) | ||
277 | 277 | |
278 | 278 | /* update legend */ |
279 | 279 | nb_char = g_snprintf(legend, sizeof(legend), "#%d : %s", sozi_frame->sequence, sozi_frame->title); |
280 | - if(sizeof(legend) < nb_char) | |
280 | + if (sizeof(legend) < nb_char) | |
281 | 281 | { |
282 | 282 | legend[sizeof(legend) - 1] = 0; |
283 | 283 | legend[sizeof(legend) - 2] = '.'; |
@@ -299,7 +299,7 @@ sozi_frame_init(SoziFrame *sozi_frame) | ||
299 | 299 | sozi_frame->old_sequence = 0; |
300 | 300 | sozi_frame->sequence = 0; |
301 | 301 | |
302 | - if(sozi_frame->title == NULL) { | |
302 | + if (sozi_frame->title == NULL) { | |
303 | 303 | sozi_frame->title = g_strdup("frame title"); |
304 | 304 | } |
305 | 305 |
@@ -315,7 +315,7 @@ sozi_frame_init(SoziFrame *sozi_frame) | ||
315 | 315 | static void |
316 | 316 | sozi_frame_kill(SoziFrame *sozi_frame) |
317 | 317 | { |
318 | - if(sozi_frame->title != NULL) { | |
318 | + if (sozi_frame->title != NULL) { | |
319 | 319 | g_free(sozi_frame->title); |
320 | 320 | } |
321 | 321 | } |
@@ -350,8 +350,10 @@ sozi_frame_create(Point *startpoint, | ||
350 | 350 | sozi_object_update(&sozi_frame->sozi_object); |
351 | 351 | |
352 | 352 | /* handle are not used */ |
353 | - *handle1 = NULL; | |
354 | - *handle2 = NULL; | |
353 | + *handle1 = NULL; /* first handle to connect: not here */ | |
354 | + /* we intend to use the lower "SE" handle */ | |
355 | + g_assert (sozi_frame->sozi_object.dia_object.handles[2]->id == HANDLE_RESIZE_SE); | |
356 | + *handle2 = sozi_frame->sozi_object.dia_object.handles[2]; /* second handle to resize */ | |
355 | 357 | |
356 | 358 | return &sozi_frame->sozi_object.dia_object; |
357 | 359 | } |
@@ -483,7 +485,7 @@ sozi_frame_draw(SoziFrame *sozi_frame, DiaRenderer *renderer) | ||
483 | 485 | if (DIA_IS_SVG_RENDERER(renderer)) { |
484 | 486 | sozi_frame_draw_svg(sozi_frame, DIA_SVG_RENDERER (renderer)); |
485 | 487 | } |
486 | - else if(DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer) || | |
488 | + else if (DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer) || | |
487 | 489 | !sozi_frame->hide) { |
488 | 490 | DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer); |
489 | 491 |
@@ -494,7 +496,7 @@ sozi_frame_draw(SoziFrame *sozi_frame, DiaRenderer *renderer) | ||
494 | 496 | |
495 | 497 | renderer_ops->draw_polygon(renderer, sozi_frame->sozi_object.corners, 4, NULL, &color_black); |
496 | 498 | |
497 | - if(sozi_frame->sozi_object.legend.disp == TRUE) { | |
499 | + if (sozi_frame->sozi_object.legend.disp == TRUE) { | |
498 | 500 | text_draw(sozi_frame->sozi_object.legend.text, renderer); |
499 | 501 | } |
500 | 502 | } |
@@ -649,9 +651,9 @@ sozi_frame_get_properties(SoziFrame *sozi_frame, gboolean is_default) | ||
649 | 651 | for (i = 0; i < dialog->prop_widgets->len; ++i) { |
650 | 652 | PropWidgetAssoc *pwa = &g_array_index(dialog->prop_widgets, |
651 | 653 | PropWidgetAssoc, i); |
652 | - if(pwa) { | |
654 | + if (pwa) { | |
653 | 655 | if (strcmp(pwa->prop->descr->name, "frame_sequence") == 0) { |
654 | - if(GTK_IS_SPIN_BUTTON(pwa->widget)) { | |
656 | + if (GTK_IS_SPIN_BUTTON(pwa->widget)) { | |
655 | 657 | int count = 0; |
656 | 658 | data_foreach_object(layer_get_parent_diagram(dia_object->parent_layer), sozi_frames_count, &count); |
657 | 659 |
@@ -217,9 +217,9 @@ sozi_media_create(Point *startpoint, | ||
217 | 217 | /* update sozi object geometry */ |
218 | 218 | sozi_object_update(&sozi_media->sozi_object); |
219 | 219 | |
220 | - /* handle are not used */ | |
221 | - *handle1 = NULL; | |
222 | - *handle2 = NULL; | |
220 | + *handle1 = NULL; /* not connectable ... */ | |
221 | + g_assert (sozi_media->sozi_object.dia_object.handles[2]->id == HANDLE_RESIZE_SE); | |
222 | + *handle2 = sozi_media->sozi_object.dia_object.handles[2]; /* ... but resizable */ | |
223 | 223 | |
224 | 224 | return &sozi_media->sozi_object.dia_object; |
225 | 225 | } |
@@ -29,6 +29,7 @@ | ||
29 | 29 | |
30 | 30 | /* dia stuff */ |
31 | 31 | #include "diarenderer.h" |
32 | +#include "message.h" | |
32 | 33 | |
33 | 34 | /* sozi stuff */ |
34 | 35 | #include "sozi-player.h" |
@@ -54,34 +55,34 @@ static const Handle default_handles[4] = | ||
54 | 55 | * @param[in] doc the svg document |
55 | 56 | * @param[in] sozi_elem the sozi player identification string that will |
56 | 57 | * probably be "//script[@id='sozi-script']" |
57 | - * @return 1 if the sozi player has been found, 0 otherwise. | |
58 | + * @return 1 if the sozi player has been found, 0 if not, -1 if errors | |
59 | + * happened. | |
58 | 60 | */ |
59 | 61 | static int |
60 | 62 | sozi_player_is_present(xmlDocPtr doc, const xmlChar *sozi_elem) |
61 | 63 | { |
62 | 64 | xmlXPathContextPtr context; |
63 | 65 | xmlXPathObjectPtr result; |
66 | + int is_present; | |
64 | 67 | |
65 | 68 | context = xmlXPathNewContext(doc); |
66 | - if(context == NULL) { | |
67 | - fprintf(stderr, "sozi-object : error in xmlXPathNewContext\n"); | |
68 | - return 0; | |
69 | + if (context == NULL) { | |
70 | + g_warning("sozi-object : error in xmlXPathNewContext\n"); | |
71 | + return -1; | |
69 | 72 | } |
70 | 73 | |
71 | 74 | result = xmlXPathEvalExpression(sozi_elem, context); |
72 | 75 | xmlXPathFreeContext(context); |
73 | - if(result == NULL) { | |
74 | - fprintf(stderr, "sozi-object : error in xmlXPathEvalExpression\n"); | |
75 | - return 0; | |
76 | + if (result == NULL) { | |
77 | + g_warning("sozi-object : error in xmlXPathEvalExpression\n"); | |
78 | + return -1; | |
76 | 79 | } |
77 | 80 | |
78 | - if(xmlXPathNodeSetIsEmpty(result->nodesetval)) { | |
79 | - xmlXPathFreeObject(result); | |
80 | - return 0; | |
81 | - } | |
81 | + is_present = xmlXPathNodeSetIsEmpty(result->nodesetval)?0:1; | |
82 | 82 | |
83 | 83 | xmlXPathFreeObject(result); |
84 | - return 1; | |
84 | + | |
85 | + return is_present; | |
85 | 86 | } |
86 | 87 | |
87 | 88 | /** |
@@ -96,7 +97,6 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr | ||
96 | 97 | { |
97 | 98 | #if defined(SOZI_PATH) |
98 | 99 | /* try to get sozi engine from SOZI_PATH */ |
99 | - int i; | |
100 | 100 | struct |
101 | 101 | { |
102 | 102 | const gchar * filename; |
@@ -108,16 +108,18 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr | ||
108 | 108 | { SOZI_PATH"/extras/sozi_extras_media.js" , sozi_extras_media_js_ptr }, |
109 | 109 | { SOZI_PATH"/sozi.css" , sozi_css_ptr } |
110 | 110 | }; |
111 | - | |
112 | - for (i = 0; i < 3; i++) { | |
111 | + static const unsigned external_sozi_cnt = sizeof(external_sozi)/sizeof(external_sozi[0]); | |
112 | + unsigned i; | |
113 | + | |
114 | + for (i = 0; i < external_sozi_cnt; i++) { | |
113 | 115 | GError * err = 0; |
114 | 116 | if (!g_file_get_contents(external_sozi[i].filename, |
115 | 117 | external_sozi[i].data, |
116 | 118 | NULL, |
117 | 119 | &err)) { |
118 | - g_warning("sozi-object : unable to read file \"%s\" : %s", | |
119 | - external_sozi[i].filename, | |
120 | - err->message); | |
120 | + message_error("sozi-object : unable to read file \"%s\" : %s", | |
121 | + external_sozi[i].filename, | |
122 | + err->message); | |
121 | 123 | g_error_free (err); |
122 | 124 | while(i--) { |
123 | 125 | g_free (*external_sozi[i].data); |
@@ -126,13 +128,12 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr | ||
126 | 128 | } |
127 | 129 | } |
128 | 130 | |
129 | - if(i == 3) { | |
131 | + if (i == external_sozi_cnt) { | |
130 | 132 | /* that's ok, don't need to go further */ |
131 | 133 | return; |
132 | 134 | } |
133 | 135 | |
134 | -#else /* defined(SOZI_PATH) */ | |
135 | - g_warning("sozi-object : use builtin player"); | |
136 | + dia_log_message("sozi-object : use builtin player"); | |
136 | 137 | #endif /* defined(SOZI_PATH) */ |
137 | 138 | |
138 | 139 | /* if SOZI_PATH isn't defined, fallback to the player that comes with dia sources */ |
@@ -142,7 +143,7 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr | ||
142 | 143 | *sozi_css_ptr = g_strdup((const gchar *)sozi_min_css); |
143 | 144 | |
144 | 145 | #if defined(SOZI_PATH) |
145 | - g_warning("sozi-object : use sozi player version '%s'", *sozi_version_ptr); | |
146 | + dia_log_message("sozi-object : use sozi player version '%s'", *sozi_version_ptr); | |
146 | 147 | #endif /* defined(SOZI_PATH) */ |
147 | 148 | } |
148 | 149 |
@@ -163,23 +164,23 @@ sozi_object_init(SoziObject *sozi_object, Point *center) | ||
163 | 164 | /* dia_object->bounding_box will be set in sozi_object_update */ |
164 | 165 | |
165 | 166 | dia_object->num_handles = 4; |
166 | - if(dia_object->handles == NULL) { | |
167 | + if (dia_object->handles == NULL) { | |
167 | 168 | dia_object->handles = g_new0(Handle *, 4); |
168 | 169 | } |
169 | 170 | |
170 | 171 | for (i = 0; i < 4; i++) { |
171 | - if(dia_object->handles[i] == NULL) { | |
172 | + if (dia_object->handles[i] == NULL) { | |
172 | 173 | dia_object->handles[i] = g_new0(Handle, 1); |
173 | 174 | } |
174 | 175 | *dia_object->handles[i] = default_handles[i]; |
175 | 176 | } |
176 | 177 | |
177 | 178 | dia_object->num_connections = 1; |
178 | - if(dia_object->connections == NULL) { | |
179 | + if (dia_object->connections == NULL) { | |
179 | 180 | dia_object->connections = g_new0(ConnectionPoint *, 1); |
180 | 181 | } |
181 | 182 | |
182 | - if(dia_object->connections[0] == NULL) { | |
183 | + if (dia_object->connections[0] == NULL) { | |
183 | 184 | dia_object->connections[0] = g_new0(ConnectionPoint, 1); |
184 | 185 | } |
185 | 186 | dia_object->connections[0]->object = dia_object; |
@@ -215,13 +216,13 @@ sozi_object_kill(SoziObject *sozi_object) | ||
215 | 216 | object_unconnect_all(&sozi_object->dia_object); |
216 | 217 | |
217 | 218 | for (i = 0; i < 1; i++) { |
218 | - if(sozi_object->dia_object.connections[i] != NULL) { | |
219 | + if (sozi_object->dia_object.connections[i] != NULL) { | |
219 | 220 | g_free(sozi_object->dia_object.connections[i]); |
220 | 221 | } |
221 | 222 | } |
222 | 223 | |
223 | 224 | for (i = 0; i < 4; i++) { |
224 | - if(sozi_object->dia_object.handles[i] != NULL) { | |
225 | + if (sozi_object->dia_object.handles[i] != NULL) { | |
225 | 226 | g_free(sozi_object->dia_object.handles[i]); |
226 | 227 | } |
227 | 228 | } |
@@ -260,10 +261,10 @@ sozi_object_update(SoziObject *sozi_object) | ||
260 | 261 | dia_object->bounding_box.bottom = -G_MAXFLOAT; |
261 | 262 | |
262 | 263 | /* angle */ |
263 | - if(sozi_object->angle < -180) { | |
264 | + if (sozi_object->angle < -180) { | |
264 | 265 | sozi_object->angle += 360.0; |
265 | 266 | } |
266 | - if(180 < sozi_object->angle) { | |
267 | + if (180 < sozi_object->angle) { | |
267 | 268 | sozi_object->angle -= 360; |
268 | 269 | } |
269 | 270 | sozi_object->cos_angle = cos(sozi_object->angle * M_PI / 180.0); |
@@ -297,16 +298,16 @@ sozi_object_update(SoziObject *sozi_object) | ||
297 | 298 | |
298 | 299 | dia_object->handles[i]->pos = sozi_object->corners[i]; |
299 | 300 | |
300 | - if(sozi_object->corners[i].x < dia_object->bounding_box.left) { | |
301 | + if (sozi_object->corners[i].x < dia_object->bounding_box.left) { | |
301 | 302 | dia_object->bounding_box.left = sozi_object->corners[i].x - SOZI_OBJECT_LINE_WIDTH; |
302 | 303 | } |
303 | - if(dia_object->bounding_box.right < sozi_object->corners[i].x) { | |
304 | + if (dia_object->bounding_box.right < sozi_object->corners[i].x) { | |
304 | 305 | dia_object->bounding_box.right = sozi_object->corners[i].x + SOZI_OBJECT_LINE_WIDTH; |
305 | 306 | } |
306 | - if(sozi_object->corners[i].y < dia_object->bounding_box.top) { | |
307 | + if (sozi_object->corners[i].y < dia_object->bounding_box.top) { | |
307 | 308 | dia_object->bounding_box.top = sozi_object->corners[i].y - SOZI_OBJECT_LINE_WIDTH; |
308 | 309 | } |
309 | - if(dia_object->bounding_box.bottom < sozi_object->corners[i].y) { | |
310 | + if (dia_object->bounding_box.bottom < sozi_object->corners[i].y) { | |
310 | 311 | dia_object->bounding_box.bottom = sozi_object->corners[i].y + SOZI_OBJECT_LINE_WIDTH; |
311 | 312 | } |
312 | 313 | } |
@@ -331,6 +332,7 @@ void | ||
331 | 332 | sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, gchar * refid, xmlNs **p_sozi_name_space, xmlNodePtr * p_root, xmlNodePtr * p_rect) |
332 | 333 | { |
333 | 334 | static xmlNs * sozi_name_space = NULL; |
335 | + int player_is_present; | |
334 | 336 | xmlNodePtr root; |
335 | 337 | xmlNodePtr node; |
336 | 338 | /* for managing sozi player implantation */ |
@@ -353,7 +355,11 @@ sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, gcha | ||
353 | 355 | |
354 | 356 | /* check that the sozi namespace, scripts and style are present */ |
355 | 357 | |
356 | - if (!sozi_player_is_present(svg_renderer->doc, (const xmlChar*) "//script[@id='sozi-script']")) { | |
358 | + player_is_present = sozi_player_is_present(svg_renderer->doc, (const xmlChar*) "//script[@id='sozi-script']"); | |
359 | + if (player_is_present < 0) { | |
360 | + return; | |
361 | + } | |
362 | + else if (!player_is_present) { | |
357 | 363 | |
358 | 364 | sozi_player_get(&sozi_version, &sozi_js, &sozi_extras_media_js, &sozi_css); |
359 | 365 |
@@ -483,7 +489,7 @@ sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, gcha | ||
483 | 489 | } |
484 | 490 | |
485 | 491 | /****************************************************************************** |
486 | - * FUNCTIONS FOR MANAGING THE OBJECT GRABBING AND SCALLING | |
492 | + * FUNCTIONS FOR MANAGING THE OBJECT GRABBING, SCALLING AND ROTATION | |
487 | 493 | *****************************************************************************/ |
488 | 494 | |
489 | 495 | ObjectChange* |
@@ -491,6 +497,7 @@ sozi_object_move(SoziObject *sozi_object, Point *to) | ||
491 | 497 | { |
492 | 498 | sozi_object->center = *to; |
493 | 499 | |
500 | + /* refresh interactive rendering */ | |
494 | 501 | sozi_object_update(sozi_object); |
495 | 502 | |
496 | 503 | return NULL; |
@@ -498,125 +505,126 @@ sozi_object_move(SoziObject *sozi_object, Point *to) | ||
498 | 505 | |
499 | 506 | ObjectChange* |
500 | 507 | sozi_object_move_handle(SoziObject *sozi_object, Handle *handle, |
501 | - Point *to, ConnectionPoint *cp, | |
502 | - HandleMoveReason reason, ModifierKeys modifiers) | |
508 | + Point *to, ConnectionPoint *cp, | |
509 | + HandleMoveReason reason, ModifierKeys modifiers) | |
503 | 510 | { |
504 | - if(reason == HANDLE_MOVE_USER) { | |
505 | - | |
506 | - if(modifiers & MODIFIER_SHIFT) { | |
507 | - /* rotate object around its center */ | |
508 | - Point p1; | |
509 | - Point p2; | |
510 | - | |
511 | - /* p1 is the vector from the center to the old position of the handle */ | |
512 | - p1 = handle->pos; | |
513 | - point_sub(&p1, &sozi_object->center); | |
514 | - /* p2 is the vector from the center to the new position of the handle */ | |
515 | - p2 = *to; | |
516 | - point_sub(&p2, &sozi_object->center); | |
517 | - | |
518 | - /* | |
519 | - p1 . p2 = ||p1|| ||p2|| cos(delta) | |
520 | - p1 ^ p2 = ||p1|| ||p2|| sin(delta) | |
521 | - tan(delta) = (p1 ^ p2) / p1 . p2 | |
522 | - */ | |
523 | - sozi_object->angle += (180.0 / M_PI * atan2(p1.x * p2.y - p1.y * p2.x, p1.x * p2.x + p1.y * p2.y)); | |
511 | + /* fprintf(stdout, "reason %d modifiers %x\n", reason, modifiers); */ | |
512 | + | |
513 | + if (modifiers & MODIFIER_SHIFT) { | |
514 | + /* rotate object around its center */ | |
515 | + Point p1; | |
516 | + Point p2; | |
517 | + | |
518 | + /* p1 is the vector from the center to the old position of the handle */ | |
519 | + p1 = handle->pos; | |
520 | + point_sub(&p1, &sozi_object->center); | |
521 | + /* p2 is the vector from the center to the new position of the handle */ | |
522 | + p2 = *to; | |
523 | + point_sub(&p2, &sozi_object->center); | |
524 | + | |
525 | + /* | |
526 | + p1 . p2 = ||p1|| ||p2|| cos(delta) | |
527 | + p1 ^ p2 = ||p1|| ||p2|| sin(delta) | |
528 | + tan(delta) = (p1 ^ p2) / p1 . p2 | |
529 | + */ | |
530 | + sozi_object->angle += (180.0 / M_PI * atan2(p1.x * p2.y - p1.y * p2.x, p1.x * p2.x + p1.y * p2.y)); | |
531 | + } | |
532 | + else { | |
533 | + /* scale object */ | |
534 | + DiaObject * dia_object; | |
535 | + unsigned i; | |
536 | + | |
537 | + Point diagonal; | |
538 | + | |
539 | + real ratio; | |
540 | + real width; | |
541 | + real height; | |
542 | + | |
543 | + /* find the current handle */ | |
544 | + dia_object = &sozi_object->dia_object; | |
545 | + for (i = 0; i < 4; i++) { | |
546 | + if (dia_object->handles[i] == handle) { | |
547 | + break; | |
548 | + } | |
549 | + } | |
550 | + assert(i < 4); | |
551 | + | |
552 | + if (sozi_object->scale_from_center) { | |
553 | + /* scale object from its center */ | |
554 | + | |
555 | + /* diagonal is the vector from the center to the new handle pos */ | |
556 | + diagonal = *to; | |
557 | + point_sub(&diagonal, &sozi_object->center); | |
558 | + /* ratio is the old ratio */ | |
559 | + ratio = sozi_object->width / sozi_object->height; | |
560 | + /* dot product with the unit lenght vector that hold the width axe */ | |
561 | + width = 2 * fabs(diagonal.x * sozi_object->cos_angle + | |
562 | + diagonal.y * sozi_object->sin_angle); | |
563 | + /* cross product with the unit lenght vector that hold the width axe */ | |
564 | + height = 2 * fabs(diagonal.x * sozi_object->sin_angle - | |
565 | + diagonal.y * sozi_object->cos_angle); | |
566 | + /* compute the new size */ | |
567 | + if (sozi_object->aspect == ASPECT_FREE) { | |
568 | + sozi_object->width = width; | |
569 | + sozi_object->height = height; | |
570 | + } | |
571 | + else { | |
572 | + sozi_object->width = (((height * ratio) < width)?width:(height * ratio)); | |
573 | + sozi_object->height = (((width / ratio) < height)?height:(width / ratio)); | |
574 | + } | |
524 | 575 | } |
525 | 576 | else { |
526 | - /* scale object */ | |
527 | - DiaObject * dia_object; | |
528 | - unsigned i; | |
529 | - | |
530 | - Point diagonal; | |
531 | - | |
532 | - real ratio; | |
533 | - real width; | |
534 | - real height; | |
535 | - | |
536 | - /* find the current handle */ | |
537 | - dia_object = &sozi_object->dia_object; | |
538 | - for(i = 0; i < 4; i++) { | |
539 | - if(dia_object->handles[i] == handle) { | |
540 | - break; | |
541 | - } | |
577 | + /* scale object from oposite handle */ | |
578 | + | |
579 | + /* go to the oposite handle */ | |
580 | + i = (i + 2) % 4; | |
581 | + | |
582 | + /* diagonal is the vector from the oposite handle to the new handle pos */ | |
583 | + diagonal = *to; | |
584 | + point_sub(&diagonal, &dia_object->handles[i]->pos); | |
585 | + /* ratio is the old ratio */ | |
586 | + ratio = sozi_object->width / sozi_object->height; | |
587 | + /* dot product with the unit lenght vector that hold the width axe */ | |
588 | + width = fabs(diagonal.x * sozi_object->cos_angle + | |
589 | + diagonal.y * sozi_object->sin_angle); | |
590 | + /* cross product with the unit lenght vector that hold the width axe */ | |
591 | + height = fabs(diagonal.x * sozi_object->sin_angle - | |
592 | + diagonal.y * sozi_object->cos_angle); | |
593 | + /* compute the new size */ | |
594 | + if (sozi_object->aspect == ASPECT_FREE) { | |
595 | + sozi_object->width = width; | |
596 | + sozi_object->height = height; | |
597 | + } | |
598 | + else { | |
599 | + sozi_object->width = (((height * ratio) < width)?width:(height * ratio)); | |
600 | + sozi_object->height = (((width / ratio) < height)?height:(width / ratio)); | |
542 | 601 | } |
543 | - assert(i < 4); | |
544 | - | |
545 | - if(sozi_object->scale_from_center) { | |
546 | - /* scale object from its center */ | |
547 | - | |
548 | - /* diagonal is the vector from the center to the new handle pos */ | |
549 | - diagonal = *to; | |
550 | - point_sub(&diagonal, &sozi_object->center); | |
551 | - /* ratio is the old ratio */ | |
552 | - ratio = sozi_object->width / sozi_object->height; | |
553 | - /* dot product with the unit lenght vector that hold the width axe */ | |
554 | - width = 2 * fabs(diagonal.x * sozi_object->cos_angle + | |
555 | - diagonal.y * sozi_object->sin_angle); | |
556 | - /* cross product with the unit lenght vector that hold the width axe */ | |
557 | - height = 2 * fabs(diagonal.x * sozi_object->sin_angle - | |
558 | - diagonal.y * sozi_object->cos_angle); | |
559 | - /* compute the new size */ | |
560 | - if(sozi_object->aspect == ASPECT_FREE) { | |
561 | - sozi_object->width = width; | |
562 | - sozi_object->height = height; | |
563 | - } | |
564 | - else { | |
565 | - sozi_object->width = (((height * ratio) < width)?width:(height * ratio)); | |
566 | - sozi_object->height = (((width / ratio) < height)?height:(width / ratio)); | |
567 | - } | |
602 | + /* compute the new position */ | |
603 | + if (sozi_object->aspect == ASPECT_FREE) { | |
604 | + sozi_object->center.x = 0.5 * (dia_object->handles[i]->pos.x + to->x); | |
605 | + sozi_object->center.y = 0.5 * (dia_object->handles[i]->pos.y + to->y); | |
568 | 606 | } |
569 | 607 | else { |
570 | - /* scale object from oposite handle */ | |
571 | - | |
572 | - /* go to the oposite handle */ | |
573 | - i = (i + 2) % 4; | |
574 | - | |
575 | - /* diagonal is the vector from the oposite handle to the new handle pos */ | |
576 | - diagonal = *to; | |
577 | - point_sub(&diagonal, &dia_object->handles[i]->pos); | |
578 | - /* ratio is the old ratio */ | |
579 | - ratio = sozi_object->width / sozi_object->height; | |
580 | - /* dot product with the unit lenght vector that hold the width axe */ | |
581 | - width = fabs(diagonal.x * sozi_object->cos_angle + | |
582 | - diagonal.y * sozi_object->sin_angle); | |
583 | - /* cross product with the unit lenght vector that hold the width axe */ | |
584 | - height = fabs(diagonal.x * sozi_object->sin_angle - | |
585 | - diagonal.y * sozi_object->cos_angle); | |
586 | - /* compute the new size */ | |
587 | - if(sozi_object->aspect == ASPECT_FREE) { | |
588 | - sozi_object->width = width; | |
589 | - sozi_object->height = height; | |
590 | - } | |
591 | - else { | |
592 | - sozi_object->width = (((height * ratio) < width)?width:(height * ratio)); | |
593 | - sozi_object->height = (((width / ratio) < height)?height:(width / ratio)); | |
594 | - } | |
595 | - /* compute the new position */ | |
596 | - if(sozi_object->aspect == ASPECT_FREE) { | |
597 | - sozi_object->center.x = 0.5 * (dia_object->handles[i]->pos.x + to->x); | |
598 | - sozi_object->center.y = 0.5 * (dia_object->handles[i]->pos.y + to->y); | |
599 | - } | |
600 | - else { | |
601 | - /* FIXME : in FIXED aspect the behavior isn't userfriendly */ | |
602 | - static const real coefs [4][4] = | |
603 | - { | |
604 | - { 0.5,-0.5, 0.5, 0.5}, | |
605 | - { 0.5, 0.5, 0.5,-0.5}, | |
606 | - {-0.5, 0.5,-0.5,-0.5}, | |
607 | - {-0.5,-0.5,-0.5, 0.5}, | |
608 | - }; | |
609 | - sozi_object->center.x = dia_object->handles[i]->pos.x + | |
610 | - coefs[i][0] * sozi_object->width * sozi_object->cos_angle + | |
611 | - coefs[i][1] * sozi_object->height * sozi_object->sin_angle; | |
612 | - sozi_object->center.y = dia_object->handles[i]->pos.y + | |
613 | - coefs[i][2] * sozi_object->width * sozi_object->sin_angle + | |
614 | - coefs[i][3] * sozi_object->height * sozi_object->cos_angle; | |
615 | - } | |
608 | + /* FIXME : in FIXED aspect the behavior isn't userfriendly */ | |
609 | + static const real coefs [4][4] = | |
610 | + { | |
611 | + { 0.5,-0.5, 0.5, 0.5}, | |
612 | + { 0.5, 0.5, 0.5,-0.5}, | |
613 | + {-0.5, 0.5,-0.5,-0.5}, | |
614 | + {-0.5,-0.5,-0.5, 0.5}, | |
615 | + }; | |
616 | + sozi_object->center.x = dia_object->handles[i]->pos.x + | |
617 | + coefs[i][0] * sozi_object->width * sozi_object->cos_angle + | |
618 | + coefs[i][1] * sozi_object->height * sozi_object->sin_angle; | |
619 | + sozi_object->center.y = dia_object->handles[i]->pos.y + | |
620 | + coefs[i][2] * sozi_object->width * sozi_object->sin_angle + | |
621 | + coefs[i][3] * sozi_object->height * sozi_object->cos_angle; | |
616 | 622 | } |
617 | 623 | } |
618 | - sozi_object_update(sozi_object); | |
619 | 624 | } |
620 | 625 | |
626 | + /* refresh interactive rendering */ | |
627 | + sozi_object_update(sozi_object); | |
628 | + | |
621 | 629 | return NULL; |
622 | 630 | } |
@@ -126,13 +126,14 @@ void sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, | ||
126 | 126 | * Helper function for the dia's MoveFunc |
127 | 127 | * @param[in] sozi_object pointer to object |
128 | 128 | * @param[in] to destination point pointer |
129 | + * @see lib/object.h | |
129 | 130 | */ |
130 | 131 | ObjectChange* sozi_object_move(SoziObject *sozi_object, Point *to); |
131 | 132 | |
132 | 133 | /** |
133 | 134 | * Helper function for the dia's MoveHandleFunc |
134 | 135 | * @param[in] sozi_object pointer to object |
135 | - * ... | |
136 | + * @see lib/object.h | |
136 | 137 | */ |
137 | 138 | ObjectChange* sozi_object_move_handle(SoziObject *sozi_object, Handle *handle, |
138 | 139 | Point *to, ConnectionPoint *cp, |