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. |