]> git.saurik.com Git - apple/icu.git/blame - icuSources/layout/LookupTables.cpp
ICU-531.48.tar.gz
[apple/icu.git] / icuSources / layout / LookupTables.cpp
CommitLineData
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
12U_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 27const 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 60const 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
90U_NAMESPACE_END