2 Copyright 2004-2020 Chris Tallon
4 This file is part of VOMP.
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.
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.
16 You should have received a copy of the GNU General Public License
17 along with VOMP. If not, see <https://www.gnu.org/licenses/>.
25 #include "teletxt/txtfont.h"
26 #include "staticartwork.h"
30 Surface* Surface::screen = NULL;
32 #ifndef GRADIENT_DRAWING
33 osd_font_t* Surface::font = &font_helvB18;
36 Surface::Surface(int id)
38 if (id == SCREEN) screen = this;
45 Surface* Surface::getScreen()
50 void Surface::initpol_tables()
56 if (Video::getInstance()->getFormat() == Video::PAL)
65 float ttcharsizex = 12;
66 float ttcharsizey = 10;
68 for (int py = 0; py < charsizey; py++)
70 float fposy = ttcharsizey / static_cast<float>(charsizey) * static_cast<float>(py);
71 float yweight = fposy - floor(fposy);
72 float yinvweight = 1.0f - yweight;
73 interpol_upline[py] = std::min(static_cast<int>(ceil(fposy)), 9);
74 interpol_lowline[py] = std::max(static_cast<int>(floor(fposy)), 0);
76 for (int px = 0; px < charsizex; px++)
78 float fposx = ttcharsizex / static_cast<float>(charsizex) * static_cast<float>(px);
79 float xweight = fposx - floor(fposx);
80 float xinvweight = 1.0f - xweight;
81 interpol_upbit[px] = (std::min(static_cast<int>(ceil(fposx)), 11));
82 interpol_lowbit[px] = (std::max(static_cast<int>(floor(fposx)), 0));
84 interpol_table_fac1[px][py] = static_cast<unsigned int>(xweight * yweight * 256);
85 interpol_table_fac2[px][py] = static_cast<unsigned int>(xinvweight * yweight * 256);
86 interpol_table_fac3[px][py] = static_cast<unsigned int>(xweight * yinvweight * 256);
87 interpol_table_fac4[px][py] = static_cast<unsigned int>(xinvweight * yinvweight * 256);
92 int Surface::drawText(const char* text, int x, int y, const DrawStyle& c)
94 return drawText(text, x, y, 2000, c);
97 #ifndef GRADIENT_DRAWING
98 int Surface::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
108 ULONG rgba = c.rgba();
111 for (i = 0; i < n; i++)
113 unsigned char ch = text[i];
114 unsigned long* character = &font->content[font->offset[ch]];
115 int w = font->width[ch];
118 for (X = 0; (X < w) && (X + cx < width); X++)
120 for (Y = 0; Y < h; Y++)
122 if ((character[Y] >> (32 - X)) & 0x1)
124 drawPixel(x + X + cx, y + Y, rgba, true);
137 int Surface::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
144 for (i = 0; i < n; i++)
146 w += font->width[(unsigned char)text[i]];
152 else return drawText(text, x, y, c);
155 int Surface::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
162 for (i = 0; i < n; i++)
164 w += font->width[(unsigned char)text[i]]; //Characters bigger then 128 can appear
170 else return drawText(text, x, y, c);
173 float Surface::getCharWidth(wchar_t c)
175 return (float)font->width[(unsigned char) c];
178 int Surface::getFontHeight()
180 return font->spacing;
184 //Moved from Teletext view in order to allow device depend optimizations
186 Colour Surface::enumTeletextColorToCoulour(enumTeletextColor ttcol)
191 return Colour(0, 0, 0);
194 return Colour(255, 0, 0);
197 return Colour(0, 255, 0);
200 return Colour(255, 255, 0);
203 return Colour(0, 0, 255);
206 return Colour(255, 0, 255);
209 return Colour(0, 255, 255);
212 return Colour(255, 255, 255);
215 return Colour(0, 0, 0, 0);
218 return Colour(127, 0, 0);
221 return Colour(0, 127, 0);
224 return Colour(127, 127, 0);
227 return Colour(0, 0, 127);
230 return Colour(127, 0, 127);
233 return Colour(0, 127, 127);
236 return Colour(127, 127, 127);
239 return Colour(0, 0, 0);
243 //Next function inspired by osdteletext plugin
244 void Surface::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c)
246 if (!pol_table_inited)
249 pol_table_inited = true;
252 unsigned int buffer[10];
253 unsigned int* charmap = GetFontChar(c, buffer);
255 if (!charmap) //invalid char
257 memset(&buffer, 0, 10 * sizeof(unsigned int));
261 enumTeletextColor ttforegcolour = c.GetFGColor();
262 enumTeletextColor ttbackgcolour = c.GetBGColor();
266 ttforegcolour = ttcTransparent;
267 ttbackgcolour = ttcTransparent;
274 if (Video::getInstance()->getFormat() == Video::PAL)
283 //int ttcharsizex=12;
284 //int ttcharsizey=10;
285 int screenposx = charsizex * x + ox; //12*40= 480 250
286 int screenposy = y * charsizey + oy;
288 // Log::getInstance()->log("Surface", Log::ERR, "TTpos %d %d %d %d %d %d",x,y,ox,oy,screenposx,screenposy);
289 Colour fgcharcl = enumTeletextColorToCoulour(ttforegcolour);
290 Colour bgcharcl = enumTeletextColorToCoulour(ttbackgcolour);
294 for (int py = 0; py < charsizey; py++)
296 int upperbitline = charmap[interpol_upline[py]];
297 int lowerbitline = charmap[interpol_lowline[py]];
299 for (int px = 0; px < charsizex; px++)
301 int upperbit = interpol_upbit[px];
302 int lowerbit = interpol_lowbit[px];
303 Colour uuc = (upperbitline & (0x8000 >> upperbit)) ? fgcharcl : bgcharcl;
304 Colour ulc = (upperbitline & (0x8000 >> lowerbit)) ? fgcharcl : bgcharcl;
305 Colour luc = (lowerbitline & (0x8000 >> upperbit)) ? fgcharcl : bgcharcl;
306 Colour llc = (lowerbitline & (0x8000 >> lowerbit)) ? fgcharcl : bgcharcl;
307 unsigned int fac1, fac2, fac3, fac4;
308 fac1 = interpol_table_fac1[px][py];
309 fac2 = interpol_table_fac2[px][py];
310 fac3 = interpol_table_fac3[px][py];
311 fac4 = interpol_table_fac4[px][py];
313 Colour res((uuc.red * fac1 + ulc.red * fac2 + luc.red * fac3 + llc.red * fac4) / 256,
314 (uuc.green * fac1 + ulc.green * fac2 + luc.green * fac3 + llc.green * fac4) / 256,
315 (uuc.blue * fac1 + ulc.blue * fac2 + luc.blue * fac3 + llc.blue * fac4) / 256,
316 (uuc.alpha * fac1 + ulc.alpha * fac2 + luc.alpha * fac3 + llc.alpha * fac4) / 256); //if this is too slow make a table
317 int newcolour = ( (res.alpha << 24)
321 drawPixel(screenposx + px, screenposy + py, newcolour, true);
328 void Surface::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,
329 unsigned int width, const DrawStyle& nextColour)
333 unsigned int bytesIn, bitsIn;
334 int widthBytes = width / 8;
336 for (y = 0; y < height; y++)
338 for (x = 0; x < width; x++)
340 bytesIn = (y * widthBytes) + (x / 8);
343 if ((base[bytesIn] >> (7 - bitsIn)) & 0x01)
345 drawPixel(dx + x, dy + y, nextColour, true);
353 void Surface::drawPoint(int x, int y, const DrawStyle& c, bool fastdraw)
355 drawPixel(x, y, c, fastdraw);