aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2007-12-01 02:38:23 +0000
committerKenichi Handa2007-12-01 02:38:23 +0000
commit1701724c31e96a930fa6f1de03f9f2f858826641 (patch)
treef5cabafd47073b58068246a4086152b7e4189698 /src
parent4b4836deafd8fb1f8d190539c40a8829f8f2c091 (diff)
downloademacs-1701724c31e96a930fa6f1de03f9f2f858826641.tar.gz
emacs-1701724c31e96a930fa6f1de03f9f2f858826641.zip
* font.c [HAVE_M17N_FLT]: Include <m17n-flt.h>.
(font_charset_alist): Moved from xfont.c and renamed. (font_registry_charsets): Likewise. (font_prop_validate_otf): New function. (font_property_table): Register it for QCotf. (DEVICE_DELTA, adjust_anchor, REPLACEMENT_CHARACTER) (font_drive_otf): Deleted. (font_prepare_composition): New arg F. Adjusted for the change of lispy gstring. (font_find_for_lface): New arg C. (font_load_for_face): Adjusted for the change of font_find_for_lface. (Ffont_make_gstring): Adjusted for the change of lispy gstring. (Ffont_fill_gstring): Likewise. (Ffont_shape_text): New function. (Fopen_font): If the font size is not given, use 12-pixel. (Ffont_at): New arg STRING. (syms_of_font): Initalize font_charset_alist. Declare Ffont_shape_text as a Lisp function. Call syms_of_XXfont conditionally.
Diffstat (limited to 'src')
-rw-r--r--src/font.c701
1 files changed, 353 insertions, 348 deletions
diff --git a/src/font.c b/src/font.c
index 23dcb4f2033..43af7345c33 100644
--- a/src/font.c
+++ b/src/font.c
@@ -25,6 +25,9 @@ Boston, MA 02110-1301, USA. */
25#include <stdio.h> 25#include <stdio.h>
26#include <stdlib.h> 26#include <stdlib.h>
27#include <ctype.h> 27#include <ctype.h>
28#ifdef HAVE_M17N_FLT
29#include <m17n-flt.h>
30#endif
28 31
29#include "lisp.h" 32#include "lisp.h"
30#include "buffer.h" 33#include "buffer.h"
@@ -109,6 +112,24 @@ Lisp_Object QCantialias;
109/* Symbols representing values of font spacing property. */ 112/* Symbols representing values of font spacing property. */
110Lisp_Object Qc, Qm, Qp, Qd; 113Lisp_Object Qc, Qm, Qp, Qd;
111 114
115/* Alist of font registry symbol and the corresponding charsets
116 information. The information is retrieved from
117 Vfont_encoding_alist on demand.
118
119 Eash element has the form:
120 (REGISTRY . (ENCODING-CHARSET-ID . REPERTORY-CHARSET-ID))
121 or
122 (REGISTRY . nil)
123
124 In the former form, ENCODING-CHARSET-ID is an ID of a charset that
125 encodes a character code to a glyph code of a font, and
126 REPERTORY-CHARSET-ID is an ID of a charset that tells if a
127 character is supported by a font.
128
129 The latter form means that the information for REGISTRY couldn't be
130 retrieved. */
131static Lisp_Object font_charset_alist;
132
112/* List of all font drivers. Each font-backend (XXXfont.c) calls 133/* List of all font drivers. Each font-backend (XXXfont.c) calls
113 register_font_driver in syms_of_XXXfont to register its font-driver 134 register_font_driver in syms_of_XXXfont to register its font-driver
114 here. */ 135 here. */
@@ -251,6 +272,69 @@ build_font_family_alist ()
251 } 272 }
252} 273}
253 274
275extern Lisp_Object find_font_encoding P_ ((Lisp_Object));
276
277/* Return encoding charset and repertory charset for REGISTRY in
278 ENCODING and REPERTORY correspondingly. If correct information for
279 REGISTRY is available, return 0. Otherwise return -1. */
280
281int
282font_registry_charsets (registry, encoding, repertory)
283 Lisp_Object registry;
284 struct charset **encoding, **repertory;
285{
286 Lisp_Object val;
287 int encoding_id, repertory_id;
288
289 val = assq_no_quit (registry, font_charset_alist);
290 if (! NILP (val))
291 {
292 val = XCDR (val);
293 if (NILP (val))
294 return -1;
295 encoding_id = XINT (XCAR (val));
296 repertory_id = XINT (XCDR (val));
297 }
298 else
299 {
300 val = find_font_encoding (SYMBOL_NAME (registry));
301 if (SYMBOLP (val) && CHARSETP (val))
302 {
303 encoding_id = repertory_id = XINT (CHARSET_SYMBOL_ID (val));
304 }
305 else if (CONSP (val))
306 {
307 if (! CHARSETP (XCAR (val)))
308 goto invalid_entry;
309 encoding_id = XINT (CHARSET_SYMBOL_ID (XCAR (val)));
310 if (NILP (XCDR (val)))
311 repertory_id = -1;
312 else
313 {
314 if (! CHARSETP (XCDR (val)))
315 goto invalid_entry;
316 repertory_id = XINT (CHARSET_SYMBOL_ID (XCDR (val)));
317 }
318 }
319 else
320 goto invalid_entry;
321 val = Fcons (make_number (encoding_id), make_number (repertory_id));
322 font_charset_alist
323 = nconc2 (font_charset_alist, Fcons (Fcons (registry, val), Qnil));
324 }
325
326 if (encoding)
327 *encoding = CHARSET_FROM_ID (encoding_id);
328 if (repertory)
329 *repertory = repertory_id >= 0 ? CHARSET_FROM_ID (repertory_id) : NULL;
330 return 0;
331
332 invalid_entry:
333 font_charset_alist
334 = nconc2 (font_charset_alist, Fcons (Fcons (registry, Qnil), Qnil));
335 return -1;
336}
337
254 338
255/* Font property value validaters. See the comment of 339/* Font property value validaters. See the comment of
256 font_property_table for the meaning of the arguments. */ 340 font_property_table for the meaning of the arguments. */
@@ -329,6 +413,41 @@ font_prop_validate_spacing (prop, val)
329 return Qerror; 413 return Qerror;
330} 414}
331 415
416static Lisp_Object
417font_prop_validate_otf (prop, val)
418 Lisp_Object prop, val;
419{
420 Lisp_Object tail, tmp;
421 int i;
422
423 /* VAL = (SCRIPT [ LANGSYS [ GSUB-FEATURES [ GPOS-FEATURES ]]])
424 GSUB-FEATURES = (FEATURE ... [ nil FEATURE ... ]) | nil
425 GPOS-FEATURES = (FEATURE ... [ nil FEATURE ... ]) | nil */
426 if (! CONSP (val))
427 return Qerror;
428 if (! SYMBOLP (XCAR (val)))
429 return Qerror;
430 tail = XCDR (val);
431 if (NILP (tail))
432 return val;
433 if (! CONSP (tail) || ! SYMBOLP (XCAR (val)))
434 return Qerror;
435 for (i = 0; i < 2; i++)
436 {
437 tail = XCDR (tail);
438 if (NILP (tail))
439 return val;
440 if (! CONSP (tail))
441 return Qerror;
442 for (tmp = XCAR (tail); CONSP (tmp); tmp = XCDR (tmp))
443 if (! SYMBOLP (XCAR (tmp)))
444 return Qerror;
445 if (! NILP (tmp))
446 return Qerror;
447 }
448 return val;
449}
450
332/* Structure of known font property keys and validater of the 451/* Structure of known font property keys and validater of the
333 values. */ 452 values. */
334struct 453struct
@@ -354,7 +473,7 @@ struct
354 { &QCdpi, font_prop_validate_non_neg }, 473 { &QCdpi, font_prop_validate_non_neg },
355 { &QCspacing, font_prop_validate_spacing }, 474 { &QCspacing, font_prop_validate_spacing },
356 { &QCscalable, NULL }, 475 { &QCscalable, NULL },
357 { &QCotf, font_prop_validate_symbol }, 476 { &QCotf, font_prop_validate_otf },
358 { &QCantialias, font_prop_validate_symbol } 477 { &QCantialias, font_prop_validate_symbol }
359 }; 478 };
360 479
@@ -1662,31 +1781,6 @@ generate_otf_features (spec, features)
1662 error ("OTF spec too long"); 1781 error ("OTF spec too long");
1663} 1782}
1664 1783
1665#define DEVICE_DELTA(table, size) \
1666 (((size) >= (table).StartSize && (size) <= (table).EndSize) \
1667 ? (table).DeltaValue[(size) - (table).StartSize] \
1668 : 0)
1669
1670void
1671adjust_anchor (struct font *font, OTF_Anchor *anchor,
1672 unsigned code, int size, int *x, int *y)
1673{
1674 if (anchor->AnchorFormat == 2 && font->driver->anchor_point)
1675 {
1676 int x0, y0;
1677
1678 if (font->driver->anchor_point (font, code, anchor->f.f1.AnchorPoint,
1679 &x0, &y0) >= 0)
1680 *x = x0, *y = y0;
1681 }
1682 else if (anchor->AnchorFormat == 3)
1683 {
1684 if (anchor->f.f2.XDeviceTable.offset)
1685 *x += DEVICE_DELTA (anchor->f.f2.XDeviceTable, size);
1686 if (anchor->f.f2.YDeviceTable.offset)
1687 *y += DEVICE_DELTA (anchor->f.f2.YDeviceTable, size);
1688 }
1689}
1690 1784
1691Lisp_Object 1785Lisp_Object
1692font_otf_DeviceTable (device_table) 1786font_otf_DeviceTable (device_table)
@@ -1743,244 +1837,6 @@ font_otf_Anchor (anchor)
1743 return val; 1837 return val;
1744} 1838}
1745 1839
1746#define REPLACEMENT_CHARACTER 0xFFFD
1747
1748/* Drive FONT's OpenType FEATURES. See the comment of (sturct
1749 font_driver).drive_otf. */
1750
1751int
1752font_drive_otf (font, otf_features, gstring_in, from, to, gstring_out, idx,
1753 alternate_subst)
1754 struct font *font;
1755 Lisp_Object otf_features;
1756 Lisp_Object gstring_in;
1757 int from, to;
1758 Lisp_Object gstring_out;
1759 int idx, alternate_subst;
1760{
1761 Lisp_Object val;
1762 int len;
1763 int i;
1764 OTF *otf;
1765 OTF_GlyphString otf_gstring;
1766 OTF_Glyph *g;
1767 char *script, *langsys = NULL, *gsub_features = NULL, *gpos_features = NULL;
1768 int need_cmap;
1769
1770 val = XCAR (otf_features);
1771 script = SDATA (SYMBOL_NAME (val));
1772 otf_features = XCDR (otf_features);
1773 val = XCAR (otf_features);
1774 langsys = NILP (val) ? NULL : SDATA (SYMBOL_NAME (val));
1775 otf_features = XCDR (otf_features);
1776 val = XCAR (otf_features);
1777 if (! NILP (val))
1778 {
1779 gsub_features = alloca (XINT (Flength (val)) * 6);
1780 generate_otf_features (val, &script, &langsys, gsub_features);
1781 }
1782 otf_features = XCDR (otf_features);
1783 val = XCAR (otf_features);
1784 if (! NILP (val))
1785 {
1786 gpos_features = alloca (XINT (Flength (val)) * 6);
1787 generate_otf_features (val, &script, &langsys, gpos_features);
1788 }
1789
1790 otf = otf_open (font->entity, font->file_name);
1791 if (! otf)
1792 return 0;
1793 if (OTF_get_table (otf, "head") < 0)
1794 return 0;
1795 if (OTF_get_table (otf, "cmap") < 0)
1796 return 0;
1797 if ((! gsub_features || OTF_check_table (otf, "GSUB") < 0)
1798 && (! gpos_features || OTF_check_table (otf, "GPOS") < 0))
1799 return 0;
1800
1801 len = to - from;
1802 otf_gstring.size = otf_gstring.used = len;
1803 otf_gstring.glyphs = (OTF_Glyph *) malloc (sizeof (OTF_Glyph) * len);
1804 memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * len);
1805 for (i = 0, need_cmap = 0; i < len; i++)
1806 {
1807 Lisp_Object g = LGSTRING_GLYPH (gstring_in, from + i);
1808
1809 otf_gstring.glyphs[i].c = XINT (LGLYPH_CHAR (g));
1810 if (otf_gstring.glyphs[i].c == REPLACEMENT_CHARACTER)
1811 otf_gstring.glyphs[i].c = 0;
1812 if (NILP (LGLYPH_CODE (g)))
1813 {
1814 otf_gstring.glyphs[i].glyph_id = 0;
1815 need_cmap = 1;
1816 }
1817 else
1818 otf_gstring.glyphs[i].glyph_id = XINT (LGLYPH_CODE (g));
1819 }
1820 if (need_cmap)
1821 OTF_drive_cmap (otf, &otf_gstring);
1822 OTF_drive_gdef (otf, &otf_gstring);
1823
1824 if (gsub_features)
1825 {
1826 if ((alternate_subst
1827 ? OTF_drive_gsub_alternate (otf, &otf_gstring, script, langsys,
1828 gsub_features)
1829 : OTF_drive_gsub (otf, &otf_gstring, script, langsys,
1830 gsub_features)) < 0)
1831 {
1832 free (otf_gstring.glyphs);
1833 return 0;
1834 }
1835 if (ASIZE (gstring_out) < idx + otf_gstring.used)
1836 {
1837 free (otf_gstring.glyphs);
1838 return -1;
1839 }
1840 for (i = 0, g = otf_gstring.glyphs; i < otf_gstring.used;)
1841 {
1842 int i0 = g->f.index.from, i1 = g->f.index.to;
1843 Lisp_Object glyph = LGSTRING_GLYPH (gstring_in, from + i0);
1844 Lisp_Object min_idx = AREF (glyph, 0);
1845 Lisp_Object max_idx = AREF (glyph, 1);
1846
1847 if (i0 < i1)
1848 {
1849 int min_idx_i = XINT (min_idx), max_idx_i = XINT (max_idx);
1850
1851 for (i0++; i0 <= i1; i0++)
1852 {
1853 glyph = LGSTRING_GLYPH (gstring_in, from + i0);
1854 if (min_idx_i > XINT (AREF (glyph, 0)))
1855 min_idx_i = XINT (AREF (glyph, 0));
1856 if (max_idx_i < XINT (AREF (glyph, 1)))
1857 max_idx_i = XINT (AREF (glyph, 1));
1858 }
1859 min_idx = make_number (min_idx_i);
1860 max_idx = make_number (max_idx_i);
1861 i0 = g->f.index.from;
1862 }
1863 for (; i < otf_gstring.used && g->f.index.from == i0; i++, g++)
1864 {
1865 glyph = LGSTRING_GLYPH (gstring_out, idx + i);
1866 ASET (glyph, 0, min_idx);
1867 ASET (glyph, 1, max_idx);
1868 if (g->c > 0)
1869 LGLYPH_SET_CHAR (glyph, make_number (g->c));
1870 else
1871 LGLYPH_SET_CHAR (glyph, make_number (REPLACEMENT_CHARACTER));
1872 LGLYPH_SET_CODE (glyph, make_number (g->glyph_id));
1873 }
1874 }
1875 }
1876
1877 if (gpos_features)
1878 {
1879 Lisp_Object glyph;
1880 int u = otf->head->unitsPerEm;
1881 int size = font->pixel_size;
1882 Lisp_Object base = Qnil, mark = Qnil;
1883
1884 if (OTF_drive_gpos (otf, &otf_gstring, script, langsys,
1885 gpos_features) < 0)
1886 {
1887 free (otf_gstring.glyphs);
1888 return 0;
1889 }
1890 for (i = 0, g = otf_gstring.glyphs; i < otf_gstring.used; i++, g++)
1891 {
1892 Lisp_Object prev;
1893 int xoff = 0, yoff = 0, width_adjust = 0;
1894
1895 if (! g->glyph_id)
1896 continue;
1897
1898 switch (g->positioning_type)
1899 {
1900 case 0:
1901 break;
1902 case 1: case 2:
1903 {
1904 int format = g->f.f1.format;
1905
1906 if (format & OTF_XPlacement)
1907 xoff = g->f.f1.value->XPlacement * size / u;
1908 if (format & OTF_XPlaDevice)
1909 xoff += DEVICE_DELTA (g->f.f1.value->XPlaDevice, size);
1910 if (format & OTF_YPlacement)
1911 yoff = - (g->f.f1.value->YPlacement * size / u);
1912 if (format & OTF_YPlaDevice)
1913 yoff -= DEVICE_DELTA (g->f.f1.value->YPlaDevice, size);
1914 if (format & OTF_XAdvance)
1915 width_adjust += g->f.f1.value->XAdvance * size / u;
1916 if (format & OTF_XAdvDevice)
1917 width_adjust += DEVICE_DELTA (g->f.f1.value->XAdvDevice, size);
1918 }
1919 break;
1920 case 3:
1921 /* Not yet supported. */
1922 break;
1923 case 4: case 5:
1924 if (NILP (base))
1925 break;
1926 prev = base;
1927 goto label_adjust_anchor;
1928 default: /* i.e. case 6 */
1929 if (NILP (mark))
1930 break;
1931 prev = mark;
1932
1933 label_adjust_anchor:
1934 {
1935 int base_x, base_y, mark_x, mark_y, width;
1936 unsigned code;
1937
1938 base_x = g->f.f4.base_anchor->XCoordinate * size / u;
1939 base_y = g->f.f4.base_anchor->YCoordinate * size / u;
1940 mark_x = g->f.f4.mark_anchor->XCoordinate * size / u;
1941 mark_y = g->f.f4.mark_anchor->YCoordinate * size / u;
1942
1943 code = XINT (LGLYPH_CODE (prev));
1944 if (g->f.f4.base_anchor->AnchorFormat != 1)
1945 adjust_anchor (font, g->f.f4.base_anchor,
1946 code, size, &base_x, &base_y);
1947 if (g->f.f4.mark_anchor->AnchorFormat != 1)
1948 adjust_anchor (font, g->f.f4.mark_anchor,
1949 code, size, &mark_x, &mark_y);
1950
1951 if (NILP (LGLYPH_WIDTH (prev)))
1952 {
1953 width = font->driver->text_extents (font, &code, 1, NULL);
1954 LGLYPH_SET_WIDTH (prev, make_number (width));
1955 }
1956 else
1957 width = XINT (LGLYPH_WIDTH (prev));
1958 xoff = XINT (LGLYPH_XOFF (prev)) + (base_x - width) - mark_x;
1959 yoff = XINT (LGLYPH_YOFF (prev)) + mark_y - base_y;
1960 }
1961 }
1962 if (xoff || yoff || width_adjust)
1963 {
1964 Lisp_Object adjustment = Fmake_vector (make_number (3), Qnil);
1965
1966 ASET (adjustment, 0, make_number (xoff));
1967 ASET (adjustment, 1, make_number (yoff));
1968 ASET (adjustment, 2, make_number (width_adjust));
1969 LGLYPH_SET_ADJUSTMENT (glyph, adjustment);
1970 }
1971 if (g->GlyphClass == OTF_GlyphClass0)
1972 base = mark = glyph;
1973 else if (g->GlyphClass == OTF_GlyphClassMark)
1974 mark = glyph;
1975 else
1976 base = glyph;
1977 }
1978 }
1979
1980 free (otf_gstring.glyphs);
1981 return i;
1982}
1983
1984#endif /* HAVE_LIBOTF */ 1840#endif /* HAVE_LIBOTF */
1985 1841
1986/* G-string (glyph string) handler */ 1842/* G-string (glyph string) handler */
@@ -1989,55 +1845,26 @@ font_drive_otf (font, otf_features, gstring_in, from, to, gstring_out, idx,
1989 See the docstring of `font-make-gstring' for more detail. */ 1845 See the docstring of `font-make-gstring' for more detail. */
1990 1846
1991struct font * 1847struct font *
1992font_prepare_composition (cmp) 1848font_prepare_composition (cmp, f)
1993 struct composition *cmp; 1849 struct composition *cmp;
1850 FRAME_PTR f;
1994{ 1851{
1995 Lisp_Object gstring 1852 Lisp_Object gstring
1996 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value, 1853 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
1997 cmp->hash_index * 2); 1854 cmp->hash_index * 2);
1998 struct font *font = XSAVE_VALUE (LGSTRING_FONT (gstring))->pointer;
1999 int len = LGSTRING_LENGTH (gstring);
2000 int i;
2001
2002 cmp->font = font;
2003 cmp->lbearing = cmp->rbearing = cmp->pixel_width = 0;
2004 cmp->ascent = font->ascent;
2005 cmp->descent = font->descent;
2006 1855
2007 for (i = 0; i < len; i++) 1856 cmp->font = XSAVE_VALUE (LGSTRING_FONT (gstring))->pointer;
2008 { 1857 cmp->glyph_len = LGSTRING_LENGTH (gstring);
2009 Lisp_Object g = LGSTRING_GLYPH (gstring, i); 1858 cmp->pixel_width = LGSTRING_WIDTH (gstring);
2010 unsigned code; 1859 cmp->lbearing = LGSTRING_LBEARING (gstring);
2011 struct font_metrics metrics; 1860 cmp->rbearing = LGSTRING_RBEARING (gstring);
1861 cmp->ascent = LGSTRING_ASCENT (gstring);
1862 cmp->descent = LGSTRING_DESCENT (gstring);
1863 cmp->width = cmp->pixel_width / FRAME_COLUMN_WIDTH (f);
1864 if (cmp->width == 0)
1865 cmp->width = 1;
2012 1866
2013 if (NILP (LGLYPH_FROM (g))) 1867 return cmp->font;
2014 break;
2015 code = XINT (LGLYPH_CODE (g));
2016 font->driver->text_extents (font, &code, 1, &metrics);
2017 LGLYPH_SET_WIDTH (g, make_number (metrics.width));
2018 metrics.lbearing += LGLYPH_XOFF (g);
2019 metrics.rbearing += LGLYPH_XOFF (g);
2020 metrics.ascent += LGLYPH_YOFF (g);
2021 metrics.descent += LGLYPH_YOFF (g);
2022
2023 if (cmp->lbearing > cmp->pixel_width + metrics.lbearing)
2024 cmp->lbearing = cmp->pixel_width + metrics.lbearing;
2025 if (cmp->rbearing < cmp->pixel_width + metrics.rbearing)
2026 cmp->rbearing = cmp->pixel_width + metrics.rbearing;
2027 if (cmp->ascent < metrics.ascent)
2028 cmp->ascent = metrics.ascent;
2029 if (cmp->descent < metrics.descent)
2030 cmp->descent = metrics.descent;
2031 cmp->pixel_width += metrics.width + LGLYPH_WADJUST (g);
2032 }
2033 cmp->glyph_len = i;
2034 LGSTRING_SET_LBEARING (gstring, make_number (cmp->lbearing));
2035 LGSTRING_SET_RBEARING (gstring, make_number (cmp->rbearing));
2036 LGSTRING_SET_WIDTH (gstring, make_number (cmp->pixel_width));
2037 LGSTRING_SET_ASCENT (gstring, make_number (cmp->ascent));
2038 LGSTRING_SET_DESCENT (gstring, make_number (cmp->descent));
2039
2040 return font;
2041} 1868}
2042 1869
2043int 1870int
@@ -2559,7 +2386,8 @@ font_close_object (f, font_object)
2559} 2386}
2560 2387
2561 2388
2562/* Return 1 iff FONT on F has a glyph for character C. */ 2389/* Return 1 if FONT on F has a glyph for character C, 0 if not, -1 if
2390 FONT is a font-entity and it must be opened to check. */
2563 2391
2564int 2392int
2565font_has_char (f, font, c) 2393font_has_char (f, font, c)
@@ -2658,13 +2486,15 @@ font_get_frame (font)
2658 2486
2659 2487
2660/* Find a font entity best matching with LFACE. If SPEC is non-nil, 2488/* Find a font entity best matching with LFACE. If SPEC is non-nil,
2661 the font must exactly match with it. */ 2489 the font must exactly match with it. C, if not negative, is a
2490 character that the entity must support. */
2662 2491
2663Lisp_Object 2492Lisp_Object
2664font_find_for_lface (f, lface, spec) 2493font_find_for_lface (f, lface, spec, c)
2665 FRAME_PTR f; 2494 FRAME_PTR f;
2666 Lisp_Object *lface; 2495 Lisp_Object *lface;
2667 Lisp_Object spec; 2496 Lisp_Object spec;
2497 int c;
2668{ 2498{
2669 Lisp_Object frame, entities; 2499 Lisp_Object frame, entities;
2670 int i; 2500 int i;
@@ -2673,6 +2503,8 @@ font_find_for_lface (f, lface, spec)
2673 2503
2674 if (NILP (spec)) 2504 if (NILP (spec))
2675 { 2505 {
2506 if (c >= 0x100)
2507 return Qnil;
2676 for (i = 0; i < FONT_SPEC_MAX; i++) 2508 for (i = 0; i < FONT_SPEC_MAX; i++)
2677 ASET (scratch_font_spec, i, Qnil); 2509 ASET (scratch_font_spec, i, Qnil);
2678 ASET (scratch_font_spec, FONT_REGISTRY_INDEX, Qiso8859_1); 2510 ASET (scratch_font_spec, FONT_REGISTRY_INDEX, Qiso8859_1);
@@ -2700,10 +2532,32 @@ font_find_for_lface (f, lface, spec)
2700 } 2532 }
2701 else 2533 else
2702 { 2534 {
2535 Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX);
2536
2537 if (NILP (registry))
2538 registry = Qiso8859_1;
2539
2540 if (c >= 0)
2541 {
2542 struct charset *repertory;
2543
2544 if (font_registry_charsets (registry, NULL, &repertory) < 0)
2545 return Qnil;
2546 if (repertory)
2547 {
2548 if (ENCODE_CHAR (repertory, c)
2549 == CHARSET_INVALID_CODE (repertory))
2550 return Qnil;
2551 /* Any font of this registry support C. So, let's
2552 suppress the further checking. */
2553 c = -1;
2554 }
2555 else if (c > MAX_UNICODE_CHAR)
2556 return Qnil;
2557 }
2703 for (i = 0; i < FONT_SPEC_MAX; i++) 2558 for (i = 0; i < FONT_SPEC_MAX; i++)
2704 ASET (scratch_font_spec, i, AREF (spec, i)); 2559 ASET (scratch_font_spec, i, AREF (spec, i));
2705 if (NILP (AREF (spec, FONT_REGISTRY_INDEX))) 2560 ASET (scratch_font_spec, FONT_REGISTRY_INDEX, registry);
2706 ASET (scratch_font_spec, FONT_REGISTRY_INDEX, Qiso8859_1);
2707 entities = font_list_entities (frame, scratch_font_spec); 2561 entities = font_list_entities (frame, scratch_font_spec);
2708 } 2562 }
2709 2563
@@ -2729,10 +2583,27 @@ font_find_for_lface (f, lface, spec)
2729 font_sort_entites (entities, prefer, frame, spec); 2583 font_sort_entites (entities, prefer, frame, spec);
2730 } 2584 }
2731 2585
2732 return AREF (entities, 0); 2586 if (c < 0)
2733} 2587 return AREF (entities, 0);
2734 2588 for (i = 0; i < ASIZE (entities); i++)
2589 {
2590 int result = font_has_char (f, AREF (entities, i), c);
2591 Lisp_Object font_object;
2735 2592
2593 if (result > 0)
2594 return AREF (entities, i);
2595 if (result <= 0)
2596 continue;
2597 font_object = font_open_for_lface (f, AREF (entities, i), lface, spec);
2598 if (NILP (font_object))
2599 continue;
2600 result = font_has_char (f, font_object, c);
2601 font_close_object (f, font_object);
2602 if (result > 0)
2603 return AREF (entities, i);
2604 }
2605 return Qnil;
2606}
2736 2607
2737 2608
2738Lisp_Object 2609Lisp_Object
@@ -2770,7 +2641,7 @@ font_load_for_face (f, face)
2770 2641
2771 if (NILP (font_object)) 2642 if (NILP (font_object))
2772 { 2643 {
2773 Lisp_Object entity = font_find_for_lface (f, face->lface, Qnil); 2644 Lisp_Object entity = font_find_for_lface (f, face->lface, Qnil, -1);
2774 2645
2775 if (! NILP (entity)) 2646 if (! NILP (entity))
2776 font_object = font_open_for_lface (f, entity, face->lface, Qnil); 2647 font_object = font_open_for_lface (f, entity, face->lface, Qnil);
@@ -3433,18 +3304,19 @@ G-string is sequence of glyphs of a specific font,
3433and is a vector of this form: 3304and is a vector of this form:
3434 [ HEADER GLYPH ... ] 3305 [ HEADER GLYPH ... ]
3435HEADER is a vector of this form: 3306HEADER is a vector of this form:
3436 [FONT-OBJECT LBEARING RBEARING WIDTH ASCENT DESCENT] 3307 [FONT-OBJECT WIDTH LBEARING RBEARING ASCENT DESCENT]
3437where 3308where
3438 FONT-OBJECT is a font-object for all glyphs in the g-string, 3309 FONT-OBJECT is a font-object for all glyphs in the g-string,
3439 LBEARING thry DESCENT is the metrics (in pixels) of the whole G-string. 3310 WIDTH thry DESCENT are the metrics (in pixels) of the whole G-string.
3440GLYPH is a vector of this form: 3311GLYPH is a vector of this form:
3441 [ FROM-IDX TO-IDX C CODE WIDTH [ [X-OFF Y-OFF WADJUST] | nil] ] 3312 [ FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT
3313 [ [X-OFF Y-OFF WADJUST] | nil] ]
3442where 3314where
3443 FROM-IDX and TO-IDX are used internally and should not be touched. 3315 FROM-IDX and TO-IDX are used internally and should not be touched.
3444 C is the character of the glyph. 3316 C is the character of the glyph.
3445 CODE is the glyph-code of C in FONT-OBJECT. 3317 CODE is the glyph-code of C in FONT-OBJECT.
3318 WIDTH thry DESCENT are the metrics (in pixels) of the glyph.
3446 X-OFF and Y-OFF are offests to the base position for the glyph. 3319 X-OFF and Y-OFF are offests to the base position for the glyph.
3447 WIDTH is the normal width of the glyph.
3448 WADJUST is the adjustment to the normal width of the glyph. */) 3320 WADJUST is the adjustment to the normal width of the glyph. */)
3449 (font_object, num) 3321 (font_object, num)
3450 Lisp_Object font_object, num; 3322 Lisp_Object font_object, num;
@@ -3463,7 +3335,7 @@ where
3463 ASET (g, 0, font_object); 3335 ASET (g, 0, font_object);
3464 ASET (gstring, 0, g); 3336 ASET (gstring, 0, g);
3465 for (i = 1; i < len; i++) 3337 for (i = 1; i < len; i++)
3466 ASET (gstring, i, Fmake_vector (make_number (8), Qnil)); 3338 ASET (gstring, i, Fmake_vector (make_number (10), Qnil));
3467 return gstring; 3339 return gstring;
3468} 3340}
3469 3341
@@ -3494,7 +3366,7 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */)
3494 if (XINT (start) > XINT (end) 3366 if (XINT (start) > XINT (end)
3495 || XINT (end) > ASIZE (object) 3367 || XINT (end) > ASIZE (object)
3496 || XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring)) 3368 || XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring))
3497 args_out_of_range (start, end); 3369 args_out_of_range_3 (object, start, end);
3498 3370
3499 len = XINT (end) - XINT (start); 3371 len = XINT (end) - XINT (start);
3500 p = SDATA (object) + string_char_to_byte (object, XINT (start)); 3372 p = SDATA (object) + string_char_to_byte (object, XINT (start));
@@ -3506,10 +3378,10 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */)
3506 code = font->driver->encode_char (font, c); 3378 code = font->driver->encode_char (font, c);
3507 if (code > MOST_POSITIVE_FIXNUM) 3379 if (code > MOST_POSITIVE_FIXNUM)
3508 error ("Glyph code 0x%X is too large", code); 3380 error ("Glyph code 0x%X is too large", code);
3509 LGLYPH_SET_FROM (g, make_number (i)); 3381 LGLYPH_SET_FROM (g, i);
3510 LGLYPH_SET_TO (g, make_number (i + 1)); 3382 LGLYPH_SET_TO (g, i);
3511 LGLYPH_SET_CHAR (g, make_number (c)); 3383 LGLYPH_SET_CHAR (g, c);
3512 LGLYPH_SET_CODE (g, make_number (code)); 3384 LGLYPH_SET_CODE (g, code);
3513 } 3385 }
3514 } 3386 }
3515 else 3387 else
@@ -3532,19 +3404,123 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */)
3532 code = font->driver->encode_char (font, c); 3404 code = font->driver->encode_char (font, c);
3533 if (code > MOST_POSITIVE_FIXNUM) 3405 if (code > MOST_POSITIVE_FIXNUM)
3534 error ("Glyph code 0x%X is too large", code); 3406 error ("Glyph code 0x%X is too large", code);
3535 LGLYPH_SET_FROM (g, make_number (i)); 3407 LGLYPH_SET_FROM (g, i);
3536 LGLYPH_SET_TO (g, make_number (i + 1)); 3408 LGLYPH_SET_TO (g, i);
3537 LGLYPH_SET_CHAR (g, make_number (c)); 3409 LGLYPH_SET_CHAR (g, c);
3538 LGLYPH_SET_CODE (g, make_number (code)); 3410 LGLYPH_SET_CODE (g, code);
3539 } 3411 }
3540 } 3412 }
3541 for (i = LGSTRING_LENGTH (gstring) - 1; i >= len; i--) 3413 for (i = LGSTRING_LENGTH (gstring) - 1; i >= len; i--)
3414 LGSTRING_SET_GLYPH (gstring, i, Qnil);
3415 return Qnil;
3416}
3417
3418DEFUN ("font-shape-text", Ffont_shape_text, Sfont_shape_text, 3, 4, 0,
3419 doc: /* Shape text between FROM and TO by FONT-OBJECT.
3420If optional 4th argument STRING is non-nil, it is a string to shape,
3421and FROM and TO are indices to the string.
3422The value is the end position of the shaped text. */)
3423 (from, to, font_object, string)
3424 Lisp_Object from, to, font_object, string;
3425{
3426 struct font *font;
3427 struct font_metrics metrics;
3428 EMACS_INT start, end;
3429 Lisp_Object gstring, n;
3430 int i;
3431
3432 if (NILP (string))
3433 {
3434 validate_region (&from, &to);
3435 start = XFASTINT (from);
3436 end = XFASTINT (to);
3437 modify_region (current_buffer, start, end, 0);
3438 }
3439 else
3440 {
3441 CHECK_STRING (string);
3442 start = XINT (from);
3443 end = XINT (to);
3444 if (start < 0 || start > end || end > SCHARS (string))
3445 args_out_of_range_3 (string, from, to);
3446 }
3447
3448 CHECK_FONT_GET_OBJECT (font_object, font);
3449 if (! font->driver->shape)
3450 return from;
3451
3452 gstring = Ffont_make_gstring (font_object, make_number (end - start));
3453 Ffont_fill_gstring (gstring, font_object, from, to, string);
3454 n = font->driver->shape (gstring);
3455 if (NILP (n))
3456 return Qnil;
3457 for (i = 0; i < XINT (n);)
3542 { 3458 {
3459 Lisp_Object gstr;
3543 Lisp_Object g = LGSTRING_GLYPH (gstring, i); 3460 Lisp_Object g = LGSTRING_GLYPH (gstring, i);
3461 EMACS_INT this_from = LGLYPH_FROM (g);
3462 EMACS_INT this_to = LGLYPH_TO (g) + 1;
3463 int j, k;
3464
3465 metrics.lbearing = LGLYPH_LBEARING (g);
3466 metrics.rbearing = LGLYPH_RBEARING (g);
3467 metrics.ascent = LGLYPH_ASCENT (g);
3468 metrics.descent = LGLYPH_DESCENT (g);
3469 if (NILP (LGLYPH_ADJUSTMENT (g)))
3470 metrics.width = LGLYPH_WIDTH (g);
3471 else
3472 {
3473 metrics.width = LGLYPH_WADJUST (g);
3474 metrics.lbearing += LGLYPH_XOFF (g);
3475 metrics.rbearing += LGLYPH_XOFF (g);
3476 metrics.ascent -= LGLYPH_YOFF (g);
3477 metrics.descent += LGLYPH_YOFF (g);
3478 }
3479 for (j = i + 1; j < XINT (n); j++)
3480 {
3481 int x;
3482
3483 g = LGSTRING_GLYPH (gstring, j);
3484 if (this_from != LGLYPH_FROM (g))
3485 break;
3486 x = metrics.width + LGLYPH_LBEARING (g) + LGLYPH_XOFF (g);
3487 if (metrics.lbearing > x)
3488 metrics.lbearing = x;
3489 x = metrics.width + LGLYPH_RBEARING (g) + LGLYPH_XOFF (g);
3490 if (metrics.rbearing < x)
3491 metrics.rbearing = x;
3492 x = LGLYPH_ASCENT (g) - LGLYPH_YOFF (g);
3493 if (metrics.ascent < x)
3494 metrics.ascent = x;
3495 x = LGLYPH_DESCENT (g) - LGLYPH_YOFF (g);
3496 if (metrics.descent < x)
3497 metrics.descent = x;
3498 if (NILP (LGLYPH_ADJUSTMENT (g)))
3499 metrics.width += LGLYPH_WIDTH (g);
3500 else
3501 metrics.width += LGLYPH_WADJUST (g);
3502 }
3544 3503
3545 LGLYPH_SET_FROM (g, Qnil); 3504 gstr = Ffont_make_gstring (font_object, make_number (j - i));
3505 LGSTRING_SET_WIDTH (gstr, metrics.width);
3506 LGSTRING_SET_LBEARING (gstr, metrics.lbearing);
3507 LGSTRING_SET_RBEARING (gstr, metrics.rbearing);
3508 LGSTRING_SET_ASCENT (gstr, metrics.ascent);
3509 LGSTRING_SET_DESCENT (gstr, metrics.descent);
3510 for (k = i; i < j; i++)
3511 LGSTRING_SET_GLYPH (gstr, i - k, LGSTRING_GLYPH (gstring, i));
3512 if (NILP (string))
3513 Fcompose_region_internal (make_number (start + this_from),
3514 make_number (start + this_to),
3515 gstr, Qnil);
3516 else
3517 Fcompose_string_internal (string,
3518 make_number (start + this_from),
3519 make_number (start + this_to),
3520 gstr, Qnil);
3546 } 3521 }
3547 return Qnil; 3522
3523 return make_number (start + XINT (n));
3548} 3524}
3549 3525
3550DEFUN ("font-drive-otf", Ffont_drive_otf, Sfont_drive_otf, 6, 6, 0, 3526DEFUN ("font-drive-otf", Ffont_drive_otf, Sfont_drive_otf, 6, 6, 0,
@@ -3687,6 +3663,8 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0,
3687 CHECK_LIVE_FRAME (frame); 3663 CHECK_LIVE_FRAME (frame);
3688 3664
3689 isize = XINT (size); 3665 isize = XINT (size);
3666 if (isize == 0)
3667 isize = 120;
3690 if (isize < 0) 3668 if (isize < 0)
3691 isize = POINT_TO_PIXEL (- isize, XFRAME (frame)->resy); 3669 isize = POINT_TO_PIXEL (- isize, XFRAME (frame)->resy);
3692 3670
@@ -3832,23 +3810,41 @@ FONT is a font-spec, font-entity, or font-object. */)
3832 return (font_match_p (spec, font) ? Qt : Qnil); 3810 return (font_match_p (spec, font) ? Qt : Qnil);
3833} 3811}
3834 3812
3835DEFUN ("font-at", Ffont_at, Sfont_at, 1, 2, 0, 3813DEFUN ("font-at", Ffont_at, Sfont_at, 1, 3, 0,
3836 doc: /* Return a font-object for displaying a character at POSISTION. 3814 doc: /* Return a font-object for displaying a character at POSISTION.
3837Optional second arg WINDOW, if non-nil, is a window displaying 3815Optional second arg WINDOW, if non-nil, is a window displaying
3838the current buffer. It defaults to the currently selected window. */) 3816the current buffer. It defaults to the currently selected window. */)
3839 (position, window) 3817 (position, window, string)
3840 Lisp_Object position, window; 3818 Lisp_Object position, window, string;
3841{ 3819{
3842 struct window *w; 3820 struct window *w;
3843 EMACS_INT pos, pos_byte; 3821 EMACS_INT pos, pos_byte;
3844 int c; 3822 int c;
3845 3823
3846 CHECK_NUMBER_COERCE_MARKER (position); 3824 if (NILP (string))
3847 pos = XINT (position); 3825 {
3848 if (pos < BEGV || pos >= ZV) 3826 CHECK_NUMBER_COERCE_MARKER (position);
3849 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); 3827 pos = XINT (position);
3850 pos_byte = CHAR_TO_BYTE (pos); 3828 if (pos < BEGV || pos >= ZV)
3851 c = FETCH_CHAR (pos_byte); 3829 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
3830 pos_byte = CHAR_TO_BYTE (pos);
3831 c = FETCH_CHAR (pos_byte);
3832 }
3833 else
3834 {
3835 EMACS_INT len;
3836 unsigned char *str;
3837
3838 CHECK_NUMBER (position);
3839 CHECK_STRING (string);
3840 pos = XINT (position);
3841 if (pos < 0 || pos >= SCHARS (string))
3842 args_out_of_range (string, position);
3843 pos_byte = string_char_to_byte (string, pos);
3844 str = SDATA (string) + pos_byte;
3845 len = SBYTES (string) - pos_byte;
3846 c = STRING_CHAR (str, eln);
3847 }
3852 if (NILP (window)) 3848 if (NILP (window))
3853 window = selected_window; 3849 window = selected_window;
3854 CHECK_LIVE_WINDOW (window); 3850 CHECK_LIVE_WINDOW (window);
@@ -3929,6 +3925,9 @@ syms_of_font ()
3929 staticpro (&font_family_alist); 3925 staticpro (&font_family_alist);
3930 font_family_alist = Qnil; 3926 font_family_alist = Qnil;
3931 3927
3928 staticpro (&font_charset_alist);
3929 font_charset_alist = Qnil;
3930
3932 DEFSYM (Qopentype, "opentype"); 3931 DEFSYM (Qopentype, "opentype");
3933 3932
3934 DEFSYM (Qiso8859_1, "iso8859-1"); 3933 DEFSYM (Qiso8859_1, "iso8859-1");
@@ -3981,6 +3980,7 @@ syms_of_font ()
3981 defsubr (&Sinternal_set_font_style_table); 3980 defsubr (&Sinternal_set_font_style_table);
3982 defsubr (&Sfont_make_gstring); 3981 defsubr (&Sfont_make_gstring);
3983 defsubr (&Sfont_fill_gstring); 3982 defsubr (&Sfont_fill_gstring);
3983 defsubr (&Sfont_shape_text);
3984 defsubr (&Sfont_drive_otf); 3984 defsubr (&Sfont_drive_otf);
3985 defsubr (&Sfont_otf_alternates); 3985 defsubr (&Sfont_otf_alternates);
3986 3986
@@ -3996,29 +3996,34 @@ syms_of_font ()
3996#endif 3996#endif
3997#endif /* FONT_DEBUG */ 3997#endif /* FONT_DEBUG */
3998 3998
3999#ifdef USE_FONT_BACKEND
4000 if (enable_font_backend)
4001 {
3999#ifdef HAVE_FREETYPE 4002#ifdef HAVE_FREETYPE
4000 syms_of_ftfont (); 4003 syms_of_ftfont ();
4001#ifdef HAVE_X_WINDOWS 4004#ifdef HAVE_X_WINDOWS
4002 syms_of_xfont (); 4005 syms_of_xfont ();
4003 syms_of_ftxfont (); 4006 syms_of_ftxfont ();
4004#ifdef HAVE_XFT 4007#ifdef HAVE_XFT
4005 syms_of_xftfont (); 4008 syms_of_xftfont ();
4006#endif /* HAVE_XFT */ 4009#endif /* HAVE_XFT */
4007#endif /* HAVE_X_WINDOWS */ 4010#endif /* HAVE_X_WINDOWS */
4008#else /* not HAVE_FREETYPE */ 4011#else /* not HAVE_FREETYPE */
4009#ifdef HAVE_X_WINDOWS 4012#ifdef HAVE_X_WINDOWS
4010 syms_of_xfont (); 4013 syms_of_xfont ();
4011#endif /* HAVE_X_WINDOWS */ 4014#endif /* HAVE_X_WINDOWS */
4012#endif /* not HAVE_FREETYPE */ 4015#endif /* not HAVE_FREETYPE */
4013#ifdef HAVE_BDFFONT 4016#ifdef HAVE_BDFFONT
4014 syms_of_bdffont (); 4017 syms_of_bdffont ();
4015#endif /* HAVE_BDFFONT */ 4018#endif /* HAVE_BDFFONT */
4016#ifdef WINDOWSNT 4019#ifdef WINDOWSNT
4017 syms_of_w32font (); 4020 syms_of_w32font ();
4018#endif /* WINDOWSNT */ 4021#endif /* WINDOWSNT */
4019#ifdef MAC_OS 4022#ifdef MAC_OS
4020 syms_of_atmfont (); 4023 syms_of_atmfont ();
4021#endif /* MAC_OS */ 4024#endif /* MAC_OS */
4025 }
4026#endif /* USE_FONT_BACKEND */
4022} 4027}
4023 4028
4024/* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846 4029/* arch-tag: 74c9475d-5976-4c93-a327-942ae3072846