Home | History | Annotate | Download | only in layout
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
      4  *
      5  */
      6 
      7 #include "LETypes.h"
      8 #include "LayoutTables.h"
      9 #include "LookupTables.h"
     10 #include "LESwaps.h"
     11 
     12 U_NAMESPACE_BEGIN
     13 
     14 /*
     15     These are the rolled-up versions of the uniform binary search.
     16     Someday, if we need more performance, we can un-roll them.
     17 
     18     Note: I put these in the base class, so they only have to
     19     be written once. Since the base class doesn't define the
     20     segment table, these routines assume that it's right after
     21     the binary search header.
     22 
     23     Another way to do this is to put each of these routines in one
     24     of the derived classes, and implement it in the others by casting
     25     the "this" pointer to the type that has the implementation.
     26 */
     27 const LookupSegment *BinarySearchLookupTable::lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const
     28 {
     29 
     30     le_int16  unity = SWAPW(unitSize);
     31     le_int16  probe = SWAPW(searchRange);
     32     le_int16  extra = SWAPW(rangeShift);
     33     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
     34     LEReferenceTo<LookupSegment> entry(base, success, segments);
     35     LEReferenceTo<LookupSegment> trial(entry, success, extra);
     36 
     37     if(LE_FAILURE(success)) return NULL;
     38 
     39     if (SWAPW(trial->lastGlyph) <= ttGlyph) {
     40         entry = trial;
     41     }
     42 
     43     while (probe > unity && LE_SUCCESS(success)) {
     44         probe >>= 1;
     45         trial = entry; // copy
     46         trial.addOffset(probe, success);
     47 
     48         if (SWAPW(trial->lastGlyph) <= ttGlyph) {
     49             entry = trial;
     50         }
     51     }
     52 
     53     if (SWAPW(entry->firstGlyph) <= ttGlyph) {
     54       return entry.getAlias();
     55     }
     56 
     57     return NULL;
     58 }
     59 
     60 const LookupSingle *BinarySearchLookupTable::lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const
     61 {
     62     le_int16  unity = SWAPW(unitSize);
     63     le_int16  probe = SWAPW(searchRange);
     64     le_int16  extra = SWAPW(rangeShift);
     65     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
     66     LEReferenceTo<LookupSingle> entry(base, success, entries);
     67     LEReferenceTo<LookupSingle> trial(entry, success, extra);
     68 
     69     if (SWAPW(trial->glyph) <= ttGlyph) {
     70         entry = trial;
     71     }
     72 
     73     while (probe > unity && LE_SUCCESS(success)) {
     74         probe >>= 1;
     75         trial = entry;
     76         trial.addOffset(probe, success);
     77 
     78         if (SWAPW(trial->glyph) <= ttGlyph) {
     79             entry = trial;
     80         }
     81     }
     82 
     83     if (SWAPW(entry->glyph) == ttGlyph) {
     84       return entry.getAlias();
     85     }
     86 
     87     return NULL;
     88 }
     89 
     90 U_NAMESPACE_END
     91