• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

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

作図ソフト dia の改良版


Commit MetaInfo

修訂7e62f6e76dbd9329004b7d96a91dfc48e4133a19 (tree)
時間2014-06-08 17:58:33
作者Hans Breuer <hans@breu...>
CommiterHans Breuer

Log Message

Fix path_build_arc() and implement DiaPathRenderer:draw_rounded_rect()

Together this fixes two main issues open with convert-to-path.

Change Summary

差異

--- a/lib/diapathrenderer.c
+++ b/lib/diapathrenderer.c
@@ -269,18 +269,18 @@ _path_arc_segment (GArray *path,
269269 real r_sin_B, r_cos_B;
270270 real h;
271271
272- r_sin_A = radius * sin (angle_A);
273- r_cos_A = radius * cos (angle_A);
274- r_sin_B = radius * sin (angle_B);
275- r_cos_B = radius * cos (angle_B);
272+ r_sin_A = -radius * sin (angle_A);
273+ r_cos_A = radius * cos (angle_A);
274+ r_sin_B = -radius * sin (angle_B);
275+ r_cos_B = radius * cos (angle_B);
276276
277277 h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0);
278-
278+
279279 bp.type = BEZ_CURVE_TO;
280- bp.p1.x = center->x + r_cos_A - h * r_sin_A;
281- bp.p1.y = center->y + r_sin_A + h * r_cos_A,
282- bp.p2.x = center->x + r_cos_B + h * r_sin_B,
283- bp.p2.y = center->y + r_sin_B - h * r_cos_B,
280+ bp.p1.x = center->x + r_cos_A + h * r_sin_A;
281+ bp.p1.y = center->y + r_sin_A - h * r_cos_A,
282+ bp.p2.x = center->x + r_cos_B - h * r_sin_B,
283+ bp.p2.y = center->y + r_sin_B + h * r_cos_B,
284284 bp.p3.x = center->x + r_cos_B;
285285 bp.p3.y = center->y + r_sin_B;
286286
@@ -381,13 +381,19 @@ path_build_arc (GArray *path,
381381 real ar2;
382382 int i, segs;
383383 real ars;
384+ real ctl;
385+ gboolean ccw = angle2 > angle1;
384386
385387 ar1 = (M_PI / 180.0) * angle1;
386388 ar2 = (M_PI / 180.0) * angle2;
387389 /* one segment for ever 90 degrees */
388- segs = (int)(fabs(ar2 - ar1) / (M_PI/2)) + 1;
389- ars = - (ar2 - ar1) / segs;
390-
390+ if (ccw) {
391+ segs = (int)((ar2 - ar1) / (M_PI/2)) + 1;
392+ ars = (ar2 - ar1) / segs;
393+ } else {
394+ segs = (int)((ar1 - ar2) / (M_PI/2)) + 1;
395+ ars = -(ar1 - ar2) / segs;
396+ }
391397 /* move to start point */
392398 start.x = center->x + (width / 2.0) * cos(ar1);
393399 start.y = center->y - (height / 2.0) * sin(ar1);
@@ -398,7 +404,8 @@ path_build_arc (GArray *path,
398404 _path_arc_segment (path, center, radius, ar1, ar1 + ars);
399405 } else {
400406 _path_moveto (path, &start);
401- _path_arc_segment (path, center, radius, ar1, ar2);
407+ for (i = 0; i < segs; ++i, ar1 += ars)
408+ _path_arc_segment (path, center, radius, ar1, ar2);
402409 _path_lineto (path, center);
403410 _path_lineto (path, &start);
404411 }
@@ -406,8 +413,6 @@ path_build_arc (GArray *path,
406413
407414 /*!
408415 * \brief Convert an arc to some bezier curve-to
409- * \bug For arcs going through angle 0 the result is wrong,
410- * kind of the opposite of the desired.
411416 * \protected \memberof _DiaPathRenderer
412417 */
413418 static void
@@ -644,6 +649,34 @@ draw_image(DiaRenderer *self,
644649 _path_lineto (path, &to);
645650 }
646651
652+/*!
653+ * \brief Create contour of the rounded rect
654+ *
655+ * This methods needs to be implemented to avoid the default
656+ * implementation mixing calls of draw_arc, drar_line and fill_arc.
657+ * We still use the default but only method but only for the outline.
658+ */
659+static void
660+draw_rounded_rect (DiaRenderer *self,
661+ Point *ul_corner, Point *lr_corner,
662+ Color *fill, Color *stroke, real radius)
663+{
664+ DiaPathRenderer *renderer = DIA_PATH_RENDERER (self);
665+ real rx = (lr_corner->x - ul_corner->x) / 2;
666+ real ry = (lr_corner->y - ul_corner->y) / 2;
667+ /* limit radius to fit */
668+ if (radius > rx)
669+ radius = rx;
670+ if (radius > ry)
671+ radius = ry;
672+ DIA_RENDERER_CLASS(dia_path_renderer_parent_class)->draw_rounded_rect(self,
673+ ul_corner, lr_corner,
674+ NULL, stroke ? stroke : fill, radius);
675+ /* stroke is set by the piecewise rendering above already */
676+ if (fill)
677+ renderer->fill = *fill;
678+}
679+
647680 /*!
648681 * \brief _DiaPathRenderer class initialization
649682 * Overwrite methods of the base classes here.
@@ -682,6 +715,8 @@ dia_path_renderer_class_init (DiaPathRendererClass *klass)
682715 renderer_class->draw_bezier = draw_bezier;
683716 renderer_class->draw_beziergon = draw_beziergon;
684717 renderer_class->draw_text = draw_text;
718+ /* highest level function */
719+ renderer_class->draw_rounded_rect = draw_rounded_rect;
685720 /* other */
686721 renderer_class->is_capable_to = is_capable_to;
687722 }
Binary files a/samples/arcs.dia and b/samples/arcs.dia differ