|
1
|
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 } |