X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fspv%2Fspv-writer.c;h=bb37a05e24b103ab86be47f9e766e2a39e98fe7d;hb=3537319aa75f28056beaf85901f1716eb291d739;hp=03a415146d795b0a95decfd868042641a9cc6ead;hpb=4a2dcede63a2fc6423301245b2e65c4b5f1aabbe;p=pspp diff --git a/src/output/spv/spv-writer.c b/src/output/spv/spv-writer.c index 03a415146d..bb37a05e24 100644 --- a/src/output/spv/spv-writer.c +++ b/src/output/spv/spv-writer.c @@ -34,15 +34,10 @@ #include "libpspp/version.h" #include "libpspp/zip-writer.h" #include "output/cairo-chart.h" -#include "output/chart-item.h" #include "output/driver.h" -#include "output/group-item.h" -#include "output/image-item.h" -#include "output/page-eject-item.h" -#include "output/page-setup-item.h" +#include "output/output-item.h" +#include "output/page-setup.h" #include "output/pivot-table.h" -#include "output/table-item.h" -#include "output/text-item.h" #include "gl/xalloc.h" #include "gl/xvasprintf.h" @@ -199,8 +194,9 @@ spv_writer_open_file (struct spv_writer *w) time_t t = time (NULL); struct tm *tm = gmtime (&t); - char *tm_s = asctime (tm); - write_attr (w, "creation-date-time", tm_s); + char tm_s[128]; + if (strftime (tm_s, sizeof tm_s, "%x %X", tm)) + write_attr (w, "creation-date-time", tm_s); write_attr (w, "creator", version); @@ -227,8 +223,7 @@ spv_writer_open_file (struct spv_writer *w) } static void -spv_writer_open_heading (struct spv_writer *w, const char *command_id, - const char *label) +spv_writer_open_heading (struct spv_writer *w, const struct output_item *item) { if (!w->heading) { @@ -238,12 +233,15 @@ spv_writer_open_heading (struct spv_writer *w, const char *command_id, w->heading_depth++; start_elem (w, "heading"); - write_attr (w, "commandName", command_id); + if (item->command_name) + write_attr (w, "commandName", item->command_name); + if (!item->show) + write_attr (w, "visibility", "collapsed"); /* XXX locale */ /* XXX olang */ start_elem (w, "label"); - write_text (w, label); + write_text (w, output_item_get_label (item)); end_elem (w); } @@ -281,10 +279,11 @@ spv_writer_close_heading (struct spv_writer *w) } static void -start_container (struct spv_writer *w, const struct output_item *item) +open_container (struct spv_writer *w, const struct output_item *item, + const char *inner_elem) { start_elem (w, "container"); - write_attr (w, "visibility", "visible"); + write_attr (w, "visibility", item->show ? "visible" : "hidden"); if (w->need_page_break) { write_attr (w, "page-break-before", "always"); @@ -294,33 +293,44 @@ start_container (struct spv_writer *w, const struct output_item *item) start_elem (w, "label"); write_text (w, output_item_get_label (item)); end_elem (w); + + start_elem (w, inner_elem); + if (item->command_name) + write_attr (w, "commandName", item->command_name); +} + +static void +close_container (struct spv_writer *w) +{ + end_elem (w); + end_elem (w); } static void -spv_writer_put_text (struct spv_writer *w, const struct text_item *text, - const char *command_id) +spv_writer_put_text (struct spv_writer *w, struct output_item *item) { bool initial_depth = w->heading_depth; if (!initial_depth) spv_writer_open_file (w); - start_container (w, &text->output_item); - - start_elem (w, "vtx:text"); - write_attr (w, "type", (text->type == TEXT_ITEM_TITLE ? "title" - : text->type == TEXT_ITEM_PAGE_TITLE ? "page-title" - : "log")); - if (command_id) - write_attr (w, "commandName", command_id); + open_container (w, item, "vtx:text"); + write_attr (w, "type", + (item->text.subtype == TEXT_ITEM_TITLE ? "title" + : item->text.subtype == TEXT_ITEM_PAGE_TITLE ? "page-title" + : "log")); start_elem (w, "html"); - write_text (w, text->text); /* XXX */ - end_elem (w); /* html */ - end_elem (w); /* vtx:text */ - end_elem (w); /* container */ + char *s = text_item_get_plain_text (item); + write_text (w, s); + free (s); + end_elem (w); + + close_container (w); if (!initial_depth) spv_writer_close_file (w, ""); + + output_item_unref (item); } static cairo_status_t @@ -342,13 +352,10 @@ spv_writer_put_image (struct spv_writer *w, const struct output_item *item, char *uri = xasprintf ("%010d_Imagegeneric.png", ++w->n_tables); - start_container (w, item); - - start_elem (w, "object"); + open_container (w, item, "object"); write_attr (w, "type", "unknown"); write_attr (w, "uri", uri); - end_elem (w); /* object */ - end_elem (w); /* container */ + close_container (w); if (!initial_depth) spv_writer_close_file (w, ""); @@ -551,20 +558,25 @@ static void put_value_mod (struct buf *buf, const struct pivot_value *value, const char *template) { - if (value->n_footnotes || value->n_subscripts - || template || value->font_style || value->cell_style) + if ((value->ex + && (value->ex->n_footnotes + || value->ex->n_subscripts + || value->ex->font_style + || value->ex->cell_style)) + || template) { + const struct pivot_value_ex *ex = pivot_value_ex (value); put_byte (buf, 0x31); /* Footnotes. */ - put_u32 (buf, value->n_footnotes); - for (size_t i = 0; i < value->n_footnotes; i++) - put_u16 (buf, value->footnote_indexes[i]); + put_u32 (buf, ex->n_footnotes); + for (size_t i = 0; i < ex->n_footnotes; i++) + put_u16 (buf, ex->footnote_indexes[i]); /* Subscripts. */ - put_u32 (buf, value->n_subscripts); - for (size_t i = 0; i < value->n_subscripts; i++) - put_string (buf, value->subscripts[i]); + put_u32 (buf, ex->n_subscripts); + for (size_t i = 0; i < ex->n_subscripts; i++) + put_string (buf, ex->subscripts[i]); /* Template and style. */ uint32_t v3_start = start_count (buf); @@ -578,7 +590,7 @@ put_value_mod (struct buf *buf, const struct pivot_value *value, put_string (buf, template); } end_count_u32 (buf, template_string_start); - put_style_pair (buf, value->font_style, value->cell_style); + put_style_pair (buf, ex->font_style, ex->cell_style); end_count_u32 (buf, v3_start); } else @@ -637,9 +649,10 @@ put_value (struct buf *buf, const struct pivot_value *value) put_value_mod (buf, value, NULL); size_t len = strlen (value->string.s); if (value->string.hex) - put_format (buf, &(struct fmt_spec) { FMT_AHEX, len * 2, 0 }, false); + put_format (buf, &(struct fmt_spec) { .type = FMT_AHEX, .w = len * 2 }, + false); else - put_format (buf, &(struct fmt_spec) { FMT_A, len, 0 }, false); + put_format (buf, &(struct fmt_spec) { .type = FMT_A, .w = len }, false); put_string (buf, value->string.value_label); put_string (buf, value->string.var_name); put_show_values (buf, value->string.show); @@ -1045,7 +1058,7 @@ put_light_table (struct buf *buf, uint64_t table_id, } static void -spv_writer_put_table (struct spv_writer *w, const struct table_item *item) +spv_writer_put_table (struct spv_writer *w, const struct output_item *item) { int table_id = ++w->n_tables; @@ -1053,18 +1066,14 @@ spv_writer_put_table (struct spv_writer *w, const struct table_item *item) if (!initial_depth) spv_writer_open_file (w); - start_container (w, &item->output_item); - - char *subtype = (item->pt->subtype - ? pivot_value_to_string (item->pt->subtype, item->pt) - : xstrdup ("unknown")); + open_container (w, item, "vtb:table"); - start_elem (w, "vtb:table"); - write_attr (w, "commandName", item->pt->command_c); write_attr (w, "type", "table"); /* XXX */ - write_attr (w, "subType", subtype); write_attr_format (w, "tableId", "%d", table_id); - + char *subtype = (item->table->subtype + ? pivot_value_to_string (item->table->subtype, item->table) + : xstrdup ("unknown")); + write_attr (w, "subType", subtype); free (subtype); start_elem (w, "vtb:tableStructure"); @@ -1073,14 +1082,14 @@ spv_writer_put_table (struct spv_writer *w, const struct table_item *item) write_text (w, data_path); end_elem (w); /* vtb:dataPath */ end_elem (w); /* vtb:tableStructure */ - end_elem (w); /* vtb:table */ - end_elem (w); /* container */ + + close_container (w); if (!initial_depth) spv_writer_close_file (w, ""); struct buf buf = { NULL, 0, 0 }; - put_light_table (&buf, table_id, item->pt); + put_light_table (&buf, table_id, item->table); zip_writer_add_memory (w->zw, data_path, buf.data, buf.len); free (buf.data); @@ -1090,38 +1099,54 @@ spv_writer_put_table (struct spv_writer *w, const struct table_item *item) void spv_writer_write (struct spv_writer *w, const struct output_item *item) { - if (is_group_open_item (item)) - spv_writer_open_heading (w, - to_group_open_item (item)->command_name, - to_group_open_item (item)->command_name); - else if (is_group_close_item (item)) - spv_writer_close_heading (w); - else if (is_table_item (item)) - spv_writer_put_table (w, to_table_item (item)); - else if (is_chart_item (item)) + switch (item->type) { - cairo_surface_t *surface = xr_draw_image_chart ( - to_chart_item (item), - &(struct cell_color) CELL_COLOR_BLACK, - &(struct cell_color) CELL_COLOR_WHITE); - if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) - spv_writer_put_image (w, item, surface); - cairo_surface_destroy (surface); - } - else if (is_image_item (item)) - spv_writer_put_image (w, item, to_image_item (item)->image); - else if (is_text_item (item)) - { - char *command_id = output_get_command_name (); - spv_writer_put_text (w, to_text_item (item), - command_id); - free (command_id); - } - else if (is_page_eject_item (item)) - w->need_page_break = true; - else if (is_page_setup_item (item)) - { - page_setup_destroy (w->page_setup); - w->page_setup = page_setup_clone (to_page_setup_item (item)->page_setup); + case OUTPUT_ITEM_CHART: + { + cairo_surface_t *surface = xr_draw_image_chart ( + item->chart, + &(struct cell_color) CELL_COLOR_BLACK, + &(struct cell_color) CELL_COLOR_WHITE); + if (cairo_surface_status (surface) == CAIRO_STATUS_SUCCESS) + spv_writer_put_image (w, item, surface); + cairo_surface_destroy (surface); + } + break; + + case OUTPUT_ITEM_GROUP: + spv_writer_open_heading (w, item); + for (size_t i = 0; i < item->group.n_children; i++) + spv_writer_write (w, item->group.children[i]); + spv_writer_close_heading (w); + break; + + case OUTPUT_ITEM_IMAGE: + spv_writer_put_image (w, item, item->image); + break; + + case OUTPUT_ITEM_MESSAGE: + spv_writer_put_text ( + w, message_item_to_text_item (output_item_ref (item))); + break; + + case OUTPUT_ITEM_PAGE_BREAK: + w->need_page_break = true; + break; + + case OUTPUT_ITEM_TABLE: + spv_writer_put_table (w, item); + break; + + case OUTPUT_ITEM_TEXT: + spv_writer_put_text (w, output_item_ref (item)); + break; } } + +void +spv_writer_set_page_setup (struct spv_writer *w, + const struct page_setup *ps) +{ + page_setup_destroy (w->page_setup); + w->page_setup = page_setup_clone (ps); +}