#include "mkhiblib.h" /** * Free the file * It frees every datas allocated by the file * * @param hfile the file to free */ void hl_freehFile(h_File * hfile) { if (hfile->h_logs != H_NULL) HeapFree(hfile->h_logs); if (hfile->h_bkmks != H_NULL) HeapFree(hfile->h_bkmks); if (hfile->h_bkmks_level != H_NULL) HeapFree(hfile->h_bkmks_level); if (hfile->h_objs != H_NULL) { short no_obj = 0; while (no_obj < hfile->nb_objs) { if ( (hfile->hobjs[no_obj].type == HOBJECT_PIC && !hfile->hobjs[no_obj].datas.pic.wrong && hfile->hobjs[no_obj].datas.pic.comp) || (hfile->hobjs[no_obj].type == HOBJECT_PPRINT && !hfile->hobjs[no_obj].datas.pic.wrong) ) HeapFree(hfile->hobjs[no_obj].datas.pic.handle); no_obj++; } HeapFree(hfile->h_objs); } if (hfile->h_scrlines != H_NULL) HeapFree(hfile->h_scrlines); if (hfile->h_links != H_NULL) HeapFree(hfile->h_links); if (hfile->h_buffer != H_NULL) HeapFree(hfile->h_buffer); } /** * Lock the file * It locks every datas allocated by the file. A file has to be locked before * each use with the HibLib engine. * * @param hfile the file to lock */ void hl_lockhFile(h_File * hfile) { hfile->hobjs = HLock(hfile->h_objs); hfile->hbkmks = HLock(hfile->h_bkmks); hfile->hbkmks_level = HLock(hfile->h_bkmks_level); hfile->hlogs = HLock(hfile->h_logs); if (hfile->h_scrlines != H_NULL) hfile->hscrlines = HLock(hfile->h_scrlines); if (hfile->h_links != H_NULL) hfile->hlinks = HLock(hfile->h_links); if (hfile->h_buffer != H_NULL) hfile->buffer.mem.ptr = HLock(hfile->h_buffer); } /** * Unlock the file * It unlocks every datas allocated by the file. * * @param hfile the file to unlock */ void hl_unlockhFile(h_File * hfile) { HeapUnlock(hfile->h_objs); HeapUnlock(hfile->h_bkmks); HeapUnlock(hfile->h_bkmks_level); HeapUnlock(hfile->h_logs); if (hfile->h_scrlines != H_NULL) HeapUnlock(hfile->h_scrlines); if (hfile->h_links != H_NULL) HeapUnlock(hfile->h_links); if (hfile->h_buffer != H_NULL) { HeapUnlock(hfile->h_buffer); } } /** * Set the screen where the file have to be drawn * Note that the specified screen should be a screen used for the LCD, a screen * with a width of 30 bytes. * * @param hfile the file * @param screen the memory of the screen * @param x the real starting x position where the file will be draw * @param y the real starting y position where the file will be draw * @param width the width allowed to draw in * @param height the heght allowed to draw in */ void hl_setScreen(h_File * hfile, void * screen, short x, short y, short width, short height) { hfile->screen.mem.ptr = screen; hfile->screen.mem.byte_width = 30; hfile->screen_start = screen + 30 * y; hfile->screen_end = screen + 30 * (y + height); hfile->screen.size.height = height; hfile->screen.size.width = width; hfile->screen.pos.x = x; hfile->screen.pos.y = y; } /** * Read a character from a tagged text. It returns the next readable character (avoiding * every tag format) from the specified position. The position in the text will be updated. * * @param text the text to read * @param pos_txt pointer to the current position in the text * * @return the found character */ short hreadCaract(const unsigned char * text, unsigned short * pos_txt) { unsigned char caract1; unsigned char caract2; unsigned char caract3; short j; deb: caract1 = text[(*pos_txt)++]; if (caract1 == '#') { //can be special caracter. caract2 = text[(*pos_txt)++]; switch (caract2) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'W': //wordwarp option case 'U': //underline case 'N': //dotted underline case 'J': //conjugate case 'V': //a vector case 'S': //strikethrought case 'i': //italic case 'B': //bold /* case 'G': //gray color */ case 'I': //inversed color /* case 'b': //backgroung gray color */ case 'E': //exponent case 'D': //suffix case 'L': // a link goto deb; /* case 'L': // a link while ( !(text[*pos_txt]=='#' && text[(*pos_txt)+1]=='L') && text[*pos_txt]!=13 && text[*pos_txt]!='\0') { (*pos_txt)++; } if (text[*pos_txt]==13 || text[*pos_txt]=='\0') { return text[*pos_txt]; } else { (*pos_txt)+=2; } goto deb;*/ case '#': //only draw # return '#'; case 'C': //caracter definition caract1 = text[(*pos_txt)++]; caract2 = text[(*pos_txt)++]; caract3 = text[(*pos_txt)++]; if ( caract1 >= '0' && caract1 <= '9' && caract2 >= '0' && caract2 <= '9' && caract3 >= '0' && caract3 <= '9' ) { //there must be 3 caracters j = (caract3 - '0') + 10 * (caract2 - '0') + 100 * (caract1 - '0'); if (j < 256) { //there are only 256 caracters if (j != 10 && j != 0) { return j; } (*pos_txt) -= 4; //the caracter 10 and the caracter 0 are forbidden return '#'; } else if (j < NB_SPECIAL_CARACTERS + 256) { return j; } } *pos_txt -= 4; //wrong syntax return '#'; default: //no caracter of format (*pos_txt)--; }//end of switch } return caract1; } /** * Search the number of the line the object correspond to. * * @param no_obj the number of the object * @param hfile the file to study * * @return the number of the line */ short hnoObject2NoScrLine(short no_obj, h_File * hfile) { short no_scrline_sup = hfile->nb_scrlines; short no_scrline_min = 0; short no_scrline; unsigned short pos_txt = hfile->hobjs[no_obj].pos_txt; while (TRUE) { no_scrline = no_scrline_min + (no_scrline_sup-no_scrline_min) / 2; if (pos_txt < hfile->hscrlines[no_scrline].pos_txt) { no_scrline_sup = no_scrline; } else if (pos_txt > hfile->hscrlines[no_scrline + 1].pos_txt) { if (no_scrline_min == no_scrline) { no_scrline_min++; } else { no_scrline_min = no_scrline; } } else { break; } } if (pos_txt == hfile->hscrlines[no_scrline + 1].pos_txt) no_scrline++; return no_scrline; } /** * Search the number of the object the position correspond to. * * @param pos_txt the position in the text * @param hfile the file to study * * @return the number of the object */ short hposTxt2NoObject(unsigned short pos_txt, h_File * hfile) { short no_obj_sup = hfile->nb_objs; short no_obj_min = 0; short no_obj; while (TRUE) { no_obj = no_obj_min + (no_obj_sup - no_obj_min) / 2; if (pos_txt < hfile->hobjs[no_obj].pos_txt) { no_obj_sup = no_obj; } else if (pos_txt > hfile->hobjs[no_obj + 1].pos_txt) { if (no_obj_min == no_obj) { no_obj_min++; } else { no_obj_min = no_obj; } } else { break; } } if (pos_txt == hfile->hobjs[no_obj + 1].pos_txt) no_obj++; return no_obj; } /** * Function that add an item in a table * This function allows to see a HANDLE as a table in which we can add items. The HANDLE * have to be allocated one time before the first use of this function. Every items have to * have the same size. * This function will automatically realloc the handle if it is too small; this function * allocates by step. The value of the step is STEP_REALLOC. * Typically, this function will be used as it : * * typedef struct { ... } MyStruct; * short nb = 0; * short size = 3; * HANDLE h = HeapAlloc(size * sizeof(MyStruct)); * ... * num = hl_addHANDLE(&h, &nb, &size, sizeof(MyStruct)); * if (num != NOK) { * ((MyStruct *)HeapDeref(h))[num] = (MyStruct) { ... }; * } * ... * * * @param h the HANDLE to modify * @param nb the number of items already stored * @param size the number of items that can be stored * @param size_item the size of one item * * @return the number of the added entry, NOK (-1) if there is a memory error */ short hl_addHANDLE(HANDLE * h, unsigned short * nb, unsigned short * size, unsigned short size_item) { HANDLE h2; if (*nb >= *size) { h2 = HeapRealloc(*h, (*size + STEP_REALLOC) * size_item); if (h2 == H_NULL) return NOK; (*size) += STEP_REALLOC; *h = h2; } (*nb)++; return *nb - 1; }