X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fcairo-fsm.c;h=2df39754343b966b3305c6a7393b17a3c9989625;hb=d55fbbb4fda554d02c93dd46c6fa66128060e6f0;hp=1671edac4f512f93095d0071cfc48f4a64521ae5;hpb=7e8c8917a83cb0e7e48d5af2f3886e0a5256adb5;p=pspp diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index 1671edac4f..2df3975434 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -38,6 +38,7 @@ #include "output/charts/scree.h" #include "output/charts/spreadlevel-plot.h" #include "output/group-item.h" +#include "output/image-item.h" #include "output/message-item.h" #include "output/page-eject-item.h" #include "output/page-setup-item.h" @@ -760,14 +761,17 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, } size_t footnote_ofs = ds_length (&body); + size_t n_footnotes = 0; for (size_t i = 0; i < value->n_footnotes; i++) { - if (i) - ds_put_byte (&body, ','); - - size_t idx = value->footnote_indexes[i]; - const struct pivot_footnote *f = pt->footnotes[idx]; - pivot_value_format (f->marker, pt, &body); + const struct pivot_footnote *f + = pt->footnotes[value->footnote_indexes[i]]; + if (f->show) + { + if (n_footnotes++) + ds_put_byte (&body, ','); + pivot_footnote_format_marker (f, pt, &body); + } } /* Allow footnote markers to occupy the right margin. That way, numbers @@ -811,8 +815,11 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, add_attr (attrs, pango_attr_rise_new (-3000), subscript_ofs, footnote_ofs - subscript_ofs); if (value->n_footnotes) - add_attr (attrs, pango_attr_rise_new (3000), footnote_ofs, - PANGO_ATTR_INDEX_TO_TEXT_END); + { + bool superscript = pt->look->footnote_marker_superscripts; + add_attr (attrs, pango_attr_rise_new (superscript ? 3000 : -3000), + footnote_ofs, PANGO_ATTR_INDEX_TO_TEXT_END); + } } /* Set the attributes, if any. */ @@ -987,6 +994,7 @@ xr_fsm_create (const struct output_item *item_, struct output_item *item; if (is_table_item (item_) || is_chart_item (item_) + || is_image_item (item_) || is_page_eject_item (item_)) item = output_item_ref (item_); else if (is_message_item (item_)) @@ -1017,6 +1025,7 @@ xr_fsm_create (const struct output_item *item_, NOT_REACHED (); assert (is_table_item (item) || is_chart_item (item) + || is_image_item (item) || is_page_eject_item (item)); size_t *layer_indexes = NULL; @@ -1147,6 +1156,12 @@ xr_fsm_measure (struct xr_fsm *fsm, cairo_t *cr, int *wp, int *hp) w = CHART_WIDTH; h = CHART_HEIGHT; } + else if (is_image_item (fsm->item)) + { + cairo_surface_t *image = to_image_item (fsm->item)->image; + w = cairo_image_surface_get_width (image); + h = cairo_image_surface_get_height (image); + } else NOT_REACHED (); @@ -1171,6 +1186,18 @@ mul_XR_POINT (int x) : x * XR_POINT); } +static void +draw_image (cairo_surface_t *image, cairo_t *cr) +{ + cairo_save (cr); + cairo_set_source_surface (cr, image, 0, 0); + cairo_rectangle (cr, 0, 0, cairo_image_surface_get_width (image), + cairo_image_surface_get_height (image)); + cairo_clip (cr); + cairo_paint (cr); + cairo_restore (cr); +} + void xr_fsm_draw_region (struct xr_fsm *fsm, cairo_t *cr, int x, int y, int w, int h) @@ -1183,6 +1210,8 @@ xr_fsm_draw_region (struct xr_fsm *fsm, cairo_t *cr, mul_XR_POINT (w), mul_XR_POINT (h)); fsm->cairo = NULL; } + else if (is_image_item (fsm->item)) + draw_image (to_image_item (fsm->item)->image, cr); else if (is_chart_item (fsm->item)) xr_draw_chart (to_chart_item (fsm->item), cr, CHART_WIDTH, CHART_HEIGHT); else if (is_page_eject_item (fsm->item)) @@ -1237,6 +1266,49 @@ xr_fsm_draw_chart (struct xr_fsm *fsm, int space) return chart_height; } +static int +xr_fsm_draw_image (struct xr_fsm *fsm, int space) +{ + cairo_surface_t *image = to_image_item (fsm->item)->image; + int width = cairo_image_surface_get_width (image) * XR_POINT; + int height = cairo_image_surface_get_height (image) * XR_POINT; + if (!width || !height) + goto error; + + if (height > fsm->rp.size[V]) + { + double scale = fsm->rp.size[V] / (double) height; + width *= scale; + height *= scale; + if (!width || !height) + goto error; + + cairo_scale (fsm->cairo, scale, scale); + } + + if (width > fsm->rp.size[H]) + { + double scale = fsm->rp.size[H] / (double) width; + width *= scale; + height *= scale; + if (!width || !height) + goto error; + + cairo_scale (fsm->cairo, scale, scale); + } + + if (space < height) + return 0; + + draw_image (image, fsm->cairo); + fsm->done = true; + return height; + +error: + fsm->done = true; + return 0; +} + static int xr_fsm_draw_eject (struct xr_fsm *fsm, int space) { @@ -1257,6 +1329,7 @@ xr_fsm_draw_slice (struct xr_fsm *fsm, cairo_t *cr, int space) fsm->cairo = cr; int used = (is_table_item (fsm->item) ? xr_fsm_draw_table (fsm, space) : is_chart_item (fsm->item) ? xr_fsm_draw_chart (fsm, space) + : is_image_item (fsm->item) ? xr_fsm_draw_image (fsm, space) : is_page_eject_item (fsm->item) ? xr_fsm_draw_eject (fsm, space) : (abort (), 0)); fsm->cairo = NULL;