Support turbo2.
[vuplus_dvbapp] / lib / gui / esubtitle.cpp
1 #include <lib/gui/esubtitle.h>
2 #include <lib/gui/ewidgetdesktop.h>
3 #include <lib/gdi/grc.h>
4 #include <lib/gdi/font.h>
5 #include <lib/base/estring.h>
6 #include <lib/base/nconfig.h>
7
8         /*
9                 ok, here's much room for improvements.
10         
11                 first, the placing of the individual elements is sub-optimal.
12                 then maybe a colored background would be an option.
13                 ....
14         */      
15
16 eSubtitleWidget::eSubtitleStyle eSubtitleWidget::subtitleStyles[Subtitle_MAX];
17
18 eSubtitleWidget::eSubtitleWidget(eWidget *parent)
19         : eWidget(parent), m_hide_subtitles_timer(eTimer::create(eApp))
20 {
21         setBackgroundColor(gRGB(0,0,0,255));
22         m_page_ok = 0;
23         m_dvb_page_ok = 0;
24         m_pango_page_ok = 0;
25         CONNECT(m_hide_subtitles_timer->timeout, eSubtitleWidget::clearPage);
26 }
27
28 #define startX 50
29 #define paddingY 10
30 void eSubtitleWidget::setPage(const eDVBTeletextSubtitlePage &p)
31 {
32         eDVBTeletextSubtitlePage newpage = p;
33         m_page = p;
34         m_page.clear();
35         m_page_ok = 1;
36         invalidate(m_visible_region);  // invalidate old visible regions
37         m_visible_region.rects.clear();
38
39         unsigned int elements = newpage.m_elements.size();
40         if (elements)
41         {
42                 int fontsize = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_fontsize", 34) * getDesktop(0)->size().width()/1280;
43                 int startY = size().height() - (size().height() / 3 * 1) / 2 - ((fontsize + paddingY) * elements) / 2;
44                 int width = size().width() - startX * 2;
45                 int height = size().height() - startY;
46                 int size_per_element = fontsize + paddingY;
47                 bool original_position = ePythonConfigQuery::getConfigBoolValue("config.subtitles.subtitle_original_position");
48                 bool rewrap = ePythonConfigQuery::getConfigBoolValue("config.subtitles.subtitle_rewrap");
49                 gRGB color;
50                 bool original_colors = false;
51                 switch (ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_fontcolor", 0))
52                 {
53                         default:
54                         case 0: /* use original teletext colors */
55                                 color = newpage.m_elements[0].m_color;
56                                 original_colors = true;
57                                 break;
58                         case FONTCOLOR_WHITE:
59                                 color = gRGB(255, 255, 255);
60                                 break;
61                         case FONTCOLOR_YELLOW:
62                                 color = gRGB(255, 255, 0);
63                                 break;
64                         case FONTCOLOR_GREEN:
65                                 color = gRGB(0, 255, 0);
66                                 break;
67                         case FONTCOLOR_CYAN:
68                                 color = gRGB(0, 255, 255);
69                                 break;
70                         case FONTCOLOR_BLUE:
71                                 color = gRGB(0, 0, 255);
72                                 break;
73                         case FONTCOLOR_MAGNETA:
74                                 color = gRGB(255, 0, 255);
75                                 break;
76                         case FONTCOLOR_RED:
77                                 color = gRGB(255, 0, 0);
78                                 break;
79                         case FONTCOLOR_BLACK:
80                                 color = gRGB(0, 0, 0);
81                                 break;
82                 }
83                 color.a = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_opacity");
84
85                 int line = newpage.m_elements[0].m_source_line;
86                 int currentelement = 0;
87                 m_page.m_elements.push_back(eDVBTeletextSubtitlePageElement(color, "", line));
88                 for (int i=0; i<elements; ++i)
89                 {
90                         if (!m_page.m_elements[currentelement].m_text.empty())
91                                 m_page.m_elements[currentelement].m_text += " ";
92                         if (original_colors && color != newpage.m_elements[i].m_color)
93                         {
94                                 color = newpage.m_elements[i].m_color;
95                                 m_page.m_elements[currentelement].m_text += (std::string)color;
96                         }
97                         if (line != newpage.m_elements[i].m_source_line)
98                         {
99                                 line = newpage.m_elements[i].m_source_line;
100                                 if (!rewrap)
101                                 {
102                                         m_page.m_elements.push_back(eDVBTeletextSubtitlePageElement(color, "", line));
103                                         currentelement++;
104                                 }
105                         }
106                         m_page.m_elements[currentelement].m_text += newpage.m_elements[i].m_text;
107                 }
108                 for (int i=0; i<m_page.m_elements.size(); i++)
109                 {
110                         eRect &area = m_page.m_elements[i].m_area;
111                         area.setLeft(startX);
112                         if (!original_position)
113                         {
114                                 int lowerborder = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_position", 50);
115                                 area.setTop(size().height() - size_per_element * (m_page.m_elements.size() - i) - lowerborder * getDesktop(0)->size().height()/720);
116                         }
117                         else
118                                 area.setTop(size_per_element * i + startY);
119                         area.setWidth(width);
120                         area.setHeight(size_per_element);
121                         m_visible_region.rects.push_back(area);
122                 }
123         }
124         m_hide_subtitles_timer->start(7500, true);
125         invalidate(m_visible_region);  // invalidate new regions
126 }
127
128 void eSubtitleWidget::setPage(const eDVBSubtitlePage &p)
129 {
130         eDebug("setPage");
131         m_dvb_page = p;
132         invalidate(m_visible_region);  // invalidate old visible regions
133         m_visible_region.rects.clear();
134         int line = 0;
135         bool original_position = ePythonConfigQuery::getConfigBoolValue("config.subtitles.subtitle_original_position");
136         for (std::list<eDVBSubtitleRegion>::iterator it(m_dvb_page.m_regions.begin()); it != m_dvb_page.m_regions.end(); ++it)
137         {
138                 if (!original_position)
139                 {
140                         int lines = m_dvb_page.m_regions.size();
141                         int lowerborder = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_position", -1);
142                         if (lowerborder >= 0)
143                         {
144                                 it->m_position = ePoint(it->m_position.x(), p.m_display_size.height() - (lines - line) * it->m_pixmap->size().height() - lowerborder);
145                         }
146                         line++;
147                 }
148                 eDebug("add %d %d %d %d", it->m_position.x(), it->m_position.y(), it->m_pixmap->size().width(), it->m_pixmap->size().height());
149                 eDebug("disp width %d, disp height %d", p.m_display_size.width(), p.m_display_size.height());
150                 eRect r = eRect(it->m_position, it->m_pixmap->size());
151                 r.scale(size().width(), p.m_display_size.width(), size().height(), p.m_display_size.height());
152                 m_visible_region.rects.push_back(r);
153         }
154         m_dvb_page_ok = 1;
155         m_hide_subtitles_timer->start(7500, true);
156         invalidate(m_visible_region);  // invalidate new regions
157 }
158
159 void eSubtitleWidget::setPage(const ePangoSubtitlePage &p)
160 {
161         m_pango_page = p;
162         m_pango_page_ok = 1;
163         invalidate(m_visible_region);  // invalidate old visible regions
164         m_visible_region.rects.clear();
165
166         bool rewrap_enabled = ePythonConfigQuery::getConfigBoolValue("config.subtitles.subtitle_rewrap");
167         bool colourise_dialogs_enabled = ePythonConfigQuery::getConfigBoolValue("config.subtitles.colourise_dialogs");
168         bool original_position = ePythonConfigQuery::getConfigBoolValue("config.subtitles.subtitle_original_position");
169
170         int elements = m_pango_page.m_elements.size();
171
172         if(rewrap_enabled | colourise_dialogs_enabled)
173         {
174                 size_t ix, colourise_dialogs_current = 0;
175                 std::vector<std::string> colourise_dialogs_colours;
176                 std::string replacement;
177                 std::string alignmentValue;
178                 ePythonConfigQuery::getConfigValue("config.subtitles.subtitle_alignment", alignmentValue);
179                 bool alignment_center = (alignmentValue == "center");
180
181                 if(colourise_dialogs_enabled)
182                 {
183                         colourise_dialogs_colours.push_back((std::string)gRGB(0xff, 0xff, 0x00));       // yellow
184                         colourise_dialogs_colours.push_back((std::string)gRGB(0x00, 0xff, 0xff));       // cyan
185                         colourise_dialogs_colours.push_back((std::string)gRGB(0xff, 0x00, 0xff));       // magenta
186                         colourise_dialogs_colours.push_back((std::string)gRGB(0x00, 0xff, 0x00));       // green
187                         colourise_dialogs_colours.push_back((std::string)gRGB(0xff, 0xaa, 0xaa));       // light red
188                         colourise_dialogs_colours.push_back((std::string)gRGB(0xaa, 0xaa, 0xff));       // light blue
189                 }
190
191                 for (int i=0; i<elements; ++i)
192                 {
193                         std::string& line = m_pango_page.m_elements[i].m_pango_line;
194
195                         for (ix = 0; ix < line.length(); ix++)
196                         {
197                                 if(rewrap_enabled && !line.compare(ix, 1, "\n"))
198                                         line.replace(ix, 1, " ");
199
200                                 if(colourise_dialogs_enabled && !line.compare(ix, 2, "- "))
201                                 {
202                                         /* workaround for rendering fault when colouring is enabled, rewrap is off and alignment is center */
203                                         replacement = std::string((!rewrap_enabled && alignment_center) ? "  " : "") + colourise_dialogs_colours.at(colourise_dialogs_current);
204
205                                         line.replace(ix, 2, replacement);
206                                         colourise_dialogs_current++;
207
208                                         if(colourise_dialogs_current >= colourise_dialogs_colours.size())
209                                                 colourise_dialogs_current = 0;
210                                 }
211                         }
212                 }
213         }
214
215         if (elements)
216         {
217                 int startY = elements > 1
218                         ? size().height() / 2
219                         : size().height() / 3 * 2;
220                 int width = size().width() - startX * 2;
221                 int height = size().height() - startY;
222                 int size_per_element = height / (elements ? elements : 1);
223                 for (int i=0; i<elements; ++i)
224                 {
225                         eRect &area = m_pango_page.m_elements[i].m_area;
226                         area.setLeft(startX);
227                         if (!original_position)
228                         {
229                                 int lowerborder = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_position", 50);
230                                 if (lowerborder == 0)
231                                         lowerborder -= 100 * getDesktop(0)->size().height()/720;
232                                 else if (lowerborder == 50)
233                                         lowerborder -= 50 * getDesktop(0)->size().height()/720;
234                                 area.setTop(size_per_element * i + startY - lowerborder);
235                         }
236                         else
237                                 area.setTop(size_per_element * i + startY);
238                         area.setWidth(width);
239                         area.setHeight(size_per_element);
240                         m_visible_region.rects.push_back(area);
241                 }
242         }
243         int timeout_ms = m_pango_page.m_timeout;
244         m_hide_subtitles_timer->start(timeout_ms, true);
245         invalidate(m_visible_region);  // invalidate new regions
246 }
247
248 void eSubtitleWidget::clearPage()
249 {
250         eDebug("subtitle timeout... hide");
251         m_page_ok = 0;
252         m_dvb_page_ok = 0;
253         m_pango_page_ok = 0;
254         invalidate(m_visible_region);
255         m_visible_region.rects.clear();
256 }
257
258 void eSubtitleWidget::setPixmap(ePtr<gPixmap> &pixmap, gRegion changed, eRect pixmap_dest)
259 {
260         m_pixmap = pixmap;
261         m_pixmap_dest = pixmap_dest; /* this is in a virtual 720x576 cage */
262         
263                 /* incoming "changed" regions are relative to the physical pixmap area, so they have to be scaled to the virtual pixmap area, then to the screen */
264         changed.scale(m_pixmap_dest.width(), 720, m_pixmap_dest.height(), 576);
265         changed.moveBy(ePoint(m_pixmap_dest.x(), m_pixmap_dest.y()));
266
267         if (pixmap->size().width() && pixmap->size().height())
268                 changed.scale(size().width(), pixmap->size().width(), size().height(), pixmap->size().height());
269         
270         invalidate(changed);
271 }
272
273 int eSubtitleWidget::event(int event, void *data, void *data2)
274 {
275         switch (event)
276         {
277         case evtPaint:
278         {
279                 ePtr<eWindowStyle> style;
280                 gPainter &painter = *(gPainter*)data2;
281
282                 getStyle(style);
283                 eWidget::event(event, data, data2);
284
285                 std::string alignmentValue;
286                 int rt_halignment_flag;
287                 ePythonConfigQuery::getConfigValue("config.subtitles.subtitle_alignment", alignmentValue);
288                 if (alignmentValue == "right")
289                         rt_halignment_flag = gPainter::RT_HALIGN_RIGHT;
290                 else if (alignmentValue == "left")
291                         rt_halignment_flag = gPainter::RT_HALIGN_LEFT;
292                 else
293                         rt_halignment_flag = gPainter::RT_HALIGN_CENTER;
294
295                 int fontsize = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_fontsize", 34) * getDesktop(0)->size().width()/1280;
296                 int edgestyle = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_edgestyle");
297                 int borderwidth = (edgestyle == FONTSTYLE_UNIFORM) ? ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_edgestyle_level") : 0;
298                 gRGB bordercolor = gRGB();
299                 bool original_colors = false;
300
301                 if (m_pixmap)
302                 {
303                         eRect r = m_pixmap_dest;
304                         r.scale(size().width(), 720, size().height(), 576);
305                         painter.blitScale(m_pixmap, r);
306                 } else if (m_page_ok)
307                 {
308                         int elements = m_page.m_elements.size();
309
310                         subtitleStyles[Subtitle_TTX].font->pointSize = fontsize;
311
312                         painter.setFont(subtitleStyles[Subtitle_TTX].font);
313                         for (int i=0; i<elements; ++i)
314                         {
315                                 eDVBTeletextSubtitlePageElement &element = m_page.m_elements[i];
316                                 eRect &area = element.m_area;
317                                 gRGB fontcolor = (!subtitleStyles[Subtitle_TTX].have_foreground_color) ? element.m_color : subtitleStyles[Subtitle_TTX].foreground_color;
318                                 int bg_r, bg_g, bg_b, bg_a;
319                                 if (ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgopacity") < 0xFF)
320                                 {
321                                         eTextPara *para = new eTextPara(area);
322                                         para->setFont(subtitleStyles[Subtitle_TTX].font);
323                                         para->renderString(element.m_text.c_str(), RS_WRAP);
324
325                                         eRect bgbox = para->getBoundBox();
326                                         int bgboxWidth = bgbox.width();
327                                         int bgboxHeight = bgbox.height();
328                                         if (alignmentValue == "left")
329                                                 bgbox.setLeft(area.left() - paddingY - borderwidth);
330                                         else if (alignmentValue == "right")
331                                                 bgbox.setLeft(area.left() + area.width() - bgboxWidth - paddingY - borderwidth);
332                                         else
333                                                 bgbox.setLeft(area.left() + area.width() / 2 - bgboxWidth / 2 - paddingY - borderwidth);
334                                         bgbox.setTop(area.top());
335                                         bgbox.setWidth(bgboxWidth + paddingY * 2 + borderwidth * 2);
336                                         bgbox.setHeight(area.height());
337
338                                         switch (ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgcolor", 0))
339                                         {
340                                                 case BGCOLOR_WHITE:
341                                                         bg_r = 255;
342                                                         bg_g = 255;
343                                                         bg_b = 255;
344                                                         break;
345                                                 case BGCOLOR_YELLOW:
346                                                         bg_r = 255;
347                                                         bg_g = 255;
348                                                         bg_b = 0;
349                                                         break;
350                                                 case BGCOLOR_GREEN:
351                                                         bg_r = 0;
352                                                         bg_g = 255;
353                                                         bg_b = 0;
354                                                         break;
355                                                 case BGCOLOR_CYAN:
356                                                         bg_r = 0;
357                                                         bg_g = 255;
358                                                         bg_b = 255;
359                                                         break;
360                                                 case BGCOLOR_BLUE:
361                                                         bg_r = 0;
362                                                         bg_g = 0;
363                                                         bg_b = 255;
364                                                         break;
365                                                 case BGCOLOR_MAGNETA:
366                                                         bg_r = 255;
367                                                         bg_g = 0;
368                                                         bg_b = 255;
369                                                         break;
370                                                 case BGCOLOR_RED:
371                                                         bg_r = 255;
372                                                         bg_g = 0;
373                                                         bg_b = 0;
374                                                         break;
375                                                 case BGCOLOR_BLACK:
376                                                 default:
377                                                         bg_r = 0;
378                                                         bg_g = 0;
379                                                         bg_b = 0;
380                                                         break;
381                                         }
382                                         bg_a = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgopacity", 0);
383
384                                         painter.setForegroundColor(gRGB(bg_r, bg_g, bg_b, bg_a));
385                                         painter.fill(bgbox);
386                                 }
387
388                                 int offset = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_edgestyle_level", 3);
389                                 switch(edgestyle)
390                                 {
391                                         default:
392                                         case FONTSTYLE_NONE:
393                                                 offset = 0;
394                                                 borderwidth = 0;
395                                                 break;
396                                         case FONTSTYLE_RAISED:
397                                         {
398                                                 eRect shadow = area;
399                                                 ePoint shadow_offset = ePoint(-offset, -offset);
400                                                 shadow.moveBy(shadow_offset);
401                                                 painter.setForegroundColor(subtitleStyles[Subtitle_TTX].shadow_color);
402                                                 painter.renderText(shadow, element.m_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_CENTER|rt_halignment_flag);
403                                         }
404                                                 break;
405                                         case FONTSTYLE_DEPRESSED:
406                                         {
407                                                 eRect shadow = area;
408                                                 ePoint shadow_offset = ePoint(offset, offset);
409                                                 shadow.moveBy(shadow_offset);
410                                                 painter.setForegroundColor(subtitleStyles[Subtitle_TTX].shadow_color);
411                                                 painter.renderText(shadow, element.m_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_CENTER|rt_halignment_flag);
412                                         }
413                                                 break;
414                                         case FONTSTYLE_UNIFORM:
415                                         {
416                                                 if (borderwidth > 0)
417                                                 {
418                                                         if (fontcolor.r == 0 && fontcolor.g == 0 && fontcolor.b == 0)
419                                                         {
420                                                                 gRGB tmp_border_white = gRGB(255,255,255);
421                                                                 bordercolor = tmp_border_white;
422                                                         }
423                                                         else if (bg_r == 0 && bg_g == 0 && bg_b == 0)
424                                                         {
425                                                                 borderwidth = 0;
426                                                         }
427                                                 }
428                                         }
429                                                 break;
430                                 }
431
432                                 if ( !subtitleStyles[Subtitle_TTX].have_foreground_color )
433                                         painter.setForegroundColor(element.m_color);
434                                 else
435                                         painter.setForegroundColor(subtitleStyles[Subtitle_TTX].foreground_color);
436                                 painter.renderText(area, element.m_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_CENTER|rt_halignment_flag, bordercolor, borderwidth);
437                         }
438                 }
439                 else if (m_pango_page_ok)
440                 {
441                         int elements = m_pango_page.m_elements.size();
442                         subfont_t face;
443
444                         for (int i=0; i<elements; ++i)
445                         {
446                                 face = Subtitle_Regular;
447                                 ePangoSubtitlePageElement &element = m_pango_page.m_elements[i];
448                                 std::string text = element.m_pango_line;
449                                 text = replace_all(text, "&apos;", "'");
450                                 text = replace_all(text, "&quot;", "\"");
451                                 text = replace_all(text, "&amp;", "&");
452                                 text = replace_all(text, "&lt;", "<");
453                                 text = replace_all(text, "&gt;", ">");
454
455                                 std::string shadow_text = text;
456                                 if (edgestyle == FONTSTYLE_RAISED || edgestyle == FONTSTYLE_DEPRESSED)
457                                 {
458                                         shadow_text = replace_all(shadow_text, "</u>", "");
459                                         shadow_text = replace_all(shadow_text, "</i>", "");
460                                         shadow_text = replace_all(shadow_text, "</b>", "");
461                                         shadow_text = replace_all(shadow_text, "<u>", "");
462                                         shadow_text = replace_all(shadow_text, "<i>", "");
463                                         shadow_text = replace_all(shadow_text, "<b>", "");
464                                 }
465
466                                 if (ePythonConfigQuery::getConfigBoolValue("config.subtitles.pango_subtitle_fontswitch"))
467                                 {
468                                         if (text.find("<i>") != std::string::npos || text.find("</i>") != std::string::npos)
469                                                 face = Subtitle_Italic;
470                                         else if (text.find("<b>") != std::string::npos || text.find("</b>") != std::string::npos)
471                                                 face = Subtitle_Bold;
472                                 }
473                                 int subtitleColors = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_fontcolor", 1);
474                                 if (!subtitleColors)
475                                         {
476                                                 text = replace_all(text, "<i>", gRGB(255,255,0));
477                                                 text = replace_all(text, "<b>", gRGB(0,255,255));
478                                                 text = replace_all(text, "<u>", (std::string) gRGB(0,255,0));
479                                                 text = replace_all(text, "</i>", (std::string) gRGB(255,255,255));
480                                                 text = replace_all(text, "</b>", (std::string) gRGB(255,255,255));
481                                                 text = replace_all(text, "</u>", (std::string) gRGB(255,255,255));
482                                         }
483                                 else
484                                 {
485                                         text = replace_all(text, "</u>", "");
486                                         text = replace_all(text, "</i>", "");
487                                         text = replace_all(text, "</b>", "");
488                                         text = replace_all(text, "<u>", "");
489                                         text = replace_all(text, "<i>", "");
490                                         text = replace_all(text, "<b>", "");
491                                 }
492
493                                 gRGB fontcolor = (!subtitleStyles[face].have_foreground_color) ? element.m_color : subtitleStyles[face].foreground_color;
494                                 switch (subtitleColors)
495                                 {
496                                         default:
497                                         case 0: /* use original colors */
498                                                 original_colors = true;
499                                                 break;
500                                         case FONTCOLOR_WHITE:
501                                                 fontcolor = gRGB(255, 255, 255);
502                                                 break;
503                                         case FONTCOLOR_YELLOW:
504                                                 fontcolor = gRGB(255, 255, 0);
505                                                 break;
506                                         case FONTCOLOR_GREEN:
507                                                 fontcolor = gRGB(0, 255, 0);
508                                                 break;
509                                         case FONTCOLOR_CYAN:
510                                                 fontcolor = gRGB(0, 255, 255);
511                                                 break;
512                                         case FONTCOLOR_BLUE:
513                                                 fontcolor = gRGB(0, 0, 255);
514                                                 break;
515                                         case FONTCOLOR_MAGNETA:
516                                                 fontcolor = gRGB(255, 0, 255);
517                                                 break;
518                                         case FONTCOLOR_RED:
519                                                 fontcolor = gRGB(255, 0, 0);
520                                                 break;
521                                         case FONTCOLOR_BLACK:
522                                                 fontcolor = gRGB(0, 0, 0);
523                                                 break;
524                                 }
525                                 fontcolor.a = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_opacity");
526                                 if (!original_colors)
527                                         text = (std::string)fontcolor + text;
528
529                                 subtitleStyles[face].font->pointSize = fontsize;
530                                 painter.setFont(subtitleStyles[face].font);
531                                 eRect &area = element.m_area;
532                                 int bg_r, bg_g, bg_b, bg_a;
533                                 if (ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgopacity") < 0xFF)
534                                 {
535                                         unsigned int padding = 10;
536                                         eTextPara *para = new eTextPara(area);
537                                         para->setFont(subtitleStyles[face].font);
538                                         para->renderString(text.c_str(), RS_WRAP);
539
540                                         eRect bgbox = para->getBoundBox();
541                                         int bgboxWidth = bgbox.width();
542                                         int bgboxHeight = bgbox.height();
543                                         if (alignmentValue == "left")
544                                                 bgbox.setLeft(area.left() - padding - borderwidth);
545                                         else if (alignmentValue == "right")
546                                                 bgbox.setLeft(area.left() + area.width() - bgboxWidth - padding - borderwidth);
547                                         else
548                                                 bgbox.setLeft(area.left() + area.width() / 2 - bgboxWidth / 2 - padding - borderwidth);
549                                         bgbox.setTop(area.top() + area.height() / 2 - bgboxHeight / 2 - padding * 2 - borderwidth);
550                                         bgbox.setWidth(bgboxWidth + padding * 2 + borderwidth * 2);
551                                         bgbox.setHeight(bgboxHeight + padding * 3 + borderwidth * 2);
552
553                                         switch (ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgcolor", 0))
554                                         {
555                                                 case BGCOLOR_WHITE:
556                                                         bg_r = 255;
557                                                         bg_g = 255;
558                                                         bg_b = 255;
559                                                         break;
560                                                 case BGCOLOR_YELLOW:
561                                                         bg_r = 255;
562                                                         bg_g = 255;
563                                                         bg_b = 0;
564                                                         break;
565                                                 case BGCOLOR_GREEN:
566                                                         bg_r = 0;
567                                                         bg_g = 255;
568                                                         bg_b = 0;
569                                                         break;
570                                                 case BGCOLOR_CYAN:
571                                                         bg_r = 0;
572                                                         bg_g = 255;
573                                                         bg_b = 255;
574                                                         break;
575                                                 case BGCOLOR_BLUE:
576                                                         bg_r = 0;
577                                                         bg_g = 0;
578                                                         bg_b = 255;
579                                                         break;
580                                                 case BGCOLOR_MAGNETA:
581                                                         bg_r = 255;
582                                                         bg_g = 0;
583                                                         bg_b = 255;
584                                                         break;
585                                                 case BGCOLOR_RED:
586                                                         bg_r = 255;
587                                                         bg_g = 0;
588                                                         bg_b = 0;
589                                                         break;
590                                                 case BGCOLOR_BLACK:
591                                                 default:
592                                                         bg_r = 0;
593                                                         bg_g = 0;
594                                                         bg_b = 0;
595                                                         break;
596                                         }
597                                         bg_a = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgopacity", 0);
598
599                                         painter.setForegroundColor(gRGB(bg_r, bg_g, bg_b, bg_a));
600                                         painter.fill(bgbox);
601                                 }
602
603                                 int offset = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_edgestyle_level", 3);
604                                 switch(edgestyle)
605                                 {
606                                         default:
607                                         case FONTSTYLE_NONE:
608                                                 offset = 0;
609                                                 borderwidth = 0;
610                                                 break;
611                                         case FONTSTYLE_RAISED:
612                                         {
613                                                 eRect shadow = area;
614                                                 ePoint shadow_offset = ePoint(-offset, -offset);
615                                                 shadow.moveBy(shadow_offset);
616                                                 painter.setForegroundColor(subtitleStyles[face].shadow_color);
617                                                 painter.renderText(shadow, shadow_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_CENTER|rt_halignment_flag);
618                                         }
619                                                 break;
620                                         case FONTSTYLE_DEPRESSED:
621                                         {
622                                                 eRect shadow = area;
623                                                 ePoint shadow_offset = ePoint(offset, offset);
624                                                 shadow.moveBy(shadow_offset);
625                                                 painter.setForegroundColor(subtitleStyles[face].shadow_color);
626                                                 painter.renderText(shadow, shadow_text, gPainter::RT_WRAP|gPainter::RT_VALIGN_CENTER|rt_halignment_flag);
627                                         }
628                                                 break;
629                                         case FONTSTYLE_UNIFORM:
630                                         {
631                                                 if (borderwidth > 0)
632                                                 {
633                                                         if (fontcolor.r == 0 && fontcolor.g == 0 && fontcolor.b == 0)
634                                                         {
635                                                                 gRGB tmp_border_white = gRGB(255,255,255);
636                                                                 bordercolor = tmp_border_white;
637                                                         }
638                                                         else if (bg_r == 0 && bg_g == 0 && bg_b == 0)
639                                                         {
640                                                                 borderwidth = 0;
641                                                         }
642                                                 }
643                                         }
644                                                 break;
645                                 }
646
647                                 if ( !subtitleStyles[face].have_foreground_color && element.m_have_color )
648                                         painter.setForegroundColor(element.m_color);
649                                 else
650                                         painter.setForegroundColor(subtitleStyles[face].foreground_color);
651                                 painter.renderText(area, text, gPainter::RT_WRAP|gPainter::RT_VALIGN_CENTER|rt_halignment_flag, bordercolor, borderwidth);
652                         }
653                 }
654                 else if (m_dvb_page_ok)
655                 {
656                         for (std::list<eDVBSubtitleRegion>::iterator it(m_dvb_page.m_regions.begin()); it != m_dvb_page.m_regions.end(); ++it)
657                         {
658                                 eRect r = eRect(it->m_position, it->m_pixmap->size());
659                                 r.scale(size().width(), m_dvb_page.m_display_size.width(), size().height(),  m_dvb_page.m_display_size.height());
660                                 painter.blitScale(it->m_pixmap, r);
661                         }
662                 }
663                 return 0;
664         }
665         default:
666                 return eWidget::event(event, data, data2);
667         }
668 }
669
670 void eSubtitleWidget::setFontStyle(subfont_t face, gFont *font, int haveColor, const gRGB &col, const gRGB &shadowCol, const ePoint &shadowOffset)
671 {
672         subtitleStyles[face].font = font;
673         subtitleStyles[face].have_foreground_color = haveColor;
674         subtitleStyles[face].foreground_color = col;
675         subtitleStyles[face].shadow_color = shadowCol;
676         subtitleStyles[face].shadow_offset = shadowOffset;
677 }
678