Re: Rounded corners
- From: Hans Breuer <hans breuer org>
- To: discussions about usage and development of dia <dia-list gnome org>
- Subject: Re: Rounded corners
- Date: Thu, 29 May 2008 23:03:08 +0200
Am 29.05.2008 05:37, Don Blaheta schrieb:
I've been playing around with lib/diagdkrenderer.c to try and work on
bug #534275. I noticed the changes made in the recent SVN update, which
partially solve the problem, but there are a few problems still.
2008-05-25 Hans Breuer <hans breuer org>
Attempts to fix bug #534275
* lib/diagdkrenderer.c(draw_fill_rounded_rect) : attempt to make
arc drawing for radius<line_width less backend specific.
* objects/standard/box.c objects/standard/polyline.c
objects/standard/zigzagline.c :
set LINEJOIN_ROUND when rendering "rounded" (with radius>0)
What I was trying to say here was: arc drawing (rounded somethings) are
highly backend specific for radius near or smaller than half of the
linewidth. Your are right that the definition needs to come first, but my
current impression is that you may be requesting too much.
In my implmentation I tried to work around (and only partitially succeeded)
the lack of backend capabilities. But if this is really to be solved it is
not only a matter of the GdkRenderer but preferably also of all other
renderers.
The biggest, I think, is that "corner radius" is being used to mean two
different things: the radius of rounding for a rounded rectangle, and
the radius of rounding for the cap of a regular rectangle.
If I understand the terminology correctly 'caps' are only at the end of
lines, see e.g.:
http://library.gnome.org/devel/gdk/stable/gdk-Graphics-Contexts.html#GdkCapStyle
; but we need 'joins' here because we are talking about the radius between
line segments, see:
http://library.gnome.org/devel/gdk/stable/gdk-Graphics-Contexts.html#GdkJoinStyle
The former
it is reasonable to measure from the control points (as it is), although
measuring from the inside or outside edge would also be reasonable; the
latter really must be measured from the outside edge.
The latter just was undefined behaviour and kind of it still is. My attempt
for rectangles was piecewise approximation with longer lines and smaller
and thinner arcs to fill the corners. Maybe it would be better to adapt the
definition to:
radius==0 : JOIN_MITER
radius>0 && <line_width/2 : JOIN_ROUND
radius>line_width/2 : draw arcs
The current workaround is to say that if the given radius is less than
half the width of the line, treat it as a cap and measure from the
outside edge, and otherwise measure from the control points. I had to
go into the code to figure out what was going on there, because it
seemed buggy when I was just playing with it: if you compare two boxes
with line width 4, one with corner radius 2 and one with radius 1.99,
they look very different! I don't think this will work. (It's also not
mirrored in the zigzagline or polylines.)
Yes, distributing something which (maybe) can't work to other
implementations did not look feasible to me. So if it is not going to work
for rectangles how should it work for the other rounded lines?
I see three possible solutions:
* Treat rounded rectangles as different objects from regular boxes. A
rounded rectangle has a corner radius that works as the box corner
radius does now; a regular box has a "cap radius" that measures from
the outside edge of the line. If the cap radius is zero, the cap is a
square cap. The cap radius cannot be larger than the line width.
A rounded rectangle with corner radius zero would look like a regular
box with cap radius of half the linewidth. Polylines and Zigzaglines
would be made to match the regular box behaviour; as it stands they
already can't have a corner radius that rounds more than just the
corner cap.
I still don't think there is a good implmentation to do *joins* smaller
than half the line_width. Also this would mean a further explosion of
options, i.e. where for all the boxes drawn woud be made the decision of
"rounded rectangles" vs. "regular boxes"?
* Treat all rectangles as the same, but always measure the corner radius
from the outside edge of the line. This is probably ok, but it does
mean that the curve of the corner changes when the line width does.
Polylines and zigzaglines are modified to match.
Looks most similar to what I came up with above. But it seems quite
difficult to make this work for all the renderers.
* Revert the behaviour of rounded rectangles to always measure the
corner radius from the control points, but add a boolean flag to boxes
that chooses rounded vs square cap; it would be greyed out if the
corner radius is other than zero.
"Greying out" some parameter depending on some other parameter is not going
to be easy with the way Dia handles it's properties. If you would want to
modify multiple objects (in a group) it even can't work by concept.
"Rounded" would make a radius of
exactly half the linewidth. Polylines and zigzaglines get the
checkbox as well instead of a corner radius option.
The almost independent parameter which could be given to all the renderers
is the line join. Maybe we should allow the user to set it, instead of
hardcoding the behaviour for radius>=0 && radius<line_width?
How do Visio and other such programs handle any of this?
I Looked at some other renderers Dia has - namely antialised vias cairo and
wmf and the implmentation looks like the radius is applied at the control
rectangle. For radius 0 it gives sharp edges, for 0.1 it has an outer
radius of almost half of the line width.
Now I think the GdkRenderer should be fixed in that direction.
Regards,
Hans
-------- Hans "at" Breuer "dot" Org -----------
Tell me what you need, and I'll tell you how to
get along without it. -- Dilbert
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]