[gnumeric] commit of Mortens patch for Bug 687243 - ODF creates unnecessarily large files
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] commit of Mortens patch for Bug 687243 - ODF creates unnecessarily large files
- Date: Sat, 3 Nov 2012 16:29:34 +0000 (UTC)
commit 37082510c5d161c4e5cf5e6f65b3ab279f20f97a
Author: Morten Welinder <terra gnome org>
Date: Sat Nov 3 10:28:10 2012 -0600
commit of Mortens patch for Bug 687243 - ODF creates unnecessarily large files
2012-11-03 Morten Welinder <terra gnome org>
* src/sheet-style.c (sheet_style_get_row2): New function.
ChangeLog | 4 ++
NEWS | 2 +-
plugins/openoffice/ChangeLog | 8 ++++
plugins/openoffice/openoffice-write.c | 68 +++++++++++++++++++++++---------
src/sheet-style.c | 32 +++++++++++++++
src/sheet-style.h | 1 +
6 files changed, 95 insertions(+), 20 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d4c6760..58518ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2012-11-03 Morten Welinder <terra gnome org>
+
+ * src/sheet-style.c (sheet_style_get_row2): New function.
+
2012-11-02 Jean Brefort <jean brefort normalesup org>
* src/sheet-object-image.c (gnm_soi_write_xml_sax): fixed crash when
diff --git a/NEWS b/NEWS
index f43b0f4..0572c25 100644
--- a/NEWS
+++ b/NEWS
@@ -12,7 +12,7 @@ Jean:
Morten:
* Fix xlsx save performance problems. [#662058] [#685530]
- * Fix ods save performance problems. [#662057]
+ * Fix ods save performance problems. [#662057, #687243]
* Make .gnumeric use fewer style rectangles for the same style.
* Short-circuit column resize for large stf imports. [#686858]
* Enhance POWER to do root of negative numbers. [#687269]
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index d00bc62..c2abcc4 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,11 @@
+2012-11-03 Morten Welinder <terra gnome org>
+
+ * openoffice-write.c (row_info_equal): Rename from row_style_eq.
+ (compare_row_styles): New function.
+ (odf_write_content_rows): Handle repeated rows that have
+ non-default style too. Avoid single-cell style lookups in favour
+ of getting the whole row in one go. Fixes #687243.
+
2012-10-30 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-write.c (finder): deleted
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 33386c0..51897a0 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -3416,8 +3416,8 @@ write_row_style (GnmOOExport *state, ColRowInfo const *ci,
}
static gboolean
-row_style_eq (GnmOOExport *state, Sheet const *sheet,
- ColRowInfo const *ci1, ColRowInfo const *ci2)
+row_info_equal (GnmOOExport *state, Sheet const *sheet,
+ ColRowInfo const *ci1, ColRowInfo const *ci2)
{
if (ci1 == ci2)
return TRUE;
@@ -3434,6 +3434,20 @@ row_style_eq (GnmOOExport *state, Sheet const *sheet,
}
}
+static gboolean
+compare_row_styles (const Sheet *sheet, GnmStyle **styles, int orow)
+{
+ GnmStyle **ostyles = sheet_style_get_row2 (sheet, orow);
+ gboolean res;
+
+ res = !memcmp (styles, ostyles,
+ gnm_sheet_get_max_cols (sheet) * sizeof (GnmStyle *));
+
+ g_free (ostyles);
+
+ return res;
+}
+
static GSList *
odf_sheet_objects_get (Sheet const *sheet, GnmCellPos const *pos)
{
@@ -3512,16 +3526,21 @@ odf_write_content_rows (GnmOOExport *state, Sheet const *sheet, int from, int to
g_free (non_defaults_rows);
}
- for (row = from; row < to; row++) {
+ for (row = from; row < to; /* nothing here */) {
ColRowInfo const *ci = sheet_row_get (sheet, row);
GnmStyle const *null_style = NULL;
int null_cell = 0;
int covered_cell = 0;
GnmCellPos pos;
+ int repeat_count = 1;
+ guint8 rf = row_flags[row];
+ GnmStyle **row_styles = (rf & RF_STYLE)
+ ? sheet_style_get_row2 (sheet, row)
+ : NULL;
pos.row = row;
- if (row_flags[row] & RF_PAGEBREAK)
+ if (rf & RF_PAGEBREAK)
gsf_xml_out_simple_element (state->xml,
TEXT "soft-page-break",
NULL);
@@ -3529,26 +3548,34 @@ odf_write_content_rows (GnmOOExport *state, Sheet const *sheet, int from, int to
gsf_xml_out_start_element (state->xml, TABLE "table-row");
write_row_style (state, ci, sheet);
- if (row_flags[row] == 0) {
- int count = 1;
- while (row + count < to &&
- row_flags[row + count] == 0 &&
- row_style_eq (state, sheet, ci, sheet_row_get (sheet, row + count)))
- count++;
- if (count > 1) {
+ if ((rf & ~RF_STYLE) == 0) {
+ /*
+ * We have nothing but style (possibly default) in this
+ * row, so see if some rows following this one are
+ * identical.
+ */
+ int row2;
+ while ((row2 = row + repeat_count) < to &&
+ row_flags[row2] == rf &&
+ row_info_equal (state, sheet, ci, sheet_row_get (sheet, row2)) &&
+ (rf == 0 || compare_row_styles (sheet, row_styles, row2)))
+ repeat_count++;
+
+ if (repeat_count > 1)
gsf_xml_out_add_int (state->xml, TABLE "number-rows-repeated",
- count);
- row += (count - 1);
- }
+ repeat_count);
+ }
- } else {
+ if (rf) {
int col;
for (col = 0; col < row_length; col++) {
GnmCell *current_cell;
GnmRange const *merge_range;
GSList *objects;
- GnmStyle const *this_style;
+ GnmStyle const *this_style = row_styles
+ ? row_styles[col]
+ : col_styles[col];
current_cell = g_ptr_array_index (all_cells, cno);
if (current_cell &&
@@ -3559,6 +3586,7 @@ odf_write_content_rows (GnmOOExport *state, Sheet const *sheet, int from, int to
current_cell = NULL;
pos.col = col;
+
merge_range = gnm_sheet_merge_is_corner (sheet, &pos);
if (odf_cell_is_covered (sheet, current_cell, col, row,
@@ -3569,15 +3597,14 @@ odf_write_content_rows (GnmOOExport *state, Sheet const *sheet, int from, int to
continue;
}
- objects = (row_flags[row] & RF_OBJECT)
+ objects = (rf & RF_OBJECT)
? odf_sheet_objects_get (sheet, &pos)
: NULL;
if ((!(current_cell && gnm_cell_has_expr(current_cell))) &&
(merge_range == NULL) && (objects == NULL) &&
gnm_cell_is_empty (current_cell) &&
- NULL == gnm_style_get_hlink
- ((this_style = sheet_style_get (sheet, pos.col, pos.row)))) {
+ !gnm_style_get_hlink (this_style)) {
if ((null_cell == 0) || (null_style == this_style)) {
null_style = this_style;
if (covered_cell > 0)
@@ -3607,6 +3634,9 @@ odf_write_content_rows (GnmOOExport *state, Sheet const *sheet, int from, int to
odf_write_covered_cell (state, &covered_cell);
gsf_xml_out_end_element (state->xml); /* table-row */
+
+ row += repeat_count;
+ g_free (row_styles);
}
g_ptr_array_free (all_cells, TRUE);
diff --git a/src/sheet-style.c b/src/sheet-style.c
index 5bea872..335e69d 100644
--- a/src/sheet-style.c
+++ b/src/sheet-style.c
@@ -1552,6 +1552,38 @@ sheet_style_get_row (Sheet const *sheet, GnmStyleRow *sr)
get_style_row (sheet->style_data->styles, sheet->tile_top_level, 0, 0, sr);
}
+static void
+cb_get_row (GnmStyle *style,
+ int corner_col, G_GNUC_UNUSED int corner_row,
+ int width, G_GNUC_UNUSED int height,
+ GnmRange const *apply_to, gpointer user_)
+{
+ GnmStyle **res = user_;
+ int i;
+
+ /* The given dimensions refer to the tile, not the area. */
+ width = MIN (width, apply_to->end.col - corner_col + 1);
+
+ for (i = 0; i < width; i++)
+ res[corner_col + i] = style;
+}
+
+GnmStyle **
+sheet_style_get_row2 (Sheet const *sheet, int row)
+{
+ GnmRange r;
+ GnmStyle **res = g_new (GnmStyle *, gnm_sheet_get_max_cols (sheet));
+
+ range_init_rows (&r, sheet, row, row);
+
+ foreach_tile (sheet->style_data->styles,
+ sheet->tile_top_level, 0, 0, &r,
+ cb_get_row, res);
+
+ return res;
+}
+
+
/**
* style_row_init :
*
diff --git a/src/sheet-style.h b/src/sheet-style.h
index c7923a3..a9c1cb2 100644
--- a/src/sheet-style.h
+++ b/src/sheet-style.h
@@ -25,6 +25,7 @@ GnmStyle *sheet_style_default (Sheet const *sheet);
GnmStyle const *sheet_style_get (Sheet const *sheet, int col, int row);
GnmStyle *sheet_style_find (Sheet const *sheet, GnmStyle *st);
void sheet_style_get_row (Sheet const *sheet, GnmStyleRow *sr);
+GnmStyle **sheet_style_get_row2 (Sheet const *sheet, int row);
void sheet_style_apply_border (Sheet *sheet, GnmRange const *r,
GnmBorder **borders);
void sheet_style_apply_range (Sheet *sheet, GnmRange const *r,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]