@@ -283,43 +283,35 @@ SubtitleRenderer(int display, int layer,
283
283
ft_face_(),
284
284
ft_face_italic_(),
285
285
ft_stroker_(),
286
- line_height_(),
287
- box_offset_(),
288
- box_h_padding_(),
289
- margin_left_(),
290
- margin_bottom_(),
291
- buffer_width_(),
292
- buffer_height_(),
293
286
centered_(centered),
294
287
white_level_(white_level),
295
- box_opacity_(box_opacity)
288
+ box_opacity_(box_opacity),
289
+ font_size_(font_size)
296
290
{
297
291
try {
298
- uint32_t screen_width, screen_height;
299
- ENFORCE (graphics_get_display_size (display, &screen_width, &screen_height) >= 0 );
300
292
301
- initialize_fonts (font_path, italic_font_path, font_size*screen_height);
293
+ ENFORCE (graphics_get_display_size (display, &screen_width_, &screen_height_) >= 0 );
294
+ initialize_fonts (font_path, italic_font_path);
302
295
303
296
int abs_margin_bottom =
304
- static_cast <int >(margin_bottom * screen_height + 0 .5f ) - box_offset_;
305
-
306
- int buffer_padding = (line_height_+2 )/4 ;
307
- int buffer_bottom = clamp (abs_margin_bottom + box_offset_ - buffer_padding,
308
- 0 , (int ) screen_height-1 );
309
- int buffer_top = clamp (buffer_bottom + line_height_ * (int ) lines + buffer_padding*2 ,
310
- 0 , (int ) screen_height-1 );
311
-
312
- buffer_width_ = screen_width;
313
- buffer_height_ = buffer_top - buffer_bottom + 1 ;
314
- margin_left_ = (screen_width - screen_height) / 2 +
315
- static_cast <int >(margin_left * screen_height + 0 .5f );
316
- margin_bottom_ = abs_margin_bottom - buffer_bottom;
317
-
318
- initialize_window (display, layer,
319
- 0 ,
320
- screen_height - buffer_top - 1 ,
321
- screen_width,
322
- buffer_height_);
297
+ static_cast <int >(margin_bottom * screen_height_ + 0 .5f ) - config_.box_offset ;
298
+
299
+ int buffer_padding = (config_.line_height +2 )/4 ;
300
+ int buffer_bottom = clamp (abs_margin_bottom + config_.box_offset - buffer_padding,
301
+ 0 , (int ) screen_height_-1 );
302
+ int buffer_top = clamp (buffer_bottom + config_.line_height * (int ) lines + buffer_padding*2 ,
303
+ 0 , (int ) screen_height_-1 );
304
+
305
+ config_.buffer_x = 0 ;
306
+ config_.buffer_y = screen_height_ - buffer_top - 1 ;
307
+ config_.buffer_width = screen_width_;
308
+ config_.buffer_height = buffer_top - buffer_bottom + 1 ;
309
+ config_.margin_left = (screen_width_ - screen_height_) / 2 +
310
+ static_cast <int >(margin_left * screen_height_ + 0 .5f );
311
+ config_.margin_bottom = abs_margin_bottom - buffer_bottom;
312
+ config_fullscreen_ = config_; // save full-screen config for scaling reference.
313
+
314
+ initialize_window (display, layer);
323
315
324
316
initialize_vg ();
325
317
} catch (...) {
@@ -336,13 +328,13 @@ void SubtitleRenderer::destroy() {
336
328
337
329
void SubtitleRenderer::
338
330
initialize_fonts (const std::string& font_path,
339
- const std::string& italic_font_path,
340
- unsigned int font_size) {
331
+ const std::string& italic_font_path) {
341
332
ENFORCE (!FT_Init_FreeType (&ft_library_));
342
333
ENFORCE2 (!FT_New_Face (ft_library_, font_path.c_str (), 0 , &ft_face_),
343
334
" Unable to open font" );
344
335
ENFORCE2 (!FT_New_Face (ft_library_, italic_font_path.c_str (), 0 , &ft_face_italic_),
345
336
" Unable to open italic font" );
337
+ uint32_t font_size = font_size_*screen_height_;
346
338
ENFORCE (!FT_Set_Pixel_Sizes (ft_face_, 0 , font_size));
347
339
ENFORCE (!FT_Set_Pixel_Sizes (ft_face_italic_, 0 , font_size));
348
340
@@ -361,17 +353,17 @@ initialize_fonts(const std::string& font_path,
361
353
int y_min = get_bbox (' g' ).yMin ;
362
354
int y_max = get_bbox (' M' ).yMax ;
363
355
y_max += -y_min*0 .7f ;
364
- line_height_ = y_max - y_min;
365
- const int v_padding = line_height_ *padding_factor + 0 .5f ;
366
- line_height_ += v_padding*2 ;
367
- box_offset_ = y_min-v_padding;
368
- box_h_padding_ = line_height_ /5 .0f + 0 .5f ;
356
+ config_. line_height = y_max - y_min;
357
+ const int v_padding = config_. line_height *padding_factor + 0 .5f ;
358
+ config_. line_height += v_padding*2 ;
359
+ config_. box_offset = y_min-v_padding;
360
+ config_. box_h_padding = config_. line_height /5 .0f + 0 .5f ;
369
361
370
362
371
363
constexpr float border_thickness = 0 .044f ;
372
364
ENFORCE (!FT_Stroker_New (ft_library_, &ft_stroker_));
373
365
FT_Stroker_Set (ft_stroker_,
374
- line_height_ *border_thickness*64 .0f ,
366
+ config_. line_height *border_thickness*64 .0f ,
375
367
FT_STROKER_LINECAP_ROUND,
376
368
FT_STROKER_LINEJOIN_ROUND,
377
369
0 );
@@ -388,16 +380,12 @@ void SubtitleRenderer::destroy_fonts() {
388
380
}
389
381
}
390
382
391
- void SubtitleRenderer::initialize_window (int display, int layer,
392
- unsigned int x,
393
- unsigned int y,
394
- unsigned int width,
395
- unsigned int height) {
383
+ void SubtitleRenderer::initialize_window (int display, int layer) {
396
384
VC_RECT_T dst_rect;
397
- dst_rect.x = x ;
398
- dst_rect.y = y ;
399
- dst_rect.width = width ;
400
- dst_rect.height = height ;
385
+ dst_rect.x = config_. buffer_x ;
386
+ dst_rect.y = config_. buffer_y ;
387
+ dst_rect.width = config_. buffer_width ;
388
+ dst_rect.height = config_. buffer_height ;
401
389
402
390
VC_RECT_T src_rect;
403
391
src_rect.x = 0 ;
@@ -481,8 +469,8 @@ void SubtitleRenderer::initialize_vg() {
481
469
482
470
static EGL_DISPMANX_WINDOW_T nativewindow;
483
471
nativewindow.element = dispman_element_;
484
- nativewindow.width = buffer_width_ ;
485
- nativewindow.height = buffer_height_ ;
472
+ nativewindow.width = config_. buffer_width ;
473
+ nativewindow.height = config_. buffer_height ;
486
474
487
475
surface_ = eglCreateWindowSurface (display_, config, &nativewindow, NULL );
488
476
ENFORCE (surface_);
@@ -539,18 +527,18 @@ prepare(const std::vector<std::string>& text_lines) BOOST_NOEXCEPT {
539
527
internal_lines_[i] = get_internal_chars (text_lines[i], tag_tracker);
540
528
prepare_glyphs (internal_lines_[i]);
541
529
line_widths_[i] = get_text_width (internal_lines_[i]);
542
- line_positions_[i].second = margin_bottom_ + (n_lines-i-1 )*line_height_ ;
530
+ line_positions_[i].second = config_. margin_bottom + (n_lines-i-1 )*config_. line_height ;
543
531
if (centered_)
544
- line_positions_[i].first = buffer_width_ /2 - line_widths_[i]/2 ;
532
+ line_positions_[i].first = config_. buffer_width /2 - line_widths_[i]/2 ;
545
533
else
546
- line_positions_[i].first = margin_left_ ;
534
+ line_positions_[i].first = config_. margin_left ;
547
535
}
548
536
549
537
prepared_ = true ;
550
538
}
551
539
552
540
void SubtitleRenderer::clear () BOOST_NOEXCEPT {
553
- vgClear (0 , 0 , buffer_width_, buffer_height_ );
541
+ vgClear (0 , 0 , screen_width_, screen_height_ );
554
542
assert (!vgGetError ());
555
543
}
556
544
@@ -559,24 +547,27 @@ void SubtitleRenderer::draw() BOOST_NOEXCEPT {
559
547
560
548
const auto n_lines = internal_lines_.size ();
561
549
550
+ // font graybox
562
551
{
563
552
BoxRenderer box_renderer (box_opacity_);
564
553
for (size_t i = 0 ; i < n_lines; ++i) {
565
- box_renderer.push (line_positions_[i].first - box_h_padding_ ,
566
- line_positions_[i].second + box_offset_ ,
567
- line_widths_[i] + box_h_padding_ *2 ,
568
- line_height_ );
554
+ box_renderer.push (line_positions_[i].first - config_. box_h_padding ,
555
+ line_positions_[i].second + config_. box_offset ,
556
+ line_widths_[i] + config_. box_h_padding *2 ,
557
+ config_. line_height );
569
558
}
570
559
box_renderer.render ();
571
560
}
572
561
562
+ // font background
573
563
for (size_t i = 0 ; i < n_lines; ++i) {
574
564
draw_text (vg_font_border_,
575
565
internal_lines_[i],
576
566
line_positions_[i].first , line_positions_[i].second ,
577
567
0 );
578
568
}
579
569
570
+ // font foreground
580
571
for (size_t i = 0 ; i < n_lines; ++i) {
581
572
draw_text (vg_font_,
582
573
internal_lines_[i],
@@ -591,3 +582,40 @@ void SubtitleRenderer::swap_buffers() BOOST_NOEXCEPT {
591
582
EGLBoolean result = eglSwapBuffers (display_, surface_);
592
583
assert (result);
593
584
}
585
+
586
+ void SubtitleRenderer::set_rect (int x1, int y1, int x2, int y2) BOOST_NOEXCEPT
587
+ {
588
+ uint32_t width = x2-x1;
589
+ uint32_t height = y2-y1 ;
590
+ float height_mod = (float ) height / screen_height_;
591
+ float width_mod = (float ) width / screen_width_;
592
+ config_.buffer_x = x1;
593
+ config_.buffer_y = y2 - (screen_height_ - config_fullscreen_.buffer_y ) * height_mod + 0 .5f ;
594
+ config_.buffer_width = width;
595
+ config_.buffer_height = config_fullscreen_.buffer_height * height_mod + 0 .5f ;
596
+ config_.line_height = config_fullscreen_.line_height * height_mod + 0 .5f ;
597
+ config_.box_offset = config_fullscreen_.box_offset * height_mod + 0 .5f ;
598
+ config_.box_h_padding = config_fullscreen_.box_h_padding * height_mod + 0 .5f ;
599
+ config_.margin_left = config_fullscreen_.margin_left * width_mod + 0 .5f ;
600
+ config_.margin_bottom = config_fullscreen_.margin_bottom * height_mod + 0 .5f ;
601
+
602
+ // resize dispmanx element
603
+ ENFORCE (dispman_element_);
604
+ VC_RECT_T dst_rect;
605
+ vc_dispmanx_rect_set (&dst_rect, config_.buffer_x , config_.buffer_y , config_.buffer_width , config_.buffer_height );
606
+ VC_RECT_T src_rect;
607
+ vc_dispmanx_rect_set (&src_rect, x1, y1 , config_.buffer_width <<16 , config_.buffer_height <<16 );
608
+ DISPMANX_UPDATE_HANDLE_T dispman_update;
609
+ dispman_update = vc_dispmanx_update_start (0 );
610
+ ENFORCE (dispman_update);
611
+ uint32_t change_flag = 1 <<2 | 1 <<3 ; // change only dst_rect and src_rect
612
+ ENFORCE (!vc_dispmanx_element_change_attributes (dispman_update, dispman_element_, change_flag, 0 , 0 ,
613
+ &dst_rect, &src_rect, 0 , (DISPMANX_TRANSFORM_T) 0 ));
614
+ ENFORCE (!vc_dispmanx_update_submit_sync (dispman_update));
615
+
616
+ // resize font
617
+ glyphs_.clear (); // clear cached glyphs
618
+ float font_size = height*font_size_;
619
+ ENFORCE (!FT_Set_Pixel_Sizes (ft_face_, 0 , font_size));
620
+ ENFORCE (!FT_Set_Pixel_Sizes (ft_face_italic_, 0 , font_size));
621
+ }
0 commit comments