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