// C Source File // Created 07/11/2003; 18:53:37 #include "mkhiblib.h" /** * Give the height of the format upon the text line * * @param frt the format * @param y_offset the current offset for exponent and suffix * @param font_upperline the size of upper part of the font * @param font_underline the size of the under part of the font * * @return the height of the format upon the text line */ short hgetHeightExp(h_Format frt, short y_offset, short font_upperline, short font_underline) { return (frt.exponent != 0) *(font_underline + y_offset) + (frt.vector != 0) * 3 + (frt.conjug != 0) * 2 - (frt.suffix != 0) * (font_upperline - y_offset) + font_upperline; } /** * Give the height of the format under the text line * * @param frt the format * @param y_offset the current offset for exponent and suffix * @param font_upperline the size of upper part of the font * @param font_underline the size of the under part of the font * * @return the height of the format under the text line */ short hgetHeightSuffix(h_Format frt, short y_offset, short font_upperline, short font_underline) { short h = (frt.suffix != 0) * (font_upperline - y_offset) - (frt.exponent != 0) * (font_underline + y_offset); short u = (frt.underline != 0 || frt.dotted != 0 || frt.link != 0) * 3; if (u == 0 && font_underline == 0) { h++; } if (u < font_underline) { u = font_underline; } return h + u; } /** * Make the layout for the file * * @param hfile the file to study * @param line_width_max the maximum width for a line (-1 for infinite) * @param fonttab the table of the fonts * @param nb_font the number of font * @param iscomp the function that return if a data is compressed or not * @param uncomp the function that uncompressed datas */ BOOL hl_layout(h_File * hfile, short line_width_max, BOOL allowBigObject, h_Font * fonttab, short nb_font, FctIsComp iscomp, FctUnComp uncomp) { short size_tab_scrline = hfile->nb_tioslines; short no_scrline; short size_tab_link = hfile->nb_targetlinks; short no_link = 0; short no_obj_link = NOK; //current object short no_obj; short no_obj_ww; //the wordwarp save short no_obj_prev; //the wordwarp save //current character short charact; //datas on the object to add short obj_width = 0; short obj_height_exp = 0; short obj_height_suffix = 0; //current position unsigned short pos_txt; unsigned short pos_txt_ww; //the wordwarp save unsigned short pos_txt_prev; //true if the word warp is possible BOOL can_do_wordwarp; //a wordwarp save is available BOOL exist_wordwarp; //true if this is the fisrt character of the line BOOL first_obj; //the current format of the tios line h_FrtLine frtline; //the current format of the text h_Format frt; //the current y offset of the position of "line of text" short y_offset=0; //the current screenline h_ScrLine hscrline; h_ScrLine hscrline_ww; h_ScrLine hscrline_prev; short h_suffix; short size_space; short italic_offset = 0; h_Font * font=NULL; unsigned char name[20]; unsigned char * data; short width_max = 0; unsigned char nametiosfont[] = "tios0"; //for the study of a pretty-print ESI top_estack_backup; short width; short down; short up; short height; short byte_length; //for the study of object in mem (picture and pprint) HSym hsym; unsigned short * data_object; HANDLE h_data_object; short compid; short j; //initialisation of the htxt for the display hfile->linewidth = line_width_max; hfile->buffer.size.width = line_width_max; hfile->buffer.size.height = 0; hfile->iscomp=iscomp; hfile->uncomp=uncomp; hfile->fonttab=fonttab; hfile->nb_font=nb_font; //search every font used in the text for (j = 0; j < 10; j++) { switch (hfile->hh.pos_name_font[j]) { case NOK: //font not used hfile->fontptr[j] = NULL; //not defined break; case 0: //the tios font if (j == 0 || j > 3) { //set the default medium tios font nametiosfont[4] = '2'; } else { nametiosfont[4] = '0' + j; //set the tios font } hfile->fontptr[j] = hl_findFont(nametiosfont, fonttab, nb_font); break; default: hfile->fontptr[j] = hl_findFont(hfile->text + hfile->hh.pos_name_font[j], fonttab,nb_font); if (hfile->fontptr[j] == NULL) { //font not found : replace it by the tios2 font hfile->fontptr[j] = hl_findFont("tios2", fonttab, nb_font); } } } hl_unlockhFile(hfile); //create the table of hScreenLine hfile->nb_scrlines = 0; hfile->h_scrlines = HeapAlloc(size_tab_scrline * sizeof(h_ScrLine)); if (hfile->h_scrlines == H_NULL) { return FALSE; } hfile->nb_links = 0; hfile->h_links = HeapAlloc(size_tab_link * sizeof(h_Link)); if (hfile->h_links == H_NULL) { return FALSE; } hl_lockhFile(hfile); memset(hfile->hscrlines, 0, sizeof(h_ScrLine) * size_tab_scrline); hscrline.space = 0; no_obj = 1; pos_txt = hfile->hobjs[1].pos_txt; frtline = hfile->hobjs[0].datas.frtline; hscrline = (h_ScrLine) { .pos_txt = pos_txt, .height = 0, .exp_max = 0, .width = 0, .space = 0 }; first_obj = TRUE; exist_wordwarp = FALSE; can_do_wordwarp = FALSE; size_space = 0; if (line_width_max == -1) { width_max = -1; } else { width_max = line_width_max - frtline.margin; if (width_max < MIN_MARGIN) { width_max = MIN_MARGIN; } } hscrline_ww = hscrline; pos_txt_ww = pos_txt; no_obj_ww = no_obj; while (hfile->hobjs[no_obj].type != HOBJECT_END_TEXT) { //loop on every objects, until the end //save datas pos_txt_prev = pos_txt; no_obj_prev = no_obj; hscrline_prev = hscrline; //read the next object< switch (hfile->hobjs[no_obj].type) { case HOBJECT_TIOS_LINE: //get the new format frtline = hfile->hobjs[no_obj].datas.frtline; if (line_width_max == -1) { width_max = -1; } else { width_max = line_width_max - frtline.margin; if (width_max < MIN_MARGIN) { width_max = MIN_MARGIN; } } hscrline.space = 0; no_obj++; pos_txt = hfile->hobjs[no_obj].pos_txt; new_scrline: hl_unlockhFile(hfile); no_scrline = hl_addHANDLE(&(hfile->h_scrlines), &(hfile->nb_scrlines), &size_tab_scrline, sizeof(h_ScrLine)); if (no_scrline == NOK) { return FALSE; } hl_lockhFile(hfile); if (hscrline.height > hfile->buffer.size.height) { hfile->buffer.size.height = hscrline.height; } if ((allowBigObject || line_width_max == -1) && hscrline.width > hfile->buffer.size.width) { hfile->buffer.size.width = hscrline.width; } hfile->hscrlines[no_scrline] = hscrline; hscrline = (h_ScrLine) { .pos_txt = pos_txt, .height = 0, .exp_max = 0, .width = 0, .space = 0 }; first_obj = TRUE; exist_wordwarp = FALSE; can_do_wordwarp = FALSE; italic_offset = 0; continue; case HOBJECT_TEXT: if (pos_txt == hfile->hobjs[no_obj].pos_txt) { //get the format of this text object frt = hfile->hobjs[no_obj].datas.frt; font = hfile->fontptr[(short)(frt.num_font)]; } obj_height_exp = hgetHeightExp(frt, y_offset, font->upperline, font->underline); obj_height_suffix = hgetHeightSuffix(frt, y_offset, font->upperline, font->underline); charact = hreadCaract(hfile->text, &pos_txt); if (charact==13 || charact=='\0') { h_suffix = hscrline.height - hscrline.exp_max; if (obj_height_exp > hscrline.exp_max) { hscrline.exp_max = obj_height_exp; } if (obj_height_suffix > h_suffix) { h_suffix = obj_height_suffix; } hscrline.height = hscrline.exp_max + h_suffix; no_obj++; continue; } obj_width = hl_charWidth(font, charact, frt.italic != 0, frt.bold != 0); if (frt.italic) { obj_width -= italic_offset; italic_offset = hl_italicWidth(font); } else { italic_offset = 0; } if (charact == ' ') { can_do_wordwarp = TRUE; size_space = obj_width + (!first_obj); } else if (charact == '-') { can_do_wordwarp = TRUE; } else { can_do_wordwarp = FALSE; } if (pos_txt >= hfile->hobjs[no_obj + 1].pos_txt) { no_obj++; } break; case HOBJECT_PIC: pos_txt = hfile->hobjs[no_obj].pos_txt; name[0] = '\0'; j = 1; while (hfile->text[pos_txt] != 13 && hfile->text[pos_txt] != '\0' && j < 18) { name[j++] = hfile->text[pos_txt++]; } name[j] = '\0'; hsym = SymFind(name + j); if (hsym.folder == H_NULL) { hscrline.height = HEIGHT_NO_PIC + 2; hscrline.exp_max = HEIGHT_NO_PIC + 2; hscrline.width = WIDTH_NO_PIC; hfile->hobjs[no_obj].datas.pic.wrong = TRUE; } else { hfile->hobjs[no_obj].datas.pic.wrong = FALSE; h_data_object = DerefSym(hsym)->handle; compid = 0; if (iscomp != NULL && uncomp != NULL) { compid = iscomp(h_data_object); if (compid != 0) { h_data_object = uncomp(compid, h_data_object); } } data_object = HeapDeref(h_data_object); hscrline.height = data_object[1] + 2; hscrline.exp_max = hscrline.height; hscrline.width = data_object[2]; hfile->hobjs[no_obj].datas.pic.comp = (compid!=0); hfile->hobjs[no_obj].datas.pic.handle = h_data_object; } no_obj++; italic_offset = 0; continue; case HOBJECT_PPRINT: pos_txt = hfile->hobjs[no_obj].pos_txt; top_estack_backup = top_estack; j = 0; while (hfile->text[pos_txt + j] != 13 && hfile->text[pos_txt + j] != '\0') { j++; } data = malloc(j + 1); if (data == NULL) { return FALSE; } memcpy(data,hfile->text + pos_txt, j); data[j] = '\0'; TRY push_END_TAG(); push_parse_text(data); // NG_rationalESI (top_estack); //calculate the expression Parms2D(Parse2DExpr(top_estack, FALSE), &width, &down, &up); //get the dimensions ONERR // there is an error in the expression hfile->hobjs[no_obj].datas.pic.wrong = TRUE; hscrline.height = HEIGHT_NO_PPRINT + 2; hscrline.exp_max = HEIGHT_NO_PPRINT + 2; hscrline.width = WIDTH_NO_PPRINT; goto end_pprint; ENDTRY byte_length = ((width + 7) >> 3); // +1: don't know why, it needs 1 pixel more the width... height = up + down; h_data_object = HeapAlloc(byte_length * height + 4); if (h_data_object == H_NULL) { free(data); top_estack = top_estack_backup; return FALSE; } data_object = HeapDeref(h_data_object); *(data_object++) = height; *(data_object++) = width; unsigned char tiosfont = FontGetSys(); WINDOW window; memcpy(&window, DeskTop, sizeof(WINDOW)); window.Client = (SCR_RECT) { { 0, 0, width - 1, height - 1 } }; window.Window = window.Client; window.Clip = window.Client; window.Port = window.Client; PortSet(data_object, width - 1, height - 1); memset(data_object, 0, height * byte_length); Print2DExpr(top_estack, &window, 0, up - 1); PortRestore(); FontSetSys(tiosfont); hscrline.height = height + 2; hscrline.exp_max = hscrline.height; hscrline.width = width; hfile->hobjs[no_obj].datas.pic.wrong = FALSE; hfile->hobjs[no_obj].datas.pic.handle = h_data_object; // short ij; // byte_length = ((width + 7) >> 3); // for (ij = 0; ij < height ; ij++ ) { // memcpy(LCD_MEM + ij * 30,((unsigned char *)data_object) + ij*byte_length,byte_length); // } // ngetchx(); end_pprint: free(data); top_estack = top_estack_backup; no_obj++; italic_offset = 0; continue; case HOBJECT_LINK: no_obj_link = no_obj; //nothing to draw no_obj++; pos_txt = hfile->hobjs[no_obj].pos_txt; continue; case HOBJECT_SEPARAT1: hscrline.height = 3; hscrline.exp_max = 3; no_obj++; italic_offset = 0; continue; case HOBJECT_SEPARAT2: hscrline.height = 5; hscrline.exp_max = 5; no_obj++; italic_offset = 0; continue; case HOBJECT_END_TEXT: //come never here break; } //add the object if (!first_obj) { obj_width++; } //try to add it if (width_max != -1 && hscrline.width + obj_width >= width_max) { //can't add the object //try to do wordwarp if (exist_wordwarp && (frt.wordwarp != 0)) { //can do wordwarp hscrline = hscrline_ww; pos_txt = pos_txt_ww; no_obj = no_obj_ww; } else { pos_txt = pos_txt_prev; no_obj = no_obj_prev; hscrline = hscrline_prev; } goto new_scrline; } //can add the object if (frt.link) { if (no_obj_link != NOK) { //first object of the link : create it hl_unlockhFile(hfile); no_link = hl_addHANDLE(&(hfile->h_links), &(hfile->nb_links), &size_tab_link, sizeof(h_Link)); if (no_link == NOK) { return FALSE; } hl_lockhFile(hfile); hfile->hlinks[no_link] = (h_Link) { .no_obj = no_obj_link, .no_scrline = MAXSHORT, .h_exp = MINCHAR, .h_suffix = MINCHAR }; hfile->hlinks[no_link].no_scrline = hfile->nb_scrlines; hfile->hlinks[no_link].x1 = hscrline.width + (!first_obj); no_obj_link = NOK; } else if (first_obj) { //the link is on 2 lines hl_unlockhFile(hfile); no_link = hl_addHANDLE(&(hfile->h_links), &(hfile->nb_links), &size_tab_link,sizeof(h_Link)); if (no_link == NOK) return FALSE; hl_lockhFile(hfile); hfile->hlinks[no_link] = (h_Link) { .no_obj = hfile->hlinks[no_link - 1].no_obj, .no_scrline = hfile->nb_scrlines, .x1 = hscrline.width, .h_exp = MINCHAR, .h_suffix = MINCHAR }; } } hscrline.width += obj_width; if (frtline.align == HALIGN_JUSTIFIED) { hscrline.space += size_space; } size_space = 0; first_obj = FALSE; h_suffix = hscrline.height - hscrline.exp_max; if (obj_height_exp > hscrline.exp_max) { hscrline.exp_max = obj_height_exp; } if (obj_height_suffix > h_suffix) { h_suffix = obj_height_suffix; } hscrline.height = hscrline.exp_max + h_suffix; y_offset = font->upperline / 2; if (frt.link) { hfile->hlinks[no_link].x2 = hscrline.width; if (hfile->hlinks[no_link].h_suffix < obj_height_suffix) { hfile->hlinks[no_link].h_suffix = obj_height_suffix; } if (hfile->hlinks[no_link].h_exp < obj_height_exp) { hfile->hlinks[no_link].h_exp = obj_height_exp; } } //save wordwarp postion if ((frt.wordwarp!=0) && can_do_wordwarp) {//can do word warp here ? //yes, so save current position (just before the current object) pos_txt_ww = pos_txt; no_obj_ww = no_obj; hscrline_ww = hscrline; exist_wordwarp = TRUE; } } //next object to add if (hfile->hobjs[no_obj - 1].type == HOBJECT_TIOS_LINE) { //the last line is an empty line : set a correct height hscrline.height = hgetHeightExp(frt, y_offset, font->upperline, font->underline) + hgetHeightSuffix(frt, y_offset, font->upperline, font->underline); } //add the last line hscrline.space = 0; hl_unlockhFile(hfile); no_scrline = hl_addHANDLE(&(hfile->h_scrlines), &(hfile->nb_scrlines), &size_tab_scrline, sizeof(h_ScrLine)); if (no_scrline == NOK) { return FALSE; } hl_lockhFile(hfile); //check if this last line line is not the biggest one if (hscrline.height > hfile->buffer.size.height) { hfile->buffer.size.height = hscrline.height; } if ((allowBigObject || line_width_max == -1) && hscrline.width > hfile->buffer.size.width) { hfile->buffer.size.width = hscrline.width; } hfile->hscrlines[no_scrline] = hscrline; hfile->buffer.mem.byte_width = ((hfile->buffer.size.width + 7) >> 3); hl_unlockhFile(hfile); hfile->buffer.size.height = 2 * hfile->buffer.size.height + LCD_HEIGHT; hfile->h_buffer = HeapAlloc(hfile->buffer.size.height * hfile->buffer.mem.byte_width); if (hfile->h_buffer == H_NULL) { return FALSE; } hfile->drawn_height = 0; hfile->line_top = 0; hfile->line_bot = 0; hfile->x_offset = 0; hfile->buffer.pos.x = 0; hfile->buffer.pos.y = 0; hl_lockhFile(hfile); //clean the buffer hl_clrScreen(hfile->buffer); return TRUE; }