]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/layout/OpenTypeUtilities.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / layout / OpenTypeUtilities.cpp
index 8a3cd2c1f1c644981e419561bcdaa29a35f77bcd..d77c63e0dfe724f2edba8ee4d25e0cb323c725d8 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * @(#)OpenTypeUtilities.cpp   1.6 00/03/15
  *
- * (C) Copyright IBM Corp. 1998-2003 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -52,54 +51,75 @@ le_int8 OpenTypeUtilities::highBit(le_int32 value)
     return bit;
 }
 
-Offset OpenTypeUtilities::getTagOffset(LETag tag, const TagAndOffsetRecord *records, le_int32 recordCount)
-{
-    le_uint8 bit = highBit(recordCount);
-    le_int32 power = 1 << bit;
-    le_int32 extra = recordCount - power;
-    le_int32 probe = power;
-    le_int32 index = 0;
-
-    if (SWAPT(records[extra].tag) <= tag) {
-        index = extra;
-    }
 
-    while (probe > (1 << 0)) {
-        probe >>= 1;
-
-        if (SWAPT(records[index + probe].tag) <= tag) {
-            index += probe;
-        }
-    }
-
-    if (SWAPT(records[index].tag) == tag) {
-        return SWAPW(records[index].offset);
-    }
-
-    return 0;
+Offset OpenTypeUtilities::getTagOffset(LETag tag, const LEReferenceToArrayOf<TagAndOffsetRecord> &records, LEErrorCode &success)
+{
+  const TagAndOffsetRecord *r0 = (const TagAndOffsetRecord*)records.getAlias();
+  if(LE_FAILURE(success)) return 0;
+
+  le_uint32 recordCount = records.getCount();
+  le_uint8 bit = highBit(recordCount);
+  le_int32 power = 1 << bit;
+  le_int32 extra = recordCount - power;
+  le_int32 probe = power;
+  le_int32 index = 0;
+  
+  { 
+    const ATag &aTag = (r0+extra)->tag;
+    if (SWAPT(aTag) <= tag) {
+      index = extra;
+    }
+  }
+  
+  while (probe > (1 << 0)) {
+    probe >>= 1;
+    
+    {
+      const ATag &aTag = (r0+index+probe)->tag;
+      if (SWAPT(aTag) <= tag) {
+        index += probe;
+      }
+    }
+  }
+  
+  {
+    const ATag &aTag = (r0+index)->tag;
+    if (SWAPT(aTag) == tag) {
+      return SWAPW((r0+index)->offset);
+    }
+  }
+
+  return 0;
 }
 
-le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const GlyphRangeRecord *records, le_int32 recordCount)
+le_int32 OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID, const LEReferenceToArrayOf<GlyphRangeRecord> &records, LEErrorCode &success)
 {
+  if(LE_FAILURE(success)) return -1;
+
+    le_uint32 recordCount = records.getCount();
     le_uint8 bit = highBit(recordCount);
     le_int32 power = 1 << bit;
     le_int32 extra = recordCount - power;
     le_int32 probe = power;
     le_int32 range = 0;
 
-    if (SWAPW(records[extra].firstGlyph) <= glyphID) {
+    if (recordCount == 0) {
+      return -1;
+    }
+
+    if (SWAPW(records(extra,success).firstGlyph) <= glyphID) {
         range = extra;
     }
 
-    while (probe > (1 << 0)) {
+    while (probe > (1 << 0) && LE_SUCCESS(success)) {
         probe >>= 1;
 
-        if (SWAPW(records[range + probe].firstGlyph) <= glyphID) {
+        if (SWAPW(records(range + probe,success).firstGlyph) <= glyphID) {
             range += probe;
         }
     }
 
-    if (SWAPW(records[range].firstGlyph) <= glyphID && SWAPW(records[range].lastGlyph) >= glyphID) {
+    if (SWAPW(records(range,success).firstGlyph) <= glyphID && SWAPW(records(range,success).lastGlyph) >= glyphID) {
         return range;
     }
 
@@ -171,6 +191,38 @@ void OpenTypeUtilities::sort(le_uint16 *array, le_int32 count)
     }
 }
 
-
 U_NAMESPACE_END
+
+#if LE_ASSERT_BAD_FONT
+#include <stdio.h>
+
+static const char *letagToStr(LETag tag, char *str) {
+  str[0]= 0xFF & (tag>>24);
+  str[1]= 0xFF & (tag>>16);
+  str[2]= 0xFF & (tag>>8);
+  str[3]= 0xFF & (tag>>0);
+  str[4]= 0;
+  return str;
+}
+
+U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len) {
+  char tagbuf[5];
+  
+  fprintf(stderr, "%s:%d: LETableReference@0x%p: ", f, l, what);
+  fprintf(stderr, msg, ptr, len);
+  fprintf(stderr, "\n");
+
+  for(int depth=0;depth<10&&(what!=NULL);depth++) {
+    for(int i=0;i<depth;i++) {
+      fprintf(stderr, " "); // indent
+    }
+    if(!what->isValid()) {
+      fprintf(stderr, "(invalid)");
+    }
+    fprintf(stderr, "@%p: tag (%s) font (0x%p), [0x%p+0x%lx]\n", what, letagToStr(what->getTag(), tagbuf), what->getFont(),
+            what->getAlias(), what->getLength());
+
+    what = what->getParent();
+  }
+}
+#endif