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/>.
26 #include "teletxt/txtfont.h"
27 #include "staticartwork.h"
31 Surface* Surface::screen = NULL;
33 #ifndef GRADIENT_DRAWING
34 osd_font_t* Surface::font = &font_helvB18;
37 Surface::Surface(int id)
39 if (id == SCREEN) screen = this;
46 Surface* Surface::getScreen()
51 void Surface::initpol_tables()
57 if (Video::getInstance()->getFormat() == Video::PAL)
66 float ttcharsizex = 12;
67 float ttcharsizey = 10;
69 for (int py = 0; py < charsizey; py++)
71 float fposy = ttcharsizey / static_cast<float>(charsizey) * static_cast<float>(py);
72 float yweight = fposy - floor(fposy);
73 float yinvweight = 1.0f - yweight;
74 interpol_upline[py] = std::min(static_cast<int>(ceil(fposy)), 9);
75 interpol_lowline[py] = std::max(static_cast<int>(floor(fposy)), 0);
77 for (int px = 0; px < charsizex; px++)
79 float fposx = ttcharsizex / static_cast<float>(charsizex) * static_cast<float>(px);
80 float xweight = fposx - floor(fposx);
81 float xinvweight = 1.0f - xweight;
82 interpol_upbit[px] = (std::min(static_cast<int>(ceil(fposx)), 11));
83 interpol_lowbit[px] = (std::max(static_cast<int>(floor(fposx)), 0));
85 interpol_table_fac1[px][py] = static_cast<unsigned int>(xweight * yweight * 256);
86 interpol_table_fac2[px][py] = static_cast<unsigned int>(xinvweight * yweight * 256);
87 interpol_table_fac3[px][py] = static_cast<unsigned int>(xweight * yinvweight * 256);
88 interpol_table_fac4[px][py] = static_cast<unsigned int>(xinvweight * yinvweight * 256);
93 int Surface::drawText(const char* text, int x, int y, const DrawStyle& c)
95 return drawText(text, x, y, 2000, c);
98 #ifndef GRADIENT_DRAWING
99 int Surface::drawText(const char* text, int x, int y, int width, const DrawStyle& c)
109 ULONG rgba = c.rgba();
112 for (i = 0; i < n; i++)
114 unsigned char ch = text[i];
115 unsigned long* character = &font->content[font->offset[ch]];
116 int w = font->width[ch];
119 for (X = 0; (X < w) && (X + cx < width); X++)
121 for (Y = 0; Y < h; Y++)
123 if ((character[Y] >> (32 - X)) & 0x1)
125 drawPixel(x + X + cx, y + Y, rgba, true);
138 int Surface::drawTextRJ(const char* text, int x, int y, const DrawStyle& c)
145 for (i = 0; i < n; i++)
147 w += font->width[(unsigned char)text[i]];
153 else return drawText(text, x, y, c);
156 int Surface::drawTextCentre(const char* text, int x, int y, const DrawStyle& c)
163 for (i = 0; i < n; i++)
165 w += font->width[(unsigned char)text[i]]; //Characters bigger then 128 can appear
171 else return drawText(text, x, y, c);
174 float Surface::getCharWidth(wchar_t c)
176 return (float)font->width[(unsigned char) c];
179 int Surface::getFontHeight()
181 return font->spacing;
185 //Moved from Teletext view in order to allow device depend optimizations
187 Colour Surface::enumTeletextColorToCoulour(enumTeletextColor ttcol)
192 return Colour(0, 0, 0);
195 return Colour(255, 0, 0);
198 return Colour(0, 255, 0);
201 return Colour(255, 255, 0);
204 return Colour(0, 0, 255);
207 return Colour(255, 0, 255);
210 return Colour(0, 255, 255);
213 return Colour(255, 255, 255);
216 return Colour(0, 0, 0, 0);
219 return Colour(127, 0, 0);
222 return Colour(0, 127, 0);
225 return Colour(127, 127, 0);
228 return Colour(0, 0, 127);
231 return Colour(127, 0, 127);
234 return Colour(0, 127, 127);
237 return Colour(127, 127, 127);
240 return Colour(0, 0, 0);
244 //Next function inspired by osdteletext plugin
245 void Surface::drawTTChar(int ox, int oy, int x, int y, cTeletextChar c)
247 if (!pol_table_inited)
250 pol_table_inited = true;
253 unsigned int buffer[10];
254 unsigned int* charmap = GetFontChar(c, buffer);
256 if (!charmap) //invalid char
258 memset(&buffer, 0, 10 * sizeof(unsigned int));
262 enumTeletextColor ttforegcolour = c.GetFGColor();
263 enumTeletextColor ttbackgcolour = c.GetBGColor();
267 ttforegcolour = ttcTransparent;
268 ttbackgcolour = ttcTransparent;
275 if (Video::getInstance()->getFormat() == Video::PAL)
284 //int ttcharsizex=12;
285 //int ttcharsizey=10;
286 int screenposx = charsizex * x + ox; //12*40= 480 250
287 int screenposy = y * charsizey + oy;
289 // Log::getInstance()->log("Surface", Log::ERR, "TTpos %d %d %d %d %d %d",x,y,ox,oy,screenposx,screenposy);
290 Colour fgcharcl = enumTeletextColorToCoulour(ttforegcolour);
291 Colour bgcharcl = enumTeletextColorToCoulour(ttbackgcolour);
295 for (int py = 0; py < charsizey; py++)
297 int upperbitline = charmap[interpol_upline[py]];
298 int lowerbitline = charmap[interpol_lowline[py]];
300 for (int px = 0; px < charsizex; px++)
302 int upperbit = interpol_upbit[px];
303 int lowerbit = interpol_lowbit[px];
304 Colour uuc = (upperbitline & (0x8000 >> upperbit)) ? fgcharcl : bgcharcl;
305 Colour ulc = (upperbitline & (0x8000 >> lowerbit)) ? fgcharcl : bgcharcl;
306 Colour luc = (lowerbitline & (0x8000 >> upperbit)) ? fgcharcl : bgcharcl;
307 Colour llc = (lowerbitline & (0x8000 >> lowerbit)) ? fgcharcl : bgcharcl;
308 unsigned int fac1, fac2, fac3, fac4;
309 fac1 = interpol_table_fac1[px][py];
310 fac2 = interpol_table_fac2[px][py];
311 fac3 = interpol_table_fac3[px][py];
312 fac4 = interpol_table_fac4[px][py];
314 Colour res((uuc.red * fac1 + ulc.red * fac2 + luc.red * fac3 + llc.red * fac4) / 256,
315 (uuc.green * fac1 + ulc.green * fac2 + luc.green * fac3 + llc.green * fac4) / 256,
316 (uuc.blue * fac1 + ulc.blue * fac2 + luc.blue * fac3 + llc.blue * fac4) / 256,
317 (uuc.alpha * fac1 + ulc.alpha * fac2 + luc.alpha * fac3 + llc.alpha * fac4) / 256); //if this is too slow make a table
318 int newcolour = ( (res.alpha << 24)
322 drawPixel(screenposx + px, screenposy + py, newcolour, true);
329 void Surface::drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,
330 unsigned int width, DrawStyle& nextColour)
334 unsigned int bytesIn, bitsIn;
335 int widthBytes = width / 8;
337 for (y = 0; y < height; y++)
339 for (x = 0; x < width; x++)
341 bytesIn = (y * widthBytes) + (x / 8);
344 if ((base[bytesIn] >> (7 - bitsIn)) & 0x01)
346 drawPixel(dx + x, dy + y, nextColour, true);
354 void Surface::drawPoint(int x, int y, DrawStyle& c, bool fastdraw)
356 drawPixel(x, y, c, fastdraw);