--- psiconv/trunk/lib/psiconv/generate_common.c 2000/12/25 14:34:17 78 +++ psiconv/trunk/lib/psiconv/generate_common.c 2000/12/25 22:25:33 79 @@ -25,6 +25,10 @@ #include "generate_routines.h" #include "error.h" +static int psiconv_write_layout_section(psiconv_buffer buf, + const psiconv_text_and_layout value, + const psiconv_word_styles_section styles, + int with_styles); /* Maybe use a psiconv_header_section variable instead? */ int psiconv_write_header_section(psiconv_buffer buf,psiconv_u32 uid1, @@ -47,7 +51,7 @@ psiconv_section_table_entry entry; if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null section table section"); + psiconv_warn(0,psiconv_buffer_length(buf),"Null section table section"); return -PSICONV_E_GENERATE; } @@ -55,7 +59,7 @@ return res; for (i = 0; i < psiconv_list_length(value); i++) { if (!(entry = psiconv_list_get(value,i))) { - psiconv_warn(0,psiconv_list_length(buf),"Massive memory corruption"); + psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption"); return -PSICONV_E_NOMEM; } if ((res = psiconv_write_u32(buf,entry->id))) @@ -84,15 +88,15 @@ psiconv_paragraph paragraph; if (!value) { - psiconv_warn(0,psiconv_list_length(buf),"Null text section"); + psiconv_warn(0,psiconv_buffer_length(buf),"Null text section"); return -PSICONV_E_GENERATE; } - if (!(extra_buf = psiconv_new_buffer())) + if (!(extra_buf = psiconv_buffer_new(0))) return -PSICONV_E_NOMEM; for (i = 0; i < psiconv_list_length(value); i++) { if (!(paragraph = psiconv_list_get(value,i))) { - psiconv_warn(0,psiconv_list_length(buf),"Massive memory corruption"); + psiconv_warn(0,psiconv_buffer_length(buf),"Massive memory corruption"); res = -PSICONV_E_OTHER; goto ERROR; } @@ -101,11 +105,236 @@ goto ERROR; psiconv_write_u8(extra_buf,0x06); } - if ((res = psiconv_write_X(buf,psiconv_list_length(extra_buf)))) + if ((res = psiconv_write_X(buf,psiconv_buffer_length(extra_buf)))) goto ERROR; - res = psiconv_list_concat(buf,extra_buf); + res = psiconv_buffer_concat(buf,extra_buf); ERROR: - psiconv_free_buffer(extra_buf); + psiconv_buffer_free(extra_buf); return res; } + +int psiconv_write_layout_section(psiconv_buffer buf, + const psiconv_text_and_layout value, + const psiconv_word_styles_section styles, + int with_styles) +{ + typedef struct psiconv_paragraph_type_list_s + { + psiconv_character_layout character; + psiconv_paragraph_layout paragraph; + psiconv_u8 style; + psiconv_u8 nr; + } *psiconv_paragraph_type_list; + psiconv_list paragraph_type_list; /* Of psiconv_paragraph_type_list_s */ + psiconv_paragraph_type_list paragraph_type; + struct psiconv_paragraph_type_list_s new_type; + psiconv_buffer buf_types,buf_elements,buf_inlines; + psiconv_paragraph paragraph; + psiconv_in_line_layout in_line; + psiconv_word_style style; + int i,j,para_type,nr_of_inlines=0,res; + + if (!value) { + psiconv_warn(0,psiconv_buffer_length(buf),"Null text section"); + return -PSICONV_E_GENERATE; + } + + if (!(paragraph_type_list = psiconv_list_new(sizeof(new_type)))) { + res = -PSICONV_E_NOMEM; + goto ERROR1; + } + + if (!(buf_types = psiconv_buffer_new(0))) { + res = -PSICONV_E_NOMEM; + goto ERROR2; + } + + if (!(buf_elements = psiconv_buffer_new(0))) { + res = -PSICONV_E_NOMEM; + goto ERROR3; + } + + if (!(buf_inlines = psiconv_buffer_new(0))) { + res = -PSICONV_E_NOMEM; + goto ERROR4; + } + + 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 ERROR5; + } + if ((res = psiconv_write_u32(buf_elements,strlen(paragraph->text)+1))) + goto ERROR5; + + if (psiconv_list_length(paragraph->in_lines)) { + /* Inline layouts, so we generate a paragraph element and inline + elements */ + if ((res = psiconv_write_u32(buf_elements,0x00))) + goto ERROR5; + if (!(style = psiconv_get_style(styles,paragraph->base_style))) { + psiconv_warn(0,psiconv_buffer_length(buf),"Unknown style"); + res = -PSICONV_E_GENERATE; + goto ERROR5; + } + if ((res = psiconv_write_paragraph_layout_list(buf_elements, + paragraph->base_paragraph, + style->paragraph))) + goto ERROR5; + if (with_styles) + if ((res = psiconv_write_u8(buf_elements,paragraph->base_style))) + goto ERROR5; + if ((res = psiconv_write_u32(buf_elements, + psiconv_list_length(paragraph->in_lines)))) + goto ERROR5; + + /* Generate the inlines. NB: Against what are all settings relative?!? */ + 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"); + 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))) + goto ERROR5; + if ((res = psiconv_write_character_layout_list(buf_elements, + in_line->layout, + style->character))) + goto ERROR5; + } + } else { + /* No inline layouts, so we generate a paragraph type list */ + para_type = 0; + 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"); + res = -PSICONV_E_OTHER; + goto ERROR5; + } + if ((paragraph->base_style == paragraph_type->style) && + !psiconv_compare_character_layout(paragraph->base_character, + paragraph_type->character) && + !psiconv_compare_paragraph_layout(paragraph->base_paragraph, + paragraph_type->paragraph)) { + para_type = paragraph_type->nr; + break; + } + } + if (!para_type) { + /* We need to add a new entry */ + 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.style = paragraph->base_style; + paragraph_type = &new_type; + if ((res = psiconv_list_add(paragraph_type_list,paragraph_type))) + goto ERROR5; + if ((res = psiconv_write_u32(buf_types,paragraph_type->nr))) + goto ERROR5; + if (!(style = psiconv_get_style(styles,paragraph_type->style))) { + psiconv_warn(0,psiconv_buffer_length(buf),"Unknown style"); + res = -PSICONV_E_GENERATE; + goto ERROR5; + } + if ((res = psiconv_write_paragraph_layout_list(buf_types, + paragraph_type->paragraph,style->paragraph))) + goto ERROR5; + if (with_styles) + if ((res = psiconv_write_u8(buf_types,paragraph_type->style))) + goto ERROR5; + if ((res = psiconv_write_character_layout_list(buf_types, + paragraph_type->character,style->character))) + goto ERROR5; + } + if ((res = psiconv_write_u8(buf_elements,para_type))) + goto ERROR5; + } + } + + /* Now append everything */ + if ((res = psiconv_write_u8(buf,with_styles?0x00:0x01))) + goto ERROR5; + if ((res = psiconv_write_u8(buf,0x00))) + goto ERROR5; + if ((res = psiconv_write_u8(buf,psiconv_list_length(paragraph_type_list)))) + goto ERROR5; + if ((res = psiconv_buffer_concat(buf,buf_types))) + goto ERROR5; + if ((res = psiconv_write_u32(buf,psiconv_list_length(value)))) + goto ERROR5; + if ((res = psiconv_buffer_concat(buf,buf_elements))) + goto ERROR5; + if ((res = psiconv_write_u32(buf,nr_of_inlines))) + goto ERROR5; + res = psiconv_buffer_concat(buf,buf_inlines); + +ERROR5: + psiconv_buffer_free(buf_inlines); +ERROR4: + psiconv_buffer_free(buf_elements); +ERROR3: + psiconv_buffer_free(buf_types); +ERROR2: + psiconv_list_free(paragraph_type_list); +ERROR1: + return res; +} + +int psiconv_write_styled_layout_section(psiconv_buffer buf, + psiconv_text_and_layout result, + psiconv_word_styles_section styles) +{ + return psiconv_write_layout_section(buf,result,styles,1); +} + +int psiconv_write_styleless_layout_section(psiconv_buffer buf, + const psiconv_text_and_layout value, + const psiconv_character_layout base_char, + const psiconv_paragraph_layout base_para) +{ + int res = 0; + psiconv_word_styles_section styles_section; + + if (!(styles_section = malloc(sizeof(*styles_section)))) + goto ERROR1; + if (!(styles_section->normal = malloc(sizeof(*styles_section->normal)))) + goto ERROR2; + if (!(styles_section->normal->character = + psiconv_clone_character_layout(base_char))) + goto ERROR3; + if (!(styles_section->normal->paragraph = + psiconv_clone_paragraph_layout(base_para))) + goto ERROR4; + styles_section->normal->hotkey = 0; + if (!(styles_section->normal->name = strdup(""))) + goto ERROR5; + if (!(styles_section->styles = psiconv_list_new(sizeof( + struct psiconv_word_style_s)))) + goto ERROR6; + + res = psiconv_write_layout_section(buf,value,styles_section,0); + psiconv_free_word_styles_section(styles_section); + return res; + +ERROR6: + free(styles_section->normal->name); +ERROR5: + psiconv_free_paragraph_layout(styles_section->normal->paragraph); +ERROR4: + psiconv_free_character_layout(styles_section->normal->character); +ERROR3: + free(styles_section->normal); +ERROR2: + free(styles_section); +ERROR1: + if (!res) + return -PSICONV_E_NOMEM; + else + return res; +}