|
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 |