@@ -169,12 +169,8 @@ FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1,
169
169
m_dirty = true ;
170
170
}
171
171
172
- static FT_UInt ft_get_char_index_or_warn (FT_Face face, FT_ULong charcode)
172
+ static FT_UInt ft_glyph_warn ( FT_ULong charcode)
173
173
{
174
- FT_UInt glyph_index = FT_Get_Char_Index (face, charcode);
175
- if (glyph_index) {
176
- return glyph_index;
177
- }
178
174
PyObject *text_helpers = NULL , *tmp = NULL ;
179
175
if (!(text_helpers = PyImport_ImportModule (" matplotlib._text_helpers" )) ||
180
176
!(tmp = PyObject_CallMethod (text_helpers, " warn_on_missing_glyph" , " k" , charcode))) {
@@ -189,6 +185,14 @@ static FT_UInt ft_get_char_index_or_warn(FT_Face face, FT_ULong charcode)
189
185
return 0 ;
190
186
}
191
187
188
+ static FT_UInt ft_get_char_index_or_warn (FT_Face face, FT_ULong charcode)
189
+ {
190
+ FT_UInt glyph_index = FT_Get_Char_Index (face, charcode);
191
+ if (glyph_index) {
192
+ return glyph_index;
193
+ }
194
+ return ft_glyph_warn (charcode);
195
+ }
192
196
193
197
// ft_outline_decomposer should be passed to FT_Outline_Decompose. On the
194
198
// first pass, vertices and codes are set to NULL, and index is simply
@@ -319,7 +323,10 @@ FT2Font::get_path()
319
323
return Py_BuildValue (" NN" , vertices.pyobj (), codes.pyobj ());
320
324
}
321
325
322
- FT2Font::FT2Font (FT_Open_Args &open_args, long hinting_factor_) : image(), face(NULL )
326
+ FT2Font::FT2Font (FT_Open_Args &open_args,
327
+ long hinting_factor_,
328
+ std::vector<FT2Font *> &fallback_list)
329
+ : image(), face(NULL )
323
330
{
324
331
clear ();
325
332
@@ -353,6 +360,9 @@ FT2Font::FT2Font(FT_Open_Args &open_args, long hinting_factor_) : image(), face(
353
360
354
361
FT_Matrix transform = { 65536 / hinting_factor, 0 , 0 , 65536 };
355
362
FT_Set_Transform (face, &transform, 0 );
363
+
364
+ // Set fallbacks
365
+ set_fallbacks (fallback_list);
356
366
}
357
367
358
368
FT2Font::~FT2Font ()
@@ -364,6 +374,10 @@ FT2Font::~FT2Font()
364
374
if (face) {
365
375
FT_Done_Face (face);
366
376
}
377
+
378
+ for (uint i = 0 ; i < fallbacks.size (); i ++) {
379
+ fallbacks[i]->~FT2Font ();
380
+ }
367
381
}
368
382
369
383
void FT2Font::clear ()
@@ -376,6 +390,17 @@ void FT2Font::clear()
376
390
}
377
391
378
392
glyphs.clear ();
393
+
394
+ for (uint i = 0 ; i < fallbacks.size (); i ++) {
395
+ fallbacks[i]->clear ();
396
+ }
397
+ }
398
+
399
+ void FT2Font::check () {
400
+ printf (" Fallback num: -1; Numface: %lu\n " , get_face ()->num_glyphs );
401
+ for (uint i = 0 ; i < fallbacks.size (); i++) {
402
+ printf (" Fallback num: %u; Numface: %lu\n " , i, fallbacks[i]->get_face ()->num_glyphs );
403
+ }
379
404
}
380
405
381
406
void FT2Font::set_size (double ptsize, double dpi)
@@ -387,8 +412,18 @@ void FT2Font::set_size(double ptsize, double dpi)
387
412
}
388
413
FT_Matrix transform = { 65536 / hinting_factor, 0 , 0 , 65536 };
389
414
FT_Set_Transform (face, &transform, 0 );
415
+
416
+ for (uint i = 0 ; i < fallbacks.size (); i++) {
417
+ fallbacks[i]->set_size (ptsize, dpi);
418
+ }
390
419
}
391
420
421
+ void FT2Font::set_fallbacks (std::vector<FT2Font *> &fallback_list)
422
+ {
423
+ fallbacks.assign (fallback_list.begin (), fallback_list.end ());
424
+ }
425
+
426
+
392
427
void FT2Font::set_charmap (int i)
393
428
{
394
429
if (i >= face->num_charmaps ) {
@@ -421,15 +456,32 @@ int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode)
421
456
}
422
457
}
423
458
459
+ int FT2Font::get_kerning (FT_UInt left, FT_UInt right, FT_UInt mode, FT_Vector &delta)
460
+ {
461
+ if (!FT_HAS_KERNING (face)) {
462
+ return 0 ;
463
+ }
464
+
465
+ if (!FT_Get_Kerning (face, left, right, mode, &delta)) {
466
+ return (int )(delta.x ) / (hinting_factor << kerning_factor);
467
+ } else {
468
+ return 0 ;
469
+ }
470
+ }
471
+
424
472
void FT2Font::set_kerning_factor (int factor)
425
473
{
426
474
kerning_factor = factor;
475
+ for (uint i = 0 ; i < fallbacks.size (); i ++){
476
+ fallbacks[i]->set_kerning_factor (factor);
477
+ }
427
478
}
428
479
429
480
void FT2Font::set_text (
430
481
size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double > &xys)
431
482
{
432
483
FT_Matrix matrix; /* transformation matrix */
484
+ check ();
433
485
434
486
angle = angle / 360.0 * 2 * M_PI;
435
487
@@ -452,28 +504,47 @@ void FT2Font::set_text(
452
504
FT_BBox glyph_bbox;
453
505
FT_Pos last_advance;
454
506
455
- glyph_index = ft_get_char_index_or_warn (face, codepoints[n]);
507
+ FT_UInt final_glyph_index;
508
+ FT_Error charcode_error, glyph_error;
509
+ FT2Font *ft_object_with_glyph = this ;
510
+ printf (" \n Before loading char! \n " );
511
+ load_char_with_fallback (ft_object_with_glyph, final_glyph_index, glyphs, codepoints[n],
512
+ flags, charcode_error, glyph_error);
513
+ printf (" Final ft2font: %lu\n " , ft_object_with_glyph->get_face ()->num_glyphs );
514
+ if (charcode_error || glyph_error) {
515
+ ft_glyph_warn ((FT_ULong)codepoints[n]);
516
+ return ;
517
+ }
518
+
519
+ glyph_index = final_glyph_index;
456
520
457
521
// retrieve kerning distance and move pen position
458
522
if (use_kerning && previous && glyph_index) {
459
523
FT_Vector delta;
460
- FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, & delta);
524
+ ft_object_with_glyph-> get_kerning ( previous, glyph_index, FT_KERNING_DEFAULT, delta);
461
525
pen.x += delta.x / (hinting_factor << kerning_factor);
462
526
}
463
- if (FT_Error error = FT_Load_Glyph (face, glyph_index, flags)) {
464
- throw_ft_error (" Could not load glyph" , error);
465
- }
527
+
528
+ // DONE with load_char_with_fallback
529
+ // if (FT_Error error = FT_Load_Glyph(face, glyph_index, flags)) {
530
+ // throw_ft_error("Could not load glyph", error);
531
+ // }
532
+
466
533
// ignore errors, jump to next glyph
467
534
468
535
// extract glyph image and store it in our table
469
536
470
- FT_Glyph thisGlyph;
471
- if (FT_Error error = FT_Get_Glyph (face->glyph , &thisGlyph)) {
472
- throw_ft_error (" Could not get glyph" , error);
473
- }
537
+ // DONE with load_char_with_fallback
538
+ // FT_Glyph thisGlyph;
539
+ // if (FT_Error error = FT_Get_Glyph(face->glyph, &thisGlyph)) {
540
+ // throw_ft_error("Could not get glyph", error);
541
+ // }
474
542
// ignore errors, jump to next glyph
475
543
476
- last_advance = face->glyph ->advance .x ;
544
+ FT_Glyph &thisGlyph = glyphs[glyphs.size () - 1 ];
545
+
546
+ // Compare with thisGlyph?
547
+ last_advance = ft_object_with_glyph->get_face ()->glyph ->advance .x ;
477
548
FT_Glyph_Transform (thisGlyph, 0 , &pen);
478
549
FT_Glyph_Transform (thisGlyph, &matrix, 0 );
479
550
xys.push_back (pen.x );
@@ -489,7 +560,10 @@ void FT2Font::set_text(
489
560
pen.x += last_advance;
490
561
491
562
previous = glyph_index;
492
- glyphs.push_back (thisGlyph);
563
+
564
+ printf (" Set_Text complete! \n " );
565
+ // DONE with load_char_with_fallback
566
+ // glyphs.push_back(thisGlyph);
493
567
}
494
568
495
569
FT_Vector_Transform (&pen, &matrix);
@@ -513,6 +587,48 @@ void FT2Font::load_char(long charcode, FT_Int32 flags)
513
587
glyphs.push_back (thisGlyph);
514
588
}
515
589
590
+ void FT2Font::load_char_with_fallback (FT2Font* &ft_object_with_glyph,
591
+ FT_UInt &final_glyph_index,
592
+ std::vector<FT_Glyph> &parent_glyphs,
593
+ long charcode,
594
+ FT_Int32 flags,
595
+ FT_Error &charcode_error,
596
+ FT_Error &glyph_error)
597
+ {
598
+ printf (" loading char!\n " );
599
+ FT_UInt glyph_index = FT_Get_Char_Index (face, charcode);
600
+
601
+ if (glyph_index) {
602
+ printf (" glyph found!\n " );
603
+ charcode_error = FT_Load_Glyph (face, glyph_index, flags);
604
+ // throw_ft_error("Could not load charcode", error);
605
+ FT_Glyph thisGlyph;
606
+ glyph_error = FT_Get_Glyph (face->glyph , &thisGlyph);
607
+ // throw_ft_error("Could not get glyph", error);
608
+ final_glyph_index = glyph_index;
609
+ parent_glyphs.push_back (thisGlyph);
610
+ }
611
+
612
+ else {
613
+ printf (" glyph not found! Fallback size: %lu\n " , fallbacks.size ());
614
+ for (uint i = 0 ; i < fallbacks.size (); ++i) {
615
+ uint current_size = parent_glyphs.size ();
616
+ printf (" Fallback %u: %u\n " , i, current_size);
617
+ fallbacks[i]->load_char_with_fallback (ft_object_with_glyph, final_glyph_index,
618
+ parent_glyphs, charcode, flags, charcode_error,
619
+ glyph_error);
620
+ printf (" Got back from fallback load char!\n " );
621
+ // jump out if glyph size increased
622
+ if (parent_glyphs.size () == current_size + 1 ) {
623
+ printf (" size increased!\n " );
624
+ ft_object_with_glyph = fallbacks[i];
625
+ printf (" Ft object assigned!\n " );
626
+ return ;
627
+ }
628
+ }
629
+ }
630
+ }
631
+
516
632
void FT2Font::load_glyph (FT_UInt glyph_index, FT_Int32 flags)
517
633
{
518
634
if (FT_Error error = FT_Load_Glyph (face, glyph_index, flags)) {
0 commit comments