[CoreText] Ensure cluster indices in output buffer are non-decreasing.
authorJonathan Kew <jfkthame@gmail.com>
Thu, 26 Jul 2012 19:58:45 +0000 (15:58 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 26 Jul 2012 19:58:45 +0000 (15:58 -0400)
Does not provide Uniscribe-compatible results, but should at least avoid
breaking hb-view due to out-of-order cluster values.

For RTL runs, ensure cluster values are non-increasing (instead of
non-decreasing).

src/hb-coretext.cc

index 65a1c73..c99ffc4 100644 (file)
@@ -319,5 +319,42 @@ _hb_coretext_shape (hb_font_t          *font,
     pos->y_offset = info->var2.u32;
   }
 
+  // Fix up clusters so that we never return out-of-order indices;
+  // if core text has reordered glyphs, we'll merge them to the
+  // beginning of the reordered cluster.
+  // This does *not* mean we'll form the same clusters as Uniscribe
+  // or the native OT backend, only that the cluster indices will be
+  // non-decreasing in the output buffer.
+  if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
+    unsigned int prev_cluster = 0;
+    for (unsigned int i = 0; i < count; i++) {
+      unsigned int curr_cluster = buffer->info[i].cluster;
+      if (curr_cluster < prev_cluster) {
+        for (unsigned int j = i; j > 0; j--) {
+          if (buffer->info[j - 1].cluster > curr_cluster)
+            buffer->info[j - 1].cluster = curr_cluster;
+          else
+            break;
+        }
+      }
+      prev_cluster = curr_cluster;
+    }
+  } else {
+    // For RTL runs, we make them non-increasing instead.
+    unsigned int prev_cluster = (unsigned int)-1;
+    for (unsigned int i = 0; i < count; i++) {
+      unsigned int curr_cluster = buffer->info[i].cluster;
+      if (curr_cluster > prev_cluster) {
+        for (unsigned int j = i; j > 0; j--) {
+          if (buffer->info[j - 1].cluster < curr_cluster)
+            buffer->info[j - 1].cluster = curr_cluster;
+          else
+            break;
+        }
+      }
+      prev_cluster = curr_cluster;
+    }
+  }
+
   return true;
 }