#include "mkhiblib.h" /*=============================================================================================== =========================================== Pictures ============================================ ===============================================================================================*/ //picture to show if there is an error in a picture BITMAP hnopic = { .NumRows = 12, .NumCols = 39, .Data = { 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11000010, 0b00000000, 0b10001011, 0b00010010, 0b01001110, 0b01100011, 0b11100000, 0b10001010, 0b10101011, 0b01010000, 0b00110101, 0b00100000, 0b10101011, 0b00101010, 0b11010110, 0b00111101, 0b00100000, 0b01010010, 0b10010010, 0b01001110, 0b01001100, 0b10100000, 0b00000000, 0b00000000, 0b00000010, 0b10001111, 0b10100000, 0b00000000, 0b00000000, 0b00000000, 0b10000111, 0b00100000, 0b00000001, 0b10010011, 0b00000000, 0b01001001, 0b11100000, 0b00000001, 0b01010100, 0b00000000, 0b00110000, 0b11000000, 0b00000001, 0b10010100, 0b00000000, 0b00000000, 0b01100000, 0b00000001, 0b00010011, 0b00000000, 0b00000000, 0b00100000, 0b00000000, 0b00000000, 0b00000000 } }; //picture to show if there is an error in a pretty-print expression BITMAP hnopprint = { .NumRows = 12, .NumCols = 39, .Data = { 0b10000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b11000000, 0b00000000, 0b10001011, 0b00010010, 0b01001110, 0b01100001, 0b01000000, 0b10001010, 0b10101011, 0b01010000, 0b00111000, 0b10000000, 0b10101011, 0b00101010, 0b11010110, 0b01011100, 0b10000000, 0b01010010, 0b10010010, 0b01001110, 0b00001101, 0b01000000, 0b00000000, 0b00000000, 0b00000010, 0b00001110, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010011, 0b00000000, 0b00001111, 0b01010110, 0b01100000, 0b00100001, 0b10000000, 0b00001110, 0b00100101, 0b01010000, 0b01111100, 0b11000000, 0b00001000, 0b00100110, 0b01100000, 0b00000000, 0b01100000, 0b00001111, 0b01010100, 0b01010000, 0b00000000, 0b00100000, 0b00000000, 0b00000000, 0b00000000 } }; /** * Draw a line of text * * @param no_line the number of the line * @param x the x position in the screen of the start of the line * @param y the y position in the screen of the top of the line * @param scrsize the size of the screen * @param screen the screen * @param hfile the file to draw */ void hdrawLine(short no_line, short x, short y, h_ScreenSize scrsize, h_ScreenMem screen, h_File * hfile) { h_ScrLine hscrline = hfile->hscrlines[no_line]; short no_obj = 0; short caract; unsigned short pos_txt; unsigned short next_pos_txt; unsigned short last_pos_txt; short x_start; short x2; short y_offset = 4; h_FrtLine frtline; h_Format frt; h_Format next_frt; short y_top; //for the drawing of the vectors short x_vect = -1; short y_vect = -1; //for the drawing of inversed color short x_inv = -1; //for the drawing of strike short x_strike = -1; h_Font * font; //for justifying short end_space; short space; short space_add; short y_text; //for picture BITMAP * pic; h_Screen hscr2; short charsize; short offset_italic = 0; short j; pos_txt = hscrline.pos_txt; no_obj = hposTxt2NoObject(pos_txt,hfile); //search the frt_line j = no_obj; while (hfile->hobjs[j].type != HOBJECT_TIOS_LINE) j--; frtline = hfile->hobjs[j].datas.frtline; //search the last offset j = no_obj - 1; while (hfile->hobjs[j].type != HOBJECT_TEXT && j > 0) j--; if (j != 0) y_offset = hfile->fontptr[(short)(hfile->hobjs[j].datas.frt.num_font)]->upperline / 2; if (hfile->hobjs[no_obj].type == HOBJECT_TIOS_LINE) pos_txt = hfile->hobjs[++no_obj].pos_txt; if (no_line < hfile->nb_scrlines - 1) { last_pos_txt = hfile->hscrlines[no_line + 1].pos_txt; } else { last_pos_txt = hfile->hobjs[hfile->nb_objs - 1].pos_txt; } space = hscrline.space; x = frtline.margin; if (hfile->linewidth != -1 && x > hfile->linewidth - MIN_MARGIN) { x = hfile->linewidth - MIN_MARGIN; } if (hfile->linewidth != -1) { end_space = hfile->linewidth - hscrline.width - x; } else { end_space = hfile->buffer.size.width - hscrline.width - x; } switch (frtline.align) { case HALIGN_JUSTIFIED: if (space==0) { end_space=0; } break; case HALIGN_LEFT: break; case HALIGN_RIGHT: x += end_space; break; case HALIGN_CENTER: x += end_space / 2; break; } y_text = y + hfile->hscrlines[no_line].exp_max - 1; y_top = y; while (pos_txt < last_pos_txt) { //util the end of the screen line : loop on every objects switch (hfile->hobjs[no_obj].type) { case HOBJECT_PIC: if (hfile->hobjs[no_obj].datas.pic.wrong) { pic = &hnopic; } else { pic = (BITMAP *)(HeapDeref(hfile->hobjs[no_obj].datas.pic.handle) + 2); }; draw_pic: hscr2.mem = screen; hscr2.size = scrsize; hscr2.pos.x = x + (((short)(scrsize.width - pic->NumCols)) / 2); hscr2.pos.y = y + 1; if (hscr2.pos.x < 0) { hscr2.pos.x = 0; } short byte_width = ((pic->NumCols + 7) >> 3); hl_screenCopy(hscr2,(h_Screen){.mem = {.ptr = pic->Data, .byte_width = byte_width}, .pos={.x = 0, .y = 0}, .size={.width = pic->NumCols, .height = pic->NumRows}}); return; case HOBJECT_PPRINT: if (hfile->hobjs[no_obj].datas.pic.wrong) { pic = &hnopprint; } else { pic = (BITMAP *)HeapDeref(hfile->hobjs[no_obj].datas.pic.handle); }; goto draw_pic; case HOBJECT_SEPARAT2: //draw 2 lines ! hl_drawLineHoriz(0, hfile->buffer.size.width - 1, y + 3, HGRAPHMODE_BLACK, hfile->buffer.mem); case HOBJECT_SEPARAT1: hl_drawLineHoriz(0, hfile->buffer.size.width - 1, y + 1, HGRAPHMODE_BLACK, hfile->buffer.mem); return; case HOBJECT_LINK: //nothing to draw... break; case HOBJECT_TEXT: frt = hfile->hobjs[no_obj].datas.frt; font = hfile->fontptr[(short)(frt.num_font)]; y = y_text + 1 - font->upperline; //caculate the y position if (frt.exponent) { y -= y_offset; } else if (frt.suffix) { y += y_offset; } //caculate the position of text to stop next_pos_txt = hfile->hobjs[no_obj + 1].pos_txt; if (last_pos_txt < next_pos_txt) next_pos_txt = last_pos_txt; x_start = x; if (frt.italic != 0) { x -= offset_italic; } BOOL first = TRUE; while (pos_txt < next_pos_txt) { //draw every caracter of the text object caract = hreadCaract(hfile->text, &pos_txt); if (caract == 13 || caract == '\0') break; charsize = hl_drawChar(font, x, y, caract, frt.italic != 0, frt.bold != 0, hfile->buffer.mem) + 1; first = FALSE; space_add = 0; if (caract == ' ' && space != 0) { space_add = charsize * end_space / space; space -= charsize; end_space -= space_add; } x += charsize + space_add; } offset_italic = 0; if (frt.italic != 0) { offset_italic = hl_italicWidth(font); } x += offset_italic; BOOL is_end = ( (pos_txt == last_pos_txt) || (hfile->hobjs[no_obj + 1].type != HOBJECT_TEXT) ); next_frt = hfile->hobjs[no_obj + 1].datas.frt; //format vector and conjugate : can be on several format of text // ==> draw the vector on the upper one if (frt.conjug != 0 || frt.vector != 0) { if (x_vect == -1) { x_vect = x_start; y_vect = y; } else { if (y_vect > y) y_vect = y; } } if (frt.strike != 0) { if (x_strike == -1) { x_strike = x_start; } } if (frt.vector && (is_end || !next_frt.vector)) { hl_drawLineHoriz(x_vect, x, y_vect - 2, HGRAPHMODE_BLACK, hfile->buffer.mem); if (hfile->hobjs[no_obj + 1].datas.frt.vector == 0) { hl_drawPixel(x - 1, y_vect - 3, HGRAPHMODE_BLACK, hfile->buffer.mem); hl_drawPixel(x - 1, y_vect - 1, HGRAPHMODE_BLACK, hfile->buffer.mem); } x_vect = -1; } else if (frt.conjug && (is_end || !next_frt.conjug)) { hl_drawLineHoriz(x_vect, x - 2, y_vect - 2, HGRAPHMODE_BLACK, hfile->buffer.mem); x_vect = -1; } else if (frt.strike && (is_end || !next_frt.strike)) { hl_drawLineHoriz(x_strike, x - 2, y + font->upperline / 2, HGRAPHMODE_BLACK, hfile->buffer.mem); x_strike = -1; } //underline if (frt.link) { hl_drawLineHoriz(x_start, x - 2, y + font->upperline - 1 + 2, HGRAPHMODE_BLACK, hfile->buffer.mem); hl_drawPixel(x_start, y + font->upperline - 1 + 2 - 1, HGRAPHMODE_BLACK, hfile->buffer.mem); hl_drawPixel(x - 2, y + font->upperline - 1 + 2 - 1, HGRAPHMODE_BLACK, hfile->buffer.mem); hl_drawPixel(x_start, y + font->upperline - 1 + 2 + 1, HGRAPHMODE_BLACK, hfile->buffer.mem); hl_drawPixel(x - 2, y + font->upperline - 1 + 2 + 1, HGRAPHMODE_BLACK, hfile->buffer.mem); } else if (frt.underline && (is_end || !next_frt.underline)) { hl_drawLineHoriz(x_start, x - 2, y + font->upperline - 1 + 2, HGRAPHMODE_BLACK, hfile->buffer.mem); } else if (frt.dotted && (is_end || !next_frt.dotted)) { x2 = x_start; while (x2 + 5 < x - 1) { hl_drawLineHoriz(x2, x2 + 3, y + font->upperline - 1 + 2, HGRAPHMODE_BLACK, hfile->buffer.mem); x2 += 5; } hl_drawLineHoriz(x2, x - 2, y + font->upperline - 1 + 2, HGRAPHMODE_BLACK, hfile->buffer.mem); } if (frt.inversed && x_inv == -1) { x_inv = x_start; } if (frt.inversed && (is_end || !next_frt.inversed)) { hl_fillFrame(x_inv, y_top, x - 1, y_top + hscrline.height - 1, HGRAPHMODE_INVERSED, hfile->buffer.mem); x_inv = -1; } y_offset = font->upperline / 2; break; case HOBJECT_TIOS_LINE: case HOBJECT_END_TEXT: return; } no_obj++; pos_txt = hfile->hobjs[no_obj].pos_txt; } // next object } /** * Draw a page of text * * @param no_line the number of the first line to draw * @param hfile the file to draw */ void hl_drawPage(short no_line, h_File * hfile) { short y; if (no_line > 0) { hfile->line_top = no_line - 1; hfile->buffer.pos.y = hfile->hscrlines[no_line].height; } else if (no_line == 0) { hfile->line_top = 0; hfile->buffer.pos.y = 0; } hl_clrScreen(hfile->buffer); //clean the buffer no_line = hfile->line_top; hfile->drawn_height = 0; while (no_line < hfile->nb_scrlines && (y = hfile->hscrlines[no_line].height) + hfile->drawn_height <= hfile->buffer.size.height) { hdrawLine(no_line++, 0, hfile->drawn_height, hfile->buffer.size, hfile->buffer.mem, hfile); hfile->drawn_height += y; } hfile->line_bot = no_line - 1; }