root/src/haikufont.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. haikufont_apply_registry
  2. haikufont_get_fallback_entity
  3. haikufont_get_cache
  4. haikufont_weight_to_lisp
  5. haikufont_lisp_to_weight
  6. haikufont_slant_to_lisp
  7. haikufont_lisp_to_slant
  8. haikufont_width_to_lisp
  9. haikufont_lisp_to_width
  10. haikufont_maybe_handle_special_family
  11. haikufont_pattern_to_entity
  12. haikufont_pattern_from_object
  13. haikufont_spec_or_entity_to_pattern
  14. haikufont_done_with_query_pattern
  15. haikufont_match
  16. haikufont_list
  17. haiku_bulk_encode
  18. haikufont_encode_char
  19. haikufont_open
  20. haikufont_close
  21. haikufont_prepare_face
  22. haikufont_glyph_extents
  23. haikufont_text_extents
  24. haikufont_shape
  25. haikufont_draw
  26. haikufont_list_family
  27. haikufont_filter_properties
  28. haikufont_should_quit_popup
  29. DEFUN
  30. DEFUN
  31. haiku_handle_font_change_event
  32. syms_of_haikufont_for_pdumper
  33. syms_of_haikufont

     1 /* Font support for Haiku windowing
     2 
     3 Copyright (C) 2021-2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 #include <config.h>
    21 
    22 #include "lisp.h"
    23 #include "dispextern.h"
    24 #include "composite.h"
    25 #include "blockinput.h"
    26 #include "charset.h"
    27 #include "frame.h"
    28 #include "window.h"
    29 #include "fontset.h"
    30 #include "haikuterm.h"
    31 #include "character.h"
    32 #include "coding.h"
    33 #include "font.h"
    34 #include "termchar.h"
    35 #include "pdumper.h"
    36 #include "haiku_support.h"
    37 
    38 #include <math.h>
    39 #include <stdlib.h>
    40 
    41 static Lisp_Object font_cache;
    42 
    43 #define METRICS_NCOLS_PER_ROW   (128)
    44 
    45 enum metrics_status
    46   {
    47     METRICS_INVALID = -1,    /* metrics entry is invalid */
    48   };
    49 
    50 #define METRICS_STATUS(metrics) ((metrics)->ascent + (metrics)->descent)
    51 #define METRICS_SET_STATUS(metrics, status) \
    52   ((metrics)->ascent = 0, (metrics)->descent = (status))
    53 
    54 static struct
    55 {
    56   /* registry name */
    57   const char *name;
    58   /* characters to distinguish the charset from the others */
    59   int uniquifier[6];
    60   /* additional constraint by language */
    61   const char *lang;
    62 } em_charset_table[] =
    63   { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } },
    64     { "iso8859-2", { 0x00A0, 0x010E }},
    65     { "iso8859-3", { 0x00A0, 0x0108 }},
    66     { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
    67     { "iso8859-5", { 0x00A0, 0x0401 }},
    68     { "iso8859-6", { 0x00A0, 0x060C }},
    69     { "iso8859-7", { 0x00A0, 0x0384 }},
    70     { "iso8859-8", { 0x00A0, 0x05D0 }},
    71     { "iso8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }},
    72     { "iso8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }},
    73     { "iso8859-11", { 0x00A0, 0x0E01 }},
    74     { "iso8859-13", { 0x00A0, 0x201C }},
    75     { "iso8859-14", { 0x00A0, 0x0174 }},
    76     { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }},
    77     { "iso8859-16", { 0x00A0, 0x0218}},
    78     { "gb2312.1980-0", { 0x4E13 }, "zh-cn"},
    79     { "big5-0", { 0x9C21 }, "zh-tw" },
    80     { "jisx0208.1983-0", { 0x4E55 }, "ja"},
    81     { "ksc5601.1985-0", { 0xAC00 }, "ko"},
    82     { "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
    83     { "cns11643.1992-2", { 0x4E33, 0x7934 }},
    84     { "cns11643.1992-3", { 0x201A9 }},
    85     { "cns11643.1992-4", { 0x20057 }},
    86     { "cns11643.1992-5", { 0x20000 }},
    87     { "cns11643.1992-6", { 0x20003 }},
    88     { "cns11643.1992-7", { 0x20055 }},
    89     { "gbk-0", { 0x4E06 }, "zh-cn"},
    90     { "jisx0212.1990-0", { 0x4E44 }},
    91     { "jisx0213.2000-1", { 0xFA10 }, "ja"},
    92     { "jisx0213.2000-2", { 0xFA49 }},
    93     { "jisx0213.2004-1", { 0x20B9F }},
    94     { "viscii1.1-1", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"},
    95     { "tis620.2529-1", { 0x0E01 }, "th"},
    96     { "microsoft-cp1251", { 0x0401, 0x0490 }, "ru"},
    97     { "koi8-r", { 0x0401, 0x2219 }, "ru"},
    98     { "mulelao-1", { 0x0E81 }, "lo"},
    99     { "unicode-sip", { 0x20000 }},
   100     { "mulearabic-0", { 0x628 }},
   101     { "mulearabic-1", { 0x628 }},
   102     { "mulearabic-2", { 0x628 }},
   103     { NULL }
   104   };
   105 
   106 static void
   107 haikufont_apply_registry (struct haiku_font_pattern *pattern,
   108                           Lisp_Object registry)
   109 {
   110   char *str = SSDATA (SYMBOL_NAME (registry));
   111   USE_SAFE_ALLOCA;
   112   char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
   113   int i, j;
   114 
   115   for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
   116     {
   117       if (str[i] == '.')
   118         re[j++] = '\\';
   119       else if (str[i] == '*')
   120         re[j++] = '.';
   121       re[j] = str[i];
   122       if (re[j] == '?')
   123         re[j] = '.';
   124     }
   125   re[j] = '\0';
   126   AUTO_STRING_WITH_LEN (regexp, re, j);
   127   for (i = 0; em_charset_table[i].name; i++)
   128     if (fast_c_string_match_ignore_case
   129         (regexp, em_charset_table[i].name,
   130          strlen (em_charset_table[i].name)) >= 0)
   131       break;
   132   SAFE_FREE ();
   133   if (!em_charset_table[i].name)
   134     return;
   135   int *uniquifier = em_charset_table[i].uniquifier;
   136   int l;
   137 
   138   for (l = 0; uniquifier[l]; ++l);
   139 
   140   int *a = xmalloc (l * sizeof *a);
   141   for (l = 0; uniquifier[l]; ++l)
   142     a[l] = uniquifier[l];
   143 
   144   if (pattern->specified & FSPEC_WANTED)
   145     {
   146       int old_l = l;
   147       l += pattern->want_chars_len;
   148       a = xrealloc (a, l * sizeof *a);
   149       memcpy (&a[old_l], pattern->wanted_chars, (l - old_l) * sizeof *a);
   150       xfree (pattern->wanted_chars);
   151     }
   152 
   153   pattern->specified |= FSPEC_WANTED;
   154   pattern->want_chars_len = l;
   155   pattern->wanted_chars = a;
   156 
   157   if (em_charset_table[i].lang)
   158     {
   159       if (!strncmp (em_charset_table[i].lang, "zh", 2))
   160         {
   161           pattern->specified |= FSPEC_LANGUAGE;
   162           pattern->language = LANGUAGE_CN;
   163         }
   164       else if (!strncmp (em_charset_table[i].lang, "ko", 2))
   165         {
   166           pattern->specified |= FSPEC_LANGUAGE;
   167           pattern->language = LANGUAGE_KO;
   168         }
   169       else if (!strncmp (em_charset_table[i].lang, "ja", 2))
   170         {
   171           pattern->specified |= FSPEC_LANGUAGE;
   172           pattern->language = LANGUAGE_JP;
   173         }
   174     }
   175 
   176   return;
   177 }
   178 
   179 static Lisp_Object
   180 haikufont_get_fallback_entity (void)
   181 {
   182   Lisp_Object ent = font_make_entity ();
   183   ASET (ent, FONT_TYPE_INDEX, Qhaiku);
   184   ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku);
   185   ASET (ent, FONT_FAMILY_INDEX, Qnil);
   186   ASET (ent, FONT_ADSTYLE_INDEX, Qnil);
   187   ASET (ent, FONT_REGISTRY_INDEX, Qiso10646_1);
   188   ASET (ent, FONT_SIZE_INDEX, make_fixnum (0));
   189   ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0));
   190   ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
   191   FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnil);
   192   FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnil);
   193   FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnil);
   194 
   195   return ent;
   196 }
   197 
   198 static Lisp_Object
   199 haikufont_get_cache (struct frame *frame)
   200 {
   201   return font_cache;
   202 }
   203 
   204 static Lisp_Object
   205 haikufont_weight_to_lisp (int weight)
   206 {
   207   switch (weight)
   208     {
   209     case HAIKU_THIN:
   210       return Qthin;
   211     case HAIKU_EXTRALIGHT:
   212       return Qextra_light;
   213     case HAIKU_LIGHT:
   214       return Qlight;
   215     case HAIKU_SEMI_LIGHT:
   216       return Qsemi_light;
   217     case HAIKU_REGULAR:
   218       return Qnormal;
   219     case HAIKU_SEMI_BOLD:
   220       return Qsemi_bold;
   221     case HAIKU_BOLD:
   222       return Qbold;
   223     case HAIKU_EXTRA_BOLD:
   224       return Qextra_bold;
   225     case HAIKU_BOOK:
   226       return Qbook;
   227     case HAIKU_HEAVY:
   228       return Qheavy;
   229     case HAIKU_ULTRA_HEAVY:
   230       return Qultra_heavy;
   231     case HAIKU_BLACK:
   232       return Qblack;
   233     case HAIKU_MEDIUM:
   234       return Qmedium;
   235     }
   236   emacs_abort ();
   237 }
   238 
   239 static int
   240 haikufont_lisp_to_weight (Lisp_Object weight)
   241 {
   242   if (EQ (weight, Qthin))
   243     return HAIKU_THIN;
   244   if (EQ (weight, Qultra_light))
   245     return HAIKU_EXTRALIGHT;
   246   if (EQ (weight, Qextra_light))
   247     return HAIKU_EXTRALIGHT;
   248   if (EQ (weight, Qlight))
   249     return HAIKU_LIGHT;
   250   if (EQ (weight, Qsemi_light))
   251     return HAIKU_SEMI_LIGHT;
   252   if (EQ (weight, Qnormal) || EQ (weight, Qregular))
   253     return HAIKU_REGULAR;
   254   if (EQ (weight, Qsemi_bold))
   255     return HAIKU_SEMI_BOLD;
   256   if (EQ (weight, Qbold))
   257     return HAIKU_BOLD;
   258   if (EQ (weight, Qextra_bold))
   259     return HAIKU_EXTRA_BOLD;
   260   if (EQ (weight, Qultra_bold))
   261     return HAIKU_EXTRA_BOLD;
   262   if (EQ (weight, Qbook))
   263     return HAIKU_BOOK;
   264   if (EQ (weight, Qheavy))
   265     return HAIKU_HEAVY;
   266   if (EQ (weight, Qultra_heavy))
   267     return HAIKU_ULTRA_HEAVY;
   268   if (EQ (weight, Qblack))
   269     return HAIKU_BLACK;
   270   if (EQ (weight, Qmedium))
   271     return HAIKU_MEDIUM;
   272 
   273   return HAIKU_REGULAR;
   274 }
   275 
   276 static Lisp_Object
   277 haikufont_slant_to_lisp (enum haiku_font_slant slant)
   278 {
   279   switch (slant)
   280     {
   281     case NO_SLANT:
   282       emacs_abort ();
   283     case SLANT_ITALIC:
   284       return Qitalic;
   285     case SLANT_REGULAR:
   286       return Qnormal;
   287     case SLANT_OBLIQUE:
   288       return Qoblique;
   289     }
   290   emacs_abort ();
   291 }
   292 
   293 static enum haiku_font_slant
   294 haikufont_lisp_to_slant (Lisp_Object slant)
   295 {
   296   if (EQ (slant, Qitalic)
   297       || EQ (slant, Qreverse_italic))
   298     return SLANT_ITALIC;
   299   if (EQ (slant, Qoblique)
   300       || EQ (slant, Qreverse_oblique))
   301     return SLANT_OBLIQUE;
   302   if (EQ (slant, Qnormal) || EQ (slant, Qregular))
   303     return SLANT_REGULAR;
   304 
   305   return SLANT_REGULAR;
   306 }
   307 
   308 static Lisp_Object
   309 haikufont_width_to_lisp (enum haiku_font_width width)
   310 {
   311   switch (width)
   312     {
   313     case NO_WIDTH:
   314       emacs_abort ();
   315     case ULTRA_CONDENSED:
   316       return Qultra_condensed;
   317     case EXTRA_CONDENSED:
   318       return Qextra_condensed;
   319     case CONDENSED:
   320       return Qcondensed;
   321     case SEMI_CONDENSED:
   322       return Qsemi_condensed;
   323     case NORMAL_WIDTH:
   324       return Qnormal;
   325     case SEMI_EXPANDED:
   326       return Qsemi_expanded;
   327     case EXPANDED:
   328       return Qexpanded;
   329     case EXTRA_EXPANDED:
   330       return Qextra_expanded;
   331     case ULTRA_EXPANDED:
   332       return Qultra_expanded;
   333     }
   334 
   335   emacs_abort ();
   336 }
   337 
   338 static enum haiku_font_width
   339 haikufont_lisp_to_width (Lisp_Object lisp)
   340 {
   341   if (EQ (lisp, Qultra_condensed))
   342     return ULTRA_CONDENSED;
   343   if (EQ (lisp, Qextra_condensed))
   344     return EXTRA_CONDENSED;
   345   if (EQ (lisp, Qcondensed))
   346     return CONDENSED;
   347   if (EQ (lisp, Qsemi_condensed))
   348     return SEMI_CONDENSED;
   349   if (EQ (lisp, Qnormal) || EQ (lisp, Qregular))
   350     return NORMAL_WIDTH;
   351   if (EQ (lisp, Qexpanded))
   352     return EXPANDED;
   353   if (EQ (lisp, Qextra_expanded))
   354     return EXTRA_EXPANDED;
   355   if (EQ (lisp, Qultra_expanded))
   356     return ULTRA_EXPANDED;
   357 
   358   return NORMAL_WIDTH;
   359 }
   360 
   361 static int
   362 haikufont_maybe_handle_special_family (Lisp_Object family,
   363                                        struct haiku_font_pattern *ptn)
   364 {
   365   CHECK_SYMBOL (family);
   366 
   367   if (EQ (family, Qmonospace) || EQ (family, Qfixed) ||
   368       EQ (family, Qdefault))
   369     {
   370       BFont_populate_fixed_family (ptn);
   371       return 1;
   372     }
   373   else if (EQ (family, QSans_Serif))
   374     {
   375       BFont_populate_plain_family (ptn);
   376       return 1;
   377     }
   378   return 0;
   379 }
   380 
   381 static Lisp_Object
   382 haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
   383 {
   384   Lisp_Object entity, extras;
   385 
   386   entity = font_make_entity ();
   387   extras = Qnil;
   388 
   389   ASET (entity, FONT_TYPE_INDEX, Qhaiku);
   390   ASET (entity, FONT_FOUNDRY_INDEX, Qhaiku);
   391   ASET (entity, FONT_FAMILY_INDEX, Qdefault);
   392   ASET (entity, FONT_ADSTYLE_INDEX, Qnil);
   393   ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
   394   ASET (entity, FONT_SIZE_INDEX, make_fixnum (0));
   395   ASET (entity, FONT_AVGWIDTH_INDEX, make_fixnum (0));
   396   ASET (entity, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
   397 
   398   /* FONT_EXTRA_INDEX in a font entity can contain a cons of two
   399      numbers (STYLE . IDX) under the key :indices that tell Emacs how
   400      to open a font.  */
   401   if (ptn->specified & FSPEC_INDICES)
   402     extras = Fcons (Fcons (QCindices,
   403                            Fcons (make_fixnum (ptn->family_index),
   404                                   make_fixnum (ptn->style_index))),
   405                     extras);
   406 
   407   if (ptn->specified & FSPEC_ANTIALIAS)
   408     extras = Fcons (Fcons (QCantialias,
   409                            ptn->use_antialiasing ? Qt : Qnil),
   410                     extras);
   411 
   412   ASET (entity, FONT_EXTRA_INDEX, extras);
   413 
   414   FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, Qnormal);
   415   FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, Qnormal);
   416   FONT_SET_STYLE (entity, FONT_SLANT_INDEX, Qnormal);
   417 
   418   if (ptn->specified & FSPEC_FAMILY)
   419     ASET (entity, FONT_FAMILY_INDEX, intern (ptn->family));
   420   else
   421     ASET (entity, FONT_FAMILY_INDEX, Qdefault);
   422 
   423   if (ptn->specified & FSPEC_STYLE)
   424     ASET (entity, FONT_ADSTYLE_INDEX, intern (ptn->style));
   425   else
   426     {
   427       if (ptn->specified & FSPEC_WEIGHT)
   428         FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
   429                         haikufont_weight_to_lisp (ptn->weight));
   430       if (ptn->specified & FSPEC_SLANT)
   431         FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
   432                         haikufont_slant_to_lisp (ptn->slant));
   433       if (ptn->specified & FSPEC_WIDTH)
   434         FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
   435                         haikufont_width_to_lisp (ptn->width));
   436     }
   437 
   438   if (ptn->specified & FSPEC_SPACING)
   439     ASET (entity, FONT_SPACING_INDEX,
   440           make_fixnum (ptn->mono_spacing_p
   441                        ? FONT_SPACING_MONO
   442                        : FONT_SPACING_PROPORTIONAL));
   443 
   444   return entity;
   445 }
   446 
   447 static void
   448 haikufont_pattern_from_object (struct haiku_font_pattern *pattern,
   449                                Lisp_Object font_object)
   450 {
   451   Lisp_Object val;
   452 
   453   pattern->specified = 0;
   454 
   455   val = AREF (font_object, FONT_FAMILY_INDEX);
   456   if (!NILP (val))
   457     {
   458       pattern->specified |= FSPEC_FAMILY;
   459       strncpy ((char *) &pattern->family,
   460                SSDATA (SYMBOL_NAME (val)),
   461                sizeof pattern->family - 1);
   462       pattern->family[sizeof pattern->family - 1] = '\0';
   463     }
   464 
   465   val = AREF (font_object, FONT_ADSTYLE_INDEX);
   466   if (!NILP (val))
   467     {
   468       pattern->specified |= FSPEC_STYLE;
   469       strncpy ((char *) &pattern->style,
   470                SSDATA (SYMBOL_NAME (val)),
   471                sizeof pattern->style - 1);
   472       pattern->style[sizeof pattern->style - 1] = '\0';
   473     }
   474 
   475   val = FONT_WEIGHT_FOR_FACE (font_object);
   476   if (!NILP (val) && !EQ (val, Qunspecified))
   477     {
   478       pattern->specified |= FSPEC_WEIGHT;
   479       pattern->weight = haikufont_lisp_to_weight (val);
   480     }
   481 
   482   val = FONT_SLANT_FOR_FACE (font_object);
   483   if (!NILP (val) && !EQ (val, Qunspecified))
   484     {
   485       pattern->specified |= FSPEC_SLANT;
   486       pattern->slant = haikufont_lisp_to_slant (val);
   487     }
   488 
   489   val = FONT_WIDTH_FOR_FACE (font_object);
   490   if (!NILP (val) && !EQ (val, Qunspecified))
   491     {
   492       pattern->specified |= FSPEC_WIDTH;
   493       pattern->width = haikufont_lisp_to_width (val);
   494     }
   495 
   496   val = assq_no_quit (QCantialias,
   497                       AREF (font_object, FONT_EXTRA_INDEX));
   498   if (CONSP (val))
   499     {
   500       pattern->specified |= FSPEC_ANTIALIAS;
   501       pattern->use_antialiasing = !NILP (XCDR (val));
   502     }
   503 }
   504 
   505 static void
   506 haikufont_spec_or_entity_to_pattern (Lisp_Object ent, int list_p,
   507                                      struct haiku_font_pattern *ptn)
   508 {
   509   Lisp_Object tem;
   510   ptn->specified = 0;
   511 
   512   tem = AREF (ent, FONT_ADSTYLE_INDEX);
   513   if (!NILP (tem))
   514     {
   515       ptn->specified |= FSPEC_STYLE;
   516       strncpy ((char *) &ptn->style,
   517                SSDATA (SYMBOL_NAME (tem)),
   518                sizeof ptn->style - 1);
   519       ptn->style[sizeof ptn->style - 1] = '\0';
   520     }
   521 
   522   tem = FONT_SLANT_SYMBOLIC (ent);
   523   if (!NILP (tem) && !EQ (tem, Qunspecified))
   524     {
   525       ptn->specified |= FSPEC_SLANT;
   526       ptn->slant = haikufont_lisp_to_slant (tem);
   527     }
   528 
   529   tem = FONT_WEIGHT_SYMBOLIC (ent);
   530   if (!NILP (tem) && !EQ (tem, Qunspecified))
   531     {
   532       ptn->specified |= FSPEC_WEIGHT;
   533       ptn->weight = haikufont_lisp_to_weight (tem);
   534     }
   535 
   536   tem = FONT_WIDTH_SYMBOLIC (ent);
   537   if (!NILP (tem) && !EQ (tem, Qunspecified))
   538     {
   539       ptn->specified |= FSPEC_WIDTH;
   540       ptn->width = haikufont_lisp_to_width (tem);
   541     }
   542 
   543   tem = AREF (ent, FONT_SPACING_INDEX);
   544   if (!NILP (tem) && !EQ (tem, Qunspecified))
   545     {
   546       ptn->specified |= FSPEC_SPACING;
   547       ptn->mono_spacing_p = XFIXNUM (tem) != FONT_SPACING_PROPORTIONAL;
   548     }
   549 
   550   tem = AREF (ent, FONT_FAMILY_INDEX);
   551   if (!NILP (tem) && !EQ (tem, Qunspecified)
   552       && (list_p
   553           && !haikufont_maybe_handle_special_family (tem, ptn)))
   554     {
   555       ptn->specified |= FSPEC_FAMILY;
   556       strncpy ((char *) &ptn->family,
   557                SSDATA (SYMBOL_NAME (tem)),
   558                sizeof ptn->family - 1);
   559       ptn->family[sizeof ptn->family - 1] = '\0';
   560     }
   561 
   562   tem = assq_no_quit (QCscript, AREF (ent, FONT_EXTRA_INDEX));
   563   if (!NILP (tem))
   564     {
   565       tem = assq_no_quit (XCDR (tem), Vscript_representative_chars);
   566 
   567       if (CONSP (tem) && VECTORP (XCDR (tem)))
   568         {
   569           tem = XCDR (tem);
   570 
   571           int count = 0;
   572 
   573           for (int j = 0; j < ASIZE (tem); ++j)
   574             if (TYPE_RANGED_FIXNUMP (uint32_t, AREF (tem, j)))
   575               ++count;
   576 
   577           if (count)
   578             {
   579               ptn->specified |= FSPEC_NEED_ONE_OF;
   580               ptn->need_one_of_len = count;
   581               ptn->need_one_of = xmalloc (count * sizeof *ptn->need_one_of);
   582               count = 0;
   583               for (int j = 0; j < ASIZE (tem); ++j)
   584                 if (TYPE_RANGED_FIXNUMP (uint32_t, AREF (tem, j)))
   585                   {
   586                     ptn->need_one_of[j] = XFIXNAT (AREF (tem, j));
   587                     ++count;
   588                   }
   589             }
   590         }
   591       else if (CONSP (tem) && CONSP (XCDR (tem)))
   592         {
   593           int count = 0;
   594 
   595           for (Lisp_Object it = XCDR (tem); CONSP (it); it = XCDR (it))
   596             if (TYPE_RANGED_FIXNUMP (uint32_t, XCAR (it)))
   597               ++count;
   598 
   599           if (count)
   600             {
   601               ptn->specified |= FSPEC_WANTED;
   602               ptn->want_chars_len = count;
   603               ptn->wanted_chars = xmalloc (count * sizeof *ptn->wanted_chars);
   604               count = 0;
   605 
   606               for (tem = XCDR (tem); CONSP (tem); tem = XCDR (tem))
   607                 if (TYPE_RANGED_FIXNUMP (uint32_t, XCAR (tem)))
   608                   {
   609                     ptn->wanted_chars[count] = XFIXNAT (XCAR (tem));
   610                     ++count;
   611                   }
   612             }
   613         }
   614     }
   615 
   616   tem = assq_no_quit (QClang, AREF (ent, FONT_EXTRA_INDEX));
   617   if (CONSP (tem))
   618     {
   619       tem = XCDR (tem);
   620       if (EQ (tem, Qzh))
   621         {
   622           ptn->specified |= FSPEC_LANGUAGE;
   623           ptn->language = LANGUAGE_CN;
   624         }
   625       else if (EQ (tem, Qko))
   626         {
   627           ptn->specified |= FSPEC_LANGUAGE;
   628           ptn->language = LANGUAGE_KO;
   629         }
   630       else if (EQ (tem, Qjp))
   631         {
   632           ptn->specified |= FSPEC_LANGUAGE;
   633           ptn->language = LANGUAGE_JP;
   634         }
   635     }
   636 
   637   tem = assq_no_quit (QCantialias, AREF (ent, FONT_EXTRA_INDEX));
   638   if (CONSP (tem))
   639     {
   640       ptn->specified |= FSPEC_ANTIALIAS;
   641       ptn->use_antialiasing = !NILP (XCDR (tem));
   642     }
   643 
   644   tem = AREF (ent, FONT_REGISTRY_INDEX);
   645   if (SYMBOLP (tem))
   646     haikufont_apply_registry (ptn, tem);
   647 }
   648 
   649 static void
   650 haikufont_done_with_query_pattern (struct haiku_font_pattern *ptn)
   651 {
   652   if (ptn->specified & FSPEC_WANTED)
   653     xfree (ptn->wanted_chars);
   654 
   655   if (ptn->specified & FSPEC_NEED_ONE_OF)
   656     xfree (ptn->need_one_of);
   657 }
   658 
   659 static Lisp_Object
   660 haikufont_match (struct frame *f, Lisp_Object font_spec)
   661 {
   662   block_input ();
   663   Lisp_Object tem = Qnil;
   664   struct haiku_font_pattern ptn;
   665   haikufont_spec_or_entity_to_pattern (font_spec, 0, &ptn);
   666   ptn.specified &= ~FSPEC_FAMILY;
   667   struct haiku_font_pattern *found = BFont_find (&ptn);
   668   haikufont_done_with_query_pattern (&ptn);
   669   if (found)
   670     {
   671       tem = haikufont_pattern_to_entity (found);
   672       haiku_font_pattern_free (found);
   673     }
   674   unblock_input ();
   675   return !NILP (tem) ? tem : haikufont_get_fallback_entity ();
   676 }
   677 
   678 static Lisp_Object
   679 haikufont_list (struct frame *f, Lisp_Object font_spec)
   680 {
   681   Lisp_Object lst, tem;
   682   struct haiku_font_pattern ptn, *found, *pt;
   683 
   684   lst = Qnil;
   685 
   686   block_input ();
   687   /* Returning irrelevant results on receiving an OTF form will cause
   688      fontset.c to loop over and over, making displaying some
   689      characters very slow.  */
   690   tem = assq_no_quit (QCotf, AREF (font_spec, FONT_EXTRA_INDEX));
   691 
   692   if (CONSP (tem) && !NILP (XCDR (tem)))
   693     {
   694       unblock_input ();
   695       return Qnil;
   696     }
   697 
   698   haikufont_spec_or_entity_to_pattern (font_spec, 1, &ptn);
   699   found = BFont_find (&ptn);
   700   haikufont_done_with_query_pattern (&ptn);
   701   if (found)
   702     {
   703       for (pt = found; pt; pt = pt->next)
   704         lst = Fcons (haikufont_pattern_to_entity (pt), lst);
   705       haiku_font_pattern_free (found);
   706     }
   707   unblock_input ();
   708   return lst;
   709 }
   710 
   711 static void
   712 haiku_bulk_encode (struct haikufont_info *font_info, int block)
   713 {
   714   unsigned short *unichars = xmalloc (0x101 * sizeof (*unichars));
   715   unsigned int i, idx;
   716 
   717   block_input ();
   718 
   719   font_info->glyphs[block] = unichars;
   720   if (!unichars)
   721     emacs_abort ();
   722 
   723   for (idx = block << 8, i = 0; i < 0x100; idx++, i++)
   724     unichars[i] = idx;
   725   unichars[0x100] = 0;
   726 
   727 
   728   /* If the font contains the entire block, just store it.  */
   729   if (!BFont_have_char_block (font_info->be_font,
   730                               unichars[0], unichars[0xff]))
   731     {
   732       for (int i = 0; i < 0x100; ++i)
   733         if (!BFont_have_char_p (font_info->be_font, unichars[i]))
   734           unichars[i] = 0xFFFF;
   735     }
   736 
   737   unblock_input ();
   738 }
   739 
   740 static unsigned int
   741 haikufont_encode_char (struct font *font, int c)
   742 {
   743   struct haikufont_info *font_info = (struct haikufont_info *) font;
   744   unsigned char high = (c & 0xff00) >> 8, low = c & 0x00ff;
   745   unsigned short g;
   746 
   747   if (c > 0xFFFF)
   748     return FONT_INVALID_CODE;
   749 
   750   if (!font_info->glyphs[high])
   751     haiku_bulk_encode (font_info, high);
   752   g = font_info->glyphs[high][low];
   753   return g == 0xFFFF ? FONT_INVALID_CODE : g;
   754 }
   755 
   756 static Lisp_Object
   757 haikufont_open (struct frame *f, Lisp_Object font_entity, int x)
   758 {
   759   struct haikufont_info *font_info;
   760   struct haiku_font_pattern ptn;
   761   struct font *font;
   762   void *be_font;
   763   Lisp_Object font_object, tem, extra, indices, antialias;
   764   int px_size, min_width, max_width;
   765   int avg_width, height, space_width, ascent;
   766   int descent, underline_pos, underline_thickness;
   767 
   768   if (x <= 0)
   769     {
   770       /* Get pixel size from frame instead.  */
   771       tem = get_frame_param (f, Qfontsize);
   772       x = NILP (tem) ? 0 : XFIXNAT (tem);
   773     }
   774 
   775   extra = AREF (font_entity, FONT_EXTRA_INDEX);
   776 
   777   indices = assq_no_quit (QCindices, extra);
   778   antialias = assq_no_quit (QCantialias, extra);
   779 
   780   if (CONSP (indices))
   781     indices = XCDR (indices);
   782 
   783   /* If the font's indices is already available, open the font using
   784      those instead.  */
   785 
   786   if (CONSP (indices) && FIXNUMP (XCAR (indices))
   787       && FIXNUMP (XCDR (indices)))
   788     {
   789       block_input ();
   790       be_font = be_open_font_at_index (XFIXNUM (XCAR (indices)),
   791                                        XFIXNUM (XCDR (indices)), x);
   792       unblock_input ();
   793 
   794       if (!be_font)
   795         return Qnil;
   796     }
   797   else
   798     {
   799       block_input ();
   800       haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn);
   801 
   802       if (BFont_open_pattern (&ptn, &be_font, x))
   803         {
   804           haikufont_done_with_query_pattern (&ptn);
   805           unblock_input ();
   806           return Qnil;
   807         }
   808 
   809       haikufont_done_with_query_pattern (&ptn);
   810       unblock_input ();
   811     }
   812 
   813   block_input ();
   814 
   815   font_object = font_make_object (VECSIZE (struct haikufont_info),
   816                                   font_entity, x);
   817 
   818   ASET (font_object, FONT_TYPE_INDEX, Qhaiku);
   819   font_info = (struct haikufont_info *) XFONT_OBJECT (font_object);
   820   font = (struct font *) font_info;
   821 
   822   if (!font)
   823     {
   824       unblock_input ();
   825       return Qnil;
   826     }
   827 
   828   font_info->be_font = be_font;
   829   font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
   830 
   831   if (CONSP (antialias))
   832     be_set_font_antialiasing (be_font, !NILP (XCDR (antialias)));
   833 
   834   font->pixel_size = 0;
   835   font->driver = &haikufont_driver;
   836   font->encoding_charset = -1;
   837   font->repertory_charset = -1;
   838   font->default_ascent = 0;
   839   font->vertical_centering = 0;
   840   font->baseline_offset = 0;
   841   font->relative_compose = 0;
   842 
   843   font_info->metrics = NULL;
   844   font_info->metrics_nrows = 0;
   845 
   846   BFont_metrics (be_font, &px_size, &min_width,
   847                  &max_width, &avg_width, &height,
   848                  &space_width, &ascent, &descent,
   849                  &underline_pos, &underline_thickness);
   850 
   851   font->pixel_size = px_size;
   852   font->min_width = min_width;
   853   font->max_width = max_width;
   854   font->average_width = avg_width;
   855   font->height = height;
   856   font->space_width = space_width;
   857   font->ascent = ascent;
   858   font->descent = descent;
   859   font->default_ascent = ascent;
   860   font->underline_position = underline_pos;
   861   font->underline_thickness = underline_thickness;
   862 
   863   font->vertical_centering = 0;
   864   font->baseline_offset = 0;
   865   font->relative_compose = 0;
   866 
   867   font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
   868 
   869   unblock_input ();
   870   return font_object;
   871 }
   872 
   873 static void
   874 haikufont_close (struct font *font)
   875 {
   876   struct haikufont_info *info = (struct haikufont_info *) font;
   877   int i;
   878 
   879   if (font_data_structures_may_be_ill_formed ())
   880     return;
   881 
   882   block_input ();
   883   if (info && info->be_font)
   884     BFont_close (info->be_font);
   885 
   886   for (i = 0; i < info->metrics_nrows; i++)
   887     {
   888       if (info->metrics[i])
   889         xfree (info->metrics[i]);
   890     }
   891 
   892   if (info->metrics)
   893     xfree (info->metrics);
   894 
   895   for (i = 0; i < 0x100; ++i)
   896     {
   897       if (info->glyphs[i])
   898         xfree (info->glyphs[i]);
   899     }
   900 
   901   xfree (info->glyphs);
   902   unblock_input ();
   903 }
   904 
   905 static void
   906 haikufont_prepare_face (struct frame *f, struct face *face)
   907 {
   908 
   909 }
   910 
   911 static void
   912 haikufont_glyph_extents (struct font *font, unsigned code,
   913                          struct font_metrics *metrics)
   914 {
   915   struct haikufont_info *info = (struct haikufont_info *) font;
   916 
   917   struct font_metrics *cache;
   918   int row, col;
   919 
   920   row = code / METRICS_NCOLS_PER_ROW;
   921   col = code % METRICS_NCOLS_PER_ROW;
   922   if (row >= info->metrics_nrows)
   923     {
   924       info->metrics =
   925         xrealloc (info->metrics,
   926                   sizeof (struct font_metrics *) * (row + 1));
   927       memset (info->metrics + info->metrics_nrows, 0,
   928               (sizeof (struct font_metrics *)
   929                * (row + 1 - info->metrics_nrows)));
   930       info->metrics_nrows = row + 1;
   931     }
   932 
   933   if (info->metrics[row] == NULL)
   934     {
   935       struct font_metrics *new;
   936       int i;
   937 
   938       new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
   939       for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
   940         METRICS_SET_STATUS (new + i, METRICS_INVALID);
   941       info->metrics[row] = new;
   942     }
   943   cache = info->metrics[row] + col;
   944 
   945   if (METRICS_STATUS (cache) == METRICS_INVALID)
   946     {
   947       unsigned char utf8[MAX_MULTIBYTE_LENGTH];
   948       memset (utf8, 0, MAX_MULTIBYTE_LENGTH);
   949       CHAR_STRING (code, utf8);
   950       int advance, lb, rb;
   951       BFont_char_bounds (info->be_font, (const char *) utf8, &advance, &lb, &rb);
   952 
   953       cache->lbearing = lb;
   954       cache->rbearing = rb;
   955       cache->width = advance;
   956       cache->ascent = font->ascent;
   957       cache->descent = font->descent;
   958     }
   959 
   960   if (metrics)
   961     *metrics = *cache;
   962 }
   963 
   964 static void
   965 haikufont_text_extents (struct font *font, const unsigned int *code,
   966                         int nglyphs, struct font_metrics *metrics)
   967 {
   968   int totalwidth = 0;
   969   memset (metrics, 0, sizeof (struct font_metrics));
   970 
   971   block_input ();
   972   for (int i = 0; i < nglyphs; i++)
   973     {
   974       struct font_metrics m;
   975       haikufont_glyph_extents (font, code[i], &m);
   976       if (metrics)
   977         {
   978           if (totalwidth + m.lbearing < metrics->lbearing)
   979             metrics->lbearing = totalwidth + m.lbearing;
   980           if (totalwidth + m.rbearing > metrics->rbearing)
   981             metrics->rbearing = totalwidth + m.rbearing;
   982           if (m.ascent > metrics->ascent)
   983             metrics->ascent = m.ascent;
   984           if (m.descent > metrics->descent)
   985             metrics->descent = m.descent;
   986         }
   987       totalwidth += m.width;
   988     }
   989 
   990   unblock_input ();
   991 
   992   if (metrics)
   993     metrics->width = totalwidth;
   994 }
   995 
   996 static Lisp_Object
   997 haikufont_shape (Lisp_Object lgstring, Lisp_Object direction)
   998 {
   999   struct haikufont_info *font =
  1000     (struct haikufont_info *) CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
  1001   int *advance, *lb, *rb;
  1002   ptrdiff_t glyph_len, len, i, b_len;
  1003   Lisp_Object tem;
  1004   char *b;
  1005   uint32_t *mb_buf;
  1006 
  1007   glyph_len = LGSTRING_GLYPH_LEN (lgstring);
  1008   for (i = 0; i < glyph_len; ++i)
  1009     {
  1010       tem = LGSTRING_GLYPH (lgstring, i);
  1011 
  1012       if (NILP (tem))
  1013         break;
  1014     }
  1015 
  1016   len = i;
  1017 
  1018   if (INT_MAX / 2 < len)
  1019     memory_full (SIZE_MAX);
  1020 
  1021   block_input ();
  1022 
  1023   b_len = 0;
  1024   b = xmalloc (b_len);
  1025   mb_buf = alloca (len * sizeof *mb_buf);
  1026 
  1027   for (i = b_len; i < len; ++i)
  1028     {
  1029       uint32_t c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
  1030       mb_buf[i] = c;
  1031       unsigned char mb[MAX_MULTIBYTE_LENGTH];
  1032       int slen = CHAR_STRING (c, mb);
  1033 
  1034       b = xrealloc (b, b_len = (b_len + slen));
  1035       if (len == 1)
  1036         b[b_len - slen] = mb[0];
  1037       else
  1038         memcpy (b + b_len - slen, mb, slen);
  1039     }
  1040 
  1041   advance = alloca (len * sizeof *advance);
  1042   lb = alloca (len * sizeof *lb);
  1043   rb = alloca (len * sizeof *rb);
  1044 
  1045   eassert (font->be_font);
  1046   BFont_nchar_bounds (font->be_font, b, advance, lb, rb, len);
  1047   xfree (b);
  1048 
  1049   for (i = 0; i < len; ++i)
  1050     {
  1051       tem = LGSTRING_GLYPH (lgstring, i);
  1052       if (NILP (tem))
  1053         {
  1054           tem = LGLYPH_NEW ();
  1055           LGSTRING_SET_GLYPH (lgstring, i, tem);
  1056         }
  1057 
  1058       LGLYPH_SET_FROM (tem, i);
  1059       LGLYPH_SET_TO (tem, i);
  1060       LGLYPH_SET_CHAR (tem, mb_buf[i]);
  1061       LGLYPH_SET_CODE (tem, mb_buf[i]);
  1062 
  1063       LGLYPH_SET_WIDTH (tem, advance[i]);
  1064       LGLYPH_SET_LBEARING (tem, lb[i]);
  1065       LGLYPH_SET_RBEARING (tem, rb[i]);
  1066       LGLYPH_SET_ASCENT (tem, font->font.ascent);
  1067       LGLYPH_SET_DESCENT (tem, font->font.descent);
  1068     }
  1069 
  1070   unblock_input ();
  1071 
  1072   return make_fixnum (len);
  1073 }
  1074 
  1075 static int
  1076 haikufont_draw (struct glyph_string *s, int from, int to,
  1077                 int x, int y, bool with_background)
  1078 {
  1079   struct frame *f = s->f;
  1080   struct face *face = s->face;
  1081   struct font_info *info = (struct font_info *) s->font;
  1082   unsigned char mb[MAX_MULTIBYTE_LENGTH];
  1083   void *view = FRAME_HAIKU_VIEW (f);
  1084   unsigned long foreground, background;
  1085 
  1086   block_input ();
  1087   prepare_face_for_display (s->f, face);
  1088 
  1089   if (s->hl != DRAW_CURSOR)
  1090     {
  1091       foreground = s->face->foreground;
  1092       background = s->face->background;
  1093     }
  1094   else
  1095     haiku_merge_cursor_foreground (s, &foreground, &background);
  1096 
  1097   /* Presumably the draw lock is already held by
  1098      haiku_draw_glyph_string; */
  1099   if (with_background)
  1100     {
  1101       int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
  1102 
  1103       /* Font's global height and ascent values might be
  1104          preposterously large for some fonts.  We fix here the case
  1105          when those fonts are used for display of glyphless
  1106          characters, because drawing background with font dimensions
  1107          in those cases makes the display illegible.  There's only one
  1108          more call to the draw method with with_background set to
  1109          true, and that's in x_draw_glyph_string_foreground, when
  1110          drawing the cursor, where we have no such heuristics
  1111          available.  FIXME.  */
  1112       if (s->first_glyph->type == GLYPHLESS_GLYPH
  1113           && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
  1114               || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
  1115         height = ascent =
  1116           s->first_glyph->slice.glyphless.lower_yoff
  1117           - s->first_glyph->slice.glyphless.upper_yoff;
  1118 
  1119       haiku_draw_background_rect (s, s->face, x, y - ascent,
  1120                                   s->width, height);
  1121       s->background_filled_p = 1;
  1122     }
  1123 
  1124   BView_SetHighColor (view, foreground);
  1125   BView_MovePenTo (view, x, y);
  1126   BView_SetFont (view, ((struct haikufont_info *) info)->be_font);
  1127 
  1128   if (from == to)
  1129     {
  1130       int len = CHAR_STRING (s->char2b[from], mb);
  1131       BView_DrawString (view, (char *) mb, len);
  1132     }
  1133   else
  1134     {
  1135       ptrdiff_t b_len = 0;
  1136       char *b = alloca ((to - from + 1) * MAX_MULTIBYTE_LENGTH);
  1137 
  1138       for (int idx = from; idx < to; ++idx)
  1139         {
  1140           int len = CHAR_STRING (s->char2b[idx], mb);
  1141           b_len += len;
  1142 
  1143           if (len == 1)
  1144             b[b_len - len] = mb[0];
  1145           else
  1146             memcpy (b + b_len - len, mb, len);
  1147         }
  1148 
  1149       BView_DrawString (view, b, b_len);
  1150     }
  1151 
  1152   unblock_input ();
  1153   return 1;
  1154 }
  1155 
  1156 static Lisp_Object
  1157 haikufont_list_family (struct frame *f)
  1158 {
  1159   Lisp_Object list = Qnil;
  1160   size_t length;
  1161   ptrdiff_t idx;
  1162   haiku_font_family_or_style *styles;
  1163 
  1164   block_input ();
  1165   styles = be_list_font_families (&length);
  1166   unblock_input ();
  1167 
  1168   if (!styles)
  1169     return list;
  1170 
  1171   block_input ();
  1172   for (idx = 0; idx < length; ++idx)
  1173     {
  1174       if (styles[idx][0])
  1175         list = Fcons (intern ((char *) &styles[idx]), list);
  1176     }
  1177 
  1178   free (styles);
  1179   unblock_input ();
  1180 
  1181   return list;
  1182 }
  1183 
  1184 /* List of boolean properties in font names accepted by this font
  1185    driver.  */
  1186 static const char *const haikufont_booleans[] =
  1187   {
  1188     ":antialias",
  1189     NULL,
  1190   };
  1191 
  1192 /* List of non-boolean properties.  Currently empty.  */
  1193 static const char *const haikufont_non_booleans[1];
  1194 
  1195 static void
  1196 haikufont_filter_properties (Lisp_Object font, Lisp_Object alist)
  1197 {
  1198   font_filter_properties (font, alist, haikufont_booleans,
  1199                           haikufont_non_booleans);
  1200 }
  1201 
  1202 struct font_driver const haikufont_driver =
  1203   {
  1204     .type = LISPSYM_INITIALLY (Qhaiku),
  1205     .case_sensitive = true,
  1206     .get_cache = haikufont_get_cache,
  1207     .list = haikufont_list,
  1208     .match = haikufont_match,
  1209     .draw = haikufont_draw,
  1210     .open_font = haikufont_open,
  1211     .close_font = haikufont_close,
  1212     .prepare_face = haikufont_prepare_face,
  1213     .encode_char = haikufont_encode_char,
  1214     .text_extents = haikufont_text_extents,
  1215     .shape = haikufont_shape,
  1216     .list_family = haikufont_list_family,
  1217     .filter_properties = haikufont_filter_properties,
  1218   };
  1219 
  1220 static bool
  1221 haikufont_should_quit_popup (void)
  1222 {
  1223   return !NILP (Vquit_flag);
  1224 }
  1225 
  1226 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
  1227        doc: /* Read a font using a native dialog.
  1228 Return a font spec describing the font chosen by the user.
  1229 
  1230 FRAME is the frame on which to pop up the font chooser.  If omitted or
  1231 nil, it defaults to the selected frame.
  1232 If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
  1233 in the font selection dialog.  */)
  1234   (Lisp_Object frame, Lisp_Object exclude_proportional)
  1235 {
  1236   struct frame *f;
  1237   struct font *font;
  1238   Lisp_Object font_object;
  1239   haiku_font_family_or_style family, style;
  1240   int rc, size, initial_family, initial_style, initial_size;
  1241   struct haiku_font_pattern pattern;
  1242   Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle, lsize;
  1243   bool disable_antialiasing, initial_antialias;
  1244 
  1245   f = decode_window_system_frame (frame);
  1246 
  1247   if (popup_activated_p)
  1248     error ("Trying to use a menu from within a menu-entry");
  1249 
  1250   initial_style = -1;
  1251   initial_family = -1;
  1252   initial_size = -1;
  1253   initial_antialias = true;
  1254 
  1255   font = FRAME_FONT (f);
  1256 
  1257   if (font)
  1258     {
  1259       XSETFONT (font_object, font);
  1260 
  1261       haikufont_pattern_from_object (&pattern, font_object);
  1262       be_find_font_indices (&pattern, &initial_family,
  1263                             &initial_style);
  1264       haikufont_done_with_query_pattern (&pattern);
  1265 
  1266       initial_size = font->pixel_size;
  1267 
  1268       /* This field is safe to access even after
  1269          haikufont_done_with_query_pattern.  */
  1270       if (pattern.specified & FSPEC_ANTIALIAS)
  1271         initial_antialias = pattern.use_antialiasing;
  1272     }
  1273 
  1274   popup_activated_p++;
  1275   unrequest_sigio ();
  1276   rc = be_select_font (process_pending_signals,
  1277                        haikufont_should_quit_popup,
  1278                        &family, &style, &size,
  1279                        !NILP (exclude_proportional),
  1280                        initial_family, initial_style,
  1281                        initial_size, initial_antialias,
  1282                        &disable_antialiasing);
  1283   request_sigio ();
  1284   popup_activated_p--;
  1285 
  1286   if (!rc)
  1287     quit ();
  1288 
  1289   be_font_style_to_flags (style, &pattern);
  1290 
  1291   lfamily = build_string_from_utf8 (family);
  1292   lweight = (pattern.specified & FSPEC_WEIGHT
  1293              ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
  1294   lslant = (pattern.specified & FSPEC_SLANT
  1295             ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
  1296   lwidth = (pattern.specified & FSPEC_WIDTH
  1297             ? haikufont_width_to_lisp (pattern.width) : Qnil);
  1298   ladstyle = (pattern.specified & FSPEC_STYLE
  1299               ? intern (pattern.style) : Qnil);
  1300   lsize = (size >= 0 ? make_fixnum (size) : Qnil);
  1301 
  1302   if (disable_antialiasing)
  1303     return CALLN (Ffont_spec, QCfamily, lfamily,
  1304                   QCweight, lweight, QCslant, lslant,
  1305                   QCwidth, lwidth, QCadstyle, ladstyle,
  1306                   QCsize, lsize, QCantialias, Qnil);
  1307 
  1308   return CALLN (Ffont_spec, QCfamily, lfamily,
  1309                 QCweight, lweight, QCslant, lslant,
  1310                 QCwidth, lwidth, QCadstyle, ladstyle,
  1311                 QCsize, lsize);
  1312 }
  1313 
  1314 DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
  1315        Sfont_get_system_normal_font, 0, 0, 0,
  1316        doc: /* SKIP: real doc in xsettings.c.  */)
  1317   (void)
  1318 {
  1319   Lisp_Object value;
  1320   const char *name, *style;
  1321   struct haiku_font_pattern pattern;
  1322   Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle;
  1323   int size;
  1324 
  1325   if (!be_lock_font_defaults ())
  1326     return Qnil;
  1327 
  1328   name = be_get_font_default (DEFAULT_FAMILY);
  1329   style = be_get_font_default (DEFAULT_STYLE);
  1330   size = be_get_font_size (DEFAULT_FAMILY);
  1331 
  1332   be_font_style_to_flags (style, &pattern);
  1333 
  1334   lfamily = build_string_from_utf8 (name);
  1335   lweight = (pattern.specified & FSPEC_WEIGHT
  1336              ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
  1337   lslant = (pattern.specified & FSPEC_SLANT
  1338             ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
  1339   lwidth = (pattern.specified & FSPEC_WIDTH
  1340             ? haikufont_width_to_lisp (pattern.width) : Qnil);
  1341   ladstyle = (pattern.specified & FSPEC_STYLE
  1342               ? intern (pattern.style) : Qnil);
  1343 
  1344   value = CALLN (Ffont_spec, QCfamily, lfamily,
  1345                  QCweight, lweight, QCslant, lslant,
  1346                  QCwidth, lwidth, QCadstyle, ladstyle,
  1347                  QCsize, make_fixnum (size));
  1348   be_unlock_font_defaults ();
  1349 
  1350   return value;
  1351 }
  1352 
  1353 DEFUN ("font-get-system-font", Ffont_get_system_font,
  1354        Sfont_get_system_font, 0, 0, 0,
  1355        doc: /* SKIP: real doc in xsettings.c.  */)
  1356   (void)
  1357 {
  1358   Lisp_Object value;
  1359   const char *name, *style;
  1360   struct haiku_font_pattern pattern;
  1361   Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle;
  1362   int size;
  1363 
  1364   if (!be_lock_font_defaults ())
  1365     return Qnil;
  1366 
  1367   name = be_get_font_default (FIXED_FAMILY);
  1368   style = be_get_font_default (FIXED_STYLE);
  1369   size = be_get_font_size (FIXED_FAMILY);
  1370 
  1371   be_font_style_to_flags (style, &pattern);
  1372 
  1373   lfamily = build_string_from_utf8 (name);
  1374   lweight = (pattern.specified & FSPEC_WEIGHT
  1375              ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
  1376   lslant = (pattern.specified & FSPEC_SLANT
  1377             ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
  1378   lwidth = (pattern.specified & FSPEC_WIDTH
  1379             ? haikufont_width_to_lisp (pattern.width) : Qnil);
  1380   ladstyle = (pattern.specified & FSPEC_STYLE
  1381               ? intern (pattern.style) : Qnil);
  1382 
  1383   value = CALLN (Ffont_spec, QCfamily, lfamily,
  1384                  QCweight, lweight, QCslant, lslant,
  1385                  QCwidth, lwidth, QCadstyle, ladstyle,
  1386                  QCsize, make_fixnum (size));
  1387   be_unlock_font_defaults ();
  1388 
  1389   return value;
  1390 }
  1391 
  1392 void
  1393 haiku_handle_font_change_event (struct haiku_font_change_event *event,
  1394                                 struct input_event *ie)
  1395 {
  1396   ie->kind = CONFIG_CHANGED_EVENT;
  1397 
  1398   /* This is the name of the display.  */
  1399   ie->frame_or_window = XCAR (x_display_list->name_list_element);
  1400 
  1401   /* And this is the font that changed.  */
  1402   ie->arg = (event->what == FIXED_FAMILY
  1403              ? Qmonospace_font_name : Qfont_name);
  1404 }
  1405 
  1406 static void
  1407 syms_of_haikufont_for_pdumper (void)
  1408 {
  1409   register_font_driver (&haikufont_driver, NULL);
  1410 }
  1411 
  1412 void
  1413 syms_of_haikufont (void)
  1414 {
  1415   DEFSYM (QSans_Serif, "Sans Serif");
  1416   DEFSYM (Qfontsize, "fontsize");
  1417   DEFSYM (Qfixed, "fixed");
  1418   DEFSYM (Qplain, "plain");
  1419   DEFSYM (Qultra_light, "ultra-light");
  1420   DEFSYM (Qthin, "thin");
  1421   DEFSYM (Qreverse_italic, "reverse-italic");
  1422   DEFSYM (Qreverse_oblique, "reverse-oblique");
  1423   DEFSYM (Qmonospace, "monospace");
  1424   DEFSYM (Qultra_condensed, "ultra-condensed");
  1425   DEFSYM (Qextra_condensed, "extra-condensed");
  1426   DEFSYM (Qcondensed, "condensed");
  1427   DEFSYM (Qsemi_condensed, "semi-condensed");
  1428   DEFSYM (Qsemi_expanded, "semi-expanded");
  1429   DEFSYM (Qexpanded, "expanded");
  1430   DEFSYM (Qextra_expanded, "extra-expanded");
  1431   DEFSYM (Qultra_expanded, "ultra-expanded");
  1432   DEFSYM (Qregular, "regular");
  1433   DEFSYM (Qzh, "zh");
  1434   DEFSYM (Qko, "ko");
  1435   DEFSYM (Qjp, "jp");
  1436 
  1437   DEFSYM (QCindices, ":indices");
  1438 
  1439   DEFSYM (Qmonospace_font_name, "monospace-font-name");
  1440   DEFSYM (Qfont_name, "font-name");
  1441   DEFSYM (Qdynamic_setting, "dynamic-setting");
  1442 
  1443   DEFVAR_BOOL ("font-use-system-font", use_system_font,
  1444     doc: /* SKIP: real doc in xsettings.c.  */);
  1445   use_system_font = false;
  1446 
  1447 #ifdef USE_BE_CAIRO
  1448   Fput (Qhaiku, Qfont_driver_superseded_by, Qftcr);
  1449 #endif
  1450   pdumper_do_now_and_after_load (syms_of_haikufont_for_pdumper);
  1451 
  1452   font_cache = list (Qnil);
  1453   staticpro (&font_cache);
  1454 
  1455   defsubr (&Sx_select_font);
  1456   defsubr (&Sfont_get_system_normal_font);
  1457   defsubr (&Sfont_get_system_font);
  1458 
  1459   be_init_font_data ();
  1460 
  1461   /* This tells loadup to load dynamic-setting.el, which handles
  1462      config-changed events.  */
  1463   Fprovide (Qdynamic_setting, Qnil);
  1464 }

/* [<][>][^][v][top][bottom][index][help] */