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 decorationThe 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/
Attachment:
decoration_diff.gz
Description: GNU Zip compressed data