< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-shape-plan.cc

Print this page

        

@@ -44,24 +44,29 @@
 
 static void
 hb_shape_plan_plan (hb_shape_plan_t    *shape_plan,
                     const hb_feature_t *user_features,
                     unsigned int        num_user_features,
+                    const int          *coords,
+                    unsigned int        num_coords,
                     const char * const *shaper_list)
 {
   DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
-                  "num_features=%d shaper_list=%p",
+                  "num_features=%d num_coords=%d shaper_list=%p",
                   num_user_features,
+                  num_coords,
                   shaper_list);
 
   const hb_shaper_pair_t *shapers = _hb_shapers_get ();
 
 #define HB_SHAPER_PLAN(shaper) \
         HB_STMT_START { \
           if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
             HB_SHAPER_DATA (shaper, shape_plan) = \
-              HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
+              HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \
+                                                               user_features, num_user_features, \
+                                                               coords, num_coords); \
             shape_plan->shaper_func = _hb_##shaper##_shape; \
             shape_plan->shaper_name = #shaper; \
             return; \
           } \
         } HB_STMT_END

@@ -113,26 +118,50 @@
                       const hb_segment_properties_t *props,
                       const hb_feature_t            *user_features,
                       unsigned int                   num_user_features,
                       const char * const            *shaper_list)
 {
+  return hb_shape_plan_create2 (face, props,
+                                user_features, num_user_features,
+                                NULL, 0,
+                                shaper_list);
+}
+
+hb_shape_plan_t *
+hb_shape_plan_create2 (hb_face_t                     *face,
+                       const hb_segment_properties_t *props,
+                       const hb_feature_t            *user_features,
+                       unsigned int                   num_user_features,
+                       const int                     *orig_coords,
+                       unsigned int                   num_coords,
+                       const char * const            *shaper_list)
+{
   DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
-                  "face=%p num_features=%d shaper_list=%p",
+                  "face=%p num_features=%d num_coords=%d shaper_list=%p",
                   face,
                   num_user_features,
+                  num_coords,
                   shaper_list);
 
   hb_shape_plan_t *shape_plan;
   hb_feature_t *features = NULL;
+  int *coords = NULL;
 
   if (unlikely (!face))
     face = hb_face_get_empty ();
   if (unlikely (!props))
     return hb_shape_plan_get_empty ();
   if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t))))
     return hb_shape_plan_get_empty ();
-  if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
+  if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int))))
+  {
+    free (features);
+    return hb_shape_plan_get_empty ();
+  }
+  if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
+  {
+    free (coords);
     free (features);
     return hb_shape_plan_get_empty ();
   }
 
   assert (props->direction != HB_DIRECTION_INVALID);

@@ -143,12 +172,19 @@
   shape_plan->props = *props;
   shape_plan->num_user_features = num_user_features;
   shape_plan->user_features = features;
   if (num_user_features)
     memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
-
-  hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
+  shape_plan->num_coords = num_coords;
+  shape_plan->coords = coords;
+  if (num_coords)
+    memcpy (coords, orig_coords, num_coords * sizeof (int));
+
+  hb_shape_plan_plan (shape_plan,
+                      user_features, num_user_features,
+                      coords, num_coords,
+                      shaper_list);
 
   return shape_plan;
 }
 
 /**

@@ -174,10 +210,13 @@
     NULL, /* shaper_name */
 
     NULL, /* user_features */
     0,    /* num_user_featurs */
 
+    NULL, /* coords */
+    0,    /* num_coords */
+
     {
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
     }

@@ -218,10 +257,11 @@
 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 
   free (shape_plan->user_features);
