/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* ppt-parsing-helper.c -
* Copyright (C) 2004, Christopher James Lahey
*
* Authors:
* Christopher James Lahey <clahey@ximian.com>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU Library General Public
* License as published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this file; if not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
**/
#include <config.h>
#include "ppt-parsing-helper.h"
#include <gsf/gsf-utils.h>
#include <goffice/utils/go-units.h>
#include <string.h>
enum {
TEXT_FIELD_PROPERTY_EXISTS_BOLD = 0x00000001,
TEXT_FIELD_PROPERTY_EXISTS_ITALIC = 0x00000002,
TEXT_FIELD_PROPERTY_EXISTS_UNDERLINE = 0x00000004,
TEXT_FIELD_PROPERTY_EXISTS_SHADOW = 0x00000010,
TEXT_FIELD_PROPERTY_EXISTS_STRIKEOUT = 0x00000100,
TEXT_FIELD_PROPERTY_EXISTS_RELIEF = 0x00000200,
TEXT_FIELD_PROPERTY_EXISTS_RESET_NUMBERING = 0x00000400,
TEXT_FIELD_PROPERTY_EXISTS_ENABLE_NUMBERING1 = 0x00000800,
TEXT_FIELD_PROPERTY_EXISTS_ENABLE_NUMBERING2 = 0x00001000,
TEXT_FIELD_PROPERTY_EXISTS_FLAGS = 0x0000ffff,
TEXT_FIELD_PROPERTY_EXISTS_FONT = 0x00010000,
TEXT_FIELD_PROPERTY_EXISTS_FONT_SIZE = 0x00020000,
TEXT_FIELD_PROPERTY_EXISTS_COLOR = 0x00040000,
TEXT_FIELD_PROPERTY_EXISTS_OFFSET = 0x00080000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN1 = 0x00100000,
TEXT_FIELD_PROPERTY_EXISTS_ASIAN_OR_COMPLEX = 0x00200000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN2 = 0x00400000,
TEXT_FIELD_PROPERTY_EXISTS_SYMBOL = 0x00800000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN3 = 0x01000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN4 = 0x02000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN5 = 0x04000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN6 = 0x08000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN7 = 0x10000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN8 = 0x20000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN9 = 0x40000000,
TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN10 = 0x80000000,
} TextFieldPropExists;
enum {
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FLAGS = 0x0000000f,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_CHARACTER = 0x00000080,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FAMILY = 0x00000010,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_SIZE = 0x00000040,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_COLOR = 0x00000020,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ALIGNMENT = 0x00000800,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_1 = 0x00000400,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_2 = 0x00000200,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_3 = 0x00000100,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_LINE_FEED = 0x00001000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_ABOVE = 0x00002000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_BELOW = 0x00004000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_4 = 0x00008000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_5 = 0x00010000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ASIAN_UNKNOWN = 0x000e0000,
TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BIDI = 0x00200000,
} TextFieldParagraphPropExists;
enum {
PARAGRAPH_ALIGNMENT_LEFT = 0,
PARAGRAPH_ALIGNMENT_CENTER = 1,
PARAGRAPH_ALIGNMENT_RIGHT = 2,
PARAGRAPH_ALIGNMENT_JUSTIFY = 3,
} ParagraphAlignment;
void
ppt_parsing_helper_parse_style_text_prop_atom (const char *data, int length, GodTextModel *model, GPtrArray *fonts)
{
int indent_type = 0;
int i = 0;
int position = 0;
int text_len;
GodParagraphAttributes *para_attr;
const char *text = god_text_model_get_text (model);
if (NULL == text)
return;
for (text_len = strlen (text); position < text_len ; ) {
int sublen = 0;
int end;
guint fields;
int section_length = GSF_LE_GET_GUINT32 (data + i);
para_attr = god_paragraph_attributes_new ();
sublen += 4;
indent_type = GSF_LE_GET_GUINT16 (data + i + sublen);
sublen += 2;
fields = GSF_LE_GET_GUINT32 (data + i + sublen);
sublen += 4;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FLAGS) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_CHARACTER) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_FAMILY) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_SIZE) {
sublen += 2;
#if 0 /* From OOo */
if ( ! ( ( nMask & ( 1 << PPT_ParaAttr_BuHardHeight ) )
&& ( nBulFlg && ( 1 << PPT_ParaAttr_BuHardHeight ) ) ) )
aSet.mnAttrSet ^= 0x40;
#endif
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BULLET_COLOR) {
sublen += 4;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ALIGNMENT) {
g_object_set (para_attr, "alignment", (guint) GSF_LE_GET_GUINT16 (data + i + sublen), NULL);
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_1) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_2) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_3) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_LINE_FEED) {
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_ABOVE) {
int space;
double space_before;
space = GSF_LE_GET_GUINT16 (data + i + sublen);
if (space & 0x8000) {
space = 0x10000 - space;
}
space_before = space * (UN_PER_IN / 576.0);
g_object_set (para_attr,
"space_before", space_before,
NULL);
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_SPACING_BELOW) {
int space;
double space_after;
space = GSF_LE_GET_GUINT16 (data + i + sublen);
if (space & 0x8000) {
space = 0x10000 - space;
}
space_after = space * (UN_PER_IN / 576.0);
g_object_set (para_attr,
"space_after", space_after,
NULL);
sublen += 2;
}
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_4)
sublen += 2;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_UNKNOWN_5)
sublen += 2;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_ASIAN_UNKNOWN)
sublen += 2;
if (fields & TEXT_FIELD_PARAGRAPH_PROPERTY_EXISTS_BIDI)
sublen += 2;
end = position;
while (section_length && end < text_len) {
section_length --;
end += g_utf8_skip[(guchar) text[end]];
}
god_text_model_set_paragraph_attributes (model,
position,
end,
para_attr);
god_text_model_set_indent (model,
position,
end,
indent_type);
g_object_unref (para_attr);
i += sublen;
position = end;
}
position = 0;
while (position < text_len) {
int sublen = 0;
int end;
GList *attrs = NULL, *iterator;
guint fields;
int section_length = GSF_LE_GET_GUINT32 (data + i);
sublen += 4;
fields = GSF_LE_GET_GUINT32 (data + i + sublen);
sublen += 4;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_FLAGS) {
guint text_fields = GSF_LE_GET_GUINT16 (data + i + sublen);
if (fields & TEXT_FIELD_PROPERTY_EXISTS_BOLD)
attrs = g_list_append (attrs, pango_attr_weight_new
(text_fields & TEXT_FIELD_PROPERTY_EXISTS_BOLD ?
PANGO_WEIGHT_BOLD :
PANGO_WEIGHT_NORMAL));
if (fields & TEXT_FIELD_PROPERTY_EXISTS_ITALIC)
attrs = g_list_append (attrs, pango_attr_style_new
(text_fields & TEXT_FIELD_PROPERTY_EXISTS_ITALIC ?
PANGO_STYLE_ITALIC :
PANGO_STYLE_NORMAL));
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNDERLINE)
attrs = g_list_append (attrs, pango_attr_underline_new
(text_fields & TEXT_FIELD_PROPERTY_EXISTS_UNDERLINE ?
PANGO_UNDERLINE_SINGLE :
PANGO_UNDERLINE_NONE));
#if 0
if (text_fields & 0x10)
printf ("shadow\n");
if (text_fields & 0x200)
printf ("relief\n");
#endif
sublen += 2;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_FONT) {
guint font_index = GSF_LE_GET_GUINT16 (data + i + sublen);
if (font_index < fonts->len &&
g_ptr_array_index (fonts, font_index)) {
attrs = g_list_append (attrs, pango_attr_family_new
(g_ptr_array_index (fonts, font_index)));
}
sublen += 2;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_ASIAN_OR_COMPLEX)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN2)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_SYMBOL)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_FONT_SIZE) {
attrs = g_list_append (attrs, pango_attr_size_new
(GSF_LE_GET_GUINT16 (data + i + sublen) * PANGO_SCALE * 72 / 96)); /* Powerpoint fonts are specified in pixels at 96 dpi. */
sublen += 2;
}
if (fields & (TEXT_FIELD_PROPERTY_EXISTS_COLOR)) {
#if 0
printf ("color: #");
printf ("%02X", data[i + sublen++]);
printf ("%02X", data[i + sublen++]);
printf ("%02X", data[i + sublen++]);
printf ("\n");
sublen ++;
#endif
sublen += 4;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_OFFSET) {
#if 0
int offset = GSF_LE_GET_GUINT16 (data + i + sublen - 2);
if (offset & 0x8000)
offset -= 0x10000;
printf ("offset: %d\n", offset);
#endif
sublen += 2;
}
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN1)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN3)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN4)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN5)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN6)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN7)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN8)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN9)
sublen += 2;
if (fields & TEXT_FIELD_PROPERTY_EXISTS_UNKNOWN10)
sublen += 2;
end = position;
while (section_length && end < text_len) {
section_length --;
end += g_utf8_skip[(guchar) text[end]];
}
god_text_model_set_pango_attributes (model,
position,
end,
attrs);
for (iterator = attrs; iterator; iterator = iterator->next)
pango_attribute_destroy (iterator->data);
g_list_free (attrs);
position = end;
i += sublen;
}
}
syntax highlighted by Code2HTML, v. 0.9.1