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