diff options
| author | Po Lu | 2023-03-27 11:24:05 +0800 |
|---|---|---|
| committer | Po Lu | 2023-03-27 11:24:05 +0800 |
| commit | 18b34e9ca01deff8e0bde4b1e53293f27712a149 (patch) | |
| tree | 4e80d1cbf5f6211f03c834425f88bc9657fdfb71 /src | |
| parent | 67a325243c6942ff367b24211999554690c328d2 (diff) | |
| download | emacs-18b34e9ca01deff8e0bde4b1e53293f27712a149.tar.gz emacs-18b34e9ca01deff8e0bde4b1e53293f27712a149.zip | |
Refactor sfntfont.c
* src/sfnt.c (sfnt_build_glyph_outline): Take scale, not head
and pixel size.
(sfnt_scale_metrics_to_pixel_size): Delete function.
(sfnt_get_scale): New function.
(main): Update tests.
* src/sfnt.h (PROTOTYPE): Update prototypes.
* src/sfntfont.c (struct sfnt_outline_cache)
(sfntfont_get_glyph_outline, struct sfnt_font_info)
(sfntfont_open): Save scale in font information and use it.
(sfntfont_measure_instructed_pcm): Delete function.
(sfntfont_measure_pcm): Make this the only ``measure pcm''
function.
(sfntfont_draw): Rely on sfntfont_get_glyph_outline for the
scale.
Diffstat (limited to 'src')
| -rw-r--r-- | src/sfnt.c | 57 | ||||
| -rw-r--r-- | src/sfnt.h | 6 | ||||
| -rw-r--r-- | src/sfntfont.c | 169 |
3 files changed, 85 insertions, 147 deletions
diff --git a/src/sfnt.c b/src/sfnt.c index 8e7a30e3b05..9a1094a1ca9 100644 --- a/src/sfnt.c +++ b/src/sfnt.c | |||
| @@ -3760,21 +3760,21 @@ sfnt_curve_to_and_build (struct sfnt_point control, | |||
| 3760 | } | 3760 | } |
| 3761 | 3761 | ||
| 3762 | /* Non-reentrantly build the outline for the specified GLYPH at the | 3762 | /* Non-reentrantly build the outline for the specified GLYPH at the |
| 3763 | given pixel size. Return the outline data with a refcount of 0 | 3763 | given scale factor. Return the outline data with a refcount of 0 |
| 3764 | upon success, or NULL upon failure. | 3764 | upon success, or NULL upon failure. |
| 3765 | 3765 | ||
| 3766 | SCALE is a scale factor that converts between em space and device | ||
| 3767 | space. | ||
| 3768 | |||
| 3766 | Use the scaled glyph METRICS to determine the origin point of the | 3769 | Use the scaled glyph METRICS to determine the origin point of the |
| 3767 | outline. | 3770 | outline. |
| 3768 | 3771 | ||
| 3769 | Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain | 3772 | Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain |
| 3770 | glyphs for compound glyph subcomponents. | 3773 | glyphs for compound glyph subcomponents. */ |
| 3771 | |||
| 3772 | HEAD should be the `head' table of the font. */ | ||
| 3773 | 3774 | ||
| 3774 | TEST_STATIC struct sfnt_glyph_outline * | 3775 | TEST_STATIC struct sfnt_glyph_outline * |
| 3775 | sfnt_build_glyph_outline (struct sfnt_glyph *glyph, | 3776 | sfnt_build_glyph_outline (struct sfnt_glyph *glyph, |
| 3776 | struct sfnt_head_table *head, | 3777 | sfnt_fixed scale, |
| 3777 | int pixel_size, | ||
| 3778 | struct sfnt_glyph_metrics *metrics, | 3778 | struct sfnt_glyph_metrics *metrics, |
| 3779 | sfnt_get_glyph_proc get_glyph, | 3779 | sfnt_get_glyph_proc get_glyph, |
| 3780 | sfnt_free_glyph_proc free_glyph, | 3780 | sfnt_free_glyph_proc free_glyph, |
| @@ -3805,19 +3805,8 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph, | |||
| 3805 | outline->xmax = 0; | 3805 | outline->xmax = 0; |
| 3806 | outline->ymax = 0; | 3806 | outline->ymax = 0; |
| 3807 | 3807 | ||
| 3808 | /* Figure out how to convert from font unit-space to pixel space. | 3808 | /* Set the scale factor. */ |
| 3809 | To turn one unit to its corresponding pixel size given a ppem of | 3809 | build_outline_context.factor = scale; |
| 3810 | 1, the unit must be divided by head->units_per_em. Then, it must | ||
| 3811 | be multipled by the ppem. So, | ||
| 3812 | |||
| 3813 | PIXEL = UNIT / UPEM * PPEM | ||
| 3814 | |||
| 3815 | which means: | ||
| 3816 | |||
| 3817 | PIXEL = UNIT * PPEM / UPEM */ | ||
| 3818 | |||
| 3819 | build_outline_context.factor | ||
| 3820 | = sfnt_div_fixed (pixel_size, head->units_per_em); | ||
| 3821 | 3810 | ||
| 3822 | /* Decompose the outline. */ | 3811 | /* Decompose the outline. */ |
| 3823 | rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build, | 3812 | rc = sfnt_decompose_glyph (glyph, sfnt_move_to_and_build, |
| @@ -4536,21 +4525,24 @@ sfnt_scale_metrics (struct sfnt_glyph_metrics *metrics, | |||
| 4536 | = sfnt_mul_fixed (metrics->advance * 65536, factor); | 4525 | = sfnt_mul_fixed (metrics->advance * 65536, factor); |
| 4537 | } | 4526 | } |
| 4538 | 4527 | ||
| 4539 | /* Like `sfnt_scale_metrics', except it scales the specified metrics | 4528 | /* Calculate the factor used to convert em space to device space for a |
| 4540 | by a factor calculated using the given PPEM and HEAD table's UPEM | 4529 | font with the specified HEAD table and PPEM value. */ |
| 4541 | value. */ | ||
| 4542 | 4530 | ||
| 4543 | MAYBE_UNUSED TEST_STATIC void | 4531 | MAYBE_UNUSED TEST_STATIC sfnt_fixed |
| 4544 | sfnt_scale_metrics_to_pixel_size (struct sfnt_glyph_metrics *metrics, | 4532 | sfnt_get_scale (struct sfnt_head_table *head, int ppem) |
| 4545 | int ppem, | ||
| 4546 | struct sfnt_head_table *head) | ||
| 4547 | { | 4533 | { |
| 4548 | sfnt_fixed factor; | 4534 | /* Figure out how to convert from font unit-space to pixel space. |
| 4535 | To turn one unit to its corresponding pixel size given a ppem of | ||
| 4536 | 1, the unit must be divided by head->units_per_em. Then, it must | ||
| 4537 | be multipled by the ppem. So, | ||
| 4538 | |||
| 4539 | PIXEL = UNIT / UPEM * PPEM | ||
| 4540 | |||
| 4541 | which means: | ||
| 4542 | |||
| 4543 | PIXEL = UNIT * PPEM / UPEM */ | ||
| 4549 | 4544 | ||
| 4550 | /* Now calculate the factor scale lbearing and advance up to the | 4545 | return sfnt_div_fixed (ppem, head->units_per_em); |
| 4551 | given PPEM size. */ | ||
| 4552 | factor = sfnt_div_fixed (ppem, head->units_per_em); | ||
| 4553 | sfnt_scale_metrics (metrics, factor); | ||
| 4554 | } | 4546 | } |
| 4555 | 4547 | ||
| 4556 | 4548 | ||
| @@ -19419,8 +19411,7 @@ main (int argc, char **argv) | |||
| 19419 | 19411 | ||
| 19420 | /* Time this important bit. */ | 19412 | /* Time this important bit. */ |
| 19421 | clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); | 19413 | clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); |
| 19422 | outline = sfnt_build_glyph_outline (glyph, head, | 19414 | outline = sfnt_build_glyph_outline (glyph, scale, |
| 19423 | EASY_PPEM, | ||
| 19424 | &metrics, | 19415 | &metrics, |
| 19425 | sfnt_test_get_glyph, | 19416 | sfnt_test_get_glyph, |
| 19426 | sfnt_test_free_glyph, | 19417 | sfnt_test_free_glyph, |
diff --git a/src/sfnt.h b/src/sfnt.h index 84e51ff6766..fb8cb80bae9 100644 --- a/src/sfnt.h +++ b/src/sfnt.h | |||
| @@ -1370,8 +1370,7 @@ extern void sfnt_free_glyph (struct sfnt_glyph *); | |||
| 1370 | 1370 | ||
| 1371 | #define PROTOTYPE \ | 1371 | #define PROTOTYPE \ |
| 1372 | struct sfnt_glyph *, \ | 1372 | struct sfnt_glyph *, \ |
| 1373 | struct sfnt_head_table *, \ | 1373 | sfnt_fixed, \ |
| 1374 | int, \ | ||
| 1375 | struct sfnt_glyph_metrics *, \ | 1374 | struct sfnt_glyph_metrics *, \ |
| 1376 | sfnt_get_glyph_proc, \ | 1375 | sfnt_get_glyph_proc, \ |
| 1377 | sfnt_free_glyph_proc, \ | 1376 | sfnt_free_glyph_proc, \ |
| @@ -1403,8 +1402,7 @@ extern int sfnt_lookup_glyph_metrics (sfnt_glyph, int, | |||
| 1403 | 1402 | ||
| 1404 | extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *, | 1403 | extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *, |
| 1405 | sfnt_fixed); | 1404 | sfnt_fixed); |
| 1406 | extern void sfnt_scale_metrics_to_pixel_size (struct sfnt_glyph_metrics *, | 1405 | extern sfnt_fixed sfnt_get_scale (struct sfnt_head_table *, int); |
| 1407 | int, struct sfnt_head_table *); | ||
| 1408 | 1406 | ||
| 1409 | #define PROTOTYPE int, struct sfnt_offset_subtable * | 1407 | #define PROTOTYPE int, struct sfnt_offset_subtable * |
| 1410 | extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE); | 1408 | extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE); |
diff --git a/src/sfntfont.c b/src/sfntfont.c index 09aa89a9cdd..346e145082a 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c | |||
| @@ -1648,7 +1648,10 @@ enum | |||
| 1648 | 1648 | ||
| 1649 | /* Caching subsystem. Generating outlines from glyphs is expensive, | 1649 | /* Caching subsystem. Generating outlines from glyphs is expensive, |
| 1650 | and so is rasterizing them, so two caches are maintained for both | 1650 | and so is rasterizing them, so two caches are maintained for both |
| 1651 | glyph outlines and rasters. */ | 1651 | glyph outlines and rasters. |
| 1652 | |||
| 1653 | Computing metrics also requires some expensive processing if the | ||
| 1654 | glyph has instructions or distortions. */ | ||
| 1652 | 1655 | ||
| 1653 | struct sfnt_outline_cache | 1656 | struct sfnt_outline_cache |
| 1654 | { | 1657 | { |
| @@ -1658,6 +1661,9 @@ struct sfnt_outline_cache | |||
| 1658 | /* Pointer to outline. */ | 1661 | /* Pointer to outline. */ |
| 1659 | struct sfnt_glyph_outline *outline; | 1662 | struct sfnt_glyph_outline *outline; |
| 1660 | 1663 | ||
| 1664 | /* Reference to glyph metrics. */ | ||
| 1665 | struct sfnt_glyph_metrics metrics; | ||
| 1666 | |||
| 1661 | /* What glyph this caches. */ | 1667 | /* What glyph this caches. */ |
| 1662 | sfnt_glyph glyph; | 1668 | sfnt_glyph glyph; |
| 1663 | }; | 1669 | }; |
| @@ -1724,20 +1730,21 @@ sfntfont_dereference_outline (struct sfnt_glyph_outline *outline) | |||
| 1724 | } | 1730 | } |
| 1725 | 1731 | ||
| 1726 | /* Get the outline corresponding to the specified GLYPH_CODE in CACHE. | 1732 | /* Get the outline corresponding to the specified GLYPH_CODE in CACHE. |
| 1727 | Use the pixel size PIXEL_SIZE, the glyf table GLYF, and the head | 1733 | Use the scale factor SCALE, the glyf table GLYF, and the head table |
| 1728 | table HEAD. Keep *CACHE_SIZE updated with the number of elements | 1734 | HEAD. Keep *CACHE_SIZE updated with the number of elements in the |
| 1729 | in the cache. | 1735 | cache. |
| 1730 | 1736 | ||
| 1731 | Use the offset information in the long or short loca tables | 1737 | Use the offset information in the long or short loca tables |
| 1732 | LOCA_LONG and LOCA_SHORT, whichever is set. | 1738 | LOCA_LONG and LOCA_SHORT, whichever is set. |
| 1733 | 1739 | ||
| 1734 | Use the specified HMTX, HHEA and MAXP tables when instructing | 1740 | Use the specified HMTX, HEAD, HHEA and MAXP tables when instructing |
| 1735 | compound glyphs. | 1741 | compound glyphs. |
| 1736 | 1742 | ||
| 1737 | If INTERPRETER is non-NULL, then possibly use the unscaled glyph | 1743 | If INTERPRETER is non-NULL, then possibly use it and the |
| 1738 | metrics in METRICS and the interpreter STATE to instruct the glyph. | 1744 | interpreter graphics STATE to instruct the glyph. |
| 1739 | Otherwise, METRICS must contain scaled glyph metrics used to | 1745 | |
| 1740 | compute the origin point of the outline. | 1746 | If METRICS is non-NULL, return the scaled glyph metrics after |
| 1747 | variation and instructing. | ||
| 1741 | 1748 | ||
| 1742 | Return the outline with an incremented reference count and enter | 1749 | Return the outline with an incremented reference count and enter |
| 1743 | the generated outline into CACHE upon success, possibly discarding | 1750 | the generated outline into CACHE upon success, possibly discarding |
| @@ -1746,7 +1753,7 @@ sfntfont_dereference_outline (struct sfnt_glyph_outline *outline) | |||
| 1746 | static struct sfnt_glyph_outline * | 1753 | static struct sfnt_glyph_outline * |
| 1747 | sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | 1754 | sfntfont_get_glyph_outline (sfnt_glyph glyph_code, |
| 1748 | struct sfnt_outline_cache *cache, | 1755 | struct sfnt_outline_cache *cache, |
| 1749 | int pixel_size, int *cache_size, | 1756 | sfnt_fixed scale, int *cache_size, |
| 1750 | struct sfnt_glyf_table *glyf, | 1757 | struct sfnt_glyf_table *glyf, |
| 1751 | struct sfnt_head_table *head, | 1758 | struct sfnt_head_table *head, |
| 1752 | struct sfnt_hmtx_table *hmtx, | 1759 | struct sfnt_hmtx_table *hmtx, |
| @@ -1785,6 +1792,9 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1785 | start->last->next = start; | 1792 | start->last->next = start; |
| 1786 | start->outline->refcount++; | 1793 | start->outline->refcount++; |
| 1787 | 1794 | ||
| 1795 | if (metrics) | ||
| 1796 | *metrics = start->metrics; | ||
| 1797 | |||
| 1788 | return start->outline; | 1798 | return start->outline; |
| 1789 | } | 1799 | } |
| 1790 | } | 1800 | } |
| @@ -1804,6 +1814,12 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1804 | dcontext.loca_short = loca_short; | 1814 | dcontext.loca_short = loca_short; |
| 1805 | dcontext.glyf = glyf; | 1815 | dcontext.glyf = glyf; |
| 1806 | 1816 | ||
| 1817 | /* Now load the glyph's unscaled metrics into TEMP. */ | ||
| 1818 | |||
| 1819 | if (sfnt_lookup_glyph_metrics (glyph_code, -1, &temp, hmtx, hhea, | ||
| 1820 | head, maxp)) | ||
| 1821 | goto fail; | ||
| 1822 | |||
| 1807 | if (interpreter) | 1823 | if (interpreter) |
| 1808 | { | 1824 | { |
| 1809 | if (glyph->simple) | 1825 | if (glyph->simple) |
| @@ -1813,7 +1829,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1813 | interpreter->state = *state; | 1829 | interpreter->state = *state; |
| 1814 | 1830 | ||
| 1815 | error = sfnt_interpret_simple_glyph (glyph, interpreter, | 1831 | error = sfnt_interpret_simple_glyph (glyph, interpreter, |
| 1816 | metrics, &value); | 1832 | &temp, &value); |
| 1817 | } | 1833 | } |
| 1818 | else | 1834 | else |
| 1819 | /* Restoring the interpreter state is done by | 1835 | /* Restoring the interpreter state is done by |
| @@ -1824,7 +1840,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1824 | sfntfont_get_glyph, | 1840 | sfntfont_get_glyph, |
| 1825 | sfntfont_free_glyph, | 1841 | sfntfont_free_glyph, |
| 1826 | hmtx, hhea, maxp, | 1842 | hmtx, hhea, maxp, |
| 1827 | metrics, &dcontext, | 1843 | &temp, &dcontext, |
| 1828 | &value); | 1844 | &value); |
| 1829 | 1845 | ||
| 1830 | if (!error) | 1846 | if (!error) |
| @@ -1834,32 +1850,29 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1834 | } | 1850 | } |
| 1835 | } | 1851 | } |
| 1836 | 1852 | ||
| 1853 | /* At this point, the glyph metrics are unscaled. Scale them up. | ||
| 1854 | If INTERPRETER is set, use the scale placed within. */ | ||
| 1855 | |||
| 1856 | sfnt_scale_metrics (&temp, scale); | ||
| 1857 | |||
| 1837 | if (!outline) | 1858 | if (!outline) |
| 1838 | { | 1859 | { |
| 1839 | /* If INTERPRETER is NULL, METRICS contains scaled metrics. */ | ||
| 1840 | |||
| 1841 | if (!interpreter) | 1860 | if (!interpreter) |
| 1842 | outline = sfnt_build_glyph_outline (glyph, head, pixel_size, | 1861 | outline = sfnt_build_glyph_outline (glyph, scale, |
| 1843 | metrics, | 1862 | &temp, |
| 1844 | sfntfont_get_glyph, | 1863 | sfntfont_get_glyph, |
| 1845 | sfntfont_free_glyph, | 1864 | sfntfont_free_glyph, |
| 1846 | &dcontext); | 1865 | &dcontext); |
| 1847 | else | 1866 | else |
| 1848 | { | 1867 | outline = sfnt_build_glyph_outline (glyph, scale, |
| 1849 | /* But otherwise, they are unscaled, and must be scaled | 1868 | &temp, |
| 1850 | before being used. */ | 1869 | sfntfont_get_glyph, |
| 1851 | 1870 | sfntfont_free_glyph, | |
| 1852 | temp = *metrics; | 1871 | &dcontext); |
| 1853 | sfnt_scale_metrics_to_pixel_size (&temp, pixel_size, | ||
| 1854 | head); | ||
| 1855 | outline = sfnt_build_glyph_outline (glyph, head, pixel_size, | ||
| 1856 | &temp, | ||
| 1857 | sfntfont_get_glyph, | ||
| 1858 | sfntfont_free_glyph, | ||
| 1859 | &dcontext); | ||
| 1860 | } | ||
| 1861 | } | 1872 | } |
| 1862 | 1873 | ||
| 1874 | fail: | ||
| 1875 | |||
| 1863 | xfree (glyph); | 1876 | xfree (glyph); |
| 1864 | 1877 | ||
| 1865 | if (!outline) | 1878 | if (!outline) |
| @@ -1868,6 +1881,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1868 | start = xmalloc (sizeof *start); | 1881 | start = xmalloc (sizeof *start); |
| 1869 | start->glyph = glyph_code; | 1882 | start->glyph = glyph_code; |
| 1870 | start->outline = outline; | 1883 | start->outline = outline; |
| 1884 | start->metrics = temp; | ||
| 1871 | 1885 | ||
| 1872 | /* One reference goes to the cache. The second reference goes to | 1886 | /* One reference goes to the cache. The second reference goes to |
| 1873 | the caller. */ | 1887 | the caller. */ |
| @@ -1898,7 +1912,11 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, | |||
| 1898 | (*cache_size)--; | 1912 | (*cache_size)--; |
| 1899 | } | 1913 | } |
| 1900 | 1914 | ||
| 1901 | /* Return the cached outline. */ | 1915 | /* Return the cached outline and metrics. */ |
| 1916 | |||
| 1917 | if (metrics) | ||
| 1918 | *metrics = temp; | ||
| 1919 | |||
| 1902 | return outline; | 1920 | return outline; |
| 1903 | } | 1921 | } |
| 1904 | 1922 | ||
| @@ -2104,6 +2122,9 @@ struct sfnt_font_info | |||
| 2104 | programs. */ | 2122 | programs. */ |
| 2105 | struct sfnt_graphics_state state; | 2123 | struct sfnt_graphics_state state; |
| 2106 | 2124 | ||
| 2125 | /* Factor used to convert from em space to pixel space. */ | ||
| 2126 | sfnt_fixed scale; | ||
| 2127 | |||
| 2107 | #ifdef HAVE_MMAP | 2128 | #ifdef HAVE_MMAP |
| 2108 | /* Whether or not the glyph table has been mmapped. */ | 2129 | /* Whether or not the glyph table has been mmapped. */ |
| 2109 | bool glyf_table_mapped; | 2130 | bool glyf_table_mapped; |
| @@ -2647,6 +2668,7 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 2647 | font_info->raster_cache.last = &font_info->raster_cache; | 2668 | font_info->raster_cache.last = &font_info->raster_cache; |
| 2648 | font_info->raster_cache_size = 0; | 2669 | font_info->raster_cache_size = 0; |
| 2649 | font_info->interpreter = NULL; | 2670 | font_info->interpreter = NULL; |
| 2671 | font_info->scale = 0; | ||
| 2650 | #ifdef HAVE_MMAP | 2672 | #ifdef HAVE_MMAP |
| 2651 | font_info->glyf_table_mapped = false; | 2673 | font_info->glyf_table_mapped = false; |
| 2652 | #endif /* HAVE_MMAP */ | 2674 | #endif /* HAVE_MMAP */ |
| @@ -2682,6 +2704,9 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 2682 | font_info->cmap_subtable = tables->cmap_subtable; | 2704 | font_info->cmap_subtable = tables->cmap_subtable; |
| 2683 | font_info->uvs = tables->uvs; | 2705 | font_info->uvs = tables->uvs; |
| 2684 | 2706 | ||
| 2707 | /* Calculate the font's scaling factor. */ | ||
| 2708 | font_info->scale = sfnt_get_scale (font_info->head, pixel_size); | ||
| 2709 | |||
| 2685 | /* Fill in font data. */ | 2710 | /* Fill in font data. */ |
| 2686 | font = &font_info->font; | 2711 | font = &font_info->font; |
| 2687 | font->pixel_size = pixel_size; | 2712 | font->pixel_size = pixel_size; |
| @@ -2819,21 +2844,16 @@ sfntfont_encode_char (struct font *font, int c) | |||
| 2819 | Value is 0 upon success, 1 otherwise. */ | 2844 | Value is 0 upon success, 1 otherwise. */ |
| 2820 | 2845 | ||
| 2821 | static int | 2846 | static int |
| 2822 | sfntfont_measure_instructed_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, | 2847 | sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, |
| 2823 | struct font_metrics *pcm) | 2848 | struct font_metrics *pcm) |
| 2824 | { | 2849 | { |
| 2825 | struct sfnt_glyph_metrics metrics; | 2850 | struct sfnt_glyph_metrics metrics; |
| 2826 | struct sfnt_glyph_outline *outline; | 2851 | struct sfnt_glyph_outline *outline; |
| 2827 | 2852 | ||
| 2828 | /* Ask for unscaled metrics. */ | ||
| 2829 | if (sfnt_lookup_glyph_metrics (glyph, -1, &metrics, font->hmtx, | ||
| 2830 | font->hhea, font->head, font->maxp)) | ||
| 2831 | return 1; | ||
| 2832 | |||
| 2833 | /* Now get the glyph outline, which is required to obtain the rsb, | 2853 | /* Now get the glyph outline, which is required to obtain the rsb, |
| 2834 | ascent and descent. */ | 2854 | ascent and descent. */ |
| 2835 | outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache, | 2855 | outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache, |
| 2836 | font->font.pixel_size, | 2856 | font->scale, |
| 2837 | &font->outline_cache_size, | 2857 | &font->outline_cache_size, |
| 2838 | font->glyf, font->head, | 2858 | font->glyf, font->head, |
| 2839 | font->hmtx, font->hhea, | 2859 | font->hmtx, font->hhea, |
| @@ -2846,57 +2866,6 @@ sfntfont_measure_instructed_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, | |||
| 2846 | if (!outline) | 2866 | if (!outline) |
| 2847 | return 1; | 2867 | return 1; |
| 2848 | 2868 | ||
| 2849 | /* Scale the metrics by the interpreter's scale. */ | ||
| 2850 | sfnt_scale_metrics (&metrics, font->interpreter->scale); | ||
| 2851 | |||
| 2852 | pcm->lbearing = metrics.lbearing >> 16; | ||
| 2853 | pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) >> 16; | ||
| 2854 | |||
| 2855 | /* Round the advance, ascent and descent upwards. */ | ||
| 2856 | pcm->width = SFNT_CEIL_FIXED (metrics.advance) >> 16; | ||
| 2857 | pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) >> 16; | ||
| 2858 | pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) >> 16; | ||
| 2859 | |||
| 2860 | sfntfont_dereference_outline (outline); | ||
| 2861 | return 0; | ||
| 2862 | } | ||
| 2863 | |||
| 2864 | /* Measure the single glyph GLYPH in the font FONT and return its | ||
| 2865 | metrics in *PCM. Value is 0 upon success, 1 otherwise. */ | ||
| 2866 | |||
| 2867 | static int | ||
| 2868 | sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, | ||
| 2869 | struct font_metrics *pcm) | ||
| 2870 | { | ||
| 2871 | struct sfnt_glyph_metrics metrics; | ||
| 2872 | struct sfnt_glyph_outline *outline; | ||
| 2873 | |||
| 2874 | if (font->interpreter) | ||
| 2875 | /* Use a function which instructs the glyph. */ | ||
| 2876 | return sfntfont_measure_instructed_pcm (font, glyph, pcm); | ||
| 2877 | |||
| 2878 | /* Get the glyph metrics first. */ | ||
| 2879 | if (sfnt_lookup_glyph_metrics (glyph, font->font.pixel_size, | ||
| 2880 | &metrics, font->hmtx, font->hhea, | ||
| 2881 | font->head, font->maxp)) | ||
| 2882 | return 1; | ||
| 2883 | |||
| 2884 | /* Now get the glyph outline, which is required to obtain the rsb, | ||
| 2885 | ascent and descent. */ | ||
| 2886 | outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache, | ||
| 2887 | font->font.pixel_size, | ||
| 2888 | &font->outline_cache_size, | ||
| 2889 | font->glyf, font->head, | ||
| 2890 | font->hmtx, font->hhea, | ||
| 2891 | font->maxp, | ||
| 2892 | font->loca_short, | ||
| 2893 | font->loca_long, NULL, | ||
| 2894 | &metrics, NULL); | ||
| 2895 | |||
| 2896 | if (!outline) | ||
| 2897 | return 1; | ||
| 2898 | |||
| 2899 | /* How to round lbearing and rbearing? */ | ||
| 2900 | pcm->lbearing = metrics.lbearing >> 16; | 2869 | pcm->lbearing = metrics.lbearing >> 16; |
| 2901 | pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) >> 16; | 2870 | pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) >> 16; |
| 2902 | 2871 | ||
| @@ -3049,15 +3018,10 @@ sfntfont_draw (struct glyph_string *s, int from, int to, | |||
| 3049 | struct font *font; | 3018 | struct font *font; |
| 3050 | struct sfnt_font_info *info; | 3019 | struct sfnt_font_info *info; |
| 3051 | struct sfnt_glyph_metrics metrics; | 3020 | struct sfnt_glyph_metrics metrics; |
| 3052 | int pixel_size; | ||
| 3053 | 3021 | ||
| 3054 | length = to - from; | 3022 | length = to - from; |
| 3055 | font = s->font; | 3023 | font = s->font; |
| 3056 | info = (struct sfnt_font_info *) font; | 3024 | info = (struct sfnt_font_info *) font; |
| 3057 | pixel_size = font->pixel_size; | ||
| 3058 | |||
| 3059 | if (info->interpreter) | ||
| 3060 | pixel_size = -1; | ||
| 3061 | 3025 | ||
| 3062 | rasters = alloca (length * sizeof *rasters); | 3026 | rasters = alloca (length * sizeof *rasters); |
| 3063 | x_coords = alloca (length * sizeof *x_coords); | 3027 | x_coords = alloca (length * sizeof *x_coords); |
| @@ -3066,21 +3030,10 @@ sfntfont_draw (struct glyph_string *s, int from, int to, | |||
| 3066 | /* Get rasters and outlines for them. */ | 3030 | /* Get rasters and outlines for them. */ |
| 3067 | for (i = from; i < to; ++i) | 3031 | for (i = from; i < to; ++i) |
| 3068 | { | 3032 | { |
| 3069 | /* Look up the metrics for this glyph. The metrics are unscaled | ||
| 3070 | if INFO->interpreter is set. */ | ||
| 3071 | if (sfnt_lookup_glyph_metrics (s->char2b[i], pixel_size, | ||
| 3072 | &metrics, info->hmtx, info->hhea, | ||
| 3073 | info->head, info->maxp)) | ||
| 3074 | { | ||
| 3075 | rasters[i - from] = NULL; | ||
| 3076 | x_coords[i - from] = 0; | ||
| 3077 | continue; | ||
| 3078 | } | ||
| 3079 | |||
| 3080 | /* Look up the outline. */ | 3033 | /* Look up the outline. */ |
| 3081 | outline = sfntfont_get_glyph_outline (s->char2b[i], | 3034 | outline = sfntfont_get_glyph_outline (s->char2b[i], |
| 3082 | &info->outline_cache, | 3035 | &info->outline_cache, |
| 3083 | font->pixel_size, | 3036 | info->scale, |
| 3084 | &info->outline_cache_size, | 3037 | &info->outline_cache_size, |
| 3085 | info->glyf, info->head, | 3038 | info->glyf, info->head, |
| 3086 | info->hmtx, info->hhea, | 3039 | info->hmtx, info->hhea, |
| @@ -3098,10 +3051,6 @@ sfntfont_draw (struct glyph_string *s, int from, int to, | |||
| 3098 | continue; | 3051 | continue; |
| 3099 | } | 3052 | } |
| 3100 | 3053 | ||
| 3101 | /* Scale the metrics if info->interpreter is set. */ | ||
| 3102 | if (info->interpreter) | ||
| 3103 | sfnt_scale_metrics (&metrics, info->interpreter->scale); | ||
| 3104 | |||
| 3105 | /* Rasterize the outline. */ | 3054 | /* Rasterize the outline. */ |
| 3106 | rasters[i - from] = sfntfont_get_glyph_raster (s->char2b[i], | 3055 | rasters[i - from] = sfntfont_get_glyph_raster (s->char2b[i], |
| 3107 | &info->raster_cache, | 3056 | &info->raster_cache, |