]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * | |
3 | * (C) Copyright IBM Corp. 1998-2004 - 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 LookupSegment *segments, LEGlyphID glyph) const | |
28 | { | |
29 | le_int16 unity = SWAPW(unitSize); | |
30 | le_int16 probe = SWAPW(searchRange); | |
31 | le_int16 extra = SWAPW(rangeShift); | |
32 | TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); | |
33 | const LookupSegment *entry = segments; | |
34 | const LookupSegment *trial = (const LookupSegment *) ((char *) entry + extra); | |
35 | ||
36 | if (SWAPW(trial->lastGlyph) <= ttGlyph) { | |
37 | entry = trial; | |
38 | } | |
39 | ||
40 | while (probe > unity) { | |
41 | probe >>= 1; | |
42 | trial = (const LookupSegment *) ((char *) entry + probe); | |
43 | ||
44 | if (SWAPW(trial->lastGlyph) <= ttGlyph) { | |
45 | entry = trial; | |
46 | } | |
47 | } | |
48 | ||
49 | if (SWAPW(entry->firstGlyph) <= ttGlyph) { | |
50 | return entry; | |
51 | } | |
52 | ||
53 | return NULL; | |
54 | } | |
55 | ||
56 | const LookupSingle *BinarySearchLookupTable::lookupSingle(const LookupSingle *entries, LEGlyphID glyph) const | |
57 | { | |
58 | le_int16 unity = SWAPW(unitSize); | |
59 | le_int16 probe = SWAPW(searchRange); | |
60 | le_int16 extra = SWAPW(rangeShift); | |
61 | TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph); | |
62 | const LookupSingle *entry = entries; | |
63 | const LookupSingle *trial = (const LookupSingle *) ((char *) entry + extra); | |
64 | ||
65 | if (SWAPW(trial->glyph) <= ttGlyph) { | |
66 | entry = trial; | |
67 | } | |
68 | ||
69 | while (probe > unity) { | |
70 | probe >>= 1; | |
71 | trial = (const LookupSingle *) ((char *) entry + probe); | |
72 | ||
73 | if (SWAPW(trial->glyph) <= ttGlyph) { | |
74 | entry = trial; | |
75 | } | |
76 | } | |
77 | ||
78 | if (SWAPW(entry->glyph) == ttGlyph) { | |
79 | return entry; | |
80 | } | |
81 | ||
82 | return NULL; | |
83 | } | |
84 | ||
85 | U_NAMESPACE_END |