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