Mercurial > mplayer.hg
annotate gui/win32/widgetrender.c @ 36295:0bd0297b073a
Handle special argument -1 to switch_ratio as intended.
Reset to the original aspect ratio that would have been used for
the very first rescaling rather than to the display size ratio.
This will now handle anamorphic videos correctly as well.
author | ib |
---|---|
date | Thu, 01 Aug 2013 21:18:14 +0000 |
parents | 5b01e1e9d9ef |
children | 98568083fb1d |
rev | line source |
---|---|
23077 | 1 /* |
23079 | 2 * MPlayer GUI for Win32 |
3 * Copyright (C) 2003 Sascha Sommer <saschasommer@freenet.de> | |
4 * Copyright (C) 2006 Erik Augustson <erik_27can@yahoo.com> | |
5 * Copyright (C) 2006 Gianluigi Tiesi <sherpya@netfarm.it> | |
6 * | |
7 * This file is part of MPlayer. | |
8 * | |
9 * MPlayer is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * MPlayer is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
26457 | 19 * You should have received a copy of the GNU General Public License along |
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
23079 | 22 */ |
23077 | 23 |
24 #include <stdio.h> | |
25 #include <ctype.h> | |
26 #include <windows.h> | |
23091
52488bb09d90
Consistently use quotes instead of angled brackets in #include
diego
parents:
23079
diff
changeset
|
27 |
33564 | 28 #include "gui/util/bitmap.h" |
34175 | 29 #include "gui/util/string.h" |
26372
76413880bfad
Update include paths to account for build system changes.
diego
parents:
23091
diff
changeset
|
30 #include "gui/interface.h" |
23077 | 31 #include "gui.h" |
32 | |
33 #define MAX_LABELSIZE 250 | |
34 | |
35 static void render(int bitsperpixel, image *dst, image *src, int x, int y, int sx, int sy, int sw, int sh, int transparent) | |
36 { | |
37 int i; | |
38 int bpp = bitsperpixel / 8; | |
39 int offset = (dst->width * bpp * y) + (x * bpp); | |
40 int soffset = (src->width * bpp * sy) + (sx * bpp); | |
41 | |
42 for(i=0; i<sh; i++) | |
43 { | |
44 int c; | |
45 for(c=0; c < (sw * bpp); c += bpp) | |
46 { | |
47 if(bpp == 2) | |
48 { | |
49 if(!transparent || (((src->data + soffset + (i * src->width * bpp) + c)[0] != 0x1f) | |
50 && ((src->data + soffset + (i * src->width * bpp) + c)[1] != 0x7c))) | |
51 memcpy(dst->data + offset + c, src->data + soffset + (i * src->width * bpp) + c, bpp); | |
52 } | |
53 else if(bpp > 2) | |
54 { | |
33534 | 55 if(!transparent || !IS_TRANSPARENT(*((unsigned int *) (src->data + soffset + (i * src->width * bpp) + c)))) |
23077 | 56 memcpy(dst->data + offset + c, src->data + soffset + (i * src->width * bpp) + c, bpp); |
57 } | |
58 } | |
59 offset += (dst->width * bpp); | |
60 } | |
61 } | |
62 | |
63 static image *find_background(skin_t *skin, widget *item) | |
64 { | |
65 unsigned int i; | |
66 for (i=0; i < skin->windowcount; i++) | |
67 if(skin->windows[i]->type == item->window) | |
68 return skin->windows[i]->base->bitmap[0]; | |
69 return NULL; | |
70 } | |
71 | |
72 /******************************************************************/ | |
73 /* FONT related functions */ | |
74 /******************************************************************/ | |
75 | |
76 /* returns the pos of s2 inside s1 or -1 if s1 doesn't contain s2 */ | |
77 static int strpos(char *s1, const char* s2) | |
78 { | |
79 unsigned int i, x; | |
80 for (i=0; i < strlen(s1); i++) | |
81 { | |
82 if(s1[i] == s2[0]) | |
83 { | |
84 if(strlen(s1 + i) >= strlen(s2)) | |
85 { | |
86 for (x=0; x <strlen(s2); x++) | |
87 if(s1[i + x] != s2[x]) break; | |
88 if(x == strlen(s2)) return i; | |
89 } | |
90 } | |
91 } | |
92 return -1; | |
93 } | |
94 | |
95 /* replaces all occurences of what in dest with format */ | |
96 static void stringreplace(char *dest, const char *what, const char *format, ... ) | |
97 { | |
98 char tmp[MAX_LABELSIZE]; | |
99 int offset=0; | |
100 va_list va; | |
101 va_start(va, format); | |
102 vsnprintf(tmp, MAX_LABELSIZE, format, va); | |
103 va_end(va); | |
104 /* no search string == replace the entire string */ | |
105 if(!what) | |
106 { | |
107 memcpy(dest, tmp, strlen(tmp)); | |
108 dest[strlen(tmp)] = 0; | |
109 return; | |
110 } | |
111 while((offset = strpos(dest, what)) != -1) | |
112 { | |
113 memmove(dest + offset + strlen(tmp), dest + offset + strlen(what), strlen(dest + offset + strlen(what)) + 1); | |
114 memcpy(dest + offset, tmp, strlen(tmp)); | |
115 } | |
116 } | |
117 | |
118 /* replaces the chars with special meaning with the associated data from the player info struct */ | |
119 static char *generatetextfromlabel(widget *item) | |
120 { | |
121 char *text = malloc(MAX_LABELSIZE); | |
122 char tmp[MAX_LABELSIZE]; | |
123 if(!item) | |
124 { | |
125 free(text); | |
126 return NULL; | |
127 } | |
128 strcpy(text, item->label); | |
129 if(item->type == tySlabel) return text; | |
33897 | 130 stringreplace(text, "$1", "%.2i:%.2i:%.2i", guiInfo.ElapsedTime / 3600, |
131 (guiInfo.ElapsedTime / 60) % 60, guiInfo.ElapsedTime % 60); | |
132 stringreplace(text, "$2", "%.4i:%.2i", guiInfo.ElapsedTime / 60, guiInfo.ElapsedTime % 60); | |
133 stringreplace(text, "$3", "%.2i", guiInfo.ElapsedTime / 3600); | |
134 stringreplace(text, "$4", "%.2i", (guiInfo.ElapsedTime / 60) % 60); | |
135 stringreplace(text, "$5", "%.2i", guiInfo.ElapsedTime % 60); | |
136 stringreplace(text, "$6", "%.2i:%.2i:%.2i", guiInfo.RunningTime / 3600, | |
137 (guiInfo.RunningTime / 60) % 60, guiInfo.RunningTime % 60); | |
138 stringreplace(text, "$7", "%.4i:%.2i", guiInfo.RunningTime / 60, guiInfo.RunningTime % 60); | |
139 stringreplace(text, "$8", "%i:%.2i:%.2i", guiInfo.ElapsedTime / 3600, | |
140 (guiInfo.ElapsedTime / 60) % 60, guiInfo.ElapsedTime % 60); | |
33555 | 141 stringreplace(text, "$v", "%3.2f", guiInfo.Volume); |
142 stringreplace(text, "$V", "%3.1f", guiInfo.Volume); | |
143 stringreplace(text, "$b", "%3.2f", guiInfo.Balance); | |
144 stringreplace(text, "$B", "%3.1f", guiInfo.Balance); | |
145 stringreplace(text, "$t", "%.2i", guiInfo.Track); | |
34163 | 146 stringreplace(text, "$o", "%s", acp(TranslateFilename(0, tmp, sizeof(tmp)))); |
33901 | 147 stringreplace(text, "$x", "%i", guiInfo.VideoWidth); |
148 stringreplace(text, "$y", "%i", guiInfo.VideoHeight); | |
33555 | 149 stringreplace(text, "$C", "%s", guiInfo.sh_video ? codecname : ""); |
23077 | 150 stringreplace(text, "$$", "$"); |
151 | |
152 if(!strcmp(text, "$p") || !strcmp(text, "$s") || !strcmp(text, "$e")) | |
153 { | |
33615
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33564
diff
changeset
|
154 if(guiInfo.Playing == GUI_STOP) stringreplace(text, NULL, "s"); |
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33564
diff
changeset
|
155 else if(guiInfo.Playing == GUI_PLAY) stringreplace(text, NULL, "p"); |
1f9a31d4f114
Replace all playback integer constants by their symbolic constants.
ib
parents:
33564
diff
changeset
|
156 else if(guiInfo.Playing == GUI_PAUSE) stringreplace(text, NULL, "e"); |
23077 | 157 } |
158 | |
33646 | 159 if(guiInfo.AudioChannels == 0) stringreplace(text, "$a", "n"); |
160 else if(guiInfo.AudioChannels == 1) stringreplace(text, "$a", "m"); | |
23077 | 161 else stringreplace(text, "$a", "t"); |
162 | |
33555 | 163 if(guiInfo.StreamType == 0) |
23077 | 164 stringreplace(text, "$T", "f"); |
33555 | 165 else if(guiInfo.StreamType == STREAMTYPE_DVD || guiInfo.StreamType == STREAMTYPE_DVDNAV) |
23077 | 166 stringreplace(text, "$T", "d"); |
167 else stringreplace(text, "$T", "u"); | |
168 | |
34163 | 169 stringreplace(text, "$f", acp(TranslateFilename(1, tmp, sizeof(tmp)))); |
170 stringreplace(text, "$F", acp(TranslateFilename(2, tmp, sizeof(tmp)))); | |
23077 | 171 |
172 return text; | |
173 } | |
174 | |
175 /* cuts text to buflen scrolling from right to left */ | |
176 static void scrolltext(char *text, unsigned int buflen, float *value) | |
177 { | |
30702 | 178 char *buffer = malloc(buflen + 1); |
23077 | 179 unsigned int x,i; |
180 if(*value < buflen) x = 0; | |
181 else x = *value - buflen; | |
182 memset(buffer, ' ', buflen); | |
183 for (i = (*value>=buflen) ? 0 : buflen - *value; i<buflen; i++) | |
184 { | |
185 if(x < strlen(text)) | |
186 buffer[i] = text[x]; | |
187 x++; | |
188 } | |
189 buffer[buflen] = 0; | |
190 *value += 1.0f; | |
191 if(*value >= strlen(text) + buflen) *value = 0.0f; | |
192 strcpy(text, buffer); | |
193 free(buffer); | |
194 } | |
195 | |
196 /* updates all dlabels and slabels */ | |
197 void renderinfobox(skin_t *skin, window_priv_t *priv) | |
198 { | |
199 unsigned int i; | |
200 if (!priv) return; | |
201 | |
202 /* repaint the area behind the text*/ | |
203 /* we have to do this for all labels here, because they may overlap in buggy skins ;( */ | |
204 | |
205 for (i=0; i<skin->widgetcount; i++) | |
206 if((skin->widgets[i]->type == tyDlabel) || (skin->widgets[i]->type == tySlabel)) | |
207 { | |
208 if(skin->widgets[i]->window == priv->type) | |
209 render(skin->desktopbpp, | |
210 &priv->img, | |
211 find_background(skin, skin->widgets[i]), | |
212 skin->widgets[i]->x, | |
213 skin->widgets[i]->y, | |
214 skin->widgets[i]->x, | |
215 skin->widgets[i]->y, | |
216 skin->widgets[i]->length, | |
217 skin->widgets[i]->font->chars[0]->height, | |
218 1); | |
219 } | |
220 | |
221 /* load all slabels and dlabels */ | |
222 for (i=0; i<skin->widgetcount; i++) | |
223 { | |
224 widget *item = skin->widgets[i]; | |
225 if(item->window != priv->type) continue; | |
226 if((i == skin->widgetcount) || (item->type == tyDlabel) || (item->type == tySlabel)) | |
227 { | |
228 char *text = generatetextfromlabel(item); | |
229 unsigned int current, c; | |
230 int offset = 0; | |
231 unsigned int textlen; | |
232 if(!text) continue; | |
233 textlen = strlen(text); | |
234 | |
235 /* render(win, win->background, gui->skin->widgets[i]->x, gui->skin->widgets[i]->y, | |
236 gui->skin->widgets[i]->x, gui->skin->widgets[i]->y, | |
237 gui->skin->widgets[i]->length, gui->skin->widgets[i]->font->chars[0]->height,1); */ | |
238 | |
239 /* calculate text size */ | |
240 for (current=0; current<textlen; current++) | |
241 { | |
242 for (c=0; c<item->font->charcount; c++) | |
243 if(item->font->chars[c]->c == text[current]) | |
244 { | |
245 offset += item->font->chars[c]->width; | |
246 break; | |
247 } | |
248 } | |
249 | |
250 /* labels can be scrolled if they are to big */ | |
251 if((item->type == tyDlabel) && (item->length < offset)) | |
252 { | |
253 int tomuch = (offset - item->length) / (offset /textlen); | |
254 scrolltext(text, textlen - tomuch - 1, &skin->widgets[i]->value); | |
255 textlen = strlen(text); | |
256 } | |
257 | |
258 /* align the text */ | |
259 if(item->align == 1) | |
260 offset = (item->length-offset) / 2; | |
261 else if(item->align == 2) | |
262 offset = item->length-offset; | |
263 else | |
264 offset = 0; | |
265 | |
266 if(offset < 0) offset = 0; | |
267 | |
268 /* render the text */ | |
269 for (current=0; current<textlen; current++) | |
270 { | |
271 for (c=0; c<item->font->charcount; c++) | |
272 { | |
273 char_t *cchar = item->font->chars[c]; | |
274 if(cchar->c == *(text + current)) | |
275 { | |
276 render(skin->desktopbpp, | |
277 &priv->img, | |
278 item->font->image, | |
279 item->x + offset, | |
280 item->y, | |
281 cchar->x, | |
282 cchar->y, | |
283 (cchar->width + offset > item->length) ? item->length - offset : cchar->width, | |
284 cchar->height, | |
285 1); | |
286 offset += cchar->width; | |
287 break; | |
288 } | |
289 } | |
290 } | |
291 free(text); | |
292 } | |
293 } | |
294 } | |
295 | |
296 /******************************************************************/ | |
297 /* WIDGET related functions */ | |
298 /******************************************************************/ | |
299 | |
300 void renderwidget(skin_t *skin, image *dest, widget *item, int state) | |
301 { | |
302 image *img = NULL; | |
303 int height; | |
304 int y; | |
305 | |
306 if(!dest) return; | |
307 if((item->type == tyButton) || (item->type == tyHpotmeter) || (item->type == tyPotmeter)) | |
308 img = item->bitmap[0]; | |
309 | |
310 if(!img) return; | |
311 | |
312 y = item->y; | |
313 if(item->type == tyPotmeter) | |
314 { | |
315 height = img->height / item->phases; | |
316 y = height * (int)(item->value * item->phases / 100); | |
317 if(y > img->height-height) | |
318 y = img->height - height; | |
319 } | |
320 else | |
321 { | |
322 height = img->height / 3; | |
323 y = state * height; | |
324 } | |
325 | |
326 /* redraw background */ | |
327 if(item->type == tyButton) | |
328 render(skin->desktopbpp, dest, find_background(skin,item), item->x, item->y, item->x, item->y, img->width, height, 1); | |
329 | |
330 if((item->type == tyHpotmeter) || (item->type == tyPotmeter)) | |
331 { | |
332 /* repaint the area behind the slider */ | |
333 render(skin->desktopbpp, dest, find_background(skin, item), item->wx, item->wy, item->wx, item->wy, item->wwidth, item->height, 1); | |
334 item->x = item->value * (item->wwidth-item->width) / 100 + item->wx; | |
335 if((item->x + item->width) > (item->wx + item->wwidth)) | |
336 item->x = item->wx + item->wwidth - item->width; | |
337 if(item->x < item->wx) | |
338 item->x = item->wx; | |
339 /* workaround for blue */ | |
340 if(item->type == tyHpotmeter) | |
341 height = (item->height < img->height / 3) ? item->height : img->height / 3; | |
342 } | |
343 render(skin->desktopbpp, dest, img, item->x, item->y, 0, y, img->width, height, 1); | |
344 } |