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