aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-05-05 09:46:05 +0000
committerPo Lu2022-05-05 09:46:05 +0000
commit1468eef301a59346adc47ef19a740f4e2c3737a2 (patch)
treeee16c08d185100385231849da505310cf6e9ff5e
parent30caeb789659441f8feb76b24f3d0b1f60125085 (diff)
downloademacs-1468eef301a59346adc47ef19a740f4e2c3737a2.tar.gz
emacs-1468eef301a59346adc47ef19a740f4e2c3737a2.zip
Speed up opening fonts on Haiku
* src/font.h (font_property_index): Note that some font drivers use the extra data in a font entity to store driver-specific information. * src/haiku_font_support.cc (BFont_find): Set font indices. (be_open_font_at_index): New function. (BFont_open_pattern): Clean up coding style. * src/haiku_support.h (enum haiku_font_specification) (struct haiku_font_pattern): New fields and specifications for indices. * src/haikufont.c (haikufont_pattern_to_entity, haikufont_open): Use indices to open fonts if available in the extra data.
-rw-r--r--src/font.h5
-rw-r--r--src/haiku_font_support.cc118
-rw-r--r--src/haiku_support.h48
-rw-r--r--src/haikufont.c59
4 files changed, 183 insertions, 47 deletions
diff --git a/src/font.h b/src/font.h
index 424616a4a1e..06bd297ccb2 100644
--- a/src/font.h
+++ b/src/font.h
@@ -155,8 +155,9 @@ enum font_property_index
155 /* In a font-spec, the value is an alist of extra information of a 155 /* In a font-spec, the value is an alist of extra information of a
156 font such as name, OpenType features, and language coverage. 156 font such as name, OpenType features, and language coverage.
157 In addition, in a font-entity, the value may contain a pair 157 In addition, in a font-entity, the value may contain a pair
158 (font-entity . INFO) where INFO is extra information to identify 158 (font-entity . INFO) where INFO is extra information to
159 a font (font-driver dependent). */ 159 identify a font (font-driver dependent). In a font-entity,
160 this holds font driver-specific information. */
160 FONT_EXTRA_INDEX, /* alist alist */ 161 FONT_EXTRA_INDEX, /* alist alist */
161 162
162 /* This value is the length of font-spec vector. */ 163 /* This value is the length of font-spec vector. */
diff --git a/src/haiku_font_support.cc b/src/haiku_font_support.cc
index 339634f01be..ca6aaf71204 100644
--- a/src/haiku_font_support.cc
+++ b/src/haiku_font_support.cc
@@ -574,18 +574,21 @@ BFont_find (struct haiku_font_pattern *pt)
574 font_family name; 574 font_family name;
575 font_style sname; 575 font_style sname;
576 uint32 flags; 576 uint32 flags;
577 int sty_count; 577 int sty_count, fam_count, si, fi;
578 int fam_count = count_font_families (); 578 struct haiku_font_pattern *p, *head, *n;
579 bool oblique_seen_p;
579 580
580 for (int fi = 0; fi < fam_count; ++fi) 581 fam_count = count_font_families ();
582
583 for (fi = 0; fi < fam_count; ++fi)
581 { 584 {
582 if (get_font_family (fi, &name, &flags) == B_OK) 585 if (get_font_family (fi, &name, &flags) == B_OK)
583 { 586 {
584 sty_count = count_font_styles (name); 587 sty_count = count_font_styles (name);
585 if (!sty_count && 588 if (!sty_count
586 font_family_style_matches_p (name, NULL, flags, pt)) 589 && font_family_style_matches_p (name, NULL, flags, pt))
587 { 590 {
588 struct haiku_font_pattern *p = new struct haiku_font_pattern; 591 p = new struct haiku_font_pattern;
589 p->specified = 0; 592 p->specified = 0;
590 p->oblique_seen_p = 1; 593 p->oblique_seen_p = 1;
591 haiku_font_fill_pattern (p, name, NULL, flags); 594 haiku_font_fill_pattern (p, name, NULL, flags);
@@ -598,11 +601,11 @@ BFont_find (struct haiku_font_pattern *pt)
598 } 601 }
599 else if (sty_count) 602 else if (sty_count)
600 { 603 {
601 for (int si = 0; si < sty_count; ++si) 604 for (si = 0; si < sty_count; ++si)
602 { 605 {
603 int oblique_seen_p = 0; 606 oblique_seen_p = 0;
604 struct haiku_font_pattern *head = r; 607 head = r;
605 struct haiku_font_pattern *p = NULL; 608 p = NULL;
606 609
607 if (get_font_style (name, si, &sname, &flags) == B_OK) 610 if (get_font_style (name, si, &sname, &flags) == B_OK)
608 { 611 {
@@ -611,8 +614,18 @@ BFont_find (struct haiku_font_pattern *pt)
611 p = new struct haiku_font_pattern; 614 p = new struct haiku_font_pattern;
612 p->specified = 0; 615 p->specified = 0;
613 haiku_font_fill_pattern (p, name, (char *) &sname, flags); 616 haiku_font_fill_pattern (p, name, (char *) &sname, flags);
614 if (p->specified & FSPEC_SLANT && 617
615 ((p->slant == SLANT_OBLIQUE) || (p->slant == SLANT_ITALIC))) 618 /* Add the indices to this font now so we
619 won't have to loop over each font in
620 order to open it later. */
621
622 p->specified |= FSPEC_INDICES;
623 p->family_index = fi;
624 p->style_index = si;
625
626 if (p->specified & FSPEC_SLANT
627 && (p->slant == SLANT_OBLIQUE
628 || p->slant == SLANT_ITALIC))
616 oblique_seen_p = 1; 629 oblique_seen_p = 1;
617 630
618 p->next = r; 631 p->next = r;
@@ -627,9 +640,7 @@ BFont_find (struct haiku_font_pattern *pt)
627 p->last = NULL; 640 p->last = NULL;
628 641
629 for (; head; head = head->last) 642 for (; head; head = head->last)
630 { 643 head->oblique_seen_p = oblique_seen_p;
631 head->oblique_seen_p = oblique_seen_p;
632 }
633 } 644 }
634 } 645 }
635 } 646 }
@@ -642,13 +653,18 @@ BFont_find (struct haiku_font_pattern *pt)
642 if (!(pt->specified & FSPEC_SLANT)) 653 if (!(pt->specified & FSPEC_SLANT))
643 { 654 {
644 /* r->last is invalid from here onwards. */ 655 /* r->last is invalid from here onwards. */
645 for (struct haiku_font_pattern *p = r; p;) 656 for (p = r; p;)
646 { 657 {
647 if (!p->oblique_seen_p) 658 if (!p->oblique_seen_p)
648 { 659 {
649 struct haiku_font_pattern *n = new haiku_font_pattern; 660 n = new haiku_font_pattern;
650 *n = *p; 661 *n = *p;
662
651 n->slant = SLANT_OBLIQUE; 663 n->slant = SLANT_OBLIQUE;
664
665 /* Opening a font by its indices doesn't provide enough
666 information to synthesize the oblique font later. */
667 n->specified &= ~FSPEC_INDICES;
652 p->next = n; 668 p->next = n;
653 p = p->next_family; 669 p = p->next_family;
654 } 670 }
@@ -660,26 +676,68 @@ BFont_find (struct haiku_font_pattern *pt)
660 return r; 676 return r;
661} 677}
662 678
679/* Find and open a font with the family at FAMILY and the style at
680 STYLE, and set its size to SIZE. Value is NULL if opening the font
681 failed. */
682void *
683be_open_font_at_index (int family, int style, float size)
684{
685 font_family family_name;
686 font_style style_name;
687 uint32 flags;
688 status_t rc;
689 BFont *font;
690
691 rc = get_font_family (family, &family_name, &flags);
692
693 if (rc != B_OK)
694 return NULL;
695
696 rc = get_font_style (family_name, style, &style_name, &flags);
697
698 if (rc != B_OK)
699 return NULL;
700
701 font = new BFont;
702
703 rc = font->SetFamilyAndStyle (family_name, style_name);
704
705 if (rc != B_OK)
706 {
707 delete font;
708 return NULL;
709 }
710
711 font->SetSize (size);
712 font->SetEncoding (B_UNICODE_UTF8);
713 font->SetSpacing (B_BITMAP_SPACING);
714 return font;
715}
716
663/* Find and open a font matching the pattern PAT, which must have its 717/* Find and open a font matching the pattern PAT, which must have its
664 family set. */ 718 family set. */
665int 719int
666BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size) 720BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
667{ 721{
668 int sty_count; 722 int sty_count, si, code;
669 font_family name; 723 font_family name;
670 font_style sname; 724 font_style sname;
725 BFont *ft;
671 uint32 flags = 0; 726 uint32 flags = 0;
727 struct haiku_font_pattern copy;
728
672 if (!(pat->specified & FSPEC_FAMILY)) 729 if (!(pat->specified & FSPEC_FAMILY))
673 return 1; 730 return 1;
731
674 strncpy (name, pat->family, sizeof name - 1); 732 strncpy (name, pat->family, sizeof name - 1);
675 name[sizeof name - 1] = '\0'; 733 name[sizeof name - 1] = '\0';
676 734
677 sty_count = count_font_styles (name); 735 sty_count = count_font_styles (name);
678 736
679 if (!sty_count && 737 if (!sty_count
680 font_family_style_matches_p (name, NULL, flags, pat, 1)) 738 && font_family_style_matches_p (name, NULL, flags, pat, 1))
681 { 739 {
682 BFont *ft = new BFont; 740 ft = new BFont;
683 ft->SetSize (size); 741 ft->SetSize (size);
684 ft->SetEncoding (B_UNICODE_UTF8); 742 ft->SetEncoding (B_UNICODE_UTF8);
685 ft->SetSpacing (B_BITMAP_SPACING); 743 ft->SetSpacing (B_BITMAP_SPACING);
@@ -694,12 +752,13 @@ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
694 } 752 }
695 else if (sty_count) 753 else if (sty_count)
696 { 754 {
697 for (int si = 0; si < sty_count; ++si) 755 for (si = 0; si < sty_count; ++si)
698 { 756 {
699 if (get_font_style (name, si, &sname, &flags) == B_OK && 757 if (get_font_style (name, si, &sname, &flags) == B_OK
700 font_family_style_matches_p (name, (char *) &sname, flags, pat)) 758 && font_family_style_matches_p (name, (char *) &sname,
759 flags, pat))
701 { 760 {
702 BFont *ft = new BFont; 761 ft = new BFont;
703 ft->SetSize (size); 762 ft->SetSize (size);
704 ft->SetEncoding (B_UNICODE_UTF8); 763 ft->SetEncoding (B_UNICODE_UTF8);
705 ft->SetSpacing (B_BITMAP_SPACING); 764 ft->SetSpacing (B_BITMAP_SPACING);
@@ -709,6 +768,7 @@ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
709 delete ft; 768 delete ft;
710 return 1; 769 return 1;
711 } 770 }
771
712 *font = (void *) ft; 772 *font = (void *) ft;
713 return 0; 773 return 0;
714 } 774 }
@@ -717,12 +777,14 @@ BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
717 777
718 if (pat->specified & FSPEC_SLANT && pat->slant == SLANT_OBLIQUE) 778 if (pat->specified & FSPEC_SLANT && pat->slant == SLANT_OBLIQUE)
719 { 779 {
720 struct haiku_font_pattern copy = *pat; 780 copy = *pat;
721 copy.slant = SLANT_REGULAR; 781 copy.slant = SLANT_REGULAR;
722 int code = BFont_open_pattern (&copy, font, size); 782 code = BFont_open_pattern (&copy, font, size);
783
723 if (code) 784 if (code)
724 return code; 785 return code;
725 BFont *ft = (BFont *) *font; 786
787 ft = (BFont *) *font;
726 /* XXX Font measurements don't respect shear. Haiku bug? 788 /* XXX Font measurements don't respect shear. Haiku bug?
727 This apparently worked in BeOS. 789 This apparently worked in BeOS.
728 ft->SetShear (100.0); */ 790 ft->SetShear (100.0); */
diff --git a/src/haiku_support.h b/src/haiku_support.h
index 63ba7260506..0fe2af3329a 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -246,6 +246,7 @@ enum haiku_font_specification
246 FSPEC_NEED_ONE_OF = 1 << 6, 246 FSPEC_NEED_ONE_OF = 1 << 6,
247 FSPEC_WIDTH = 1 << 7, 247 FSPEC_WIDTH = 1 << 7,
248 FSPEC_LANGUAGE = 1 << 8, 248 FSPEC_LANGUAGE = 1 << 8,
249 FSPEC_INDICES = 1 << 9,
249 }; 250 };
250 251
251typedef char haiku_font_family_or_style[64]; 252typedef char haiku_font_family_or_style[64];
@@ -300,25 +301,61 @@ enum haiku_font_weight
300 301
301struct haiku_font_pattern 302struct haiku_font_pattern
302{ 303{
304 /* Bitmask indicating which fields are set. */
303 int specified; 305 int specified;
306
307 /* The next font in this list. */
304 struct haiku_font_pattern *next; 308 struct haiku_font_pattern *next;
305 /* The next two fields are only temporarily used during the font 309
306 discovery process! Do not rely on them being correct outside 310 /* The last font in the list during font lookup. */
307 BFont_find. */
308 struct haiku_font_pattern *last; 311 struct haiku_font_pattern *last;
312
313 /* The next font in the list whose family differs from this one.
314 Only valid during font lookup. */
309 struct haiku_font_pattern *next_family; 315 struct haiku_font_pattern *next_family;
316
317 /* The family of the font. */
310 haiku_font_family_or_style family; 318 haiku_font_family_or_style family;
319
320 /* The style of the font. */
311 haiku_font_family_or_style style; 321 haiku_font_family_or_style style;
322
323 /* Whether or the font is monospace. */
312 int mono_spacing_p; 324 int mono_spacing_p;
313 int want_chars_len; 325
314 int need_one_of_len; 326 /* The slant of the font. */
315 enum haiku_font_slant slant; 327 enum haiku_font_slant slant;
328
329 /* The width of the font. */
316 enum haiku_font_width width; 330 enum haiku_font_width width;
331
332 /* The language of the font. Used during font lookup. */
317 enum haiku_font_language language; 333 enum haiku_font_language language;
334
335 /* The weight of the font. */
318 enum haiku_font_weight weight; 336 enum haiku_font_weight weight;
337
338 /* List of characters that must be present in the font for the match
339 to succeed. */
319 int *wanted_chars; 340 int *wanted_chars;
341
342 /* The number of characters in `wanted_chars'. */
343 int want_chars_len;
344
345 /* List of characters. The font must fullfill at least one of
346 them for the match to succeed. */
320 int *need_one_of; 347 int *need_one_of;
321 348
349 /* The number of characters in `need_one_of'. */
350 int need_one_of_len;
351
352 /* The index of the family of the font this pattern represents. */
353 int family_index;
354
355 /* The index of the style of the font this pattern represents. */
356 int style_index;
357
358 /* Temporary field used during font enumeration. */
322 int oblique_seen_p; 359 int oblique_seen_p;
323}; 360};
324 361
@@ -635,6 +672,7 @@ extern bool be_use_subpixel_antialiasing (void);
635extern const char *be_find_setting (const char *); 672extern const char *be_find_setting (const char *);
636extern haiku_font_family_or_style *be_list_font_families (size_t *); 673extern haiku_font_family_or_style *be_list_font_families (size_t *);
637extern void be_font_style_to_flags (char *, struct haiku_font_pattern *); 674extern void be_font_style_to_flags (char *, struct haiku_font_pattern *);
675extern void *be_open_font_at_index (int, int, float);
638extern int be_get_ui_color (const char *, uint32_t *); 676extern int be_get_ui_color (const char *, uint32_t *);
639 677
640extern void BMessage_delete (void *); 678extern void BMessage_delete (void *);
diff --git a/src/haikufont.c b/src/haikufont.c
index d18c1a393a0..f8cf45284d0 100644
--- a/src/haikufont.c
+++ b/src/haikufont.c
@@ -381,7 +381,9 @@ haikufont_maybe_handle_special_family (Lisp_Object family,
381static Lisp_Object 381static Lisp_Object
382haikufont_pattern_to_entity (struct haiku_font_pattern *ptn) 382haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
383{ 383{
384 Lisp_Object ent = font_make_entity (); 384 Lisp_Object ent;
385
386 ent = font_make_entity ();
385 ASET (ent, FONT_TYPE_INDEX, Qhaiku); 387 ASET (ent, FONT_TYPE_INDEX, Qhaiku);
386 ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku); 388 ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku);
387 ASET (ent, FONT_FAMILY_INDEX, Qdefault); 389 ASET (ent, FONT_FAMILY_INDEX, Qdefault);
@@ -390,6 +392,14 @@ haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
390 ASET (ent, FONT_SIZE_INDEX, make_fixnum (0)); 392 ASET (ent, FONT_SIZE_INDEX, make_fixnum (0));
391 ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0)); 393 ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0));
392 ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO)); 394 ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
395
396 /* FONT_EXTRA_INDEX in a font entity can be a cons of two numbers
397 (STYLE . IDX) that tell Emacs how to open a font. */
398 if (ptn->specified & FSPEC_INDICES)
399 ASET (ent, FONT_EXTRA_INDEX,
400 Fcons (make_fixnum (ptn->family_index),
401 make_fixnum (ptn->style_index)));
402
393 FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnormal); 403 FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnormal);
394 FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnormal); 404 FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnormal);
395 FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnormal); 405 FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnormal);
@@ -722,10 +732,11 @@ haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
722 struct haiku_font_pattern ptn; 732 struct haiku_font_pattern ptn;
723 struct font *font; 733 struct font *font;
724 void *be_font; 734 void *be_font;
725 Lisp_Object font_object; 735 Lisp_Object font_object, tem, extra;
726 Lisp_Object tem; 736 int px_size, min_width, max_width,
737 avg_width, height, space_width, ascent,
738 descent, underline_pos, underline_thickness;
727 739
728 block_input ();
729 if (x <= 0) 740 if (x <= 0)
730 { 741 {
731 /* Get pixel size from frame instead. */ 742 /* Get pixel size from frame instead. */
@@ -733,19 +744,47 @@ haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
733 x = NILP (tem) ? 0 : XFIXNAT (tem); 744 x = NILP (tem) ? 0 : XFIXNAT (tem);
734 } 745 }
735 746
736 haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn); 747 extra = AREF (font_entity, FONT_EXTRA_INDEX);
748
749 /* If the font's indices is already available, open the font using
750 those instead. */
751
752 if (CONSP (extra) && FIXNUMP (XCAR (extra))
753 && FIXNUMP (XCDR (extra)))
754 {
755 block_input ();
756 be_font = be_open_font_at_index (XFIXNUM (XCAR (extra)),
757 XFIXNUM (XCDR (extra)), x);
758 unblock_input ();
737 759
738 if (BFont_open_pattern (&ptn, &be_font, x)) 760 if (!be_font)
761 return Qnil;
762 }
763 else
739 { 764 {
765 block_input ();
766 haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn);
767
768 if (BFont_open_pattern (&ptn, &be_font, x))
769 {
770 haikufont_done_with_query_pattern (&ptn);
771 unblock_input ();
772 return Qnil;
773 }
774
740 haikufont_done_with_query_pattern (&ptn); 775 haikufont_done_with_query_pattern (&ptn);
741 unblock_input (); 776 unblock_input ();
742 return Qnil;
743 } 777 }
744 778
745 haikufont_done_with_query_pattern (&ptn); 779 block_input ();
746 780
781 /* `font_make_object' tries to treat the extra data as an alist.
782 There is never any real data here, so clear that field. */
783
784 ASET (font_entity, FONT_EXTRA_INDEX, Qnil);
747 font_object = font_make_object (VECSIZE (struct haikufont_info), 785 font_object = font_make_object (VECSIZE (struct haikufont_info),
748 font_entity, x); 786 font_entity, x);
787 ASET (font_entity, FONT_EXTRA_INDEX, extra);
749 788
750 ASET (font_object, FONT_TYPE_INDEX, Qhaiku); 789 ASET (font_object, FONT_TYPE_INDEX, Qhaiku);
751 font_info = (struct haikufont_info *) XFONT_OBJECT (font_object); 790 font_info = (struct haikufont_info *) XFONT_OBJECT (font_object);
@@ -772,10 +811,6 @@ haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
772 font_info->metrics = NULL; 811 font_info->metrics = NULL;
773 font_info->metrics_nrows = 0; 812 font_info->metrics_nrows = 0;
774 813
775 int px_size, min_width, max_width,
776 avg_width, height, space_width, ascent,
777 descent, underline_pos, underline_thickness;
778
779 BFont_metrics (be_font, &px_size, &min_width, 814 BFont_metrics (be_font, &px_size, &min_width,
780 &max_width, &avg_width, &height, 815 &max_width, &avg_width, &height,
781 &space_width, &ascent, &descent, 816 &space_width, &ascent, &descent,