2000-11-28 20:56:52 +00:00
|
|
|
/*
|
|
|
|
* @(#)LookupTables.cpp 1.5 00/03/15
|
|
|
|
*
|
2001-01-19 00:30:17 +00:00
|
|
|
* (C) Copyright IBM Corp. 1998, 1999, 2000, 2001 - All Rights Reserved
|
2000-11-28 20:56:52 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "LETypes.h"
|
|
|
|
#include "LayoutTables.h"
|
|
|
|
#include "LookupTables.h"
|
|
|
|
#include "LESwaps.h"
|
|
|
|
|
2001-10-16 00:39:01 +00:00
|
|
|
U_NAMESPACE_BEGIN
|
|
|
|
|
2000-11-28 20:56:52 +00:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2003-02-05 00:05:40 +00:00
|
|
|
const LookupSegment *BinarySearchLookupTable::lookupSegment(const LookupSegment *segments, LEGlyphID glyph) const
|
2000-11-28 20:56:52 +00:00
|
|
|
{
|
2003-02-05 00:05:40 +00:00
|
|
|
le_int16 unity = SWAPW(unitSize);
|
|
|
|
le_int16 probe = SWAPW(searchRange);
|
|
|
|
le_int16 extra = SWAPW(rangeShift);
|
2003-02-05 22:08:20 +00:00
|
|
|
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
|
2001-01-19 00:30:17 +00:00
|
|
|
const LookupSegment *entry = segments;
|
|
|
|
const LookupSegment *trial = (const LookupSegment *) ((char *) entry + extra);
|
2000-11-28 20:56:52 +00:00
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
if (SWAPW(trial->lastGlyph) <= ttGlyph) {
|
2000-11-28 20:56:52 +00:00
|
|
|
entry = trial;
|
|
|
|
}
|
|
|
|
|
2001-01-19 00:30:17 +00:00
|
|
|
while (probe > unity) {
|
2000-11-28 20:56:52 +00:00
|
|
|
probe >>= 1;
|
2001-01-19 00:30:17 +00:00
|
|
|
trial = (const LookupSegment *) ((char *) entry + probe);
|
2000-11-28 20:56:52 +00:00
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
if (SWAPW(trial->lastGlyph) <= ttGlyph) {
|
2000-11-28 20:56:52 +00:00
|
|
|
entry = trial;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
if (SWAPW(entry->firstGlyph) <= ttGlyph) {
|
2000-11-28 20:56:52 +00:00
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const
|
2000-11-28 20:56:52 +00:00
|
|
|
{
|
2003-02-05 00:05:40 +00:00
|
|
|
le_int16 unity = SWAPW(unitSize);
|
|
|
|
le_int16 probe = SWAPW(searchRange);
|
|
|
|
le_int16 extra = SWAPW(rangeShift);
|
2003-02-05 22:08:20 +00:00
|
|
|
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
|
2001-01-19 00:30:17 +00:00
|
|
|
const LookupSingle *entry = entries;
|
|
|
|
const LookupSingle *trial = (const LookupSingle *) ((char *) entry + extra);
|
2000-11-28 20:56:52 +00:00
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
if (SWAPW(trial->glyph) <= ttGlyph) {
|
2000-11-28 20:56:52 +00:00
|
|
|
entry = trial;
|
|
|
|
}
|
|
|
|
|
2001-01-19 00:30:17 +00:00
|
|
|
while (probe > unity) {
|
2000-11-28 20:56:52 +00:00
|
|
|
probe >>= 1;
|
2001-01-19 00:30:17 +00:00
|
|
|
trial = (const LookupSingle *) ((char *) entry + probe);
|
2000-11-28 20:56:52 +00:00
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
if (SWAPW(trial->glyph) <= ttGlyph) {
|
2000-11-28 20:56:52 +00:00
|
|
|
entry = trial;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-02-05 00:05:40 +00:00
|
|
|
if (SWAPW(entry->glyph) == ttGlyph) {
|
2000-11-28 20:56:52 +00:00
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-10-16 00:39:01 +00:00
|
|
|
|
|
|
|
U_NAMESPACE_END
|