aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-02-08 16:34:29 +0800
committerPo Lu2023-02-08 16:34:29 +0800
commit1a70941c8ed58e5b78fec406f30457765f38daef (patch)
tree7c83a40723a579688f7817d4d12581337220d21b /src
parentbd55cca4b8c8b9ff5dd0413716eb51181b9baae8 (diff)
downloademacs-1a70941c8ed58e5b78fec406f30457765f38daef.tar.gz
emacs-1a70941c8ed58e5b78fec406f30457765f38daef.zip
Improve text display on Android port
* src/sfnt.c (sfnt_build_glyph_outline): Clear build_outline_context. (sfnt_poly_coverage): Extend coverage map. (sfnt_prepare_raster): Always floor coordinates, since the increase in coverage makes this hack unnecessary. (sfnt_build_outline_edges): Likewise. (sfnt_compare_edges): Remove function. (sfnt_edge_sort): New function. Since edges are already partially sorted, and there are not many, insertion sort suffices. (sfnt_poly_edges): Use sfnt_edge_sort. (sfnt_fill_span): Stop rounding x0 and x1 to the grid, and make coverage computation static. (sfnt_lookup_glyph_metrics): Fix return code for unscaled metrics. (sfnt_scale_metrics): New function. (SFNT_ENABLE_HINTING): Remove define. (struct sfnt_cvt_table, struct sfnt_fpgm_table) (struct sfnt_prep_table): Move to sfnt.h. (sfnt_read_cvt_table): (sfnt_read_fpgm_table, sfnt_read_prep_table): Make TEST_STATIC. (struct sfnt_unit_vector, struct sfnt_interpreter_definition) (struct sfnt_interpreter_zone, struct sfnt_graphics_state): (struct sfnt_interpreter): Move to sfnt.h. (sfnt_make_interpreter): Make TEST_STATIC. (POP, PUSH, DELTAP1, DELTAP2, DELTAP3): When TEST, define to regular push and pop. (sfnt_deltac): (sfnt_deltap): Fix order of arguments. (IUP_SINGLE_PAIR): Fix interpolation loop wraparound. (sfnt_interpret_font_program): (sfnt_interpret_control_value_program): Make TEST_STATIC. (struct sfnt_instructed_outline): Move to sfnt.h. (sfnt_build_instructed_outline): Make TEST_STATIC. (sfnt_interpret_simple_glyph): (sfnt_x_raster): (sfnt_test_raster): (all_tests): (sfnt_verbose): (main): Improve test code. * src/sfnt.h (SFNT_ENABLE_HINTING, struct sfnt_cvt_table) (struct sfnt_fpgm_table, struct sfnt_prep_table) (struct sfnt_unit_vector, struct sfnt_interpreter_definition) (struct sfnt_interpreter_zone, struct sfnt_graphics_state) (struct sfnt_interpreter, struct sfnt_instructed_outline) (PROTOTYPE): New definitions. * src/sfntfont-android.c (sfntfont_android_put_glyphs): Make coordinate generation more straightforward. * src/sfntfont.c (sfntfont_get_glyph_outline): New arguments INTERPRETER and METRICS. (struct sfnt_font_info): New tables. (sfntfont_setup_interpreter): New function. (sfntfont_open): Avoid memory leak. Set up interpreter. (sfntfont_measure_instructed_pcm): New function. (sfntfont_measure_pcm): Delegate to measure_instructed_pcm where appropriate. (sfntfont_close): Free new tables. (sfntfont_draw): Scale metrics properly.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c913
-rw-r--r--src/sfnt.h483
-rw-r--r--src/sfntfont-android.c4
-rw-r--r--src/sfntfont.c238
4 files changed, 1078 insertions, 560 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index ab21c41b8a0..8dc189919b7 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -3459,6 +3459,8 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3459 struct sfnt_glyph_outline *outline; 3459 struct sfnt_glyph_outline *outline;
3460 int rc; 3460 int rc;
3461 3461
3462 memset (&build_outline_context, 0, sizeof build_outline_context);
3463
3462 /* Allocate the outline now with enough for 44 words at the end. */ 3464 /* Allocate the outline now with enough for 44 words at the end. */
3463 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline)); 3465 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline));
3464 outline->outline_size = 40; 3466 outline->outline_size = 40;
@@ -3521,12 +3523,16 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph,
3521/* Coverage table. This is a four dimensional array indiced by the Y, 3523/* Coverage table. This is a four dimensional array indiced by the Y,
3522 then X axis fractional, shifted down to 2 bits. */ 3524 then X axis fractional, shifted down to 2 bits. */
3523 3525
3524static unsigned char sfnt_poly_coverage[4][4] = 3526static const unsigned char sfnt_poly_coverage[8][9] =
3525 { 3527 {
3526 { 0x10, 0x10, 0x10, 0x10 }, 3528 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3527 { 0x10, 0x10, 0x10, 0x10 }, 3529 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3528 { 0x0f, 0x10, 0x10, 0x10 }, 3530 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3529 { 0x10, 0x10, 0x10, 0x10 }, 3531 { 0, 3, 7, 11, 15, 19, 23, 27, 31, },
3532 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3533 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3534 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3535 { 0, 4, 8, 12, 16, 20, 24, 28, 32, },
3530 }; 3536 };
3531 3537
3532/* Return the nearest coordinate on the sample grid no less than 3538/* Return the nearest coordinate on the sample grid no less than
@@ -3566,7 +3572,7 @@ sfnt_prepare_raster (struct sfnt_raster *raster,
3566 + (SFNT_POLY_ALIGNMENT - 1)) 3572 + (SFNT_POLY_ALIGNMENT - 1))
3567 & ~(SFNT_POLY_ALIGNMENT - 1)); 3573 & ~(SFNT_POLY_ALIGNMENT - 1));
3568 3574
3569 raster->offx = sfnt_round_fixed (outline->xmin) >> 16; 3575 raster->offx = sfnt_floor_fixed (outline->xmin) >> 16;
3570 raster->offy = sfnt_floor_fixed (outline->ymin) >> 16; 3576 raster->offy = sfnt_floor_fixed (outline->ymin) >> 16;
3571} 3577}
3572 3578
@@ -3602,10 +3608,9 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3602 edge = 0; 3608 edge = 0;
3603 3609
3604 /* ymin and xmin must be the same as the offset used to set offy and 3610 /* ymin and xmin must be the same as the offset used to set offy and
3605 offx in rasters. However, xmin is not floored; otherwise, glyphs 3611 offx in rasters. */
3606 like ``e'' look bad at certain ppem. */
3607 ymin = sfnt_floor_fixed (outline->ymin); 3612 ymin = sfnt_floor_fixed (outline->ymin);
3608 xmin = outline->xmin; 3613 xmin = sfnt_floor_fixed (outline->xmin);
3609 3614
3610 for (i = 0; i < outline->outline_used; ++i) 3615 for (i = 0; i < outline->outline_used; ++i)
3611 { 3616 {
@@ -3694,15 +3699,31 @@ sfnt_build_outline_edges (struct sfnt_glyph_outline *outline,
3694 edge_proc (edges, edge, dcontext); 3699 edge_proc (edges, edge, dcontext);
3695} 3700}
3696 3701
3697static int 3702/* Sort an array of SIZE edges to increase by bottom Y position, in
3698sfnt_compare_edges (const void *a, const void *b) 3703 preparation for building spans.
3704
3705 Insertion sort is used because there are usually not very many
3706 edges, and anything larger would bloat up the code. */
3707
3708static void
3709sfnt_edge_sort (struct sfnt_edge *edges, size_t size)
3699{ 3710{
3700 const struct sfnt_edge *first, *second; 3711 ssize_t i, j;
3712 struct sfnt_edge edge;
3701 3713
3702 first = a; 3714 for (i = 1; i < size; ++i)
3703 second = b; 3715 {
3716 edge = edges[i];
3717 j = i - 1;
3718
3719 while (j >= 0 && (edges[j].bottom > edge.bottom))
3720 {
3721 edges[j + 1] = edges[j];
3722 j--;
3723 }
3704 3724
3705 return (int) (first->bottom - second->bottom); 3725 edges[j + 1] = edge;
3726 }
3706} 3727}
3707 3728
3708/* Draw EDGES, an unsorted array of polygon edges of size SIZE. For 3729/* Draw EDGES, an unsorted array of polygon edges of size SIZE. For
@@ -3751,7 +3772,7 @@ sfnt_poly_edges (struct sfnt_edge *edges, size_t size,
3751 3772
3752 /* Sort edges to ascend by Y-order. Once again, remember: cartesian 3773 /* Sort edges to ascend by Y-order. Once again, remember: cartesian
3753 coordinates. */ 3774 coordinates. */
3754 qsort (edges, size, sizeof *edges, sfnt_compare_edges); 3775 sfnt_edge_sort (edges, size);
3755 3776
3756 /* Step down line by line. Find active edges. */ 3777 /* Step down line by line. Find active edges. */
3757 3778
@@ -3837,10 +3858,10 @@ sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
3837 sfnt_fixed x0, sfnt_fixed x1) 3858 sfnt_fixed x0, sfnt_fixed x1)
3838{ 3859{
3839 unsigned char *start; 3860 unsigned char *start;
3840 unsigned char *coverage; 3861 const unsigned char *coverage;
3841 sfnt_fixed left, right, end; 3862 sfnt_fixed left, right, end;
3842 unsigned short w, a; 3863 unsigned short w, a;
3843 int row, col; 3864 int row;
3844 3865
3845 /* Clip bounds to pixmap. */ 3866 /* Clip bounds to pixmap. */
3846 if (x0 < 0) 3867 if (x0 < 0)
@@ -3863,16 +3884,10 @@ sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
3863 return; 3884 return;
3864 3885
3865 /* Set start, then start filling according to coverage. left and 3886 /* Set start, then start filling according to coverage. left and
3866 right are now 16.2. */ 3887 right are now .3. */
3867 left = sfnt_poly_grid_ceil (x0) >> (16 - SFNT_POLY_SHIFT); 3888 left = x0 >> (16 - SFNT_POLY_SHIFT);
3868 right = sfnt_poly_grid_ceil (x1) >> (16 - SFNT_POLY_SHIFT); 3889 right = x1 >> (16 - SFNT_POLY_SHIFT);
3869#if 7 > __GNUC__
3870 start = raster->cells + row * raster->stride; 3890 start = raster->cells + row * raster->stride;
3871#else
3872 start = __builtin_assume_aligned ((raster->cells
3873 + row * raster->stride),
3874 SFNT_POLY_ALIGNMENT);
3875#endif
3876 start += left >> SFNT_POLY_SHIFT; 3891 start += left >> SFNT_POLY_SHIFT;
3877 3892
3878 w = 0; 3893 w = 0;
@@ -3880,25 +3895,25 @@ sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
3880 /* Compute coverage for first pixel, then poly. */ 3895 /* Compute coverage for first pixel, then poly. */
3881 if (left & SFNT_POLY_MASK) 3896 if (left & SFNT_POLY_MASK)
3882 { 3897 {
3883 /* Note that col is an index into the columns of the coverage 3898 /* Compute the coverage for the first pixel, and move left past
3884 map, unlike row which indexes the raster. */ 3899 it. The coverage is a number from 1 to 7 describing how
3885 col = 0; 3900 ``partially'' covered this pixel is. */
3886
3887 /* Precompute this to allow for better optimizations. */
3888 end = ((left + SFNT_POLY_SAMPLE - 1) & ~SFNT_POLY_MASK);
3889 3901
3890 while (left < right && left < end) 3902 end = (left + SFNT_POLY_SAMPLE - 1) & ~SFNT_POLY_MASK;
3891 left++, w += coverage[col++]; 3903 end = MIN (right, end);
3892 3904
3905 w = coverage[end - left];
3893 a = *start + w; 3906 a = *start + w;
3907
3908 /* Now move left past. */
3909 left = end;
3910
3894 *start++ = sfnt_saturate_short (a); 3911 *start++ = sfnt_saturate_short (a);
3895 } 3912 }
3896 3913
3897 /* Clear coverage info for first pixel. Compute coverage for center 3914 /* Clear coverage info for first pixel. Compute coverage for center
3898 pixels. */ 3915 pixels. */
3899 w = 0; 3916 w = coverage[SFNT_POLY_MASK];
3900 for (col = 0; col < SFNT_POLY_SAMPLE; ++col)
3901 w += coverage[col];
3902 3917
3903 /* Fill pixels between left and right. */ 3918 /* Fill pixels between left and right. */
3904 while (left + SFNT_POLY_MASK < right) 3919 while (left + SFNT_POLY_MASK < right)
@@ -3912,10 +3927,7 @@ sfnt_fill_span (struct sfnt_raster *raster, sfnt_fixed y,
3912 part.) */ 3927 part.) */
3913 if (right & SFNT_POLY_MASK) 3928 if (right & SFNT_POLY_MASK)
3914 { 3929 {
3915 w = 0; 3930 w = coverage[right - left];
3916 col = 0;
3917 while (left < right)
3918 left++, w += coverage[col++];
3919 a = *start + w; 3931 a = *start + w;
3920 *start = sfnt_saturate_short (a); 3932 *start = sfnt_saturate_short (a);
3921 } 3933 }
@@ -4155,20 +4167,34 @@ sfnt_lookup_glyph_metrics (sfnt_glyph glyph, int pixel_size,
4155 /* Return unscaled metrics in this case. */ 4167 /* Return unscaled metrics in this case. */
4156 metrics->lbearing = lbearing; 4168 metrics->lbearing = lbearing;
4157 metrics->advance = advance; 4169 metrics->advance = advance;
4158 return 1; 4170 return 0;
4159 } 4171 }
4160 4172
4161 /* Now scale lbearing and advance up to the pixel size. */ 4173 /* Now scale lbearing and advance up to the pixel size. */
4162 factor = sfnt_div_fixed (pixel_size, head->units_per_em); 4174 factor = sfnt_div_fixed (pixel_size, head->units_per_em);
4163 4175
4164 /* Save them. */ 4176 /* Save them. */
4165 metrics->lbearing = sfnt_mul_fixed (lbearing << 16, factor); 4177 metrics->lbearing = sfnt_mul_fixed (lbearing * 65536, factor);
4166 metrics->advance = sfnt_mul_fixed (advance << 16, factor); 4178 metrics->advance = sfnt_mul_fixed (advance * 65536, factor);
4167 4179
4168 /* All done. */ 4180 /* All done. */
4169 return 0; 4181 return 0;
4170} 4182}
4171 4183
4184/* Scale the specified glyph metrics by FACTOR.
4185 Set METRICS->lbearing and METRICS->advance to their current
4186 values times factor. */
4187
4188MAYBE_UNUSED TEST_STATIC void
4189sfnt_scale_metrics (struct sfnt_glyph_metrics *metrics,
4190 sfnt_fixed factor)
4191{
4192 metrics->lbearing
4193 = sfnt_mul_fixed (metrics->lbearing * 65536, factor);
4194 metrics->advance
4195 = sfnt_mul_fixed (metrics->advance * 65536, factor);
4196}
4197
4172 4198
4173 4199
4174/* Font style parsing. */ 4200/* Font style parsing. */
@@ -4602,10 +4628,6 @@ sfnt_read_ttc_header (int fd)
4602 4628
4603 4629
4604 4630
4605#ifdef TEST
4606#define SFNT_ENABLE_HINTING
4607#endif
4608
4609#ifdef SFNT_ENABLE_HINTING 4631#ifdef SFNT_ENABLE_HINTING
4610 4632
4611/* TrueType hinting support. 4633/* TrueType hinting support.
@@ -4649,37 +4671,6 @@ sfnt_read_ttc_header (int fd)
4649 through one of three ``zone pointer'' registers, and are accessible 4671 through one of three ``zone pointer'' registers, and are accessible
4650 only when a program is being run on behalf of a glyph. */ 4672 only when a program is being run on behalf of a glyph. */
4651 4673
4652/* Structure definitions for tables used by the TrueType
4653 interpreter. */
4654
4655struct sfnt_cvt_table
4656{
4657 /* Number of elements in the control value table. */
4658 size_t num_elements;
4659
4660 /* Pointer to elements in the control value table. */
4661 sfnt_fword *values;
4662};
4663
4664struct sfnt_fpgm_table
4665{
4666 /* Number of instructions in the font program table. */
4667 size_t num_instructions;
4668
4669 /* Pointer to elements in the font program table. */
4670 unsigned char *instructions;
4671};
4672
4673struct sfnt_prep_table
4674{
4675 /* Number of instructions in the control value program (pre-program)
4676 table. */
4677 size_t num_instructions;
4678
4679 /* Pointer to elements in the preprogram table. */
4680 unsigned char *instructions;
4681};
4682
4683 4674
4684 4675
4685/* Functions for reading tables used by the TrueType interpreter. */ 4676/* Functions for reading tables used by the TrueType interpreter. */
@@ -4689,7 +4680,7 @@ struct sfnt_prep_table
4689 in the control value table. Return NULL upon failure, else the cvt 4680 in the control value table. Return NULL upon failure, else the cvt
4690 table. */ 4681 table. */
4691 4682
4692static struct sfnt_cvt_table * 4683TEST_STATIC struct sfnt_cvt_table *
4693sfnt_read_cvt_table (int fd, struct sfnt_offset_subtable *subtable) 4684sfnt_read_cvt_table (int fd, struct sfnt_offset_subtable *subtable)
4694{ 4685{
4695 struct sfnt_table_directory *directory; 4686 struct sfnt_table_directory *directory;
@@ -4740,7 +4731,7 @@ sfnt_read_cvt_table (int fd, struct sfnt_offset_subtable *subtable)
4740 directory specified as SUBTABLE. Value is NULL upon failure, else 4731 directory specified as SUBTABLE. Value is NULL upon failure, else
4741 the fpgm table. */ 4732 the fpgm table. */
4742 4733
4743static struct sfnt_fpgm_table * 4734TEST_STATIC struct sfnt_fpgm_table *
4744sfnt_read_fpgm_table (int fd, struct sfnt_offset_subtable *subtable) 4735sfnt_read_fpgm_table (int fd, struct sfnt_offset_subtable *subtable)
4745{ 4736{
4746 struct sfnt_table_directory *directory; 4737 struct sfnt_table_directory *directory;
@@ -4788,7 +4779,7 @@ sfnt_read_fpgm_table (int fd, struct sfnt_offset_subtable *subtable)
4788 directory specified as SUBTABLE. Value is NULL upon failure, else 4779 directory specified as SUBTABLE. Value is NULL upon failure, else
4789 the prep table. */ 4780 the prep table. */
4790 4781
4791static struct sfnt_prep_table * 4782TEST_STATIC struct sfnt_prep_table *
4792sfnt_read_prep_table (int fd, struct sfnt_offset_subtable *subtable) 4783sfnt_read_prep_table (int fd, struct sfnt_offset_subtable *subtable)
4793{ 4784{
4794 struct sfnt_table_directory *directory; 4785 struct sfnt_table_directory *directory;
@@ -4836,344 +4827,6 @@ sfnt_read_prep_table (int fd, struct sfnt_offset_subtable *subtable)
4836 4827
4837/* Interpreter execution environment. */ 4828/* Interpreter execution environment. */
4838 4829
4839/* 26.6 fixed point type used within the interpreter. */
4840typedef int32_t sfnt_f26dot6;
4841
4842/* 2.14 fixed point type used to represent versors of unit
4843 vectors. */
4844typedef int16_t sfnt_f2dot14;
4845
4846/* 18.14 fixed point type used to calculate rounding details. */
4847typedef int32_t sfnt_f18dot14;
4848
4849struct sfnt_unit_vector
4850{
4851 /* X and Y versors of the 2d unit vector. */
4852 sfnt_f2dot14 x, y;
4853};
4854
4855struct sfnt_interpreter_definition
4856{
4857 /* The opcode of this instruction or function. */
4858 uint16_t opcode;
4859
4860 /* The number of instructions. */
4861 uint16_t instruction_count;
4862
4863 /* Pointer to instructions belonging to the definition. This
4864 pointer points directly into the control value or font program.
4865 Make sure both programs are kept around as long as the
4866 interpreter continues to exist. */
4867 unsigned char *instructions;
4868};
4869
4870/* This structure represents a ``struct sfnt_glyph'' that has been
4871 scaled to a given pixel size.
4872
4873 It can either contain a simple glyph, or a decomposed compound
4874 glyph; instructions are interpreted for both simple glyphs, simple
4875 glyph components inside a compound glyph, and compound glyphs as a
4876 whole.
4877
4878 In addition to the glyph data itself, it also records various
4879 information for the instruction interpretation process:
4880
4881 - ``current'' point coordinates, which have been modified
4882 by the instructing process.
4883
4884 - two phantom points at the origin and the advance of the
4885 glyph. */
4886
4887struct sfnt_interpreter_zone
4888{
4889 /* The number of points in this zone, including the two phantom
4890 points at the end. */
4891 size_t num_points;
4892
4893 /* The number of contours in this zone. */
4894 size_t num_contours;
4895
4896 /* The end points of each contour. */
4897 size_t *contour_end_points;
4898
4899 /* Pointer to the X axis point data. */
4900 sfnt_f26dot6 *restrict x_points;
4901
4902 /* Pointer to the X axis current point data. */
4903 sfnt_f26dot6 *restrict x_current;
4904
4905 /* Pointer to the Y axis point data. */
4906 sfnt_f26dot6 *restrict y_points;
4907
4908 /* Pointer to the Y axis current point data. */
4909 sfnt_f26dot6 *restrict y_current;
4910
4911 /* Pointer to the flags associated with this data. */
4912 unsigned char *flags;
4913};
4914
4915enum
4916 {
4917 /* Bits 7 and 6 of a glyph point's flags is reserved. This scaler
4918 uses it to mean that the point has been touched in one axis or
4919 another. */
4920 SFNT_POINT_TOUCHED_X = (1 << 7),
4921 SFNT_POINT_TOUCHED_Y = (1 << 6),
4922 SFNT_POINT_TOUCHED_BOTH = (SFNT_POINT_TOUCHED_X
4923 | SFNT_POINT_TOUCHED_Y),
4924 };
4925
4926/* This is needed because `round' below needs an interpreter
4927 argument. */
4928struct sfnt_interpreter;
4929
4930struct sfnt_graphics_state
4931{
4932 /* Pointer to the function used for rounding. This function is
4933 asymmetric, so -0.5 rounds up to 0, not -1. It is up to the
4934 caller to handle negative values.
4935
4936 Value is undefined unless sfnt_validate_gs has been called, and
4937 the second argument may be used to provide detailed rounding
4938 information (``super rounding state''.) */
4939 sfnt_f26dot6 (*round) (sfnt_f26dot6, struct sfnt_interpreter *);
4940
4941 /* Pointer to the function used to project euclidean vectors onto
4942 the projection vector. Value is the magnitude of the projected
4943 vector. */
4944 sfnt_f26dot6 (*project) (sfnt_f26dot6, sfnt_f26dot6,
4945 struct sfnt_interpreter *);
4946
4947 /* Pointer to the function used to project euclidean vectors onto
4948 the dual projection vector. Value is the magnitude of the
4949 projected vector. */
4950 sfnt_f26dot6 (*dual_project) (sfnt_f26dot6, sfnt_f26dot6,
4951 struct sfnt_interpreter *);
4952
4953 /* Pointer to the function used to move specified points
4954 along the freedom vector by a distance specified in terms
4955 of the projection vector. */
4956 void (*move) (sfnt_f26dot6 *restrict,
4957 sfnt_f26dot6 *restrict, size_t,
4958 struct sfnt_interpreter *,
4959 sfnt_f26dot6, unsigned char *);
4960
4961 /* Dot product between the freedom and the projection vectors. */
4962 sfnt_f2dot14 vector_dot_product;
4963
4964 /* Controls whether the sign of control value table entries will be
4965 changed to match the sign of the actual distance measurement with
4966 which it is compared. Setting auto flip to TRUE makes it
4967 possible to control distances measured with or against the
4968 projection vector with a single control value table entry. When
4969 auto flip is set to FALSE, distances must be measured with the
4970 projection vector. */
4971 bool auto_flip;
4972
4973 /* Limits the regularizing effects of control value table entries to
4974 cases where the difference between the table value and the
4975 measurement taken from the original outline is sufficiently
4976 small. */
4977 sfnt_f26dot6 cvt_cut_in;
4978
4979 /* Establishes the base value used to calculate the range of point
4980 sizes to which a given DELTAC[] or DELTAP[] instruction will
4981 apply. The formulas given below are used to calculate the range
4982 of the various DELTA instructions.
4983
4984 DELTAC1 DELTAP1 (delta_base) through (delta_base + 15)
4985 DELTAC2 DELTAP2 (delta_base + 16) through (delta_base + 31)
4986 DELTAC3 DELTAP3 (delta_base + 32) through (delta_base + 47)
4987
4988 Please keep this documentation in sync with the TrueType
4989 reference manual. */
4990 unsigned short delta_base;
4991
4992 /* Determines the range of movement and smallest magnitude of
4993 movement (the step) in a DELTAC[] or DELTAP[] instruction.
4994 Changing the value of the delta shift makes it possible to trade
4995 off fine control of point movement for range of movement. A low
4996 delta shift favors range of movement over fine control. A high
4997 delta shift favors fine control over range of movement. The step
4998 has the value 1/2 to the power delta shift. The range of
4999 movement is calculated by taking the number of steps allowed (16)
5000 and multiplying it by the step.
5001
5002 The legal range for delta shift is zero through six. Negative
5003 values are illegal. */
5004 unsigned short delta_shift;
5005
5006 /* A second projection vector set to a line defined by the original
5007 outline location of two points. The dual projection vector is
5008 used when it is necessary to measure distances from the scaled
5009 outline before any instructions were executed. */
5010 struct sfnt_unit_vector dual_projection_vector;
5011
5012 /* A unit vector that establishes an axis along which points can
5013 move. */
5014 struct sfnt_unit_vector freedom_vector;
5015
5016 /* Makes it possible to turn off instructions under some
5017 circumstances. When flag 1 is set, changes to the graphics state
5018 made in the control value program will be ignored. When flag is
5019 1, grid fitting instructions will be ignored. */
5020 unsigned char instruct_control;
5021
5022 /* Makes it possible to repeat certain instructions a designated
5023 number of times. The default value of one assures that unless
5024 the value of loop is altered, these instructions will execute one
5025 time. */
5026 unsigned short loop;
5027
5028 /* Establishes the smallest possible value to which a distance will
5029 be rounded. */
5030 sfnt_f26dot6 minimum_distance;
5031
5032 /* A unit vector whose direction establishes an axis along which
5033 distances are measured. */
5034 struct sfnt_unit_vector projection_vector;
5035
5036 /* Determines the manner in which values are rounded. Can be set to
5037 a number of predefined states or to a customized state with the
5038 SROUND or S45ROUND instructions. */
5039 int round_state;
5040
5041 /* Reference points. These reference point numbers, which together
5042 with a zone designation, specify a point in either the glyph zone
5043 or the twilight zone. */
5044 uint16_t rp0, rp1, rp2;
5045
5046 /* Flags which determine whether the interpreter will activate
5047 dropout control for the current glyph. */
5048 int scan_control;
5049
5050 /* The distance difference below which the interpreter will replace
5051 a CVT distance or an actual distance in favor of the single width
5052 value. */
5053 sfnt_f26dot6 sw_cut_in;
5054
5055 /* The value used in place of the control value table distance or
5056 the actual distance value when the difference between that
5057 distance and the single width value is less than the single width
5058 cut-in. */
5059 sfnt_f26dot6 single_width_value;
5060
5061 /* Zone pointers, which reference a zone. */
5062 int zp0, zp1, zp2;
5063};
5064
5065struct sfnt_interpreter
5066{
5067 /* The number of elements in the stack. */
5068 uint16_t max_stack_elements;
5069
5070 /* The number of instructions in INSTRUCTIONS. */
5071 uint16_t num_instructions;
5072
5073 /* Size of the storage area. */
5074 uint16_t storage_size;
5075
5076 /* Size of the function definition area. */
5077 uint16_t function_defs_size;
5078
5079 /* Size of the instruction definition area. */
5080 uint16_t instruction_defs_size;
5081
5082 /* Size of the twilight zone. */
5083 uint16_t twilight_zone_size;
5084
5085 /* The instruction pointer. This points to the instruction
5086 currently being executed. */
5087 int IP;
5088
5089 /* The current scale. */
5090 sfnt_fixed scale;
5091
5092 /* The current ppem and point size. */
5093 int ppem, point_size;
5094
5095 /* The execution stack. This has at most max_stack_elements
5096 elements. */
5097 uint32_t *stack;
5098
5099 /* Pointer past the top of the stack. */
5100 uint32_t *SP;
5101
5102 /* The size of the control value table. */
5103 size_t cvt_size;
5104
5105 /* Pointer to instructions currently being executed. */
5106 unsigned char *restrict instructions;
5107
5108 /* The twilight zone. May not be NULL. */
5109 sfnt_f26dot6 *restrict twilight_x, *restrict twilight_y;
5110
5111 /* The original X positions of points in the twilight zone. */
5112 sfnt_f26dot6 *restrict twilight_original_x;
5113
5114 /* The original Y positions of points in the twilight zone.
5115
5116 Apple does not directly say whether or not points in the twilight
5117 zone can have their original positions changed. But this is
5118 implied by ``create points in the twilight zone''. */
5119 sfnt_f26dot6 *restrict twilight_original_y;
5120
5121 /* The scaled outlines being manipulated. May be NULL. */
5122 struct sfnt_interpreter_zone *glyph_zone;
5123
5124 /* The glyph advance width. Value is undefined unless GLYPH_ZONE is
5125 set. */
5126 sfnt_f26dot6 advance_width;
5127
5128 /* The storage area. */
5129 uint32_t *storage;
5130
5131 /* Control value table values. */
5132 sfnt_f26dot6 *cvt;
5133
5134 /* Function definitions. */
5135 struct sfnt_interpreter_definition *function_defs;
5136
5137 /* Instruction definitions. */
5138 struct sfnt_interpreter_definition *instruction_defs;
5139
5140 /* Interpreter registers. */
5141 struct sfnt_graphics_state state;
5142
5143 /* Detailed rounding state used when state.round_state indicates
5144 that fine grained rounding should be used.
5145
5146 PERIOD says how often a round value occurs, for numbers
5147 increasing from PHASE to infinity.
5148
5149 THRESHOLD says when to round a value between two increasing
5150 periods towards the larger period. */
5151 sfnt_f26dot6 period, phase, threshold;
5152
5153 /* The depth of any ongoing calls. */
5154 int call_depth;
5155
5156 /* Jump buffer for traps. */
5157 jmp_buf trap;
5158
5159 /* What was the trap. */
5160 const char *trap_reason;
5161
5162#ifdef TEST
5163 /* If non-NULL, function called before each instruction is
5164 executed. */
5165 void (*run_hook) (struct sfnt_interpreter *);
5166
5167 /* If non-NULL, function called before each stack element is
5168 pushed. */
5169 void (*push_hook) (struct sfnt_interpreter *, uint32_t);
5170
5171 /* If non-NULL, function called before each stack element is
5172 popped. */
5173 void (*pop_hook) (struct sfnt_interpreter *, uint32_t);
5174#endif
5175};
5176
5177/* Divide the specified two 26.6 fixed point numbers X and Y. 4830/* Divide the specified two 26.6 fixed point numbers X and Y.
5178 Return the result. */ 4831 Return the result. */
5179 4832
@@ -5409,7 +5062,7 @@ sfnt_init_graphics_state (struct sfnt_graphics_state *state)
5409 Value is the interpreter, with all state initialized to default 5062 Value is the interpreter, with all state initialized to default
5410 values, or NULL upon failure. */ 5063 values, or NULL upon failure. */
5411 5064
5412static struct sfnt_interpreter * 5065TEST_STATIC struct sfnt_interpreter *
5413sfnt_make_interpreter (struct sfnt_maxp_table *maxp, 5066sfnt_make_interpreter (struct sfnt_maxp_table *maxp,
5414 struct sfnt_cvt_table *cvt, 5067 struct sfnt_cvt_table *cvt,
5415 struct sfnt_head_table *head, 5068 struct sfnt_head_table *head,
@@ -5661,13 +5314,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5661 _value); \ 5314 _value); \
5662 _value;})) 5315 _value;}))
5663 5316
5664#define POP_UNCHECKED() \ 5317#define POP_UNCHECKED() POP ()
5665 ({uint32_t _value; \
5666 _value = *(--interpreter->SP); \
5667 if (interpreter->pop_hook) \
5668 interpreter->pop_hook (interpreter, \
5669 _value); \
5670 _value;})
5671 5318
5672#endif 5319#endif
5673 5320
@@ -5710,15 +5357,7 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
5710 interpreter->SP++; \ 5357 interpreter->SP++; \
5711 } 5358 }
5712 5359
5713#define PUSH_UNCHECKED(value) \ 5360#define PUSH_UNCHECKED(value) PUSH (value)
5714 { \
5715 if (interpreter->push_hook) \
5716 interpreter->push_hook (interpreter, \
5717 value); \
5718 \
5719 *interpreter->SP = value; \
5720 interpreter->SP++; \
5721 }
5722 5361
5723#endif 5362#endif
5724 5363
@@ -6722,8 +6361,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6722 if (!n) \ 6361 if (!n) \
6723 break; \ 6362 break; \
6724 \ 6363 \
6725 argn = POP (); \
6726 pn = POP (); \ 6364 pn = POP (); \
6365 argn = POP (); \
6727 sfnt_deltap (1, interpreter, argn, pn); \ 6366 sfnt_deltap (1, interpreter, argn, pn); \
6728 n--; \ 6367 n--; \
6729 goto deltap1_start; \ 6368 goto deltap1_start; \
@@ -6739,8 +6378,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6739 if (!n) \ 6378 if (!n) \
6740 break; \ 6379 break; \
6741 \ 6380 \
6742 argn = POP (); \
6743 pn = POP (); \ 6381 pn = POP (); \
6382 argn = POP (); \
6744 sfnt_deltap (2, interpreter, argn, pn); \ 6383 sfnt_deltap (2, interpreter, argn, pn); \
6745 n--; \ 6384 n--; \
6746 goto deltap2_start; \ 6385 goto deltap2_start; \
@@ -6756,8 +6395,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter,
6756 if (!n) \ 6395 if (!n) \
6757 break; \ 6396 break; \
6758 \ 6397 \
6759 argn = POP (); \
6760 pn = POP (); \ 6398 pn = POP (); \
6399 argn = POP (); \
6761 sfnt_deltap (3, interpreter, argn, pn); \ 6400 sfnt_deltap (3, interpreter, argn, pn); \
6762 n--; \ 6401 n--; \
6763 goto deltap3_start; \ 6402 goto deltap3_start; \
@@ -8394,7 +8033,7 @@ sfnt_interpret_ip (struct sfnt_interpreter *interpreter)
8394 8033
8395static void 8034static void
8396sfnt_deltac (int number, struct sfnt_interpreter *interpreter, 8035sfnt_deltac (int number, struct sfnt_interpreter *interpreter,
8397 unsigned char operand, unsigned int index) 8036 unsigned int index, unsigned char operand)
8398{ 8037{
8399 int ppem, delta; 8038 int ppem, delta;
8400 8039
@@ -8565,6 +8204,8 @@ sfnt_deltap (int number, struct sfnt_interpreter *interpreter,
8565{ 8204{
8566 int ppem, delta; 8205 int ppem, delta;
8567 8206
8207 return;
8208
8568 /* Extract the ppem from OPERAND. The format is the same as in 8209 /* Extract the ppem from OPERAND. The format is the same as in
8569 sfnt_deltac. */ 8210 sfnt_deltac. */
8570 8211
@@ -9699,26 +9340,31 @@ sfnt_interpret_shp (struct sfnt_interpreter *interpreter,
9699 \ 9340 \
9700 i = touch_start + 1; \ 9341 i = touch_start + 1; \
9701 \ 9342 \
9702 for (; i <= end; ++i) \ 9343 while (i != touch_end) \
9703 { \ 9344 { \
9704 if (i > end) \
9705 i = start; \
9706 \
9707 /* Movement is always relative to the original position of \ 9345 /* Movement is always relative to the original position of \
9708 the point. */ \ 9346 the point. */ \
9709 position = load_original (i); \ 9347 position = load_original (i); \
9710 \ 9348 \
9711 /* If i is in between touch_start and touch_end... */ \ 9349 /* If i is in between touch_start and touch_end... */ \
9712 if (position >= original_min_pos \ 9350 if (position >= original_min_pos \
9713 && position <= original_max_pos \ 9351 && position <= original_max_pos) \
9714 && original_min_pos != original_max_pos) \
9715 { \ 9352 { \
9716 /* ... preserve the ratio of i between min_pos and \ 9353 /* Handle the degenerate case where original_min_pos and \
9717 max_pos... */ \ 9354 original_max_pos have not changed by placing the point in \
9718 ratio = sfnt_div_fixed (sfnt_sub (position, \ 9355 the middle. */ \
9719 original_min_pos) * 1024, \ 9356 if (original_min_pos == original_max_pos) \
9720 sfnt_sub (original_max_pos, \ 9357 ratio = 077777; \
9721 original_min_pos) * 1024); \ 9358 else \
9359 /* ... preserve the ratio of i between min_pos and \
9360 max_pos... */ \
9361 ratio = sfnt_div_fixed ((sfnt_sub (position, \
9362 original_min_pos) \
9363 * 1024), \
9364 (sfnt_sub (original_max_pos, \
9365 original_min_pos) \
9366 * 1024)); \
9367 \
9722 delta = sfnt_sub (max_pos, min_pos); \ 9368 delta = sfnt_sub (max_pos, min_pos); \
9723 delta = sfnt_mul_fixed (ratio, delta); \ 9369 delta = sfnt_mul_fixed (ratio, delta); \
9724 store_point (i, sfnt_add (min_pos, delta)); \ 9370 store_point (i, sfnt_add (min_pos, delta)); \
@@ -9735,6 +9381,9 @@ sfnt_interpret_shp (struct sfnt_interpreter *interpreter,
9735 \ 9381 \
9736 store_point (i, sfnt_add (position, delta)); \ 9382 store_point (i, sfnt_add (position, delta)); \
9737 } \ 9383 } \
9384 \
9385 if (++i > end) \
9386 i = start; \
9738 } \ 9387 } \
9739 9388
9740/* Interpolate untouched points in the contour between and including 9389/* Interpolate untouched points in the contour between and including
@@ -10711,9 +10360,12 @@ sfnt_interpret_run (struct sfnt_interpreter *interpreter,
10711 undefined. 10360 undefined.
10712 10361
10713 Value is NULL upon success, else it is a string describing the 10362 Value is NULL upon success, else it is a string describing the
10714 reason for failure. */ 10363 reason for failure.
10715 10364
10716static const char * 10365 The caller must save the graphics state after interpreting the font
10366 program and restore it prior to instructing each glyph. */
10367
10368TEST_STATIC const char *
10717sfnt_interpret_font_program (struct sfnt_interpreter *interpreter, 10369sfnt_interpret_font_program (struct sfnt_interpreter *interpreter,
10718 struct sfnt_fpgm_table *fpgm) 10370 struct sfnt_fpgm_table *fpgm)
10719{ 10371{
@@ -10735,9 +10387,13 @@ sfnt_interpret_font_program (struct sfnt_interpreter *interpreter,
10735 10387
10736 Return NULL and the graphics state after the execution of the 10388 Return NULL and the graphics state after the execution of the
10737 program in *STATE, or a string describing the reason for a failure 10389 program in *STATE, or a string describing the reason for a failure
10738 to interpret the program. */ 10390 to interpret the program.
10739 10391
10740static const char * 10392 The caller must save the graphics state after interpreting the
10393 control value program and restore it prior to instructing each
10394 glyph. */
10395
10396TEST_STATIC const char *
10741sfnt_interpret_control_value_program (struct sfnt_interpreter *interpreter, 10397sfnt_interpret_control_value_program (struct sfnt_interpreter *interpreter,
10742 struct sfnt_prep_table *prep, 10398 struct sfnt_prep_table *prep,
10743 struct sfnt_graphics_state *state) 10399 struct sfnt_graphics_state *state)
@@ -10776,30 +10432,6 @@ sfnt_interpret_control_value_program (struct sfnt_interpreter *interpreter,
10776 scaling separately. It might be nice to fix that in the 10432 scaling separately. It might be nice to fix that in the
10777 future. */ 10433 future. */
10778 10434
10779/* Structure describing a single scaled and fitted outline. */
10780
10781struct sfnt_instructed_outline
10782{
10783 /* The number of points in this contour, including the two phantom
10784 points at the end. */
10785 size_t num_points;
10786
10787 /* The number of contours in this outline. */
10788 size_t num_contours;
10789
10790 /* The end points of each contour. */
10791 size_t *contour_end_points;
10792
10793 /* The points of each contour, with two additional phantom points at
10794 the end. */
10795 sfnt_f26dot6 *restrict x_points, *restrict y_points;
10796
10797 /* The flags of each point. */
10798 unsigned char *flags;
10799};
10800
10801
10802
10803/* Instructed glyph outline decomposition. This is separate from 10435/* Instructed glyph outline decomposition. This is separate from
10804 sfnt_decompose_glyph because this file should be able to be built 10436 sfnt_decompose_glyph because this file should be able to be built
10805 with instructions disabled. */ 10437 with instructions disabled. */
@@ -10958,12 +10590,14 @@ sfnt_decompose_instructed_outline (struct sfnt_instructed_outline *outline,
10958 10590
10959 This function is not reentrant. */ 10591 This function is not reentrant. */
10960 10592
10961static struct sfnt_glyph_outline * 10593TEST_STATIC struct sfnt_glyph_outline *
10962sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed) 10594sfnt_build_instructed_outline (struct sfnt_instructed_outline *instructed)
10963{ 10595{
10964 struct sfnt_glyph_outline *outline; 10596 struct sfnt_glyph_outline *outline;
10965 int rc; 10597 int rc;
10966 10598
10599 memset (&build_outline_context, 0, sizeof build_outline_context);
10600
10967 /* Allocate the outline now with enough for 44 words at the end. */ 10601 /* Allocate the outline now with enough for 44 words at the end. */
10968 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline)); 10602 outline = xmalloc (sizeof *outline + 40 * sizeof (*outline->outline));
10969 outline->outline_size = 40; 10603 outline->outline_size = 40;
@@ -11047,7 +10681,7 @@ sfnt_compute_phantom_points (struct sfnt_glyph *glyph,
11047 Upon success, return NULL and the resulting points and contours in 10681 Upon success, return NULL and the resulting points and contours in
11048 *VALUE. Else, value is the reason interpretation failed. */ 10682 *VALUE. Else, value is the reason interpretation failed. */
11049 10683
11050static const char * 10684TEST_STATIC const char *
11051sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph, 10685sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
11052 struct sfnt_interpreter *interpreter, 10686 struct sfnt_interpreter *interpreter,
11053 struct sfnt_glyph_metrics *metrics, 10687 struct sfnt_glyph_metrics *metrics,
@@ -11445,12 +11079,16 @@ sfnt_test_edge (struct sfnt_edge *edges, size_t num_edges,
11445} 11079}
11446 11080
11447static void 11081static void
11448sfnt_x_raster (struct sfnt_raster *raster) 11082sfnt_x_raster (struct sfnt_raster **rasters,
11083 int *advances,
11084 int nrasters,
11085 struct sfnt_hhea_table *hhea,
11086 sfnt_fixed scale)
11449{ 11087{
11450 Display *display; 11088 Display *display;
11451 Window window; 11089 Window window;
11452 Pixmap pixmap; 11090 Pixmap *pixmaps;
11453 Picture glyph, drawable, solid; 11091 Picture *glyphs, drawable, solid;
11454 int event_base, error_base; 11092 int event_base, error_base;
11455 int major, minor, *depths, count; 11093 int major, minor, *depths, count;
11456 XRenderPictFormat *format, *glyph_format; 11094 XRenderPictFormat *format, *glyph_format;
@@ -11460,7 +11098,11 @@ sfnt_x_raster (struct sfnt_raster *raster)
11460 XGCValues gcvalues; 11098 XGCValues gcvalues;
11461 XEvent event; 11099 XEvent event;
11462 XRenderColor white, black; 11100 XRenderColor white, black;
11463 int i; 11101 int i, ascent, origin, x, y;
11102 Font font;
11103
11104 if (!nrasters)
11105 exit (0);
11464 11106
11465 display = XOpenDisplay (NULL); 11107 display = XOpenDisplay (NULL);
11466 11108
@@ -11475,7 +11117,7 @@ sfnt_x_raster (struct sfnt_raster *raster)
11475 exit (0); 11117 exit (0);
11476 11118
11477 window = XCreateSimpleWindow (display, DefaultRootWindow (display), 11119 window = XCreateSimpleWindow (display, DefaultRootWindow (display),
11478 0, 0, 40, 40, 0, 0, 11120 0, 0, 100, 150, 0, 0,
11479 WhitePixel (display, 11121 WhitePixel (display,
11480 DefaultScreen (display))); 11122 DefaultScreen (display)));
11481 XSelectInput (display, window, ExposureMask); 11123 XSelectInput (display, window, ExposureMask);
@@ -11501,37 +11143,57 @@ sfnt_x_raster (struct sfnt_raster *raster)
11501 depth_found: 11143 depth_found:
11502 11144
11503 XFree (depths); 11145 XFree (depths);
11504 pixmap = XCreatePixmap (display, DefaultRootWindow (display), 11146 pixmaps = alloca (sizeof *pixmaps * nrasters);
11505 raster->width, raster->height, 8); 11147 glyphs = alloca (sizeof *glyphs * nrasters);
11506 11148 gc = None;
11507 /* Upload the raster. */ 11149
11508 image.width = raster->width; 11150 for (i = 0; i < nrasters; ++i)
11509 image.height = raster->height; 11151 {
11510 image.xoffset = 0; 11152 pixmaps[i] = XCreatePixmap (display, DefaultRootWindow (display),
11511 image.format = ZPixmap; 11153 rasters[i]->width, rasters[i]->height, 8);
11512 image.data = (char *) raster->cells; 11154 if (!gc)
11513 image.byte_order = MSBFirst; 11155 gc = XCreateGC (display, pixmaps[i], 0, &gcvalues);
11514 image.bitmap_unit = 8; 11156
11515 image.bitmap_bit_order = LSBFirst; 11157 /* Upload the raster. */
11516 image.bitmap_pad = SFNT_POLY_ALIGNMENT * 8; 11158 image.width = rasters[i]->width;
11517 image.depth = 8; 11159 image.height = rasters[i]->height;
11518 image.bytes_per_line = raster->stride; 11160 image.xoffset = 0;
11519 image.bits_per_pixel = 8; 11161 image.format = ZPixmap;
11520 image.red_mask = 0; 11162 image.data = (char *) rasters[i]->cells;
11521 image.green_mask = 0; 11163 image.byte_order = MSBFirst;
11522 image.blue_mask = 0; 11164 image.bitmap_unit = 8;
11523 11165 image.bitmap_bit_order = LSBFirst;
11524 if (!XInitImage (&image)) 11166 image.bitmap_pad = SFNT_POLY_ALIGNMENT * 8;
11525 abort (); 11167 image.depth = 8;
11168 image.bytes_per_line = rasters[i]->stride;
11169 image.bits_per_pixel = 8;
11170 image.red_mask = 0;
11171 image.green_mask = 0;
11172 image.blue_mask = 0;
11173
11174 if (!XInitImage (&image))
11175 abort ();
11176
11177 XPutImage (display, pixmaps[i], gc, &image,
11178 0, 0, 0, 0, image.width, image.height);
11179
11180 glyphs[i] = XRenderCreatePicture (display, pixmaps[i],
11181 glyph_format, 0, NULL);
11182 }
11526 11183
11527 gc = XCreateGC (display, pixmap, 0, &gcvalues); 11184 XFreeGC (display, gc);
11528 XPutImage (display, pixmap, gc, &image, 11185
11529 0, 0, 0, 0, image.width, image.height); 11186 font = XLoadFont (display, "6x13");
11187
11188 if (!font)
11189 exit (1);
11190
11191 gcvalues.font = font;
11192 gcvalues.foreground = BlackPixel (display, DefaultScreen (display));
11193 gc = XCreateGC (display, window, GCForeground | GCFont, &gcvalues);
11530 11194
11531 drawable = XRenderCreatePicture (display, window, format, 11195 drawable = XRenderCreatePicture (display, window, format,
11532 0, NULL); 11196 0, NULL);
11533 glyph = XRenderCreatePicture (display, pixmap, glyph_format,
11534 0, NULL);
11535 memset (&black, 0, sizeof black); 11197 memset (&black, 0, sizeof black);
11536 black.alpha = 65535; 11198 black.alpha = 65535;
11537 11199
@@ -11552,18 +11214,35 @@ sfnt_x_raster (struct sfnt_raster *raster)
11552 XRenderFillRectangle (display, PictOpSrc, drawable, 11214 XRenderFillRectangle (display, PictOpSrc, drawable,
11553 &white, 0, 0, 65535, 65535); 11215 &white, 0, 0, 65535, 65535);
11554 11216
11555 /* Draw the solid fill with the glyph as clip mask. */ 11217 /* Compute ascent line. */
11556 XRenderComposite (display, PictOpOver, solid, glyph, 11218 ascent = sfnt_mul_fixed (hhea->ascent * 65536,
11557 drawable, 0, 0, 0, 0, 0, 0, 11219 scale) / 65536;
11558 raster->width, raster->height); 11220
11221 origin = 0;
11222
11223 for (i = 0; i < nrasters; ++i)
11224 {
11225 /* Compute the base position. */
11226 x = origin + rasters[i]->offx;
11227 y = ascent - rasters[i]->height - rasters[i]->offy;
11228
11229 /* Draw the solid fill with the glyph as clip mask. */
11230 XRenderComposite (display, PictOpOver, solid, glyphs[i],
11231 drawable, 0, 0, 0, 0, x, y,
11232 rasters[i]->width, rasters[i]->height);
11233
11234 origin += advances[i];
11235 }
11559 } 11236 }
11560 } 11237 }
11561} 11238}
11562 11239
11563static void 11240static void
11564sfnt_test_raster (struct sfnt_raster *raster) 11241sfnt_test_raster (struct sfnt_raster *raster,
11242 struct sfnt_hhea_table *hhea,
11243 sfnt_fixed scale)
11565{ 11244{
11566 int x, y; 11245 int x, y, i;
11567 11246
11568 for (y = 0; y < raster->height; ++y) 11247 for (y = 0; y < raster->height; ++y)
11569 { 11248 {
@@ -11572,10 +11251,12 @@ sfnt_test_raster (struct sfnt_raster *raster)
11572 puts (""); 11251 puts ("");
11573 } 11252 }
11574 11253
11575 if (getenv ("SFNT_X")) 11254 if (hhea && getenv ("SFNT_X"))
11576 { 11255 {
11256 i = 0;
11257
11577 if (!fork ()) 11258 if (!fork ())
11578 sfnt_x_raster (raster); 11259 sfnt_x_raster (&raster, &i, 1, hhea, scale);
11579 } 11260 }
11580} 11261}
11581 11262
@@ -14074,12 +13755,12 @@ static struct sfnt_interpreter_test all_tests[] =
14074 SDB[] ; delta base now 2 13755 SDB[] ; delta base now 2
14075 PUSHB[0] 6 13756 PUSHB[0] 6
14076 SDS[] ; delta shift now 6 13757 SDS[] ; delta shift now 6
14077 PUSHB[2] 1 0xff 1 ; CVT index 5, ppem 15 + 2, magnitude 15 13758 PUSHB[2] 0xff 5 1 ; CVT index 5, ppem 15 + 2, magnitude 15
14078 DELTAC1[] 13759 DELTAC1[]
14079 PUSHB[0] 1 13760 PUSHB[0] 1
14080 RCVT[] ; CVT index 5 should now be greater by 8 / 64 13761 RCVT[] ; CVT index 5 should now be greater by 8 / 64
14081 13762
14082 PUSHB[2] 1 0xef 1 ; CVT index 5, ppem 14 + 2, magnitude 15 13763 PUSHB[2] 0xef 5 1 ; CVT index 5, ppem 14 + 2, magnitude 15
14083 DELTAC1[] 13764 DELTAC1[]
14084 PUSHB[0] 1 13765 PUSHB[0] 1
14085 RCVT[] ; CVT index 5 should be unchanged */ 13766 RCVT[] ; CVT index 5 should be unchanged */
@@ -14087,11 +13768,11 @@ static struct sfnt_interpreter_test all_tests[] =
14087 0x5e, 13768 0x5e,
14088 0xb0, 6, 13769 0xb0, 6,
14089 0x5f, 13770 0x5f,
14090 0xb2, 5, 255, 1, 13771 0xb2, 255, 5, 1,
14091 0x73, 13772 0x73,
14092 0xb0, 5, 13773 0xb0, 5,
14093 0x45, 13774 0x45,
14094 0xb2, 5, 239, 1, 13775 0xb2, 239, 5, 1,
14095 0x73, 13776 0x73,
14096 0xb0, 5, 13777 0xb0, 5,
14097 0x45, }, 13778 0x45, },
@@ -14105,12 +13786,12 @@ static struct sfnt_interpreter_test all_tests[] =
14105 SDB[] ; delta base now 2 13786 SDB[] ; delta base now 2
14106 PUSHB[0] 6 13787 PUSHB[0] 6
14107 SDS[] ; delta shift now 6 13788 SDS[] ; delta shift now 6
14108 PUSHB[2] 1 0xff 1 ; CVT index 5, ppem 15 + 2 + 16, magnitude 15 13789 PUSHB[2] 0xff 5 1 ; CVT index 5, ppem 15 + 2 + 16, magnitude 15
14109 DELTAC2[] 13790 DELTAC2[]
14110 PUSHB[0] 1 13791 PUSHB[0] 1
14111 RCVT[] ; CVT index 5 should be unchanged 13792 RCVT[] ; CVT index 5 should be unchanged
14112 13793
14113 PUSHB[2] 1 0xef 1 ; CVT index 5, ppem 14 + 2 + 16, magnitude 15 13794 PUSHB[2] 0xef 5 1 ; CVT index 5, ppem 14 + 2 + 16, magnitude 15
14114 DELTAC2[] 13795 DELTAC2[]
14115 PUSHB[0] 1 13796 PUSHB[0] 1
14116 RCVT[] ; CVT index 5 should be unchanged */ 13797 RCVT[] ; CVT index 5 should be unchanged */
@@ -14118,11 +13799,11 @@ static struct sfnt_interpreter_test all_tests[] =
14118 0x5e, 13799 0x5e,
14119 0xb0, 6, 13800 0xb0, 6,
14120 0x5f, 13801 0x5f,
14121 0xb2, 5, 255, 1, 13802 0xb2, 255, 5, 1,
14122 0x74, 13803 0x74,
14123 0xb0, 5, 13804 0xb0, 5,
14124 0x45, 13805 0x45,
14125 0xb2, 5, 239, 1, 13806 0xb2, 239, 5, 1,
14126 0x74, 13807 0x74,
14127 0xb0, 5, 13808 0xb0, 5,
14128 0x45, }, 13809 0x45, },
@@ -14136,12 +13817,12 @@ static struct sfnt_interpreter_test all_tests[] =
14136 SDB[] ; delta base now 2 13817 SDB[] ; delta base now 2
14137 PUSHB[0] 6 13818 PUSHB[0] 6
14138 SDS[] ; delta shift now 6 13819 SDS[] ; delta shift now 6
14139 PUSHB[2] 1 0xff 1 ; CVT index 5, ppem 15 + 2 + 32, magnitude 15 13820 PUSHB[2] 0xff 5 1 ; CVT index 5, ppem 15 + 2 + 32, magnitude 15
14140 DELTAC3[] 13821 DELTAC3[]
14141 PUSHB[0] 1 13822 PUSHB[0] 1
14142 RCVT[] ; CVT index 5 should be unchanged 13823 RCVT[] ; CVT index 5 should be unchanged
14143 13824
14144 PUSHB[2] 1 0xef 1 ; CVT index 5, ppem 14 + 2 + 32, magnitude 15 13825 PUSHB[2] 0xef 5 1 ; CVT index 5, ppem 14 + 2 + 32, magnitude 15
14145 DELTAC3[] 13826 DELTAC3[]
14146 PUSHB[0] 1 13827 PUSHB[0] 1
14147 RCVT[] ; CVT index 5 should be unchanged */ 13828 RCVT[] ; CVT index 5 should be unchanged */
@@ -14149,11 +13830,11 @@ static struct sfnt_interpreter_test all_tests[] =
14149 0x5e, 13830 0x5e,
14150 0xb0, 6, 13831 0xb0, 6,
14151 0x5f, 13832 0x5f,
14152 0xb2, 5, 255, 1, 13833 0xb2, 255, 5, 1,
14153 0x75, 13834 0x75,
14154 0xb0, 5, 13835 0xb0, 5,
14155 0x45, 13836 0x45,
14156 0xb2, 5, 239, 1, 13837 0xb2, 239, 5, 1,
14157 0x75, 13838 0x75,
14158 0xb0, 5, 13839 0xb0, 5,
14159 0x45, }, 13840 0x45, },
@@ -14818,15 +14499,22 @@ sfnt_verbose (struct sfnt_interpreter *interpreter)
14818 temp.x_points = interpreter->glyph_zone->x_current; 14499 temp.x_points = interpreter->glyph_zone->x_current;
14819 temp.y_points = interpreter->glyph_zone->y_current; 14500 temp.y_points = interpreter->glyph_zone->y_current;
14820 temp.flags = interpreter->glyph_zone->flags; 14501 temp.flags = interpreter->glyph_zone->flags;
14502
14821 outline = sfnt_build_instructed_outline (&temp); 14503 outline = sfnt_build_instructed_outline (&temp);
14822 14504
14823 if (!outline) 14505 if (!outline)
14824 return; 14506 return;
14825 14507
14508 printf ("outline bounds: %g %g, %g %g\n",
14509 sfnt_coerce_fixed (outline->xmin),
14510 sfnt_coerce_fixed (outline->ymin),
14511 sfnt_coerce_fixed (outline->xmax),
14512 sfnt_coerce_fixed (outline->ymax));
14513
14826 raster = sfnt_raster_glyph_outline (outline); 14514 raster = sfnt_raster_glyph_outline (outline);
14827 14515
14828 if (raster) 14516 if (raster)
14829 sfnt_test_raster (raster); 14517 sfnt_test_raster (raster, NULL, 0);
14830 14518
14831 xfree (outline); 14519 xfree (outline);
14832 xfree (raster); 14520 xfree (raster);
@@ -14937,6 +14625,11 @@ main (int argc, char **argv)
14937 struct sfnt_prep_table *prep; 14625 struct sfnt_prep_table *prep;
14938 struct sfnt_graphics_state state; 14626 struct sfnt_graphics_state state;
14939 struct sfnt_instructed_outline *value; 14627 struct sfnt_instructed_outline *value;
14628 sfnt_fixed scale;
14629 char *fancy;
14630 int *advances;
14631 struct sfnt_raster **rasters;
14632 size_t length;
14940 14633
14941 if (argc != 2) 14634 if (argc != 2)
14942 return 1; 14635 return 1;
@@ -15025,6 +14718,9 @@ main (int argc, char **argv)
15025 data[i]->format); 14718 data[i]->format);
15026 } 14719 }
15027 14720
14721#define FANCY_PPEM 30
14722#define EASY_PPEM 30
14723
15028 interpreter = NULL; 14724 interpreter = NULL;
15029 head = sfnt_read_head_table (fd, font); 14725 head = sfnt_read_head_table (fd, font);
15030 hhea = sfnt_read_hhea_table (fd, font); 14726 hhea = sfnt_read_hhea_table (fd, font);
@@ -15040,6 +14736,123 @@ main (int argc, char **argv)
15040 exec_prep = prep; 14736 exec_prep = prep;
15041 exec_fpgm = fpgm; 14737 exec_fpgm = fpgm;
15042 14738
14739 if (getenv ("SFNT_FANCY_TEST"))
14740 {
14741 loca_long = NULL;
14742 loca_short = NULL;
14743 fancy = getenv ("SFNT_FANCY_TEST");
14744 length = strlen (fancy);
14745 scale = sfnt_div_fixed (FANCY_PPEM, head->units_per_em);
14746
14747 if (hhea && maxp)
14748 hmtx = sfnt_read_hmtx_table (fd, font, hhea, maxp);
14749
14750 if (!maxp || !head || !prep || !hmtx || !hhea
14751 || table->num_subtables < 1)
14752 exit (1);
14753
14754 if (head->index_to_loc_format)
14755 {
14756 loca_long = sfnt_read_loca_table_long (fd, font);
14757 if (!loca_long)
14758 return 1;
14759
14760 fprintf (stderr, "long loca table has %zu glyphs\n",
14761 loca_long->num_offsets);
14762 }
14763 else
14764 {
14765 loca_short = sfnt_read_loca_table_short (fd, font);
14766 if (!loca_short)
14767 return 1;
14768
14769 fprintf (stderr, "short loca table has %zu glyphs\n",
14770 loca_short->num_offsets);
14771 }
14772
14773 interpreter = sfnt_make_interpreter (maxp, cvt, head,
14774 FANCY_PPEM, FANCY_PPEM);
14775
14776 if (!interpreter)
14777 exit (1);
14778
14779 if (fpgm)
14780 {
14781 fprintf (stderr, "interpreting the font program, with"
14782 " %zu instructions\n", fpgm->num_instructions);
14783 trap = sfnt_interpret_font_program (interpreter, fpgm);
14784
14785 if (trap)
14786 fprintf (stderr, "**TRAP**: %s\n", trap);
14787 }
14788
14789 if (prep)
14790 {
14791 fprintf (stderr, "interpreting the control value program, with"
14792 " %zu instructions\n", prep->num_instructions);
14793 trap = sfnt_interpret_control_value_program (interpreter, prep,
14794 &state);
14795
14796 if (trap)
14797 fprintf (stderr, "**TRAP**: %s\n", trap);
14798 }
14799
14800 state = interpreter->state;
14801
14802 advances = alloca (sizeof *advances * length);
14803 rasters = alloca (sizeof *rasters * length);
14804
14805 for (i = 0; i < length; ++i)
14806 {
14807 code = sfnt_lookup_glyph (fancy[i], data[0]);
14808
14809 if (!code)
14810 exit (2);
14811
14812 glyph = sfnt_read_glyph (code, glyf, loca_short,
14813 loca_long);
14814
14815 if (!glyph || !glyph->simple)
14816 exit (3);
14817
14818 if (sfnt_lookup_glyph_metrics (code, -1,
14819 &metrics,
14820 hmtx, hhea,
14821 head, maxp))
14822 exit (4);
14823
14824 interpreter->state = state;
14825 trap = sfnt_interpret_simple_glyph (glyph, interpreter,
14826 &metrics, &value);
14827
14828 if (trap)
14829 {
14830 fprintf (stderr, "*TRAP*: %s\n", trap);
14831 exit (5);
14832 }
14833
14834 outline = sfnt_build_instructed_outline (value);
14835
14836 if (!outline)
14837 exit (6);
14838
14839 xfree (value);
14840
14841 raster = sfnt_raster_glyph_outline (outline);
14842
14843 if (!raster)
14844 exit (7);
14845
14846 xfree (outline);
14847
14848 rasters[i] = raster;
14849 advances[i] = sfnt_mul_fixed (metrics.advance, scale);
14850 }
14851
14852 sfnt_x_raster (rasters, advances, length, hhea, scale);
14853 exit (0);
14854 }
14855
15043 if (head && maxp && maxp->version >= 0x00010000) 14856 if (head && maxp && maxp->version >= 0x00010000)
15044 { 14857 {
15045 fprintf (stderr, "creating interpreter\n" 14858 fprintf (stderr, "creating interpreter\n"
@@ -15057,7 +14870,8 @@ main (int argc, char **argv)
15057 cvt ? cvt->num_elements : 0ul); 14870 cvt ? cvt->num_elements : 0ul);
15058 14871
15059 interpreter = sfnt_make_interpreter (maxp, cvt, head, 14872 interpreter = sfnt_make_interpreter (maxp, cvt, head,
15060 20, 20); 14873 FANCY_PPEM,
14874 FANCY_PPEM);
15061 state = interpreter->state; 14875 state = interpreter->state;
15062 14876
15063 if (fpgm) 14877 if (fpgm)
@@ -15210,6 +15024,7 @@ main (int argc, char **argv)
15210 15024
15211 if ((loca_long || loca_short) && glyf) 15025 if ((loca_long || loca_short) && glyf)
15212 { 15026 {
15027 scale = sfnt_div_fixed (EASY_PPEM, head->units_per_em);
15213 glyph = sfnt_read_glyph (code, glyf, loca_short, 15028 glyph = sfnt_read_glyph (code, glyf, loca_short,
15214 loca_long); 15029 loca_long);
15215 15030
@@ -15233,7 +15048,7 @@ main (int argc, char **argv)
15233 /* Time this important bit. */ 15048 /* Time this important bit. */
15234 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); 15049 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
15235 outline = sfnt_build_glyph_outline (glyph, head, 15050 outline = sfnt_build_glyph_outline (glyph, head,
15236 20, 15051 EASY_PPEM,
15237 sfnt_test_get_glyph, 15052 sfnt_test_get_glyph,
15238 sfnt_test_free_glyph, 15053 sfnt_test_free_glyph,
15239 &dcontext); 15054 &dcontext);
@@ -15275,7 +15090,7 @@ main (int argc, char **argv)
15275 15090
15276 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start); 15091 clock_gettime (CLOCK_THREAD_CPUTIME_ID, &start);
15277 15092
15278 for (i = 0; i < 400; ++i) 15093 for (i = 0; i < 120; ++i)
15279 { 15094 {
15280 xfree (raster); 15095 xfree (raster);
15281 raster = sfnt_raster_glyph_outline (outline); 15096 raster = sfnt_raster_glyph_outline (outline);
@@ -15285,7 +15100,7 @@ main (int argc, char **argv)
15285 sub2 = timespec_sub (end, start); 15100 sub2 = timespec_sub (end, start);
15286 15101
15287 /* Print out the raster. */ 15102 /* Print out the raster. */
15288 sfnt_test_raster (raster); 15103 sfnt_test_raster (raster, hhea, scale);
15289 printf ("raster offsets: %d, %d\n", 15104 printf ("raster offsets: %d, %d\n",
15290 raster->offx, raster->offy); 15105 raster->offx, raster->offy);
15291 15106
@@ -15300,7 +15115,7 @@ main (int argc, char **argv)
15300 15115
15301 if (hmtx && head) 15116 if (hmtx && head)
15302 { 15117 {
15303 if (!sfnt_lookup_glyph_metrics (code, 20, 15118 if (!sfnt_lookup_glyph_metrics (code, EASY_PPEM,
15304 &metrics, 15119 &metrics,
15305 hmtx, hhea, 15120 hmtx, hhea,
15306 head, maxp)) 15121 head, maxp))
@@ -15320,10 +15135,10 @@ main (int argc, char **argv)
15320 } 15135 }
15321 15136
15322 if (glyph->simple 15137 if (glyph->simple
15323 && sfnt_lookup_glyph_metrics (code, -1, 15138 && !sfnt_lookup_glyph_metrics (code, -1,
15324 &metrics, 15139 &metrics,
15325 hmtx, hhea, 15140 hmtx, hhea,
15326 head, maxp)) 15141 head, maxp))
15327 { 15142 {
15328 printf ("interpreting glyph\n"); 15143 printf ("interpreting glyph\n");
15329 interpreter->state = state; 15144 interpreter->state = state;
@@ -15349,7 +15164,9 @@ main (int argc, char **argv)
15349 15164
15350 if (raster) 15165 if (raster)
15351 { 15166 {
15352 sfnt_test_raster (raster); 15167 sfnt_test_raster (raster, hhea, scale);
15168 printf ("raster offsets: %d, %d\n",
15169 raster->offx, raster->offy);
15353 xfree (raster); 15170 xfree (raster);
15354 } 15171 }
15355 } 15172 }
@@ -15368,7 +15185,7 @@ main (int argc, char **argv)
15368 printf ("time spent building edges: %lld sec %ld nsec\n", 15185 printf ("time spent building edges: %lld sec %ld nsec\n",
15369 (long long) sub1.tv_sec, sub1.tv_nsec); 15186 (long long) sub1.tv_sec, sub1.tv_nsec);
15370 printf ("time spent rasterizing: %lld sec %ld nsec\n", 15187 printf ("time spent rasterizing: %lld sec %ld nsec\n",
15371 (long long) sub2.tv_sec / 400, sub2.tv_nsec / 400); 15188 (long long) sub2.tv_sec / 120, sub2.tv_nsec / 120);
15372 15189
15373 xfree (outline); 15190 xfree (outline);
15374 } 15191 }
diff --git a/src/sfnt.h b/src/sfnt.h
index 409c45085ba..0845cb5be51 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -23,6 +23,11 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 23
24#include <stdint.h> 24#include <stdint.h>
25#include <stddef.h> 25#include <stddef.h>
26#include <setjmp.h>
27
28#if defined emacs || defined TEST
29#define SFNT_ENABLE_HINTING
30#endif
26 31
27 32
28 33
@@ -719,7 +724,7 @@ struct sfnt_edge
719 724
720enum 725enum
721 { 726 {
722 SFNT_POLY_SHIFT = 2, 727 SFNT_POLY_SHIFT = 3,
723 SFNT_POLY_SAMPLE = (1 << SFNT_POLY_SHIFT), 728 SFNT_POLY_SAMPLE = (1 << SFNT_POLY_SHIFT),
724 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1), 729 SFNT_POLY_MASK = (SFNT_POLY_SAMPLE - 1),
725 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT), 730 SFNT_POLY_STEP = (0x10000 >> SFNT_POLY_SHIFT),
@@ -984,6 +989,9 @@ extern int sfnt_lookup_glyph_metrics (sfnt_glyph, int,
984 struct sfnt_head_table *, 989 struct sfnt_head_table *,
985 struct sfnt_maxp_table *); 990 struct sfnt_maxp_table *);
986 991
992extern void sfnt_scale_metrics (struct sfnt_glyph_metrics *,
993 sfnt_fixed);
994
987#define PROTOTYPE int, struct sfnt_offset_subtable * 995#define PROTOTYPE int, struct sfnt_offset_subtable *
988extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE); 996extern struct sfnt_name_table *sfnt_read_name_table (PROTOTYPE);
989#undef PROTOTYPE 997#undef PROTOTYPE
@@ -1003,4 +1011,477 @@ extern char *sfnt_find_metadata (struct sfnt_meta_table *,
1003extern struct sfnt_ttc_header *sfnt_read_ttc_header (int); 1011extern struct sfnt_ttc_header *sfnt_read_ttc_header (int);
1004 1012
1005#endif /* TEST */ 1013#endif /* TEST */
1014
1015
1016
1017/* TrueType hinting support. */
1018
1019#ifdef SFNT_ENABLE_HINTING
1020
1021/* Structure definitions for tables used by the TrueType
1022 interpreter. */
1023
1024struct sfnt_cvt_table
1025{
1026 /* Number of elements in the control value table. */
1027 size_t num_elements;
1028
1029 /* Pointer to elements in the control value table. */
1030 sfnt_fword *values;
1031};
1032
1033struct sfnt_fpgm_table
1034{
1035 /* Number of instructions in the font program table. */
1036 size_t num_instructions;
1037
1038 /* Pointer to elements in the font program table. */
1039 unsigned char *instructions;
1040};
1041
1042struct sfnt_prep_table
1043{
1044 /* Number of instructions in the control value program (pre-program)
1045 table. */
1046 size_t num_instructions;
1047
1048 /* Pointer to elements in the preprogram table. */
1049 unsigned char *instructions;
1050};
1051
1052
1053
1054/* Fixed point types used by the TrueType interpreter. */
1055
1056/* 26.6 fixed point type used within the interpreter. */
1057typedef int32_t sfnt_f26dot6;
1058
1059/* 2.14 fixed point type used to represent versors of unit
1060 vectors. */
1061typedef int16_t sfnt_f2dot14;
1062
1063/* 18.14 fixed point type used to calculate rounding details. */
1064typedef int32_t sfnt_f18dot14;
1065
1066
1067
1068/* Interpreter execution environment. */
1069
1070struct sfnt_unit_vector
1071{
1072 /* X and Y versors of the 2d unit vector. */
1073 sfnt_f2dot14 x, y;
1074};
1075
1076struct sfnt_interpreter_definition
1077{
1078 /* The opcode of this instruction or function. */
1079 uint16_t opcode;
1080
1081 /* The number of instructions. */
1082 uint16_t instruction_count;
1083
1084 /* Pointer to instructions belonging to the definition. This
1085 pointer points directly into the control value or font program.
1086 Make sure both programs are kept around as long as the
1087 interpreter continues to exist. */
1088 unsigned char *instructions;
1089};
1090
1091/* This structure represents a ``struct sfnt_glyph'' that has been
1092 scaled to a given pixel size.
1093
1094 It can either contain a simple glyph, or a decomposed compound
1095 glyph; instructions are interpreted for both simple glyphs, simple
1096 glyph components inside a compound glyph, and compound glyphs as a
1097 whole.
1098
1099 In addition to the glyph data itself, it also records various
1100 information for the instruction interpretation process:
1101
1102 - ``current'' point coordinates, which have been modified
1103 by the instructing process.
1104
1105 - two phantom points at the origin and the advance of the
1106 glyph. */
1107
1108struct sfnt_interpreter_zone
1109{
1110 /* The number of points in this zone, including the two phantom
1111 points at the end. */
1112 size_t num_points;
1113
1114 /* The number of contours in this zone. */
1115 size_t num_contours;
1116
1117 /* The end points of each contour. */
1118 size_t *contour_end_points;
1119
1120 /* Pointer to the X axis point data. */
1121 sfnt_f26dot6 *restrict x_points;
1122
1123 /* Pointer to the X axis current point data. */
1124 sfnt_f26dot6 *restrict x_current;
1125
1126 /* Pointer to the Y axis point data. */
1127 sfnt_f26dot6 *restrict y_points;
1128
1129 /* Pointer to the Y axis current point data. */
1130 sfnt_f26dot6 *restrict y_current;
1131
1132 /* Pointer to the flags associated with this data. */
1133 unsigned char *flags;
1134};
1135
1136enum
1137 {
1138 /* Bits 7 and 6 of a glyph point's flags is reserved. This scaler
1139 uses it to mean that the point has been touched in one axis or
1140 another. */
1141 SFNT_POINT_TOUCHED_X = (1 << 7),
1142 SFNT_POINT_TOUCHED_Y = (1 << 6),
1143 SFNT_POINT_TOUCHED_BOTH = (SFNT_POINT_TOUCHED_X
1144 | SFNT_POINT_TOUCHED_Y),
1145 };
1146
1147/* This is needed because `round' below needs an interpreter
1148 argument. */
1149struct sfnt_interpreter;
1150
1151struct sfnt_graphics_state
1152{
1153 /* Pointer to the function used for rounding. This function is
1154 asymmetric, so -0.5 rounds up to 0, not -1. It is up to the
1155 caller to handle negative values.
1156
1157 Value is undefined unless sfnt_validate_gs has been called, and
1158 the second argument may be used to provide detailed rounding
1159 information (``super rounding state''.) */
1160 sfnt_f26dot6 (*round) (sfnt_f26dot6, struct sfnt_interpreter *);
1161
1162 /* Pointer to the function used to project euclidean vectors onto
1163 the projection vector. Value is the magnitude of the projected
1164 vector. */
1165 sfnt_f26dot6 (*project) (sfnt_f26dot6, sfnt_f26dot6,
1166 struct sfnt_interpreter *);
1167
1168 /* Pointer to the function used to project euclidean vectors onto
1169 the dual projection vector. Value is the magnitude of the
1170 projected vector. */
1171 sfnt_f26dot6 (*dual_project) (sfnt_f26dot6, sfnt_f26dot6,
1172 struct sfnt_interpreter *);
1173
1174 /* Pointer to the function used to move specified points
1175 along the freedom vector by a distance specified in terms
1176 of the projection vector. */
1177 void (*move) (sfnt_f26dot6 *restrict,
1178 sfnt_f26dot6 *restrict, size_t,
1179 struct sfnt_interpreter *,
1180 sfnt_f26dot6, unsigned char *);
1181
1182 /* Dot product between the freedom and the projection vectors. */
1183 sfnt_f2dot14 vector_dot_product;
1184
1185 /* Controls whether the sign of control value table entries will be
1186 changed to match the sign of the actual distance measurement with
1187 which it is compared. Setting auto flip to TRUE makes it
1188 possible to control distances measured with or against the
1189 projection vector with a single control value table entry. When
1190 auto flip is set to FALSE, distances must be measured with the
1191 projection vector. */
1192 bool auto_flip;
1193
1194 /* Limits the regularizing effects of control value table entries to
1195 cases where the difference between the table value and the
1196 measurement taken from the original outline is sufficiently
1197 small. */
1198 sfnt_f26dot6 cvt_cut_in;
1199
1200 /* Establishes the base value used to calculate the range of point
1201 sizes to which a given DELTAC[] or DELTAP[] instruction will
1202 apply. The formulas given below are used to calculate the range
1203 of the various DELTA instructions.
1204
1205 DELTAC1 DELTAP1 (delta_base) through (delta_base + 15)
1206 DELTAC2 DELTAP2 (delta_base + 16) through (delta_base + 31)
1207 DELTAC3 DELTAP3 (delta_base + 32) through (delta_base + 47)
1208
1209 Please keep this documentation in sync with the TrueType
1210 reference manual. */
1211 unsigned short delta_base;
1212
1213 /* Determines the range of movement and smallest magnitude of
1214 movement (the step) in a DELTAC[] or DELTAP[] instruction.
1215 Changing the value of the delta shift makes it possible to trade
1216 off fine control of point movement for range of movement. A low
1217 delta shift favors range of movement over fine control. A high
1218 delta shift favors fine control over range of movement. The step
1219 has the value 1/2 to the power delta shift. The range of
1220 movement is calculated by taking the number of steps allowed (16)
1221 and multiplying it by the step.
1222
1223 The legal range for delta shift is zero through six. Negative
1224 values are illegal. */
1225 unsigned short delta_shift;
1226
1227 /* A second projection vector set to a line defined by the original
1228 outline location of two points. The dual projection vector is
1229 used when it is necessary to measure distances from the scaled
1230 outline before any instructions were executed. */
1231 struct sfnt_unit_vector dual_projection_vector;
1232
1233 /* A unit vector that establishes an axis along which points can
1234 move. */
1235 struct sfnt_unit_vector freedom_vector;
1236
1237 /* Makes it possible to turn off instructions under some
1238 circumstances. When flag 1 is set, changes to the graphics state
1239 made in the control value program will be ignored. When flag is
1240 1, grid fitting instructions will be ignored. */
1241 unsigned char instruct_control;
1242
1243 /* Makes it possible to repeat certain instructions a designated
1244 number of times. The default value of one assures that unless
1245 the value of loop is altered, these instructions will execute one
1246 time. */
1247 unsigned short loop;
1248
1249 /* Establishes the smallest possible value to which a distance will
1250 be rounded. */
1251 sfnt_f26dot6 minimum_distance;
1252
1253 /* A unit vector whose direction establishes an axis along which
1254 distances are measured. */
1255 struct sfnt_unit_vector projection_vector;
1256
1257 /* Determines the manner in which values are rounded. Can be set to
1258 a number of predefined states or to a customized state with the
1259 SROUND or S45ROUND instructions. */
1260 int round_state;
1261
1262 /* Reference points. These reference point numbers, which together
1263 with a zone designation, specify a point in either the glyph zone
1264 or the twilight zone. */
1265 uint16_t rp0, rp1, rp2;
1266
1267 /* Flags which determine whether the interpreter will activate
1268 dropout control for the current glyph. */
1269 int scan_control;
1270
1271 /* The distance difference below which the interpreter will replace
1272 a CVT distance or an actual distance in favor of the single width
1273 value. */
1274 sfnt_f26dot6 sw_cut_in;
1275
1276 /* The value used in place of the control value table distance or
1277 the actual distance value when the difference between that
1278 distance and the single width value is less than the single width
1279 cut-in. */
1280 sfnt_f26dot6 single_width_value;
1281
1282 /* Zone pointers, which reference a zone. */
1283 int zp0, zp1, zp2;
1284};
1285
1286struct sfnt_interpreter
1287{
1288 /* The number of elements in the stack. */
1289 uint16_t max_stack_elements;
1290
1291 /* The number of instructions in INSTRUCTIONS. */
1292 uint16_t num_instructions;
1293
1294 /* Size of the storage area. */
1295 uint16_t storage_size;
1296
1297 /* Size of the function definition area. */
1298 uint16_t function_defs_size;
1299
1300 /* Size of the instruction definition area. */
1301 uint16_t instruction_defs_size;
1302
1303 /* Size of the twilight zone. */
1304 uint16_t twilight_zone_size;
1305
1306 /* The instruction pointer. This points to the instruction
1307 currently being executed. */
1308 int IP;
1309
1310 /* The current scale. */
1311 sfnt_fixed scale;
1312
1313 /* The current ppem and point size. */
1314 int ppem, point_size;
1315
1316 /* The execution stack. This has at most max_stack_elements
1317 elements. */
1318 uint32_t *stack;
1319
1320 /* Pointer past the top of the stack. */
1321 uint32_t *SP;
1322
1323 /* The size of the control value table. */
1324 size_t cvt_size;
1325
1326 /* Pointer to instructions currently being executed. */
1327 unsigned char *restrict instructions;
1328
1329 /* The twilight zone. May not be NULL. */
1330 sfnt_f26dot6 *restrict twilight_x, *restrict twilight_y;
1331
1332 /* The original X positions of points in the twilight zone. */
1333 sfnt_f26dot6 *restrict twilight_original_x;
1334
1335 /* The original Y positions of points in the twilight zone.
1336
1337 Apple does not directly say whether or not points in the twilight
1338 zone can have their original positions changed. But this is
1339 implied by ``create points in the twilight zone''. */
1340 sfnt_f26dot6 *restrict twilight_original_y;
1341
1342 /* The scaled outlines being manipulated. May be NULL. */
1343 struct sfnt_interpreter_zone *glyph_zone;
1344
1345 /* The glyph advance width. Value is undefined unless GLYPH_ZONE is
1346 set. */
1347 sfnt_f26dot6 advance_width;
1348
1349 /* The storage area. */
1350 uint32_t *storage;
1351
1352 /* Control value table values. */
1353 sfnt_f26dot6 *cvt;
1354
1355 /* Function definitions. */
1356 struct sfnt_interpreter_definition *function_defs;
1357
1358 /* Instruction definitions. */
1359 struct sfnt_interpreter_definition *instruction_defs;
1360
1361 /* Interpreter registers. */
1362 struct sfnt_graphics_state state;
1363
1364 /* Detailed rounding state used when state.round_state indicates
1365 that fine grained rounding should be used.
1366
1367 PERIOD says how often a round value occurs, for numbers
1368 increasing from PHASE to infinity.
1369
1370 THRESHOLD says when to round a value between two increasing
1371 periods towards the larger period. */
1372 sfnt_f26dot6 period, phase, threshold;
1373
1374 /* The depth of any ongoing calls. */
1375 int call_depth;
1376
1377 /* Jump buffer for traps. */
1378 jmp_buf trap;
1379
1380 /* What was the trap. */
1381 const char *trap_reason;
1382
1383#ifdef TEST
1384 /* If non-NULL, function called before each instruction is
1385 executed. */
1386 void (*run_hook) (struct sfnt_interpreter *);
1387
1388 /* If non-NULL, function called before each stack element is
1389 pushed. */
1390 void (*push_hook) (struct sfnt_interpreter *, uint32_t);
1391
1392 /* If non-NULL, function called before each stack element is
1393 popped. */
1394 void (*pop_hook) (struct sfnt_interpreter *, uint32_t);
1395#endif
1396};
1397
1398
1399
1400/* Glyph hinting. */
1401
1402/* Structure describing a single scaled and fitted outline. */
1403
1404struct sfnt_instructed_outline
1405{
1406 /* The number of points in this contour, including the two phantom
1407 points at the end. */
1408 size_t num_points;
1409
1410 /* The number of contours in this outline. */
1411 size_t num_contours;
1412
1413 /* The end points of each contour. */
1414 size_t *contour_end_points;
1415
1416 /* The points of each contour, with two additional phantom points at
1417 the end. */
1418 sfnt_f26dot6 *restrict x_points, *restrict y_points;
1419
1420 /* The flags of each point. */
1421 unsigned char *flags;
1422};
1423
1424
1425
1426/* Functions used to read tables used by the TrueType interpreter. */
1427
1428#ifndef TEST
1429
1430#define PROTOTYPE int, struct sfnt_offset_subtable *
1431
1432extern struct sfnt_cvt_table *sfnt_read_cvt_table (PROTOTYPE);
1433extern struct sfnt_fpgm_table *sfnt_read_fpgm_table (PROTOTYPE);
1434extern struct sfnt_prep_table *sfnt_read_prep_table (PROTOTYPE);
1435
1436#undef PROTOTYPE
1437
1438#define PROTOTYPE \
1439 struct sfnt_maxp_table *, \
1440 struct sfnt_cvt_table *, \
1441 struct sfnt_head_table *, \
1442 int, int
1443
1444extern struct sfnt_interpreter *sfnt_make_interpreter (PROTOTYPE);
1445
1446#undef PROTOTYPE
1447
1448#define PROTOTYPE \
1449 struct sfnt_interpreter *, \
1450 struct sfnt_fpgm_table *
1451
1452extern const char *sfnt_interpret_font_program (PROTOTYPE);
1453
1454#undef PROTOTYPE
1455
1456#define PROTOTYPE \
1457 struct sfnt_interpreter *, \
1458 struct sfnt_prep_table *, \
1459 struct sfnt_graphics_state *
1460
1461extern const char *sfnt_interpret_control_value_program (PROTOTYPE);
1462
1463#undef PROTOTYPE
1464
1465#define PROTOTYPE struct sfnt_instructed_outline *
1466
1467extern struct sfnt_glyph_outline *sfnt_build_instructed_outline (PROTOTYPE);
1468
1469#undef PROTOTYPE
1470
1471#define PROTOTYPE \
1472 struct sfnt_glyph *, \
1473 struct sfnt_interpreter *, \
1474 struct sfnt_glyph_metrics *, \
1475 struct sfnt_instructed_outline **
1476
1477extern const char *sfnt_interpret_simple_glyph (PROTOTYPE);
1478
1479#undef PROTOTYPE
1480
1481#endif /* TEST */
1482
1483
1484
1485#endif /* SFNT_ENABLE_HINTING */
1486
1006#endif /* _SFNT_H_ */ 1487#endif /* _SFNT_H_ */
diff --git a/src/sfntfont-android.c b/src/sfntfont-android.c
index d8f598fd330..feea92827d9 100644
--- a/src/sfntfont-android.c
+++ b/src/sfntfont-android.c
@@ -454,7 +454,7 @@ sfntfont_android_put_glyphs (struct glyph_string *s, int from,
454 { 454 {
455 text.x1 = x_coords[0] + rasters[0]->offx; 455 text.x1 = x_coords[0] + rasters[0]->offx;
456 text.x2 = text.x1 + rasters[0]->width; 456 text.x2 = text.x1 + rasters[0]->width;
457 text.y1 = y - (rasters[0]->height + rasters[0]->offy); 457 text.y1 = y - rasters[0]->height - rasters[0]->offy;
458 text.y2 = y - rasters[0]->offy; 458 text.y2 = y - rasters[0]->offy;
459 } 459 }
460 else 460 else
@@ -469,7 +469,7 @@ sfntfont_android_put_glyphs (struct glyph_string *s, int from,
469 469
470 character.x1 = x_coords[i] + rasters[i]->offx; 470 character.x1 = x_coords[i] + rasters[i]->offx;
471 character.x2 = character.x1 + rasters[i]->width; 471 character.x2 = character.x1 + rasters[i]->width;
472 character.y1 = y - (rasters[i]->height + rasters[i]->offy); 472 character.y1 = y - rasters[i]->height - rasters[i]->offy;
473 character.y2 = y - rasters[i]->offy; 473 character.y2 = y - rasters[i]->offy;
474 474
475 sfntfont_android_union_boxes (text, character, &text); 475 sfntfont_android_union_boxes (text, character, &text);
diff --git a/src/sfntfont.c b/src/sfntfont.c
index d9b152e27eb..dbd1a037f4a 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -1456,6 +1456,9 @@ sfntfont_dereference_outline (struct sfnt_glyph_outline *outline)
1456 Use the offset information in the long or short loca tables 1456 Use the offset information in the long or short loca tables
1457 LOCA_LONG and LOCA_SHORT, whichever is set. 1457 LOCA_LONG and LOCA_SHORT, whichever is set.
1458 1458
1459 If INTERPRETER is non-NULL, then possibly use the unscaled glyph
1460 metrics in METRICS when instructing the glyph.
1461
1459 Return the outline with an incremented reference count and enter 1462 Return the outline with an incremented reference count and enter
1460 the generated outline into CACHE upon success, possibly discarding 1463 the generated outline into CACHE upon success, possibly discarding
1461 any older outlines, or NULL on failure. */ 1464 any older outlines, or NULL on failure. */
@@ -1467,12 +1470,16 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
1467 struct sfnt_glyf_table *glyf, 1470 struct sfnt_glyf_table *glyf,
1468 struct sfnt_head_table *head, 1471 struct sfnt_head_table *head,
1469 struct sfnt_loca_table_short *loca_short, 1472 struct sfnt_loca_table_short *loca_short,
1470 struct sfnt_loca_table_long *loca_long) 1473 struct sfnt_loca_table_long *loca_long,
1474 struct sfnt_interpreter *interpreter,
1475 struct sfnt_glyph_metrics *metrics)
1471{ 1476{
1472 struct sfnt_outline_cache *start; 1477 struct sfnt_outline_cache *start;
1473 struct sfnt_glyph_outline *outline; 1478 struct sfnt_glyph_outline *outline;
1474 struct sfnt_glyph *glyph; 1479 struct sfnt_glyph *glyph;
1475 struct sfntfont_get_glyph_outline_dcontext dcontext; 1480 struct sfntfont_get_glyph_outline_dcontext dcontext;
1481 struct sfnt_instructed_outline *value;
1482 const char *error;
1476 1483
1477 start = cache->next; 1484 start = cache->next;
1478 1485
@@ -1504,14 +1511,32 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
1504 if (!glyph) 1511 if (!glyph)
1505 return NULL; 1512 return NULL;
1506 1513
1514 /* Try to instruct the glyph if INTERPRETER is specified.
1515 TODO: support compound glyphs. */
1516
1517 outline = NULL;
1518
1519 if (interpreter && glyph->simple)
1520 {
1521 error = sfnt_interpret_simple_glyph (glyph, interpreter,
1522 metrics, &value);
1523
1524 if (!error)
1525 {
1526 outline = sfnt_build_instructed_outline (value);
1527 xfree (value);
1528 }
1529 }
1530
1507 dcontext.loca_long = loca_long; 1531 dcontext.loca_long = loca_long;
1508 dcontext.loca_short = loca_short; 1532 dcontext.loca_short = loca_short;
1509 dcontext.glyf = glyf; 1533 dcontext.glyf = glyf;
1510 1534
1511 outline = sfnt_build_glyph_outline (glyph, head, pixel_size, 1535 if (!outline)
1512 sfntfont_get_glyph, 1536 outline = sfnt_build_glyph_outline (glyph, head, pixel_size,
1513 sfntfont_free_glyph, 1537 sfntfont_get_glyph,
1514 &dcontext); 1538 sfntfont_free_glyph,
1539 &dcontext);
1515 xfree (glyph); 1540 xfree (glyph);
1516 1541
1517 if (!outline) 1542 if (!outline)
@@ -1709,6 +1734,9 @@ struct sfnt_font_info
1709 struct sfnt_glyf_table *glyf; 1734 struct sfnt_glyf_table *glyf;
1710 struct sfnt_loca_table_short *loca_short; 1735 struct sfnt_loca_table_short *loca_short;
1711 struct sfnt_loca_table_long *loca_long; 1736 struct sfnt_loca_table_long *loca_long;
1737 struct sfnt_prep_table *prep;
1738 struct sfnt_fpgm_table *fpgm;
1739 struct sfnt_cvt_table *cvt;
1712 1740
1713 /* The selected character map. */ 1741 /* The selected character map. */
1714 struct sfnt_cmap_encoding_subtable_data *cmap_data; 1742 struct sfnt_cmap_encoding_subtable_data *cmap_data;
@@ -1727,6 +1755,13 @@ struct sfnt_font_info
1727 1755
1728 /* Number of elements in the raster cache. */ 1756 /* Number of elements in the raster cache. */
1729 int raster_cache_size; 1757 int raster_cache_size;
1758
1759 /* Interpreter for grid fitting (if enabled). */
1760 struct sfnt_interpreter *interpreter;
1761
1762 /* Graphics state after the execution of the font and control value
1763 programs. */
1764 struct sfnt_graphics_state state;
1730}; 1765};
1731 1766
1732/* Look up the glyph corresponding to the character C in FONT. Return 1767/* Look up the glyph corresponding to the character C in FONT. Return
@@ -1813,6 +1848,106 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info)
1813 font_info->font.average_width = total_width / num_characters; 1848 font_info->font.average_width = total_width / num_characters;
1814} 1849}
1815 1850
1851/* Initialize the instruction interpreter for INFO, whose file and
1852 offset subtable should be respectively FD and SUBTABLE. Load the
1853 font and preprogram for the pixel size in INFO and its
1854 corresponding point size POINT_SIZE.
1855
1856 The font tables in INFO must already have been initialized.
1857
1858 Set INFO->interpreter, INFO->cvt, INFO->prep, INFO->fpgm and
1859 INFO->state upon success, and leave those fields intact
1860 otherwise. */
1861
1862static void
1863sfntfont_setup_interpreter (int fd, struct sfnt_font_info *info,
1864 struct sfnt_offset_subtable *subtable,
1865 int point_size)
1866{
1867 struct sfnt_cvt_table *cvt;
1868 struct sfnt_fpgm_table *fpgm;
1869 struct sfnt_prep_table *prep;
1870 struct sfnt_interpreter *interpreter;
1871 const char *error;
1872 struct sfnt_graphics_state state;
1873
1874 /* Try to read the control value program, cvt, and font program
1875 tables. */
1876
1877 cvt = sfnt_read_cvt_table (fd, subtable);
1878 fpgm = sfnt_read_fpgm_table (fd, subtable);
1879 prep = sfnt_read_prep_table (fd, subtable);
1880
1881 /* If both fpgm and prep are NULL, this font likely has no
1882 instructions, so don't bother setting up the interpreter. */
1883
1884 if (!fpgm && !prep)
1885 goto bail;
1886
1887 /* Now, create the interpreter using the limits in info->maxp and
1888 info->head. CVT can be NULL. */
1889 interpreter = sfnt_make_interpreter (info->maxp, cvt, info->head,
1890 info->font.pixel_size,
1891 point_size);
1892
1893 /* Bail if the interpreter couldn't be created. */
1894 if (!interpreter)
1895 goto bail;
1896
1897 if (fpgm)
1898 {
1899 /* Otherwise, evaluate the font and cvt programs.
1900
1901 FIXME: make sure infinite loops inside these programs
1902 cannot lock up Emacs. */
1903
1904 error = sfnt_interpret_font_program (interpreter, fpgm);
1905
1906 if (error)
1907 {
1908 /* If an error occurs, log it to the *Messages* buffer. */
1909 message_with_string ("While interpreting font program: %s",
1910 build_string (error), true);
1911 goto bail1;
1912 }
1913
1914 /* Save the graphics state. */
1915 state = interpreter->state;
1916 }
1917
1918 if (prep)
1919 {
1920 /* This will overwrite state if the instruction control is set
1921 appropriately. */
1922 error = sfnt_interpret_control_value_program (interpreter, prep,
1923 &state);
1924
1925 if (error)
1926 {
1927 /* If an error occurs, log it to the *Messages* buffer. */
1928 message_with_string ("While interpreting preprogram: %s",
1929 build_string (error), true);
1930 goto bail1;
1931 }
1932 }
1933
1934 /* The interpreter has been properly set up. */
1935 info->fpgm = fpgm;
1936 info->prep = prep;
1937 info->cvt = cvt;
1938 info->state = state;
1939 info->interpreter = interpreter;
1940
1941 return;
1942
1943 bail1:
1944 xfree (interpreter);
1945 bail:
1946 xfree (cvt);
1947 xfree (fpgm);
1948 xfree (prep);
1949}
1950
1816/* Open the font corresponding to the font-entity FONT_ENTITY. Return 1951/* Open the font corresponding to the font-entity FONT_ENTITY. Return
1817 nil upon failure, else the opened font-object. */ 1952 nil upon failure, else the opened font-object. */
1818 1953
@@ -1829,6 +1964,8 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
1829 struct sfnt_cmap_encoding_subtable *subtables; 1964 struct sfnt_cmap_encoding_subtable *subtables;
1830 struct sfnt_cmap_encoding_subtable_data **data; 1965 struct sfnt_cmap_encoding_subtable_data **data;
1831 struct charset *charset; 1966 struct charset *charset;
1967 int point_size;
1968 Display_Info *dpyinfo;
1832 1969
1833 if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0) 1970 if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
1834 pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)); 1971 pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
@@ -1868,6 +2005,9 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
1868 font_info->loca_short = NULL; 2005 font_info->loca_short = NULL;
1869 font_info->loca_long = NULL; 2006 font_info->loca_long = NULL;
1870 font_info->cmap_data = NULL; 2007 font_info->cmap_data = NULL;
2008 font_info->prep = NULL;
2009 font_info->fpgm = NULL;
2010 font_info->cvt = NULL;
1871 2011
1872 font_info->outline_cache.next = &font_info->outline_cache; 2012 font_info->outline_cache.next = &font_info->outline_cache;
1873 font_info->outline_cache.last = &font_info->outline_cache; 2013 font_info->outline_cache.last = &font_info->outline_cache;
@@ -1875,6 +2015,7 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
1875 font_info->raster_cache.next = &font_info->raster_cache; 2015 font_info->raster_cache.next = &font_info->raster_cache;
1876 font_info->raster_cache.last = &font_info->raster_cache; 2016 font_info->raster_cache.last = &font_info->raster_cache;
1877 font_info->raster_cache_size = 0; 2017 font_info->raster_cache_size = 0;
2018 font_info->interpreter = NULL;
1878 2019
1879 /* Open the font. */ 2020 /* Open the font. */
1880 fd = emacs_open (desc->path, O_RDONLY, 0); 2021 fd = emacs_open (desc->path, O_RDONLY, 0);
@@ -2027,9 +2168,20 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
2027 /* Calculate the xfld name. */ 2168 /* Calculate the xfld name. */
2028 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil); 2169 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
2029 2170
2171 /* Now try to set up grid fitting for this font. */
2172 dpyinfo = FRAME_DISPLAY_INFO (f);
2173 point_size = PIXEL_TO_POINT (pixel_size, (dpyinfo->resx
2174 * dpyinfo->resy
2175 / 2));
2176 sfntfont_setup_interpreter (fd, font_info, subtable,
2177 point_size);
2178
2030 /* Close the font file descriptor. */ 2179 /* Close the font file descriptor. */
2031 emacs_close (fd); 2180 emacs_close (fd);
2032 2181
2182 /* Free the offset subtable. */
2183 xfree (subtable);
2184
2033 /* All done. */ 2185 /* All done. */
2034 unblock_input (); 2186 unblock_input ();
2035 return font_object; 2187 return font_object;
@@ -2091,6 +2243,54 @@ sfntfont_encode_char (struct font *font, int c)
2091} 2243}
2092 2244
2093/* Measure the single glyph GLYPH in the font FONT and return its 2245/* Measure the single glyph GLYPH in the font FONT and return its
2246 metrics in *PCM.
2247
2248 Instruct the glyph if possible.
2249
2250 Value is 0 upon success, 1 otherwise. */
2251
2252static int
2253sfntfont_measure_instructed_pcm (struct sfnt_font_info *font, sfnt_glyph glyph,
2254 struct font_metrics *pcm)
2255{
2256 struct sfnt_glyph_metrics metrics;
2257 struct sfnt_glyph_outline *outline;
2258
2259 /* Ask for unscaled metrics. */
2260 if (sfnt_lookup_glyph_metrics (glyph, -1, &metrics, font->hmtx,
2261 font->hhea, font->head, font->maxp))
2262 return 1;
2263
2264 /* Now get the glyph outline, which is required to obtain the rsb,
2265 ascent and descent. */
2266 outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache,
2267 font->font.pixel_size,
2268 &font->outline_cache_size,
2269 font->glyf, font->head,
2270 font->loca_short,
2271 font->loca_long,
2272 font->interpreter, &metrics);
2273
2274 if (!outline)
2275 return 1;
2276
2277 /* Scale the metrics by the interpreter's scale. */
2278 sfnt_scale_metrics (&metrics, font->interpreter->scale);
2279
2280 /* How to round lbearing and rbearing? */
2281 pcm->lbearing = metrics.lbearing >> 16;
2282 pcm->rbearing = outline->xmax >> 16;
2283
2284 /* Round the advance, ascent and descent upwards. */
2285 pcm->width = SFNT_CEIL_FIXED (metrics.advance) >> 16;
2286 pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) >> 16;
2287 pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) >> 16;
2288
2289 sfntfont_dereference_outline (outline);
2290 return 0;
2291}
2292
2293/* Measure the single glyph GLYPH in the font FONT and return its
2094 metrics in *PCM. Value is 0 upon success, 1 otherwise. */ 2294 metrics in *PCM. Value is 0 upon success, 1 otherwise. */
2095 2295
2096static int 2296static int
@@ -2100,6 +2300,10 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph,
2100 struct sfnt_glyph_metrics metrics; 2300 struct sfnt_glyph_metrics metrics;
2101 struct sfnt_glyph_outline *outline; 2301 struct sfnt_glyph_outline *outline;
2102 2302
2303 if (font->interpreter)
2304 /* Use a function which instructs the glyph. */
2305 return sfntfont_measure_instructed_pcm (font, glyph, pcm);
2306
2103 /* Get the glyph metrics first. */ 2307 /* Get the glyph metrics first. */
2104 if (sfnt_lookup_glyph_metrics (glyph, font->font.pixel_size, 2308 if (sfnt_lookup_glyph_metrics (glyph, font->font.pixel_size,
2105 &metrics, font->hmtx, font->hhea, 2309 &metrics, font->hmtx, font->hhea,
@@ -2113,7 +2317,7 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph,
2113 &font->outline_cache_size, 2317 &font->outline_cache_size,
2114 font->glyf, font->head, 2318 font->glyf, font->head,
2115 font->loca_short, 2319 font->loca_short,
2116 font->loca_long); 2320 font->loca_long, NULL, NULL);
2117 2321
2118 if (!outline) 2322 if (!outline)
2119 return 1; 2323 return 1;
@@ -2192,6 +2396,10 @@ sfntfont_close (struct font *font)
2192 xfree (info->loca_short); 2396 xfree (info->loca_short);
2193 xfree (info->loca_long); 2397 xfree (info->loca_long);
2194 xfree (info->cmap_data); 2398 xfree (info->cmap_data);
2399 xfree (info->prep);
2400 xfree (info->fpgm);
2401 xfree (info->cvt);
2402 xfree (info->interpreter);
2195 2403
2196 sfntfont_free_outline_cache (&info->outline_cache); 2404 sfntfont_free_outline_cache (&info->outline_cache);
2197 sfntfont_free_raster_cache (&info->raster_cache); 2405 sfntfont_free_raster_cache (&info->raster_cache);
@@ -2221,10 +2429,15 @@ sfntfont_draw (struct glyph_string *s, int from, int to,
2221 struct font *font; 2429 struct font *font;
2222 struct sfnt_font_info *info; 2430 struct sfnt_font_info *info;
2223 struct sfnt_glyph_metrics metrics; 2431 struct sfnt_glyph_metrics metrics;
2432 int pixel_size;
2224 2433
2225 length = to - from; 2434 length = to - from;
2226 font = s->font; 2435 font = s->font;
2227 info = (struct sfnt_font_info *) font; 2436 info = (struct sfnt_font_info *) font;
2437 pixel_size = font->pixel_size;
2438
2439 if (info->interpreter)
2440 pixel_size = -1;
2228 2441
2229 rasters = alloca (length * sizeof *rasters); 2442 rasters = alloca (length * sizeof *rasters);
2230 x_coords = alloca (length * sizeof *x_coords); 2443 x_coords = alloca (length * sizeof *x_coords);
@@ -2233,8 +2446,9 @@ sfntfont_draw (struct glyph_string *s, int from, int to,
2233 /* Get rasters and outlines for them. */ 2446 /* Get rasters and outlines for them. */
2234 for (i = from; i < to; ++i) 2447 for (i = from; i < to; ++i)
2235 { 2448 {
2236 /* Look up the metrics for this glyph. */ 2449 /* Look up the metrics for this glyph. The metrics are unscaled
2237 if (sfnt_lookup_glyph_metrics (s->char2b[i], font->pixel_size, 2450 if INFO->interpreter is set. */
2451 if (sfnt_lookup_glyph_metrics (s->char2b[i], pixel_size,
2238 &metrics, info->hmtx, info->hhea, 2452 &metrics, info->hmtx, info->hhea,
2239 info->head, info->maxp)) 2453 info->head, info->maxp))
2240 { 2454 {
@@ -2250,7 +2464,9 @@ sfntfont_draw (struct glyph_string *s, int from, int to,
2250 &info->outline_cache_size, 2464 &info->outline_cache_size,
2251 info->glyf, info->head, 2465 info->glyf, info->head,
2252 info->loca_short, 2466 info->loca_short,
2253 info->loca_long); 2467 info->loca_long,
2468 info->interpreter,
2469 &metrics);
2254 x_coords[i - from] = 0; 2470 x_coords[i - from] = 0;
2255 2471
2256 if (!outline) 2472 if (!outline)
@@ -2259,6 +2475,10 @@ sfntfont_draw (struct glyph_string *s, int from, int to,
2259 continue; 2475 continue;
2260 } 2476 }
2261 2477
2478 /* Scale the metrics if info->interpreter is set. */
2479 if (info->interpreter)
2480 sfnt_scale_metrics (&metrics, info->interpreter->scale);
2481
2262 /* Rasterize the outline. */ 2482 /* Rasterize the outline. */
2263 rasters[i - from] = sfntfont_get_glyph_raster (s->char2b[i], 2483 rasters[i - from] = sfntfont_get_glyph_raster (s->char2b[i],
2264 &info->raster_cache, 2484 &info->raster_cache,