aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-08-16 11:02:55 +0800
committerPo Lu2023-08-16 11:02:55 +0800
commit6dacf5bce4e55f216561c3f38561b5479f8ba640 (patch)
treedd07e9ed013d9d6eb03659618159ba9e20afd2f9 /src
parent612f25c24ff08b9343ec8897c8dbcfc02d9b0d07 (diff)
downloademacs-6dacf5bce4e55f216561c3f38561b5479f8ba640.tar.gz
emacs-6dacf5bce4e55f216561c3f38561b5479f8ba640.zip
Fix display of compound glyphs that employ simple transforms
* src/sfnt.c (sfnt_transform_coordinates): Always compute an affine transform matrix except if no scale is provided at all. Unconditionally apply x_off and y_off. (sfnt_decompose_compound_glyph): Delete arguments OF_X and OFF_Y. Apply component offsets after writing simple glyph contours. (sfnt_decompose_glyph): Modify for new calling convention. (sfnt_transform_f26dot6): Modify analogously to sfnt_decompose_compound_glyph. Also correct anchor offset computation to scale the unscaled component anchor coordinates by the interpreter scale. (sfnt_interpret_compound_glyph_1): Also modify for new calling convention. * src/sfnt.h (struct sfnt_compound_glyph_component): <u>: Make scale fields signed.
Diffstat (limited to 'src')
-rw-r--r--src/sfnt.c220
-rw-r--r--src/sfnt.h14
2 files changed, 117 insertions, 117 deletions
diff --git a/src/sfnt.c b/src/sfnt.c
index 71e7ecfde47..5cea2613ddb 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -2442,11 +2442,7 @@ sfnt_free_glyph (struct sfnt_glyph *glyph)
2442 the array of points of length NUM_COORDINATES given as X and Y. 2442 the array of points of length NUM_COORDINATES given as X and Y.
2443 2443
2444 Also, apply the fixed point offsets X_OFF and Y_OFF to each X and Y 2444 Also, apply the fixed point offsets X_OFF and Y_OFF to each X and Y
2445 coordinate. 2445 coordinate after transforms within COMPONENT are effected. */
2446
2447 See sfnt_decompose_compound_glyph for an explanation of why offsets
2448 might be applied here, and not while reading the subglyph
2449 itself. */
2450 2446
2451static void 2447static void
2452sfnt_transform_coordinates (struct sfnt_compound_glyph_component *component, 2448sfnt_transform_coordinates (struct sfnt_compound_glyph_component *component,
@@ -2460,56 +2456,59 @@ sfnt_transform_coordinates (struct sfnt_compound_glyph_component *component,
2460 2456
2461 if (component->flags & 010) /* WE_HAVE_A_SCALE */ 2457 if (component->flags & 010) /* WE_HAVE_A_SCALE */
2462 { 2458 {
2463 for (i = 0; i < num_coordinates; ++i) 2459 m1 = component->u.scale / 16384.0;
2464 { 2460 m2 = m3 = m4 = 0;
2465 x[i] *= component->u.scale / 16384.0; 2461 m5 = component->u.scale / 16384.0;
2466 y[i] *= component->u.scale / 16384.0; 2462 m6 = 0;
2467 x[i] += x_off;
2468 y[i] += y_off;
2469 }
2470 } 2463 }
2471 else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */ 2464 else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */
2472 { 2465 {
2473 for (i = 0; i < num_coordinates; ++i) 2466 m1 = component->u.a.xscale / 16384.0;
2474 { 2467 m2 = m3 = m4 = 0;
2475 x[i] *= component->u.a.xscale / 16384.0; 2468 m5 = component->u.a.yscale / 16384.0;
2476 y[i] *= component->u.a.yscale / 16384.0; 2469 m6 = 0;
2477 x[i] += x_off;
2478 y[i] += y_off;
2479 }
2480 } 2470 }
2481 else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */ 2471 else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
2482 { 2472 {
2483 /* Apply the specified affine transformation.
2484 A transform looks like:
2485
2486 M1 M2 M3 X
2487 M4 M5 M6 * Y
2488
2489 =
2490
2491 M1*X + M2*Y + M3*1 = X1
2492 M4*X + M5*Y + M6*1 = Y1
2493
2494 (In most transforms, there is another row at the bottom for
2495 mathematical reasons. Since Z1 is always 1.0, the row is
2496 simply implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 =
2497 1.0. See the definition of matrix3x3 in image.c for some
2498 more explanations about this.) */
2499 m1 = component->u.b.xscale / 16384.0; 2473 m1 = component->u.b.xscale / 16384.0;
2500 m2 = component->u.b.scale01 / 16384.0; 2474 m2 = component->u.b.scale01 / 16384.0;
2501 m3 = 0; 2475 m3 = 0;
2502 m4 = component->u.b.scale10 / 16384.0; 2476 m4 = component->u.b.scale10 / 16384.0;
2503 m5 = component->u.b.yscale / 16384.0; 2477 m5 = component->u.b.yscale / 16384.0;
2504 m6 = 0; 2478 m6 = 0;
2505 2479 }
2480 else /* No scale, just apply x_off and y_off. */
2481 {
2506 for (i = 0; i < num_coordinates; ++i) 2482 for (i = 0; i < num_coordinates; ++i)
2507 { 2483 x[i] += x_off, y[i] += y_off;
2508 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1; 2484
2509 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1; 2485 return;
2510 x[i] += x_off; 2486 }
2511 y[i] += y_off; 2487
2512 } 2488 m3 = x_off;
2489 m6 = y_off;
2490
2491 /* Apply the specified affine transformation.
2492 A transform looks like:
2493
2494 M1 M2 M3 X
2495 M4 M5 M6 * Y
2496
2497 =
2498
2499 M1*X + M2*Y + M3*1 = X1
2500 M4*X + M5*Y + M6*1 = Y1
2501
2502 (In most transforms, there is another row at the bottom for
2503 mathematical reasons. Since Z1 is always 1.0, the row is simply
2504 implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 = 1.0. See
2505 the definition of matrix3x3 in image.c for some more explanations
2506 about this.) */
2507
2508 for (i = 0; i < num_coordinates; ++i)
2509 {
2510 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
2511 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
2513 } 2512 }
2514} 2513}
2515 2514
@@ -2629,10 +2628,9 @@ sfnt_round_fixed (int32_t number)
2629/* Decompose GLYPH, a compound glyph, into an array of points and 2628/* Decompose GLYPH, a compound glyph, into an array of points and
2630 contours. 2629 contours.
2631 2630
2632 CONTEXT should be zeroed and put on the stack. OFF_X and OFF_Y 2631 CONTEXT should be zeroed and put on the stack. RECURSION_COUNT
2633 should be zero, as should RECURSION_COUNT. GET_GLYPH and 2632 should be initialized to 0. GET_GLYPH and FREE_GLYPH, along with
2634 FREE_GLYPH, along with DCONTEXT, mean the same as in 2633 DCONTEXT, mean the same as in sfnt_decompose_glyph.
2635 sfnt_decompose_glyph.
2636 2634
2637 Value is 1 upon failure, else 0. */ 2635 Value is 1 upon failure, else 0. */
2638 2636
@@ -2641,7 +2639,6 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2641 struct sfnt_compound_glyph_context *context, 2639 struct sfnt_compound_glyph_context *context,
2642 sfnt_get_glyph_proc get_glyph, 2640 sfnt_get_glyph_proc get_glyph,
2643 sfnt_free_glyph_proc free_glyph, 2641 sfnt_free_glyph_proc free_glyph,
2644 sfnt_fixed off_x, sfnt_fixed off_y,
2645 int recursion_count, 2642 int recursion_count,
2646 void *dcontext) 2643 void *dcontext)
2647{ 2644{
@@ -2822,16 +2819,14 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2822 2819
2823 for (i = 0; i <= last_point; ++i) 2820 for (i = 0; i <= last_point; ++i)
2824 { 2821 {
2825 x_base[i] = ((subglyph->simple->x_coordinates[i] * 65536) 2822 x_base[i] = (subglyph->simple->x_coordinates[i] * 65536);
2826 + off_x + x); 2823 y_base[i] = (subglyph->simple->y_coordinates[i] * 65536);
2827 y_base[i] = ((subglyph->simple->y_coordinates[i] * 65536)
2828 + off_y + y);
2829 flags_base[i] = subglyph->simple->flags[i]; 2824 flags_base[i] = subglyph->simple->flags[i];
2830 } 2825 }
2831 2826
2832 /* Apply the transform to the points. */ 2827 /* Apply the transform to the points. */
2833 sfnt_transform_coordinates (component, x_base, y_base, 2828 sfnt_transform_coordinates (component, x_base, y_base,
2834 last_point + 1, 0, 0); 2829 last_point + 1, x, y);
2835 2830
2836 /* Copy over the contours. */ 2831 /* Copy over the contours. */
2837 for (i = 0; i < number_of_contours; ++i) 2832 for (i = 0; i < number_of_contours; ++i)
@@ -2847,8 +2842,6 @@ sfnt_decompose_compound_glyph (struct sfnt_glyph *glyph,
2847 context, 2842 context,
2848 get_glyph, 2843 get_glyph,
2849 free_glyph, 2844 free_glyph,
2850 off_x + x,
2851 off_y + y,
2852 recursion_count + 1, 2845 recursion_count + 1,
2853 dcontext); 2846 dcontext);
2854 2847
@@ -3276,7 +3269,7 @@ sfnt_decompose_glyph (struct sfnt_glyph *glyph,
3276 3269
3277 if (sfnt_decompose_compound_glyph (glyph, &context, 3270 if (sfnt_decompose_compound_glyph (glyph, &context,
3278 get_glyph, free_glyph, 3271 get_glyph, free_glyph,
3279 0, 0, 0, dcontext)) 3272 0, dcontext))
3280 { 3273 {
3281 xfree (context.x_coordinates); 3274 xfree (context.x_coordinates);
3282 xfree (context.y_coordinates); 3275 xfree (context.y_coordinates);
@@ -11347,11 +11340,8 @@ sfnt_interpret_simple_glyph (struct sfnt_glyph *glyph,
11347 Treat X and Y as arrays of 26.6 fixed point values. 11340 Treat X and Y as arrays of 26.6 fixed point values.
11348 11341
11349 Also, apply the 26.6 fixed point offsets X_OFF and Y_OFF to each X 11342 Also, apply the 26.6 fixed point offsets X_OFF and Y_OFF to each X
11350 and Y coordinate. 11343 and Y coordinate after the transforms in COMPONENT are
11351 11344 effected. */
11352 See sfnt_decompose_compound_glyph for an explanation of why offsets
11353 might be applied here, and not while reading the subglyph
11354 itself. */
11355 11345
11356static void 11346static void
11357sfnt_transform_f26dot6 (struct sfnt_compound_glyph_component *component, 11347sfnt_transform_f26dot6 (struct sfnt_compound_glyph_component *component,
@@ -11365,56 +11355,59 @@ sfnt_transform_f26dot6 (struct sfnt_compound_glyph_component *component,
11365 11355
11366 if (component->flags & 010) /* WE_HAVE_A_SCALE */ 11356 if (component->flags & 010) /* WE_HAVE_A_SCALE */
11367 { 11357 {
11368 for (i = 0; i < num_coordinates; ++i) 11358 m1 = component->u.scale / 16384.0;
11369 { 11359 m2 = m3 = m4 = 0;
11370 x[i] *= component->u.scale / 16384.0; 11360 m5 = component->u.scale / 16384.0;
11371 y[i] *= component->u.scale / 16384.0; 11361 m6 = 0;
11372 x[i] += x_off;
11373 y[i] += y_off;
11374 }
11375 } 11362 }
11376 else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */ 11363 else if (component->flags & 0100) /* WE_HAVE_AN_X_AND_Y_SCALE */
11377 { 11364 {
11378 for (i = 0; i < num_coordinates; ++i) 11365 m1 = component->u.a.xscale / 16384.0;
11379 { 11366 m2 = m3 = m4 = 0;
11380 x[i] *= component->u.a.xscale / 16384.0; 11367 m5 = component->u.a.yscale / 16384.0;
11381 y[i] *= component->u.a.yscale / 16384.0; 11368 m6 = 0;
11382 x[i] += x_off;
11383 y[i] += y_off;
11384 }
11385 } 11369 }
11386 else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */ 11370 else if (component->flags & 0200) /* WE_HAVE_A_TWO_BY_TWO */
11387 { 11371 {
11388 /* Apply the specified affine transformation.
11389 A transform looks like:
11390
11391 M1 M2 M3 X
11392 M4 M5 M6 * Y
11393
11394 =
11395
11396 M1*X + M2*Y + M3*1 = X1
11397 M4*X + M5*Y + M6*1 = Y1
11398
11399 (In most transforms, there is another row at the bottom for
11400 mathematical reasons. Since Z1 is always 1.0, the row is
11401 simply implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 =
11402 1.0. See the definition of matrix3x3 in image.c for some
11403 more explanations about this.) */
11404 m1 = component->u.b.xscale / 16384.0; 11372 m1 = component->u.b.xscale / 16384.0;
11405 m2 = component->u.b.scale01 / 16384.0; 11373 m2 = component->u.b.scale01 / 16384.0;
11406 m3 = 0; 11374 m3 = 0;
11407 m4 = component->u.b.scale10 / 16384.0; 11375 m4 = component->u.b.scale10 / 16384.0;
11408 m5 = component->u.b.yscale / 16384.0; 11376 m5 = component->u.b.yscale / 16384.0;
11409 m6 = 0; 11377 m6 = 0;
11410 11378 }
11379 else /* No scale, just apply x_off and y_off. */
11380 {
11411 for (i = 0; i < num_coordinates; ++i) 11381 for (i = 0; i < num_coordinates; ++i)
11412 { 11382 x[i] += x_off, y[i] += y_off;
11413 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1; 11383
11414 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1; 11384 return;
11415 x[i] += x_off; 11385 }
11416 y[i] += y_off; 11386
11417 } 11387 m3 = x_off;
11388 m6 = y_off;
11389
11390 /* Apply the specified affine transformation.
11391 A transform looks like:
11392
11393 M1 M2 M3 X
11394 M4 M5 M6 * Y
11395
11396 =
11397
11398 M1*X + M2*Y + M3*1 = X1
11399 M4*X + M5*Y + M6*1 = Y1
11400
11401 (In most transforms, there is another row at the bottom for
11402 mathematical reasons. Since Z1 is always 1.0, the row is simply
11403 implied to be 0 0 1, because 0 * x + 0 * y + 1 * 1 = 1.0. See
11404 the definition of matrix3x3 in image.c for some more explanations
11405 about this.) */
11406
11407 for (i = 0; i < num_coordinates; ++i)
11408 {
11409 x[i] = m1 * x[i] + m2 * y[i] + m3 * 1;
11410 y[i] = m4 * x[i] + m5 * y[i] + m6 * 1;
11418 } 11411 }
11419} 11412}
11420 11413
@@ -11617,7 +11610,6 @@ sfnt_interpret_compound_glyph_2 (struct sfnt_glyph *glyph,
11617 11610
11618/* Internal helper for sfnt_interpret_compound_glyph. 11611/* Internal helper for sfnt_interpret_compound_glyph.
11619 RECURSION_COUNT is the number of times this function has called itself. 11612 RECURSION_COUNT is the number of times this function has called itself.
11620 OFF_X and OFF_Y are the offsets to apply to the glyph outline.
11621 11613
11622 METRICS are the unscaled metrics of this compound glyph. 11614 METRICS are the unscaled metrics of this compound glyph.
11623 11615
@@ -11636,7 +11628,6 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11636 struct sfnt_hhea_table *hhea, 11628 struct sfnt_hhea_table *hhea,
11637 struct sfnt_maxp_table *maxp, 11629 struct sfnt_maxp_table *maxp,
11638 struct sfnt_glyph_metrics *metrics, 11630 struct sfnt_glyph_metrics *metrics,
11639 sfnt_fixed off_x, sfnt_fixed off_y,
11640 int recursion_count, 11631 int recursion_count,
11641 void *dcontext) 11632 void *dcontext)
11642{ 11633{
@@ -11672,7 +11663,7 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11672 maximum valid value of `max_component_depth', which is 16. */ 11663 maximum valid value of `max_component_depth', which is 16. */
11673 11664
11674 if (recursion_count > 16) 11665 if (recursion_count > 16)
11675 return "Overly deep recursion in compound glyph data"; 11666 return "Excessive recursion in compound glyph data";
11676 11667
11677 /* Pacify -Wmaybe-uninitialized. */ 11668 /* Pacify -Wmaybe-uninitialized. */
11678 point = point2 = 0; 11669 point = point2 = 0;
@@ -11762,7 +11753,7 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11762 if (need_free) 11753 if (need_free)
11763 free_glyph (subglyph, dcontext); 11754 free_glyph (subglyph, dcontext);
11764 11755
11765 return "Invalid anchor point"; 11756 return "Invalid anchor reference point";
11766 } 11757 }
11767 11758
11768 if (!subglyph->compound) 11759 if (!subglyph->compound)
@@ -11772,14 +11763,25 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11772 if (need_free) 11763 if (need_free)
11773 free_glyph (subglyph, dcontext); 11764 free_glyph (subglyph, dcontext);
11774 11765
11775 return "Invalid anchored point"; 11766 return "Invalid component anchor point";
11776 } 11767 }
11777 11768
11778 /* Get the points and use them to compute the offsets. */ 11769 /* Get the points and use them to compute the offsets. */
11779 xtemp = context->x_coordinates[point]; 11770 xtemp = context->x_coordinates[point];
11780 ytemp = context->y_coordinates[point]; 11771 ytemp = context->y_coordinates[point];
11781 x = (xtemp - subglyph->simple->x_coordinates[point2] * 64); 11772
11782 y = (ytemp - subglyph->simple->y_coordinates[point2] * 64); 11773 /* Convert the unscaled coordinates within
11774 SIMPLE->x_coordinates to device space. */
11775 x = subglyph->simple->x_coordinates[point2];
11776 y = subglyph->simple->y_coordinates[point2];
11777 x = sfnt_mul_f26dot6_fixed (x * 64, interpreter->scale);
11778 y = sfnt_mul_f26dot6_fixed (y * 64, interpreter->scale);
11779
11780 /* Derive the X and Y offsets from the difference
11781 between the reference point's position and the anchor
11782 point's. */
11783 x = xtemp - x;
11784 y = ytemp - y;
11783 } 11785 }
11784 else 11786 else
11785 { 11787 {
@@ -11870,8 +11872,8 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11870 11872
11871 for (i = 0; i < last_point; ++i) 11873 for (i = 0; i < last_point; ++i)
11872 { 11874 {
11873 x_base[i] = value->x_points[i] + off_x + x; 11875 x_base[i] = value->x_points[i];
11874 y_base[i] = value->y_points[i] + off_y + y; 11876 y_base[i] = value->y_points[i];
11875 flags_base[i] = value->flags[i]; 11877 flags_base[i] = value->flags[i];
11876 } 11878 }
11877 11879
@@ -11884,7 +11886,7 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11884 11886
11885 /* Apply the transform to the points. */ 11887 /* Apply the transform to the points. */
11886 sfnt_transform_f26dot6 (component, x_base, y_base, 11888 sfnt_transform_f26dot6 (component, x_base, y_base,
11887 last_point, 0, 0); 11889 last_point, x, y);
11888 } 11890 }
11889 } 11891 }
11890 else 11892 else
@@ -11897,7 +11899,6 @@ sfnt_interpret_compound_glyph_1 (struct sfnt_glyph *glyph,
11897 context, get_glyph, 11899 context, get_glyph,
11898 free_glyph, hmtx, hhea, 11900 free_glyph, hmtx, hhea,
11899 maxp, &sub_metrics, 11901 maxp, &sub_metrics,
11900 off_x + x, off_y + y,
11901 recursion_count + 1, 11902 recursion_count + 1,
11902 dcontext); 11903 dcontext);
11903 11904
@@ -12028,8 +12029,7 @@ sfnt_interpret_compound_glyph (struct sfnt_glyph *glyph,
12028 state, &context, 12029 state, &context,
12029 get_glyph, free_glyph, 12030 get_glyph, free_glyph,
12030 hmtx, hhea, maxp, 12031 hmtx, hhea, maxp,
12031 metrics, 0, 0, 0, 12032 metrics, 0, dcontext);
12032 dcontext);
12033 12033
12034 /* If an error occurs, free the data in the context and return. */ 12034 /* If an error occurs, free the data in the context and return. */
12035 12035
diff --git a/src/sfnt.h b/src/sfnt.h
index 48d22aa8d29..6f93393c1d3 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -623,16 +623,16 @@ struct sfnt_compound_glyph_component
623 623
624 /* Various scale formats. */ 624 /* Various scale formats. */
625 union { 625 union {
626 uint16_t scale; 626 int16_t scale;
627 struct { 627 struct {
628 uint16_t xscale; 628 int16_t xscale;
629 uint16_t yscale; 629 int16_t yscale;
630 } a; 630 } a;
631 struct { 631 struct {
632 uint16_t xscale; 632 int16_t xscale;
633 uint16_t scale01; 633 int16_t scale01;
634 uint16_t scale10; 634 int16_t scale10;
635 uint16_t yscale; 635 int16_t yscale;
636 } b; 636 } b;
637 } u; 637 } u;
638}; 638};