--- psiconv/trunk/lib/psiconv/generate_common.c 2000/12/27 02:12:23 80 +++ psiconv/trunk/lib/psiconv/generate_common.c 2002/01/29 18:38:38 142 @@ -25,6 +25,10 @@ #include "generate_routines.h" #include "error.h" +#ifdef DMALLOC +#include +#endif + static int psiconv_write_layout_section(psiconv_buffer buf, const psiconv_text_and_layout value, const psiconv_word_styles_section styles, @@ -92,22 +96,26 @@ return -PSICONV_E_GENERATE; } - if (!(extra_buf = psiconv_buffer_new())) - return -PSICONV_E_NOMEM; - for (i = 0; i < psiconv_list_length(value); i++) { - if (!(paragraph = psiconv_list_get(value,i))) { - psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption"); - res = -PSICONV_E_OTHER; - goto ERROR; - } - for (j = 0; j < strlen(paragraph->text); j++) - if ((res = psiconv_write_u8(extra_buf,paragraph->text[j]))) + if (psiconv_list_length(value)) { + if (!(extra_buf = psiconv_buffer_new())) + return -PSICONV_E_NOMEM; + for (i = 0; i < psiconv_list_length(value); i++) { + if (!(paragraph = psiconv_list_get(value,i))) { + psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption"); + res = -PSICONV_E_OTHER; goto ERROR; - psiconv_write_u8(extra_buf,0x06); - } - if ((res = psiconv_write_X(buf,psiconv_buffer_length(extra_buf)))) - goto ERROR; - res = psiconv_buffer_concat(buf,extra_buf); + } + for (j = 0; j < strlen(paragraph->text); j++) + if ((res = psiconv_write_u8(extra_buf,paragraph->text[j]))) + goto ERROR; + psiconv_write_u8(extra_buf,0x06); + } + if ((res = psiconv_write_X(buf,psiconv_buffer_length(extra_buf)))) + goto ERROR; + res = psiconv_buffer_concat(buf,extra_buf); + } else + /* Hack: empty text sections are just not allowed */ + return psiconv_write_u16(buf,0x0602); ERROR: psiconv_buffer_free(extra_buf); @@ -133,7 +141,8 @@ psiconv_paragraph paragraph; psiconv_in_line_layout in_line; psiconv_word_style style; - int i,j,para_type,nr_of_inlines=0,res; + psiconv_character_layout para_charlayout; + int i,j,para_type,nr_of_inlines=0,res,ptl_length,pel_length,thislen,paralen; if (!value) { psiconv_warn(0,psiconv_buffer_length(buf),"Null text section"); @@ -169,7 +178,7 @@ if ((res = psiconv_write_u32(buf_elements,strlen(paragraph->text)+1))) goto ERROR5; - if (psiconv_list_length(paragraph->in_lines)) { + if (psiconv_list_length(paragraph->in_lines) > 1) { /* Inline layouts, so we generate a paragraph element and inline elements */ if ((res = psiconv_write_u8(buf_elements,0x00))) @@ -191,16 +200,29 @@ goto ERROR5; /* Generate the inlines. NB: Against what are all settings relative?!? */ + paralen = 0; for (j = 0; j < psiconv_list_length(paragraph->in_lines); j++) { nr_of_inlines ++; if (!(in_line = psiconv_list_get(paragraph->in_lines,j))) { - psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption"); + psiconv_warn(0,psiconv_buffer_length(buf), + "Massive memory corruption"); res = -PSICONV_E_OTHER; goto ERROR5; } if ((res = psiconv_write_u8(buf_inlines,0x00))) goto ERROR5; - if ((res = psiconv_write_u32(buf_inlines,in_line->length))) + thislen = in_line->length; + paralen += thislen; + /* If this is the last in_line, we need to make sure that the + complete length of all inlines equals the text length */ + if (j == psiconv_list_length(paragraph->in_lines)-1) { + if (paralen > strlen(paragraph->text)+1) { + res = -PSICONV_E_GENERATE; + goto ERROR5; + } + thislen += strlen(paragraph->text)+1-paralen; + } + if ((res = psiconv_write_u32(buf_inlines,thislen))) goto ERROR5; if ((res = psiconv_write_character_layout_list(buf_inlines, in_line->layout, @@ -208,16 +230,29 @@ goto ERROR5; } } else { - /* No inline layouts, so we generate a paragraph type list */ + /* No inline layouts (or only 1), so we generate a paragraph type list */ para_type = 0; + /* Set para_charlayout to the correct character-level layout */ + if (psiconv_list_length(paragraph->in_lines) == 0) + para_charlayout = paragraph->base_character; + else { + if (!(in_line = psiconv_list_get(paragraph->in_lines,0))) { + psiconv_warn(0,psiconv_buffer_length(buf), + "Massive memory corruption"); + res = -PSICONV_E_OTHER; + goto ERROR5; + } + para_charlayout = in_line->layout; + } for (j = 0; j < psiconv_list_length(paragraph_type_list); j++) { if (!(paragraph_type = psiconv_list_get(paragraph_type_list,j))) { - psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption"); + psiconv_warn(0,psiconv_buffer_length(buf), + "Massive memory corruption"); res = -PSICONV_E_OTHER; goto ERROR5; } if ((paragraph->base_style == paragraph_type->style) && - !psiconv_compare_character_layout(paragraph->base_character, + !psiconv_compare_character_layout(para_charlayout, paragraph_type->character) && !psiconv_compare_paragraph_layout(paragraph->base_paragraph, paragraph_type->paragraph)) { @@ -230,7 +265,7 @@ para_type = new_type.nr = j+1; /* No need to copy them, we won't change them anyway */ new_type.paragraph = paragraph->base_paragraph; - new_type.character = paragraph->base_character; + new_type.character = para_charlayout; new_type.style = paragraph->base_style; paragraph_type = &new_type; if ((res = psiconv_list_add(paragraph_type_list,paragraph_type))) @@ -257,14 +292,37 @@ } } + /* HACK: special case: no paragraphs at all. We need to improvize. */ + if (!psiconv_list_length(value)) { + if ((res = psiconv_write_u32(buf_types,1))) + goto ERROR5; + if ((res = psiconv_write_u32(buf_types,0))) + goto ERROR5; + if (with_styles) + if ((res = psiconv_write_u8(buf_types,0))) + goto ERROR5; + if ((res = psiconv_write_u32(buf_types,0))) + goto ERROR5; + + if ((res = psiconv_write_u32(buf_elements,1))) + goto ERROR5; + if ((res = psiconv_write_u8(buf_elements,1))) + goto ERROR5; + pel_length = 1; + ptl_length = 1; + } else { + pel_length = psiconv_list_length(value); + ptl_length = psiconv_list_length(paragraph_type_list); + } + /* Now append everything */ if ((res = psiconv_write_u16(buf,with_styles?0x0001:0x0000))) goto ERROR5; - if ((res = psiconv_write_u8(buf,psiconv_list_length(paragraph_type_list)))) + if ((res = psiconv_write_u8(buf, ptl_length))) goto ERROR5; if ((res = psiconv_buffer_concat(buf,buf_types))) goto ERROR5; - if ((res = psiconv_write_u32(buf,psiconv_list_length(value)))) + if ((res = psiconv_write_u32(buf,pel_length))) goto ERROR5; if ((res = psiconv_buffer_concat(buf,buf_elements))) goto ERROR5;