new->ref_cnt = 1;
for (int i = 0; i < 2; i++)
page_heading_copy (&new->headings[i], &old->headings[i]);
- if (old->font)
- new->font = pango_font_description_copy (old->font);
return new;
}
{
for (int i = 0; i < 2; i++)
page_heading_uninit (&ps->headings[i]);
- if (ps->font)
- pango_font_description_free (ps->font);
free (ps);
}
}
}
-static bool
-pfd_equals (const PangoFontDescription *a,
- const PangoFontDescription *b)
-{
- return a && b ? pango_font_description_equal (a, b) : !a && !b;
-}
-
bool
xr_page_style_equals (const struct xr_page_style *a,
const struct xr_page_style *b)
{
for (int i = 0; i < TABLE_N_AXES; i++)
- {
- if (a->size[i] != b->size[i])
+ for (int j = 0; j < 2; j++)
+ if (a->margins[i][j] != b->margins[i][j])
return false;
- for (int j = 0; j < 2; j++)
- if (a->margins[i][j] != b->margins[i][j])
- return false;
- }
-
for (int i = 0; i < 2; i++)
if (!page_heading_equals (&a->headings[i], &b->headings[i]))
return false;
- return (pfd_equals (a->font, b->font)
- && a->font_scale == b->font_scale
- && a->initial_page_number == b->initial_page_number
+ return (a->initial_page_number == b->initial_page_number
&& a->object_spacing == b->object_spacing);
}
\f
struct xr_pager
{
struct xr_page_style *page_style;
+ struct xr_fsm_style *fsm_style;
int page_index;
int heading_heights[2];
/* Current output item. */
struct xr_fsm *fsm;
- struct xr_fsm_style *fsm_style;
struct output_item *item;
/* Current output page. */
}
static void
-xr_measure_headings (const struct xr_page_style *ps, int heading_heights[2])
+xr_measure_headings (const struct xr_page_style *ps,
+ const struct xr_fsm_style *fs,
+ int heading_heights[2])
{
cairo_surface_t *surface = cairo_recording_surface_create (
CAIRO_CONTENT_COLOR, NULL);
for (int i = 0; i < 2; i++)
{
int *h = &heading_heights[i];
- *h = xr_render_page_heading (cairo, ps->font, &ps->headings[i], -1,
- ps->size[H], false, 0);
+ *h = xr_render_page_heading (cairo, fs->fonts[XR_FONT_PROPORTIONAL],
+ &ps->headings[i], -1, fs->size[H], false,
+ 0);
if (*h)
*h += ps->object_spacing;
}
}
struct xr_pager *
-xr_pager_create (const struct xr_page_style *ps_)
+xr_pager_create (const struct xr_page_style *ps_,
+ const struct xr_fsm_style *fs_)
{
+ printf ("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
struct xr_page_style *ps = xr_page_style_ref (ps_);
+ struct xr_fsm_style *fs = xr_fsm_style_ref (fs_);
int heading_heights[2];
- xr_measure_headings (ps, heading_heights);
+ xr_measure_headings (ps, fs, heading_heights);
int total = heading_heights[0] + heading_heights[1];
- if (total > 0 && total < ps->size[V])
+ if (total > 0 && total < fs->size[V])
{
+ fs = xr_fsm_style_unshare (fs);
ps = xr_page_style_unshare (ps);
for (int i = 0; i < 2; i++)
ps->margins[V][i] += heading_heights[i];
- ps->size[V] -= total;
+ fs->size[V] -= total;
}
struct xr_pager *p = xmalloc (sizeof *p);
- *p = (struct xr_pager) { .page_style = ps };
+ *p = (struct xr_pager) { .page_style = ps, .fsm_style = fs };
return p;
}
{
if (p)
{
- xr_fsm_destroy (p->fsm);
+ printf (">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+ xr_page_style_unref (p->page_style);
xr_fsm_style_unref (p->fsm_style);
+
+ xr_fsm_destroy (p->fsm);
output_item_unref (p->item);
- xr_page_style_unref (p->page_style);
if (p->cr)
- cairo_destroy (p->cr);
+ {
+ cairo_restore (p->cr);
+ cairo_destroy (p->cr);
+ }
free (p);
}
}
}
void
-xr_pager_add_item (struct xr_pager *p, const struct xr_fsm_style *fsm_style,
- const struct output_item *item)
+xr_pager_add_item (struct xr_pager *p, const struct output_item *item)
{
+ printf ("add_item\n");
assert (!p->item);
p->item = output_item_ref (item);
- p->fsm_style = xr_fsm_style_ref (fsm_style);
xr_pager_run (p);
}
void
xr_pager_add_page (struct xr_pager *p, cairo_t *cr)
{
+ printf ("add_page\n");
assert (!p->cr);
+ cairo_save (cr);
p->cr = cr;
p->y = 0;
+ const struct xr_fsm_style *fs = p->fsm_style;
const struct xr_page_style *ps = p->page_style;
const struct cell_color *bg = &ps->bg;
if (bg->alpha)
cairo_save (cr);
cairo_set_source_rgba (cr, bg->r / 255.0, bg->g / 255.0,
bg->b / 255.0, bg->alpha / 255.0);
- cairo_rectangle (cr, 0, 0, ps->size[H], ps->size[V]);
+ cairo_rectangle (cr, 0, 0, fs->size[H], fs->size[V]);
cairo_fill (cr);
cairo_restore (cr);
}
xr_to_pt (ps->margins[H][0]),
xr_to_pt (ps->margins[V][0]));
+ const PangoFontDescription *font = fs->fonts[XR_FONT_PROPORTIONAL];
int page_number = p->page_index++ + ps->initial_page_number;
if (p->heading_heights[0])
- xr_render_page_heading (cr, ps->font, &ps->headings[0], page_number,
- ps->size[H], true, -p->heading_heights[0]);
+ xr_render_page_heading (cr, font, &ps->headings[0], page_number,
+ fs->size[H], true, -p->heading_heights[0]);
if (p->heading_heights[1])
- xr_render_page_heading (cr, ps->font, &ps->headings[1], page_number,
- ps->size[H], true,
- ps->size[V] + ps->object_spacing);
+ xr_render_page_heading (cr, font, &ps->headings[1], page_number,
+ fs->size[H], true,
+ fs->size[V] + ps->object_spacing);
xr_pager_run (p);
}
bool
xr_pager_needs_new_page (struct xr_pager *p)
{
- if (p->item && p->y >= p->page_style->size[V])
+ if (p->item && (!p->cr || p->y >= p->fsm_style->size[V]))
{
- cairo_destroy (p->cr);
- p->cr = NULL;
+ if (p->cr)
+ {
+ cairo_restore (p->cr);
+ cairo_destroy (p->cr);
+ p->cr = NULL;
+ }
return true;
}
else
static void
xr_pager_run (struct xr_pager *p)
{
- if (p->item && p->cr && p->y < p->page_style->size[V])
+ printf ("run:\n");
+ if (p->item && p->cr && p->y < p->fsm_style->size[V])
{
if (!p->fsm)
{
- /* XXX fsm_style needs to account for heading_heights */
+ printf ("\tcreate fsm\n");
p->fsm = xr_fsm_create (p->item, p->fsm_style, p->cr);
if (!p->fsm)
{
- xr_fsm_style_unref (p->fsm_style);
- p->fsm_style = NULL;
+ printf ("\t(was null)\n");
output_item_unref (p->item);
p->item = NULL;
for (;;)
{
+ printf ("\tdraw slice\n");
int spacing = p->page_style->object_spacing;
int chunk = xr_fsm_draw_slice (p->fsm, p->cr,
- p->page_style->size[V] - p->y);
+ p->fsm_style->size[V] - p->y);
p->y += chunk + spacing;
cairo_translate (p->cr, 0, xr_to_pt (chunk + spacing));
if (xr_fsm_is_empty (p->fsm))
{
+ printf ("\tfinished object\n");
xr_fsm_destroy (p->fsm);
p->fsm = NULL;
- xr_fsm_style_unref (p->fsm_style);
- p->fsm_style = NULL;
output_item_unref (p->item);
p->item = NULL;
return;
}
else if (!chunk)
{
+ printf ("\tobject doesn't fit on page\n");
assert (p->y > 0);
p->y = INT_MAX;
return;
}
+ printf ("\tneed to draw another slice\n");
}
}
+ if (!p->item)
+ printf ("\tno item\n");
+ if (!p->cr)
+ printf ("\tno page\n");
}