+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii), rest;
+ int maxph = 0, maxpw = 0, nitems = 0, ph_adjust = 0;
+
+ /* Flip through the items to work out how much stuff we have to display */
+ LIST_LOOP (rest, items)
+ {
+ Lisp_Object glyph = XCAR (rest);
+ unsigned int gheight, gwidth;
+
+ image_instance_query_geometry (glyph, &gwidth, &gheight, disp, domain);
+
+ /* Pick up the border text if we have one. */
+ if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
+ && NILP (XCDR (rest)))
+ {
+ ph_adjust = gheight / 2;
+ }
+ else
+ {
+
+ nitems ++;
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_HORIZONTAL)
+ {
+ maxph = max (maxph, gheight);
+ maxpw += gwidth;
+ }
+ else
+ {
+ maxpw = max (maxpw, gwidth);
+ maxph += gheight;
+ }
+ }
+ }
+
+ /* work out spacing between items and bounds of the layout. No user
+ provided width so we just do default spacing. */
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_HORIZONTAL)
+ *width = maxpw + (nitems + 1) * WIDGET_BORDER_WIDTH * 2;
+ else
+ *width = maxpw + 2 * WIDGET_BORDER_WIDTH * 2;
+
+ /* Work out vertical spacings. */
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_VERTICAL)
+ *height = maxph + (nitems + 1) * WIDGET_BORDER_HEIGHT * 2 + ph_adjust;
+ else
+ *height = maxph + 2 * WIDGET_BORDER_HEIGHT * 2 + ph_adjust;
+}
+
+
+static void
+layout_layout (Lisp_Object image_instance,
+ unsigned int width, unsigned int height, Lisp_Object domain)
+{
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object rest;
+ Lisp_Object items = IMAGE_INSTANCE_LAYOUT_CHILDREN (ii);
+ int x, y, maxph = 0, maxpw = 0, nitems = 0,
+ horiz_spacing, vert_spacing, ph_adjust = 0;
+ unsigned int gheight, gwidth;
+
+ /* flip through the items to work out how much stuff we have to display */
+ LIST_LOOP (rest, items)
+ {
+ Lisp_Object glyph = XCAR (rest);
+
+ image_instance_query_geometry (glyph, &gwidth, &gheight,
+ IMAGE_DESIRED_GEOMETRY, domain);
+
+ /* Pick up the border text if we have one. */
+ if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
+ && NILP (XCDR (rest)))
+ {
+ XIMAGE_INSTANCE_XOFFSET (glyph) = 10; /* Really, what should this be? */
+ XIMAGE_INSTANCE_YOFFSET (glyph) = 0;
+ ph_adjust = gheight / 2;
+ IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust);
+ }
+ else
+ {
+ nitems ++;
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_HORIZONTAL)
+ {
+ maxph = max (maxph, gheight);
+ maxpw += gwidth;
+ }
+ else
+ {
+ maxpw = max (maxpw, gwidth);
+ maxph += gheight;
+ }
+ }
+ }
+
+ /* work out spacing between items and bounds of the layout */
+ if (width < maxpw)
+ /* The user wants a smaller space than the largest item, so we
+ just provide default spacing and will let the output routines
+ clip.. */
+ horiz_spacing = WIDGET_BORDER_WIDTH * 2;
+ else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_HORIZONTAL)
+ /* We have a larger area to display in so distribute the space
+ evenly. */
+ horiz_spacing = (width - maxpw) / (nitems + 1);
+ else
+ horiz_spacing = (width - maxpw) / 2;
+
+ if (height < maxph)
+ vert_spacing = WIDGET_BORDER_HEIGHT * 2;
+ else if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_VERTICAL)
+ vert_spacing = (height - (maxph + ph_adjust)) / (nitems + 1);
+ else
+ vert_spacing = (height - (maxph + ph_adjust)) / 2;
+
+ y = vert_spacing + ph_adjust;
+ x = horiz_spacing;
+
+ /* Now flip through putting items where we want them, paying
+ attention to justification. Make sure we don't mess with the
+ border glyph. */
+ LIST_LOOP (rest, items)
+ {
+ Lisp_Object glyph = XCAR (rest);
+
+ image_instance_query_geometry (glyph, &gwidth, &gheight,
+ IMAGE_DESIRED_GEOMETRY, domain);
+
+ if (!INTP (IMAGE_INSTANCE_LAYOUT_BORDER (ii))
+ || !NILP (XCDR (rest)))
+ {
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_HORIZONTAL)
+ {
+ if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
+ == LAYOUT_JUSTIFY_RIGHT)
+ y = height - (gheight + vert_spacing);
+ if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
+ == LAYOUT_JUSTIFY_CENTER)
+ y = (height - gheight) / 2;
+ }
+ else
+ {
+ if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
+ == LAYOUT_JUSTIFY_RIGHT)
+ x = width - (gwidth + horiz_spacing);
+ if (IMAGE_INSTANCE_SUBWINDOW_JUSTIFY (ii)
+ == LAYOUT_JUSTIFY_CENTER)
+ x = (width - gwidth) / 2;
+ }
+
+ XIMAGE_INSTANCE_XOFFSET (glyph) = x;
+ XIMAGE_INSTANCE_YOFFSET (glyph) = y;
+
+ if (IMAGE_INSTANCE_SUBWINDOW_ORIENT (ii)
+ == LAYOUT_HORIZONTAL)
+ {
+ x += (gwidth + horiz_spacing);
+ }
+ else
+ {
+ y += (gheight + vert_spacing);
+ }
+ }
+
+ /* Now layout subwidgets if they require it. */
+ image_instance_layout (glyph, gwidth, gheight, domain);
+ }