|
From: Tony G. <Ton...@Su...> - 2005-03-03 01:28:57
|
gn...@th... writes:
...
> I can try adding border-color resolution support. I checked out
Great!
> fo-context-util - it looks like I'd be modifying
> fo_context_util_border_resolve() to understand the shorthand border-color
> property and using code similar to fo_context_util_paddings_resolve() to
> deal with the border-color FoTblr, no? Just checking that I am on the
> right track... Chapter 5 of the XSL spec is quite clear about the precedence
You are on the right track.
> rules for shorthand properties etc. I'll probably have questions though...
I would be surprised, very surprised, if you didn't have questions
over the combination of the XSL spec and the xmlroff code.
> In general, I am starting to slowly work my way through the XSL spec, getting
> the hang of GObject, and getting a better feel for the code and how things
> fit together.
Let me try to prime the pump...
AFAICT, the immediate problem of adding 'border-color' support boils
down to adding the equivalent of the "if (shorthand_component !=
null)" block from resolve_absolute_relative_padding() to the color
handling portions of fo_context_util_border_resolve().
fo_context_util_border_resolve() currently does practically the same
thing twelve different ways: it resolves the absolute and relative
properties for each of 'color', 'width', and 'style' for each of the
four borders of an FO that has borders.
fo_context_util_border_resolve() works on the FoContext of the current
FO; that is, it works on the full set of absolute and relative
property values that were specified on the current FO.
The result from running fo_context_util_border_resolve() is that the
current FoContext is updated with the absolute and relative property
values resolved as specified in the XSL spec.
One twist in the tale is that if neither an absolute nor relative
color property is provided (e.g., if neither 'border-left-color' or
'border-start-color' for the start border), then you use the same
color as the text, i.e., use the either 'color' property value of the
current FO or the 'color' property value of the parent FO if 'color'
is not set on the current FO.
Another twist is when the style is 'none', then the border has zero
width no matter what values are used for the absolute and relative
border width properties.
fo_context_util_padding_resolve() is a later version of handling much
the same problem. Handling padding is much simpler since padding only
has width, even though the width can have conditionality. Because
padding is simpler, that was my first attempt at a shorthand property.
fo_context_util_padding_resolve() takes a different approach to the
fact that you do practically the same thing for each of the four
sides: rather than copying the code four times with slightly different
function names each time, fo_context_util_padding_resolve() leaves all
the processing to the resolve_absolute_relative_padding() function and
just calls it four times with the values appropriate for each side.
In principle, that's a technique that will scale better when xmlroff
gets around to handling reference-orientation, since when the
relationship between relative and absolute is no longer fixed, you
really don't want a single function that's 16 times as long as
resolve_absolute_relative_padding() just to do nearly the same thing
16 times over.
Some things you will see a lot of in the code:
FoDatatype *datatype;
FoProperty *property = ...;
...
datatype = fo_property_get_value (property);
As a comment on using GObjects: since GObjects are only
object-oriented by convention, you need to pass the GObject as
(usually) the first argument of a function that operates on the
GObject. In an object-oriented language that does things with
dots to signify methods of objects, this would probably be
expressed as 'property.getValue()'.
As a comment on using FoProperty: you can use
fo_property_get_value() to get (a pointer to) the FoDatatype
that is the value of the property.
FoDataypes are (or should be) immutable. (I'm still working on
modifying all the datatypes so they are, but when you could
change the value of a datatype that was the value of a property,
it sometimes caused strange behaviour in other FOs because their
property's value had also been changed. At least some of the
time, I also think of making FoProperty objects immutable for
much the same reason.)
FoProperty *property;
...
property = fo_property_border_left_style_new ();
This gets a new instance of the property type, to which you will
probably assign a value shortly afterwards.
fo_property_set_value (absolute, datatype);
Sets a property's value.
FoProperty *property;
...
property = fo_property_border_left_style_get_initial ();
This gets an instance of the property that is set to the initial
value as specified in the XSL spec. In practice, this always
returns the same property instance since for non-inherited values
it saves creating a lot of instances that all have the same value
and are never going to change. You *really* don't want to change
the value of a FoProperty you got this way.
property = fo_context_get_margin_left (current_context);
fo_context_set_border_left_style (current_context, property);
Getter and setter for FoContext components.
One last thing that I only found out on the weekend... The CSS2
errata says that individual border's colour values should be "<color>
| transparent" (i.e., the same as 'background-color'). It probably
won't make any difference to fo_context_util_border_resolve(), but I
thought I'd mention it since you'd start to wonder when you look in
the spec and see "[<color> | transparent]{1,4} | inherit" for
'border-color' and just '<color> | inherit' for the individual colour
properties.
Regards,
Tony.
|