aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2009-05-08 06:05:38 +0000
committerKenichi Handa2009-05-08 06:05:38 +0000
commit92f192809352574cac652b437c0d4467aa06fb6c (patch)
tree61134010bf837eadca09386abde7364e4082913b /src
parent3909e3a33227a144215e29ab3b64c63cac290aac (diff)
downloademacs-92f192809352574cac652b437c0d4467aa06fb6c.tar.gz
emacs-92f192809352574cac652b437c0d4467aa06fb6c.zip
(xfont_check_char_support)
(xfont_check_registry_char_support): New functions. (xfont_list_pattern): Delete unused arg FRAME, add arg CHARS. Callers adjusted. (xfont_list): Handle :script property.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/xfont.c174
2 files changed, 164 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 779f0d99645..61e3420cb32 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12009-05-08 Kenichi Handa <handa@m17n.org>
2
3 * xfont.c (xfont_check_char_support)
4 (xfont_check_registry_char_support): New functions.
5 (xfont_list_pattern): Delete unused arg FRAME, add arg CHARS.
6 Callers adjusted.
7 (xfont_list): Handle :script property.
8
12009-05-07 David Reitter <david.reitter@gmail.com> 92009-05-07 David Reitter <david.reitter@gmail.com>
2 10
3 * nsterm.m (ns_dumpglyphs_stretch,ns_dumpglyphs_image): 11 * nsterm.m (ns_dumpglyphs_stretch,ns_dumpglyphs_image):
diff --git a/src/xfont.c b/src/xfont.c
index afafca89c24..987c2ddc210 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -256,13 +256,129 @@ xfont_encode_coding_xlfd (char *xlfd)
256 return len; 256 return len;
257} 257}
258 258
259static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *)); 259/* Check if XFONT supports CHARS (cons or vector of characters). If
260 yes, return 1. If no, return 0. */
261
262static int xfont_check_char_support P_ ((XFontStruct *, Lisp_Object));
263
264static int
265xfont_check_char_support (xfont, chars)
266 XFontStruct *xfont;
267 Lisp_Object chars;
268{
269 if (CONSP (chars))
270 {
271 Lisp_Object tail = chars;
272
273 while (CONSP (tail))
274 {
275 int c = XINT (XCAR (chars));
276 XChar2b char2b;
277 char2b.byte1 = c >> 16;
278 char2b.byte2 = c & 0xFF;
279 if (! xfont_get_pcm (xfont, &char2b))
280 return 0;
281 }
282 return 1;
283 }
284 if (VECTORP (chars))
285 {
286 int i;
287
288 for (i = ASIZE (chars) - 1; i >= 0; i--)
289 {
290 int c = XINT (AREF (chars, i));
291 XChar2b char2b;
292 char2b.byte1 = c >> 16;
293 char2b.byte2 = c & 0xFF;
294 if (xfont_get_pcm (xfont, &char2b))
295 return 1;
296 }
297 return 0;
298 }
299 return 0;
300}
301
302
303/* Check if a repertory charset correponding to REGISTRY supports
304 CHARS (cons or vector of characters). If yes, return Qt. If no,
305 return Qnil. If not decidable by REGISTRY, return a copy of CHARS
306 but with elements changed to glyph codes. */
307
308static Lisp_Object xfont_check_registry_char_support P_ ((Lisp_Object,
309 Lisp_Object));
260 310
261static Lisp_Object 311static Lisp_Object
262xfont_list_pattern (frame, display, pattern) 312xfont_check_registry_char_support (registry, chars)
263 Lisp_Object frame; 313 Lisp_Object registry, chars;
314{
315 struct charset *encoding, *repertory, *charset;
316
317 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
318 return Qnil;
319 if (! repertory)
320 chars = Fcopy_sequence (chars);
321 charset = repertory ? repertory : encoding;
322 if (CONSP (chars))
323 {
324 Lisp_Object tail = chars;
325
326 while (CONSP (tail))
327 {
328 int c, code;
329
330 if (! INTEGERP (XCAR (tail)))
331 return Qnil;
332 c = XINT (XCAR (tail));
333 code = ENCODE_CHAR (charset, c);
334 if (code == CHARSET_INVALID_CODE (charset))
335 return Qnil;
336 if (! repertory)
337 XSETCAR (tail, make_number (code));
338 }
339 return repertory ? Qt : chars;
340 }
341 if (VECTORP (chars))
342 {
343 int i;
344
345 for (i = ASIZE (chars) - 1; i >= 0; i--)
346 {
347 int c, code;
348
349 if (! INTEGERP (AREF (chars, i)))
350 return Qnil;
351 c = XINT (AREF (chars, i));
352 code = ENCODE_CHAR (charset, c);
353
354 if (code == CHARSET_INVALID_CODE (charset))
355 {
356 if (! repertory)
357 return Qnil;
358 }
359 else
360 {
361 if (repertory)
362 return Qt;
363 ASET (chars, i, make_number (code));
364 }
365 }
366 return repertory ? Qnil : chars;
367 }
368 return Qnil;
369}
370
371static Lisp_Object xfont_list_pattern P_ ((Display *, char *, Lisp_Object));
372
373/* Return a list of font-entities matching with PATTERN available on
374 DISPLAY. If CHARS is non-nil, exclude fonts not supporting
375 CHARS. */
376
377static Lisp_Object
378xfont_list_pattern (display, pattern, chars)
264 Display *display; 379 Display *display;
265 char *pattern; 380 char *pattern;
381 Lisp_Object chars;
266{ 382{
267 Lisp_Object list = Qnil; 383 Lisp_Object list = Qnil;
268 int i, limit, num_fonts; 384 int i, limit, num_fonts;
@@ -301,11 +417,21 @@ xfont_list_pattern (frame, display, pattern)
301 { 417 {
302 Lisp_Object entity; 418 Lisp_Object entity;
303 int result; 419 int result;
304 char *p; 420 XFontStruct *font = NULL;
305 421
306 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0) 422 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
307 continue; 423 continue;
308 424 if (! NILP (chars))
425 {
426 font = XLoadQueryFont (display, indices[i]);
427 if (! font)
428 continue;
429 if (! xfont_check_char_support (font, chars))
430 {
431 XFreeFont (display, font);
432 continue;
433 }
434 }
309 entity = font_make_entity (); 435 entity = font_make_entity ();
310 ASET (entity, FONT_TYPE_INDEX, Qx); 436 ASET (entity, FONT_TYPE_INDEX, Qx);
311 xfont_decode_coding_xlfd (indices[i], -1, buf); 437 xfont_decode_coding_xlfd (indices[i], -1, buf);
@@ -314,10 +440,11 @@ xfont_list_pattern (frame, display, pattern)
314 { 440 {
315 /* This may be an alias name. Try to get the full XLFD name 441 /* This may be an alias name. Try to get the full XLFD name
316 from XA_FONT property of the font. */ 442 from XA_FONT property of the font. */
317 XFontStruct *font = XLoadQueryFont (display, indices[i]);
318 unsigned long value; 443 unsigned long value;
319 444
320 if (! font) 445 if (! font)
446 font = XLoadQueryFont (display, indices[i]);
447 if (! font)
321 continue; 448 continue;
322 if (XGetFontProperty (font, XA_FONT, &value)) 449 if (XGetFontProperty (font, XA_FONT, &value))
323 { 450 {
@@ -334,9 +461,10 @@ xfont_list_pattern (frame, display, pattern)
334 } 461 }
335 XFree (name); 462 XFree (name);
336 } 463 }
337 XFreeFont (display, font);
338 } 464 }
339 465
466 if (font)
467 XFreeFont (display, font);
340 if (result == 0 468 if (result == 0
341 /* Avoid auto-scaled fonts. */ 469 /* Avoid auto-scaled fonts. */
342 && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0 470 && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0
@@ -359,7 +487,7 @@ xfont_list (frame, spec)
359{ 487{
360 FRAME_PTR f = XFRAME (frame); 488 FRAME_PTR f = XFRAME (frame);
361 Display *display = FRAME_X_DISPLAY_INFO (f)->display; 489 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
362 Lisp_Object registry, list, val, extra; 490 Lisp_Object registry, list, val, extra, chars;
363 int len; 491 int len;
364 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */ 492 /* Large enough to contain the longest XLFD (255 bytes) in UTF-8. */
365 char name[512]; 493 char name[512];
@@ -370,20 +498,32 @@ xfont_list (frame, spec)
370 val = assq_no_quit (QCotf, extra); 498 val = assq_no_quit (QCotf, extra);
371 if (! NILP (val)) 499 if (! NILP (val))
372 return Qnil; 500 return Qnil;
373 val = assq_no_quit (QCscript, extra);
374 if (! NILP (val))
375 return Qnil;
376 val = assq_no_quit (QClang, extra); 501 val = assq_no_quit (QClang, extra);
377 if (! NILP (val)) 502 if (! NILP (val))
378 return Qnil; 503 return Qnil;
379 } 504 }
380
381 registry = AREF (spec, FONT_REGISTRY_INDEX); 505 registry = AREF (spec, FONT_REGISTRY_INDEX);
382 len = font_unparse_xlfd (spec, 0, name, 512); 506 len = font_unparse_xlfd (spec, 0, name, 512);
383 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0) 507 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
384 return Qnil; 508 return Qnil;
509 val = assq_no_quit (QCscript, extra);
510 if (NILP (val))
511 chars = Qnil;
512 else
513 {
514 chars = assq_no_quit (XCDR (val), Vscript_representative_chars);
515 if (! NILP (chars) && ! NILP (registry))
516 {
517 chars = xfont_check_registry_char_support (registry, XCDR (chars));
518 if (NILP (chars))
519 return Qnil;
520 if (EQ (chars, Qt))
521 chars = Qnil;
522 }
523 }
524
385 ASET (spec, FONT_REGISTRY_INDEX, registry); 525 ASET (spec, FONT_REGISTRY_INDEX, registry);
386 list = xfont_list_pattern (frame, display, name); 526 list = xfont_list_pattern (display, name, chars);
387 if (NILP (list) && NILP (registry)) 527 if (NILP (list) && NILP (registry))
388 { 528 {
389 /* Try iso10646-1 */ 529 /* Try iso10646-1 */
@@ -392,7 +532,7 @@ xfont_list (frame, spec)
392 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */ 532 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
393 { 533 {
394 strcpy (r, "iso10646-1"); 534 strcpy (r, "iso10646-1");
395 list = xfont_list_pattern (frame, display, name); 535 list = xfont_list_pattern (display, name, chars);
396 } 536 }
397 } 537 }
398 if (NILP (list) && ! NILP (registry)) 538 if (NILP (list) && ! NILP (registry))
@@ -412,7 +552,7 @@ xfont_list (frame, spec)
412 && ((r - name) + SBYTES (XCAR (alter))) < 256) 552 && ((r - name) + SBYTES (XCAR (alter))) < 256)
413 { 553 {
414 strcpy (r, (char *) SDATA (XCAR (alter))); 554 strcpy (r, (char *) SDATA (XCAR (alter)));
415 list = xfont_list_pattern (frame, display, name); 555 list = xfont_list_pattern (display, name, chars);
416 if (! NILP (list)) 556 if (! NILP (list))
417 break; 557 break;
418 } 558 }
@@ -427,10 +567,9 @@ xfont_list (frame, spec)
427 bcopy (SDATA (XCDR (val)), name, SBYTES (XCDR (val)) + 1); 567 bcopy (SDATA (XCDR (val)), name, SBYTES (XCDR (val)) + 1);
428 if (xfont_encode_coding_xlfd (name) < 0) 568 if (xfont_encode_coding_xlfd (name) < 0)
429 return Qnil; 569 return Qnil;
430 list = xfont_list_pattern (frame, display, name); 570 list = xfont_list_pattern (display, name, chars);
431 } 571 }
432 } 572 }
433
434 return list; 573 return list;
435} 574}
436 575
@@ -569,7 +708,6 @@ xfont_open (f, entity, pixel_size)
569 Lisp_Object font_object, fullname; 708 Lisp_Object font_object, fullname;
570 struct font *font; 709 struct font *font;
571 XFontStruct *xfont; 710 XFontStruct *xfont;
572 int i;
573 711
574 /* At first, check if we know how to encode characters for this 712 /* At first, check if we know how to encode characters for this
575 font. */ 713 font. */