Subject: Re: bug#73730: 31.0.50; Support for color fonts on MS-Windows

From: Eli Zaretskii <[email-masked]>
Date: Wed, 16 Oct 2024 14:32:47 +0300

> Cc: [email-masked]
> Date: Wed, 16 Oct 2024 14:01:36 +0300
> From: Eli Zaretskii <[email-masked]>
> 
> > Date: Wed, 16 Oct 2024 00:18:20 +0200
> > Cc: [email-masked]
> > From: Cecilio Pardo <[email-masked]>
> > 
> > The attached patch works without a new font driver.
> 
> Thanks a lot for working on this!

And here's the first bug report after applying this patch:

  emacs -Q
  M-: (w32-find-non-USB-fonts) RET

This pops up the Emacs Abort dialog.  The backtrace and some
additional information are below.  The error from
GetGdiCompatibleGlyphMetrics (0x80070057) seems to be E_INVALIDARG.

Perhaps if w32_dwrite_text_extents fails, it should not abort, but
instead fall back on the old code?

If you cannot reproduce this (maybe it depends on what fonts are
installed), feel free to ask me to provide more information or try
some solutions.  In case it matters, this is a 32-bit build configured
as --with-wide-int --without-native-compilation.

  Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
  0x76611813 in KERNELBASE!DebugBreak () from C:\WINDOWS\SysWOW64\KernelBase.dll
  (gdb) bt
  #0  0x76611813 in KERNELBASE!DebugBreak ()
     from C:\WINDOWS\SysWOW64\KernelBase.dll
  #1  0x012f47e1 in emacs_abort () at w32fns.c:11570
  #2  0x013221ba in verify_hr (hr=-2147024809,
      msg=0x18cbe58 <IID_IDWriteFactory+48> "Failed to GetGdiCompatibleGlyphMetrics") at w32dwrite.c:504
  #3  0x01322430 in text_extents_internal (dwrite_font_face=0x9600720,
      font_size=0, code=0xbfc6c0, nglyphs=1, metrics=0xbfc6b6) at w32dwrite.c:588
  #4  0x013226d4 in w32_dwrite_text_extents (font=0xbf3e9f0, code=0xbfc6c0,
      nglyphs=1, metrics=0xbfc6b6) at w32dwrite.c:654
  #5  0x012fb29a in w32font_text_extents (font=0xbf3e9f0, code=0xbfc6c0,
      nglyphs=1, metrics=0xbfc6b6) at w32font.c:464
  #6  0x01229249 in Ffont_get_glyphs (font_object=XIL(0xa00000000bf3e9f0),
      from=make_fixnum(0), to=make_fixnum(3), object=XIL(0xa00000000bc5cd60))
      at font.c:5454
  #7  0x011f1176 in funcall_subr (subr=0x187cb40 <Sfont_get_glyphs>, numargs=4,
      args=0xa2eb2a0) at eval.c:3144
  #8  0x0125eeb2 in exec_byte_code (fun=XIL(0xa00000000bd9e450),
      args_template=257, nargs=1, args=0xbfcf70) at bytecode.c:813
  #9  0x011f198b in funcall_lambda (fun=XIL(0xa00000000bd9e450), nargs=1,
      arg_vector=0xbfcf68) at eval.c:3229
  #10 0x011f0a51 in funcall_general (fun=XIL(0xa00000000bd9e450), numargs=1,
      args=0xbfcf68) at eval.c:3021
  #11 0x011f0d7a in Ffuncall (nargs=2, args=0xbfcf60) at eval.c:3070
  #12 0x01206ebc in mapcar1 (leni=76, vals=0x0, fn=XIL(0xa00000000bd9e450),
      seq=XIL(0xc000000000f3ec30)) at fns.c:3370
  #13 0x01207af8 in Fmapc (function=XIL(0xa00000000bd9e450),
      sequence=XIL(0xc000000000f3ec30)) at fns.c:3507
  #14 0x011f10c7 in funcall_subr (subr=0x187bb40 <Smapc>, numargs=2,
      args=0xa2eb1f0) at eval.c:3140
  #15 0x0125eeb2 in exec_byte_code (fun=XIL(0xa000000009d8ab78),
      args_template=0, nargs=0, args=0xa2eb200) at bytecode.c:813
  #16 0x011f198b in funcall_lambda (fun=XIL(0xa000000009d8aa58), nargs=0,
      arg_vector=0xbfd6d0) at eval.c:3229
  #17 0x011f17a6 in apply_lambda (fun=XIL(0xa000000009d8aa58), args=XIL(0),
      count=480) at eval.c:3192
  #18 0x011ef553 in eval_sub (form=XIL(0xc000000000efa680)) at eval.c:2622
  #19 0x011ee62c in Feval (form=XIL(0xc000000000efa680), lexical=XIL(0x30))
      at eval.c:2439
  #20 0x011f10c7 in funcall_subr (subr=0x187a1c0 <Seval>, numargs=2,
      args=0xa2eb1a0) at eval.c:3140
  #21 0x0125eeb2 in exec_byte_code (fun=XIL(0xa0000000098cdce8),
      args_template=513, nargs=2, args=0xa2eb2f8) at bytecode.c:813
  #22 0x011f198b in funcall_lambda (fun=XIL(0xa00000000bd346a0), nargs=0,
      arg_vector=0xbfe040) at eval.c:3229
  #23 0x011f0a51 in funcall_general (fun=XIL(0xa00000000bd346a0), numargs=0,
      args=0xbfe040) at eval.c:3021
  #24 0x011f0d7a in Ffuncall (nargs=1, args=0xbfe038) at eval.c:3070
  #25 0x011e67ba in call0 (fn=XIL(0xa00000000bd346a0)) at lisp.h:3528
  #26 0x011eb1e1 in Fhandler_bind_1 (nargs=3, args=0xa2eb128) at eval.c:1463
  #27 0x011f1523 in funcall_subr (subr=0x187a080 <Shandler_bind_1>, numargs=3,
      args=0xa2eb128) at eval.c:3161
  #28 0x0125eeb2 in exec_byte_code (fun=XIL(0xa00000000997d720),
      args_template=1025, nargs=4, args=0xbfe9e0) at bytecode.c:813
  #29 0x011f198b in funcall_lambda (fun=XIL(0xa00000000997d720), nargs=4,
      arg_vector=0xbfe9c0) at eval.c:3229
  #30 0x011f0a51 in funcall_general (fun=XIL(0xa00000000997d720), numargs=4,
      args=0xbfe9c0) at eval.c:3021
  #31 0x011f0d7a in Ffuncall (nargs=5, args=0xbfe9b8) at eval.c:3070
  #32 0x011e1c1a in Ffuncall_interactively (nargs=5, args=0xbfe9b8)
      at callint.c:250
  #33 0x011f1523 in funcall_subr (subr=0x18798c0 <Sfuncall_interactively>,
      numargs=5, args=0xbfe9b8) at eval.c:3161
  #34 0x011f09ea in funcall_general (fun=XIL(0xa0000000018798c0), numargs=5,
      args=0xbfe9b8) at eval.c:3017
  #35 0x011f0d7a in Ffuncall (nargs=6, args=0xbfe9b0) at eval.c:3070
  #36 0x011efedd in Fapply (nargs=3, args=0xbfebd8) at eval.c:2742
  #37 0x011e226a in Fcall_interactively (function=XIL(0x7fcb530),
      record_flag=XIL(0), keys=XIL(0xa000000009ef2300)) at callint.c:342
  #38 0x011f110f in funcall_subr (subr=0x1879900 <Scall_interactively>,
      numargs=3, args=0xa2eb078) at eval.c:3142
  #39 0x0125eeb2 in exec_byte_code (fun=XIL(0xa000000009f0ad40),
      args_template=1025, nargs=1, args=0xbff7a0) at bytecode.c:813
  #40 0x011f198b in funcall_lambda (fun=XIL(0xa000000009f0ad40), nargs=1,
      arg_vector=0xbff798) at eval.c:3229
  #41 0x011f0a51 in funcall_general (fun=XIL(0xa000000009f0ad40), numargs=1,
      args=0xbff798) at eval.c:3021
  #42 0x011f0d7a in Ffuncall (nargs=2, args=0xbff790) at eval.c:3070
  #43 0x010f681d in command_loop_1 () at keyboard.c:1545
  #44 0x011eba71 in internal_condition_case (bfun=0x10f5c2d <command_loop_1>,
      handlers=XIL(0x90), hfun=0x10f4c86 <cmd_error>) at eval.c:1598
  #45 0x010f5692 in command_loop_2 (handlers=XIL(0x90)) at keyboard.c:1163
  #46 0x011eabee in internal_catch (tag=XIL(0x12750),
      func=0x10f565b <command_loop_2>, arg=XIL(0x90)) at eval.c:1277
  #47 0x010f55fd in command_loop () at keyboard.c:1141
  #48 0x010f46e6 in recursive_edit_1 () at keyboard.c:749
  #49 0x010f4984 in Frecursive_edit () at keyboard.c:832
  #50 0x010efaa5 in main (argc=2, argv=0x7c72570) at emacs.c:2624

  Lisp Backtrace:
  "font-get-glyphs" (0xa2eb2a0)
  0xbd9e450 PVEC_CLOSURE
  "mapc" (0xa2eb1f0)
  "w32-find-non-USB-fonts" (0xbfd6d0)
  "eval" (0xa2eb1a0)
  0xbd34678 PVEC_CLOSURE
  0xbd346a0 PVEC_CLOSURE
  "handler-bind-1" (0xa2eb128)
  "eval-expression" (0xbfe9c0)
  "funcall-interactively" (0xbfe9b8)
  "call-interactively" (0xa2eb078)
  "command-execute" (0xbff798)
  (gdb) fr 6
  #6  0x01229249 in Ffont_get_glyphs (font_object=XIL(0xa00000000bf3e9f0),
      from=make_fixnum(0), to=make_fixnum(3), object=XIL(0xa00000000bc5cd60))
      at font.c:5454
  5454          font->driver->text_extents (font, &code, 1, &metrics);
  (gdb) pp font_object
  #<font-object "-outline-Sans Serif Collection-regular-normal-normal-sans-*-*-*-*-p-*-iso10646-1">
  (gdb) fr 3
  #3  0x01322430 in text_extents_internal (dwrite_font_face=0x9600720,
      font_size=0, code=0xbfc6c0, nglyphs=1, metrics=0xbfc6b6) at w32dwrite.c:588
  588       verify_hr (hr, "Failed to GetGdiCompatibleGlyphMetrics");
  (gdb) p/x hr
  $1 = 0x80070057
  (gdb) fr 5
  #5  0x012fb29a in w32font_text_extents (font=0xbf3e9f0, code=0xbfc6c0,
      nglyphs=1, metrics=0xbfc6b6) at w32font.c:464
  464           w32_dwrite_text_extents (font, code, nglyphs, metrics);
  (gdb) p *w32_font
  $2 = {
    font = {
      header = {
	size = 1661034513
      },
      props = {XIL(0x9b40), XIL(0xe910), XIL(0xa5622a0), XIL(0x103b0),
	XIL(0xb010), make_fixnum(20544), make_fixnum(25632), make_fixnum(25664),
	make_fixnum(0), XIL(0), make_fixnum(0), XIL(0), XIL(0xc00000000be75600),
	XIL(0), XIL(0x800000000bce6cf0), XIL(0x800000000bce6ce0), XIL(0)},
      min_width = 11,
      max_width = 76,
      pixel_size = 0,
      height = 39,
      space_width = 11,
      average_width = 11,
      ascent = 26,
      descent = 13,
      underline_thickness = 1,
      underline_position = 2,
      vertical_centering = false,
      baseline_offset = 0,
      relative_compose = 0,
      default_ascent = 26,
      encoding_charset = -1,
      repertory_charset = -1,
      driver = 0x19c78a0 <harfbuzz_font_driver>
    },
    metrics = {
      tmHeight = 39,
      tmAscent = 26,
      tmDescent = 13,
      tmInternalLeading = 23,
      tmExternalLeading = 0,
      tmAveCharWidth = 11,
      tmMaxCharWidth = 76,
      tmWeight = 400,
      tmOverhang = 0,
      tmDigitizedAspectX = 96,
      tmDigitizedAspectY = 96,
      tmFirstChar = 0 L'\000',
      tmLastChar = 65071 L'\xfe2f',
      tmDefaultChar = 1 L'\001',
      tmBreakChar = 2 L'\002',
      tmItalic = 0 '\000',
      tmUnderlined = 0 '\000',
      tmStruckOut = 0 '\000',
      tmPitchAndFamily = 39 '\'',
      tmCharSet = 0 '\000'
    },
    glyph_idx = 16,
    cached_metrics = 0x0,
    n_cache_blocks = 0,
    hfont = 0x2d0a1e66
  }
  (gdb)