You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

properties.xml 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. <?xml version="1.0" encoding="ISO-8859-1"?>
  2. <!--
  3. Licensed to the Apache Software Foundation (ASF) under one or more
  4. contributor license agreements. See the NOTICE file distributed with
  5. this work for additional information regarding copyright ownership.
  6. The ASF licenses this file to You under the Apache License, Version 2.0
  7. (the "License"); you may not use this file except in compliance with
  8. the License. You may obtain a copy of the License at
  9. http://www.apache.org/licenses/LICENSE-2.0
  10. Unless required by applicable law or agreed to in writing, software
  11. distributed under the License is distributed on an "AS IS" BASIS,
  12. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. See the License for the specific language governing permissions and
  14. limitations under the License.
  15. -->
  16. <!-- $Id$ -->
  17. <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.3//EN" "http://forrest.apache.org/dtd/document-v13.dtd">
  18. <document>
  19. <header>
  20. <title>Apache™ FOP Design: Properties</title>
  21. <version>$Revision$</version>
  22. <authors>
  23. <person name="Karen Lease" email=""/>
  24. </authors>
  25. </header>
  26. <body>
  27. <section id="intro">
  28. <title>Introduction</title>
  29. <p>As the input XSL-FO is being parsed and the FO Tree is being built, the attributes of the FO elements are passed by the parser to the related FO object.
  30. The java object that represent the FO object then converts the attributes into properties that are stored in the FO Tree.</p>
  31. </section>
  32. <section id="issues">
  33. <title>Issues</title>
  34. <p>The following are some issues when dealing with properties:</p>
  35. <ul>
  36. <li>Initial Property Set</li>
  37. <li>Inheritance: Some properties can be inherited from parent objects.</li>
  38. <li>Adoption: The parentage for some elements can move around.
  39. Markers are one example.</li>
  40. <li>Multiple Namespaces: The properties for foreign namespaces must be handled.</li>
  41. <li>Expressions: XSL-FO expressions can be included in properties.</li>
  42. </ul>
  43. </section>
  44. <section id="process-overview">
  45. <title>Overview of Processing</title>
  46. <p>The general flow of property processing is as follows:</p>
  47. <ul>
  48. <li>As part of <code>FOTreeBuilder.startElement()</code>, <code>FObj.handleAttrs</code> is passed a list of attributes to be processed for the new FObj.</li>
  49. <li>FObj.handleAttrs gets a PropertyListBuilder and asks it to create a Property List from the list of attributes. There is currently only one static PropertyListBuilder, which handles the fo: namespace.</li>
  50. <li>FObj.handleAttrs then cross-references the returned PropertyList with the FObj, creates a PropertyManager to facilitate downstream processing of the PropertyList, and handles the special case of the writing-mode property.</li>
  51. </ul>
  52. </section>
  53. <section id="plb">
  54. <title>PropertyListBuilder</title>
  55. <p>Each plb object contains a hash of
  56. property names and <em>their</em> respective Makers. It may also
  57. contain element-specific property maker hashes; these are based on the
  58. <em>local name</em> of the flow object, ie. <em>table-row</em>, not
  59. <em>fo:table-row</em>. If an element-specific property mapping exists,
  60. it is preferred to the generic mapping.</p>
  61. <p>The PLB loops through each attribute in the list, finds an appropriate "Maker" for it, then calls the Maker to convert the attribute value into a Property object of the correct type, and stores that Property in the PropertyList.</p>
  62. </section>
  63. <section id="datatypes">
  64. <title>Property datatypes</title>
  65. <p>The property datatypes are defined in the
  66. org.apache.fop.datatypes package, except Number and String which are java
  67. primitives. The FOP datatypes are:</p>
  68. <ul>
  69. <li>Number</li>
  70. <li>String</li>
  71. <li>ColorType</li>
  72. <li>Length (has several subclasses)</li>
  73. <li>CondLength (compound)</li>
  74. <li>LengthRange (compound)</li>
  75. <li>Space (compound)</li>
  76. <li>Keep (compound)</li>
  77. </ul>
  78. <p>The <em>org.apache.fop.fo.Property</em> class is the superclass for all
  79. Property subclasses. There is a subclass for each kind of property
  80. datatype. These are named using the datatype name plus the word
  81. Property, resulting in NumberProperty, StringProperty, and so
  82. on. There is also a class EnumProperty which uses an <code>int</code>
  83. primitive to hold enumerated values. There is no corresponding Enum
  84. datatype class.</p>
  85. <p>The Property class provides a "wrapper" around any possible
  86. property value. Code manipulating property values (in layout for
  87. example) usually knows what kind (or kinds) of datatypes are
  88. acceptable for a given property and will use the appropriate accessor.</p>
  89. <p>The base Property class defines accessor methods for all FO property
  90. datatypes, such as getNumber(), getColorType(), getSpace(), getEnum(),
  91. etc. It doesn't define
  92. accessors for SVG types, since these are handled separately (at least
  93. for now.) In the base Property class, all of these methods return
  94. null, except getEnum which returns 0. Individual subclasses return a value of the appropriate type,
  95. such as Length or ColorType. A subclass may also choose to return a
  96. reasonable value for other accessor types. For example, a
  97. SpaceProperty will return the optimum value if asked for a Length.</p>
  98. </section>
  99. <section id="makers">
  100. <title>Property Makers</title>
  101. <p>The Property class contains a nested class called
  102. <em>Maker</em>. This is the base class for all other property Makers. It
  103. provides basic framework functionality which is overridden by the
  104. code generated by properties.xsl from the *properties.xml files. In
  105. particular it provides basic expression evaluation, using
  106. PropertyParser class in the org.apache.fop.fo.expr package.</p>
  107. <p>Other Property subclasses such as LengthProperty define their own
  108. nested Maker classes (subclasses of Property.Maker). These handle
  109. conversion from the Property subclass returned from expression
  110. evaluation into the appropriate subclass for the property.</p>
  111. <p>For each generic or specific property definition in the
  112. properties.xml files, a new subclass of one of the Maker classes is
  113. created. Note that no new Property subclasses are created, only new
  114. PropertyMaker subclasses. Once the property value has been parsed and
  115. stored, it has no specific functionality. Only the Maker code is
  116. specific. Maker subclasses define such aspects as keyword
  117. substitutions, whether the property can be inherited or not, which
  118. enumerated values are legal, default values, corresponding properties
  119. and specific datatype conversions.</p>
  120. <p>The PLB finds a "Maker" for the property based on the attribute name and
  121. the element name. Most Makers are generic and handle the attribute on
  122. any element, but it's possible to set up an element-specific property
  123. Maker. The attribute name to Maker mappings are automatically created
  124. during the code generation phase by processing the XML property
  125. description files.</p>
  126. </section>
  127. <section id="attribute-list">
  128. <title>Processing the attribute list</title>
  129. <p>The PLB first looks to see if the font-size property is specified, since
  130. it sets up relative units which can be used in other property
  131. specifications. Each attribute is then handled in turn. If the attribute
  132. specifies part of a compound property such as space-before.optimum, the
  133. PLB looks to see if the attribute list also contains the "base" property
  134. (space-before in this case) and processes that first.</p>
  135. </section>
  136. <section id="maker-design">
  137. <title>How the Property Maker works</title>
  138. <p>There is a family of Maker objects for each of the property datatypes,
  139. such as Length, Number, Enumerated, Space, etc. But since each Property
  140. has specific aspects such as whether it's inherited, its default value,
  141. its corresponding properties, etc. there is usually a specific Maker for
  142. each Property. All these Maker classes are created during the code
  143. generation phase by processing (using XSLT) the XML property description
  144. files to create Java classes.</p>
  145. <p>The Maker first checks for "keyword" values for a property. These are
  146. things like "thin, medium, thick" for the border-width property. The
  147. datatype is really a Length but it can be specified using these keywords
  148. whose actual value is determined by the "User Agent" rather than being
  149. specified in the XSL standard. For FOP, these values are currently
  150. defined in foproperties.xml. The keyword value is just a string, so it
  151. still needs to be parsed as described next.</p>
  152. <p>The Maker also checks to see if the property is an Enumerated type and
  153. then checks whether the value matches one of the specified enumeration
  154. values.</p>
  155. <p>Otherwise the Maker uses the property parser in the fo.expr package to
  156. evaluate the attribute value and return a Property object. The parser
  157. interprets the expression language and performs numeric operations and
  158. function call evaluations.</p>
  159. <p>If the returned Property value is of the correct type (specificed in
  160. foproperties.xml, where else?), the Maker returns it. Otherwise, it may
  161. be able to convert the returned type into the correct type.</p>
  162. <p>Some kinds of property values can't be fully resolved during FO tree
  163. building because they depend on layout information. This is the case of
  164. length values specified as percentages and of the special
  165. proportional-column-width(x) specification for table-column widths.
  166. These are stored as special kinds of Length objects which are evaluated
  167. during layout. Expressions involving "em" units which are relative to
  168. font-size _are_ resolved during the FO tree building however.</p>
  169. </section>
  170. <section id="property-list-struct">
  171. <title>Structure of the PropertyList</title>
  172. <p>The PropertyList extends HashMap and its basic function is to associate
  173. Property value objects with Property names. The Property objects are all
  174. subclasses of the base Property class. Each one simply contains a
  175. reference to one of the property datatype objects. Property provides
  176. accessors for all known datatypes and various subclasses override the
  177. accessor(s) which are reasonable for the datatype they store.</p>
  178. <p>The PropertyList itself provides various ways of looking up Property
  179. values to handle such issues as inheritance and corresponding
  180. properties.</p>
  181. <p>The main logic is:<br/>If the property is a writing-mode relative property (using start, end,
  182. before or after in its name), the corresponding absolute property value
  183. is returned if it's explicitly set on this FO. <br/>Otherwise, the
  184. writing-mode relative value is returned if it's explicitly set. If the
  185. property is inherited, the process repeats using the PropertyList of the
  186. FO's parent object. (This is easy because each PropertyList points to
  187. the PropertyList of the nearest ancestor FO.) If the property isn't
  188. inherited or no value is found at any level, the initial value is
  189. returned.</p>
  190. </section>
  191. <section id="property-spec">
  192. <title>Implementing Standard Properties</title>
  193. <p>Because the properties defined in the standard are basically static, FOP currently builds the source code for the related Property classes from an XML data file.
  194. All properties are specified in src/codegen/foproperties.xml.
  195. The related classes are created automatically during the build process by applying an XSLT stylesheet to the foproperties.xml file.</p>
  196. <section id="generic">
  197. <title>Generic properties</title>
  198. <p>In the properties xml files, one can define generic property
  199. definitions which can serve as a basis for individual property
  200. definitions. There are currently several generic properties defined in
  201. foproperties.xml. An example is GenericColor, which defines basic properties
  202. for all ColorType properties. Since the generic specification doesn't include
  203. the inherited or default elements, these should be set in each property
  204. which is based on GenericColor. Here is an example:</p>
  205. <p>
  206. <code>&lt;property type='generic'&gt;
  207. &lt;name&gt;background-color&lt;/name&gt;
  208. &lt;use-generic&gt;GenericColor&lt;/use-generic&gt;
  209. &lt;inherited&gt;false&lt;/inherited&gt;
  210. &lt;default&gt;transparent&lt;/default&gt;
  211. &lt;/property&gt;</code>
  212. </p>
  213. <p>A generic property specification can include all of the elements
  214. defined for the property element in the DTD, including the description
  215. of components for compound properties, and the specification of
  216. keyword shorthands.</p>
  217. <p>Generic property specifications can be based on other generic
  218. specifications.
  219. An example is GenericCondPadding template which is based on the
  220. GenericCondLength definition but which extends it by adding an inherited
  221. element and a default value for the length component.</p>
  222. <p>Generic properties can specify enumerated values, as in the
  223. GenericBorderStyle template. This means that the list of values, which
  224. is used by 8 properties (the "absolute" and "writing-mode-relative"
  225. variants for each BorderStyle property) is only specified one time.</p>
  226. <p>When a property includes a "use-generic" element and includes no other
  227. elements (except the "name" element), then no class is generated for the
  228. property. Instead the generated mapping will associate this
  229. property directly with an instance of the generic Maker.</p>
  230. <p>A generic class may also be hand-coded, rather than generated from the
  231. properties file.
  232. Properties based on such a generic class are indicated by the
  233. attribute <code>ispropclass='true'</code> on the
  234. <em>use-generic</em> element.</p>
  235. <p>This is illustrated by the SVG properties, most of
  236. which use one of the Property subclasses defined in the
  237. <em>org.apache.fop.svg</em>
  238. package. Although all of these properties are now declared in
  239. svgproperties.xml, no specific classes are generated. Classes are only
  240. generated for those SVG properties which are not based on generic
  241. classes defined in svg.</p>
  242. </section>
  243. <section id="element-specific">
  244. <title>Element-specific properties</title>
  245. <p>Properties may be defined for all flow objects or only for
  246. particular flow objects. A PropertyListBuilder object will always look
  247. first for a Property.Maker for the flow object before looking in the
  248. general list. These are specified in the
  249. <code>element-property-list</code> section of the properties.xml
  250. files. The <code>localname</code> element children of this element specify for
  251. which flow-object elements the property should be registered.</p>
  252. <p>
  253. <em>NOTE</em>: All the properties for an object or set of objects
  254. must be specified in a single element-property-list element. If the
  255. same localname appears in several element lists, the later set of
  256. properties will hide the earlier ones! Use the <em>ref</em>
  257. functionality if the same property is to be used in different sets of
  258. element-specific mappings.</p>
  259. </section>
  260. <section id="reference">
  261. <title>Reference properties</title>
  262. <p>A property element may have a type attribute with the value
  263. <code>ref</code>. The
  264. content of the <em>name</em> child element is the name of the referenced
  265. property (not its class-name!). This indicates that the property
  266. specification has
  267. already been given, either in this same specification file or in a
  268. different one (indicated by the <code>family</code> attribute). The
  269. value of the family attribute is <em>XX</em> where the file
  270. <em>XXproperties.xml</em> defines the referenced property. For
  271. example, some SVG objects may have properties defined for FO. Rather
  272. than defining them again with a new name, the SVG properties simply
  273. reference the defined FO properties. The generating mapping for the
  274. SVG properties will use the FO Maker classes.</p>
  275. </section>
  276. <section id="corresponding">
  277. <title>Corresponding properties</title>
  278. <p>Some properties have both <em>absolute</em> and
  279. <em>writing-mode-relative</em> forms. In general, the absolute forms
  280. are equivalent to CSS properties, and the writing-mode-relative forms
  281. are based on DSSSL. FO files may use either or both forms. In
  282. FOP code, a request for an absolute form will retrieve that value if it
  283. was specified on the FO; otherwise the corresponding relative property
  284. will be used if it was specified. However, a request for a relative
  285. form will only use the specified relative value if the corresponding
  286. absolute value was <em>not</em> specified for that FO.</p>
  287. <p>Corresponding properties are specified in the properties.xml files
  288. using the element <code>corresponding</code>, which has at least one
  289. <code>propval</code> child and may have a <code>propexpr</code> child,
  290. if the corresponding
  291. value is calculated based on several other properties, as for
  292. <code>start-indent</code>.</p>
  293. <p>
  294. <em>NOTE</em>: most current FOP code accesses the absolute variants
  295. of these properties, notably for padding, border, height and width
  296. attributes. However it does use start-indent and end-indent, rather
  297. than the "absolute" margin properties.</p>
  298. </section>
  299. </section>
  300. <section id="mapping">
  301. <title>Mapping</title>
  302. <p>The XSL script <code>propmap.xsl</code> is used to generate
  303. property mappings based on
  304. both foproperties.xml and svgproperties.xml. The mapping classes
  305. in the main fop packages simply load these automatically generated
  306. mappings. The mapping code still uses the static
  307. "maker" function of the generated object to obtain a Maker
  308. object. However, for all generated classes, this method returns an
  309. instance of the class itself (which is a subclass of Property.Maker)
  310. and not an instance of a separate nested Maker class.</p>
  311. <p>For most SVG properties which use the SVG Property classes directly,
  312. the generated mapper code calls the "maker" method of the SVG Property
  313. class, which returns an instance of its nested Maker class.</p>
  314. <p>The property generation also handles element-specific property
  315. mappings as specified in the properties XML files.</p>
  316. </section>
  317. <section id="enumerated">
  318. <title>Enumerated values</title>
  319. <p>For any property whose datatype is <code>Enum</code> or which
  320. contains possible enumerated values, FOP code may need to access
  321. enumeration constants. These are defined in the interfaces whose name
  322. is the same as the generated class name for the property,
  323. for example <code>BorderBeforeStyle.NONE</code>. These interface classes
  324. are generated by the XSL script <code>enumgen.xsl</code>. A separate
  325. interface defining the enumeration constants is always generated for
  326. every property which uses the constants, even if the constants
  327. themselves are defined in a generic class, as in BorderStyle.</p>
  328. <p>If a subproperty or component of a compound property has enumerated
  329. values, the constants are defined in a nested interface whose name is
  330. the name of the subproperty (using appropriate capitalization
  331. rules). For example,
  332. the keep properties may have values of AUTO or FORCE or an integer
  333. value. These are defined for each kind of keep property. For example,
  334. the keep-together property is a compound property with the components
  335. within-line, within-column and within-page. Since each component may
  336. have the values AUTO or FORCE, the KeepTogether interface defines
  337. three nested interfaces, one for each component, and each defines
  338. these two constants. An example of a reference in code to the constant
  339. is <code>KeepTogether.WithinPage.AUTO</code>.</p>
  340. </section>
  341. <section id="compound">
  342. <title>Compound property types</title>
  343. <p>Some XSL FO properties are specified by compound datatypes. In the FO file,
  344. these are defined by a group of attributes, each having a name of the
  345. form <code>property.component</code>, for example
  346. <code>space-before.minimum</code>. These are several compound
  347. datatypes:</p>
  348. <ul>
  349. <li>LengthConditional, with components length and conditionality</li>
  350. <li>LengthRange, with components minimum, optimum, and maximum</li>
  351. <li>Space, with components minimum, optimum, maximum, precedence and
  352. conditionality </li>
  353. <li>Keep, with components within-line, within-column and within-page</li>
  354. </ul>
  355. <p>These are described in the properties.xml files using the element
  356. <code>compound</code> which has <code>subproperty</code> children. A subproperty element is much
  357. like a property element, although it may not have an <code>inherited</code> child
  358. element, as only a complete property object may be inherited.</p>
  359. <p>Specific datatype classes exist for each compound property. Each
  360. component of a compound datatype is itself stored as a Property
  361. object. Individual components may be accessed either by directly
  362. performing a get operation on the name, using the "dot" notation,
  363. eg. <code>get("space-before.optimum")</code>; or by using an accessor on the compound
  364. property, eg. <code>get("space-before").getOptimum()</code>.
  365. In either case,
  366. the result is a Property object, and the actual value may be accessed
  367. (in this example) by using the "getLength()" accessor.</p>
  368. </section>
  369. <section id="refine">
  370. <title>Refinement</title>
  371. <p>The <strong>Refinement</strong> step is part of reading and using the properties which may happen immediately or during the layout process. FOP does not currently use a separate Refinement process, but tends to handle refining steps as the FO Tree is built.</p>
  372. </section>
  373. <section id="refined-fo-tree">
  374. <title>Refined FO Tree</title>
  375. <p>The Refined FO Tree is the result of the Refinement process.</p>
  376. </section>
  377. </body>
  378. </document>