Mercurial > foo_out_sdl
view foosdk/sdk/foobar2000/shared/text_drawing.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line source
#include "shared.h" static bool is_rect_null(const RECT * r) { return r->right <= r->left || r->bottom <= r->top; } UINT SHARED_EXPORT uGetTextHeight(HDC dc) { TEXTMETRIC tm; POINT pt[2]; GetTextMetrics(dc,&tm); pt[0].x = 0; pt[0].y = tm.tmHeight; pt[1].x = 0; pt[1].y = 0; LPtoDP(dc,pt,2); int ret = pt[0].y - pt[1].y; return ret > 1 ? (unsigned)ret : 1; } static int get_text_width(HDC dc,const TCHAR * src,int len) { if (len<=0) return 0; else { SIZE goatse; GetTextExtentPoint32(dc,src,len,&goatse); return goatse.cx; } } //GetTextExtentPoint32 wrapper, removes color marks static int get_text_width_color(HDC dc,const TCHAR * src,int len) { int ptr = 0; int start = 0; int rv = 0; if (len<0) len = (int) _tcslen(src); while(ptr<len) { if (src[ptr]==3) { rv += get_text_width(dc,src+start,ptr-start); ptr++; while(ptr<len && src[ptr]!=3) ptr++; if (ptr<len) ptr++; start = ptr; } else ptr++; } rv += get_text_width(dc,src+start,ptr-start); return rv; } static BOOL text_out_colors(HDC dc,const TCHAR * src,int len,int pos_x,int pos_y,const RECT * clip,bool selected,DWORD default_color) { if (clip) { if (is_rect_null(clip) || clip->right<=pos_x || clip->bottom<=pos_y) return TRUE; } SetTextAlign(dc,TA_LEFT); SetBkMode(dc,TRANSPARENT); SetTextColor(dc,selected ? 0xFFFFFF - default_color : default_color); int title_ptr = 0; int textout_start = 0; int position = pos_x;//item.left+BORDER; for(;;) { if (title_ptr>=len || src[title_ptr]==3) { if (title_ptr>textout_start) { int width = get_text_width(dc,src+textout_start,title_ptr-textout_start); ExtTextOut(dc,position,pos_y,clip ? ETO_CLIPPED : 0,clip,src+textout_start,title_ptr-textout_start,0); position += width; textout_start = title_ptr; } if (title_ptr>=len) break; } if (src[title_ptr]==3) { DWORD new_color; DWORD new_inverted; bool have_inverted = false; if (src[title_ptr+1]==3) {new_color=default_color;title_ptr+=2;} else { title_ptr++; new_color = _tcstoul(src+title_ptr,0,16); while(title_ptr<len && src[title_ptr]!=3) { if (!have_inverted && src[title_ptr-1]=='|') { new_inverted = _tcstoul(src+title_ptr,0,16); have_inverted = true; } title_ptr++; } if (title_ptr<len) title_ptr++; } if (selected) new_color = have_inverted ? new_inverted : 0xFFFFFF - new_color; SetTextColor(dc,new_color); textout_start = title_ptr; } else { title_ptr = (int)( CharNext(src+title_ptr)-src ); } } return TRUE; } static BOOL text_out_colors_tab(HDC dc,const TCHAR * display,int display_len,const RECT * item,int border,const RECT * base_clip,bool selected,DWORD default_color,bool columns) { RECT clip; if (base_clip) IntersectRect(&clip,base_clip,item); else clip = *item; if (is_rect_null(&clip)) return TRUE; int pos_y = item->top + (item->bottom-item->top - (int)uGetTextHeight(dc)) / 2; int n_tabs = 0; int total_width = 0; { int start = 0; int n; for(n=0;n<display_len;n++) { if (display[n]=='\t') { if (start<n) total_width += get_text_width_color(dc,display+start,n-start) + 2*border; start = n+1; n_tabs++; } } if (start<display_len) { total_width += get_text_width_color(dc,display+start,display_len-start) + 2*border; } } int tab_total = item->right - item->left; if (!columns) tab_total -= total_width; int ptr = display_len; int tab_ptr = 0; int written = 0; int clip_x = item->right; do { int ptr_end = ptr; while(ptr>0 && display[ptr-1]!='\t') ptr--; const TCHAR * t_string = display + ptr; int t_length = ptr_end - ptr; if (t_length>0) { int t_width = get_text_width_color(dc,t_string,t_length) + border*2; int pos_x; int pos_x_right; if (!columns) { pos_x_right = item->right - MulDiv(tab_ptr,tab_total,n_tabs) - written; } else { if (tab_ptr==0) pos_x_right = item->right; else pos_x_right = item->right - MulDiv(tab_ptr,tab_total,n_tabs) + t_width; } if (ptr==0) { pos_x = item->left; } else { pos_x = pos_x_right - t_width ; if (pos_x<item->left) pos_x = item->left; } RECT t_clip = clip; if (t_clip.right > clip_x) t_clip.right = clip_x; text_out_colors(dc,t_string,t_length,pos_x+border,pos_y,&t_clip,selected,default_color); if (clip_x>pos_x) clip_x = pos_x; written += t_width; } if (ptr>0) { ptr--;//tab char tab_ptr++; } } while(ptr>0); return TRUE; } extern "C" { BOOL SHARED_EXPORT uTextOutColors(HDC dc,const char * p_text,UINT len,int x,int y,const RECT * clip,BOOL is_selected,DWORD default_color) { try { pfc::stringcvt::string_os_from_utf8 temp(p_text); return text_out_colors(dc,temp,pfc::downcast_guarded<int>(temp.length()),x,y,clip,!!is_selected,default_color); } catch(...) {return FALSE;} } BOOL SHARED_EXPORT uTextOutColorsTabbed(HDC dc,const char * p_text,UINT len,const RECT * item,int border,const RECT * clip,BOOL selected,DWORD default_color,BOOL use_columns) { try { pfc::stringcvt::string_os_from_utf8 temp(p_text); return text_out_colors_tab(dc,temp,pfc::downcast_guarded<int>(temp.length()),item,border,clip,!!selected,default_color,!!use_columns); } catch(...) {return FALSE;} } }
