]> git.vomp.tv Git - vompclient.git/blob - surface.cc
Formatting
[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
58   if (Video::getInstance()->getFormat() == Video::PAL)
59   {
60     charsizey = 22;
61   }
62   else
63   {
64     charsizey = 18;
65   }
66
67   int ttcharsizex = 12;
68   int ttcharsizey = 10;
69
70   for (int py = 0; py < charsizey; py++)
71   {
72     float fposy = ((float)(ttcharsizey)) / ((float)(charsizey)) * ((float)py);
73     float yweight = fposy - floor(fposy);
74     float yinvweight = 1. - yweight;
75     interpol_upline[py] = std::min((int)(ceil(fposy)), 9);
76     interpol_lowline[py] = std::max((int)(floor(fposy)), 0);
77
78     for (int px = 0; px < charsizex; px++)
79     {
80       float fposx = ((float)(ttcharsizex)) / ((float)(charsizex)) * ((float)px);
81       float xweight = fposx - floor(fposx);
82       float xinvweight = 1. - xweight;
83       interpol_upbit[px] = (std::min((int)ceil(fposx), 11));
84       interpol_lowbit[px] = (std::max((int)floor(fposx), 0));
85
86       interpol_table_fac1[px][py] = (unsigned int)(xweight * yweight * 256.);
87       interpol_table_fac2[px][py] = (unsigned int)(xinvweight * yweight * 256.);
88       interpol_table_fac3[px][py] = (unsigned int)(xweight * yinvweight * 256.);
89       interpol_table_fac4[px][py] = (unsigned int)(xinvweight * yinvweight * 256.);
90     }
91   }
92 }
93
94 int Surface::drawText(const char* text, int x, int y, const DrawStyle& c)
95 {
96   return drawText(text, x, y, 2000, c);
97 }
98 #ifndef GRADIENT_DRAWING
99 int Surface::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
100 {
101   int h, n, i;
102   int Y, X, cx;
103
104   n = strlen(text);
105   h = font->height;
106
107   X = 0;
108   cx = 0;
109   ULONG rgba = c.rgba();
110   startFastDraw();
111
112   for (i = 0; i < n; i++)
113   {
114     unsigned char ch = text[i];
115     unsigned long* character = &font->content[font->offset[ch]];
116     int w = font->width[ch];
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
131     cx += w;
132   }
133
134   endFastDraw();
135   return 1;
136 }
137
138 int Surface::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
139 {
140   int i, n, w;
141   w = 0;
142
143   n = strlen(text);
144
145   for (i = 0; i < n; i++)
146   {
147     w += font->width[(unsigned char)text[i]];
148   }
149
150   x -= w;
151
152   if (x < 0) return 0;
153   else return drawText(text, x, y, c);
154 }
155
156 int Surface::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
157 {
158   int i, n, w;
159   w = 0;
160
161   n = strlen(text);
162
163   for (i = 0; i < n; i++)
164   {
165     w += font->width[(unsigned char)text[i]]; //Characters bigger then 128 can appear
166   }
167
168   x -= w / 2;
169
170   if (x < 0) return 0;
171   else return drawText(text, x, y, c);
172 }
173
174 float Surface::getCharWidth(wchar_t c)
175 {
176   return (float)font->width[(unsigned char) c];
177 }
178
179 int Surface::getFontHeight()
180 {
181   return font->spacing;
182 }
183 #endif
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   {
191     case ttcBlack:
192       return Colour(0, 0, 0);
193
194     case ttcRed:
195       return Colour(255, 0, 0);
196
197     case ttcGreen:
198       return Colour(0, 255, 0);
199
200     case ttcYellow:
201       return Colour(255, 255, 0);
202
203     case ttcBlue:
204       return Colour(0, 0, 255);
205
206     case ttcMagenta:
207       return Colour(255, 0, 255);
208
209     case ttcCyan:
210       return Colour(0, 255, 255);
211
212     case ttcWhite:
213       return Colour(255, 255, 255);
214
215     case ttcTransparent:
216       return Colour(0, 0, 0, 0);
217
218     case ttcHalfRed:
219       return Colour(127, 0, 0);
220
221     case ttcHalfGreen:
222       return Colour(0, 127, 0);
223
224     case ttcHalfYellow:
225       return Colour(127, 127, 0);
226
227     case ttcHalfBlue:
228       return Colour(0, 0, 127);
229
230     case ttcHalfMagenta:
231       return Colour(127, 0, 127);
232
233     case ttcHalfCyan:
234       return Colour(0, 127, 127);
235
236     case ttcGrey:
237       return Colour(127, 127, 127);
238
239     default:
240       return Colour(0, 0, 0);
241   };
242 }
243
244
245
246 //Next function inspired by osdteletext plugin
247 void Surface::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c)
248 {
249   if (!pol_table_inited)
250   {
251     initpol_tables();
252     pol_table_inited = true;
253   }
254
255   unsigned int buffer [10];
256   unsigned int* charmap = GetFontChar(c, buffer);
257
258   if (!charmap)   //invalid char
259   {
260     memset(&buffer, 0, 10);
261     charmap = buffer;
262   }
263
264   enumTeletextColor ttforegcolour = c.GetFGColor();
265   enumTeletextColor ttbackgcolour = c.GetBGColor();
266
267   if (c.GetBoxedOut())
268   {
269     ttforegcolour = ttcTransparent;
270     ttbackgcolour = ttcTransparent;
271   }
272
273   int charsizex;
274   int charsizey;
275   charsizex = 16;
276
277   if (Video::getInstance()->getFormat() == Video::PAL)
278   {
279     charsizey = 22;
280   }
281   else
282   {
283     charsizey = 18;
284   }
285
286   //int ttcharsizex=12;
287   //int ttcharsizey=10;
288   int screenposx = charsizex * x + ox; //12*40= 480 250
289   int screenposy = y * charsizey + oy;
290
291
292   // Log::getInstance()->log("Surface", Log::ERR, "TTpos %d %d %d %d %d %d",x,y,ox,oy,screenposx,screenposy);
293   Colour fgcharcl = enumTeletextColorToCoulour(ttforegcolour);
294   Colour bgcharcl = enumTeletextColorToCoulour(ttbackgcolour);
295
296   startFastDraw();
297
298   for (int py = 0; py < charsizey; py++)
299   {
300     int upperbitline = charmap[interpol_upline[py]];
301     int lowerbitline = charmap[interpol_lowline[py]];
302
303     for (int px = 0; px < charsizex; px++)
304     {
305       int upperbit = interpol_upbit[px];
306       int lowerbit = interpol_lowbit[px];
307       Colour uuc = ( upperbitline & (0x8000 >> upperbit)) ? fgcharcl : bgcharcl;
308       Colour ulc = ( upperbitline & (0x8000 >> lowerbit)) ? fgcharcl : bgcharcl;
309       Colour luc = ( lowerbitline & (0x8000 >> upperbit)) ? fgcharcl : bgcharcl;
310       Colour llc = ( lowerbitline & (0x8000 >> lowerbit)) ? fgcharcl : bgcharcl;
311       unsigned int fac1, fac2, fac3, fac4;
312       fac1 = interpol_table_fac1[px][py];
313       fac2 = interpol_table_fac2[px][py];
314       fac3 = interpol_table_fac3[px][py];
315       fac4 = interpol_table_fac4[px][py];
316
317       Colour res((uuc.red * fac1 + ulc.red * fac2 + luc.red * fac3 + llc.red * fac4) / 256,
318                  (uuc.green * fac1 + ulc.green * fac2 + luc.green * fac3 + llc.green * fac4) / 256,
319                  (uuc.blue * fac1 + ulc.blue * fac2 + luc.blue * fac3 + llc.blue * fac4) / 256,
320                  (uuc.alpha * fac1 + ulc.alpha * fac2 + luc.alpha * fac3 + llc.alpha * fac4) / 256); //if this is too slow make a table
321       int newcolour = (  (res.alpha  << 24)
322                          | (res.red    << 16)
323                          | (res.green  <<  8)
324                          | (res.blue        ) );
325       drawPixel(screenposx + px, screenposy + py, newcolour, true);
326     }
327   }
328
329
330   endFastDraw();
331
332
333 }
334
335 void Surface::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,
336                              unsigned int width, DrawStyle& nextColour)
337 {
338   startFastDraw();
339   unsigned int x, y;
340   unsigned int bytesIn, bitsIn;
341   int widthBytes = width / 8;
342
343   for (y = 0; y < height; y++)
344   {
345     for (x = 0; x < width; x++)
346     {
347       bytesIn = (y * widthBytes) + (int) (x / 8);
348       bitsIn = x % 8;
349
350       if ((base[bytesIn] >> (7 - bitsIn)) & 0x01)
351       {
352         drawPixel(dx + x, dy + y, nextColour, true);
353       }
354     }
355   }
356
357   endFastDraw();
358 }
359
360 void Surface::drawPoint(int x, int y, DrawStyle& c, bool fastdraw)
361 {
362   drawPixel(x, y, c, fastdraw);
363 }