/** * Gets the width of a string. The width of a string is not necesserily * the sum of all the widths of it's glyphs. * * @param text The string to return the width of. * @return The width of a string. */ int OpenGLFont::getWidth(const std::string& text) const { unsigned int w = 0; const char* ptr = text.c_str(); size_t textlen = strlen(ptr); while (textlen > 0) { Uint32 c = UTF8_getch(&ptr, &textlen); if (c == UNICODE_BOM_NATIVE || c == UNICODE_BOM_SWAPPED) { continue; } FT_GlyphSlot slot = this->pmpl->face->glyph; // Load glyph image into the slot int error = FT_Load_Char(this->pmpl->face, c, FT_LOAD_DEFAULT); if (error) continue; w += (slot->advance.x >> 6); } return w; }
void curses_drawwindow(WINDOW *win) { int i,j,drawx,drawy; unsigned tmp; RECT update = {win->x * fontwidth, -1, (win->x + win->width) * fontwidth, -1}; for (j=0; j<win->height; j++){ if (win->line[j].touched) { update.bottom = (win->y+j+1)*fontheight; if (update.top == -1) { update.top = update.bottom - fontheight; } win->line[j].touched=false; for (i=0; i<win->width; i++){ const cursecell &cell = win->line[j].chars[i]; if( cell.ch.empty() ) { continue; // second cell of a multi-cell character } drawx=((win->x+i)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if( drawx + fontwidth > WindowWidth || drawy + fontheight > WindowHeight ) { // Outside of the display area, would not render anyway continue; } const char* utf8str = cell.ch.c_str(); int len = cell.ch.length(); tmp = UTF8_getch(&utf8str, &len); int FG = cell.FG; int BG = cell.BG; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if (tmp != UNKNOWN_UNICODE) { int color = RGB(windowsPalette[FG].rgbRed,windowsPalette[FG].rgbGreen,windowsPalette[FG].rgbBlue); SetTextColor(backbuffer,color); int cw = mk_wcwidth(tmp); if (cw > 1) { FillRectDIB(drawx+fontwidth*(cw-1), drawy, fontwidth, fontheight, BG); i += cw - 1; } if (tmp) { const std::wstring utf16 = widen(cell.ch); ExtTextOutW( backbuffer, drawx, drawy, 0, NULL, utf16.c_str(), utf16.length(), NULL ); } } else { switch ((unsigned char)win->line[j].chars[i].ch[0]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; };//switch (tmp) }//(tmp < 0) };//for (i=0;i<_windows[w].width;i++) } };// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if (update.top != -1) { RedrawWindow(WindowHandle, &update, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } }
// If we're using curses, we need to provide get_input_event() here. input_event input_manager::get_input_event(WINDOW * /*win*/) { previously_pressed_key = 0; long key = getch(); // Our current tiles and Windows code doesn't have ungetch() #if !(defined TILES || defined SDLTILES || defined _WIN32 || defined WINDOWS) if (key != ERR) { long newch; // Clear the buffer of characters that match the one we're going to act on. timeout(0); do { newch = getch(); } while(newch != ERR && newch == key); timeout(-1); // If we read a different character than the one we're going to act on, re-queue it. if (newch != ERR && newch != key) { ungetch(newch); } } #endif input_event rval; if (key == ERR) { if (input_timeout > 0) { rval.type = CATA_INPUT_TIMEOUT; } else { rval.type = CATA_INPUT_ERROR; } #if !(defined TILES || defined SDLTILES || defined _WIN32 || defined WINDOWS || defined __CYGWIN__) // ncurses mouse handling } else if (key == KEY_MOUSE) { MEVENT event; if (getmouse(&event) == OK) { rval.type = CATA_INPUT_MOUSE; rval.mouse_x = event.x - VIEW_OFFSET_X; rval.mouse_y = event.y - VIEW_OFFSET_Y; if (event.bstate & BUTTON1_CLICKED) { rval.add_input(MOUSE_BUTTON_LEFT); } else if (event.bstate & BUTTON3_CLICKED) { rval.add_input(MOUSE_BUTTON_RIGHT); } else if (event.bstate & REPORT_MOUSE_POSITION) { rval.add_input(MOUSE_MOVE); if (input_timeout > 0) { // Mouse movement seems to clear ncurses timeout set_timeout(input_timeout); } } else { rval.type = CATA_INPUT_ERROR; } } else { rval.type = CATA_INPUT_ERROR; } #endif } else { if( key == 127 ) { // == Unicode DELETE previously_pressed_key = KEY_BACKSPACE; return input_event( KEY_BACKSPACE, CATA_INPUT_KEYBOARD ); } rval.type = CATA_INPUT_KEYBOARD; rval.text.append(1, (char) key); // Read the UTF-8 sequence (if any) if( key < 127 ) { // Single byte sequence } else if( 194 <= key && key <= 223 ) { rval.text.append(1, (char) getch() ); } else if( 224 <= key && key <= 239 ) { rval.text.append(1, (char) getch() ); rval.text.append(1, (char) getch() ); } else if( 240 <= key && key <= 244 ) { rval.text.append(1, (char) getch() ); rval.text.append(1, (char) getch() ); rval.text.append(1, (char) getch() ); } else { // Other control character, etc. - no text at all, return an event // without the text property previously_pressed_key = key; return input_event( key, CATA_INPUT_KEYBOARD ); } // Now we have loaded an UTF-8 sequence (possibly several bytes) // but we should only return *one* key, so return the code point of it. const char *utf8str = rval.text.c_str(); int len = rval.text.length(); const unsigned cp = UTF8_getch(&utf8str, &len); if( cp == UNKNOWN_UNICODE ) { // Invalid UTF-8 sequence, this should never happen, what now? // Maybe return any error instead? previously_pressed_key = key; return input_event( key, CATA_INPUT_KEYBOARD ); } previously_pressed_key = cp; // for compatibility only add the first byte, not the code point // as it would conflict with the special keys defined by ncurses rval.add_input(key); } return rval; }
void curses_drawwindow(WINDOW *win) { int i,j,w,drawx,drawy; unsigned tmp; for (j=0; j<win->height; j++){ if (win->line[j].touched) { needupdate = true; win->line[j].touched=false; for (i=0,w=0; w<win->width; i++,w++){ drawx=((win->x+w)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){ const char* utf8str = win->line[j].chars+i; int len = ANY_LENGTH; tmp = UTF8_getch(&utf8str, &len); int FG = win->line[j].FG[w]; int BG = win->line[j].BG[w]; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if ( tmp != UNKNOWN_UNICODE){ int cw = mk_wcwidth((wchar_t)tmp); len = ANY_LENGTH-len; if(cw>1) { FillRectDIB(drawx+fontwidth*(cw-1),drawy,fontwidth,fontheight,BG); w+=cw-1; } if(len>1) { i+=len-1; } if(tmp) OutputChar(tmp, drawx,drawy,FG); } else { switch ((unsigned char)win->line[j].chars[i]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; } };//switch (tmp) }//(tmp < 0) };//for (i=0;i<_windows[w].width;i++) } };// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if (needupdate) try_update(); }
// utf-8 version std::string word_rewrap (const std::string &ins, int width) { std::ostringstream o; std::string in = ins; // find non-printing tags std::vector<size_t> tag_positions = get_tag_positions(in); int lastwb = 0; //last word break int lastout = 0; const char *instr = in.c_str(); bool skipping_tag = false; for (int j = 0, x = 0; j < in.size(); ) { const char *ins = instr + j; int len = ANY_LENGTH; unsigned uc = UTF8_getch(&ins, &len); if (uc == '<') { // maybe skip non-printing tag std::vector<size_t>::iterator it; for (it = tag_positions.begin(); it != tag_positions.end(); ++it) { if (*it == j) { skipping_tag = true; break; } } } j += ANY_LENGTH - len; if (skipping_tag) { if (uc == '>') { skipping_tag = false; } continue; } x += mk_wcwidth(uc); if (x > width) { if (lastwb == lastout) { lastwb = j; } for(int k = lastout; k < lastwb; k++) { o << in[k]; } o << '\n'; x = 0; lastout = j = lastwb; } if (uc == ' ' || uc >= 0x2E80) { lastwb = j; } } for (int k = lastout; k < in.size(); k++) { o << in[k]; } return o.str(); }
void curses_drawwindow(WINDOW *win) { int i,j,w,drawx,drawy; unsigned tmp; RECT update = {win->x * fontwidth, -1, (win->x + win->width) * fontwidth, -1}; for (j=0; j<win->height; j++){ if (win->line[j].touched) { update.bottom = (win->y+j+1)*fontheight; if (update.top == -1) { update.top = update.bottom - fontheight; } win->line[j].touched=false; for (i=0,w=0; w<win->width; i++,w++){ drawx=((win->x+w)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){ const char* utf8str = win->line[j].chars+i; int len = ANY_LENGTH; tmp = UTF8_getch(&utf8str, &len); int FG = win->line[j].FG[w]; int BG = win->line[j].BG[w]; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if (tmp != UNKNOWN_UNICODE) { int color = RGB(windowsPalette[FG].rgbRed,windowsPalette[FG].rgbGreen,windowsPalette[FG].rgbBlue); SetTextColor(backbuffer,color); int cw = mk_wcwidth(tmp); len = ANY_LENGTH-len; if (cw > 1) { FillRectDIB(drawx+fontwidth*(cw-1), drawy, fontwidth, fontheight, BG); w += cw - 1; } if (len > 1) { i += len - 1; } if (tmp) ExtTextOutW (backbuffer, drawx, drawy, 0, NULL, (WCHAR*)&tmp, 1, NULL); } else { switch ((unsigned char)win->line[j].chars[i]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; } };//switch (tmp) }//(tmp < 0) };//for (i=0;i<_windows[w].width;i++) } };// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if (update.top != -1) { RedrawWindow(WindowHandle, &update, NULL, RDW_INVALIDATE | RDW_UPDATENOW); } }
int waddch(WINDOW *win, const chtype ch) { char charcode; charcode=ch; switch (ch){ //LINE_NESW - X for on, O for off case LINE_XOXO: //#define LINE_XOXO 4194424 charcode=LINE_XOXO_C; break; case LINE_OXOX: //#define LINE_OXOX 4194417 charcode=LINE_OXOX_C; break; case LINE_XXOO: //#define LINE_XXOO 4194413 charcode=LINE_XXOO_C; break; case LINE_OXXO: //#define LINE_OXXO 4194412 charcode=LINE_OXXO_C; break; case LINE_OOXX: //#define LINE_OOXX 4194411 charcode=LINE_OOXX_C; break; case LINE_XOOX: //#define LINE_XOOX 4194410 charcode=LINE_XOOX_C; break; case LINE_XXOX: //#define LINE_XXOX 4194422 charcode=LINE_XXOX_C; break; case LINE_XXXO: //#define LINE_XXXO 4194420 charcode=LINE_XXXO_C; break; case LINE_XOXX: //#define LINE_XOXX 4194421 charcode=LINE_XOXX_C; break; case LINE_OXXX: //#define LINE_OXXX 4194423 charcode=LINE_OXXX_C; break; case LINE_XXXX: //#define LINE_XXXX 4194414 charcode=LINE_XXXX_C; break; default: charcode = (char)ch; break; } int cury=win->cursory; int p = win->cursorx; int curx=(win->line[cury].width_in_bytes==win->width)?win->cursorx:cursorx_to_position(win->line[cury].chars, win->cursorx, &p); if(curx!=p) { const char* ts = win->line[cury].chars+p; int len = ANY_LENGTH; unsigned tc = UTF8_getch(&ts, &len); int tw = mk_wcwidth((wchar_t)tc); win->line[cury].width_in_bytes += erease_utf8_by_cw(win->line[cury].chars+p, tw, tw, win->width*4-p-1); curx = p+tw-1; } else if(win->line[cury].width_in_bytes!=win->width) { win->line[cury].width_in_bytes += erease_utf8_by_cw(win->line[cury].chars+p, 1, 1, win->width*4-p-1); } //if (win2 > -1){ win->line[cury].chars[curx]=charcode; win->line[cury].FG[win->cursorx]=win->FG; win->line[cury].BG[win->cursorx]=win->BG; win->draw=true; addedchar(win); return 1; // else{ // win2=win2+1; }
void curses_drawwindow(WINDOW *win) { int i,j,w,drawx,drawy; unsigned tmp; int miny = 99999; int maxy = -99999; for (j=0; j<win->height; j++) { if (win->line[j].touched) { if(j<miny) { miny=j; } if(j>maxy) { maxy=j; } win->line[j].touched=false; for (i=0,w=0; w<win->width; i++,w++) { drawx=((win->x+w)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)) { const char* utf8str = win->line[j].chars+i; int len = ANY_LENGTH; tmp = UTF8_getch(&utf8str, &len); int FG = win->line[j].FG[w]; int BG = win->line[j].BG[w]; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if ( tmp != UNKNOWN_UNICODE){ int cw = mk_wcwidth((wchar_t)tmp); len = ANY_LENGTH-len; if(cw>1) { FillRectDIB(drawx+fontwidth*(cw-1),drawy,fontwidth,fontheight,BG); w+=cw-1; } if(len>1) { i+=len-1; } if(0!=tmp) { OutputChar(tmp, drawx,drawy,FG); } } else { switch ((unsigned char)win->line[j].chars[i]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; }//switch (tmp) } }//(tmp < 0) }//for (i=0;i<_windows[w].width;i++) } }// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if(maxy>=0) { int tx=win->x, ty=win->y+miny, tw=win->width, th=maxy-miny+1; int maxw=WindowWidth/fontwidth, maxh=WindowHeight/fontheight; if(tw+tx>maxw) { tw= maxw-tx; } if(th+ty>maxh) { th= maxh-ty; } SDL_UpdateRect(screen, tx*fontwidth, ty*fontheight, tw*fontwidth, th*fontheight); } }
void curses_drawwindow(WINDOW *win) { int i,j,w,drawx,drawy; unsigned tmp; SDL_Rect update_rect; update_rect.x = win->x * fontwidth; update_rect.w = win->width * fontwidth; update_rect.y = 9999; // default value update_rect.h = 9999; // default value int jr = 0; for (j=0; j<win->height; j++){ if (win->line[j].touched) { if (update_rect.y == 9999) { update_rect.y = (win->y+j)*fontheight; jr=j; } update_rect.h = (j-jr+1)*fontheight; needupdate = true; win->line[j].touched=false; for (i=0,w=0; w<win->width; i++,w++){ drawx=((win->x+w)*fontwidth); drawy=((win->y+j)*fontheight);//-j; if (((drawx+fontwidth)<=WindowWidth) && ((drawy+fontheight)<=WindowHeight)){ const char* utf8str = win->line[j].chars+i; int len = ANY_LENGTH; tmp = UTF8_getch(&utf8str, &len); int FG = win->line[j].FG[w]; int BG = win->line[j].BG[w]; FillRectDIB(drawx,drawy,fontwidth,fontheight,BG); if ( tmp != UNKNOWN_UNICODE){ int cw = mk_wcwidth(tmp); len = ANY_LENGTH-len; if(cw>1) { FillRectDIB(drawx+fontwidth*(cw-1),drawy,fontwidth,fontheight,BG); w+=cw-1; } if(len>1) { i+=len-1; } if(tmp) OutputChar(tmp, drawx,drawy,FG); } else { switch ((unsigned char)win->line[j].chars[i]) { case LINE_OXOX_C://box bottom/top side (horizontal line) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_XOXO_C://box left/right side (vertical line) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_OXXO_C://box top left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_OOXX_C://box top right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XOOX_C://box bottom right HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOO_C://box bottom left HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight+1,2,FG); break; case LINE_XXOX_C://box bottom north T (left, right, up) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+halfheight,2,FG); break; case LINE_XXXO_C://box bottom east T (up, right, down) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx+halfwidth,drawy+halfheight,drawx+fontwidth,1,FG); break; case LINE_OXXX_C://box bottom south T (left, right, down) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy+halfheight,drawy+fontheight,2,FG); break; case LINE_XXXX_C://box X (left down up right) HorzLineDIB(drawx,drawy+halfheight,drawx+fontwidth,1,FG); VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); break; case LINE_XOXX_C://box bottom east T (left, down, up) VertLineDIB(drawx+halfwidth,drawy,drawy+fontheight,2,FG); HorzLineDIB(drawx,drawy+halfheight,drawx+halfwidth,1,FG); break; default: break; } };//switch (tmp) }//(tmp < 0) };//for (i=0;i<_windows[w].width;i++) } };// for (j=0;j<_windows[w].height;j++) win->draw=false; //We drew the window, mark it as so if (g && win == g->w_terrain && use_tiles) { update_rect.y = win->y*tilecontext->tile_height; update_rect.h = win->height*tilecontext->tile_height; update_rect.x = win->y*tilecontext->tile_width; update_rect.w = win->width*tilecontext->tile_width; //GfxDraw(thegame, win->x*fontwidth, win->y*fontheight, thegame->terrain_view_x, thegame->terrain_view_y, win->width*fontwidth, win->height*fontheight); tilecontext->draw(win->x * fontwidth, win->y * fontheight, g->ter_view_x, g->ter_view_y, tilecontext->terrain_term_x * fontwidth, tilecontext->terrain_term_y * fontheight); } //*/ if (update_rect.y != 9999) { SDL_UpdateRect(screen, update_rect.x, update_rect.y, update_rect.w, update_rect.h); } if (needupdate) try_update(); }