[gnumeric] speed up writing of odf files and shrink those files
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnumeric] speed up writing of odf files and shrink those files
- Date: Tue, 16 Jun 2009 19:22:09 -0400 (EDT)
commit 02ac8f8790faf2c923b94d568dd8b36e1163d082
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date: Tue Jun 16 17:21:36 2009 -0600
speed up writing of odf files and shrink those files
2009-06-16 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-write.c (odf_write_comment): new
(equal_style): deleted
(odf_write_empty_cell): change arguments and adjust all callers.
(filter_style): just compare pointers
(finder): new
(write_styled_cells): new
(odf_write_styled_empty_rows): new
(odf_write_formatted_empty_rows): deleted
(odf_write_content_rows): new
(odf_write_sheet): split into parts
plugins/openoffice/ChangeLog | 13 ++
plugins/openoffice/openoffice-write.c | 312 ++++++++++++++++++++-------------
2 files changed, 207 insertions(+), 118 deletions(-)
---
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 45b3c3f..e1713b1 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-16 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * openoffice-write.c (odf_write_comment): new
+ (equal_style): deleted
+ (odf_write_empty_cell): change arguments and adjust all callers.
+ (filter_style): just compare pointers
+ (finder): new
+ (write_styled_cells): new
+ (odf_write_styled_empty_rows): new
+ (odf_write_formatted_empty_rows): deleted
+ (odf_write_content_rows): new
+ (odf_write_sheet): split into parts
+
2009-06-15 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-write.c (cell_styles_free): deleted
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 5f2c42f..58c77e8 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -517,16 +517,6 @@ odf_write_table_styles (GnmOOExport *state)
}
}
-static gboolean
-equal_style (GnmStyle const *that, GnmStyle const *this)
-{
- if (this == that)
- return TRUE;
- if (this == NULL || that == NULL)
- return FALSE;
- return gnm_style_equal (that, this);
-}
-
static char *
odf_get_border_format (GnmBorder *border)
{
@@ -1326,22 +1316,55 @@ odf_cell_is_covered (Sheet const *sheet, GnmCell *current_cell,
}
static void
-odf_write_empty_cell (GnmOOExport *state, int *num, GnmStyle const *style)
+odf_write_comment (GnmOOExport *state, GnmComment const *cc)
{
- if (*num > 0) {
+ char const *author;
+ char const *text;
+ const PangoAttrList * markup;
+ gboolean pp = TRUE;
+
+ g_object_get (G_OBJECT (state->xml), "pretty-print", &pp, NULL);
+
+ g_object_get (G_OBJECT (cc), "text", &text,
+ "markup", &markup, "author", &author, NULL);
+
+ gsf_xml_out_start_element (state->xml, OFFICE "annotation");
+ if (author != NULL) {
+ gsf_xml_out_start_element (state->xml, DUBLINCORE "creator");
+ gsf_xml_out_add_cstr (state->xml, NULL, author);
+ gsf_xml_out_end_element (state->xml); /* DUBLINCORE "creator" */;
+ }
+ g_object_set (G_OBJECT (state->xml), "pretty-print", FALSE, NULL);
+ gsf_xml_out_start_element (state->xml, TEXT "p");
+ if (markup != NULL)
+ odf_new_markup (state, markup, text);
+ else {
+ gboolean white_written = TRUE;
+ odf_add_chars (state, text, strlen (text), &white_written);
+ }
+ gsf_xml_out_end_element (state->xml); /* p */
+ g_object_set (G_OBJECT (state->xml), "pretty-print", pp, NULL);
+ gsf_xml_out_end_element (state->xml); /* OFFICE "annotation" */
+}
+
+static void
+odf_write_empty_cell (GnmOOExport *state, int num, GnmStyle const *style, GnmComment const *cc)
+{
+ if (num > 0) {
gsf_xml_out_start_element (state->xml, TABLE "table-cell");
- if (*num > 1)
+ if (num > 1)
gsf_xml_out_add_int (state->xml,
TABLE "number-columns-repeated",
- *num);
+ num);
if (style != NULL) {
char const * name = odf_find_style (state, style);
if (name != NULL)
gsf_xml_out_add_cstr (state->xml,
TABLE "style-name", name);
}
+ if (cc != NULL)
+ odf_write_comment (state, cc);
gsf_xml_out_end_element (state->xml); /* table-cell */
- *num = 0;
}
}
@@ -1459,33 +1482,8 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
}
}
- if (cc != NULL) {
- char const *author;
- char const *text;
- const PangoAttrList * markup;
-
- g_object_get (G_OBJECT (cc), "text", &text,
- "markup", &markup, "author", &author, NULL);
-
- gsf_xml_out_start_element (state->xml, OFFICE "annotation");
- if (author != NULL) {
- gsf_xml_out_start_element (state->xml, DUBLINCORE "creator");
- gsf_xml_out_add_cstr (state->xml, NULL, author);
- gsf_xml_out_end_element (state->xml); /* DUBLINCORE "creator" */;
- }
- g_object_set (G_OBJECT (state->xml), "pretty-print", FALSE, NULL);
- gsf_xml_out_start_element (state->xml, TEXT "p");
- if (markup != NULL)
- odf_new_markup (state, markup, text);
- else {
- gboolean white_written = TRUE;
- odf_add_chars (state, text, strlen (text), &white_written);
- }
- gsf_xml_out_end_element (state->xml); /* p */
- g_object_set (G_OBJECT (state->xml), "pretty-print", pp, NULL);
- gsf_xml_out_end_element (state->xml); /* OFFICE "annotation" */
- }
-
+ if (cc != NULL)
+ odf_write_comment (state, cc);
if (cell != NULL && cell->value != NULL) {
g_object_set (G_OBJECT (state->xml), "pretty-print", FALSE, NULL);
@@ -1525,7 +1523,7 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
static GnmStyle *
filter_style (GnmStyle *default_style, GnmStyle * this)
{
- return (equal_style (default_style, this) ? NULL : this);
+ return ((default_style == this) ? NULL : this);
}
static void
@@ -1565,7 +1563,7 @@ odf_write_formatted_columns (GnmOOExport *state, Sheet const *sheet, GnmStyle **
GnmStyle *this_col_style = filter_style (state->default_style, col_styles[i]);
ColRowInfo const *this_ci = sheet_col_get (sheet, i);
- if (equal_style (this_col_style, last_col_style) && colrow_equal (last_ci, this_ci))
+ if ((this_col_style == last_col_style) && colrow_equal (last_ci, this_ci))
number_cols_rep++;
else {
if (number_cols_rep > 1)
@@ -1600,14 +1598,61 @@ write_row_style (GnmOOExport *state, ColRowInfo const *ci,
gsf_xml_out_add_cstr (state->xml, TABLE "style-name", name);
}
+
+static gint
+finder (gconstpointer a, gconstpointer b)
+{
+ GnmStyleRegion const *region = a;
+ GnmCellPos const *where = b;
+
+ return !range_contains ((®ion->range), where->col, where->row);
+}
+
+static int
+write_styled_cells (GnmOOExport *state, Sheet const *sheet, int row, int row_length,
+ int max_rows, GnmStyleList *list)
+{
+ int answer = max_rows;
+ GnmCellPos where;
+ where.row = row;
+
+ for (where.col = 0; where.col < row_length; ) {
+ GSList* l = g_slist_find_custom (list, &where, finder);
+
+ if (l == NULL) {
+ answer = 1;
+ odf_write_empty_cell (state, 1, NULL, NULL);
+ where.col++;
+ } else {
+ GnmStyleRegion *region = l->data;
+ int repetition = region->range.end.col - where.col + 1;
+ int rows = region->range.end.row - where.row + 1;
+
+ odf_write_empty_cell (state, repetition, region->style, NULL);
+ where.col += repetition;
+ if (rows < answer)
+ answer = rows;
+ }
+ }
+ return answer;
+}
+
static void
-odf_write_formatted_empty_rows (GnmOOExport *state, Sheet const *sheet,
- int from, int to, int row_length)
+odf_write_styled_empty_rows (GnmOOExport *state, Sheet const *sheet,
+ int from, int to, int row_length,
+ GnmPageBreaks *pb, G_GNUC_UNUSED GnmStyle **col_styles)
{
int number_rows_rep;
ColRowInfo const *last_ci;
- int i, next_to;
- GnmPageBreaks *pb = sheet->print_info->page_breaks.v;
+ int i, j, next_to, style_rep;
+ GnmStyleList *list;
+ GnmRange r;
+
+ if (from >= to)
+ return;
+
+ range_init_rows (&r, sheet, from, to - 1);
+ list = sheet_style_get_range (sheet, &r);
for (i = from; i < to; ) {
if (gnm_page_breaks_get_break (pb, i) != GNM_PAGE_BREAK_NONE)
@@ -1619,84 +1664,74 @@ odf_write_formatted_empty_rows (GnmOOExport *state, Sheet const *sheet,
next_to = to;
gsf_xml_out_start_element (state->xml, TABLE "table-row");
- number_rows_rep = 1;
- last_ci = sheet_row_get (sheet, from);
+ last_ci = sheet_row_get (sheet, i);
write_row_style (state, last_ci, sheet);
-
+ style_rep = write_styled_cells (state, sheet, i - from, row_length,
+ next_to - i, list) - 1;
+ gsf_xml_out_end_element (state->xml); /* table-row */
i++;
+
+ if (style_rep <= 0)
+ continue;
+
+ if (i + style_rep < next_to)
+ next_to = i + style_rep;
- for (; i < next_to; i++) {
- ColRowInfo const *this_ci = sheet_row_get (sheet, i);
+ number_rows_rep = 1;
+ last_ci = sheet_row_get (sheet, i);
+ for (j = i + 1; j < next_to; j++) {
+ ColRowInfo const *this_ci = sheet_row_get (sheet, j);
if (colrow_equal (last_ci, this_ci))
number_rows_rep++;
- else {
- if (number_rows_rep > 1)
- gsf_xml_out_add_int (state->xml, TABLE "number-rows-repeated",
- number_rows_rep);
- gsf_xml_out_start_element (state->xml, TABLE "table-cell");
- gsf_xml_out_add_int (state->xml, TABLE "number-columns-repeated",
- row_length);
- gsf_xml_out_end_element (state->xml); /* table-cell */
- gsf_xml_out_end_element (state->xml); /* table-row */
-
- gsf_xml_out_start_element (state->xml, TABLE "table-row");
- number_rows_rep = 1;
- last_ci = this_ci;
- write_row_style (state, last_ci, sheet);
- }
}
+ gsf_xml_out_start_element (state->xml, TABLE "table-row");
+ write_row_style (state, last_ci, sheet);
if (number_rows_rep > 1)
gsf_xml_out_add_int (state->xml, TABLE "number-rows-repeated",
number_rows_rep);
- gsf_xml_out_start_element (state->xml, TABLE "table-cell");
- gsf_xml_out_add_int (state->xml, TABLE "number-columns-repeated",
- row_length);
- gsf_xml_out_end_element (state->xml); /* table-cell */
- gsf_xml_out_end_element (state->xml); /* table-row */
+ write_styled_cells (state, sheet, i - from, row_length, 0, list);
+ gsf_xml_out_end_element (state->xml); /* table-row */
+
+ i += number_rows_rep;
}
+ style_list_free (list);
}
static void
-odf_write_sheet (GnmOOExport *state, Sheet const *sheet)
-{
- int max_cols = gnm_sheet_get_max_cols (sheet);
- int max_rows = gnm_sheet_get_max_rows (sheet);
- GnmStyle **col_styles = g_new (GnmStyle *, max_cols);
- GnmRange extent;
- int i, col, row;
- GSList *sheet_merges = NULL;
- GnmPageBreaks *pb = sheet->print_info->page_breaks.v;
-
- extent = sheet_get_extent (sheet, FALSE);
- sheet_style_get_extent (sheet, &extent, col_styles);
-
- /* include collapsed or hidden cols and rows */
- for (i = max_rows ; i-- > extent.end.row ; )
- if (!colrow_is_empty (sheet_row_get (sheet, i))) {
- extent.end.row = i;
- break;
- }
- for (i = max_cols ; i-- > extent.end.col ; )
- if (!colrow_is_empty (sheet_col_get (sheet, i))) {
- extent.end.col = i;
- break;
- }
-
- /* ODF does not allow us to mark sof page breaks between columns */
- odf_write_formatted_columns (state, sheet, col_styles, 0, max_cols);
-
- odf_write_formatted_empty_rows (state, sheet,
- 0, extent.start.row, max_cols);
-
- for (row = extent.start.row; row <= extent.end.row; row++) {
+odf_write_content_rows (GnmOOExport *state, Sheet const *sheet, int from, int to,
+ G_GNUC_UNUSED int col_from, G_GNUC_UNUSED int col_to, int row_length,
+ GSList **sheet_merges, GnmPageBreaks *pb, G_GNUC_UNUSED GnmStyle **col_styles)
+{
+ int col, row;
+ int n;
+ GnmStyleRow sr;
+
+ n = row_length + 2;
+ sr.vertical = g_alloca (n * 4 * sizeof (gpointer));
+ sr.vertical += 1;
+ sr.top = sr.vertical + n;
+ sr.bottom = sr.top + n;
+ sr.styles = ((GnmStyle const **) (sr.bottom + n));
+ sr.start_col = 0;
+ sr.end_col = row_length - 1;
+ sr.hide_grid = TRUE;
+
+ /* We are currently ignoring col_from and col_to but using them should speed things up.*/
+
+ for (row = from; row < to; row++) {
ColRowInfo const *ci = sheet_row_get (sheet, row);
GnmStyle const *null_style = NULL;
- int null_cell = extent.start.col;
+ int null_cell = 0;
int covered_cell = 0;
GnmCellPos pos;
+
pos.row = row;
+
+ sr.row = row;
+ sheet_style_get_row (sheet, &sr);
+
if (gnm_page_breaks_get_break (pb, row) != GNM_PAGE_BREAK_NONE)
gsf_xml_out_simple_element (state->xml,
TEXT "soft-page-break",
@@ -1705,7 +1740,7 @@ odf_write_sheet (GnmOOExport *state, Sheet const *sheet)
gsf_xml_out_start_element (state->xml, TABLE "table-row");
write_row_style (state, ci, sheet);
- for (col = extent.start.col; col <= extent.end.col; col++) {
+ for (col = 0; col < row_length; col++) {
GnmCell *current_cell = sheet_cell_get (sheet, col, row);
GnmRange const *merge_range;
GnmComment const *cc;
@@ -1715,48 +1750,89 @@ odf_write_sheet (GnmOOExport *state, Sheet const *sheet)
merge_range = gnm_sheet_merge_is_corner (sheet, &pos);
if (odf_cell_is_covered (sheet, current_cell, col, row,
- merge_range, &sheet_merges)) {
-
- odf_write_empty_cell (state, &null_cell, null_style);
-
+ merge_range, sheet_merges)) {
+ odf_write_empty_cell (state, null_cell, null_style, NULL);
+ null_cell = 0;
covered_cell++;
continue;
}
if ((merge_range == NULL) && (cc == NULL) &&
gnm_cell_is_empty (current_cell)) {
- GnmStyle const *this_style = sheet_style_get (sheet, col, row);
- if ((null_cell == 0) || equal_style (null_style, this_style)) {
+ GnmStyle const *this_style = sr.styles [col];
+ if ((null_cell == 0) || (null_style == this_style)) {
null_style = this_style;
if (covered_cell > 0)
odf_write_covered_cell (state, &covered_cell);
null_cell++;
} else {
- odf_write_empty_cell (state, &null_cell, null_style);
+ odf_write_empty_cell (state, null_cell, null_style, NULL);
null_style = this_style;
null_cell = 1;
}
continue;
}
- odf_write_empty_cell (state, &null_cell, null_style);
+ odf_write_empty_cell (state, null_cell, null_style, NULL);
+ null_cell = 0;
if (covered_cell > 0)
odf_write_covered_cell (state, &covered_cell);
odf_write_cell (state, current_cell, merge_range, cc);
}
- odf_write_empty_cell (state, &null_cell, null_style);
+ odf_write_empty_cell (state, null_cell, null_style, NULL);
+ null_cell = 0;
if (covered_cell > 0)
odf_write_covered_cell (state, &covered_cell);
gsf_xml_out_end_element (state->xml); /* table-row */
}
+
+}
+
+static void
+odf_write_sheet (GnmOOExport *state, Sheet const *sheet)
+{
+ int max_cols = gnm_sheet_get_max_cols (sheet);
+ int max_rows = gnm_sheet_get_max_rows (sheet);
+ GnmStyle **col_styles = g_new0 (GnmStyle *, max_cols);
+ GnmRange extent, style_extent;
+ int i;
+ GSList *sheet_merges = NULL;
+ GnmPageBreaks *pb = sheet->print_info->page_breaks.v;
+
+ extent = sheet_get_extent (sheet, FALSE);
+
+ /* include collapsed or hidden cols and rows */
+ for (i = max_rows ; i-- > extent.end.row ; )
+ if (!colrow_is_empty (sheet_row_get (sheet, i))) {
+ extent.end.row = i;
+ break;
+ }
+ for (i = max_cols ; i-- > extent.end.col ; )
+ if (!colrow_is_empty (sheet_col_get (sheet, i))) {
+ extent.end.col = i;
+ break;
+ }
+
+ style_extent = extent;
+ sheet_style_get_extent (sheet, &style_extent, col_styles);
+
+ /* ODF does not allow us to mark soft page breaks between columns */
+ odf_write_formatted_columns (state, sheet, col_styles, 0, max_cols);
+
+ odf_write_styled_empty_rows (state, sheet, 0, extent.start.row,
+ max_cols, pb, col_styles);
+ odf_write_content_rows (state, sheet,
+ extent.start.row, extent.end.row + 1,
+ extent.start.col, extent.end.col + 1,
+ max_cols, &sheet_merges, pb, col_styles);
+ odf_write_styled_empty_rows (state, sheet, extent.end.col + 1, max_rows,
+ max_cols, pb, col_styles);
+
go_slist_free_custom (sheet_merges, g_free);
g_free (col_styles);
- odf_write_formatted_empty_rows (state, sheet,
- extent.end.row + 1, max_rows, max_cols);
-
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]