Commit e19a6a25 authored by Michael Meeks's avatar Michael Meeks
Browse files

Jon K Hellan's excellent style export stuff...

silly CORBA bug fix.
parent be1d650d
1999-12-16 Michael Meeks <mmeeks@gnu.org>
* src/corba-sheet.c (Sheet_range_set_alignment): add orientation.
1999-12-16 Michael Meeks <mmeeks@gnu.org> 1999-12-16 Michael Meeks <mmeeks@gnu.org>
* src/sheet.c (sheet_get_extent_cb): Fix biggest leak ever seen, * src/sheet.c (sheet_get_extent_cb): Fix biggest leak ever seen,
......
...@@ -6,7 +6,7 @@ Michael: ...@@ -6,7 +6,7 @@ Michael:
Jon: Jon:
* Lots of Excel style export work: * Lots of Excel style export work:
format, font, colors format, font, colors, borders, alignment, wrap, rotation.
JP: JP:
* Added sorting of infinite ranges * Added sorting of infinite ranges
......
1999-12-16 Michael Meeks <mmeeks@gnu.org>
* src/corba-sheet.c (Sheet_range_set_alignment): add orientation.
1999-12-16 Michael Meeks <mmeeks@gnu.org> 1999-12-16 Michael Meeks <mmeeks@gnu.org>
* src/sheet.c (sheet_get_extent_cb): Fix biggest leak ever seen, * src/sheet.c (sheet_get_extent_cb): Fix biggest leak ever seen,
......
1999-12-14 Jon K Hellan <hellan@acm.org>
* ms-excel-write.h (XF_MAGIC, PALETTE_ALSO_BLACK, FILL_MAGIC,
BORDER_MAGIC): define
(PALETTE_WHITE, PALETTE_BLACK): Fix typo, they were switched around.
* ms-excel-write.c (put_colors): Include border colors.
(excel_font_new): Newline to conform to coding style.
(fonts_get_font): New function. Get font, given index.
(fonts_free, write_fonts): Use it.
(write_font): Fix boldstyle typo.
(formats_get_format): New function. Get format, given index.
(formats_free, write_format): Use it.
(xf_get_mstyle): New function. Get mstyle, given index.
(xf_free): Use it.
(halign_to_excel):
New function. Map horizontal alignment to Excel bitfield
(valign_to_excel):
New function. Map vertical alignment to Excel bitfield.
(orientation_to_excel):
New function. Map text orientation to Excel bitfield.
(border_type_to_excel):
New function. Map border type to Excel bitfield.
(fixup_fill_colors):
New function. Kluge fill foreground and background colors.
(get_xf_differences): Fill out map of differences to parent style.
(log_xf_data):
New function. Log XF data for a record about to be written. Pulled
out of write_xf_record.
(build_xf_data): New function. Build XF data for a style. Pulled
out of write_xf_record, but uses BiffXFData struct. Add support
for borders, alignments, wrap, rotation. Change some
local variable names for consistency with import code.
(write_xf_magic_record): Comment magic color value.
(write_xf_record): Change signature, take BiffXFData instead of
mstyle. Simplify by moving out logging and marshaling. Make more
complex by writing borders, alignment, wrap, rotation.
(write_xf): Use xf_get_mstyle, build_xf_data, log_xf_data.
* ms-excel-util.h: Fix typo.
* ms-excel-xf.h: New file for BiffXFData struct def.
* ms-excel-read.c: Move BiffXFData struct def to
ms-excel-xf.h. Include ms-excel-xf.h. Remove include "border.h" -
ms-excel-xf.h includes it.
(ms_excel_get_style_from_xf): Express some bewilderment.
* ms-excel-biff.h: Define enums for horizontal alignment, vertical
alignment, text orientation, difference bits
1999-12-11 Frank Chiulli <fchiulli@home.com> 1999-12-11 Frank Chiulli <fchiulli@home.com>
* ms-summary.c (ms_summary_write): comment out DocumentSummary. * ms-summary.c (ms_summary_write): comment out DocumentSummary.
......
...@@ -24,6 +24,7 @@ libexcel_a_SOURCES = \ ...@@ -24,6 +24,7 @@ libexcel_a_SOURCES = \
ms-escher.h \ ms-escher.h \
ms-excel-util.c \ ms-excel-util.c \
ms-excel-util.h \ ms-excel-util.h \
ms-excel-xf.h \
ms-excel-read.c \ ms-excel-read.c \
ms-excel-read.h \ ms-excel-read.h \
ms-excel-write.c \ ms-excel-write.c \
......
...@@ -48,6 +48,39 @@ typedef enum _eBiffFontUnderline ...@@ -48,6 +48,39 @@ typedef enum _eBiffFontUnderline
typedef enum _eBiffFontScript { eBiffFSNone, eBiffFSSub, eBiffFSSuper } eBiffFontScript ; typedef enum _eBiffFontScript { eBiffFSNone, eBiffFSSub, eBiffFSSuper } eBiffFontScript ;
typedef enum _eBiffHAlign { /* Horizontal alignment */
eBiffHAGeneral = 0,
eBiffHALeft = 1,
eBiffHACenter = 2,
eBiffHARight = 3,
eBiffHAFill = 4,
eBiffHAJustify = 5,
eBuffHACenterAcrossSelection = 6
} eBiffHAlign;
typedef enum _eBiffVAlign { /* Vertical alignment */
eBiffVATop = 0,
eBiffVACenter = 1,
eBiffVABottom = 2,
eBiffVAJustify = 3
} eBiffVAlign;
typedef enum _eBiffOrient { /* Text orientation */
eBiffOHoriz = 0,
eBiffOVertHorizText = 1,
eBiffOVertVertText = 2,
eBiffOVertVertText2 = 3
} eBiffOrient;
typedef enum _eBiffDifferences { /* Differences to parent styles */
eBiffDFormatbit = 10,
eBiffDFontbit = 11,
eBiffDAlignbit = 12,
eBiffDBorderbit = 13,
eBiffDFillbit = 14,
eBiffDLockbit = 15
} _eBiffDifferences;
typedef struct _BIFF_BOF_DATA typedef struct _BIFF_BOF_DATA
{ {
eBiff_version version ; eBiff_version version ;
......
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
#include "ms-escher.h" #include "ms-escher.h"
#include "print-info.h" #include "print-info.h"
#include "selection.h" #include "selection.h"
#include "border.h"
#include "utils.h" /* for cell_name */ #include "utils.h" /* for cell_name */
#include "ranges.h" #include "ranges.h"
#include "ms-excel-xf.h"
/* #define NO_DEBUG_EXCEL */ /* #define NO_DEBUG_EXCEL */
...@@ -44,14 +44,6 @@ static ExcelSheet *ms_excel_sheet_new (ExcelWorkbook *wb, ...@@ -44,14 +44,6 @@ static ExcelSheet *ms_excel_sheet_new (ExcelWorkbook *wb,
static void ms_excel_workbook_attach (ExcelWorkbook *wb, static void ms_excel_workbook_attach (ExcelWorkbook *wb,
ExcelSheet *ans); ExcelSheet *ans);
#define STYLE_TOP (MSTYLE_BORDER_TOP - MSTYLE_BORDER_TOP)
#define STYLE_BOTTOM (MSTYLE_BORDER_BOTTOM - MSTYLE_BORDER_TOP)
#define STYLE_LEFT (MSTYLE_BORDER_LEFT - MSTYLE_BORDER_TOP)
#define STYLE_RIGHT (MSTYLE_BORDER_RIGHT - MSTYLE_BORDER_TOP)
#define STYLE_DIAGONAL (MSTYLE_BORDER_DIAGONAL - MSTYLE_BORDER_TOP)
#define STYLE_REV_DIAGONAL (MSTYLE_BORDER_REV_DIAGONAL - MSTYLE_BORDER_TOP)
#define STYLE_ORIENT_MAX 6
void void
ms_excel_unexpected_biff (BiffQuery *q, char const *const state) ms_excel_unexpected_biff (BiffQuery *q, char const *const state)
...@@ -948,30 +940,6 @@ ms_excel_palette_destroy (ExcelPalette *pal) ...@@ -948,30 +940,6 @@ ms_excel_palette_destroy (ExcelPalette *pal)
g_free (pal); g_free (pal);
} }
typedef struct _BiffXFData {
guint16 font_idx;
guint16 format_idx;
StyleFormat *style_format;
eBiff_hidden hidden;
eBiff_locked locked;
eBiff_xftype xftype; /* -- Very important field... */
eBiff_format format;
guint16 parentstyle;
StyleHAlignFlags halign;
StyleVAlignFlags valign;
gboolean wrap;
guint8 rotation;
eBiff_eastern eastern;
guint8 border_color[STYLE_ORIENT_MAX];
StyleBorderType border_type[STYLE_ORIENT_MAX];
guint8 fill_pattern_idx;
guint8 pat_foregnd_col;
guint8 pat_backgnd_col;
MStyle *mstyle;
} BiffXFData;
/** /**
* Search for a font record from its index in the workbooks font table * Search for a font record from its index in the workbooks font table
* NB. index 4 is omitted supposedly for backwards compatiblity * NB. index 4 is omitted supposedly for backwards compatiblity
...@@ -1128,6 +1096,14 @@ ms_excel_get_style_from_xf (ExcelSheet *sheet, guint16 xfidx) ...@@ -1128,6 +1096,14 @@ ms_excel_get_style_from_xf (ExcelSheet *sheet, guint16 xfidx)
mstyle_set_pattern (mstyle, xf->fill_pattern_idx); mstyle_set_pattern (mstyle, xf->fill_pattern_idx);
/* Solid patterns seem to reverse the meaning */ /* Solid patterns seem to reverse the meaning */
/*
* FIXME: Is this test correct? I fed Excel an XF record with
* fill_pattern_idx = 1, pat_backgnd_col = 1 (black),
* pat_foregnd_col = 0 (white). Excel displays it with black
* background. Gnumeric displays it with white background.
* Can the "xf->pat_foregnd_col != 0" test be removed?
* - Jon Hellan
*/
if (xf->fill_pattern_idx == 1 && xf->pat_foregnd_col != 0) { if (xf->fill_pattern_idx == 1 && xf->pat_foregnd_col != 0) {
pattern_index = xf->pat_backgnd_col; pattern_index = xf->pat_backgnd_col;
back_index = xf->pat_foregnd_col; back_index = xf->pat_foregnd_col;
......
/** /**
* ms-excel-util.h: Utility functions for MS Excel import * ms-excel-util.h: Utility functions for MS Excel export
* *
* Author: * Author:
* Jon K Hellan (hellan@acm.org) * Jon K Hellan (hellan@acm.org)
...@@ -46,3 +46,4 @@ gpointer ...@@ -46,3 +46,4 @@ gpointer
two_way_table_idx_to_key (const TwoWayTable *table, gint idx); two_way_table_idx_to_key (const TwoWayTable *table, gint idx);
#endif #endif
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "ms-biff.h" #include "ms-biff.h"
#include "excel.h" #include "excel.h"
#include "ms-excel-write.h" #include "ms-excel-write.h"
#include "ms-excel-xf.h"
#include "ms-formula-write.h" #include "ms-formula-write.h"
/** /**
...@@ -641,15 +642,23 @@ put_color (ExcelWorkbook *wb, const StyleColor *c) ...@@ -641,15 +642,23 @@ put_color (ExcelWorkbook *wb, const StyleColor *c)
/** /**
* Add colors in mstyle to palette * Add colors in mstyle to palette
*
* FIXME: Border colors not yet included
**/ **/
static void static void
put_colors (MStyle *st, gconstpointer dummy, ExcelWorkbook *wb) put_colors (MStyle *st, gconstpointer dummy, ExcelWorkbook *wb)
{ {
int i;
const MStyleBorder * b;
put_color (wb, mstyle_get_color (st, MSTYLE_COLOR_FORE)); put_color (wb, mstyle_get_color (st, MSTYLE_COLOR_FORE));
put_color (wb, mstyle_get_color (st, MSTYLE_COLOR_BACK)); put_color (wb, mstyle_get_color (st, MSTYLE_COLOR_BACK));
put_color (wb, mstyle_get_color (st, MSTYLE_COLOR_PATTERN)); put_color (wb, mstyle_get_color (st, MSTYLE_COLOR_PATTERN));
/* Borders */
for (i = STYLE_TOP; i < STYLE_ORIENT_MAX; i++) {
b = mstyle_get_border (st, MSTYLE_BORDER_TOP + i);
if (b && b->color)
put_color (wb, b->color);
}
} }
/** /**
...@@ -761,7 +770,8 @@ excel_font_to_string (const ExcelFont *f) ...@@ -761,7 +770,8 @@ excel_font_to_string (const ExcelFont *f)
* *
* Style color is *not* unrefed. This is correct * Style color is *not* unrefed. This is correct
**/ **/
static ExcelFont *excel_font_new (MStyle *st) static ExcelFont *
excel_font_new (MStyle *st)
{ {
ExcelFont *f; ExcelFont *f;
StyleColor *c; StyleColor *c;
...@@ -840,6 +850,17 @@ fonts_init (ExcelWorkbook *wb) ...@@ -840,6 +850,17 @@ fonts_init (ExcelWorkbook *wb)
= two_way_table_new (excel_font_hash, excel_font_equal, 0); = two_way_table_new (excel_font_hash, excel_font_equal, 0);
} }
/**
* Get an ExcelFont, given index
**/
static ExcelFont *
fonts_get_font (ExcelWorkbook *wb, gint idx)
{
TwoWayTable *twt = wb->fonts->two_way_table;
return (ExcelFont *) two_way_table_idx_to_key (twt, idx);
}
/** /**
* Free font table * Free font table
**/ **/
...@@ -854,8 +875,7 @@ fonts_free (ExcelWorkbook *wb) ...@@ -854,8 +875,7 @@ fonts_free (ExcelWorkbook *wb)
twt = wb->fonts->two_way_table; twt = wb->fonts->two_way_table;
if (twt) { if (twt) {
for (i = 0; i < twt->idx_to_key->len; i++) { for (i = 0; i < twt->idx_to_key->len; i++) {
f = two_way_table_idx_to_key (twt, f = fonts_get_font (wb, i + twt->base);
i + twt->base);
excel_font_free (f); excel_font_free (f);
} }
two_way_table_free (twt); two_way_table_free (twt);
...@@ -944,7 +964,7 @@ write_font (ExcelWorkbook *wb, BiffPut *bp, const ExcelFont *f) ...@@ -944,7 +964,7 @@ write_font (ExcelWorkbook *wb, BiffPut *bp, const ExcelFont *f)
guint16 grbit = 0; guint16 grbit = 0;
guint16 color = palette_get_index (wb, f->color); guint16 color = palette_get_index (wb, f->color);
guint16 boldstyle = 190; /* Normal boldness */ guint16 boldstyle = 0x190; /* Normal boldness */
guint16 subsuper = 0; /* 0: Normal, 1; Super, 2: Sub script*/ guint16 subsuper = 0; /* 0: Normal, 1; Super, 2: Sub script*/
guint8 underline = 0; /* No underline */ guint8 underline = 0; /* No underline */
guint8 family = 0; guint8 family = 0;
...@@ -995,14 +1015,14 @@ write_fonts (ExcelWorkbook *wb, BiffPut *bp) ...@@ -995,14 +1015,14 @@ write_fonts (ExcelWorkbook *wb, BiffPut *bp)
for (lp = 0; lp < nfonts; lp++) { for (lp = 0; lp < nfonts; lp++) {
if (lp != FONT_SKIP) { /* FONT_SKIP is invalid, skip it */ if (lp != FONT_SKIP) { /* FONT_SKIP is invalid, skip it */
f = two_way_table_idx_to_key (twt, lp); f = fonts_get_font (wb, lp);
write_font (wb, bp, f); write_font (wb, bp, f);
} }
} }
if (nfonts < FONTS_MINIMUM + 1) { /* Add 1 to account for skip */ if (nfonts < FONTS_MINIMUM + 1) { /* Add 1 to account for skip */
/* Fill up until we've got the minimum number */ /* Fill up until we've got the minimum number */
f = two_way_table_idx_to_key (twt, 0); f = fonts_get_font (wb, 0);
for (; lp < FONTS_MINIMUM + 1; lp++) { for (; lp < FONTS_MINIMUM + 1; lp++) {
if (lp != FONT_SKIP) { if (lp != FONT_SKIP) {
/* FONT_SKIP is invalid, skip it */ /* FONT_SKIP is invalid, skip it */
...@@ -1070,6 +1090,18 @@ formats_init (ExcelWorkbook *wb) ...@@ -1070,6 +1090,18 @@ formats_init (ExcelWorkbook *wb)
formats_put_magic (wb); formats_put_magic (wb);
} }
/**
* Get a format, given index
**/
static char *
formats_get_format (ExcelWorkbook *wb, gint idx)
{
TwoWayTable *twt = wb->formats->two_way_table;
return (char *) two_way_table_idx_to_key (twt, idx);
}
/** /**
* Free format table * Free format table
**/ **/
...@@ -1084,8 +1116,8 @@ formats_free (ExcelWorkbook *wb) ...@@ -1084,8 +1116,8 @@ formats_free (ExcelWorkbook *wb)
twt = wb->formats->two_way_table; twt = wb->formats->two_way_table;
if (twt) { if (twt) {
for (i = 0; i < twt->idx_to_key->len; i++) { for (i = 0; i < twt->idx_to_key->len; i++) {
format = two_way_table_idx_to_key format = formats_get_format (wb,
(twt, i + twt->base); i + twt->base);
g_free (format); g_free (format);
} }
two_way_table_free (twt); two_way_table_free (twt);
...@@ -1147,8 +1179,7 @@ static void ...@@ -1147,8 +1179,7 @@ static void
write_format (ExcelWorkbook *wb, BiffPut *bp, int fidx) write_format (ExcelWorkbook *wb, BiffPut *bp, int fidx)
{ {
guint8 data[64]; guint8 data[64];
TwoWayTable *twt = wb->formats->two_way_table; char *format = formats_get_format(wb, fidx);
char *format = two_way_table_idx_to_key (twt, fidx);
#ifndef NO_DEBUG_EXCEL #ifndef NO_DEBUG_EXCEL
if (ms_excel_write_debug > 1) { if (ms_excel_write_debug > 1) {
...@@ -1270,6 +1301,18 @@ xf_init (ExcelWorkbook *wb) ...@@ -1270,6 +1301,18 @@ xf_init (ExcelWorkbook *wb)
wb->xf->default_style = get_default_mstyle (); wb->xf->default_style = get_default_mstyle ();
} }
/**
* Get an mstyle, given index
**/
static MStyle *
xf_get_mstyle (ExcelWorkbook *wb, gint idx)
{
TwoWayTable *twt = wb->xf->two_way_table;
return (MStyle *) two_way_table_idx_to_key (twt, idx);
}
/** /**
* Free XF/MStyle table * Free XF/MStyle table
**/ **/
...@@ -1284,8 +1327,7 @@ xf_free (ExcelWorkbook *wb) ...@@ -1284,8 +1327,7 @@ xf_free (ExcelWorkbook *wb)
if (wb->xf->two_way_table) { if (wb->xf->two_way_table) {
twt = wb->xf->two_way_table; twt = wb->xf->two_way_table;
for (i = 0; i < twt->idx_to_key->len; i++) { for (i = 0; i < twt->idx_to_key->len; i++) {
st = two_way_table_idx_to_key (twt, st = xf_get_mstyle (wb, i + twt->base);
i + twt->base);
mstyle_unref (st); mstyle_unref (st);
} }
two_way_table_free (wb->xf->two_way_table); two_way_table_free (wb->xf->two_way_table);
...@@ -1459,6 +1501,339 @@ map_pattern_index_to_excel (int const i) ...@@ -1459,6 +1501,339 @@ map_pattern_index_to_excel (int const i)
return map_to_excel[i]; return map_to_excel[i];
} }
/**
* Map Gnumeric horizontal alignment to Excel bitfield
* @halign Gnumeric horizontal alignment
*
* See S59E1E.HTM
**/
inline static guint
halign_to_excel (StyleHAlignFlags halign)
{
guint ialign;
switch (halign) {
case HALIGN_GENERAL:
ialign = eBiffHAGeneral;
break;
case HALIGN_LEFT:
ialign = eBiffHALeft;
break;
case HALIGN_RIGHT:
ialign = eBiffHARight;
break;
case HALIGN_CENTER:
ialign = eBiffHACenter;
break;
case HALIGN_FILL:
ialign = eBiffHAFill;
break;
case HALIGN_JUSTIFY:
ialign = eBiffHAJustify;
break;
default:
ialign = eBiffHAGeneral;
}
return ialign;
}
/**
* Map Gnumeric vertical alignment to Excel bitfield
* @valign Gnumeric vertical alignment
*
* See S59E1E.HTM
**/
inline static guint
valign_to_excel (StyleVAlignFlags valign)
{
guint ialign;
switch (valign) {
case VALIGN_TOP:
ialign = eBiffVATop;
break;
case VALIGN_BOTTOM:
ialign = eBiffVABottom;
break;
case VALIGN_CENTER:
ialign = eBiffVACenter;
break;
case VALIGN_JUSTIFY:
ialign = eBiffVAJustify;
break;
default:
ialign = eBiffVATop;
}
return ialign;
}
/**
* Map Gnumeric orientation to Excel bitfield
* @orientation Gnumeric orientation
*
* See S59E1E.HTM
**/
static guint
orientation_to_excel (StyleOrientation orientation)
{
guint ior;
switch (orientation) {
case ORIENT_HORIZ:
ior = eBiffOHoriz;
break;
case ORIENT_VERT_HORIZ_TEXT:
ior = eBiffOVertHorizText;
break;
case ORIENT_VERT_VERT_TEXT:
ior = eBiffOVertVertText;
break;
case ORIENT_VERT_VERT_TEXT2:
ior = eBiffOVertVertText2;
break;
default:
ior = eBiffOHoriz;
}
return ior;
}
/**
* Map Gnumeric border type to Excel bitfield
* @btype Gnumeric border type
* @ver Biff version
*
* See S59E1E.HTM
**/
static guint
border_type_to_excel (StyleBorderType btype, eBiff_version ver)
{
guint ibtype = btype;
if (btype <= STYLE_BORDER_NONE)
ibtype = STYLE_BORDER_NONE;
if (ver <= eBiffV7) {
if (btype > STYLE_BORDER_HAIR)
ibtype = STYLE_BORDER_MEDIUM;
}
return ibtype;
}
/**
* Do yucky stuff with fill foreground and background colors
* @xfd XF data
*
* Solid fill patterns seem to reverse the meaning of foreground and
* background
*
* FIXME:
* Import side code does not flip colors if xfd->pat_foregnd_col == 0.
*
* This table shows import side behaviour when fill pattern is 1:
*