diff options
| author | Kenichi Handa | 2007-12-05 12:02:27 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2007-12-05 12:02:27 +0000 |
| commit | cc63eaf948b8523305693940dffb35c45072b10e (patch) | |
| tree | 81753cb45853cd2187300e6b4e010d4d5cc0cbe6 /src | |
| parent | 3fae690b05c6c98ede63cf3d536bc9dd2e9a8566 (diff) | |
| download | emacs-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.c | 145 |
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 | ||
| 325 | struct 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 | |||
| 346 | static struct OpenTypeSpec * | ||
| 347 | ftfont_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 | |||
| 325 | static Lisp_Object | 403 | static Lisp_Object |
| 326 | ftfont_list (frame, spec) | 404 | ftfont_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 | ||