Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "shared.h" | |
| 2 | |
| 3 | |
| 4 static bool is_rect_null(const RECT * r) | |
| 5 { | |
| 6 return r->right <= r->left || r->bottom <= r->top; | |
| 7 } | |
| 8 | |
| 9 UINT SHARED_EXPORT uGetTextHeight(HDC dc) | |
| 10 { | |
| 11 TEXTMETRIC tm; | |
| 12 POINT pt[2]; | |
| 13 GetTextMetrics(dc,&tm); | |
| 14 pt[0].x = 0; | |
| 15 pt[0].y = tm.tmHeight; | |
| 16 pt[1].x = 0; | |
| 17 pt[1].y = 0; | |
| 18 LPtoDP(dc,pt,2); | |
| 19 | |
| 20 int ret = pt[0].y - pt[1].y; | |
| 21 return ret > 1 ? (unsigned)ret : 1; | |
| 22 } | |
| 23 | |
| 24 static int get_text_width(HDC dc,const TCHAR * src,int len) | |
| 25 { | |
| 26 if (len<=0) return 0; | |
| 27 else | |
| 28 { | |
| 29 SIZE goatse; | |
| 30 GetTextExtentPoint32(dc,src,len,&goatse); | |
| 31 return goatse.cx; | |
| 32 } | |
| 33 } | |
| 34 | |
| 35 //GetTextExtentPoint32 wrapper, removes color marks | |
| 36 static int get_text_width_color(HDC dc,const TCHAR * src,int len) | |
| 37 { | |
| 38 int ptr = 0; | |
| 39 int start = 0; | |
| 40 int rv = 0; | |
| 41 if (len<0) len = (int) _tcslen(src); | |
| 42 while(ptr<len) | |
| 43 { | |
| 44 if (src[ptr]==3) | |
| 45 { | |
| 46 rv += get_text_width(dc,src+start,ptr-start); | |
| 47 ptr++; | |
| 48 while(ptr<len && src[ptr]!=3) ptr++; | |
| 49 if (ptr<len) ptr++; | |
| 50 start = ptr; | |
| 51 } | |
| 52 else ptr++; | |
| 53 } | |
| 54 rv += get_text_width(dc,src+start,ptr-start); | |
| 55 return rv; | |
| 56 } | |
| 57 | |
| 58 | |
| 59 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) | |
| 60 { | |
| 61 if (clip) | |
| 62 { | |
| 63 if (is_rect_null(clip) || clip->right<=pos_x || clip->bottom<=pos_y) return TRUE; | |
| 64 } | |
| 65 SetTextAlign(dc,TA_LEFT); | |
| 66 SetBkMode(dc,TRANSPARENT); | |
| 67 SetTextColor(dc,selected ? 0xFFFFFF - default_color : default_color); | |
| 68 | |
| 69 int title_ptr = 0; | |
| 70 int textout_start = 0; | |
| 71 int position = pos_x;//item.left+BORDER; | |
| 72 | |
| 73 for(;;) | |
| 74 { | |
| 75 if (title_ptr>=len || src[title_ptr]==3) | |
| 76 { | |
| 77 if (title_ptr>textout_start) | |
| 78 { | |
| 79 int width = get_text_width(dc,src+textout_start,title_ptr-textout_start); | |
| 80 ExtTextOut(dc,position,pos_y,clip ? ETO_CLIPPED : 0,clip,src+textout_start,title_ptr-textout_start,0); | |
| 81 position += width; | |
| 82 textout_start = title_ptr; | |
| 83 } | |
| 84 if (title_ptr>=len) break; | |
| 85 } | |
| 86 if (src[title_ptr]==3) | |
| 87 { | |
| 88 DWORD new_color; | |
| 89 DWORD new_inverted; | |
| 90 bool have_inverted = false; | |
| 91 | |
| 92 if (src[title_ptr+1]==3) {new_color=default_color;title_ptr+=2;} | |
| 93 else | |
| 94 { | |
| 95 title_ptr++; | |
| 96 new_color = _tcstoul(src+title_ptr,0,16); | |
| 97 while(title_ptr<len && src[title_ptr]!=3) | |
| 98 { | |
| 99 if (!have_inverted && src[title_ptr-1]=='|') | |
| 100 { | |
| 101 new_inverted = _tcstoul(src+title_ptr,0,16); | |
| 102 have_inverted = true; | |
| 103 } | |
| 104 title_ptr++; | |
| 105 } | |
| 106 if (title_ptr<len) title_ptr++; | |
| 107 } | |
| 108 if (selected) new_color = have_inverted ? new_inverted : 0xFFFFFF - new_color; | |
| 109 SetTextColor(dc,new_color); | |
| 110 textout_start = title_ptr; | |
| 111 } | |
| 112 else | |
| 113 { | |
| 114 title_ptr = (int)( CharNext(src+title_ptr)-src ); | |
| 115 } | |
| 116 } | |
| 117 return TRUE; | |
| 118 } | |
| 119 | |
| 120 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) | |
| 121 { | |
| 122 RECT clip; | |
| 123 if (base_clip) | |
| 124 IntersectRect(&clip,base_clip,item); | |
| 125 else clip = *item; | |
| 126 | |
| 127 if (is_rect_null(&clip)) return TRUE; | |
| 128 | |
| 129 int pos_y = item->top + (item->bottom-item->top - (int)uGetTextHeight(dc)) / 2; | |
| 130 | |
| 131 int n_tabs = 0; | |
| 132 int total_width = 0; | |
| 133 { | |
| 134 int start = 0; | |
| 135 int n; | |
| 136 for(n=0;n<display_len;n++) | |
| 137 { | |
| 138 if (display[n]=='\t') | |
| 139 { | |
| 140 if (start<n) total_width += get_text_width_color(dc,display+start,n-start) + 2*border; | |
| 141 start = n+1; | |
| 142 n_tabs++; | |
| 143 } | |
| 144 } | |
| 145 if (start<display_len) | |
| 146 { | |
| 147 total_width += get_text_width_color(dc,display+start,display_len-start) + 2*border; | |
| 148 } | |
| 149 } | |
| 150 | |
| 151 int tab_total = item->right - item->left; | |
| 152 if (!columns) tab_total -= total_width; | |
| 153 int ptr = display_len; | |
| 154 int tab_ptr = 0; | |
| 155 int written = 0; | |
| 156 int clip_x = item->right; | |
| 157 do | |
| 158 { | |
| 159 int ptr_end = ptr; | |
| 160 while(ptr>0 && display[ptr-1]!='\t') ptr--; | |
| 161 const TCHAR * t_string = display + ptr; | |
| 162 int t_length = ptr_end - ptr; | |
| 163 if (t_length>0) | |
| 164 { | |
| 165 int t_width = get_text_width_color(dc,t_string,t_length) + border*2; | |
| 166 | |
| 167 int pos_x; | |
| 168 int pos_x_right; | |
| 169 | |
| 170 if (!columns) | |
| 171 { | |
| 172 pos_x_right = item->right - MulDiv(tab_ptr,tab_total,n_tabs) - written; | |
| 173 } | |
| 174 else | |
| 175 { | |
| 176 if (tab_ptr==0) pos_x_right = item->right; | |
| 177 else pos_x_right = item->right - MulDiv(tab_ptr,tab_total,n_tabs) + t_width; | |
| 178 } | |
| 179 | |
| 180 if (ptr==0) | |
| 181 { | |
| 182 pos_x = item->left; | |
| 183 } | |
| 184 else | |
| 185 { | |
| 186 pos_x = pos_x_right - t_width ; | |
| 187 if (pos_x<item->left) pos_x = item->left; | |
| 188 } | |
| 189 | |
| 190 RECT t_clip = clip; | |
| 191 | |
| 192 if (t_clip.right > clip_x) t_clip.right = clip_x; | |
| 193 | |
| 194 text_out_colors(dc,t_string,t_length,pos_x+border,pos_y,&t_clip,selected,default_color); | |
| 195 | |
| 196 if (clip_x>pos_x) clip_x = pos_x; | |
| 197 | |
| 198 written += t_width; | |
| 199 } | |
| 200 | |
| 201 if (ptr>0) | |
| 202 { | |
| 203 ptr--;//tab char | |
| 204 tab_ptr++; | |
| 205 } | |
| 206 } | |
| 207 while(ptr>0); | |
| 208 | |
| 209 return TRUE; | |
| 210 } | |
| 211 | |
| 212 extern "C" { | |
| 213 | |
| 214 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) | |
| 215 { | |
| 216 try { | |
| 217 pfc::stringcvt::string_os_from_utf8 temp(p_text); | |
| 218 return text_out_colors(dc,temp,pfc::downcast_guarded<int>(temp.length()),x,y,clip,!!is_selected,default_color); | |
| 219 } catch(...) {return FALSE;} | |
| 220 } | |
| 221 | |
| 222 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) | |
| 223 { | |
| 224 try { | |
| 225 pfc::stringcvt::string_os_from_utf8 temp(p_text); | |
| 226 return text_out_colors_tab(dc,temp,pfc::downcast_guarded<int>(temp.length()),item,border,clip,!!selected,default_color,!!use_columns); | |
| 227 } catch(...) {return FALSE;} | |
| 228 } | |
| 229 | |
| 230 } |
