emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 05f3f9c1c09 1/2: Update Android port


From: Po Lu
Subject: feature/android 05f3f9c1c09 1/2: Update Android port
Date: Mon, 27 Mar 2023 21:42:15 -0400 (EDT)

branch: feature/android
commit 05f3f9c1c09c3e7a4d9c1d9ac16a34742a4124c1
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 src/androidterm.c |   1 +
 src/sfnt.c        | 151 ++++++++++++++++++++++++++++++++++++------------------
 src/sfntfont.c    |  74 ++++++++++++++++----------
 3 files changed, 147 insertions(+), 79 deletions(-)

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]