+ <property name="path" type="string" default='""'>
+ A box's [[path]] consists of zero or more contours, each of
+ which consists of one or more lines, bezier curves (cubic or
+ quadradic), or generalized elliptic arcs. The grammar and
+ feature set supported are identical to that specified in <link
+ url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
+ section 8"/>.
+
+ One of the most common sources of frustration when working with
+ text representations of vector paths, or programs that manipulate
+ them, is making a mistake when setting a transform which causes
+ the entire path to be off the screen. Since no part of the path
+ is visible, you have no idea which direction it went! To minimize
+ the chance of this happening, and generally make dealing with
+ vectors a more enjoyable experience, Ibex always **recenters** a
+ path. When you set a box's path (either by writing to its
+ [[path]] or [[text]] properties), Ibex translates the entire path
+ so that it is lined up with the X and Y axes, as close to the
+ origin as possible, in the positive-X, positive-Y quadrant. Ibex
+ will note this translation by setting the box's [[transform]] to
+ the transformation used to do this. If you do not desire this
+ behavior, just set the [[transform]] back to the identity
+ transform.
+ </property>
+
+ <property name="stroke" type="string" default="clear">
+ The color with which to stroke the path. Ibex paths may
+ only be stroked with a single color, solid line (not
+ dashed), of "hairline width" (meaning that the line is never more than one
+ antialiased pixel wide no matter what magnification it is
+ viewed at).
+
+ This property can be set to a 5-character hex string
+ ([[#RGB]]), 7-character hex string ([[#RRGGBB]]),
+ 9-character hex string ([[#AARRGGBB]]), specifying the box's
+ hexadecimal color. Any other string is compared against the
+ <link url="http://www.color.org/ICC-1A_1999-04.PDF"
+ text="ICC"/> colors (the same set of color names supported
+ by SVG). If this property is set to [[null]], the stroke
+ color will be set to clear ([[#00000000]]).
+
+ Other vector formats (notably SVG and PDF) support "thick"
+ lines, dashed lines, lines stroked with a gradient or
+ texture, and an assortment of special caps and joins for
+ these thick lines (hairline lines do not need joins or
+ caps). Fortunately, all of these constructs can be
+ converted into **filled** paths rather easily, making it
+ possible for Ibex to support the same functionality with a
+ much simpler API (and more efficient rendering engine).
+ </property>
+
+ <property name="fill">
+ The graphic element with which to fill the path. This
+ property can be set to any of the values specified for
+ [[stroke]], as well as to a texture (an image) or a
+ gradient. Paths which self-intersect are filled according
+ to the SVG guidelines.
+
+ When an image (texture) is written to this property, the
+ box's [[minwidth]] and [[minheight]] properties will be
+ automatically set to the dimensions of the image (they can
+ be changed later if desired).
+ </property>
+ </section>
+
+ <section title="Text">
+
+ Ibex treats text exactly the same way it treats other paths.
+ Writing to the [[text]] property actually sets the box's path to
+ the outline of the rendered form of the text, and text is
+ subject to the same rotation, shearing, and scaling
+ transformations as all other boxes. You can even **read back**
+ the curves from which the text is composed by reading from the
+ [[path]] property (the string returned will be in SVG Path
+ syntax), modify it, and write it to the [[path]] property of
+ another box.
+
+ <property name="text" type="string" default='""'>
+ The box's text; writing [[null]] to this property sets it to
+ [[""]]. In order to help eliminate common chores when working
+ with text, Ibex will automatically take the following actions
+ when you write to the [[text]] property:
+ </property>
+
+ <list>
+ The text is converted to curves using the Freetype library,
+ and the resulting curve becomes the box's path.
+
+ If the box's [[strokecolor]] is [[null]], it is set to black
+ ([[#FF000000]]). When first created, a box has an invisible
+ stroke; automatically setting the stroke to a visible color
+ helps eliminate confusing errors. You can change the stroke
+ color back to clear after writing to the [[text]] property.
+
+ The box's [[aspect]] property is automatically set to the
+ correct aspect ratio for the chosen string in the chosen
+ font. This ensures that resizing will not warp the text.
+ </list>
+
+ <property name="font" type="stream" default=".ibex.ui.font.sansserif">
+ Fonts are rendered using the [[stroke]] assigned to the box,
+ using the font assigned to the [[font]] property. When an
+ object is written to this property, it is coerced to a stream which is interpreted using
+ the <link url="http://www.freetype.org" text="FreeType 2
+ library"/>, and the resulting font is used to render the box's
+ [[text]].
+
+ To choose the size of a font, just set the box's [[height]]
+ property to the desired height **in pixels**. Conversion
+ functions from points to pixels are available.
+ </property>
+ </section>
+
+ <section title="Transformations">
+ The [[transform]] property allows the user to specify an
+ arbitrary affine transformation to be applied to the box's path,
+ text, and children. The syntax and features supported are
+ identical to those described in <link
+ url="http://www.w3.org/TR/SVG11/coords.html" text="SVG 1.1,
+ section 7"/>, and include rotation, shearing, scaling, and
+ translation.
+
+ <property name="transform">
+ FIXME
+ </property>
+
+ One tricky part about transformations is their interaction with
+ box packing and dimension properties. A box's size properties
+ (such as [[minwidth]] or [[height]]) are **always** measured in
+ the box's own coordinate space (ie after applying the box's
+ [[transform]]). This means that the sum of the [[width]]s of a
+ box's children may not be equal to the parent box's [[width]],
+ even if the children appear (on screen) to completely fill its
+ width.
+
+ One other consequence of combining transformations with
+ constraint-based layout is that when a box is rotated, its width
+ and height are no longer completely independent (remember, the
+ box's width is measured in the rotated coordinate space). If a
+ box is turned at a 45 degree angle and then forced into a space
+ 10 pixels wide, enlarging the box's width will force a reduction
+ in its height (in order to cram it in the 10 pixel space). In
+ situations like this, Ibex will first look to the box's
+ [[aspect]], if explicitly set, and obey that. If the box's
+ [[aspect]] is unspecified, Ibex will use the ratio between the
+ box's [[minwidth]] and [[minheight]] to guide the tradeoff. If
+ either of these properties is [[0]], Ibex will simply attempt to
+ make the ratio as close to [[1:1]] as possible.
+
+ When we talk about a box's **bounding box**, we are referring to
+ the smallest rectangle in the **parent's** coordinate space
+ which completely encloses the child box's path. This is the
+ only time we will deal with the size of a child using a
+ coordinate space other than its own.
+ </section>
+
+ <section title="Layout Properties">
+
+ We will cover the layout algorithm in detail in the next section,
+ but we introduce the properties at play here and give an intuition
+ about their purpose.
+
+ <property name="packed" type="boolean" default="true">
+ The layout strategy for this box. If set to [[true]], the
+ box occupies no cells and is laid out independently of its
+ siblings.
+ </property>
+
+ <property name="zoom" type="boolean" default="false">
+ This property controls the strategy Ibex uses for changing the
+ box's width and height in response to layout constraints.
+
+ If [[zoom]] is set to [[false]] (the default), then the box's
+ [[path]] will be altered by multiplying all the vertices by a
+ scaling factor in order to make the path's bounding box meet
+ the required constraints. The box's [[transform]] will not be
+ affected, and the scaling of the box's children will not be
+ affected.
+
+ If [[zoom]] is set to [[true]], the box's [[path]] will not be
+ altered in response to layout constraints; rather, its
+ [[transform]] will be altered in order to "zoom in" or "zoom
+ out" and bring all of the path's vertices within the desired
+ region. Since the box's [[transform]] also applies to its
+ descendants, they too will be magnified or reduced.
+ </property>
+
+ <property name="shrink" type="boolean" default="false">
+ If set to [[true]], this box will shrink
+ (horizontally/vertically/both) to the smallest size allowed by
+ its children and the bounding box of its path.
+ </property>
+
+ <property name="x y" type="integer" default="varies">
+ If the box is a root box, writing to these properties moves
+ the surface; reading from them returns the position of the
+ surface.
+
+ On non-root boxes, writing to these properties is a shorthand
+ for adding a [["translate(x, y)"]] to the box's [[transform]].
+ Reading from these properties will return FIXME.
+ </property>
+
+ <property name="minwidth minheight" type="integer" default="0">
+ The desired minimum width and height. See the [[zoom]]
+ property for a description of how the box is altered to meet
+ these constraints.
+ </property>
+
+ <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
+ The desired maximum width and height. See the [[zoom]]
+ property for a description of how the box is altered to meet
+ these constraints.
+ </property>
+
+ <property name="width height" type="integer">
+ When read, this is the current (width/height) of this box.
+ Writing to this property is equivalent to writing to
+ **both** the minimum and maximum (width/height).
+ </property>
+
+ <property name="cols rows" type="integer" default="0">
+ The number of (columns/rows) in which to lay out the children of this
+ box. If set to zero, the number of (columns/rows) is unconstrained.
+ Either [[rows]] or [[cols]] must be zero. If
+ [[0]] is written to [[cols]] when [[rows]] is
+ [[0]], the write is ignored. If a nonzero value is
+ written to [[cols]] when [[rows]] is nonzero,
+ [[rows]] is set to [[0]], and vice versa.
+ </property>
+
+ <property name="colspan rowspan" type="integer" default="1">
+ The number of (columns/rows) that this box spans within its parent.
+ </property>
+
+ <property name="aspect" type="float" default="0.0">
+ The width-to-height ratio constraint for this box; can be set
+ either as a floating point number ([[0.5]]) or a ratio
+ ([["1:2"]]). Setting this to [[0.0]] disables the ratio
+ constraint.
+
+ Note packed boxes always **shrink** in order to satisfy aspect
+ constraints, while unpacked boxes always **grow** in order to
+ satisfy them -- even if this means growing larger than the box's
+ parent.
+ </property>
+
+ <property name="visible" type="boolean" default="true">
+ If set to [[false]], this box will be rendered as if its
+ width and height were zero. If this is a root box, the
+ associated surface will be hidden.
+
+ When reading from this property, the value [[false]] will
+ be returned if this box **or any of its ancestors** is not
+ visible. Thus it is possible to write [[true]] to a box's
+ [[visible]] property and then read back [[false]].
+ </property>
+ </section>
+
+</section>