Cc: david hoover epfl ch,Geraint <geraint geraintpaulbevan freeserve co uk>, mtt gawthrop net,mtt-developers <mtt-developers sourceforge net>
Subject: Flexible, modular dia line decoration code
Date: Mon, 02 Dec 2002 14:01:36 +0100
Hi,
I have written some PRELIMINARY modular arrow code for dia (based on
gaps, of course). This is just a demonstration of one way of
implementing modular arrow/line code. This diff is based on the
objects/standard/line.c file in CVS.
It is based on a DecorationProp structure that allows one to define a
kind of transformation:
decorating_segment():
inputs: DecorationProp structure, line start/end segments
output: start/end points of decoration
The code demonstrates the relationship between the DecorationProp and
the drawn decoration. By providing a list of DecorationProps, it should
be possible to do just about any type of arrow (the demonstration just
does one DecorationProp at a time. It is possible to use more complex
shapes as decorations. Try it out and give me some feedback. When the
code is enabled, every line you draw will have a different decoration
attached (do not choose an arrow head--they will be placed
automatically). Notice that it is possible to specify in
DecorationProps whether asymmetric decorations are always placed on the
right or left side of the object endpoint (relative to arrow direction),
or always EAST of the endpoint or always north-east, and so forth.
It is also possible to specify that decorations be draw a fixed size, or
proportional to line length, or any combination of the two.
To make this modular, I think we could rewrite the 'GAP_define' stuff so
that the user can choose the number of decorations, and for each
decoration specify the angle, shape, and gap properties. The user could
specify 4-number gaps if desired, or select from a list of pre-made GAP
specifications. Each specification, like GAP_absolute,
GAP_proportional, or GAP_relative_alignment_shift_in, could be provided
with a text description and user-choosable parameters. For instance,
for GAP_absolute, the user would have a simple 'length' to choose. We
could also compose a huge list of parameterized arrow heads that a user
could choose directly from. The arrow heads could be in categories like
(standard, flat, shaped). The user would then choose either symmetric
or asymmetric, or anti-symmetric. This way, starting from a plain old
half-head arrow, by selecting asymmetric, symmetric, antisymmetric the
user would get:
1. asymmetric: half-head
2. symmetric: lines
3. antisymmetric: cross
or from a half-flat-head, a user could select
1. asymmetric: half-flat-head
2. symmetric: flat-head
3. antisymmetric: flat-head
These are just ideas. What do you think?
I think it's important to think about how we store gap specifications,
DecorationProp specifications, and so on. I think we should have
data_gap, data_add_gap, data_decorationprop, and data_add_decorationprop
functions. Maybe you think I'm getting ahead of myself. You may be right.
The code also partially implements line start/center/end labels that are
disabled by default. When enabled, they print out user-chosen labels
near the line start/center/end points. The labels use the
decorating_segment() code to position the labels so that they never
intersect the line. For the moment, only the start label sort of works.
The bounding boxes have not been done for the labels, and so you will
get nasty effects on the screen when you use this.
decorating_segment() is described in more detail in the code.
This code is in no way meant to be 'optimal'. Many improvements can be
made (storage of segments, etc., to avoid repeating calculations). Line
joins are not done at all, so either this code must be generalized, or
certain arrows will still have to be coded by hand to obtain optimal
results. Without doing joins, we can maybe determine when two different
segments have a common endpoint, and then draw each of those lines with
a LINECAPS_ROUND to avoid ugly intersections...??..
As usual, this patch is copyrighted (2002) by David Hoover. You can
use, copy, and modify this code according to the conditions of the GNU
General Public License (GPL) as found in the Dia distribution or found
at http://www.gnu.org/