aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2007-12-05 12:02:27 +0000
committerKenichi Handa2007-12-05 12:02:27 +0000
commitcc63eaf948b8523305693940dffb35c45072b10e (patch)
tree81753cb45853cd2187300e6b4e010d4d5cc0cbe6 /src
parent3fae690b05c6c98ede63cf3d536bc9dd2e9a8566 (diff)
downloademacs-cc63eaf948b8523305693940dffb35c45072b10e.tar.gz
emacs-cc63eaf948b8523305693940dffb35c45072b10e.zip
(struct OpenTypeSpec): New struct.
(OTF_SYM_TAG, OTF_TAG_STR): New macros. (ftfont_get_open_type_spec): New function. (ftfont_list) [HAVE_LIBOTF]: Check otf-spec property.
Diffstat (limited to 'src')
-rw-r--r--src/ftfont.c145
1 files changed, 123 insertions, 22 deletions
diff --git a/src/ftfont.c b/src/ftfont.c
index 48244ff28dc..50ad0f460de 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -322,6 +322,84 @@ ftfont_get_cache (frame)
322 return freetype_font_cache; 322 return freetype_font_cache;
323} 323}
324 324
325struct OpenTypeSpec
326{
327 unsigned int script, langsys;
328 int nfeatures[2];
329 unsigned int *features[2];
330};
331
332#define OTF_SYM_TAG(sym, tag) \
333 do { \
334 unsigned char *p = SDATA (SYMBOL_NAME (val)); \
335 tag = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; \
336 } while (0)
337
338#define OTF_TAG_STR(tag, str) \
339 do { \
340 (str)[0] = (char) (tag >> 24); \
341 (str)[1] = (char) ((tag >> 16) & 0xFF); \
342 (str)[2] = (char) ((tag >> 8) & 0xFF); \
343 (str)[3] = (char) (tag & 0xFF); \
344 } while (0)
345
346static struct OpenTypeSpec *
347ftfont_get_open_type_spec (Lisp_Object otf_spec)
348{
349 struct OpenTypeSpec *spec = malloc (sizeof (struct OpenTypeSpec));
350 Lisp_Object val;
351 int i, j, negative;
352
353 if (! spec)
354 return NULL;
355 val = XCAR (otf_spec);
356 if (! NILP (val))
357 OTF_SYM_TAG (val, spec->script);
358 else
359 spec->script = 0x44464C54; /* "DFLT" */
360 otf_spec = XCDR (otf_spec);
361 val = XCAR (otf_spec);
362 if (! NILP (val))
363 OTF_SYM_TAG (val, spec->langsys);
364 else
365 spec->langsys = 0;
366 spec->nfeatures[0] = spec->nfeatures[1] = 0;
367 for (i = 0; i < 2; i++)
368 {
369 Lisp_Object len;
370
371 otf_spec = XCDR (otf_spec);
372 if (NILP (otf_spec))
373 break;
374 val = XCAR (otf_spec);
375 if (NILP (val))
376 continue;
377 len = Flength (val);
378 spec->features[i] = malloc (sizeof (int) * XINT (len));
379 if (! spec->features[i])
380 {
381 if (i > 0 && spec->features[0])
382 free (spec->features[0]);
383 free (spec);
384 return NULL;
385 }
386 for (j = 0, negative = 0; CONSP (val); val = XCDR (val))
387 {
388 if (NILP (XCAR (val)))
389 negative = 1;
390 else
391 {
392 unsigned int tag;
393
394 OTF_SYM_TAG (XCAR (val), tag);
395 spec->features[i][j++] = negative ? tag & 0x80000000 : tag;
396 }
397 }
398 spec->nfeatures[i] = j;
399 }
400 return spec;
401}
402
325static Lisp_Object 403static Lisp_Object
326ftfont_list (frame, spec) 404ftfont_list (frame, spec)
327 Lisp_Object frame, spec; 405 Lisp_Object frame, spec;
@@ -335,11 +413,12 @@ ftfont_list (frame, spec)
335 FcObjectSet *objset = NULL; 413 FcObjectSet *objset = NULL;
336 Lisp_Object script; 414 Lisp_Object script;
337 Lisp_Object registry = Qunicode_bmp; 415 Lisp_Object registry = Qunicode_bmp;
416 struct OpenTypeSpec *otspec= NULL;
338 int weight = 0; 417 int weight = 0;
339 double dpi = -1; 418 double dpi = -1;
340 int spacing = -1; 419 int spacing = -1;
341 int scalable = -1; 420 int scalable = -1;
342 char otf_script[15]; /* For "otlayout\:XXXX" */ 421 char otlayout[15]; /* For "otlayout:XXXX" */
343 422
344 val = null_vector; 423 val = null_vector;
345 424
@@ -373,7 +452,7 @@ ftfont_list (frame, spec)
373 return val; 452 return val;
374 } 453 }
375 454
376 otf_script[0] = '\0'; 455 otlayout[0] = '\0';
377 script = Qnil; 456 script = Qnil;
378 for (extra = AREF (spec, FONT_EXTRA_INDEX); 457 for (extra = AREF (spec, FONT_EXTRA_INDEX);
379 CONSP (extra); extra = XCDR (extra)) 458 CONSP (extra); extra = XCDR (extra))
@@ -384,19 +463,11 @@ ftfont_list (frame, spec)
384 key = XCAR (tmp), val = XCDR (tmp); 463 key = XCAR (tmp), val = XCDR (tmp);
385 if (EQ (key, QCotf)) 464 if (EQ (key, QCotf))
386 { 465 {
387 tmp = XCAR (val); 466 otspec = ftfont_get_open_type_spec (val);
388 if (NILP (tmp)) 467 if (otspec)
389 strcpy (otf_script, "otlayout:DFLT"); 468 return null_vector;
390 else 469 strcat (otlayout, "otlayout:");
391 { 470 OTF_TAG_STR (otspec->script, otlayout + 9);
392 val = assq_no_quit (tmp, Votf_script_alist);
393 if (CONSP (val) && SYMBOLP (XCDR (val)))
394 {
395 sprintf (otf_script, "otlayout:%s",
396 (char *) SDATA (SYMBOL_NAME (tmp)));
397 script = XCDR (val);
398 }
399 }
400 } 471 }
401 else if (EQ (key, QClanguage)) 472 else if (EQ (key, QClanguage))
402 { 473 {
@@ -491,13 +562,13 @@ ftfont_list (frame, spec)
491 NULL); 562 NULL);
492 if (! objset) 563 if (! objset)
493 goto err; 564 goto err;
494 if (otf_script[0]) 565 if (otlayout[0])
495 { 566 {
496#ifndef FC_CAPABILITY 567#ifdef FC_CAPABILITY
497 goto finish;
498#else /* not FC_CAPABILITY */
499 if (! FcObjectSetAdd (objset, FC_CAPABILITY)) 568 if (! FcObjectSetAdd (objset, FC_CAPABILITY))
500 goto err; 569 goto err;
570#else /* not FC_CAPABILITY */
571 goto finish;
501#endif /* not FC_CAPABILITY */ 572#endif /* not FC_CAPABILITY */
502 } 573 }
503 574
@@ -541,16 +612,39 @@ ftfont_list (frame, spec)
541 continue; 612 continue;
542 } 613 }
543#ifdef FC_CAPABILITY 614#ifdef FC_CAPABILITY
544 if (otf_script[0]) 615 if (otlayout[0])
545 { 616 {
546 FcChar8 *this; 617 FcChar8 *this;
547 618
548 if (FcPatternGetString (fontset->fonts[i], FC_CAPABILITY, 0, 619 if (FcPatternGetString (fontset->fonts[i], FC_CAPABILITY, 0,
549 &this) != FcResultMatch 620 &this) != FcResultMatch
550 || ! strstr ((char *) this, otf_script)) 621 || ! strstr ((char *) this, otlayout))
551 continue; 622 continue;
552 } 623 }
553#endif /* FC_CAPABILITY */ 624#endif /* FC_CAPABILITY */
625#ifdef HAVE_LIBOTF
626 if (otspec)
627 {
628 FcChar8 *file;
629 OTF *otf;
630
631 if (FcPatternGetString (fontset->fonts[i], FC_FILE, 0, &file)
632 != FcResultMatch)
633 continue;
634 otf = OTF_open ((char *) file);
635 if (! otf)
636 continue;
637 if (OTF_check_features (otf, 0,
638 otspec->script, otspec->langsys,
639 otspec->features[0],
640 otspec->nfeatures[0]) != 1
641 || OTF_check_features (otf, 1,
642 otspec->script, otspec->langsys,
643 otspec->features[1],
644 otspec->nfeatures[1]) != 1)
645 continue;
646 }
647#endif /* HAVE_LIBOTF */
554 entity = ftfont_pattern_entity (fontset->fonts[i], frame, registry); 648 entity = ftfont_pattern_entity (fontset->fonts[i], frame, registry);
555 if (! NILP (entity)) 649 if (! NILP (entity))
556 val = Fcons (entity, val); 650 val = Fcons (entity, val);
@@ -572,7 +666,14 @@ ftfont_list (frame, spec)
572 if (fontset) FcFontSetDestroy (fontset); 666 if (fontset) FcFontSetDestroy (fontset);
573 if (langset) FcLangSetDestroy (langset); 667 if (langset) FcLangSetDestroy (langset);
574 if (pattern) FcPatternDestroy (pattern); 668 if (pattern) FcPatternDestroy (pattern);
575 669 if (otspec)
670 {
671 if (otspec->nfeatures[0] > 0)
672 free (otspec->features[0]);
673 if (otspec->nfeatures[1] > 0)
674 free (otspec->features[1]);
675 free (otspec);
676 }
576 return val; 677 return val;
577} 678}
578 679