@@ -88,13 +88,13 @@ class BoxRenderer {
88
88
}
89
89
};
90
90
91
- void SubtitleRenderer::load_glyph (char32_t codepoint ) {
91
+ void SubtitleRenderer::load_glyph (InternalChar ch ) {
92
92
VGfloat escapement[2 ]{};
93
93
94
94
auto load_glyph_internal =
95
95
[&](FT_Face ft_face, VGFont vg_font, bool border) {
96
96
try {
97
- auto glyph_index = FT_Get_Char_Index (ft_face, codepoint);
97
+ auto glyph_index = FT_Get_Char_Index (ft_face, ch. codepoint () );
98
98
ENFORCE (!FT_Load_Glyph (ft_face, glyph_index, FT_LOAD_NO_HINTING));
99
99
100
100
FT_Glyph glyph;
@@ -165,7 +165,7 @@ void SubtitleRenderer::load_glyph(char32_t codepoint) {
165
165
escapement[0 ] = static_cast <VGfloat>((ft_face->glyph ->advance .x + 32 ) / 64 );
166
166
escapement[1 ] = 0 ;
167
167
168
- vgSetGlyphToImage (vg_font, codepoint , image, glyph_origin, escapement);
168
+ vgSetGlyphToImage (vg_font, ch. val , image, glyph_origin, escapement);
169
169
assert (!vgGetError ());
170
170
171
171
if (image) {
@@ -175,34 +175,40 @@ void SubtitleRenderer::load_glyph(char32_t codepoint) {
175
175
} catch (...) {
176
176
escapement[0 ] = 0 ;
177
177
escapement[1 ] = 0 ;
178
- vgSetGlyphToImage (vg_font, codepoint , VG_INVALID_HANDLE, escapement, escapement);
178
+ vgSetGlyphToImage (vg_font, ch. val , VG_INVALID_HANDLE, escapement, escapement);
179
179
assert (!vgGetError ());
180
180
}
181
181
};
182
182
183
- load_glyph_internal (ft_face_, vg_font_, false );
184
- glyphs_[codepoint].advance = escapement[0 ];
185
- load_glyph_internal (ft_face_, vg_font_border_, true );
183
+ if (!ch.italic ()) {
184
+ load_glyph_internal (ft_face_, vg_font_, false );
185
+ glyphs_[ch].advance = escapement[0 ];
186
+ load_glyph_internal (ft_face_, vg_font_border_, true );
187
+ } else {
188
+ load_glyph_internal (ft_face_italic_, vg_font_, false );
189
+ glyphs_[ch].advance = escapement[0 ];
190
+ load_glyph_internal (ft_face_italic_, vg_font_border_, true );
191
+ }
186
192
}
187
193
188
194
int SubtitleRenderer::get_text_width (const std::vector<InternalChar>& text) {
189
195
int width = 0 ;
190
196
for (auto c = text.begin (); c != text.end (); ++c) {
191
- width += c->italic ? (assert (0 ), 0 )
192
- : glyphs_.at (c->codepoint ).advance ;
197
+ width += glyphs_.at (*c).advance ;
193
198
}
194
199
return width;
195
200
}
196
201
197
202
std::vector<SubtitleRenderer::InternalChar> SubtitleRenderer::
198
- get_internal_chars (const std::string& str) {
203
+ get_internal_chars (const std::string& str, TagTracker& tag_tracker ) {
199
204
std::vector<InternalChar> internal_chars;
200
- bool italic {};
201
205
auto c_str = str.c_str ();
202
206
for (size_t i = 0 , len = str.length (); i < len;) {
203
207
try {
204
208
auto cp = decodeUtf8 (c_str, len, i);
205
- internal_chars.push_back (InternalChar ({cp, italic }));
209
+ tag_tracker.put (cp);
210
+ if (!tag_tracker.in_tag ())
211
+ internal_chars.push_back (InternalChar (cp, tag_tracker.italic ()));
206
212
} catch (...) {
207
213
++i; // Keep going
208
214
}
@@ -213,14 +219,13 @@ get_internal_chars(const std::string& str) {
213
219
void SubtitleRenderer::
214
220
prepare_glyphs (const std::vector<InternalChar>& text) {
215
221
for (auto c = text.begin (); c != text.end (); ++c) {
216
- if (glyphs_.find (c->codepoint ) == glyphs_.end ()) {
217
- load_glyph (c->codepoint );
218
- }
222
+ if (glyphs_.find (*c) == glyphs_.end ())
223
+ load_glyph (*c);
219
224
}
220
225
}
221
226
222
227
void SubtitleRenderer::
223
- draw_text (VGFont font, VGFont italic_font,
228
+ draw_text (VGFont font,
224
229
const std::vector<SubtitleRenderer::InternalChar>& text,
225
230
int x, int y,
226
231
unsigned int lightness) {
@@ -245,10 +250,7 @@ draw_text(VGFont font, VGFont italic_font,
245
250
assert (!vgGetError ());
246
251
247
252
for (auto c = text.begin (); c != text.end (); ++c) {
248
- vgDrawGlyph (c->italic ? italic_font : font,
249
- c->codepoint ,
250
- VG_FILL_PATH,
251
- VG_FALSE);
253
+ vgDrawGlyph (font, c->val , VG_FILL_PATH, VG_FALSE);
252
254
assert (!vgGetError ());
253
255
}
254
256
}
@@ -261,6 +263,7 @@ SubtitleRenderer::~SubtitleRenderer() BOOST_NOEXCEPT {
261
263
SubtitleRenderer::
262
264
SubtitleRenderer (int layer,
263
265
const std::string& font_path,
266
+ const std::string& italic_font_path,
264
267
float font_size,
265
268
float margin_left,
266
269
float margin_bottom,
@@ -276,10 +279,9 @@ SubtitleRenderer(int layer,
276
279
surface_(),
277
280
vg_font_(),
278
281
vg_font_border_(),
279
- vg_font_italic_(),
280
- vg_font_italic_border_(),
281
282
ft_library_(),
282
283
ft_face_(),
284
+ ft_face_italic_(),
283
285
ft_stroker_(),
284
286
line_height_(),
285
287
box_offset_(),
@@ -296,7 +298,7 @@ SubtitleRenderer(int layer,
296
298
uint32_t screen_width, screen_height;
297
299
ENFORCE (graphics_get_display_size (0 , &screen_width, &screen_height) >= 0 );
298
300
299
- initialize_fonts (font_path, font_size*screen_height);
301
+ initialize_fonts (font_path, italic_font_path, font_size*screen_height);
300
302
301
303
int abs_margin_bottom =
302
304
static_cast <int >(margin_bottom * screen_height + 0 .5f ) - box_offset_;
@@ -333,11 +335,16 @@ void SubtitleRenderer::destroy() {
333
335
}
334
336
335
337
void SubtitleRenderer::
336
- initialize_fonts (const std::string& font_path, unsigned int font_size) {
338
+ initialize_fonts (const std::string& font_path,
339
+ const std::string& italic_font_path,
340
+ unsigned int font_size) {
337
341
ENFORCE (!FT_Init_FreeType (&ft_library_));
338
342
ENFORCE2 (!FT_New_Face (ft_library_, font_path.c_str (), 0 , &ft_face_),
339
343
" Unable to open font" );
344
+ ENFORCE2 (!FT_New_Face (ft_library_, italic_font_path.c_str (), 0 , &ft_face_italic_),
345
+ " Unable to open italic font" );
340
346
ENFORCE (!FT_Set_Pixel_Sizes (ft_face_, 0 , font_size));
347
+ ENFORCE (!FT_Set_Pixel_Sizes (ft_face_italic_, 0 , font_size));
341
348
342
349
auto get_bbox = [this ](char32_t cp) {
343
350
auto glyph_index = FT_Get_Char_Index (ft_face_, cp);
@@ -376,6 +383,7 @@ void SubtitleRenderer::destroy_fonts() {
376
383
assert (!error);
377
384
ft_library_ = {};
378
385
ft_face_ = {};
386
+ ft_face_italic_ = {};
379
387
ft_stroker_ = {};
380
388
}
381
389
}
@@ -522,12 +530,13 @@ void SubtitleRenderer::destroy_vg() {
522
530
void SubtitleRenderer::
523
531
prepare (const std::vector<std::string>& text_lines) BOOST_NOEXCEPT {
524
532
const int n_lines = text_lines.size ();
533
+ TagTracker tag_tracker;
525
534
526
535
internal_lines_.resize (n_lines);
527
536
line_widths_.resize (n_lines);
528
537
line_positions_.resize (n_lines);
529
538
for (int i = 0 ; i < n_lines; ++i) {
530
- internal_lines_[i] = get_internal_chars (text_lines[i]);
539
+ internal_lines_[i] = get_internal_chars (text_lines[i], tag_tracker );
531
540
prepare_glyphs (internal_lines_[i]);
532
541
line_widths_[i] = get_text_width (internal_lines_[i]);
533
542
line_positions_[i].second = margin_bottom_ + (n_lines-i-1 )*line_height_;
@@ -562,14 +571,14 @@ void SubtitleRenderer::draw() BOOST_NOEXCEPT {
562
571
}
563
572
564
573
for (size_t i = 0 ; i < n_lines; ++i) {
565
- draw_text (vg_font_border_, vg_font_italic_border_,
574
+ draw_text (vg_font_border_,
566
575
internal_lines_[i],
567
576
line_positions_[i].first , line_positions_[i].second ,
568
577
0 );
569
578
}
570
579
571
580
for (size_t i = 0 ; i < n_lines; ++i) {
572
- draw_text (vg_font_, vg_font_italic_,
581
+ draw_text (vg_font_,
573
582
internal_lines_[i],
574
583
line_positions_[i].first , line_positions_[i].second ,
575
584
white_level_);
0 commit comments