f2fbc8c394
X-SVN-Rev: 33535
91 lines
2.5 KiB
C++
91 lines
2.5 KiB
C++
/*
|
|
*
|
|
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
|
|
*
|
|
*/
|
|
|
|
#include "LETypes.h"
|
|
#include "LayoutTables.h"
|
|
#include "LookupTables.h"
|
|
#include "LESwaps.h"
|
|
|
|
U_NAMESPACE_BEGIN
|
|
|
|
/*
|
|
These are the rolled-up versions of the uniform binary search.
|
|
Someday, if we need more performance, we can un-roll them.
|
|
|
|
Note: I put these in the base class, so they only have to
|
|
be written once. Since the base class doesn't define the
|
|
segment table, these routines assume that it's right after
|
|
the binary search header.
|
|
|
|
Another way to do this is to put each of these routines in one
|
|
of the derived classes, and implement it in the others by casting
|
|
the "this" pointer to the type that has the implementation.
|
|
*/
|
|
const LookupSegment *BinarySearchLookupTable::lookupSegment(const LETableReference &base, const LookupSegment *segments, LEGlyphID glyph, LEErrorCode &success) const
|
|
{
|
|
|
|
le_int16 unity = SWAPW(unitSize);
|
|
le_int16 probe = SWAPW(searchRange);
|
|
le_int16 extra = SWAPW(rangeShift);
|
|
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
|
|
LEReferenceTo<LookupSegment> entry(base, success, segments);
|
|
LEReferenceTo<LookupSegment> trial(entry, success, extra);
|
|
|
|
if(LE_FAILURE(success)) return NULL;
|
|
|
|
if (SWAPW(trial->lastGlyph) <= ttGlyph) {
|
|
entry = trial;
|
|
}
|
|
|
|
while (probe > unity && LE_SUCCESS(success)) {
|
|
probe >>= 1;
|
|
trial = entry; // copy
|
|
trial.addOffset(probe, success);
|
|
|
|
if (SWAPW(trial->lastGlyph) <= ttGlyph) {
|
|
entry = trial;
|
|
}
|
|
}
|
|
|
|
if (SWAPW(entry->firstGlyph) <= ttGlyph) {
|
|
return entry.getAlias();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const LookupSingle *BinarySearchLookupTable::lookupSingle(const LETableReference &base, const LookupSingle *entries, LEGlyphID glyph, LEErrorCode &success) const
|
|
{
|
|
le_int16 unity = SWAPW(unitSize);
|
|
le_int16 probe = SWAPW(searchRange);
|
|
le_int16 extra = SWAPW(rangeShift);
|
|
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
|
|
LEReferenceTo<LookupSingle> entry(base, success, entries);
|
|
LEReferenceTo<LookupSingle> trial(entry, success, extra);
|
|
|
|
if (SWAPW(trial->glyph) <= ttGlyph) {
|
|
entry = trial;
|
|
}
|
|
|
|
while (probe > unity && LE_SUCCESS(success)) {
|
|
probe >>= 1;
|
|
trial = entry;
|
|
trial.addOffset(probe, success);
|
|
|
|
if (SWAPW(trial->glyph) <= ttGlyph) {
|
|
entry = trial;
|
|
}
|
|
}
|
|
|
|
if (SWAPW(entry->glyph) == ttGlyph) {
|
|
return entry.getAlias();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
U_NAMESPACE_END
|