Mercurial > hg > xemacs-beta
annotate src/objects-xlike-inc.c @ 4952:19a72041c5ed
Mule-izing, various fixes related to char * arguments
-------------------- ChangeLog entries follow: --------------------
modules/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* postgresql/postgresql.c:
* postgresql/postgresql.c (CHECK_LIVE_CONNECTION):
* postgresql/postgresql.c (print_pgresult):
* postgresql/postgresql.c (Fpq_conn_defaults):
* postgresql/postgresql.c (Fpq_connectdb):
* postgresql/postgresql.c (Fpq_connect_start):
* postgresql/postgresql.c (Fpq_result_status):
* postgresql/postgresql.c (Fpq_res_status):
Mule-ize large parts of it.
2010-01-26 Ben Wing <ben@xemacs.org>
* ldap/eldap.c (print_ldap):
* ldap/eldap.c (allocate_ldap):
Use write_ascstring().
src/ChangeLog addition:
2010-01-26 Ben Wing <ben@xemacs.org>
* alloc.c:
* alloc.c (build_ascstring):
* alloc.c (build_msg_cistring):
* alloc.c (staticpro_1):
* alloc.c (staticpro_name):
* alloc.c (staticpro_nodump_1):
* alloc.c (staticpro_nodump_name):
* alloc.c (unstaticpro_nodump_1):
* alloc.c (mcpro_1):
* alloc.c (mcpro_name):
* alloc.c (object_memory_usage_stats):
* alloc.c (common_init_alloc_early):
* alloc.c (init_alloc_once_early):
* buffer.c (print_buffer):
* buffer.c (vars_of_buffer):
* buffer.c (common_init_complex_vars_of_buffer):
* buffer.c (init_initial_directory):
* bytecode.c (invalid_byte_code):
* bytecode.c (print_compiled_function):
* bytecode.c (mark_compiled_function):
* chartab.c (print_table_entry):
* chartab.c (print_char_table):
* config.h.in:
* console-gtk.c:
* console-gtk.c (gtk_device_to_console_connection):
* console-gtk.c (gtk_semi_canonicalize_console_connection):
* console-gtk.c (gtk_canonicalize_console_connection):
* console-gtk.c (gtk_semi_canonicalize_device_connection):
* console-gtk.c (gtk_canonicalize_device_connection):
* console-stream.c (stream_init_frame_1):
* console-stream.c (vars_of_console_stream):
* console-stream.c (init_console_stream):
* console-x.c (x_semi_canonicalize_console_connection):
* console-x.c (x_semi_canonicalize_device_connection):
* console-x.c (x_canonicalize_device_connection):
* console-x.h:
* data.c (eq_with_ebola_notice):
* data.c (Fsubr_interactive):
* data.c (Fnumber_to_string):
* data.c (digit_to_number):
* device-gtk.c (gtk_init_device):
* device-msw.c (print_devmode):
* device-x.c (x_event_name):
* dialog-msw.c (handle_directory_dialog_box):
* dialog-msw.c (handle_file_dialog_box):
* dialog-msw.c (vars_of_dialog_mswindows):
* doc.c (weird_doc):
* doc.c (Fsnarf_documentation):
* doc.c (vars_of_doc):
* dumper.c (pdump):
* dynarr.c:
* dynarr.c (Dynarr_realloc):
* editfns.c (Fuser_real_login_name):
* editfns.c (get_home_directory):
* elhash.c (print_hash_table_data):
* elhash.c (print_hash_table):
* emacs.c (main_1):
* emacs.c (vars_of_emacs):
* emodules.c:
* emodules.c (_emodules_list):
* emodules.c (Fload_module):
* emodules.c (Funload_module):
* emodules.c (Flist_modules):
* emodules.c (find_make_module):
* emodules.c (attempt_module_delete):
* emodules.c (emodules_load):
* emodules.c (emodules_doc_subr):
* emodules.c (emodules_doc_sym):
* emodules.c (syms_of_module):
* emodules.c (vars_of_module):
* emodules.h:
* eval.c (print_subr):
* eval.c (signal_call_debugger):
* eval.c (build_error_data):
* eval.c (signal_error):
* eval.c (maybe_signal_error):
* eval.c (signal_continuable_error):
* eval.c (maybe_signal_continuable_error):
* eval.c (signal_error_2):
* eval.c (maybe_signal_error_2):
* eval.c (signal_continuable_error_2):
* eval.c (maybe_signal_continuable_error_2):
* eval.c (signal_ferror):
* eval.c (maybe_signal_ferror):
* eval.c (signal_continuable_ferror):
* eval.c (maybe_signal_continuable_ferror):
* eval.c (signal_ferror_with_frob):
* eval.c (maybe_signal_ferror_with_frob):
* eval.c (signal_continuable_ferror_with_frob):
* eval.c (maybe_signal_continuable_ferror_with_frob):
* eval.c (syntax_error):
* eval.c (syntax_error_2):
* eval.c (maybe_syntax_error):
* eval.c (sferror):
* eval.c (sferror_2):
* eval.c (maybe_sferror):
* eval.c (invalid_argument):
* eval.c (invalid_argument_2):
* eval.c (maybe_invalid_argument):
* eval.c (invalid_constant):
* eval.c (invalid_constant_2):
* eval.c (maybe_invalid_constant):
* eval.c (invalid_operation):
* eval.c (invalid_operation_2):
* eval.c (maybe_invalid_operation):
* eval.c (invalid_change):
* eval.c (invalid_change_2):
* eval.c (maybe_invalid_change):
* eval.c (invalid_state):
* eval.c (invalid_state_2):
* eval.c (maybe_invalid_state):
* eval.c (wtaerror):
* eval.c (stack_overflow):
* eval.c (out_of_memory):
* eval.c (print_multiple_value):
* eval.c (issue_call_trapping_problems_warning):
* eval.c (backtrace_specials):
* eval.c (backtrace_unevalled_args):
* eval.c (Fbacktrace):
* eval.c (warn_when_safe):
* event-Xt.c (modwarn):
* event-Xt.c (modbarf):
* event-Xt.c (check_modifier):
* event-Xt.c (store_modifier):
* event-Xt.c (emacs_Xt_format_magic_event):
* event-Xt.c (describe_event):
* event-gtk.c (dragndrop_data_received):
* event-gtk.c (store_modifier):
* event-gtk.c (gtk_reset_modifier_mapping):
* event-msw.c (dde_eval_string):
* event-msw.c (Fdde_alloc_advise_item):
* event-msw.c (mswindows_dde_callback):
* event-msw.c (FROB):
* event-msw.c (emacs_mswindows_format_magic_event):
* event-stream.c (external_debugging_print_event):
* event-stream.c (execute_help_form):
* event-stream.c (vars_of_event_stream):
* events.c (print_event_1):
* events.c (print_event):
* events.c (event_equal):
* extents.c (print_extent_1):
* extents.c (print_extent):
* extents.c (vars_of_extents):
* faces.c (print_face):
* faces.c (complex_vars_of_faces):
* file-coding.c:
* file-coding.c (print_coding_system):
* file-coding.c (print_coding_system_in_print_method):
* file-coding.c (default_query_method):
* file-coding.c (find_coding_system):
* file-coding.c (make_coding_system_1):
* file-coding.c (chain_print):
* file-coding.c (undecided_print):
* file-coding.c (gzip_print):
* file-coding.c (vars_of_file_coding):
* file-coding.c (complex_vars_of_file_coding):
* fileio.c:
* fileio.c (report_file_type_error):
* fileio.c (report_error_with_errno):
* fileio.c (report_file_error):
* fileio.c (barf_or_query_if_file_exists):
* fileio.c (vars_of_fileio):
* floatfns.c (matherr):
* fns.c (print_bit_vector):
* fns.c (Fmapconcat):
* fns.c (add_suffix_to_symbol):
* fns.c (add_prefix_to_symbol):
* frame-gtk.c:
* frame-gtk.c (Fgtk_window_id):
* frame-x.c (def):
* frame-x.c (x_cde_transfer_callback):
* frame.c:
* frame.c (Fmake_frame):
* gc.c (show_gc_cursor_and_message):
* gc.c (vars_of_gc):
* glyphs-eimage.c (png_instantiate):
* glyphs-eimage.c (tiff_instantiate):
* glyphs-gtk.c (gtk_print_image_instance):
* glyphs-msw.c (mswindows_print_image_instance):
* glyphs-x.c (x_print_image_instance):
* glyphs-x.c (update_widget_face):
* glyphs.c (make_string_from_file):
* glyphs.c (print_image_instance):
* glyphs.c (signal_image_error):
* glyphs.c (signal_image_error_2):
* glyphs.c (signal_double_image_error):
* glyphs.c (signal_double_image_error_2):
* glyphs.c (xbm_mask_file_munging):
* glyphs.c (pixmap_to_lisp_data):
* glyphs.h:
* gui.c (gui_item_display_flush_left):
* hpplay.c (player_error_internal):
* hpplay.c (myHandler):
* intl-win32.c:
* intl-win32.c (langcode_to_lang):
* intl-win32.c (sublangcode_to_lang):
* intl-win32.c (Fmswindows_get_locale_info):
* intl-win32.c (lcid_to_locale_mule_or_no):
* intl-win32.c (mswindows_multibyte_to_unicode_print):
* intl-win32.c (complex_vars_of_intl_win32):
* keymap.c:
* keymap.c (print_keymap):
* keymap.c (ensure_meta_prefix_char_keymapp):
* keymap.c (Fkey_description):
* keymap.c (Ftext_char_description):
* lisp.h:
* lisp.h (struct):
* lisp.h (DECLARE_INLINE_HEADER):
* lread.c (Fload_internal):
* lread.c (locate_file):
* lread.c (read_escape):
* lread.c (read_raw_string):
* lread.c (read1):
* lread.c (read_list):
* lread.c (read_compiled_function):
* lread.c (init_lread):
* lrecord.h:
* marker.c (print_marker):
* marker.c (marker_equal):
* menubar-msw.c (displayable_menu_item):
* menubar-x.c (command_builder_operate_menu_accelerator):
* menubar.c (vars_of_menubar):
* minibuf.c (reinit_complex_vars_of_minibuf):
* minibuf.c (complex_vars_of_minibuf):
* mule-charset.c (Fmake_charset):
* mule-charset.c (complex_vars_of_mule_charset):
* mule-coding.c (iso2022_print):
* mule-coding.c (fixed_width_query):
* number.c (bignum_print):
* number.c (ratio_print):
* number.c (bigfloat_print):
* number.c (bigfloat_finalize):
* objects-msw.c:
* objects-msw.c (mswindows_color_to_string):
* objects-msw.c (mswindows_color_list):
* objects-tty.c:
* objects-tty.c (tty_font_list):
* objects-tty.c (tty_find_charset_font):
* objects-xlike-inc.c (xft_find_charset_font):
* objects-xlike-inc.c (endif):
* print.c:
* print.c (write_istring):
* print.c (write_ascstring):
* print.c (Fterpri):
* print.c (Fprint):
* print.c (print_error_message):
* print.c (print_vector_internal):
* print.c (print_cons):
* print.c (print_string):
* print.c (printing_unreadable_object):
* print.c (print_internal):
* print.c (print_float):
* print.c (print_symbol):
* process-nt.c (mswindows_report_winsock_error):
* process-nt.c (nt_canonicalize_host_name):
* process-unix.c (unix_canonicalize_host_name):
* process.c (print_process):
* process.c (report_process_error):
* process.c (report_network_error):
* process.c (make_process_internal):
* process.c (Fstart_process_internal):
* process.c (status_message):
* process.c (putenv_internal):
* process.c (vars_of_process):
* process.h:
* profile.c (vars_of_profile):
* rangetab.c (print_range_table):
* realpath.c (vars_of_realpath):
* redisplay.c (vars_of_redisplay):
* search.c (wordify):
* search.c (Freplace_match):
* sheap.c (sheap_adjust_h):
* sound.c (report_sound_error):
* sound.c (Fplay_sound_file):
* specifier.c (print_specifier):
* symbols.c (Fsubr_name):
* symbols.c (do_symval_forwarding):
* symbols.c (set_default_buffer_slot_variable):
* symbols.c (set_default_console_slot_variable):
* symbols.c (store_symval_forwarding):
* symbols.c (default_value):
* symbols.c (defsymbol_massage_name_1):
* symbols.c (defsymbol_massage_name_nodump):
* symbols.c (defsymbol_massage_name):
* symbols.c (defsymbol_massage_multiword_predicate_nodump):
* symbols.c (defsymbol_massage_multiword_predicate):
* symbols.c (defsymbol_nodump):
* symbols.c (defsymbol):
* symbols.c (defkeyword):
* symbols.c (defkeyword_massage_name):
* symbols.c (check_module_subr):
* symbols.c (deferror_1):
* symbols.c (deferror):
* symbols.c (deferror_massage_name):
* symbols.c (deferror_massage_name_and_message):
* symbols.c (defvar_magic):
* symeval.h:
* symeval.h (DEFVAR_SYMVAL_FWD):
* sysdep.c:
* sysdep.c (init_system_name):
* sysdll.c:
* sysdll.c (MAYBE_PREPEND_UNDERSCORE):
* sysdll.c (dll_function):
* sysdll.c (dll_variable):
* sysdll.c (dll_error):
* sysdll.c (dll_open):
* sysdll.c (dll_close):
* sysdll.c (image_for_address):
* sysdll.c (my_find_image):
* sysdll.c (search_linked_libs):
* sysdll.h:
* sysfile.h:
* sysfile.h (DEFAULT_DIRECTORY_FALLBACK):
* syswindows.h:
* tests.c (DFC_CHECK_LENGTH):
* tests.c (DFC_CHECK_CONTENT):
* tests.c (Ftest_hash_tables):
* text.c (vars_of_text):
* text.h:
* tooltalk.c (tt_opnum_string):
* tooltalk.c (tt_message_arg_ival_string):
* tooltalk.c (Ftooltalk_default_procid):
* tooltalk.c (Ftooltalk_default_session):
* tooltalk.c (init_tooltalk):
* tooltalk.c (vars_of_tooltalk):
* ui-gtk.c (Fdll_load):
* ui-gtk.c (type_to_marshaller_type):
* ui-gtk.c (Fgtk_import_function_internal):
* ui-gtk.c (emacs_gtk_object_printer):
* ui-gtk.c (emacs_gtk_boxed_printer):
* unicode.c (unicode_to_ichar):
* unicode.c (unicode_print):
* unicode.c (unicode_query):
* unicode.c (vars_of_unicode):
* unicode.c (complex_vars_of_unicode):
* win32.c:
* win32.c (mswindows_report_process_error):
* window.c (print_window):
* xemacs.def.in.in:
BASIC IDEA: Further fixing up uses of char * and CIbyte *
to reflect their actual semantics; Mule-izing some code;
redoing of the not-yet-working code to handle message translation.
Clean up code to handle message-translation (not yet working).
Create separate versions of build_msg_string() for working with
Ibyte *, CIbyte *, and Ascbyte * arguments. Assert that Ascbyte *
arguments are pure-ASCII. Make build_msg_string() be the same
as build_msg_ascstring(). Create same three versions of GETTEXT()
and DEFER_GETTEXT(). Also create build_defer_string() and
variants for the equivalent of DEFER_GETTEXT() when building a
string. Remove old CGETTEXT(). Clean up code where GETTEXT(),
DEFER_GETTEXT(), build_msg_string(), etc. was being called and
introduce some new calls to build_msg_string(), etc. Remove
GETTEXT() from calls to weird_doc() -- we assume that the
message snarfer knows about weird_doc(). Remove uses of
DEFER_GETTEXT() from error messages in sysdep.c and instead use
special comments /* @@@begin-snarf@@@ */ and /* @@@end-snarf@@@ */
that the message snarfer presumably knows about.
Create build_ascstring() and use it in many instances in place
of build_string(). The purpose of having Ascbyte * variants is
to make the code more self-documenting in terms of what sort of
semantics is expected for char * strings. In fact in the process
of looking for uses of build_string(), much improperly Mule-ized
was discovered.
Mule-ize a lot of code as described in previous paragraph,
e.g. in sysdep.c.
Make the error functions take Ascbyte * strings and fix up a
couple of places where non-pure-ASCII strings were being passed in
(file-coding.c, mule-coding.c, unicode.c). (It's debatable whether
we really need to make the error functions work this way. It
helps catch places where code is written in a way that message
translation won't work, but we may well never implement message
translation.)
Make staticpro() and friends take Ascbyte * strings instead of
raw char * strings. Create a const_Ascbyte_ptr dynarr type
to describe what's held by staticpro_names[] and friends,
create pdump descriptions for const_Ascbyte_ptr dynarrs, and
use them in place of specially-crafted staticpro descriptions.
Mule-ize certain other functions (e.g. x_event_name) by correcting
raw use of char * to Ascbyte *, Rawbyte * or another such type,
and raw use of char[] buffers to another type (usually Ascbyte[]).
Change many uses of write_c_string() to write_msg_string(),
write_ascstring(), etc.
Mule-ize emodules.c, emodules.h, sysdll.h.
Fix some un-Mule-ized code in intl-win32.c.
A comment in event-Xt.c and the limitations of the message
snarfer (make-msgfile or whatever) is presumably incorrect --
it should be smart enough to handle function calls spread over
more than one line. Clean up code in event-Xt.c that was
written awkwardly for this reason.
In config.h.in, instead of NEED_ERROR_CHECK_TYPES_INLINES,
create a more general XEMACS_DEFS_NEEDS_INLINE_DECLS to
indicate when inlined functions need to be declared in
xemacs.defs.in.in, and make use of it in xemacs.defs.in.in.
We need to do this because postgresql.c now calls qxestrdup(),
which is an inline function.
Make nconc2() and other such functions MODULE_API and put
them in xemacs.defs.in.in since postgresql.c now uses them.
Clean up indentation in lread.c and a few other places.
In text.h, document ASSERT_ASCTEXT_ASCII() and
ASSERT_ASCTEXT_ASCII_LEN(), group together the stand-in
encodings and add some more for DLL symbols, function and
variable names, etc.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Tue, 26 Jan 2010 23:22:30 -0600 |
parents | 8b63e21b0436 |
children | e813cf16c015 |
rev | line source |
---|---|
3659 | 1 /* Shared object code between X and GTK -- include file. |
2 Copyright (C) 1991-5, 1997 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Sun Microsystems, Inc. | |
4 Copyright (C) 1996, 2001, 2002, 2003 Ben Wing. | |
5 | |
6 This file is part of XEmacs. | |
7 | |
8 XEmacs is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with XEmacs; see the file COPYING. If not, write to | |
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 Boston, MA 02111-1307, USA. */ | |
22 | |
23 /* Synched up with: Not in FSF. */ | |
24 | |
25 /* Pango is ready for prime-time now, as far as I understand it. The GTK | |
26 people should be using that. Oh well. (Aidan Kehoe, Sat Nov 4 12:41:12 | |
27 CET 2006) */ | |
28 | |
29 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) | |
30 | |
31 #ifdef DEBUG_XEMACS | |
32 # define DEBUG_OBJECTS(FORMAT, ...) \ | |
33 do { if (debug_x_objects) stderr_out(FORMAT, __VA_ARGS__); } while (0) | |
34 #else /* DEBUG_XEMACS */ | |
35 # define DEBUG_OBJECTS(format, ...) | |
36 #endif /* DEBUG_XEMACS */ | |
37 | |
38 #elif defined(__GNUC__) | |
39 | |
40 #ifdef DEBUG_XEMACS | |
41 # define DEBUG_OBJECTS(format, args...) \ | |
42 do { if (debug_x_objects) stderr_out(format, args ); } while (0) | |
43 #else /* DEBUG_XEMACS */ | |
44 # define DEBUG_OBJECTS(format, args...) | |
45 #endif /* DEBUG_XEMACS */ | |
46 | |
47 #else /* defined(__STDC_VERSION__) [...] */ | |
48 # define DEBUG_OBJECTS (void) | |
49 #endif | |
50 | |
51 #ifdef MULE | |
52 | |
53 /* For some code it's reasonable to have only one copy and conditionalize | |
54 at run-time. For other code it isn't. */ | |
55 | |
56 static int | |
57 count_hyphens(const Ibyte *str, Bytecount length, Ibyte **last_hyphen) | |
58 { | |
59 int hyphen_count = 0; | |
60 const Ibyte *hyphening = str; | |
61 const Ibyte *new_hyphening; | |
62 | |
63 for (hyphen_count = 0; | |
4124 | 64 NULL != (new_hyphening = (Ibyte *) memchr((const void *)hyphening, '-', length)); |
3659 | 65 hyphen_count++) |
66 { | |
67 ++new_hyphening; | |
68 length -= new_hyphening - hyphening; | |
69 hyphening = new_hyphening; | |
70 } | |
71 | |
72 if (NULL != last_hyphen) | |
73 { | |
74 *last_hyphen = (Ibyte *)hyphening; | |
75 } | |
76 | |
77 return hyphen_count; | |
78 } | |
79 | |
80 static int | |
81 #ifdef THIS_IS_GTK | |
82 gtk_font_spec_matches_charset (struct device * USED_IF_XFT (d), | |
83 Lisp_Object charset, | |
84 const Ibyte *nonreloc, Lisp_Object reloc, | |
85 Bytecount offset, Bytecount length, | |
86 enum font_specifier_matchspec_stages stage) | |
87 #else | |
88 x_font_spec_matches_charset (struct device * USED_IF_XFT (d), | |
89 Lisp_Object charset, | |
90 const Ibyte *nonreloc, Lisp_Object reloc, | |
91 Bytecount offset, Bytecount length, | |
92 enum font_specifier_matchspec_stages stage) | |
93 #endif | |
94 { | |
95 Lisp_Object registries = Qnil; | |
96 long i, registries_len; | |
97 const Ibyte *the_nonreloc; | |
98 Bytecount the_length; | |
99 | |
100 the_nonreloc = nonreloc; | |
101 the_length = length; | |
102 | |
103 if (!the_nonreloc) | |
104 the_nonreloc = XSTRING_DATA (reloc); | |
105 fixup_internal_substring (nonreloc, reloc, offset, &the_length); | |
106 the_nonreloc += offset; | |
107 | |
108 #ifdef USE_XFT | |
109 if (stage) | |
110 { | |
111 Display *dpy = DEVICE_X_DISPLAY (d); | |
112 Extbyte *extname; | |
113 XftFont *rf; | |
114 const Ibyte *the_nonreloc; | |
115 | |
116 if (!NILP(reloc)) | |
117 { | |
118 the_nonreloc = XSTRING_DATA (reloc); | |
119 LISP_STRING_TO_EXTERNAL (reloc, extname, Qx_font_name_encoding); | |
120 rf = xft_open_font_by_name (dpy, extname); | |
121 return 0; /* #### maybe this will compile and run ;) */ | |
122 /* Jesus, Stephen, what the fuck? */ | |
123 } | |
124 } | |
125 #endif | |
126 | |
127 /* Hmm, this smells bad. */ | |
4353
4143b78d0df0
Merge an old patch of Ben's, involving font instantiation and charsets.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4124
diff
changeset
|
128 if (NILP (charset)) |
3659 | 129 return 1; |
130 | |
131 /* Hack! Short font names don't have the registry in them, | |
132 so we just assume the user knows what they're doing in the | |
133 case of ASCII. For other charsets, you gotta give the | |
134 long form; sorry buster. | |
135 #### FMH: this screws fontconfig/Xft? | |
136 STRATEGY: use fontconfig's ability to hack languages and character | |
137 sets (lang and charset properties). | |
138 #### Maybe we can use the fontconfig model to eliminate the difference | |
139 between faces and fonts? No - it looks like that would be an abuse | |
140 (fontconfig doesn't know about colors, although Xft does). | |
141 */ | |
142 if (EQ (charset, Vcharset_ascii) && | |
143 (!memchr (the_nonreloc, '*', the_length)) | |
144 && (5 > (count_hyphens(the_nonreloc, the_length, NULL)))) | |
145 { | |
146 return 1; | |
147 } | |
148 | |
149 if (final == stage) | |
150 { | |
151 registries = Qunicode_registries; | |
152 } | |
153 else if (initial == stage) | |
154 { | |
155 registries = XCHARSET_REGISTRIES (charset); | |
156 if (NILP(registries)) | |
157 { | |
158 return 0; | |
159 } | |
160 } | |
161 else assert(0); | |
162 | |
163 CHECK_VECTOR (registries); | |
164 registries_len = XVECTOR_LENGTH(registries); | |
165 | |
166 for (i = 0; i < registries_len; ++i) | |
167 { | |
168 if (!(STRINGP(XVECTOR_DATA(registries)[i])) | |
169 || (XSTRING_LENGTH(XVECTOR_DATA(registries)[i]) > the_length)) | |
170 { | |
171 continue; | |
172 } | |
173 | |
174 /* Check if the font spec ends in the registry specified. X11 says | |
175 this comparison is case insensitive: XLFD, section 3.11: | |
176 | |
177 "Alphabetic case distinctions are allowed but are for human | |
178 readability concerns only. Conforming X servers will perform | |
179 matching on font name query or open requests independent of case." */ | |
180 if (0 == qxestrcasecmp(XSTRING_DATA(XVECTOR_DATA(registries)[i]), | |
181 the_nonreloc + (the_length - | |
182 XSTRING_LENGTH | |
183 (XVECTOR_DATA(registries)[i])))) | |
184 { | |
185 return 1; | |
186 } | |
187 } | |
188 return 0; | |
189 } | |
190 | |
191 static Lisp_Object | |
192 xlistfonts_checking_charset (Lisp_Object device, const Extbyte *xlfd, | |
193 Lisp_Object charset, | |
194 enum font_specifier_matchspec_stages stage) | |
195 { | |
196 Extbyte **names; | |
197 Lisp_Object result = Qnil; | |
198 int count = 0, i; | |
199 DECLARE_EISTRING(ei_single_result); | |
200 | |
201 names = XListFonts ( | |
202 #ifdef THIS_IS_GTK | |
203 GDK_DISPLAY (), | |
204 #else | |
205 DEVICE_X_DISPLAY (XDEVICE (device)), | |
206 #endif | |
207 xlfd, MAX_FONT_COUNT, &count); | |
208 | |
209 for (i = 0; i < count; ++i) | |
210 { | |
211 eireset(ei_single_result); | |
212 eicpy_ext(ei_single_result, names[i], Qx_font_name_encoding); | |
213 | |
214 if (DEVMETH_OR_GIVEN(XDEVICE (device), font_spec_matches_charset, | |
215 (XDEVICE (device), charset, | |
216 eidata(ei_single_result), Qnil, 0, | |
217 -1, stage), 0)) | |
218 { | |
219 result = eimake_string(ei_single_result); | |
220 DEBUG_OBJECTS ("in xlistfonts_checking_charset, returning %s\n", | |
221 eidata(ei_single_result)); | |
222 break; | |
223 } | |
224 } | |
225 | |
226 if (names) | |
227 { | |
228 XFreeFontNames (names); | |
229 } | |
230 | |
231 return result; | |
232 } | |
233 | |
234 #ifdef USE_XFT | |
235 /* #### debug functions: find a better place for us */ | |
236 const char *FcResultToString (FcResult r); | |
237 const char * | |
238 FcResultToString (FcResult r) | |
239 { | |
240 static char buffer[256]; | |
241 switch (r) | |
242 { | |
243 case FcResultMatch: | |
244 return "FcResultMatch"; | |
245 case FcResultNoMatch: | |
246 return "FcResultNoMatch"; | |
247 case FcResultTypeMismatch: | |
248 return "FcResultTypeMismatch"; | |
249 case FcResultNoId: | |
250 return "FcResultNoId"; | |
251 default: | |
252 snprintf (buffer, 255, "FcResultUndocumentedValue (%d)", r); | |
253 return buffer; | |
254 } | |
255 } | |
256 | |
257 const char *FcTypeOfValueToString (FcValue v); | |
258 const char * | |
259 FcTypeOfValueToString (FcValue v) | |
260 { | |
261 static char buffer[256]; | |
262 switch (v.type) | |
263 { | |
264 case FcTypeMatrix: | |
265 return "FcTypeMatrix"; | |
266 case FcTypeString: | |
267 return "FcTypeString"; | |
268 case FcTypeVoid: | |
269 return "FcTypeVoid"; | |
270 case FcTypeDouble: | |
271 return "FcTypeDouble"; | |
272 case FcTypeInteger: | |
273 return "FcTypeInteger"; | |
274 case FcTypeBool: | |
275 return "FcTypeBool"; | |
276 case FcTypeCharSet: | |
277 return "FcTypeCharSet"; | |
278 case FcTypeLangSet: | |
279 return "FcTypeLangSet"; | |
280 /* #### There is no union member of this type, but there are void* and | |
281 FcPattern* members, as of fontconfig.h FC_VERSION 10002 */ | |
282 case FcTypeFTFace: | |
283 return "FcTypeFTFace"; | |
284 default: | |
285 snprintf (buffer, 255, "FcTypeUndocumentedType (%d)", v.type); | |
286 return buffer; | |
287 } | |
288 } | |
289 | |
290 static FcCharSet * | |
291 mule_to_fc_charset (Lisp_Object cs) | |
292 { | |
293 int ucode, i, j; | |
294 FcCharSet *fccs; | |
295 | |
296 CHECK_CHARSET (cs); | |
297 fccs = FcCharSetCreate (); | |
298 /* #### do we also need to deal with 94 vs. 96 charsets? | |
299 ie, how are SP and DEL treated in ASCII? non-graphic should return -1 */ | |
300 if (1 == XCHARSET_DIMENSION (cs)) | |
301 /* Unicode tables are indexed by offsets from ASCII SP, not by ASCII */ | |
302 for (i = 0; i < 96; i++) | |
303 { | |
304 ucode = ((int *) XCHARSET_TO_UNICODE_TABLE (cs))[i]; | |
305 if (ucode >= 0) | |
306 /* #### should check for allocation failure */ | |
307 FcCharSetAddChar (fccs, (FcChar32) ucode); | |
308 } | |
309 else if (2 == XCHARSET_DIMENSION (cs)) | |
310 /* Unicode tables are indexed by offsets from ASCII SP, not by ASCII */ | |
311 for (i = 0; i < 96; i++) | |
312 for (j = 0; j < 96; j++) | |
313 { | |
314 ucode = ((int **) XCHARSET_TO_UNICODE_TABLE (cs))[i][j]; | |
315 if (ucode >= 0) | |
316 /* #### should check for allocation failure */ | |
317 FcCharSetAddChar (fccs, (FcChar32) ucode); | |
318 } | |
319 else | |
320 { | |
321 FcCharSetDestroy (fccs); | |
322 fccs = NULL; | |
323 } | |
324 return fccs; | |
325 } | |
326 | |
327 struct charset_reporter { | |
328 Lisp_Object *charset; | |
329 /* This is a debug facility, require ASCII. */ | |
4932 | 330 const Ascbyte *language; /* ASCII, please */ |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
331 /* Technically this is FcChar8, but fsckin' GCC 4 bitches. |
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
332 RFC 3066 is a combination of ISO 639 and ISO 3166. */ |
4932 | 333 const Ascbyte *rfc3066; /* ASCII, please */ |
3659 | 334 }; |
335 | |
336 static struct charset_reporter charset_table[] = | |
337 { | |
338 /* #### It's my branch, my favorite charsets get checked first! | |
339 That's a joke, Son. | |
340 Ie, I don't know what I'm doing, so my charsets first is as good as | |
341 any other arbitrary order. If you have a better idea, speak up! */ | |
342 { &Vcharset_ascii, "English", "en" }, | |
343 { &Vcharset_japanese_jisx0208, "Japanese", "ja" }, | |
344 { &Vcharset_japanese_jisx0212, "Japanese", "ja" }, | |
345 { &Vcharset_katakana_jisx0201, "Japanese", "ja" }, | |
346 { &Vcharset_latin_jisx0201, "Japanese", "ja" }, | |
347 { &Vcharset_japanese_jisx0208_1978, "Japanese", "ja" }, | |
348 { &Vcharset_greek_iso8859_7, "Greek", "el" }, | |
349 /* #### all the Chinese need checking | |
350 Damn the blood-sucking ISO anyway. */ | |
4756
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
351 { &Vcharset_chinese_gb2312, "simplified Chinese", "zh-cn" }, |
3659 | 352 { &Vcharset_korean_ksc5601, "Korean", "ko" }, |
4756
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
353 { &Vcharset_chinese_cns11643_1, "traditional Chinese", "zh-tw" }, |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
354 { &Vcharset_chinese_cns11643_2, "traditional Chinese", "zh-tw" }, |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
355 /* #### not obvious how to handle these |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
356 We could (for experimental purposes) make the last element into |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
357 an array of ISO 639 codes, and check for all of them. If a font |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
358 provides some but not others, warn. */ |
3659 | 359 { &Vcharset_latin_iso8859_1, NULL, NULL }, |
360 { &Vcharset_latin_iso8859_2, NULL, NULL }, | |
361 { &Vcharset_latin_iso8859_3, NULL, NULL }, | |
362 { &Vcharset_latin_iso8859_4, NULL, NULL }, | |
363 { &Vcharset_latin_iso8859_9, NULL, NULL }, | |
364 { &Vcharset_latin_iso8859_15, NULL, NULL }, | |
4756
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
365 { &Vcharset_thai_tis620, "Thai", "th" }, |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
366 /* We don't have an arabic charset. bidi issues, I guess? */ |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
367 /* { &Vcharset_arabic_iso8859_6, "Arabic", "ar" }, */ |
3659 | 368 { &Vcharset_hebrew_iso8859_8, "Hebrew", "he" }, |
4756
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
369 /* #### probably close enough for Ukraine? */ |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
370 { &Vcharset_cyrillic_iso8859_5, "Russian", "ru" }, |
3659 | 371 /* #### these probably are not quite right */ |
4756
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
372 { &Vcharset_chinese_big5_1, "traditional Chinese", "zh-tw" }, |
5d67242595a8
Update charset_table used by Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4494
diff
changeset
|
373 { &Vcharset_chinese_big5_2, "traditional Chinese", "zh-tw" }, |
3659 | 374 { NULL, NULL, NULL } |
375 }; | |
376 | |
377 /* Choose appropriate font name for debug messages. | |
378 Use only in the top half of next function (enforced with #undef). */ | |
379 #define DECLARE_DEBUG_FONTNAME(__xemacs_name) \ | |
380 Eistring *__xemacs_name; \ | |
381 do \ | |
382 { \ | |
383 __xemacs_name = debug_xft > 2 ? eistr_fullname \ | |
384 : debug_xft > 1 ? eistr_longname \ | |
385 : eistr_shortname; \ | |
386 } while (0) | |
387 | |
388 static Lisp_Object | |
389 xft_find_charset_font (Lisp_Object font, Lisp_Object charset, | |
390 enum font_specifier_matchspec_stages stage) | |
391 { | |
392 const Extbyte *patternext; | |
393 Lisp_Object result = Qnil; | |
394 | |
395 /* #### with Xft need to handle second stage here -- sjt | |
396 Hm. Or maybe not. That would be cool. :-) */ | |
397 if (stage) | |
398 return Qnil; | |
399 | |
400 /* Fontconfig converts all FreeType names to UTF-8 before passing them | |
401 back to callers---see fcfreetype.c (FcFreeTypeQuery). | |
402 I don't believe this is documented. */ | |
403 | |
404 DEBUG_XFT1 (1, "confirming charset for font instance %s\n", | |
405 XSTRING_DATA(font)); | |
406 | |
407 /* #### this looks like a fair amount of work, but the basic design | |
408 has never been rethought, and it should be | |
409 | |
410 what really should happen here is that we use FcFontSort (FcFontList?) | |
411 to get a list of matching fonts, then pick the first (best) one that | |
412 gives language or repertoire coverage. | |
413 */ | |
414 | |
415 FcInit (); /* No-op if already initialized. | |
416 In fontconfig 2.3.2, this cannot return | |
417 failure, but that looks like a bug. We | |
418 check for it with FcGetCurrentConfig(), | |
419 which *can* fail. */ | |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
420 if (!FcConfigGetCurrent()) |
3659 | 421 stderr_out ("Failed fontconfig initialization\n"); |
422 else | |
423 { | |
424 FcPattern *fontxft; /* long-lived, freed at end of this block */ | |
425 FcResult fcresult; | |
426 FcConfig *fcc; | |
4932 | 427 const Ascbyte *lang = "en"; |
3659 | 428 FcCharSet *fccs = NULL; |
429 DECLARE_EISTRING (eistr_shortname); /* user-friendly nickname */ | |
430 DECLARE_EISTRING (eistr_longname); /* omit FC_LANG and FC_CHARSET */ | |
431 DECLARE_EISTRING (eistr_fullname); /* everything */ | |
432 | |
433 LISP_STRING_TO_EXTERNAL (font, patternext, Qfc_font_name_encoding); | |
434 fcc = FcConfigGetCurrent (); | |
435 | |
436 /* parse the name, do the substitutions, and match the font */ | |
437 | |
438 { | |
439 FcPattern *p = FcNameParse ((FcChar8 *) patternext); | |
440 PRINT_XFT_PATTERN (3, "FcNameParse'ed name is %s\n", p); | |
441 /* #### Next two return FcBool, but what does the return mean? */ | |
442 /* The order is correct according the fontconfig docs. */ | |
443 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
444 PRINT_XFT_PATTERN (2, "FcConfigSubstitute'ed name is %s\n", p); | |
445 FcDefaultSubstitute (p); | |
446 PRINT_XFT_PATTERN (3, "FcDefaultSubstitute'ed name is %s\n", p); | |
447 /* #### check fcresult of following match? */ | |
4809
0d3ccd5a2509
Initialize the result variable passed to FcFontMatch. See xemacs-patches
Jerry James <james@xemacs.org>
parents:
4758
diff
changeset
|
448 fcresult = FcResultMatch; |
3659 | 449 fontxft = FcFontMatch (fcc, p, &fcresult); |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
450 switch (fcresult) |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
451 { |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
452 /* case FcResultOutOfMemory: */ |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
453 case FcResultNoMatch: |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
454 case FcResultTypeMismatch: |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
455 case FcResultNoId: |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
456 break; |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
457 case FcResultMatch: |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
458 /* this prints the long fontconfig name */ |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
459 PRINT_XFT_PATTERN (1, "FcFontMatch'ed name is %s\n", fontxft); |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
460 break; |
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
461 } |
3659 | 462 FcPatternDestroy (p); |
463 } | |
464 | |
465 /* heuristic to give reasonable-length names for debug reports | |
466 | |
467 I considered #ifdef SUPPORT_FULL_FONTCONFIG_NAME etc but that's | |
468 pointless. We're just going to remove this code once the font/ | |
469 face refactoring is done, but until then it could be very useful. | |
470 */ | |
471 { | |
472 FcPattern *p = FcFontRenderPrepare (fcc, fontxft, fontxft); | |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
473 Extbyte *name; |
3659 | 474 |
475 /* full name, including language coverage and repertoire */ | |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
476 name = (Extbyte *) FcNameUnparse (p); |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
477 eicpy_ext (eistr_fullname, |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
478 (name ? name : "NOT FOUND"), |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
479 Qfc_font_name_encoding); |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
480 if (name) free (name); |
3659 | 481 |
482 /* long name, omitting coverage and repertoire, plus a number | |
483 of rarely useful properties */ | |
484 FcPatternDel (p, FC_CHARSET); | |
485 FcPatternDel (p, FC_LANG); | |
3841 | 486 #ifdef FC_WIDTH |
3659 | 487 FcPatternDel (p, FC_WIDTH); |
3841 | 488 #endif |
3659 | 489 FcPatternDel (p, FC_SPACING); |
490 FcPatternDel (p, FC_HINTING); | |
491 FcPatternDel (p, FC_VERTICAL_LAYOUT); | |
492 FcPatternDel (p, FC_AUTOHINT); | |
493 FcPatternDel (p, FC_GLOBAL_ADVANCE); | |
494 FcPatternDel (p, FC_INDEX); | |
495 FcPatternDel (p, FC_SCALE); | |
496 FcPatternDel (p, FC_FONTVERSION); | |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
497 name = (Extbyte *) FcNameUnparse (p); |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
498 eicpy_ext (eistr_longname, |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
499 (name ? name : "NOT FOUND"), |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
500 Qfc_font_name_encoding); |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
501 if (name) free (name); |
3659 | 502 |
503 /* nickname, just family and size, but | |
504 "family" names usually have style, slant, and weight */ | |
505 FcPatternDel (p, FC_FOUNDRY); | |
506 FcPatternDel (p, FC_STYLE); | |
507 FcPatternDel (p, FC_SLANT); | |
508 FcPatternDel (p, FC_WEIGHT); | |
509 FcPatternDel (p, FC_PIXEL_SIZE); | |
510 FcPatternDel (p, FC_OUTLINE); | |
511 FcPatternDel (p, FC_SCALABLE); | |
512 FcPatternDel (p, FC_DPI); | |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
513 name = (Extbyte *) FcNameUnparse (p); |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
514 eicpy_ext (eistr_shortname, |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
515 (name ? name : "NOT FOUND"), |
4757
a23ac8f90a49
Improve warning and error messages from Xft.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4756
diff
changeset
|
516 Qfc_font_name_encoding); |
4758
75975fd0b7fc
Implement more of the fontconfig API.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4757
diff
changeset
|
517 if (name) free (name); |
3659 | 518 |
519 FcPatternDestroy (p); | |
520 } | |
521 | |
522 /* The language approach may better in the long run, but we can't use | |
523 it based on Mule charsets; fontconfig doesn't provide a way to test | |
524 for unions of languages, etc. That will require support from the | |
525 text module. | |
526 | |
527 Optimization: cache the generated FcCharSet in the Mule charset. | |
528 Don't forget to destroy it if the Mule charset gets deallocated. */ | |
529 | |
530 { | |
531 /* This block possibly should be a function, but it generates | |
532 multiple values. I find the "pass an address to return the | |
533 value in" idiom opaque, so prefer a block. */ | |
534 struct charset_reporter *cr; | |
535 for (cr = charset_table; | |
536 cr->charset && !EQ (*(cr->charset), charset); | |
537 cr++) | |
538 ; | |
539 | |
540 if (cr->rfc3066) | |
541 { | |
542 DECLARE_DEBUG_FONTNAME (name); | |
543 CHECKING_LANG (0, eidata(name), cr->language); | |
4932 | 544 lang = cr->rfc3066; |
3659 | 545 } |
546 else if (cr->charset) | |
547 { | |
548 /* what the hey, build 'em on the fly */ | |
549 /* #### in the case of error this could return NULL! */ | |
550 fccs = mule_to_fc_charset (charset); | |
4932 | 551 /* #### Bad idea here */ |
552 lang = (const Ascbyte *) XSTRING_DATA (XSYMBOL (XCHARSET_NAME | |
553 (charset))->name); | |
3659 | 554 } |
555 else | |
556 { | |
557 /* OK, we fell off the end of the table */ | |
558 warn_when_safe_lispobj (intern ("xft"), intern ("alert"), | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
559 list2 (build_ascstring ("unchecked charset"), |
3659 | 560 charset)); |
561 /* default to "en" | |
562 #### THIS IS WRONG, WRONG, WRONG!! | |
563 It is why we never fall through to XLFD-checking. */ | |
564 } | |
565 | |
4932 | 566 ASSERT_ASCTEXT_ASCII (lang); |
3659 | 567 |
568 if (fccs) | |
569 { | |
570 /* check for character set coverage */ | |
571 int i = 0; | |
572 FcCharSet *v; | |
573 FcResult r = FcPatternGetCharSet (fontxft, FC_CHARSET, i, &v); | |
574 | |
575 if (r == FcResultTypeMismatch) | |
576 { | |
577 DEBUG_XFT0 (0, "Unexpected type return in charset value\n"); | |
578 result = Qnil; | |
579 } | |
580 else if (r == FcResultMatch && FcCharSetIsSubset (fccs, v)) | |
581 { | |
582 /* The full pattern with the bitmap coverage is massively | |
583 unwieldy, but the shorter names are just *wrong*. We | |
584 should have the full thing internally as truename, and | |
585 filter stuff the client doesn't want to see on output. | |
586 Should we just store it into the truename right here? */ | |
587 DECLARE_DEBUG_FONTNAME (name); | |
588 DEBUG_XFT2 (0, "Xft font %s supports %s\n", | |
589 eidata(name), lang); | |
590 #ifdef RETURN_LONG_FONTCONFIG_NAMES | |
591 result = eimake_string(eistr_fullname); | |
592 #else | |
593 result = eimake_string(eistr_longname); | |
594 #endif | |
595 } | |
596 else | |
597 { | |
598 DECLARE_DEBUG_FONTNAME (name); | |
599 DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n", | |
600 eidata(name), lang); | |
601 result = Qnil; | |
602 } | |
603 | |
604 /* clean up */ | |
605 FcCharSetDestroy (fccs); | |
606 } | |
607 else | |
608 { | |
609 /* check for language coverage */ | |
610 int i = 0; | |
611 FcValue v; | |
612 /* the main event */ | |
613 FcResult r = FcPatternGet (fontxft, FC_LANG, i, &v); | |
614 | |
615 if (r == FcResultMatch) | |
616 { | |
617 if (v.type != FcTypeLangSet) /* excessive paranoia */ | |
618 { | |
619 ASSERT_ASCTEXT_ASCII(FcTypeOfValueToString(v)); | |
620 /* Urk! Fall back and punt to core font. */ | |
621 DEBUG_XFT1 (0, "Unexpected type of lang value (%s)\n", | |
622 FcTypeOfValueToString (v)); | |
623 result = Qnil; | |
624 } | |
4932 | 625 else if (FcLangSetHasLang (v.u.l, (FcChar8 *) lang) |
626 != FcLangDifferentLang) | |
3659 | 627 { |
628 DECLARE_DEBUG_FONTNAME (name); | |
629 DEBUG_XFT2 (0, "Xft font %s supports %s\n", | |
630 eidata(name), lang); | |
631 #ifdef RETURN_LONG_FONTCONFIG_NAMES | |
632 result = eimake_string(eistr_fullname); | |
633 #else | |
634 result = eimake_string(eistr_longname); | |
635 #endif | |
636 } | |
637 else | |
638 { | |
639 DECLARE_DEBUG_FONTNAME (name); | |
640 DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n", | |
641 eidata(name), lang); | |
642 result = Qnil; | |
643 } | |
644 } | |
645 else | |
646 { | |
647 ASSERT_ASCTEXT_ASCII(FcResultToString(r)); | |
648 DEBUG_XFT1 (0, "Getting lang: unexpected result=%s\n", | |
649 FcResultToString (r)); | |
650 result = Qnil; | |
651 } | |
652 } | |
653 | |
654 /* clean up and maybe return */ | |
655 FcPatternDestroy (fontxft); | |
656 if (!UNBOUNDP (result)) | |
657 return result; | |
658 } | |
659 } | |
660 return Qnil; | |
661 } | |
662 #undef DECLARE_DEBUG_FONTNAME | |
663 | |
664 #endif /* USE_XFT */ | |
665 | |
666 /* find a font spec that matches font spec FONT and also matches | |
667 (the registry of) CHARSET. */ | |
668 static Lisp_Object | |
669 #ifdef THIS_IS_GTK | |
670 gtk_find_charset_font (Lisp_Object device, Lisp_Object font, | |
671 Lisp_Object charset, | |
672 enum font_specifier_matchspec_stages stage) | |
673 #else | |
674 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset, | |
675 enum font_specifier_matchspec_stages stage) | |
676 #endif | |
677 { | |
678 Lisp_Object result = Qnil, registries = Qnil; | |
679 int j, hyphen_count, registries_len = 0; | |
680 Ibyte *hyphening, *new_hyphening; | |
681 Bytecount xlfd_length; | |
682 | |
683 DECLARE_EISTRING(ei_xlfd_without_registry); | |
684 DECLARE_EISTRING(ei_xlfd); | |
685 | |
686 #ifdef USE_XFT | |
687 result = xft_find_charset_font(font, charset, stage); | |
688 if (!NILP(result)) | |
689 { | |
690 return result; | |
691 } | |
692 #endif | |
693 | |
694 switch (stage) | |
695 { | |
696 case initial: | |
697 { | |
698 if (!(NILP(XCHARSET_REGISTRIES(charset))) | |
699 && VECTORP(XCHARSET_REGISTRIES(charset))) | |
700 { | |
701 registries_len = XVECTOR_LENGTH(XCHARSET_REGISTRIES(charset)); | |
702 registries = XCHARSET_REGISTRIES(charset); | |
703 } | |
704 break; | |
705 } | |
706 case final: | |
707 { | |
708 registries_len = 1; | |
709 registries = Qunicode_registries; | |
710 break; | |
711 } | |
712 default: | |
713 { | |
714 assert(0); | |
715 break; | |
716 } | |
717 } | |
718 | |
719 eicpy_lstr(ei_xlfd, font); | |
720 hyphening = eidata(ei_xlfd); | |
721 xlfd_length = eilen(ei_xlfd); | |
722 | |
723 /* Count the hyphens in the string, moving new_hyphening to just after the | |
724 last one. */ | |
725 hyphen_count = count_hyphens(hyphening, xlfd_length, &new_hyphening); | |
726 | |
727 if (0 == registries_len || (5 > hyphen_count && | |
728 !(1 == xlfd_length && '*' == *hyphening))) | |
729 { | |
730 /* No proper XLFD specified, or we can't modify the pattern to change | |
731 the registry and encoding to match what we want, or we have no | |
732 information on the registry needed. */ | |
733 eito_external(ei_xlfd, Qx_font_name_encoding); | |
734 DEBUG_OBJECTS ("about to xlistfonts_checking_charset, XLFD %s\n", | |
735 eidata(ei_xlfd)); | |
736 result = xlistfonts_checking_charset (device, eiextdata(ei_xlfd), | |
737 charset, stage); | |
738 /* No need to loop through the available registries; return | |
739 immediately. */ | |
740 return result; | |
741 } | |
742 else if (1 == xlfd_length && '*' == *hyphening) | |
743 { | |
744 /* It's a single asterisk. We can add the registry directly to the | |
745 end. */ | |
746 eicpy_ch(ei_xlfd_without_registry, '*'); | |
747 } | |
748 else | |
749 { | |
750 /* It's a fully-specified XLFD. Work out where the registry and | |
751 encoding are, and initialise ei_xlfd_without_registry to the string | |
752 without them. */ | |
753 | |
754 /* count_hyphens has set new_hyphening to just after the last | |
755 hyphen. Move back to just after the hyphen before it. */ | |
756 | |
757 for (new_hyphening -= 2; new_hyphening > hyphening | |
758 && '-' != *new_hyphening; --new_hyphening) | |
759 ; | |
760 ++new_hyphening; | |
761 | |
762 eicpy_ei(ei_xlfd_without_registry, ei_xlfd); | |
763 | |
764 /* Manipulate ei_xlfd_without_registry, using the information about | |
765 ei_xlfd, to which it's identical. */ | |
766 eidel(ei_xlfd_without_registry, new_hyphening - hyphening, -1, | |
767 eilen(ei_xlfd) - (new_hyphening - hyphening), -1); | |
768 | |
769 } | |
770 | |
771 /* Now, loop through the registries and encodings defined for this | |
772 charset, doing an XListFonts each time with the pattern modified to | |
773 specify the regisry and encoding. This avoids huge amounts of IPC and | |
774 duplicated searching; now we use the searching the X server was doing | |
775 anyway, where before the X server did its search, transferred huge | |
776 amounts of data, and then we proceeded to do a regexp search on that | |
777 data. */ | |
778 for (j = 0; j < registries_len && NILP(result); ++j) | |
779 { | |
780 eireset(ei_xlfd); | |
781 eicpy_ei(ei_xlfd, ei_xlfd_without_registry); | |
782 | |
783 eicat_lstr(ei_xlfd, XVECTOR_DATA(registries)[j]); | |
784 | |
785 eito_external(ei_xlfd, Qx_font_name_encoding); | |
786 | |
787 DEBUG_OBJECTS ("about to xlistfonts_checking_charset, XLFD %s\n", | |
788 eidata(ei_xlfd)); | |
789 result = xlistfonts_checking_charset (device, eiextdata(ei_xlfd), | |
790 charset, stage); | |
791 } | |
792 | |
3676 | 793 /* In the event that the charset is ASCII and we haven't matched |
794 anything up to now, even with a pattern of "*", add "iso8859-1" | |
795 to the charset's registry and try again. Not returning a result | |
796 for ASCII means our frame geometry calculations are | |
797 inconsistent, and that we may crash. */ | |
798 | |
799 if (1 == xlfd_length && EQ(charset, Vcharset_ascii) && NILP(result) | |
800 && ('*' == eigetch(ei_xlfd_without_registry, 0))) | |
801 | |
802 { | |
803 int have_latin1 = 0; | |
804 | |
805 /* Set this to, for example, is08859-1 if you want to see the | |
806 error behaviour. */ | |
807 | |
808 #define FALLBACK_ASCII_REGISTRY "iso8859-1" | |
809 | |
810 for (j = 0; j < registries_len; ++j) | |
811 { | |
812 if (0 == qxestrcasecmp(XSTRING_DATA(XVECTOR_DATA(registries)[j]), | |
4124 | 813 (Ibyte *) FALLBACK_ASCII_REGISTRY)) |
3676 | 814 { |
815 have_latin1 = 1; | |
816 break; | |
817 } | |
818 } | |
819 | |
820 if (!have_latin1) | |
821 { | |
822 Lisp_Object new_registries = make_vector(registries_len + 1, Qnil); | |
823 | |
824 XVECTOR_DATA(new_registries)[0] | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4932
diff
changeset
|
825 = build_ascstring(FALLBACK_ASCII_REGISTRY); |
3676 | 826 |
827 memcpy(XVECTOR_DATA(new_registries) + 1, | |
828 XVECTOR_DATA(registries), | |
829 sizeof XVECTOR_DATA(registries)[0] * | |
830 XVECTOR_LENGTH(registries)); | |
831 | |
832 /* Calling set_charset_registries instead of overwriting the | |
833 value directly, to allow the charset font caches to be | |
834 invalidated and a change to the default face to be | |
835 noted. */ | |
836 set_charset_registries(charset, new_registries); | |
837 | |
3680 | 838 warn_when_safe (Qface, Qwarning, |
839 "Your ASCII charset registries contain nothing " | |
840 "sensible. Adding `" FALLBACK_ASCII_REGISTRY "'."); | |
841 | |
3676 | 842 /* And recurse. */ |
843 result = | |
844 DEVMETH_OR_GIVEN (XDEVICE (device), find_charset_font, | |
845 (device, font, charset, stage), | |
846 result); | |
847 } | |
848 else | |
849 { | |
850 DECLARE_EISTRING (ei_connection_name); | |
851 | |
852 /* We preserve a copy of the connection name for the error message | |
853 after the device is deleted. */ | |
854 eicpy_lstr (ei_connection_name, | |
855 DEVICE_CONNECTION (XDEVICE(device))); | |
856 | |
857 stderr_out ("Cannot find a font for ASCII, deleting device on %s\n", | |
858 eidata (ei_connection_name)); | |
859 | |
860 io_error_delete_device (device); | |
861 | |
862 /* Do a normal warning in the event that we have other, non-X | |
863 frames available. (If we don't, io_error_delete_device will | |
864 have exited.) */ | |
865 warn_when_safe | |
866 (Qface, Qerror, | |
867 "Cannot find a font for ASCII, deleting device on %s.\n" | |
868 "\n" | |
869 "Your X server fonts appear to be inconsistent; fix them, or\n" | |
870 "the next frame you create on that DISPLAY will crash this\n" | |
871 "XEmacs. At a minimum, provide one font with an XLFD ending\n" | |
872 "in `" FALLBACK_ASCII_REGISTRY "', so we can work out what size\n" | |
873 "a frame should be. ", | |
874 eidata (ei_connection_name)); | |
875 } | |
876 | |
877 } | |
878 | |
3659 | 879 /* This function used to return the font spec, in the case where a font |
880 didn't exist on the X server but it did match the charset. We're not | |
881 doing that any more, because none of the other platform code does, and | |
882 the old behaviour was badly-judged in other respects, so I don't trust | |
883 the original author to have had a good reason for it. */ | |
884 | |
885 return result; | |
886 } | |
887 | |
888 #endif /* MULE */ |