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