summaryrefslogtreecommitdiff
path: root/src/lib/evas/common/evas_font_main.c
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-07-30 19:09:12 +0200
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2019-07-30 19:09:12 +0200
commit6883087ac7dac530062b24b5ea918904589a89c2 (patch)
tree2cf7d27776a5dfe4833812391b8b5b1efe3ae584 /src/lib/evas/common/evas_font_main.c
parent29d24aa409371bd0252b34eb54b1adcb256ca2a1 (diff)
Revert "evas_object_textblock: add support for variation sequences"
This reverts commit f7ce771e3243e19f8a12672ea2be752dedccbcf6.
Diffstat (limited to '')
-rw-r--r--src/lib/evas/common/evas_font_main.c296
1 files changed, 28 insertions, 268 deletions
diff --git a/src/lib/evas/common/evas_font_main.c b/src/lib/evas/common/evas_font_main.c
index 31076132fd..b99df9a927 100644
--- a/src/lib/evas/common/evas_font_main.c
+++ b/src/lib/evas/common/evas_font_main.c
@@ -355,182 +355,33 @@ end:
355/* Set of common functions that are used in a couple of places. */ 355/* Set of common functions that are used in a couple of places. */
356 356
357static void 357static void
358_fash_int_map_and_variations_free(Fash_Int_Map *map)
359 {
360 if(!map)
361 return;
362 int i;
363
364 for (i = 0; i < 256; i++)
365 {
366 if (map->items[i].variations)
367 {
368 if (map->items[i].variations->list)
369 {
370 free(map->items[i].variations->list);
371 map->items[i].variations->list = NULL;
372 map->items[i].variations->capacity = 0;
373 map->items[i].variations->length = 0;
374 }
375 free(map->items[i].variations);
376 map->items[i].variations = NULL;
377 }
378 }
379
380 free(map);
381}
382
383static void
384_fash_int2_free(Fash_Int_Map2 *fash) 358_fash_int2_free(Fash_Int_Map2 *fash)
385 { 359{
386 int i; 360 int i;
387 if (fash) 361
388 { 362 for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]);
389 for (i = 0; i < 256; i++) 363 free(fash);
390 if (fash->bucket[i])
391 {
392 _fash_int_map_and_variations_free(fash->bucket[i]);
393 fash->bucket[i] = NULL;
394 }
395 free(fash);
396 fash = NULL;
397 }
398} 364}
399 365
400static void 366static void
401_fash_int_free(Fash_Int *fash) 367_fash_int_free(Fash_Int *fash)
402{ 368{
403 int i; 369 int i;
404 if (fash)
405 {
406 if (fash->MAGIC != FASH_INT_MAGIC)
407 {
408 return;
409 }
410 370
411 for (i = 0; i < 256; i++) 371 for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_int2_free(fash->bucket[i]);
412 { 372 free(fash);
413 if (fash->bucket[i])
414 {
415 _fash_int2_free(fash->bucket[i]);
416 fash->bucket[i] = NULL;
417 }
418 }
419 free(fash);
420 }
421} 373}
422 374
423static Fash_Int * 375static Fash_Int *
424_fash_int_new(void) 376_fash_int_new(void)
425{ 377{
426 Fash_Int *fash = calloc(1, sizeof(Fash_Int)); 378 Fash_Int *fash = calloc(1, sizeof(Fash_Int));
427 EINA_SAFETY_ON_NULL_RETURN_VAL(fash, NULL);
428 fash->MAGIC = FASH_INT_MAGIC;
429 fash->freeme = _fash_int_free; 379 fash->freeme = _fash_int_free;
430 return fash; 380 return fash;
431} 381}
432 382
433static Fash_Item_variation_List *
434_variations_list_new(void)
435{
436 Fash_Item_variation_List *variations = calloc(1, sizeof(Fash_Item_variation_List));
437 EINA_SAFETY_ON_NULL_RETURN_VAL(variations, NULL);
438 variations->capacity = 0;
439 variations->length = 0;
440 variations->list = 0;
441 return variations;
442}
443
444static void
445_variations_list_add(Fash_Item_variation_List *variations,RGBA_Font_Int *fint, int index, Eina_Unicode variation_sequence)
446{
447 Fash_Item_variation_Index_Item *list = variations->list;
448 if (variations->capacity == variations->length)
449 {
450 list = (Fash_Item_variation_Index_Item *) realloc(list, (variations->capacity + 4) * sizeof(Fash_Item_variation_Index_Item));
451 if (list)
452 {
453 variations->list = list;
454 variations->capacity += 4;
455 }
456 }
457
458 EINA_SAFETY_ON_NULL_RETURN(list);
459
460 int start = 0;
461 int end = variations->length;
462 if (end == 0)
463 {
464 // if only on element just add it in 0 index
465 variations->list[0].item.fint = fint;
466 variations->list[0].item.index = index;
467 variations->list[0].variation_sequence = variation_sequence;
468 variations->length++;
469 }
470 else
471 {
472 // find lower bound
473 while (end > start)
474 {
475 int middle = start + (end - start) / 2;
476 if (variations->list[middle].variation_sequence >= variation_sequence)
477 end = middle;
478 else
479 start = middle + 1;
480 }
481
482 // if passed value founded in list, just replace it
483 if (start < (int)variations->length && variations->list[start].variation_sequence == variation_sequence)
484 {
485 variations->list[start].item.fint = fint;
486 variations->list[start].item.index = index;
487 variations->list[start].variation_sequence = variation_sequence;
488 return;
489 }
490
491 // shift array to insert item
492 for (int i = (variations->length - 1) ; i >= start; i--)
493 {
494 variations->list[i + 1] = variations->list[i];
495 }
496
497 // insert new item and keep array sorted
498 variations->list[start].item.fint = fint;
499 variations->list[start].item.index = index;
500 variations->list[start].variation_sequence = variation_sequence;
501 variations->length++;
502 }
503}
504
505
506static Fash_Item_Index_Map * 383static Fash_Item_Index_Map *
507_variations_list_find(Fash_Item_variation_List * variations, Eina_Unicode variation_sequence) 384_fash_int_find(Fash_Int *fash, int item)
508{
509 if (!variations)
510 return NULL;
511
512 if (!variations->list)
513 return NULL;
514
515 int start = 0;
516 int end = variations->length;
517
518 while(end > start)
519 {
520 int middle = start + (end - start) / 2;
521 if (variations->list[middle].variation_sequence == variation_sequence)
522 return &(variations->list[middle].item);
523 else if (variations->list[middle].variation_sequence < variation_sequence)
524 start = middle + 1;
525 else
526 end = middle - 1;
527 }
528
529 return NULL;
530}
531
532static const Fash_Item_Index_Map *
533_fash_int_find(Fash_Int *fash, int item, Eina_Unicode variation_sequence)
534{ 385{
535 int grp, maj, min; 386 int grp, maj, min;
536 387
@@ -540,22 +391,14 @@ _fash_int_find(Fash_Int *fash, int item, Eina_Unicode variation_sequence)
540 min = item & 0xff; 391 min = item & 0xff;
541 if (!fash->bucket[grp]) return NULL; 392 if (!fash->bucket[grp]) return NULL;
542 if (!fash->bucket[grp]->bucket[maj]) return NULL; 393 if (!fash->bucket[grp]->bucket[maj]) return NULL;
543 if (!variation_sequence) 394 return &(fash->bucket[grp]->bucket[maj]->item[min]);
544 return &(fash->bucket[grp]->bucket[maj]->items[min].item);
545 else
546 return _variations_list_find(fash->bucket[grp]->bucket[maj]->items[min].variations, variation_sequence);
547} 395}
548 396
549static void 397static void
550_fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int idx, Eina_Unicode variation_sequence) 398_fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int idx)
551{ 399{
552 int grp, maj, min; 400 int grp, maj, min;
553 401
554 // If we already have cached passed item, skip adding it again
555 const Fash_Item_Index_Map *fm = _fash_int_find(fash, item, variation_sequence);
556 if (fm && fm->fint)
557 return;
558
559 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) 402 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
560 grp = (item >> 16) & 0xff; 403 grp = (item >> 16) & 0xff;
561 maj = (item >> 8) & 0xff; 404 maj = (item >> 8) & 0xff;
@@ -566,20 +409,8 @@ _fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int idx, Eina_Unico
566 if (!fash->bucket[grp]->bucket[maj]) 409 if (!fash->bucket[grp]->bucket[maj])
567 fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Int_Map)); 410 fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Int_Map));
568 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]); 411 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]);
569 if (variation_sequence) 412 fash->bucket[grp]->bucket[maj]->item[min].fint = fint;
570 { 413 fash->bucket[grp]->bucket[maj]->item[min].index = idx;
571 if (!fash->bucket[grp]->bucket[maj]->items[min].variations)
572 {
573 fash->bucket[grp]->bucket[maj]->items[min].variations =_variations_list_new();
574 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]->items[min].variations);
575 }
576 _variations_list_add(fash->bucket[grp]->bucket[maj]->items[min].variations, fint, idx, variation_sequence);
577 }
578 else
579 {
580 fash->bucket[grp]->bucket[maj]->items[min].item.fint = fint;
581 fash->bucket[grp]->bucket[maj]->items[min].item.index = idx;
582 }
583} 414}
584 415
585static void 416static void
@@ -630,45 +461,24 @@ _fash_gl2_free(Fash_Glyph_Map2 *fash)
630 int i; 461 int i;
631 462
632 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) 463 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
633 for (i = 0; i < 256; i++) 464 for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_glyph_free(fash->bucket[i]);
634 {
635 if (fash->bucket[i])
636 {
637 _fash_glyph_free(fash->bucket[i]);
638 fash->bucket[i] = NULL;
639 }
640 }
641 free(fash); 465 free(fash);
642} 466}
643 467
644static void 468static void
645_fash_gl_free(Fash_Glyph *fash) 469_fash_gl_free(Fash_Glyph *fash)
646{ 470{
647 if (fash) 471 int i;
648 {
649 if (fash->MAGIC != FASH_GLYPH_MAGIC)
650 return;
651 472
652 int i; 473 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
653 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16) 474 for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_gl2_free(fash->bucket[i]);
654 for (i = 0; i < 256; i++) 475 free(fash);
655 {
656 if (fash->bucket[i])
657 {
658 _fash_gl2_free(fash->bucket[i]);
659 fash->bucket[i] = NULL;
660 }
661 }
662 free(fash);
663 }
664} 476}
665 477
666static Fash_Glyph * 478static Fash_Glyph *
667_fash_gl_new(void) 479_fash_gl_new(void)
668{ 480{
669 Fash_Glyph *fash = calloc(1, sizeof(Fash_Glyph)); 481 Fash_Glyph *fash = calloc(1, sizeof(Fash_Glyph));
670 EINA_SAFETY_ON_NULL_RETURN_VAL(fash, NULL);
671 fash->MAGIC = FASH_GLYPH_MAGIC;
672 fash->freeme = _fash_gl_free; 482 fash->freeme = _fash_gl_free;
673 return fash; 483 return fash;
674} 484}
@@ -869,7 +679,7 @@ struct _Font_Char_Index
869}; 679};
870 680
871EAPI FT_UInt 681EAPI FT_UInt
872evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl, Eina_Unicode variation_sequence) 682evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
873{ 683{
874 static const unsigned short mapfix[] = 684 static const unsigned short mapfix[] =
875 { 685 {
@@ -931,10 +741,7 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl, Eina_Unicode vari
931 * that something else try to use it. 741 * that something else try to use it.
932 */ 742 */
933 /* FTLOCK(); */ 743 /* FTLOCK(); */
934 if (variation_sequence) 744 result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
935 result.index = FT_Face_GetCharVariantIndex(fi->src->ft.face, gl, variation_sequence);
936 else
937 result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
938 /* FTUNLOCK(); */ 745 /* FTUNLOCK(); */
939 result.gl = gl; 746 result.gl = gl;
940 747
@@ -966,10 +773,7 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl, Eina_Unicode vari
966 { 773 {
967 gl = mapfix[(i << 1) + 1]; 774 gl = mapfix[(i << 1) + 1];
968 FTLOCK(); 775 FTLOCK();
969 if (variation_sequence) 776 result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
970 result.index = FT_Face_GetCharVariantIndex(fi->src->ft.face, gl, variation_sequence);
971 else
972 result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
973 FTUNLOCK(); 777 FTUNLOCK();
974 break; 778 break;
975 } 779 }
@@ -994,49 +798,20 @@ evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl, Eina_Unicode vari
994 return result.index; 798 return result.index;
995} 799}
996 800
997
998/*
999 * @internal
1000 * Search for unicode glyph inside all font files, and return font and glyph index
1001 *
1002 * @param[in] fn the font to use.
1003 * @param[out] fi_ret founded font.
1004 * @param[in] gl unicode glyph to search for
1005 * @param[in] variation_sequence for the gl glyph
1006 * @param[in] evas_font_search_options search options when searching font files
1007 *
1008 */
1009
1010EAPI int 801EAPI int
1011evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicode gl, Eina_Unicode variation_sequence, uint32_t evas_font_search_options) 802evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicode gl)
1012{ 803{
1013 Eina_List *l; 804 Eina_List *l;
1014 805
1015 if (fn->fash) 806 if (fn->fash)
1016 { 807 {
1017 const Fash_Item_Index_Map *fm = _fash_int_find(fn->fash, gl, variation_sequence); 808 Fash_Item_Index_Map *fm = _fash_int_find(fn->fash, gl);
1018 if (fm) 809 if (fm)
1019 { 810 {
1020 if (fm->fint) 811 if (fm->fint)
1021 { 812 {
1022 if (evas_font_search_options == EVAS_FONT_SEARCH_OPTION_NONE) 813 *fi_ret = fm->fint;
1023 { 814 return fm->index;
1024 *fi_ret = fm->fint;
1025 return fm->index;
1026 }
1027 else if( (evas_font_search_options & EVAS_FONT_SEARCH_OPTION_SKIP_COLOR) == EVAS_FONT_SEARCH_OPTION_SKIP_COLOR)
1028 {
1029 if (!fm->fint->src->ft.face)
1030 {
1031 evas_common_font_int_reload(fm->fint);
1032 }
1033
1034 if (fm->fint->src->ft.face && !FT_HAS_COLOR(fm->fint->src->ft.face))
1035 {
1036 *fi_ret = fm->fint;
1037 return fm->index;
1038 }
1039 }
1040 } 815 }
1041 else if (fm->index == -1) return 0; 816 else if (fm->index == -1) return 0;
1042 } 817 }
@@ -1075,35 +850,20 @@ evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicod
1075 } 850 }
1076 if (fi->src->ft.face) 851 if (fi->src->ft.face)
1077 { 852 {
1078 Eina_Bool is_color_only = (evas_font_search_options & EVAS_FONT_SEARCH_OPTION_SKIP_COLOR) == EVAS_FONT_SEARCH_OPTION_SKIP_COLOR && 853 idx = evas_common_get_char_index(fi, gl);
1079 FT_HAS_COLOR(fi->src->ft.face);
1080
1081 if (is_color_only)
1082 {
1083 /* This is color font ignore it */
1084 continue;
1085 }
1086
1087 idx = (int) evas_common_get_char_index(fi, gl, variation_sequence);
1088 if (idx != 0) 854 if (idx != 0)
1089 { 855 {
1090 if (!fi->ft.size) 856 if (!fi->ft.size)
1091 evas_common_font_int_load_complete(fi); 857 evas_common_font_int_load_complete(fi);
1092 if (!is_color_only) 858 if (!fn->fash) fn->fash = _fash_int_new();
1093 { 859 if (fn->fash) _fash_int_add(fn->fash, gl, fi, idx);
1094 if (!fn->fash) fn->fash = _fash_int_new();
1095 if (fn->fash) _fash_int_add(fn->fash, gl, fi, idx, variation_sequence);
1096 }
1097 *fi_ret = fi; 860 *fi_ret = fi;
1098 return idx; 861 return idx;
1099 } 862 }
1100 else 863 else
1101 { 864 {
1102 if (!is_color_only) 865 if (!fn->fash) fn->fash = _fash_int_new();
1103 { 866 if (fn->fash) _fash_int_add(fn->fash, gl, NULL, -1);
1104 if (!fn->fash) fn->fash = _fash_int_new();
1105 if (fn->fash) _fash_int_add(fn->fash, gl, NULL, -1, variation_sequence);
1106 }
1107 } 867 }
1108 } 868 }
1109 } 869 }