--- psiconv/trunk/lib/psiconv/generate_layout.c 2000/12/25 00:26:53 76 +++ psiconv/trunk/lib/psiconv/generate_layout.c 2014/10/22 19:53:40 351 @@ -1,6 +1,6 @@ /* generate_layout.c - Part of psiconv, a PSION 5 file formats converter - Copyright (c) 2000 Frodo Looijaard + Copyright (c) 2000-2014 Frodo Looijaard This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,47 +20,84 @@ #include "config.h" #include "compat.h" +#include + #include "generate_routines.h" #include "error.h" -int psiconv_write_color(psiconv_buffer buf, const psiconv_color value) +#ifdef DMALLOC +#include +#endif + + +int psiconv_write_color(const psiconv_config config, psiconv_buffer buf, + int lev, const psiconv_color value) { int res; + + psiconv_progress(config,lev,0,"Writing color"); + if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null color"); - return -PSICONV_E_GENERATE; + psiconv_error(config,lev,0,"Null color"); + res = -PSICONV_E_GENERATE; + goto ERROR; } - if ((res = psiconv_write_u8(buf,value->red))) - return res; - if ((res = psiconv_write_u8(buf,value->green))) - return res; - return psiconv_write_u8(buf,value->blue); + if ((res = psiconv_write_u8(config,buf,lev+1,value->red))) + goto ERROR; + if ((res = psiconv_write_u8(config,buf,lev+1,value->green))) + goto ERROR; + if ((res = psiconv_write_u8(config,buf,lev+1,value->blue))) + goto ERROR; + psiconv_progress(config,lev,0,"End of color"); + return 0; + +ERROR: + psiconv_error(config,lev,0,"Writing of color failed"); + return res; } -int psiconv_write_font(psiconv_buffer buf, const psiconv_font value) +int psiconv_write_font(const psiconv_config config, psiconv_buffer buf, + int lev, const psiconv_font value) { - int res; + int res,len; + + psiconv_progress(config,lev,0,"Writing font"); if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null font"); - return -PSICONV_E_GENERATE; + psiconv_error(config,0,psiconv_buffer_length(buf),"Null font"); + res = -PSICONV_E_GENERATE; + goto ERROR; } - if ((res = psiconv_write_string(buf,value->name))) - return res; - return psiconv_write_u8(buf,value->screenfont); + len = psiconv_unicode_strlen(value->name); + if ((res = psiconv_write_u8(config,buf,lev+1,len+1))) + goto ERROR; + if ((res = psiconv_write_charlist(config,buf,lev+1,value->name))) + goto ERROR; + if ((res = psiconv_write_u8(config,buf,lev+1,value->screenfont))) + goto ERROR; + psiconv_progress(config,lev,0,"End of font"); + return 0; + +ERROR: + psiconv_error(config,lev,0,"Writing of font failed"); + return res; } -int psiconv_write_border(psiconv_buffer buf, const psiconv_border value) +int psiconv_write_border(const psiconv_config config, psiconv_buffer buf,int lev, const psiconv_border value) { int res; + psiconv_progress(config,lev,0,"Writing border"); + if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null border"); - return -PSICONV_E_GENERATE; + psiconv_error(config,lev,0,"Null border"); + res = -PSICONV_E_GENERATE; + goto ERROR; } if (value->kind > psiconv_border_dotdotdashed) - psiconv_warn(0,psiconv_list_length(buf), + psiconv_warn(config,lev,0, "Unknown border kind (%d); assuming none",value->kind); - if ((res =psiconv_write_u8(buf,value->kind == psiconv_border_none?0: + if ((res =psiconv_write_u8(config,buf,lev+1, + value->kind == psiconv_border_none?0: value->kind == psiconv_border_solid?1: value->kind == psiconv_border_double?2: value->kind == psiconv_border_dotted?3: @@ -68,435 +105,434 @@ value->kind == psiconv_border_dotdashed?5: value->kind == psiconv_border_dotdotdashed?6: 0))) - return res; - if ((res = psiconv_write_size(buf,(value->kind == psiconv_border_solid) || - (value->kind == psiconv_border_double) ? - value->thickness:1.0/20.0))) - return res; - if ((res = psiconv_write_color(buf,value->color))) - return res; - // Unknown byte - return psiconv_write_u8(buf,1); + goto ERROR; + if ((res = psiconv_write_size(config,buf,lev+1, + (value->kind == psiconv_border_solid) || + (value->kind == psiconv_border_double) ? + value->thickness:1.0/20.0))) + goto ERROR; + if ((res = psiconv_write_color(config,buf,lev+1,value->color))) + goto ERROR; + /* Unknown byte */ + if ((res = psiconv_write_u8(config,buf,lev+1,1))) + goto ERROR; + psiconv_progress(config,lev,0,"End of border"); + return 0; + +ERROR: + psiconv_error(config,lev,0,"Writing of border failed"); + return res; } -int psiconv_write_bullet(psiconv_buffer buf, const psiconv_bullet value) +int psiconv_write_bullet(const psiconv_config config, psiconv_buffer buf,int lev, const psiconv_bullet value) { int res; psiconv_buffer extra_buf; + + psiconv_progress(config,lev,0,"Writing bullet"); + if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null bullet"); - return -PSICONV_E_GENERATE; + psiconv_error(config,0,psiconv_buffer_length(buf),"Null bullet"); + res = -PSICONV_E_GENERATE; + goto ERROR1; } - if (!(extra_buf = psiconv_new_buffer())) - return -PSICONV_E_NOMEM; - if ((res = psiconv_write_size(extra_buf,value->font_size))) - goto ERROR; - if ((res = psiconv_write_u8(extra_buf,value->character))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->on))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->indent))) - goto ERROR; - if ((res = psiconv_write_color(extra_buf,value->color))) - goto ERROR; - if ((res = psiconv_write_font(extra_buf,value->font))) - goto ERROR; - - if ((res = psiconv_write_u8(buf,psiconv_list_length(extra_buf)))) - goto ERROR; - res = psiconv_list_concat(buf,extra_buf); + if (!(extra_buf = psiconv_buffer_new())) { + psiconv_error(config,lev+1,0,"Out of memory error"); + res = -PSICONV_E_NOMEM; + goto ERROR1; + } + if ((res = psiconv_write_size(config,extra_buf,lev+1,value->font_size))) + goto ERROR2; + if ((res = psiconv_unicode_write_char(config,extra_buf,lev+1, + value->character))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->indent))) + goto ERROR2; + if ((res = psiconv_write_color(config,extra_buf,lev+1,value->color))) + goto ERROR2; + if ((res = psiconv_write_font(config,extra_buf,lev+1,value->font))) + goto ERROR2; + + if ((res = psiconv_write_u8(config,buf,lev+1,psiconv_buffer_length(extra_buf)))) + goto ERROR2; + if ((res = psiconv_buffer_concat(buf,extra_buf))) { + psiconv_error(config,lev+1,0,"Out of memory error"); + goto ERROR2; + } -ERROR: - psiconv_free_buffer(extra_buf); +ERROR2: + psiconv_buffer_free(extra_buf); +ERROR1: + if (res) + psiconv_error(config,lev,0,"Writing of bullet failed"); + else + psiconv_progress(config,lev,0,"End of bullet"); return res; } -int psiconv_write_tab(psiconv_buffer buf,psiconv_tab value) +int psiconv_write_tab(const psiconv_config config, psiconv_buffer buf,int lev, psiconv_tab value) { int res; + + psiconv_progress(config,lev,0,"Writing tab"); + if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null tab"); - return -PSICONV_E_GENERATE; + psiconv_error(config,lev,0,"Null tab"); + res = -PSICONV_E_GENERATE; + goto ERROR; } - if ((res = psiconv_write_length(buf,value->location))) - return res; + if ((res = psiconv_write_length(config,buf,lev+1,value->location))) + goto ERROR; if ((value->kind != psiconv_tab_left) && (value->kind != psiconv_tab_right) && (value->kind != psiconv_tab_centre)) - psiconv_warn(0,psiconv_list_length(buf), + psiconv_warn(config,lev,0, "Unknown tab kind (%d); assuming left",value->kind); - return psiconv_write_u8(buf, value->kind == psiconv_tab_right?2: - value->kind == psiconv_tab_centre?3:1); + if ((res = psiconv_write_u8(config,buf,lev+1, + value->kind == psiconv_tab_right?2: + value->kind == psiconv_tab_centre?3:1))) + goto ERROR; + psiconv_progress(config,lev,0,"End of tab"); + return 0; +ERROR: + psiconv_error(config,lev,0,"Writing of tab failed"); + return res; } -int psiconv_write_paragraph_layout_list(psiconv_buffer buf, +int psiconv_write_paragraph_layout_list(const psiconv_config config, + psiconv_buffer buf,int lev, psiconv_paragraph_layout value, psiconv_paragraph_layout base) { - int res,i,tabs_different; + int res,i; psiconv_buffer extra_buf; - psiconv_tab value_tab,base_tab; + psiconv_tab tab; + psiconv_progress(config,lev,0,"Writing paragraph layout list"); + if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null paragraph layout list"); - return -PSICONV_E_GENERATE; + psiconv_error(config,lev,0,"Null paragraph layout list"); + res = -PSICONV_E_GENERATE; + goto ERROR1; + } + if (!(extra_buf = psiconv_buffer_new())) { + res = -PSICONV_E_NOMEM; + goto ERROR1; } - if (!(extra_buf = psiconv_new_buffer())) - return -PSICONV_E_NOMEM; - if (!base || !base->back_color || !value->back_color || - (value->back_color->red != base->back_color->red) || - (value->back_color->green != base->back_color->green) || - (value->back_color->blue != base->back_color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x01))) - goto ERROR; - if ((res = psiconv_write_color(extra_buf,value->back_color))) - goto ERROR; + if (!base || psiconv_compare_color(base->back_color,value->back_color)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x01))) + goto ERROR2; + if ((res = psiconv_write_color(config,extra_buf,lev+1,value->back_color))) + goto ERROR2; } if (!base || (value->indent_left != base->indent_left)) { - if ((res = psiconv_write_u8(extra_buf,0x02))) - goto ERROR; - if ((res = psiconv_write_length(extra_buf,value->indent_left))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x02))) + goto ERROR2; + if ((res = psiconv_write_length(config,extra_buf,lev+1,value->indent_left))) + goto ERROR2; } if (!base || (value->indent_right != base->indent_right)) { - if ((res = psiconv_write_u8(extra_buf,0x03))) - goto ERROR; - if ((res = psiconv_write_length(extra_buf,value->indent_right))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x03))) + goto ERROR2; + if ((res = psiconv_write_length(config,extra_buf,lev+1,value->indent_right))) + goto ERROR2; } if (!base || (value->indent_first != base->indent_first)) { - if ((res = psiconv_write_u8(extra_buf,0x04))) - goto ERROR; - if ((res = psiconv_write_length(extra_buf,value->indent_first))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x04))) + goto ERROR2; + if ((res = psiconv_write_length(config,extra_buf,lev+1,value->indent_first))) + goto ERROR2; } if (!base || (value->justify_hor != base->justify_hor)) { - if ((res = psiconv_write_u8(extra_buf,0x05))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x05))) + goto ERROR2; if ((value->justify_hor < psiconv_justify_left) || (value->justify_hor > psiconv_justify_full)) - psiconv_warn(0,psiconv_list_length(buf), + psiconv_warn(config,lev,0, "Unknown horizontal justify (%d); assuming left", value->justify_hor); - if ((res = psiconv_write_u8(extra_buf, + if ((res = psiconv_write_u8(config,extra_buf,lev+1, value->justify_hor == psiconv_justify_centre?1: value->justify_hor == psiconv_justify_right?2: value->justify_hor == psiconv_justify_full?3:0))) - goto ERROR; + goto ERROR2; } if (!base || (value->justify_ver != base->justify_ver)) { - if ((res = psiconv_write_u8(extra_buf,0x06))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x06))) + goto ERROR2; if ((value->justify_ver < psiconv_justify_top) || (value->justify_ver > psiconv_justify_bottom)) - psiconv_warn(0,psiconv_list_length(buf), - "Unknown vertical justify (%d); assuming middle", + psiconv_warn(config,0,psiconv_buffer_length(buf), + "Unknown vertical justify (%d); assuming top", value->justify_ver); - if ((res = psiconv_write_u8(extra_buf, - value->justify_ver == psiconv_justify_centre?1: - value->justify_ver == psiconv_justify_right?2:0))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1, + value->justify_ver == psiconv_justify_middle?1: + value->justify_ver == psiconv_justify_bottom?2:0))) + goto ERROR2; } if (!base || (value->linespacing != base->linespacing)) { - if ((res = psiconv_write_u8(extra_buf,0x07))) - goto ERROR; - if ((res = psiconv_write_size(extra_buf,value->linespacing))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x07))) + goto ERROR2; + if ((res = psiconv_write_size(config,extra_buf,lev+1,value->linespacing))) + goto ERROR2; } if (!base || (value->linespacing_exact != base->linespacing_exact)) { - if ((res = psiconv_write_u8(extra_buf,0x08))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->linespacing_exact))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x08))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->linespacing_exact))) + goto ERROR2; } if (!base || (value->space_above != base->space_above)) { - if ((res = psiconv_write_u8(extra_buf,0x09))) - goto ERROR; - if ((res = psiconv_write_size(extra_buf,value->space_above))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x09))) + goto ERROR2; + if ((res = psiconv_write_size(config,extra_buf,lev+1,value->space_above))) + goto ERROR2; } if (!base || (value->space_below != base->space_below)) { - if ((res = psiconv_write_u8(extra_buf,0x0a))) - goto ERROR; - if ((res = psiconv_write_size(extra_buf,value->space_below))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0a))) + goto ERROR2; + if ((res = psiconv_write_size(config,extra_buf,lev+1,value->space_below))) + goto ERROR2; } if (!base || (value->keep_together != base->keep_together)) { - if ((res = psiconv_write_u8(extra_buf,0x0b))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->keep_together))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0b))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->keep_together))) + goto ERROR2; } if (!base || (value->keep_with_next != base->keep_with_next)) { - if ((res = psiconv_write_u8(extra_buf,0x0c))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->keep_with_next))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0c))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->keep_with_next))) + goto ERROR2; } if (!base || (value->on_next_page != base->on_next_page)) { - if ((res = psiconv_write_u8(extra_buf,0x0d))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->on_next_page))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0d))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->on_next_page))) + goto ERROR2; } if (!base || (value->no_widow_protection != base->no_widow_protection)) { - if ((res = psiconv_write_u8(extra_buf,0x0e))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->no_widow_protection))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0e))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->no_widow_protection))) + goto ERROR2; + } + + if (!base || (value->wrap_to_fit_cell != base->wrap_to_fit_cell)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0f))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->wrap_to_fit_cell))) + goto ERROR2; } if (!base || (value->border_distance != base->border_distance)) { - if ((res = psiconv_write_u8(extra_buf,0x10))) - goto ERROR; - if ((res = psiconv_write_length(extra_buf,value->border_distance))) - goto ERROR; - } - - if (!base || !value->top_border || !base->top_border || - !value->top_border->color || !base->top_border->color || - (value->top_border->kind != base->top_border->kind) || - (value->top_border->thickness != base->top_border->thickness) || - (value->top_border->color->red != base->top_border->color->red) || - (value->top_border->color->green != base->top_border->color->green) || - (value->top_border->color->blue != base->top_border->color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x11))) - goto ERROR; - if ((res = psiconv_write_border(extra_buf,value->top_border))) - goto ERROR; - } - - if (!base || !value->top_border || !base->top_border || - !value->top_border->color || !base->top_border->color || - (value->top_border->kind != base->top_border->kind) || - (value->top_border->thickness != base->top_border->thickness) || - (value->top_border->color->red != base->top_border->color->red) || - (value->top_border->color->green != base->top_border->color->green) || - (value->top_border->color->blue != base->top_border->color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x12))) - goto ERROR; - if ((res = psiconv_write_border(extra_buf,value->top_border))) - goto ERROR; - } - - if (!base || !value->left_border || !base->left_border || - !value->left_border->color || !base->left_border->color || - (value->left_border->kind != base->left_border->kind) || - (value->left_border->thickness != base->left_border->thickness) || - (value->left_border->color->red != base->left_border->color->red) || - (value->left_border->color->green != base->left_border->color->green) || - (value->left_border->color->blue != base->left_border->color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x13))) - goto ERROR; - if ((res = psiconv_write_border(extra_buf,value->left_border))) - goto ERROR; - } - - if (!base || !value->right_border || !base->right_border || - !value->right_border->color || !base->right_border->color || - (value->right_border->kind != base->right_border->kind) || - (value->right_border->thickness != base->right_border->thickness) || - (value->right_border->color->red != base->right_border->color->red) || - (value->right_border->color->green != - base->right_border->color->green) || - (value->right_border->color->blue != base->right_border->color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x14))) - goto ERROR; - if ((res = psiconv_write_border(extra_buf,value->right_border))) - goto ERROR; - } - - if (!base || !value->bullet || !base->bullet || - !value->bullet->color || !base->bullet->color || - !value->bullet->font || !base->bullet->font || - !value->bullet->font->name || !base->bullet->font->name || - (value->bullet->on != base->bullet->on) || - (value->bullet->font_size != base->bullet->font_size) || - (value->bullet->character != base->bullet->character) || - (value->bullet->indent != base->bullet->indent) || - (value->bullet->color->red != base->bullet->color->red) || - (value->bullet->color->green != base->bullet->color->green) || - (value->bullet->color->blue != base->bullet->color->blue) || - (value->bullet->font->screenfont != base->bullet->font->screenfont) || - strcmp(value->bullet->font->name,base->bullet->font->name)) { - if ((res = psiconv_write_u8(extra_buf,0x15))) - goto ERROR; - if ((res = psiconv_write_bullet(extra_buf,value->bullet))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x10))) + goto ERROR2; + if ((res = psiconv_write_length(config,extra_buf,lev+1,value->border_distance))) + goto ERROR2; + } + + if (!base || psiconv_compare_border(value->top_border,base->top_border)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x11))) + goto ERROR2; + if ((res = psiconv_write_border(config,extra_buf,lev+1,value->top_border))) + goto ERROR2; + } + + if (!base || psiconv_compare_border(value->bottom_border, + base->bottom_border)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x12))) + goto ERROR2; + if ((res = psiconv_write_border(config,extra_buf,lev+1,value->bottom_border))) + goto ERROR2; + } + + if (!base || psiconv_compare_border(value->left_border, + base->left_border)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x13))) + goto ERROR2; + if ((res = psiconv_write_border(config,extra_buf,lev+1,value->left_border))) + goto ERROR2; + } + + if (!base || psiconv_compare_border(value->right_border, + base->right_border)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x14))) + goto ERROR2; + if ((res = psiconv_write_border(config,extra_buf,lev+1,value->right_border))) + goto ERROR2; + } + + if (!base || psiconv_compare_bullet(value->bullet, + base->bullet)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x15))) + goto ERROR2; + if ((res = psiconv_write_bullet(config,extra_buf,lev+1,value->bullet))) + goto ERROR2; } if (!value->tabs || !value->tabs->extras) { - psiconv_warn(0,psiconv_list_length(buf),"Null tabs"); + psiconv_error(config,0,psiconv_buffer_length(buf),"Null tabs"); res = -PSICONV_E_GENERATE; - goto ERROR; + goto ERROR2; } + /* It is not entirely clear how tabs are inherited. For now, I assume if there is any difference at all, we will have to generate both the normal tab-interval, and all specific tabs */ - tabs_different = 0; - if (!base || !base->tabs || !base->tabs->extras || - (value->tabs->normal != base->tabs->normal) || - (psiconv_list_length(value->tabs->extras) != - psiconv_list_length(base->tabs->extras))) - tabs_different = 1; - else { - for (i = 0; i < psiconv_list_length(value->tabs->extras); i++) { - value_tab = psiconv_list_get(value->tabs->extras,i); - base_tab = psiconv_list_get(base->tabs->extras,i); - if (!value_tab || !base_tab) { - psiconv_warn(0,psiconv_list_length(buf),"Massive memory corruption"); - res = -PSICONV_E_NOMEM; - goto ERROR; - } - if ((value_tab->kind != base_tab->kind) || - (value_tab->location != base_tab->location)) { - tabs_different = 1; - break; - } - } - } - - if (tabs_different) { - if ((res = psiconv_write_u8(extra_buf,0x16))) - goto ERROR; - if ((res = psiconv_write_length(extra_buf,value->tabs->normal))) - goto ERROR; + if (!base || psiconv_compare_all_tabs(value->tabs,base->tabs)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x16))) + goto ERROR2; + if ((res = psiconv_write_length(config,extra_buf,lev+1,value->tabs->normal))) + goto ERROR2; for (i = 0; i < psiconv_list_length(value->tabs->extras); i++) { - if (!(value_tab = psiconv_list_get(value->tabs->extras,i))) { - psiconv_warn(0,psiconv_list_length(buf),"Massive memory corruption"); + if (!(tab = psiconv_list_get(value->tabs->extras,i))) { + psiconv_error(config,lev+1,0,"Data structure corruption"); res = -PSICONV_E_NOMEM; - goto ERROR; + goto ERROR2; } - if ((res = psiconv_write_u8(extra_buf,0x17))) - goto ERROR; - if ((res = psiconv_write_tab(extra_buf,value_tab))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x17))) + goto ERROR2; + if ((res = psiconv_write_tab(config,extra_buf,lev+1,tab))) + goto ERROR2; } } - if ((res = psiconv_write_u32(buf,psiconv_list_length(extra_buf)))) - goto ERROR; + if ((res = psiconv_write_u32(config,buf,lev+1,psiconv_buffer_length(extra_buf)))) + goto ERROR2; - res = psiconv_list_concat(buf,extra_buf); + if ((res = psiconv_buffer_concat(buf,extra_buf))) { + psiconv_error(config,lev+1,0,"Out of memory error"); + goto ERROR2; + } -ERROR: - psiconv_free_buffer(extra_buf); +ERROR2: + psiconv_buffer_free(extra_buf); +ERROR1: + if (res) + psiconv_error(config,lev,0,"Writing of paragraph layout list failed"); + else + psiconv_progress(config,lev,0,"End of paragraph layout list"); return res; } -int psiconv_write_character_layout_list(psiconv_buffer buf, +int psiconv_write_character_layout_list(const psiconv_config config, + psiconv_buffer buf,int lev, psiconv_character_layout value, psiconv_character_layout base) { int res; psiconv_buffer extra_buf; + + psiconv_progress(config,lev,0,"Writing character layout list"); + if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null character layout list"); - return -PSICONV_E_GENERATE; + psiconv_error(config,lev,0,"Null character layout list"); + res = -PSICONV_E_GENERATE; + goto ERROR1; + } + if (!(extra_buf = psiconv_buffer_new())) { + res = -PSICONV_E_NOMEM; + goto ERROR1; } - if (!(extra_buf = psiconv_new_buffer())) - return -PSICONV_E_NOMEM; - if (!base || !base->color || !value->color || - (value->color->red != base->color->red) || - (value->color->green != base->color->green) || - (value->color->blue != base->color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x19))) - goto ERROR; - if ((res = psiconv_write_color(extra_buf,value->color))) - goto ERROR; - } - - if (!base || !base->back_color || !value->back_color || - (value->back_color->red != base->back_color->red) || - (value->back_color->green != base->back_color->green) || - (value->back_color->blue != base->back_color->blue)) { - if ((res = psiconv_write_u8(extra_buf,0x1a))) - goto ERROR; - if ((res = psiconv_write_color(extra_buf,value->back_color))) - goto ERROR; + if (!base || psiconv_compare_color(base->color,value->color)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x19))) + goto ERROR2; + if ((res = psiconv_write_color(config,extra_buf,lev+1,value->color))) + goto ERROR2; + } + + if (!base || psiconv_compare_color(base->back_color,value->back_color)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1a))) + goto ERROR2; + if ((res = psiconv_write_color(config,extra_buf,lev+1,value->back_color))) + goto ERROR2; } if (!base || (value->font_size != base->font_size)) { - if ((res = psiconv_write_u8(extra_buf,0x1c))) - goto ERROR; - if ((res = psiconv_write_size(extra_buf,value->font_size))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1c))) + goto ERROR2; + if ((res = psiconv_write_size(config,extra_buf,lev+1,value->font_size))) + goto ERROR2; } if (!base || (value->italic != base->italic)) { - if ((res = psiconv_write_u8(extra_buf,0x1d))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->italic))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1d))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->italic))) + goto ERROR2; } if (!base || (value->bold != base->bold)) { - if ((res = psiconv_write_u8(extra_buf,0x1e))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->bold))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1e))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->bold))) + goto ERROR2; } if (!base || (value->super_sub != base->super_sub)) { if ((value->super_sub != psiconv_superscript) && (value->super_sub != psiconv_subscript) && (value->super_sub != psiconv_normalscript)) - psiconv_warn(0,psiconv_list_length(buf), - "Unknown supersubscript (%d); assuming normal", + psiconv_warn(config,lev,0,"Unknown supersubscript (%d); assuming normal", value->super_sub); - if ((res = psiconv_write_u8(extra_buf,0x1f))) - goto ERROR; - if ((res = psiconv_write_u8(extra_buf, - base->super_sub == psiconv_superscript?1: - base->super_sub == psiconv_superscript?2:0))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1f))) + goto ERROR2; + if ((res = psiconv_write_u8(config,extra_buf,lev+1, + value->super_sub == psiconv_superscript?1: + value->super_sub == psiconv_subscript?2:0))) + goto ERROR2; } if (!base || (value->underline != base->underline)) { - if ((res = psiconv_write_u8(extra_buf,0x20))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->underline))) - goto ERROR; + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x20))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->underline))) + goto ERROR2; } if (!base || (value->strikethrough != base->strikethrough)) { - if ((res = psiconv_write_u8(extra_buf,0x21))) - goto ERROR; - if ((res = psiconv_write_bool(extra_buf,value->strikethrough))) - goto ERROR; - } - - if (!base || !value->font || !base->font || - (value->font->screenfont != base->font->screenfont) || - strcmp(value->font->name,base->font->name)) { - if ((res = psiconv_write_u8(extra_buf,0x22))) - goto ERROR; - if ((res = psiconv_write_font(extra_buf,value->font))) - goto ERROR; - } - - if ((res = psiconv_write_u32(buf,psiconv_list_length(extra_buf)))) - goto ERROR; - - res = psiconv_list_concat(buf,extra_buf); - -ERROR: - psiconv_free_buffer(extra_buf); + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x21))) + goto ERROR2; + if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->strikethrough))) + goto ERROR2; + } + + if (!base || psiconv_compare_font(base->font,value->font)) { + if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x22))) + goto ERROR2; + if ((res = psiconv_write_font(config,extra_buf,lev+1,value->font))) + goto ERROR2; + } + + if ((res = psiconv_write_u32(config,buf,lev+1,psiconv_buffer_length(extra_buf)))) + goto ERROR2; + + res = psiconv_buffer_concat(buf,extra_buf); + +ERROR2: + psiconv_buffer_free(extra_buf); +ERROR1: + if (res) + psiconv_error(config,lev,0,"Writing of character layout list failed"); + else + psiconv_progress(config,lev,0,"End of character layout list"); return res; }