+  free (shape_plan->coords);
 
   free (shape_plan);
 }
 
 /**

@@ -287,13 +327,14 @@
                        hb_buffer_t        *buffer,
                        const hb_feature_t *features,
                        unsigned int        num_features)
 {
   DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan,
-                  "num_features=%d shaper_func=%p",
+                  "num_features=%d shaper_func=%p, shaper_name=%s",
                   num_features,
-                  shape_plan->shaper_func);
+                  shape_plan->shaper_func,
+                  shape_plan->shaper_name);
 
   if (unlikely (!buffer->len))
     return true;
 
   assert (!hb_object_is_inert (buffer));

@@ -348,32 +389,49 @@
 {
   const hb_segment_properties_t  props;
   const char * const            *shaper_list;
   const hb_feature_t            *user_features;
   unsigned int                   num_user_features;
+  const int                     *coords;
+  unsigned int                   num_coords;
   hb_shape_func_t               *shaper_func;
 };
 
 static inline hb_bool_t
 hb_shape_plan_user_features_match (const hb_shape_plan_t          *shape_plan,
                                    const hb_shape_plan_proposal_t *proposal)
 {
-  if (proposal->num_user_features != shape_plan->num_user_features) return false;
+  if (proposal->num_user_features != shape_plan->num_user_features)
+    return false;
   for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
     if (proposal->user_features[i].tag   != shape_plan->user_features[i].tag   ||
         proposal->user_features[i].value != shape_plan->user_features[i].value ||
         proposal->user_features[i].start != shape_plan->user_features[i].start ||
-        proposal->user_features[i].end   != shape_plan->user_features[i].end) return false;
+        proposal->user_features[i].end   != shape_plan->user_features[i].end)
+      return false;
+  return true;
+}
+
+static inline hb_bool_t
+hb_shape_plan_coords_match (const hb_shape_plan_t          *shape_plan,
+                            const hb_shape_plan_proposal_t *proposal)
+{
+  if (proposal->num_coords != shape_plan->num_coords)
+    return false;
+  for (unsigned int i = 0, n = proposal->num_coords; i < n; i++)
+    if (proposal->coords[i] != shape_plan->coords[i])
+      return false;
   return true;
 }
 
 static hb_bool_t
 hb_shape_plan_matches (const hb_shape_plan_t          *shape_plan,
                        const hb_shape_plan_proposal_t *proposal)
 {
   return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
          hb_shape_plan_user_features_match (shape_plan, proposal) &&
+         hb_shape_plan_coords_match (shape_plan, proposal) &&
          ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
           (shape_plan->shaper_func == proposal->shaper_func));
 }
 
 static inline hb_bool_t

@@ -386,10 +444,17 @@
     else
       num_user_features--, user_features++;
   return false;
 }
 
+static inline hb_bool_t
+hb_coords_present (const int *coords,
+                   unsigned int num_coords)
+{
+  return num_coords != 0;
+}
+
 /**
  * hb_shape_plan_create_cached:
  * @face:
  * @props:
  * @user_features: (array length=num_user_features):

@@ -407,10 +472,25 @@
                              const hb_segment_properties_t *props,
                              const hb_feature_t            *user_features,
                              unsigned int                   num_user_features,
                              const char * const            *shaper_list)
 {
+  return hb_shape_plan_create_cached2 (face, props,
+                                       user_features, num_user_features,
+                                       NULL, 0,
+                                       shaper_list);
+}
+
+hb_shape_plan_t *
+hb_shape_plan_create_cached2 (hb_face_t                     *face,
+                              const hb_segment_properties_t *props,
+                              const hb_feature_t            *user_features,
+                              unsigned int                   num_user_features,
+                              const int                     *coords,
+                              unsigned int                   num_coords,
+                              const char * const            *shaper_list)
+{
   DEBUG_MSG_FUNC (SHAPE_PLAN, NULL,
                   "face=%p num_features=%d shaper_list=%p",
                   face,
                   num_user_features,
                   shaper_list);

@@ -453,20 +533,25 @@
       return hb_shape_plan_reference (node->shape_plan);
     }
 
   /* Not found. */
 
-  hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+  hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props,
+                                                       user_features, num_user_features,
+                                                       coords, num_coords,
+                                                       shaper_list);
 
   /* Don't add to the cache if face is inert. */
   if (unlikely (hb_object_is_inert (face)))
     return shape_plan;
 
   /* Don't add the plan to the cache if there were user features with non-global ranges */
-
   if (hb_non_global_user_features_present (user_features, num_user_features))
     return shape_plan;
+  /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */
+  if (hb_coords_present (coords, num_coords))
+    return shape_plan;
 
   hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
   if (unlikely (!node))
     return shape_plan;
 
< prev index next >