• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


コミットメタ情報

リビジョン4f108f6854cde9e7cb52cca733228f50044ebb1a (tree)
日時2015-01-17 07:30:48
作者Paul Chavent <paul.chavent@fnac...>
コミッター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>

変更サマリ

差分

--- a/objects/Sozi/sozi-frame.c
+++ b/objects/Sozi/sozi-frame.c
@@ -189,18 +189,18 @@ sozi_frames_reorder(gpointer data, gpointer user_data)
189189 {
190190 /* see object.h for the description of the object structure */
191191 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) {
193193 SoziFrame *sozi_frame = (SoziFrame *)dia_object;
194194 struct sequence_pair * seq_pair = (struct sequence_pair *)user_data;
195195 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)) {
197197 /* fprintf(stdout, "old value %d ++ new value %d\n", sozi_frame->sequence, sozi_frame->sequence + 1); */
198198 sozi_frame->sequence++;
199199 sozi_frame->old_sequence = sozi_frame->sequence;
200200 /* FIXME : not sure it's the good way to redraw an object */
201201 /* sozi_frame_draw(sozi_frame); */
202202 }
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)) {
204204 /* fprintf(stdout, "old value %d -- new value %d\n", sozi_frame->sequence, sozi_frame->sequence - 1); */
205205 sozi_frame->sequence--;
206206 sozi_frame->old_sequence = sozi_frame->sequence;
@@ -215,11 +215,11 @@ sozi_frames_count(gpointer data, gpointer user_data)
215215 {
216216 /* see object.h for the description of the object structure */
217217 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) {
219219 SoziFrame *sozi_frame = (SoziFrame *)dia_object;
220220 /* only object with old_sequence different of zero should be
221221 taken into account */
222- if(sozi_frame->sequence) {
222+ if (sozi_frame->sequence) {
223223 int * counter = (int *)user_data;
224224 *counter = *counter + 1;
225225 }
@@ -236,7 +236,7 @@ sozi_frame_update(SoziFrame *sozi_frame)
236236
237237 /* probably editing default configuration or loading object
238238 -> do not care */
239- if(!sozi_frame->sozi_object.dia_object.parent_layer) {
239+ if (!sozi_frame->sozi_object.dia_object.parent_layer) {
240240 return;
241241 }
242242
@@ -246,7 +246,7 @@ sozi_frame_update(SoziFrame *sozi_frame)
246246 sequence managment
247247 We use exemples of data_foreach_object of diagramdata.h
248248 */
249- if(!sozi_frame->sequence) {
249+ if (!sozi_frame->sequence) {
250250 /* this condition is true iif the object have just been created */
251251 int frames_count = 0;
252252 /* trig COUNTING of all frames */
@@ -255,7 +255,7 @@ sozi_frame_update(SoziFrame *sozi_frame)
255255 /* fprintf(stdout, "seq must be initialized after object creation (%d frames)\n", frames_count); */
256256 sozi_frame->sequence = frames_count + 1;
257257 }
258- else if(sozi_frame->old_sequence &&
258+ else if (sozi_frame->old_sequence &&
259259 (sozi_frame->old_sequence != sozi_frame->sequence)) {
260260 /* this condition is true iif the object's sequence number
261261 have just been changed (in sozi_frame_set_props for instance) */
@@ -277,7 +277,7 @@ sozi_frame_update(SoziFrame *sozi_frame)
277277
278278 /* update legend */
279279 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)
281281 {
282282 legend[sizeof(legend) - 1] = 0;
283283 legend[sizeof(legend) - 2] = '.';
@@ -299,7 +299,7 @@ sozi_frame_init(SoziFrame *sozi_frame)
299299 sozi_frame->old_sequence = 0;
300300 sozi_frame->sequence = 0;
301301
302- if(sozi_frame->title == NULL) {
302+ if (sozi_frame->title == NULL) {
303303 sozi_frame->title = g_strdup("frame title");
304304 }
305305
@@ -315,7 +315,7 @@ sozi_frame_init(SoziFrame *sozi_frame)
315315 static void
316316 sozi_frame_kill(SoziFrame *sozi_frame)
317317 {
318- if(sozi_frame->title != NULL) {
318+ if (sozi_frame->title != NULL) {
319319 g_free(sozi_frame->title);
320320 }
321321 }
@@ -350,8 +350,10 @@ sozi_frame_create(Point *startpoint,
350350 sozi_object_update(&sozi_frame->sozi_object);
351351
352352 /* 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 */
355357
356358 return &sozi_frame->sozi_object.dia_object;
357359 }
@@ -483,7 +485,7 @@ sozi_frame_draw(SoziFrame *sozi_frame, DiaRenderer *renderer)
483485 if (DIA_IS_SVG_RENDERER(renderer)) {
484486 sozi_frame_draw_svg(sozi_frame, DIA_SVG_RENDERER (renderer));
485487 }
486- else if(DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer) ||
488+ else if (DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer) ||
487489 !sozi_frame->hide) {
488490 DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
489491
@@ -494,7 +496,7 @@ sozi_frame_draw(SoziFrame *sozi_frame, DiaRenderer *renderer)
494496
495497 renderer_ops->draw_polygon(renderer, sozi_frame->sozi_object.corners, 4, NULL, &color_black);
496498
497- if(sozi_frame->sozi_object.legend.disp == TRUE) {
499+ if (sozi_frame->sozi_object.legend.disp == TRUE) {
498500 text_draw(sozi_frame->sozi_object.legend.text, renderer);
499501 }
500502 }
@@ -649,9 +651,9 @@ sozi_frame_get_properties(SoziFrame *sozi_frame, gboolean is_default)
649651 for (i = 0; i < dialog->prop_widgets->len; ++i) {
650652 PropWidgetAssoc *pwa = &g_array_index(dialog->prop_widgets,
651653 PropWidgetAssoc, i);
652- if(pwa) {
654+ if (pwa) {
653655 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)) {
655657 int count = 0;
656658 data_foreach_object(layer_get_parent_diagram(dia_object->parent_layer), sozi_frames_count, &count);
657659
--- a/objects/Sozi/sozi-media.c
+++ b/objects/Sozi/sozi-media.c
@@ -217,9 +217,9 @@ sozi_media_create(Point *startpoint,
217217 /* update sozi object geometry */
218218 sozi_object_update(&sozi_media->sozi_object);
219219
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 */
223223
224224 return &sozi_media->sozi_object.dia_object;
225225 }
--- a/objects/Sozi/sozi-object.c
+++ b/objects/Sozi/sozi-object.c
@@ -29,6 +29,7 @@
2929
3030 /* dia stuff */
3131 #include "diarenderer.h"
32+#include "message.h"
3233
3334 /* sozi stuff */
3435 #include "sozi-player.h"
@@ -54,34 +55,34 @@ static const Handle default_handles[4] =
5455 * @param[in] doc the svg document
5556 * @param[in] sozi_elem the sozi player identification string that will
5657 * 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.
5860 */
5961 static int
6062 sozi_player_is_present(xmlDocPtr doc, const xmlChar *sozi_elem)
6163 {
6264 xmlXPathContextPtr context;
6365 xmlXPathObjectPtr result;
66+ int is_present;
6467
6568 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;
6972 }
7073
7174 result = xmlXPathEvalExpression(sozi_elem, context);
7275 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;
7679 }
7780
78- if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
79- xmlXPathFreeObject(result);
80- return 0;
81- }
81+ is_present = xmlXPathNodeSetIsEmpty(result->nodesetval)?0:1;
8282
8383 xmlXPathFreeObject(result);
84- return 1;
84+
85+ return is_present;
8586 }
8687
8788 /**
@@ -96,7 +97,6 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr
9697 {
9798 #if defined(SOZI_PATH)
9899 /* try to get sozi engine from SOZI_PATH */
99- int i;
100100 struct
101101 {
102102 const gchar * filename;
@@ -108,16 +108,18 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr
108108 { SOZI_PATH"/extras/sozi_extras_media.js" , sozi_extras_media_js_ptr },
109109 { SOZI_PATH"/sozi.css" , sozi_css_ptr }
110110 };
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++) {
113115 GError * err = 0;
114116 if (!g_file_get_contents(external_sozi[i].filename,
115117 external_sozi[i].data,
116118 NULL,
117119 &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);
121123 g_error_free (err);
122124 while(i--) {
123125 g_free (*external_sozi[i].data);
@@ -126,13 +128,12 @@ sozi_player_get(gchar **sozi_version_ptr, gchar **sozi_js_ptr, gchar **sozi_extr
126128 }
127129 }
128130
129- if(i == 3) {
131+ if (i == external_sozi_cnt) {
130132 /* that's ok, don't need to go further */
131133 return;
132134 }
133135
134-#else /* defined(SOZI_PATH) */
135- g_warning("sozi-object : use builtin player");
136+ dia_log_message("sozi-object : use builtin player");
136137 #endif /* defined(SOZI_PATH) */
137138
138139 /* 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
142143 *sozi_css_ptr = g_strdup((const gchar *)sozi_min_css);
143144
144145 #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);
146147 #endif /* defined(SOZI_PATH) */
147148 }
148149
@@ -163,23 +164,23 @@ sozi_object_init(SoziObject *sozi_object, Point *center)
163164 /* dia_object->bounding_box will be set in sozi_object_update */
164165
165166 dia_object->num_handles = 4;
166- if(dia_object->handles == NULL) {
167+ if (dia_object->handles == NULL) {
167168 dia_object->handles = g_new0(Handle *, 4);
168169 }
169170
170171 for (i = 0; i < 4; i++) {
171- if(dia_object->handles[i] == NULL) {
172+ if (dia_object->handles[i] == NULL) {
172173 dia_object->handles[i] = g_new0(Handle, 1);
173174 }
174175 *dia_object->handles[i] = default_handles[i];
175176 }
176177
177178 dia_object->num_connections = 1;
178- if(dia_object->connections == NULL) {
179+ if (dia_object->connections == NULL) {
179180 dia_object->connections = g_new0(ConnectionPoint *, 1);
180181 }
181182
182- if(dia_object->connections[0] == NULL) {
183+ if (dia_object->connections[0] == NULL) {
183184 dia_object->connections[0] = g_new0(ConnectionPoint, 1);
184185 }
185186 dia_object->connections[0]->object = dia_object;
@@ -215,13 +216,13 @@ sozi_object_kill(SoziObject *sozi_object)
215216 object_unconnect_all(&sozi_object->dia_object);
216217
217218 for (i = 0; i < 1; i++) {
218- if(sozi_object->dia_object.connections[i] != NULL) {
219+ if (sozi_object->dia_object.connections[i] != NULL) {
219220 g_free(sozi_object->dia_object.connections[i]);
220221 }
221222 }
222223
223224 for (i = 0; i < 4; i++) {
224- if(sozi_object->dia_object.handles[i] != NULL) {
225+ if (sozi_object->dia_object.handles[i] != NULL) {
225226 g_free(sozi_object->dia_object.handles[i]);
226227 }
227228 }
@@ -260,10 +261,10 @@ sozi_object_update(SoziObject *sozi_object)
260261 dia_object->bounding_box.bottom = -G_MAXFLOAT;
261262
262263 /* angle */
263- if(sozi_object->angle < -180) {
264+ if (sozi_object->angle < -180) {
264265 sozi_object->angle += 360.0;
265266 }
266- if(180 < sozi_object->angle) {
267+ if (180 < sozi_object->angle) {
267268 sozi_object->angle -= 360;
268269 }
269270 sozi_object->cos_angle = cos(sozi_object->angle * M_PI / 180.0);
@@ -297,16 +298,16 @@ sozi_object_update(SoziObject *sozi_object)
297298
298299 dia_object->handles[i]->pos = sozi_object->corners[i];
299300
300- if(sozi_object->corners[i].x < dia_object->bounding_box.left) {
301+ if (sozi_object->corners[i].x < dia_object->bounding_box.left) {
301302 dia_object->bounding_box.left = sozi_object->corners[i].x - SOZI_OBJECT_LINE_WIDTH;
302303 }
303- if(dia_object->bounding_box.right < sozi_object->corners[i].x) {
304+ if (dia_object->bounding_box.right < sozi_object->corners[i].x) {
304305 dia_object->bounding_box.right = sozi_object->corners[i].x + SOZI_OBJECT_LINE_WIDTH;
305306 }
306- if(sozi_object->corners[i].y < dia_object->bounding_box.top) {
307+ if (sozi_object->corners[i].y < dia_object->bounding_box.top) {
307308 dia_object->bounding_box.top = sozi_object->corners[i].y - SOZI_OBJECT_LINE_WIDTH;
308309 }
309- if(dia_object->bounding_box.bottom < sozi_object->corners[i].y) {
310+ if (dia_object->bounding_box.bottom < sozi_object->corners[i].y) {
310311 dia_object->bounding_box.bottom = sozi_object->corners[i].y + SOZI_OBJECT_LINE_WIDTH;
311312 }
312313 }
@@ -331,6 +332,7 @@ void
331332 sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, gchar * refid, xmlNs **p_sozi_name_space, xmlNodePtr * p_root, xmlNodePtr * p_rect)
332333 {
333334 static xmlNs * sozi_name_space = NULL;
335+ int player_is_present;
334336 xmlNodePtr root;
335337 xmlNodePtr node;
336338 /* for managing sozi player implantation */
@@ -353,7 +355,11 @@ sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, gcha
353355
354356 /* check that the sozi namespace, scripts and style are present */
355357
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) {
357363
358364 sozi_player_get(&sozi_version, &sozi_js, &sozi_extras_media_js, &sozi_css);
359365
@@ -483,7 +489,7 @@ sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer, gcha
483489 }
484490
485491 /******************************************************************************
486- * FUNCTIONS FOR MANAGING THE OBJECT GRABBING AND SCALLING
492+ * FUNCTIONS FOR MANAGING THE OBJECT GRABBING, SCALLING AND ROTATION
487493 *****************************************************************************/
488494
489495 ObjectChange*
@@ -491,6 +497,7 @@ sozi_object_move(SoziObject *sozi_object, Point *to)
491497 {
492498 sozi_object->center = *to;
493499
500+ /* refresh interactive rendering */
494501 sozi_object_update(sozi_object);
495502
496503 return NULL;
@@ -498,125 +505,126 @@ sozi_object_move(SoziObject *sozi_object, Point *to)
498505
499506 ObjectChange*
500507 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)
503510 {
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+ }
524575 }
525576 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));
542601 }
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);
568606 }
569607 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;
616622 }
617623 }
618- sozi_object_update(sozi_object);
619624 }
620625
626+ /* refresh interactive rendering */
627+ sozi_object_update(sozi_object);
628+
621629 return NULL;
622630 }
--- a/objects/Sozi/sozi-object.h
+++ b/objects/Sozi/sozi-object.h
@@ -126,13 +126,14 @@ void sozi_object_draw_svg(SoziObject *sozi_object, DiaSvgRenderer *svg_renderer,
126126 * Helper function for the dia's MoveFunc
127127 * @param[in] sozi_object pointer to object
128128 * @param[in] to destination point pointer
129+ * @see lib/object.h
129130 */
130131 ObjectChange* sozi_object_move(SoziObject *sozi_object, Point *to);
131132
132133 /**
133134 * Helper function for the dia's MoveHandleFunc
134135 * @param[in] sozi_object pointer to object
135- * ...
136+ * @see lib/object.h
136137 */
137138 ObjectChange* sozi_object_move_handle(SoziObject *sozi_object, Handle *handle,
138139 Point *to, ConnectionPoint *cp,