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