[gnumeric] Sylk: beef up the writer.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Sylk: beef up the writer.
- Date: Sun, 3 Dec 2017 04:40:44 +0000 (UTC)
commit 7bc5390aae1c1008f7f0bdb91b105c244e8a1c95
Author: Morten Welinder <terra gnome org>
Date: Sat Dec 2 23:39:33 2017 -0500
Sylk: beef up the writer.
This can now write just about what we read. Something about the
extent isn't quite right yet.
NEWS | 1 +
plugins/sylk/ChangeLog | 4 +
plugins/sylk/sylk-write.c | 145 +++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 145 insertions(+), 5 deletions(-)
---
diff --git a/NEWS b/NEWS
index 08f78cb..b6346f7 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,7 @@ Gnumeric 1.12.38
Morten:
* Avoid large stack use here and there.
* Test suite improvements.
+ * Improve sylk writer. Don't ask.
--------------------------------------------------------------------------
Gnumeric 1.12.37
diff --git a/plugins/sylk/ChangeLog b/plugins/sylk/ChangeLog
index 1aab750..b3e2e8d 100644
--- a/plugins/sylk/ChangeLog
+++ b/plugins/sylk/ChangeLog
@@ -1,3 +1,7 @@
+2017-12-02 Morten Welinder <terra gnome org>
+
+ * sylk-write.c (sylk_write_sheet): Beef this up a bit.
+
2017-12-01 Morten Welinder <terra gnome org>
* Release 1.12.37
diff --git a/plugins/sylk/sylk-write.c b/plugins/sylk/sylk-write.c
index c4aaec5..58321b8 100644
--- a/plugins/sylk/sylk-write.c
+++ b/plugins/sylk/sylk-write.c
@@ -30,8 +30,10 @@
#include "expr-impl.h"
#include "value.h"
#include "cell.h"
+#include "mstyle.h"
#include "gutils.h"
#include "parse-util.h"
+#include "style-border.h"
#include <goffice/goffice.h>
@@ -41,6 +43,26 @@
#include <glib/gi18n-lib.h>
#include <gmodule.h>
+static int
+font_equal (gconstpointer a_, gconstpointer b_)
+{
+ GnmStyle const *a = a_;
+ GnmStyle const *b = b_;
+
+ return g_str_equal (gnm_style_get_font_name (a), gnm_style_get_font_name (b)) &&
+ gnm_style_get_font_size (a) == gnm_style_get_font_size (b);
+}
+
+static guint
+font_hash (gconstpointer s_)
+{
+ GnmStyle const *s = s_;
+
+ return g_str_hash (gnm_style_get_font_name (s)) ^
+ (guint)(gnm_style_get_font_size (s));
+}
+
+
typedef struct {
GsfOutput *output;
@@ -50,6 +72,12 @@ typedef struct {
Sheet *sheet;
int cur_row;
+
+ GPtrArray *formats;
+ GHashTable *format_hash;
+
+ GPtrArray *fonts;
+ GHashTable *font_hash;
} SylkWriter;
static void
@@ -72,7 +100,7 @@ sylk_write (SylkWriter *state, char const *str)
gsf_output_write (state->output, 1, "?");
str = next;
}
-#warning handle the magic ascii escaping
+#warning "handle the magic ascii escaping"
}
gsf_output_write (state->output, p - str, str);
}
@@ -139,9 +167,87 @@ cb_sylk_write_cell (GnmCellIter const *iter, SylkWriter *state)
return NULL;
}
+static gboolean
+sylk_get_border (GnmStyle const *style, GnmStyleElement border)
+{
+ GnmBorder *b = gnm_style_get_border (style, border);
+ return b && b->line_type > GNM_STYLE_BORDER_NONE;
+}
+
+
+static GnmValue *
+cb_sylk_write_cell_style (GnmCellIter const *iter, SylkWriter *state)
+{
+ GnmStyle const *style;
+ GOFormat const *fmt;
+ unsigned n;
+ GnmHAlign halign;
+
+ gsf_output_printf (state->output, "F");
+
+ style = sheet_style_get (state->sheet, iter->pp.eval.col, iter->pp.eval.row);
+
+ halign = gnm_style_get_align_h (style);
+ switch (halign) {
+ case GNM_HALIGN_LEFT: gsf_output_printf (state->output, ";FD0L"); break;
+ case GNM_HALIGN_RIGHT: gsf_output_printf (state->output, ";FD0R"); break;
+ case GNM_HALIGN_CENTER: gsf_output_printf (state->output, ";FD0C"); break;
+ case GNM_HALIGN_FILL: gsf_output_printf (state->output, ";FD0X"); break;
+ default:
+ ; // Nothing
+ }
+
+
+ fmt = gnm_style_get_format (style);
+ n = GPOINTER_TO_UINT (g_hash_table_lookup (state->format_hash, (gpointer)fmt));
+ gsf_output_printf (state->output, ";P%d", n);
+
+ n = GPOINTER_TO_UINT (g_hash_table_lookup (state->font_hash, style));
+ gsf_output_printf (state->output, ";SM%d", n + 1);
+
+ if (gnm_style_get_font_bold (style))
+ gsf_output_printf (state->output, ";SD");
+ if (gnm_style_get_font_italic (style))
+ gsf_output_printf (state->output, ";SI");
+ if (gnm_style_get_pattern (style) == 5)
+ gsf_output_printf (state->output, ";SS");
+ if (sylk_get_border (style, MSTYLE_BORDER_TOP))
+ gsf_output_printf (state->output, ";ST");
+ if (sylk_get_border (style, MSTYLE_BORDER_BOTTOM))
+ gsf_output_printf (state->output, ";SB");
+ if (sylk_get_border (style, MSTYLE_BORDER_LEFT))
+ gsf_output_printf (state->output, ";SL");
+ if (sylk_get_border (style, MSTYLE_BORDER_RIGHT))
+ gsf_output_printf (state->output, ";SR");
+
+ if (iter->pp.eval.row != state->cur_row)
+ gsf_output_printf (state->output, ";Y%d",
+ (state->cur_row = iter->pp.eval.row) + 1);
+ gsf_output_printf (state->output, ";X%d\r\n",
+ iter->pp.eval.col + 1);
+
+ return NULL;
+}
+
+
static void
cb_sylk_collect_styles (GnmStyle const *st, SylkWriter *state)
{
+ GOFormat const *fmt;
+
+ fmt = gnm_style_get_format (st);
+ if (!g_hash_table_lookup_extended (state->format_hash, fmt, NULL, NULL)) {
+ unsigned n = state->formats->len;
+ g_hash_table_insert (state->format_hash, (gpointer)fmt, GUINT_TO_POINTER (n));
+ g_ptr_array_add (state->formats, (gpointer)fmt);
+ }
+
+ if (!g_hash_table_lookup_extended (state->font_hash, st, NULL, NULL)) {
+ unsigned n = state->fonts->len;
+ g_hash_table_insert (state->font_hash, (gpointer)st, GUINT_TO_POINTER (n));
+ g_ptr_array_add (state->fonts, (gpointer)st);
+ }
+
}
static void
@@ -154,14 +260,34 @@ static void
sylk_write_sheet (SylkWriter *state)
{
GnmRange extent;
+ unsigned ui;
/* collect style and font info */
extent = sheet_get_extent (state->sheet, FALSE, TRUE);
+
sheet_style_foreach (state->sheet,
(GFunc)cb_sylk_collect_styles, state);
sheet_cell_foreach (state->sheet,
(GHFunc)cb_sylk_collect_cell_styles, state);
+ for (ui = 0; ui < state->formats->len; ui++) {
+ GOFormat const *fmt = g_ptr_array_index (state->formats, ui);
+ gsf_output_printf (state->output, "P;P%s\r\n",
+ go_format_as_XL (fmt));
+ }
+ for (ui = 0; ui < state->fonts->len; ui++) {
+ GnmStyle const *s = g_ptr_array_index (state->fonts, ui);
+ gsf_output_printf (state->output, "P;E%s;M%d\r\n",
+ gnm_style_get_font_name (s),
+ (int)(gnm_style_get_font_size (s) * 20 + 0.5));
+ }
+
+ state->cur_row = -1;
+ sheet_foreach_cell_in_range (state->sheet, 0,
+ extent.start.col, extent.start.row,
+ extent.end.col, extent.end.row,
+ (CellIterFunc) cb_sylk_write_cell_style, state);
+
/*
* 1) formats P;P.....
* 2.1) ?? fonts P;F....
@@ -229,15 +355,24 @@ sylk_file_save (GOFileSaver const *fs, GOIOContext *io_context,
state.output = output;
state.convs = sylk_conventions_new ();
- if (NULL == state.sheet) {
- go_io_error_string (io_context, _("Cannot get default sheet."));
- return;
- }
+ state.formats = g_ptr_array_new ();
+ state.format_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ state.fonts = g_ptr_array_new ();
+ state.font_hash = g_hash_table_new (font_hash, font_equal);
locale = gnm_push_C_locale ();
gsf_output_puts (output, "ID;PGnumeric;N;E\r\n");
+
sylk_write_sheet (&state);
+
gsf_output_puts (output, "E\r\n");
gnm_pop_C_locale (locale);
gnm_conventions_unref (state.convs);
+
+ g_hash_table_destroy (state.font_hash);
+ g_ptr_array_free (state.fonts, TRUE);
+
+ g_hash_table_destroy (state.format_hash);
+ g_ptr_array_free (state.formats, TRUE);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]