diff options
Diffstat (limited to 'src/ftfont.c')
| -rw-r--r-- | src/ftfont.c | 171 |
1 files changed, 99 insertions, 72 deletions
diff --git a/src/ftfont.c b/src/ftfont.c index 419274a30aa..4c12ef5d3af 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 24 | #include <fontconfig/fontconfig.h> | 24 | #include <fontconfig/fontconfig.h> |
| 25 | #include <fontconfig/fcfreetype.h> | 25 | #include <fontconfig/fcfreetype.h> |
| 26 | 26 | ||
| 27 | #include <c-strcase.h> | ||
| 28 | |||
| 27 | #include "lisp.h" | 29 | #include "lisp.h" |
| 28 | #include "dispextern.h" | 30 | #include "dispextern.h" |
| 29 | #include "frame.h" | 31 | #include "frame.h" |
| @@ -140,6 +142,12 @@ static struct | |||
| 140 | { NULL } | 142 | { NULL } |
| 141 | }; | 143 | }; |
| 142 | 144 | ||
| 145 | static bool | ||
| 146 | matching_prefix (char const *str, ptrdiff_t len, char const *pat) | ||
| 147 | { | ||
| 148 | return len == strlen (pat) && c_strncasecmp (str, pat, len) == 0; | ||
| 149 | } | ||
| 150 | |||
| 143 | /* Dirty hack for handing ADSTYLE property. | 151 | /* Dirty hack for handing ADSTYLE property. |
| 144 | 152 | ||
| 145 | Fontconfig (actually the underlying FreeType) gives such ADSTYLE | 153 | Fontconfig (actually the underlying FreeType) gives such ADSTYLE |
| @@ -171,18 +179,10 @@ get_adstyle_property (FcPattern *p) | |||
| 171 | return Qnil; | 179 | return Qnil; |
| 172 | str = (char *) fcstr; | 180 | str = (char *) fcstr; |
| 173 | for (end = str; *end && *end != ' '; end++); | 181 | for (end = str; *end && *end != ' '; end++); |
| 174 | if (*end) | 182 | if (matching_prefix (str, end - str, "Regular") |
| 175 | { | 183 | || matching_prefix (str, end - str, "Bold") |
| 176 | char *newstr = alloca (end - str + 1); | 184 | || matching_prefix (str, end - str, "Oblique") |
| 177 | memcpy (newstr, str, end - str); | 185 | || matching_prefix (str, end - str, "Italic")) |
| 178 | newstr[end - str] = '\0'; | ||
| 179 | end = newstr + (end - str); | ||
| 180 | str = newstr; | ||
| 181 | } | ||
| 182 | if (xstrcasecmp (str, "Regular") == 0 | ||
| 183 | || xstrcasecmp (str, "Bold") == 0 | ||
| 184 | || xstrcasecmp (str, "Oblique") == 0 | ||
| 185 | || xstrcasecmp (str, "Italic") == 0) | ||
| 186 | return Qnil; | 186 | return Qnil; |
| 187 | adstyle = font_intern_prop (str, end - str, 1); | 187 | adstyle = font_intern_prop (str, end - str, 1); |
| 188 | if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0) | 188 | if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0) |
| @@ -499,8 +499,8 @@ static Lisp_Object ftfont_open (struct frame *, Lisp_Object, int); | |||
| 499 | static void ftfont_close (struct font *); | 499 | static void ftfont_close (struct font *); |
| 500 | static int ftfont_has_char (Lisp_Object, int); | 500 | static int ftfont_has_char (Lisp_Object, int); |
| 501 | static unsigned ftfont_encode_char (struct font *, int); | 501 | static unsigned ftfont_encode_char (struct font *, int); |
| 502 | static int ftfont_text_extents (struct font *, unsigned *, int, | 502 | static void ftfont_text_extents (struct font *, unsigned *, int, |
| 503 | struct font_metrics *); | 503 | struct font_metrics *); |
| 504 | static int ftfont_get_bitmap (struct font *, unsigned, | 504 | static int ftfont_get_bitmap (struct font *, unsigned, |
| 505 | struct font_bitmap *, int); | 505 | struct font_bitmap *, int); |
| 506 | static int ftfont_anchor_point (struct font *, unsigned, int, | 506 | static int ftfont_anchor_point (struct font *, unsigned, int, |
| @@ -573,7 +573,8 @@ static int | |||
| 573 | ftfont_get_charset (Lisp_Object registry) | 573 | ftfont_get_charset (Lisp_Object registry) |
| 574 | { | 574 | { |
| 575 | char *str = SSDATA (SYMBOL_NAME (registry)); | 575 | char *str = SSDATA (SYMBOL_NAME (registry)); |
| 576 | char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1); | 576 | USE_SAFE_ALLOCA; |
| 577 | char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1); | ||
| 577 | Lisp_Object regexp; | 578 | Lisp_Object regexp; |
| 578 | int i, j; | 579 | int i, j; |
| 579 | 580 | ||
| @@ -589,6 +590,7 @@ ftfont_get_charset (Lisp_Object registry) | |||
| 589 | } | 590 | } |
| 590 | re[j] = '\0'; | 591 | re[j] = '\0'; |
| 591 | regexp = make_unibyte_string (re, j); | 592 | regexp = make_unibyte_string (re, j); |
| 593 | SAFE_FREE (); | ||
| 592 | for (i = 0; fc_charset_table[i].name; i++) | 594 | for (i = 0; fc_charset_table[i].name; i++) |
| 593 | if (fast_c_string_match_ignore_case | 595 | if (fast_c_string_match_ignore_case |
| 594 | (regexp, fc_charset_table[i].name, | 596 | (regexp, fc_charset_table[i].name, |
| @@ -802,7 +804,7 @@ ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **ots | |||
| 802 | *otspec = ftfont_get_open_type_spec (val); | 804 | *otspec = ftfont_get_open_type_spec (val); |
| 803 | if (! *otspec) | 805 | if (! *otspec) |
| 804 | return NULL; | 806 | return NULL; |
| 805 | strcat (otlayout, "otlayout:"); | 807 | strcpy (otlayout, "otlayout:"); |
| 806 | OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9); | 808 | OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9); |
| 807 | script = (*otspec)->script; | 809 | script = (*otspec)->script; |
| 808 | } | 810 | } |
| @@ -1371,19 +1373,18 @@ ftfont_encode_char (struct font *font, int c) | |||
| 1371 | return (code > 0 ? code : FONT_INVALID_CODE); | 1373 | return (code > 0 ? code : FONT_INVALID_CODE); |
| 1372 | } | 1374 | } |
| 1373 | 1375 | ||
| 1374 | static int | 1376 | static void |
| 1375 | ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct font_metrics *metrics) | 1377 | ftfont_text_extents (struct font *font, unsigned int *code, |
| 1378 | int nglyphs, struct font_metrics *metrics) | ||
| 1376 | { | 1379 | { |
| 1377 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | 1380 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; |
| 1378 | FT_Face ft_face = ftfont_info->ft_size->face; | 1381 | FT_Face ft_face = ftfont_info->ft_size->face; |
| 1379 | int width = 0; | 1382 | int i, width = 0; |
| 1380 | int i; | ||
| 1381 | bool first; | 1383 | bool first; |
| 1382 | 1384 | ||
| 1383 | if (ftfont_info->ft_size != ft_face->size) | 1385 | if (ftfont_info->ft_size != ft_face->size) |
| 1384 | FT_Activate_Size (ftfont_info->ft_size); | 1386 | FT_Activate_Size (ftfont_info->ft_size); |
| 1385 | if (metrics) | 1387 | |
| 1386 | memset (metrics, 0, sizeof (struct font_metrics)); | ||
| 1387 | for (i = 0, first = 1; i < nglyphs; i++) | 1388 | for (i = 0, first = 1; i < nglyphs; i++) |
| 1388 | { | 1389 | { |
| 1389 | if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0) | 1390 | if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0) |
| @@ -1392,39 +1393,28 @@ ftfont_text_extents (struct font *font, unsigned int *code, int nglyphs, struct | |||
| 1392 | 1393 | ||
| 1393 | if (first) | 1394 | if (first) |
| 1394 | { | 1395 | { |
| 1395 | if (metrics) | 1396 | metrics->lbearing = m->horiBearingX >> 6; |
| 1396 | { | 1397 | metrics->rbearing = (m->horiBearingX + m->width) >> 6; |
| 1397 | metrics->lbearing = m->horiBearingX >> 6; | 1398 | metrics->ascent = m->horiBearingY >> 6; |
| 1398 | metrics->rbearing = (m->horiBearingX + m->width) >> 6; | 1399 | metrics->descent = (m->height - m->horiBearingY) >> 6; |
| 1399 | metrics->ascent = m->horiBearingY >> 6; | ||
| 1400 | metrics->descent = (m->height - m->horiBearingY) >> 6; | ||
| 1401 | } | ||
| 1402 | first = 0; | 1400 | first = 0; |
| 1403 | } | 1401 | } |
| 1404 | if (metrics) | 1402 | if (metrics->lbearing > width + (m->horiBearingX >> 6)) |
| 1405 | { | 1403 | metrics->lbearing = width + (m->horiBearingX >> 6); |
| 1406 | if (metrics->lbearing > width + (m->horiBearingX >> 6)) | 1404 | if (metrics->rbearing |
| 1407 | metrics->lbearing = width + (m->horiBearingX >> 6); | 1405 | < width + ((m->horiBearingX + m->width) >> 6)) |
| 1408 | if (metrics->rbearing | 1406 | metrics->rbearing |
| 1409 | < width + ((m->horiBearingX + m->width) >> 6)) | 1407 | = width + ((m->horiBearingX + m->width) >> 6); |
| 1410 | metrics->rbearing | 1408 | if (metrics->ascent < (m->horiBearingY >> 6)) |
| 1411 | = width + ((m->horiBearingX + m->width) >> 6); | 1409 | metrics->ascent = m->horiBearingY >> 6; |
| 1412 | if (metrics->ascent < (m->horiBearingY >> 6)) | 1410 | if (metrics->descent > ((m->height - m->horiBearingY) >> 6)) |
| 1413 | metrics->ascent = m->horiBearingY >> 6; | 1411 | metrics->descent = (m->height - m->horiBearingY) >> 6; |
| 1414 | if (metrics->descent > ((m->height - m->horiBearingY) >> 6)) | ||
| 1415 | metrics->descent = (m->height - m->horiBearingY) >> 6; | ||
| 1416 | } | ||
| 1417 | width += m->horiAdvance >> 6; | 1412 | width += m->horiAdvance >> 6; |
| 1418 | } | 1413 | } |
| 1419 | else | 1414 | else |
| 1420 | { | 1415 | width += font->space_width; |
| 1421 | width += font->space_width; | ||
| 1422 | } | ||
| 1423 | } | 1416 | } |
| 1424 | if (metrics) | 1417 | metrics->width = width; |
| 1425 | metrics->width = width; | ||
| 1426 | |||
| 1427 | return width; | ||
| 1428 | } | 1418 | } |
| 1429 | 1419 | ||
| 1430 | static int | 1420 | static int |
| @@ -1700,7 +1690,8 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec) | |||
| 1700 | else if (! otf) | 1690 | else if (! otf) |
| 1701 | return 0; | 1691 | return 0; |
| 1702 | for (n = 1; spec->features[i][n]; n++); | 1692 | for (n = 1; spec->features[i][n]; n++); |
| 1703 | tags = alloca (sizeof (OTF_Tag) * n); | 1693 | USE_SAFE_ALLOCA; |
| 1694 | SAFE_NALLOCA (tags, 1, n); | ||
| 1704 | for (n = 0, negative = 0; spec->features[i][n]; n++) | 1695 | for (n = 0, negative = 0; spec->features[i][n]; n++) |
| 1705 | { | 1696 | { |
| 1706 | if (spec->features[i][n] == 0xFFFFFFFF) | 1697 | if (spec->features[i][n] == 0xFFFFFFFF) |
| @@ -1710,16 +1701,17 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec) | |||
| 1710 | else | 1701 | else |
| 1711 | tags[n] = spec->features[i][n]; | 1702 | tags[n] = spec->features[i][n]; |
| 1712 | } | 1703 | } |
| 1713 | #ifdef M17N_FLT_USE_NEW_FEATURE | 1704 | bool passed = true; |
| 1714 | if (OTF_check_features (otf, i == 0, spec->script, spec->langsys, | 1705 | #ifndef M17N_FLT_USE_NEW_FEATURE |
| 1715 | tags, n - negative) != 1) | 1706 | passed = n - negative > 0; |
| 1716 | return 0; | 1707 | #endif |
| 1717 | #else /* not M17N_FLT_USE_NEW_FEATURE */ | 1708 | if (passed) |
| 1718 | if (n - negative > 0 | 1709 | passed = (OTF_check_features (otf, i == 0, spec->script, |
| 1719 | && OTF_check_features (otf, i == 0, spec->script, spec->langsys, | 1710 | spec->langsys, tags, n - negative) |
| 1720 | tags, n - negative) != 1) | 1711 | != 1); |
| 1712 | SAFE_FREE (); | ||
| 1713 | if (passed) | ||
| 1721 | return 0; | 1714 | return 0; |
| 1722 | #endif /* not M17N_FLT_USE_NEW_FEATURE */ | ||
| 1723 | } | 1715 | } |
| 1724 | return 1; | 1716 | return 1; |
| 1725 | #undef FEATURE_NONE | 1717 | #undef FEATURE_NONE |
| @@ -1811,11 +1803,15 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 1811 | if (len == 0) | 1803 | if (len == 0) |
| 1812 | return from; | 1804 | return from; |
| 1813 | OTF_tag_name (spec->script, script); | 1805 | OTF_tag_name (spec->script, script); |
| 1806 | |||
| 1807 | char langsysbuf[5]; | ||
| 1814 | if (spec->langsys) | 1808 | if (spec->langsys) |
| 1815 | { | 1809 | { |
| 1816 | langsys = alloca (5); | 1810 | langsys = langsysbuf; |
| 1817 | OTF_tag_name (spec->langsys, langsys); | 1811 | OTF_tag_name (spec->langsys, langsys); |
| 1818 | } | 1812 | } |
| 1813 | |||
| 1814 | USE_SAFE_ALLOCA; | ||
| 1819 | for (i = 0; i < 2; i++) | 1815 | for (i = 0; i < 2; i++) |
| 1820 | { | 1816 | { |
| 1821 | char *p; | 1817 | char *p; |
| @@ -1823,10 +1819,11 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 1823 | if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) | 1819 | if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) |
| 1824 | { | 1820 | { |
| 1825 | for (j = 0; spec->features[i][j]; j++); | 1821 | for (j = 0; spec->features[i][j]; j++); |
| 1822 | SAFE_NALLOCA (p, 6, j); | ||
| 1826 | if (i == 0) | 1823 | if (i == 0) |
| 1827 | p = gsub_features = alloca (6 * j); | 1824 | gsub_features = p; |
| 1828 | else | 1825 | else |
| 1829 | p = gpos_features = alloca (6 * j); | 1826 | gpos_features = p; |
| 1830 | for (j = 0; spec->features[i][j]; j++) | 1827 | for (j = 0; spec->features[i][j]; j++) |
| 1831 | { | 1828 | { |
| 1832 | if (spec->features[i][j] == 0xFFFFFFFF) | 1829 | if (spec->features[i][j] == 0xFFFFFFFF) |
| @@ -1858,7 +1855,10 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 1858 | gsub_features) < 0) | 1855 | gsub_features) < 0) |
| 1859 | goto simple_copy; | 1856 | goto simple_copy; |
| 1860 | if (out->allocated < out->used + otf_gstring.used) | 1857 | if (out->allocated < out->used + otf_gstring.used) |
| 1861 | return -2; | 1858 | { |
| 1859 | SAFE_FREE (); | ||
| 1860 | return -2; | ||
| 1861 | } | ||
| 1862 | features = otf->gsub->FeatureList.Feature; | 1862 | features = otf->gsub->FeatureList.Feature; |
| 1863 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) | 1863 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) |
| 1864 | { | 1864 | { |
| @@ -1947,7 +1947,10 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 1947 | else if (out) | 1947 | else if (out) |
| 1948 | { | 1948 | { |
| 1949 | if (out->allocated < out->used + len) | 1949 | if (out->allocated < out->used + len) |
| 1950 | return -2; | 1950 | { |
| 1951 | SAFE_FREE (); | ||
| 1952 | return -2; | ||
| 1953 | } | ||
| 1951 | for (i = 0; i < len; i++) | 1954 | for (i = 0; i < len; i++) |
| 1952 | out->glyphs[out->used++] = in->glyphs[from + i]; | 1955 | out->glyphs[out->used++] = in->glyphs[from + i]; |
| 1953 | } | 1956 | } |
| @@ -1959,7 +1962,10 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 1959 | 1962 | ||
| 1960 | if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, | 1963 | if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, |
| 1961 | gpos_features) < 0) | 1964 | gpos_features) < 0) |
| 1962 | return to; | 1965 | { |
| 1966 | SAFE_FREE (); | ||
| 1967 | return to; | ||
| 1968 | } | ||
| 1963 | features = otf->gpos->FeatureList.Feature; | 1969 | features = otf->gpos->FeatureList.Feature; |
| 1964 | x_ppem = ft_face->size->metrics.x_ppem; | 1970 | x_ppem = ft_face->size->metrics.x_ppem; |
| 1965 | y_ppem = ft_face->size->metrics.y_ppem; | 1971 | y_ppem = ft_face->size->metrics.y_ppem; |
| @@ -2081,7 +2087,10 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 2081 | { | 2087 | { |
| 2082 | if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, | 2088 | if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys, |
| 2083 | gpos_features) < 0) | 2089 | gpos_features) < 0) |
| 2084 | return to; | 2090 | { |
| 2091 | SAFE_FREE (); | ||
| 2092 | return to; | ||
| 2093 | } | ||
| 2085 | features = otf->gpos->FeatureList.Feature; | 2094 | features = otf->gpos->FeatureList.Feature; |
| 2086 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; | 2095 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; |
| 2087 | i++, otfg++) | 2096 | i++, otfg++) |
| @@ -2101,9 +2110,11 @@ ftfont_drive_otf (MFLTFont *font, | |||
| 2101 | } | 2110 | } |
| 2102 | } | 2111 | } |
| 2103 | } | 2112 | } |
| 2113 | SAFE_FREE (); | ||
| 2104 | return to; | 2114 | return to; |
| 2105 | 2115 | ||
| 2106 | simple_copy: | 2116 | simple_copy: |
| 2117 | SAFE_FREE (); | ||
| 2107 | if (! out) | 2118 | if (! out) |
| 2108 | return to; | 2119 | return to; |
| 2109 | if (out->allocated < out->used + len) | 2120 | if (out->allocated < out->used + len) |
| @@ -2141,11 +2152,15 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, | |||
| 2141 | if (len == 0) | 2152 | if (len == 0) |
| 2142 | return from; | 2153 | return from; |
| 2143 | OTF_tag_name (spec->script, script); | 2154 | OTF_tag_name (spec->script, script); |
| 2155 | |||
| 2156 | char langsysbuf[5]; | ||
| 2144 | if (spec->langsys) | 2157 | if (spec->langsys) |
| 2145 | { | 2158 | { |
| 2146 | langsys = alloca (5); | 2159 | langsys = langsysbuf; |
| 2147 | OTF_tag_name (spec->langsys, langsys); | 2160 | OTF_tag_name (spec->langsys, langsys); |
| 2148 | } | 2161 | } |
| 2162 | |||
| 2163 | USE_SAFE_ALLOCA; | ||
| 2149 | for (i = 0; i < 2; i++) | 2164 | for (i = 0; i < 2; i++) |
| 2150 | { | 2165 | { |
| 2151 | char *p; | 2166 | char *p; |
| @@ -2153,10 +2168,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, | |||
| 2153 | if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) | 2168 | if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF) |
| 2154 | { | 2169 | { |
| 2155 | for (j = 0; spec->features[i][j]; j++); | 2170 | for (j = 0; spec->features[i][j]; j++); |
| 2171 | SAFE_NALLOCA (p, 6, j); | ||
| 2156 | if (i == 0) | 2172 | if (i == 0) |
| 2157 | p = gsub_features = alloca (6 * j); | 2173 | gsub_features = p; |
| 2158 | else | 2174 | else |
| 2159 | p = gpos_features = alloca (6 * j); | 2175 | gpos_features = p; |
| 2160 | for (j = 0; spec->features[i][j]; j++) | 2176 | for (j = 0; spec->features[i][j]; j++) |
| 2161 | { | 2177 | { |
| 2162 | if (spec->features[i][j] == 0xFFFFFFFF) | 2178 | if (spec->features[i][j] == 0xFFFFFFFF) |
| @@ -2188,7 +2204,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, | |||
| 2188 | < 0) | 2204 | < 0) |
| 2189 | goto simple_copy; | 2205 | goto simple_copy; |
| 2190 | if (out->allocated < out->used + otf_gstring.used) | 2206 | if (out->allocated < out->used + otf_gstring.used) |
| 2191 | return -2; | 2207 | { |
| 2208 | SAFE_FREE (); | ||
| 2209 | return -2; | ||
| 2210 | } | ||
| 2192 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) | 2211 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) |
| 2193 | { | 2212 | { |
| 2194 | MFLTGlyph *g; | 2213 | MFLTGlyph *g; |
| @@ -2239,7 +2258,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, | |||
| 2239 | else | 2258 | else |
| 2240 | { | 2259 | { |
| 2241 | if (out->allocated < out->used + len) | 2260 | if (out->allocated < out->used + len) |
| 2242 | return -2; | 2261 | { |
| 2262 | SAFE_FREE (); | ||
| 2263 | return -2; | ||
| 2264 | } | ||
| 2243 | for (i = 0; i < len; i++) | 2265 | for (i = 0; i < len; i++) |
| 2244 | out->glyphs[out->used++] = in->glyphs[from + i]; | 2266 | out->glyphs[out->used++] = in->glyphs[from + i]; |
| 2245 | } | 2267 | } |
| @@ -2251,7 +2273,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, | |||
| 2251 | 2273 | ||
| 2252 | if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features) | 2274 | if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features) |
| 2253 | < 0) | 2275 | < 0) |
| 2254 | return to; | 2276 | { |
| 2277 | SAFE_FREE (); | ||
| 2278 | return to; | ||
| 2279 | } | ||
| 2255 | 2280 | ||
| 2256 | x_ppem = ft_face->size->metrics.x_ppem; | 2281 | x_ppem = ft_face->size->metrics.x_ppem; |
| 2257 | y_ppem = ft_face->size->metrics.y_ppem; | 2282 | y_ppem = ft_face->size->metrics.y_ppem; |
| @@ -2361,9 +2386,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in, | |||
| 2361 | base = g; | 2386 | base = g; |
| 2362 | } | 2387 | } |
| 2363 | } | 2388 | } |
| 2389 | SAFE_FREE (); | ||
| 2364 | return to; | 2390 | return to; |
| 2365 | 2391 | ||
| 2366 | simple_copy: | 2392 | simple_copy: |
| 2393 | SAFE_FREE (); | ||
| 2367 | if (out->allocated < out->used + len) | 2394 | if (out->allocated < out->used + len) |
| 2368 | return -2; | 2395 | return -2; |
| 2369 | font->get_metrics (font, in, from, to); | 2396 | font->get_metrics (font, in, from, to); |