From: Po Lu Date: Tue, 28 Mar 2023 01:41:01 +0000 (+0800) Subject: Update Android port X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=05f3f9c1c09c3e7a4d9c1d9ac16a34742a4124c1;p=emacs.git Update Android port * src/androidterm.c (android_draw_image_glyph_string): Restore potentially clobbered GC clipping. * src/sfnt.c (sfnt_large_integer_add, sfnt_multiply_divide_round) (sfnt_mul_fixed_round): New functions. (sfnt_build_glyph_outline): Take unscaled glyph metrics. (sfnt_prepare_raster, sfnt_vary_simple_glyph) (sfnt_vary_compound_glyph, sfnt_vary_interpreter): Use rounding multiplication to scale deltas. (main): Adjust tests. * src/sfntfont.c (sfntfont_get_glyph_outline) (sfntfont_probe_widths, sfntfont_open, sfntfont_measure_pcm) (sfntfont_draw): More minor fixes to variable fonts. --- diff --git a/src/androidterm.c b/src/androidterm.c index 1bc11e600f7..8ba7fb6a798 100644 --- a/src/androidterm.c +++ b/src/androidterm.c @@ -3327,6 +3327,7 @@ android_draw_image_glyph_string (struct glyph_string *s) /* Draw the foreground. */ android_draw_image_foreground (s); + android_set_glyph_string_clipping (s); /* If we must draw a relief around the image, do it. */ if (s->img->relief diff --git a/src/sfnt.c b/src/sfnt.c index f6730857f86..2762f3df457 100644 --- a/src/sfnt.c +++ b/src/sfnt.c @@ -3539,6 +3539,40 @@ sfnt_multiply_divide (unsigned int a, unsigned int b, unsigned int c) #endif } +#ifndef INT64_MAX + +/* Add the specified unsigned 32-bit N to the large integer + INTEGER. */ + +static void +sfnt_large_integer_add (struct sfnt_large_integer *integer, + uint32_t n) +{ + struct sfnt_large_integer number; + + number.low = integer->low + n; + number.high = integer->high + (number.low + < integer->low); + + *integer = number; +} + +/* Calculate (A * B) / C, rounding the result with a threshold of N. + Use a 64 bit temporary. */ + +static unsigned int +sfnt_multiply_divide_round (unsigned int a, unsigned int b, + unsigned int n, unsigned int c) +{ + struct sfnt_large_integer temp; + + sfnt_multiply_divide_1 (a, b, &temp); + sfnt_large_integer_add (&temp, n); + return sfnt_multiply_divide_2 (&temp, c); +} + +#endif /* INT64_MAX */ + /* The same as sfnt_multiply_divide, but handle signed values instead. */ @@ -3591,6 +3625,36 @@ sfnt_mul_fixed (sfnt_fixed x, sfnt_fixed y) #endif } +/* Multiply the two 16.16 fixed point numbers X and Y, with rounding + of the result. */ + +static sfnt_fixed +sfnt_mul_fixed_round (sfnt_fixed x, sfnt_fixed y) +{ +#ifdef INT64_MAX + int64_t product, round; + + product = (int64_t) x * (int64_t) y; + round = product < 0 ? -32768 : 32768; + + /* This can be done quickly with int64_t. */ + return (product + round) / (int64_t) 65536; +#else + int sign; + + sign = 1; + + if (x < 0) + sign = -sign; + + if (y < 0) + sign = -sign; + + return sfnt_multiply_divide_round (abs (x), abs (y), + 32768, 65536) * sign; +#endif +} + /* Set the pen size to the specified point and return. POINT will be scaled up to the pixel size. */ @@ -3766,7 +3830,7 @@ sfnt_curve_to_and_build (struct sfnt_point control, SCALE is a scale factor that converts between em space and device space. - Use the scaled glyph METRICS to determine the origin point of the + Use the unscaled glyph METRICS to determine the origin point of the outline. Call GET_GLYPH and FREE_GLYPH with the specified DCONTEXT to obtain @@ -3824,11 +3888,12 @@ sfnt_build_glyph_outline (struct sfnt_glyph *glyph, return NULL; } - /* Compute the origin position. */ - origin = outline->xmin - metrics->lbearing; - outline->origin - = (origin + sfnt_mul_fixed (glyph->origin_distortion, - build_outline_context.factor)); + /* Compute the origin position. Note that the original glyph xmin + is first used to calculate the origin point, and the origin + distortion is applied to it to get the distorted origin. */ + + origin = glyph->xmin - metrics->lbearing + glyph->origin_distortion; + outline->origin = sfnt_mul_fixed (origin, scale); return outline; } @@ -3881,10 +3946,10 @@ sfnt_prepare_raster (struct sfnt_raster *raster, { raster->width = (sfnt_ceil_fixed (outline->xmax) - - sfnt_floor_fixed (outline->xmin)) >> 16; + - sfnt_floor_fixed (outline->xmin)) / 65536; raster->height = (sfnt_ceil_fixed (outline->ymax) - - sfnt_floor_fixed (outline->ymin)) >> 16; + - sfnt_floor_fixed (outline->ymin)) / 65536; raster->refcount = 0; /* Align the raster to a SFNT_POLY_ALIGNMENT byte boundary. */ @@ -3896,8 +3961,8 @@ sfnt_prepare_raster (struct sfnt_raster *raster, However, variable fonts typically change this as variations are applied. */ raster->offx = sfnt_floor_fixed (outline->xmin - - outline->origin) >> 16; - raster->offy = sfnt_floor_fixed (outline->ymin) >> 16; + - outline->origin) / 65536; + raster->offy = sfnt_floor_fixed (outline->ymin) / 65536; } typedef void (*sfnt_edge_proc) (struct sfnt_edge *, size_t, @@ -5206,7 +5271,7 @@ sfnt_div_f26dot6 (sfnt_f26dot6 x, sfnt_f26dot6 y) #endif } -/* Multiply-round the specified two 26.6 fixed point numbers A and B. +/* Multiply the specified two 26.6 fixed point numbers A and B. Return the result, or an undefined value upon overflow. */ static sfnt_f26dot6 @@ -5263,26 +5328,6 @@ sfnt_mul_f2dot14 (sfnt_f2dot14 a, int32_t b) #endif } -#ifndef INT64_MAX - -/* Add the specified unsigned 32-bit N to the large integer - INTEGER. */ - -static void -sfnt_large_integer_add (struct sfnt_large_integer *integer, - uint32_t n) -{ - struct sfnt_large_integer number; - - number.low = integer->low + n; - number.high = integer->high + (number.low - < integer->low); - - *integer = number; -} - -#endif - /* Multiply the specified 26.6 fixed point number X by the specified 16.16 fixed point number Y with symmetric rounding. @@ -14343,15 +14388,15 @@ sfnt_vary_simple_glyph (struct sfnt_blend *blend, sfnt_glyph id, for (i = 0; i < glyph->simple->number_of_points; ++i) { - fword = sfnt_mul_fixed (dx[i], scale); + fword = sfnt_mul_fixed_round (dx[i], scale); glyph->simple->x_coordinates[i] += fword; - fword = sfnt_mul_fixed (dy[i], scale); + fword = sfnt_mul_fixed_round (dy[i], scale); glyph->simple->y_coordinates[i] += fword; } /* Apply the deltas for the two phantom points. */ - distortion->origin += sfnt_mul_fixed (dx[i++], scale); - distortion->advance += sfnt_mul_fixed (dx[i], scale); + distortion->origin += sfnt_mul_fixed_round (dx[i++], scale); + distortion->advance += sfnt_mul_fixed_round (dx[i], scale); break; default: @@ -14399,13 +14444,13 @@ sfnt_vary_simple_glyph (struct sfnt_blend *blend, sfnt_glyph id, if (glyph_points[i] == glyph->simple->number_of_points) { - distortion->origin += sfnt_mul_fixed (dx[i], scale); + distortion->origin += sfnt_mul_fixed_round (dx[i], scale); continue; } if (glyph_points[i] == glyph->simple->number_of_points + 1) { - distortion->advance += sfnt_mul_fixed (dx[i], scale); + distortion->advance += sfnt_mul_fixed_round (dx[i], scale); continue; } @@ -14413,9 +14458,9 @@ sfnt_vary_simple_glyph (struct sfnt_blend *blend, sfnt_glyph id, if (glyph_points[i] >= glyph->simple->number_of_points) continue; - fword = sfnt_mul_fixed (dx[i], scale); + fword = sfnt_mul_fixed_round (dx[i], scale); glyph->simple->x_coordinates[glyph_points[i]] += fword; - fword = sfnt_mul_fixed (dy[i], scale); + fword = sfnt_mul_fixed_round (dy[i], scale); glyph->simple->y_coordinates[glyph_points[i]] += fword; touched[glyph_points[i]] = true; } @@ -14729,7 +14774,7 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id, else word = component->argument1.d; - fword = sfnt_mul_fixed (dx[i], scale); + fword = sfnt_mul_fixed_round (dx[i], scale); component->flags |= 01; component->argument1.d = word + fword; @@ -14740,14 +14785,14 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id, else word = component->argument2.d; - fword = sfnt_mul_fixed (dy[i], scale); + fword = sfnt_mul_fixed_round (dy[i], scale); component->flags |= 01; component->argument2.d = word + fword; } /* Apply the deltas for the two phantom points. */ - distortion->origin += sfnt_mul_fixed (dx[i++], scale); - distortion->advance += sfnt_mul_fixed (dx[i], scale); + distortion->origin += sfnt_mul_fixed_round (dx[i++], scale); + distortion->advance += sfnt_mul_fixed_round (dx[i], scale); break; default: @@ -14795,13 +14840,13 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id, if (glyph_points[i] == glyph->compound->num_components) { - distortion->origin += sfnt_mul_fixed (dx[i], scale); + distortion->origin += sfnt_mul_fixed_round (dx[i], scale); continue; } if (glyph_points[i] == glyph->compound->num_components + 1) { - distortion->advance += sfnt_mul_fixed (dx[i], scale); + distortion->advance += sfnt_mul_fixed_round (dx[i], scale); continue; } @@ -14822,7 +14867,7 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id, else word = component->argument1.d; - fword = sfnt_mul_fixed (dx[i], scale); + fword = sfnt_mul_fixed_round (dx[i], scale); component->flags |= 01; component->argument1.d = word + fword; @@ -14833,7 +14878,7 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, sfnt_glyph id, else word = component->argument2.d; - fword = sfnt_mul_fixed (dy[i], scale); + fword = sfnt_mul_fixed_round (dy[i], scale); component->flags |= 01; component->argument2.d = word + fword; } @@ -14946,7 +14991,7 @@ sfnt_vary_interpreter (struct sfnt_interpreter *interpreter, then the tuple scale factor. */ delta = sfnt_mul_f26dot6_fixed (variation->deltas[j] * 64, interpreter->scale); - delta = sfnt_mul_fixed (delta, scale); + delta = sfnt_mul_fixed_round (delta, scale); /* Apply the delta to the control value table. */ interpreter->cvt[i] += delta; @@ -18923,8 +18968,8 @@ main (int argc, char **argv) return 1; } -#define FANCY_PPEM 40 -#define EASY_PPEM 40 +#define FANCY_PPEM 36 +#define EASY_PPEM 36 interpreter = NULL; head = sfnt_read_head_table (fd, font); @@ -19401,7 +19446,7 @@ main (int argc, char **argv) &dcontext)) printf ("decomposition failure\n"); - if (sfnt_lookup_glyph_metrics (code, EASY_PPEM, + if (sfnt_lookup_glyph_metrics (code, -1, &metrics, hmtx, hhea, head, maxp)) @@ -19424,6 +19469,10 @@ main (int argc, char **argv) if (outline) { + fprintf (stderr, "outline origin, rbearing: %" + PRIi32" %"PRIi32"\n", + outline->origin, + outline->ymax - outline->origin); sfnt_test_max = outline->ymax - outline->ymin; for (i = 0; i < outline->outline_used; i++) diff --git a/src/sfntfont.c b/src/sfntfont.c index 808c8b7c629..ee049b5c159 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c @@ -2081,11 +2081,6 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, } } - /* At this point, the glyph metrics are unscaled. Scale them up. - If INTERPRETER is set, use the scale placed within. */ - - sfnt_scale_metrics (&temp, scale); - if (!outline) { if (!interpreter) @@ -2102,6 +2097,11 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code, &dcontext); } + /* At this point, the glyph metrics are unscaled. Scale them up. + If INTERPRETER is set, use the scale placed within. */ + + sfnt_scale_metrics (&temp, scale); + fail: xfree (glyph); @@ -2460,18 +2460,18 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info) num_characters++; /* Add the advance to total_width. */ - total_width += metrics.advance >> 16; + total_width += metrics.advance / 65536; /* Update min_width if it hasn't been set yet or is wider. */ if (font_info->font.min_width == 1 - || font_info->font.min_width > metrics.advance >> 16) - font_info->font.min_width = metrics.advance >> 16; + || font_info->font.min_width > metrics.advance / 65536) + font_info->font.min_width = metrics.advance / 65536; /* If i is the space character, set the space width. Make sure to round this up. */ if (i == 32) font_info->font.space_width - = SFNT_CEIL_FIXED (metrics.advance) >> 16; + = SFNT_CEIL_FIXED (metrics.advance) / 65536; } /* Now, if characters were found, set average_width. */ @@ -3023,6 +3023,8 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, ASET (font_object, FONT_SPACING_INDEX, make_fixnum (desc->spacing)); + /* Set the font style. */ + FONT_SET_STYLE (font_object, FONT_WIDTH_INDEX, make_fixnum (desc->width)); FONT_SET_STYLE (font_object, FONT_WEIGHT_INDEX, @@ -3061,24 +3063,40 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity, /* Make sure the instance is within range. */ && instance < desc->tables->fvar->instance_count) { - sfnt_init_blend (&font_info->blend, desc->tables->fvar, - desc->tables->gvar, desc->tables->avar, - desc->tables->cvar); + tem = AREF (desc->instances, instance); + + if (!NILP (tem)) + { + sfnt_init_blend (&font_info->blend, desc->tables->fvar, + desc->tables->gvar, desc->tables->avar, + desc->tables->cvar); + + /* Copy over the coordinates. */ + for (i = 0; i < desc->tables->fvar->axis_count; ++i) + font_info->blend.coords[i] + = desc->tables->fvar->instance[instance].coords[i]; - /* Copy over the coordinates. */ - for (i = 0; i < desc->tables->fvar->axis_count; ++i) - font_info->blend.coords[i] - = desc->tables->fvar->instance[instance].coords[i]; + sfnt_normalize_blend (&font_info->blend); - sfnt_normalize_blend (&font_info->blend); + /* If an interpreter was specified, distort it now. */ - /* If an interpreter was specified, distort it now. */ + if (font_info->interpreter) + sfnt_vary_interpreter (font_info->interpreter, + &font_info->blend); - if (font_info->interpreter) - sfnt_vary_interpreter (font_info->interpreter, - &font_info->blend); + font_info->instance = instance; - font_info->instance = instance; + /* Replace the style information with that of the + instance. */ + + FONT_SET_STYLE (font_object, FONT_WIDTH_INDEX, + AREF (tem, 2)); + FONT_SET_STYLE (font_object, FONT_WEIGHT_INDEX, + AREF (tem, 3)); + FONT_SET_STYLE (font_object, FONT_SLANT_INDEX, + AREF (tem, 4)); + ASET (font_object, FONT_ADSTYLE_INDEX, Qnil); + } } #ifdef HAVE_HARFBUZZ @@ -3165,13 +3183,13 @@ sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph, if (!outline) return 1; - pcm->lbearing = metrics.lbearing >> 16; - pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) >> 16; + pcm->lbearing = metrics.lbearing / 65536; + pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) / 65536; /* Round the advance, ascent and descent upwards. */ - pcm->width = SFNT_CEIL_FIXED (metrics.advance) >> 16; - pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) >> 16; - pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) >> 16; + pcm->width = SFNT_CEIL_FIXED (metrics.advance) / 65536; + pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) / 65536; + pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) / 65536; sfntfont_dereference_outline (outline); return 0; @@ -3373,7 +3391,7 @@ sfntfont_draw (struct glyph_string *s, int from, int to, if (s->padding_p) current_x += 1; else - current_x += SFNT_CEIL_FIXED (metrics.advance) >> 16; + current_x += SFNT_CEIL_FIXED (metrics.advance) / 65536; } /* Call the window system function to put the glyphs to the