diff options
| author | Po Lu | 2023-03-30 11:18:51 +0800 |
|---|---|---|
| committer | Po Lu | 2023-03-30 11:18:51 +0800 |
| commit | 89a30637b32edea461746023717f77bd87bb4b10 (patch) | |
| tree | b8dcf974b90627070b20957d31a398c017845239 | |
| parent | 804b76ba8db20d65106394f08e807bdc93c2c55d (diff) | |
| download | emacs-89a30637b32edea461746023717f77bd87bb4b10.tar.gz emacs-89a30637b32edea461746023717f77bd87bb4b10.zip | |
Update Android port
* src/sfnt.c (sfnt_make_interpreter): New argument `fvar'. Set
axis count.
(SCANCTRL): Implement selector bit 8.
(GXAXIS): New instruction.
(SFVTPV): Validate graphics state after changing freedom vector.
(sfnt_line_to_vector): Implement `original'.
(sfnt_move): Remove redundant division.
(sfnt_interpret_run): Implement distortable font related GXAXIS
instruction (0x91).
(sfnt_vary_interpreter): Set naxis and norm_coords.
(sfnt_make_test_interpreter, pushb_test_args, pushw_test_args)
(sfnt_name_instruction, main): Adjust accordingly.
* src/sfnt.h (struct sfnt_interpreter, PROTOTYPE):
* src/sfntfont.c (sfntfont_setup_interpreter, sfntfont_open):
Set up distortion information.
| -rw-r--r-- | src/sfnt.c | 111 | ||||
| -rw-r--r-- | src/sfnt.h | 7 | ||||
| -rw-r--r-- | src/sfntfont.c | 6 |
3 files changed, 98 insertions, 26 deletions
diff --git a/src/sfnt.c b/src/sfnt.c index 4da0997751d..564f5d883bd 100644 --- a/src/sfnt.c +++ b/src/sfnt.c | |||
| @@ -5445,10 +5445,10 @@ sfnt_init_graphics_state (struct sfnt_graphics_state *state) | |||
| 5445 | } | 5445 | } |
| 5446 | 5446 | ||
| 5447 | /* Set up an interpreter to be used with a font. Use the resource | 5447 | /* Set up an interpreter to be used with a font. Use the resource |
| 5448 | limits specified in the MAXP table, the values specified in the CVT | 5448 | limits specified in the MAXP table, the values specified in the |
| 5449 | and HEAD tables, the pixel size PIXEL_SIZE, and the point size | 5449 | CVT, HEAD and FVAR tables, the pixel size PIXEL_SIZE, and the point |
| 5450 | POINT_SIZE. CVT may be NULL, in which case the interpreter will | 5450 | size POINT_SIZE. CVT may be NULL, in which case the interpreter |
| 5451 | not have access to a control value table. | 5451 | will not have access to a control value table. |
| 5452 | 5452 | ||
| 5453 | POINT_SIZE should be PIXEL_SIZE, converted to 1/72ths of an inch. | 5453 | POINT_SIZE should be PIXEL_SIZE, converted to 1/72ths of an inch. |
| 5454 | 5454 | ||
| @@ -5459,6 +5459,7 @@ TEST_STATIC struct sfnt_interpreter * | |||
| 5459 | sfnt_make_interpreter (struct sfnt_maxp_table *maxp, | 5459 | sfnt_make_interpreter (struct sfnt_maxp_table *maxp, |
| 5460 | struct sfnt_cvt_table *cvt, | 5460 | struct sfnt_cvt_table *cvt, |
| 5461 | struct sfnt_head_table *head, | 5461 | struct sfnt_head_table *head, |
| 5462 | struct sfnt_fvar_table *fvar, | ||
| 5462 | int pixel_size, int point_size) | 5463 | int pixel_size, int point_size) |
| 5463 | { | 5464 | { |
| 5464 | size_t size, temp, i, storage_size, pad; | 5465 | size_t size, temp, i, storage_size, pad; |
| @@ -5613,6 +5614,18 @@ sfnt_make_interpreter (struct sfnt_maxp_table *maxp, | |||
| 5613 | /* Fill in the current call depth. */ | 5614 | /* Fill in the current call depth. */ |
| 5614 | interpreter->call_depth = 0; | 5615 | interpreter->call_depth = 0; |
| 5615 | 5616 | ||
| 5617 | /* Clear variation axes. They will be set upon a call to | ||
| 5618 | `sfnt_vary_interpreter'. */ | ||
| 5619 | interpreter->n_axis = 0; | ||
| 5620 | interpreter->norm_coords = NULL; | ||
| 5621 | |||
| 5622 | /* Set n_axis now if a fvar table was provided. This way, GXAXIS | ||
| 5623 | pushes the correct number of values even if no blend is | ||
| 5624 | provided. */ | ||
| 5625 | |||
| 5626 | if (fvar) | ||
| 5627 | interpreter->n_axis = fvar->axis_count; | ||
| 5628 | |||
| 5616 | /* Return the interpreter. */ | 5629 | /* Return the interpreter. */ |
| 5617 | return interpreter; | 5630 | return interpreter; |
| 5618 | } | 5631 | } |
| @@ -6483,16 +6496,25 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6483 | interpreter->state.scan_control = value; \ | 6496 | interpreter->state.scan_control = value; \ |
| 6484 | } | 6497 | } |
| 6485 | 6498 | ||
| 6499 | /* Selector bit 8 is undocumented, but present in the Macintosh | ||
| 6500 | rasterizer. 02000 is returned if there is a variation axis in | ||
| 6501 | use. */ | ||
| 6502 | |||
| 6486 | #define GETINFO() \ | 6503 | #define GETINFO() \ |
| 6487 | { \ | 6504 | { \ |
| 6488 | uint32_t selector; \ | 6505 | uint32_t selector, k; \ |
| 6489 | \ | 6506 | \ |
| 6490 | selector = POP (); \ | 6507 | selector = POP (); \ |
| 6491 | \ | 6508 | \ |
| 6509 | k = 0; \ | ||
| 6510 | \ | ||
| 6492 | if (selector & 1) \ | 6511 | if (selector & 1) \ |
| 6493 | PUSH_UNCHECKED (2) \ | 6512 | k |= 02; \ |
| 6494 | else \ | 6513 | \ |
| 6495 | PUSH_UNCHECKED (0) \ | 6514 | if (selector & 8 && interpreter->n_axis) \ |
| 6515 | k |= 02000; \ | ||
| 6516 | \ | ||
| 6517 | PUSH_UNCHECKED (k); \ | ||
| 6496 | } | 6518 | } |
| 6497 | 6519 | ||
| 6498 | #define IDEF() \ | 6520 | #define IDEF() \ |
| @@ -6563,6 +6585,25 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6563 | |= (1 << s); \ | 6585 | |= (1 << s); \ |
| 6564 | } | 6586 | } |
| 6565 | 6587 | ||
| 6588 | /* GXAXIS is undocumented. It seems to return each axis in shortFrac | ||
| 6589 | format. */ | ||
| 6590 | |||
| 6591 | #define GXAXIS() \ | ||
| 6592 | { \ | ||
| 6593 | uint32_t v; \ | ||
| 6594 | int i; \ | ||
| 6595 | \ | ||
| 6596 | for (i = 0; i < interpreter->n_axis; ++i) \ | ||
| 6597 | { \ | ||
| 6598 | if (interpreter->norm_coords) \ | ||
| 6599 | v = interpreter->norm_coords[i] / 4; \ | ||
| 6600 | else \ | ||
| 6601 | v = 0; \ | ||
| 6602 | \ | ||
| 6603 | PUSH (v); \ | ||
| 6604 | } \ | ||
| 6605 | } | ||
| 6606 | |||
| 6566 | #define PUSHB() \ | 6607 | #define PUSHB() \ |
| 6567 | { \ | 6608 | { \ |
| 6568 | int b, nbytes, IP; \ | 6609 | int b, nbytes, IP; \ |
| @@ -6943,6 +6984,8 @@ sfnt_interpret_trap (struct sfnt_interpreter *interpreter, | |||
| 6943 | { \ | 6984 | { \ |
| 6944 | interpreter->state.freedom_vector \ | 6985 | interpreter->state.freedom_vector \ |
| 6945 | = interpreter->state.projection_vector; \ | 6986 | = interpreter->state.projection_vector; \ |
| 6987 | \ | ||
| 6988 | sfnt_validate_gs (&interpreter->state); \ | ||
| 6946 | } | 6989 | } |
| 6947 | 6990 | ||
| 6948 | #define ISECT() \ | 6991 | #define ISECT() \ |
| @@ -8231,6 +8274,16 @@ sfnt_line_to_vector (struct sfnt_interpreter *interpreter, | |||
| 8231 | sfnt_address_zp1 (interpreter, p1, &x1, &y1, &original_x1, | 8274 | sfnt_address_zp1 (interpreter, p1, &x1, &y1, &original_x1, |
| 8232 | &original_y1); | 8275 | &original_y1); |
| 8233 | 8276 | ||
| 8277 | /* Use original coordinates if specified. */ | ||
| 8278 | |||
| 8279 | if (original) | ||
| 8280 | { | ||
| 8281 | x2 = original_x2; | ||
| 8282 | y2 = original_y2; | ||
| 8283 | x1 = original_x1; | ||
| 8284 | y1 = original_y1; | ||
| 8285 | } | ||
| 8286 | |||
| 8234 | /* Calculate the vector between X2, Y2, and X1, Y1. */ | 8287 | /* Calculate the vector between X2, Y2, and X1, Y1. */ |
| 8235 | a = sfnt_sub (x1, x2); | 8288 | a = sfnt_sub (x1, x2); |
| 8236 | b = sfnt_sub (y1, y2); | 8289 | b = sfnt_sub (y1, y2); |
| @@ -9392,7 +9445,7 @@ sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y, | |||
| 9392 | size_t n, struct sfnt_interpreter *interpreter, | 9445 | size_t n, struct sfnt_interpreter *interpreter, |
| 9393 | sfnt_f26dot6 distance, unsigned char *flags) | 9446 | sfnt_f26dot6 distance, unsigned char *flags) |
| 9394 | { | 9447 | { |
| 9395 | sfnt_f26dot6 versor; | 9448 | sfnt_f26dot6 versor, k; |
| 9396 | sfnt_f2dot14 dot_product; | 9449 | sfnt_f2dot14 dot_product; |
| 9397 | size_t num; | 9450 | size_t num; |
| 9398 | 9451 | ||
| @@ -9412,12 +9465,13 @@ sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y, | |||
| 9412 | /* Move along X axis, converting the distance to the freedom | 9465 | /* Move along X axis, converting the distance to the freedom |
| 9413 | vector. */ | 9466 | vector. */ |
| 9414 | num = n; | 9467 | num = n; |
| 9468 | k = sfnt_multiply_divide_signed (distance, | ||
| 9469 | versor, | ||
| 9470 | dot_product); | ||
| 9415 | 9471 | ||
| 9416 | while (num--) | 9472 | while (num--) |
| 9417 | { | 9473 | { |
| 9418 | *x = sfnt_add (*x, sfnt_multiply_divide_signed (distance, | 9474 | *x = sfnt_add (*x, k); |
| 9419 | versor, | ||
| 9420 | dot_product)); | ||
| 9421 | x++; | 9475 | x++; |
| 9422 | 9476 | ||
| 9423 | if (flags) | 9477 | if (flags) |
| @@ -9432,12 +9486,13 @@ sfnt_move (sfnt_f26dot6 *restrict x, sfnt_f26dot6 *restrict y, | |||
| 9432 | /* Move along X axis, converting the distance to the freedom | 9486 | /* Move along X axis, converting the distance to the freedom |
| 9433 | vector. */ | 9487 | vector. */ |
| 9434 | num = n; | 9488 | num = n; |
| 9489 | k = sfnt_multiply_divide_signed (distance, | ||
| 9490 | versor, | ||
| 9491 | dot_product); | ||
| 9435 | 9492 | ||
| 9436 | while (num--) | 9493 | while (num--) |
| 9437 | { | 9494 | { |
| 9438 | *y = sfnt_add (*y, sfnt_multiply_divide_signed (distance, | 9495 | *y = sfnt_add (*y, k); |
| 9439 | versor, | ||
| 9440 | dot_product)); | ||
| 9441 | y++; | 9496 | y++; |
| 9442 | 9497 | ||
| 9443 | if (flags) | 9498 | if (flags) |
| @@ -10747,6 +10802,10 @@ sfnt_interpret_run (struct sfnt_interpreter *interpreter, | |||
| 10747 | NOT_IMPLEMENTED (); | 10802 | NOT_IMPLEMENTED (); |
| 10748 | break; | 10803 | break; |
| 10749 | 10804 | ||
| 10805 | case 0x91: /* GXAXIS */ | ||
| 10806 | GXAXIS (); | ||
| 10807 | break; | ||
| 10808 | |||
| 10750 | default: | 10809 | default: |
| 10751 | if (opcode >= 0xE0) /* MIRP */ | 10810 | if (opcode >= 0xE0) /* MIRP */ |
| 10752 | { | 10811 | { |
| @@ -14895,7 +14954,8 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id, | |||
| 14895 | } | 14954 | } |
| 14896 | 14955 | ||
| 14897 | /* Vary the specified INTERPRETER's control value table using the | 14956 | /* Vary the specified INTERPRETER's control value table using the |
| 14898 | variations in BLEND's CVT variations table. | 14957 | variations in BLEND's CVT variations table, then record the blend's |
| 14958 | normalized coordinates and axis count in the interpreter. | ||
| 14899 | 14959 | ||
| 14900 | The CVT table used to create INTERPRETER must be the same used | 14960 | The CVT table used to create INTERPRETER must be the same used |
| 14901 | to read BLEND->cvar. If not, behavior is undefined. */ | 14961 | to read BLEND->cvar. If not, behavior is undefined. */ |
| @@ -14953,6 +15013,9 @@ sfnt_vary_interpreter (struct sfnt_interpreter *interpreter, | |||
| 14953 | interpreter->cvt[i] += delta; | 15013 | interpreter->cvt[i] += delta; |
| 14954 | } | 15014 | } |
| 14955 | } | 15015 | } |
| 15016 | |||
| 15017 | interpreter->n_axis = blend->fvar->axis_count; | ||
| 15018 | interpreter->norm_coords = blend->norm_coords; | ||
| 14956 | } | 15019 | } |
| 14957 | 15020 | ||
| 14958 | 15021 | ||
| @@ -15443,7 +15506,7 @@ sfnt_make_test_interpreter (void) | |||
| 15443 | return sfnt_make_interpreter (&test_interpreter_profile, | 15506 | return sfnt_make_interpreter (&test_interpreter_profile, |
| 15444 | &test_interpreter_cvt, | 15507 | &test_interpreter_cvt, |
| 15445 | &test_interpreter_head, | 15508 | &test_interpreter_head, |
| 15446 | 17, 17); | 15509 | NULL, 17, 17); |
| 15447 | } | 15510 | } |
| 15448 | 15511 | ||
| 15449 | struct sfnt_interpreter_test | 15512 | struct sfnt_interpreter_test |
| @@ -15938,7 +16001,7 @@ static struct sfnt_generic_test_args npushw_test_args = | |||
| 15938 | static struct sfnt_generic_test_args pushb_test_args = | 16001 | static struct sfnt_generic_test_args pushb_test_args = |
| 15939 | { | 16002 | { |
| 15940 | (uint32_t []) { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, | 16003 | (uint32_t []) { 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, |
| 15941 | 1U, }, | 16004 | 1U, }, |
| 15942 | 9, | 16005 | 9, |
| 15943 | true, | 16006 | true, |
| 15944 | 11, | 16007 | 11, |
| @@ -15947,7 +16010,7 @@ static struct sfnt_generic_test_args pushb_test_args = | |||
| 15947 | static struct sfnt_generic_test_args pushw_test_args = | 16010 | static struct sfnt_generic_test_args pushw_test_args = |
| 15948 | { | 16011 | { |
| 15949 | (uint32_t []) { 0x203U, 0x204U, 0x205U, 0x206U, 0x207U, 0x208U, | 16012 | (uint32_t []) { 0x203U, 0x204U, 0x205U, 0x206U, 0x207U, 0x208U, |
| 15950 | 0x909U, 0x909U, (uint32_t) -1, }, | 16013 | 0x909U, 0x909U, (uint32_t) -1, }, |
| 15951 | 9, | 16014 | 9, |
| 15952 | true, | 16015 | true, |
| 15953 | 20, | 16016 | 20, |
| @@ -18347,7 +18410,7 @@ sfnt_name_instruction (unsigned char opcode) | |||
| 18347 | "7 INS_$8F", | 18410 | "7 INS_$8F", |
| 18348 | 18411 | ||
| 18349 | "7 INS_$90", | 18412 | "7 INS_$90", |
| 18350 | "7 INS_$91", | 18413 | "7 GXAXIS", |
| 18351 | "7 INS_$92", | 18414 | "7 INS_$92", |
| 18352 | "7 INS_$93", | 18415 | "7 INS_$93", |
| 18353 | "7 INS_$94", | 18416 | "7 INS_$94", |
| @@ -18924,8 +18987,8 @@ main (int argc, char **argv) | |||
| 18924 | return 1; | 18987 | return 1; |
| 18925 | } | 18988 | } |
| 18926 | 18989 | ||
| 18927 | #define FANCY_PPEM 36 | 18990 | #define FANCY_PPEM 19 |
| 18928 | #define EASY_PPEM 36 | 18991 | #define EASY_PPEM 19 |
| 18929 | 18992 | ||
| 18930 | interpreter = NULL; | 18993 | interpreter = NULL; |
| 18931 | head = sfnt_read_head_table (fd, font); | 18994 | head = sfnt_read_head_table (fd, font); |
| @@ -19085,7 +19148,7 @@ main (int argc, char **argv) | |||
| 19085 | loca_short->num_offsets); | 19148 | loca_short->num_offsets); |
| 19086 | } | 19149 | } |
| 19087 | 19150 | ||
| 19088 | interpreter = sfnt_make_interpreter (maxp, cvt, head, | 19151 | interpreter = sfnt_make_interpreter (maxp, cvt, head, fvar, |
| 19089 | FANCY_PPEM, FANCY_PPEM); | 19152 | FANCY_PPEM, FANCY_PPEM); |
| 19090 | if (instance && gvar) | 19153 | if (instance && gvar) |
| 19091 | sfnt_vary_interpreter (interpreter, &blend); | 19154 | sfnt_vary_interpreter (interpreter, &blend); |
| @@ -19296,7 +19359,7 @@ main (int argc, char **argv) | |||
| 19296 | cvt ? cvt->num_elements : 0ul); | 19359 | cvt ? cvt->num_elements : 0ul); |
| 19297 | 19360 | ||
| 19298 | interpreter = sfnt_make_interpreter (maxp, cvt, head, | 19361 | interpreter = sfnt_make_interpreter (maxp, cvt, head, |
| 19299 | FANCY_PPEM, | 19362 | fvar, FANCY_PPEM, |
| 19300 | FANCY_PPEM); | 19363 | FANCY_PPEM); |
| 19301 | state = interpreter->state; | 19364 | state = interpreter->state; |
| 19302 | 19365 | ||
diff --git a/src/sfnt.h b/src/sfnt.h index 30c82ad3795..58a6de060f4 100644 --- a/src/sfnt.h +++ b/src/sfnt.h | |||
| @@ -1860,6 +1860,12 @@ struct sfnt_interpreter | |||
| 1860 | /* What was the trap. */ | 1860 | /* What was the trap. */ |
| 1861 | const char *trap_reason; | 1861 | const char *trap_reason; |
| 1862 | 1862 | ||
| 1863 | /* Number of variation axes provided by this distortable font. */ | ||
| 1864 | int n_axis; | ||
| 1865 | |||
| 1866 | /* Normalized axis coordinates set for this distortable font. */ | ||
| 1867 | sfnt_fixed *norm_coords; | ||
| 1868 | |||
| 1863 | #ifdef TEST | 1869 | #ifdef TEST |
| 1864 | /* If non-NULL, function called before each instruction is | 1870 | /* If non-NULL, function called before each instruction is |
| 1865 | executed. */ | 1871 | executed. */ |
| @@ -1918,6 +1924,7 @@ extern struct sfnt_prep_table *sfnt_read_prep_table (PROTOTYPE); | |||
| 1918 | #define PROTOTYPE \ | 1924 | #define PROTOTYPE \ |
| 1919 | struct sfnt_maxp_table *, \ | 1925 | struct sfnt_maxp_table *, \ |
| 1920 | struct sfnt_cvt_table *, \ | 1926 | struct sfnt_cvt_table *, \ |
| 1927 | struct sfnt_fvar_table *, \ | ||
| 1921 | struct sfnt_head_table *, \ | 1928 | struct sfnt_head_table *, \ |
| 1922 | int, int | 1929 | int, int |
| 1923 | 1930 | ||
diff --git a/src/sfntfont.c b/src/sfntfont.c index c9d48f640af..960abe0d270 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c | |||
| @@ -2532,7 +2532,7 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info) | |||
| 2532 | 2532 | ||
| 2533 | /* Initialize the instruction interpreter for INFO. Load the font and | 2533 | /* Initialize the instruction interpreter for INFO. Load the font and |
| 2534 | preprogram for the pixel size in INFO and its corresponding point | 2534 | preprogram for the pixel size in INFO and its corresponding point |
| 2535 | size POINT_SIZE. | 2535 | size POINT_SIZE. Use the FVAR table in DESC. |
| 2536 | 2536 | ||
| 2537 | The font tables in INFO must already have been initialized. | 2537 | The font tables in INFO must already have been initialized. |
| 2538 | 2538 | ||
| @@ -2541,6 +2541,7 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info) | |||
| 2541 | 2541 | ||
| 2542 | static void | 2542 | static void |
| 2543 | sfntfont_setup_interpreter (struct sfnt_font_info *info, | 2543 | sfntfont_setup_interpreter (struct sfnt_font_info *info, |
| 2544 | struct sfnt_font_desc *desc, | ||
| 2544 | int point_size) | 2545 | int point_size) |
| 2545 | { | 2546 | { |
| 2546 | struct sfnt_cvt_table *cvt; | 2547 | struct sfnt_cvt_table *cvt; |
| @@ -2575,6 +2576,7 @@ sfntfont_setup_interpreter (struct sfnt_font_info *info, | |||
| 2575 | info->head. CVT can be NULL. */ | 2576 | info->head. CVT can be NULL. */ |
| 2576 | 2577 | ||
| 2577 | interpreter = sfnt_make_interpreter (info->maxp, cvt, info->head, | 2578 | interpreter = sfnt_make_interpreter (info->maxp, cvt, info->head, |
| 2579 | desc->tables->fvar, | ||
| 2578 | info->font.pixel_size, | 2580 | info->font.pixel_size, |
| 2579 | point_size); | 2581 | point_size); |
| 2580 | 2582 | ||
| @@ -3110,7 +3112,7 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, | |||
| 3110 | point_size = PIXEL_TO_POINT (pixel_size, (dpyinfo->resx | 3112 | point_size = PIXEL_TO_POINT (pixel_size, (dpyinfo->resx |
| 3111 | * dpyinfo->resy | 3113 | * dpyinfo->resy |
| 3112 | / 2)); | 3114 | / 2)); |
| 3113 | sfntfont_setup_interpreter (font_info, point_size); | 3115 | sfntfont_setup_interpreter (font_info, desc, point_size); |
| 3114 | 3116 | ||
| 3115 | /* If an instance was specified and the font is distortable, set up | 3117 | /* If an instance was specified and the font is distortable, set up |
| 3116 | the blend. */ | 3118 | the blend. */ |