]> git.vomp.tv Git - vompclient-marten.git/blob - surface.cc
FFMPEG decoding in color at 7 fps
[vompclient-marten.git] / surface.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 \r
21 #include "surface.h"\r
22 \r
23 #include <math.h>\r
24 #include "osd.h"\r
25 #include "log.h"\r
26 #include "video.h"\r
27 \r
28 #include "teletxt/txtfont.h"\r
29 \r
30 unsigned int interpol_table_fac1[16][22];\r
31 unsigned int interpol_table_fac2[16][22];\r
32 unsigned int interpol_table_fac3[16][22];\r
33 unsigned int interpol_table_fac4[16][22];\r
34 int interpol_lowbit[16];\r
35 int interpol_upbit[16];\r
36 int interpol_lowline[22];\r
37 int interpol_upline[22];\r
38 bool pol_table_inited=false;\r
39 \r
40 void initpol_tables(){\r
41     int charsizex;\r
42     int charsizey;\r
43     charsizex=16;\r
44     if (Video::getInstance()->getFormat() == Video::PAL)\r
45     {\r
46         charsizey=22;\r
47     } else {\r
48         charsizey=18;\r
49     }\r
50     int ttcharsizex=12;\r
51     int ttcharsizey=10;\r
52     for (int py=0;py<charsizey;py++) {\r
53         float fposy=((float)(ttcharsizey))/((float)(charsizey))*((float)py);\r
54         float yweight=fposy-floor(fposy);\r
55         float yinvweight=1.-yweight;\r
56         interpol_upline[py]=min((unsigned int)ceil(fposy),9);\r
57         interpol_lowline[py]=max((unsigned int)floor(fposy),0);\r
58         for (int px=0;px<charsizex;px++) {\r
59             float fposx=((float)(ttcharsizex))/((float)(charsizex))*((float)px);\r
60             float xweight=fposx-floor(fposx);\r
61             float xinvweight=1.-xweight;\r
62             interpol_upbit[px]= (min((unsigned int)ceil(fposx),11));\r
63             interpol_lowbit[px]= (max((unsigned int)floor(fposx),0));\r
64 \r
65             interpol_table_fac1[px][py]=xweight*yweight*256.;\r
66             interpol_table_fac2[px][py]=xinvweight*yweight*256.;\r
67             interpol_table_fac3[px][py]=xweight*yinvweight*256.;\r
68             interpol_table_fac4[px][py]=xinvweight*yinvweight*256.;\r
69 \r
70         }\r
71     }\r
72 }\r
73 \r
74 \r
75 Surface* Surface::screen = NULL;\r
76 osd_font_t* Surface::font = &font_helvB18;\r
77 \r
78 Surface::Surface(int id)\r
79 {\r
80   if (id == SCREEN) screen = this;\r
81 }\r
82 \r
83 Surface::~Surface()\r
84 {\r
85 }\r
86 \r
87 Surface* Surface::getScreen()\r
88 {\r
89   return screen;\r
90 }\r
91 \r
92 int Surface::drawText(const char* text, int x, int y, ULONG rgba)\r
93 {\r
94   return drawText(text, x, y, 2000, rgba);\r
95 }\r
96 \r
97 int Surface::drawText(const char* text, int x, int y, int width, ULONG rgba)\r
98 {\r
99   int h, n, i;\r
100   int Y, X, cx;\r
101 \r
102   n = strlen(text);\r
103   h = font->height;\r
104 \r
105   X = 0;\r
106   cx = 0;\r
107   startFastDraw();\r
108   for (i=0; i<n; i++)\r
109   {\r
110     unsigned char c = text[i];\r
111     unsigned long *character = &font->content[font->offset[c]];\r
112     int w = font->width[c];\r
113     int pixels = 0;\r
114 \r
115     for (X=0; (X<w) && (X + cx < width); X++)\r
116     {\r
117       for (Y=0; Y<h; Y++)\r
118       {\r
119         if ((character[Y] >> (32 - X)) & 0x1)\r
120         {\r
121           drawPixel(x+X+cx, y+Y, rgba,true);\r
122           pixels++;\r
123         }\r
124       }\r
125     }\r
126     cx += w;\r
127   }\r
128   endFastDraw();\r
129   return 1;\r
130 }\r
131 \r
132 int Surface::drawTextRJ(const char* text, int x, int y, ULONG rgba)\r
133 {\r
134   int i, n, w;\r
135   w = 0;\r
136 \r
137   n = strlen(text);\r
138 \r
139   for (i = 0; i < n; i++)\r
140   {\r
141     w += font->width[(unsigned char)text[i]];\r
142   }\r
143 \r
144   x -= w;\r
145 \r
146   if (x < 0) return 0;\r
147   else return drawText(text, x, y, rgba);\r
148 }\r
149 \r
150 int Surface::drawTextCentre(const char* text, int x, int y, ULONG rgba)\r
151 {\r
152   int i, n, w;\r
153   w = 0;\r
154 \r
155   n = strlen(text);\r
156 \r
157   for (i = 0; i < n; i++)\r
158   {\r
159     w += font->width[(unsigned char)text[i]]; //Characters bigger then 128 can appear\r
160   }\r
161 \r
162   x -= w / 2;\r
163 \r
164   if (x < 0) return 0;\r
165   else return drawText(text, x, y, rgba);\r
166 }\r
167 \r
168 int Surface::getCharWidth(char c)\r
169 {\r
170   return font->width[(unsigned char) c];\r
171 }\r
172 \r
173 int Surface::getFontHeight()\r
174 {\r
175   return font->spacing;\r
176 }\r
177 \r
178 //Moved from Teletext view in order to allow device depend optimizations\r
179 \r
180 Colour Surface::enumTeletextColorToCoulour(enumTeletextColor ttcol)\r
181 {\r
182     switch (ttcol) {\r
183         case ttcBlack:\r
184             return Colour(0,0,0);\r
185         case ttcRed:\r
186             return Colour(255,0,0);\r
187         case ttcGreen:\r
188             return Colour(0,255,0);\r
189         case ttcYellow:\r
190             return Colour(255,255,0);\r
191         case ttcBlue:\r
192             return Colour(0,0,255);\r
193         case ttcMagenta:\r
194             return Colour(255,0,255);\r
195         case ttcCyan:\r
196             return Colour(0,255,255);\r
197         case ttcWhite:\r
198             return Colour(255,255,255);\r
199         case ttcTransparent:\r
200             return Colour(0,0,0,0);\r
201         case ttcHalfRed:\r
202             return Colour(127,0,0);\r
203         case ttcHalfGreen:\r
204             return Colour(0,127,0);\r
205         case ttcHalfYellow:\r
206             return Colour(127,127,0);\r
207         case ttcHalfBlue:\r
208             return Colour(0,0,127);\r
209         case ttcHalfMagenta:\r
210             return Colour(127,0,127);\r
211         case ttcHalfCyan:\r
212             return Colour(0,127,127);\r
213         case ttcGrey:\r
214             return Colour(127,127,127);\r
215         default:\r
216             return Colour(0,0,0);\r
217     };\r
218 }\r
219 \r
220 \r
221 \r
222 //Next function inspired by osdteletext plugin\r
223 void Surface::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c)\r
224 {\r
225         if (!pol_table_inited){\r
226                 initpol_tables();\r
227                 pol_table_inited=true;\r
228         }\r
229     unsigned int buffer [10];\r
230     unsigned int * charmap=GetFontChar(c,buffer);\r
231     if (!charmap) { //invalid char\r
232         memset(&buffer,0,10);\r
233         charmap=buffer;\r
234     }\r
235     enumTeletextColor ttforegcolour=c.GetFGColor();\r
236     enumTeletextColor ttbackgcolour=c.GetBGColor();\r
237     if (c.GetBoxedOut()) {\r
238         ttforegcolour=ttcTransparent;\r
239         ttbackgcolour=ttcTransparent;\r
240     }\r
241     int charsizex;\r
242     int charsizey;\r
243     charsizex=16;\r
244 \r
245     if (Video::getInstance()->getFormat() == Video::PAL)\r
246     {\r
247         charsizey=22;\r
248     } else {\r
249         charsizey=18;\r
250     }\r
251     int ttcharsizex=12;\r
252     int ttcharsizey=10;\r
253     int screenposx=charsizex*x+ox; //12*40= 480 250\r
254     int screenposy=y*charsizey+oy;\r
255 \r
256 \r
257    // Log::getInstance()->log("Surface", Log::ERR, "TTpos %d %d %d %d %d %d",x,y,ox,oy,screenposx,screenposy);\r
258     Colour fgcharcl=enumTeletextColorToCoulour(ttforegcolour);\r
259     Colour bgcharcl=enumTeletextColorToCoulour(ttbackgcolour);\r
260 \r
261     startFastDraw();\r
262     for (int py=0;py<charsizey;py++) {\r
263         int upperbitline=charmap[interpol_upline[py]];\r
264         int lowerbitline=charmap[interpol_lowline[py]];\r
265         for (int px=0;px<charsizex;px++) {\r
266             int upperbit= interpol_upbit[px];\r
267             int lowerbit= interpol_lowbit[px];\r
268             Colour uuc=( upperbitline &(0x8000>>upperbit)) ? fgcharcl: bgcharcl;\r
269             Colour ulc=( upperbitline &(0x8000>>lowerbit)) ? fgcharcl: bgcharcl;\r
270             Colour luc=( lowerbitline &(0x8000>>upperbit)) ? fgcharcl: bgcharcl;\r
271             Colour llc=( lowerbitline &(0x8000>>lowerbit)) ? fgcharcl: bgcharcl;\r
272             unsigned int fac1,fac2,fac3,fac4;\r
273             fac1=interpol_table_fac1[px][py];\r
274             fac2=interpol_table_fac2[px][py];\r
275             fac3=interpol_table_fac3[px][py];\r
276             fac4=interpol_table_fac4[px][py];\r
277 \r
278             Colour res((uuc.red*fac1+ulc.red*fac2+luc.red*fac3+llc.red*fac4)/256,\r
279                 (uuc.green*fac1+ulc.green*fac2+luc.green*fac3+llc.green*fac4)/256,\r
280                 (uuc.blue*fac1+ulc.blue*fac2+luc.blue*fac3+llc.blue*fac4)/256,\r
281                 (uuc.alpha*fac1+ulc.alpha*fac2+luc.alpha*fac3+llc.alpha*fac4)/256); //if this is too slow make a table\r
282             int c = (  (res.alpha << 24 )\r
283                         | (res.red    << 16)\r
284                         | (res.green  <<  8)\r
285                         | (res.blue        ) );\r
286             drawPixel(screenposx+px,screenposy+py,c, true);\r
287         }\r
288     }\r
289 \r
290 \r
291     endFastDraw();\r
292 \r
293 \r
294 }\r