Commit e19a6a25 authored by Michael Meeks's avatar Michael Meeks

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>
* src/sheet.c (sheet_get_extent_cb): Fix biggest leak ever seen,
......
......@@ -6,7 +6,7 @@ Michael:
Jon:
* Lots of Excel style export work:
format, font, colors
format, font, colors, borders, alignment, wrap, rotation.
JP:
* 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>
* 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>
* ms-summary.c (ms_summary_write): comment out DocumentSummary.
......
......@@ -24,6 +24,7 @@ libexcel_a_SOURCES = \
ms-escher.h \
ms-excel-util.c \
ms-excel-util.h \
ms-excel-xf.h \
ms-excel-read.c \
ms-excel-read.h \
ms-excel-write.c \
......
......@@ -48,6 +48,39 @@ typedef enum _eBiffFontUnderline
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
{
eBiff_version version ;
......
......@@ -18,9 +18,9 @@
#include "ms-escher.h"
#include "print-info.h"
#include "selection.h"
#include "border.h"
#include "utils.h" /* for cell_name */
#include "ranges.h"
#include "ms-excel-xf.h"
/* #define NO_DEBUG_EXCEL */
......@@ -44,14 +44,6 @@ static ExcelSheet *ms_excel_sheet_new (ExcelWorkbook *wb,
static void ms_excel_workbook_attach (ExcelWorkbook *wb,
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
ms_excel_unexpected_biff (BiffQuery *q, char const *const state)
......@@ -948,30 +940,6 @@ ms_excel_palette_destroy (ExcelPalette *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
* NB. index 4 is omitted supposedly for backwards compatiblity
......@@ -1128,6 +1096,14 @@ ms_excel_get_style_from_xf (ExcelSheet *sheet, guint16 xfidx)
mstyle_set_pattern (mstyle, xf->fill_pattern_idx);
/* 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) {
pattern_index = xf->pat_backgnd_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:
* Jon K Hellan (hellan@acm.org)
......@@ -46,3 +46,4 @@ gpointer
two_way_table_idx_to_key (const TwoWayTable *table, gint idx);
#endif
......@@ -43,6 +43,7 @@
#include "ms-biff.h"
#include "excel.h"
#include "ms-excel-write.h"
#include "ms-excel-xf.h"
#include "ms-formula-write.h"
/**
......@@ -641,15 +642,23 @@ put_color (ExcelWorkbook *wb, const StyleColor *c)
/**
* Add colors in mstyle to palette
*
* FIXME: Border colors not yet included
**/
static void
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_BACK));
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)
*
* Style color is *not* unrefed. This is correct
**/
static ExcelFont *excel_font_new (MStyle *st)
static ExcelFont *
excel_font_new (MStyle *st)
{
ExcelFont *f;
StyleColor *c;
......@@ -840,6 +850,17 @@ fonts_init (ExcelWorkbook *wb)
= 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
**/
......@@ -854,8 +875,7 @@ fonts_free (ExcelWorkbook *wb)
twt = wb->fonts->two_way_table;
if (twt) {
for (i = 0; i < twt->idx_to_key->len; i++) {
f = two_way_table_idx_to_key (twt,
i + twt->base);
f = fonts_get_font (wb, i + twt->base);
excel_font_free (f);
}
two_way_table_free (twt);
......@@ -944,7 +964,7 @@ write_font (ExcelWorkbook *wb, BiffPut *bp, const ExcelFont *f)
guint16 grbit = 0;
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*/
guint8 underline = 0; /* No underline */
guint8 family = 0;
......@@ -995,14 +1015,14 @@ write_fonts (ExcelWorkbook *wb, BiffPut *bp)
for (lp = 0; lp < nfonts; lp++) {
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);
}
}
if (nfonts < FONTS_MINIMUM + 1) { /* Add 1 to account for skip */
/* 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++) {
if (lp != FONT_SKIP) {
/* FONT_SKIP is invalid, skip it */
......@@ -1070,6 +1090,18 @@ formats_init (ExcelWorkbook *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
**/
......@@ -1084,8 +1116,8 @@ formats_free (ExcelWorkbook *wb)
twt = wb->formats->two_way_table;
if (twt) {
for (i = 0; i < twt->idx_to_key->len; i++) {
format = two_way_table_idx_to_key
(twt, i + twt->base);
format = formats_get_format (wb,
i + twt->base);
g_free (format);
}
two_way_table_free (twt);
......@@ -1147,8 +1179,7 @@ static void
write_format (ExcelWorkbook *wb, BiffPut *bp, int fidx)
{
guint8 data[64];
TwoWayTable *twt = wb->formats->two_way_table;
char *format = two_way_table_idx_to_key (twt, fidx);
char *format = formats_get_format(wb, fidx);
#ifndef NO_DEBUG_EXCEL
if (ms_excel_write_debug > 1) {
......@@ -1270,6 +1301,18 @@ xf_init (ExcelWorkbook *wb)
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
**/
......@@ -1284,8 +1327,7 @@ xf_free (ExcelWorkbook *wb)
if (wb->xf->two_way_table) {
twt = wb->xf->two_way_table;
for (i = 0; i < twt->idx_to_key->len; i++) {
st = two_way_table_idx_to_key (twt,
i + twt->base);
st = xf_get_mstyle (wb, i + twt->base);
mstyle_unref (st);
}
two_way_table_free (wb->xf->two_way_table);
......@@ -1459,6 +1501,339 @@ map_pattern_index_to_excel (int const 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:
*
* bg(file) fg(file) bg(internal) fg(internal)
* == 0 == 0 0 0
* == 0 != 0 fg(file) 0
* != 0 == 0 bg(file) 0
* != 0 != 0 fg(file) bg(file)
*
* We can see from the table that bg(internal) is 0 only if fg(internal)
* is also 0 .
*
* The closest write side analogue is to flip if fg(internal) != 0.
* But we have to do something special for bg(internal) == 0. In this
* situation, I have seen Excel flip colors, but use 8 rather than 0
* for black, i.e. fg(file) = 8, bg(file) = fg(internal). This is what
* we'll do, although I don't know if Excel always does.
*
* This makes us compatible with our owin import code. The import
* side test can't be correct, though. Excel displays fg(file) = 0,
* bg(file) = 1 as black (=0) background. Gnumeric displays background
* as white, since fg(file) = 0. But I'll leave this ugliness in for
* now.
**/
static void
fixup_fill_colors (BiffXFData *xfd)
{
guint8 c;
if (xfd->fill_pattern_idx == 1
&& xfd->pat_foregnd_col != PALETTE_BLACK) {
c = xfd->pat_backgnd_col;
if (c == PALETTE_BLACK)
c = PALETTE_ALSO_BLACK;
xfd->pat_backgnd_col = xfd->pat_foregnd_col;
xfd->pat_foregnd_col = c;
}
}
/**
* Fill out map of differences to parent style *
* @wb workbook
* @xfd XF data
* @parentst parent style (Not used at present)
*
* See S59E1E.HTM
*
* FIXME
* At present, we are using a fixed XF record 0, which is the parent of all
* others. Can we use the actual default style as XF 0?
**/
static void
get_xf_differences (ExcelWorkbook *wb, BiffXFData *xfd, MStyle *parentst)
{
int i;
xfd->differences = 0;
if (xfd->format_idx != FORMAT_MAGIC)
xfd->differences |= 1 << eBiffDFormatbit;
if (xfd->font_idx != FONT_MAGIC)
xfd->differences |= 1 << eBiffDFontbit;
/* hmm. documentation doesn't say that alignment bit is
affected by vertical alignment, but it's a reasonable guess */
if (xfd->halign != HALIGN_GENERAL || xfd->valign != VALIGN_TOP
|| xfd->wrap)
xfd->differences |= 1 << eBiffDAlignbit;
for (i = 0; i < STYLE_ORIENT_MAX; i++) {
/* Should we also test colors? */
if (xfd->border_type[i] != BORDER_MAGIC) {
xfd->differences |= 1 << eBiffDBorderbit;
break;
}
}
if (xfd->pat_foregnd_col != PALETTE_BLACK
|| xfd->pat_backgnd_col != PALETTE_WHITE
|| xfd->fill_pattern_idx != FILL_MAGIC)
xfd->differences |= 1 << eBiffDFillbit;
if (xfd->hidden || xfd->locked)
xfd->differences |= 1 << eBiffDLockbit;
}
#ifndef NO_DEBUG_EXCEL
/**
* Log XF data for a record about to be written
**/
static void log_xf_data (ExcelWorkbook *wb, BiffXFData *xfd, int idx)
{
if (ms_excel_write_debug > 1) {
int i;
ExcelFont *f = fonts_get_font (wb, xfd->font_idx);
printf ("Writing xf 0x%x : font 0x%x (%s), format 0x%x (%s)\n",
idx, xfd->font_idx, excel_font_to_string (f),
xfd->format_idx, xfd->style_format->format);
printf (" hor align 0x%x, ver align 0x%x, wrap %s\n",
xfd->halign, xfd->valign, xfd->wrap ? "on" : "off");
printf (" fill fg color idx 0x%x, fill bg color idx 0x%x"
", pattern (Excel) %d\n",
xfd->pat_foregnd_col, xfd->pat_backgnd_col,
xfd->fill_pattern_idx);
for (i = STYLE_TOP; i < STYLE_ORIENT_MAX; i++) {
if (xfd->border_type[i] != STYLE_BORDER_NONE) {
printf (" border_type[%d] : 0x%x"
" border_color[%d] : 0x%x\n",
i, xfd->border_type[i],
i, xfd->border_color[i]);
}
}
printf (" difference bits: 0x%x\n", xfd->differences);
}
}
#endif
/**
* Build XF data for a style
* @wb workbook