]>
git.saurik.com Git - apple/icu.git/blob - icuSources/layout/OpenTypeUtilities.cpp
3 * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
8 #include "OpenTypeTables.h"
9 #include "OpenTypeUtilities.h"
15 // Finds the high bit by binary searching
16 // through the bits in n.
18 le_int8
OpenTypeUtilities::highBit(le_int32 value
)
26 if (value
>= 1 << 16) {
31 if (value
>= 1 << 8) {
36 if (value
>= 1 << 4) {
41 if (value
>= 1 << 2) {
46 if (value
>= 1 << 1) {
55 Offset
OpenTypeUtilities::getTagOffset(LETag tag
, const LEReferenceToArrayOf
<TagAndOffsetRecord
> &records
, LEErrorCode
&success
)
57 const TagAndOffsetRecord
*r0
= (const TagAndOffsetRecord
*)records
.getAlias();
58 if(LE_FAILURE(success
)) return 0;
60 le_uint32 recordCount
= records
.getCount();
61 le_uint8 bit
= highBit(recordCount
);
62 le_int32 power
= 1 << bit
;
63 le_int32 extra
= recordCount
- power
;
64 le_int32 probe
= power
;
68 const ATag
&aTag
= (r0
+extra
)->tag
;
69 if (SWAPT(aTag
) <= tag
) {
74 while (probe
> (1 << 0)) {
78 const ATag
&aTag
= (r0
+index
+probe
)->tag
;
79 if (SWAPT(aTag
) <= tag
) {
86 const ATag
&aTag
= (r0
+index
)->tag
;
87 if (SWAPT(aTag
) == tag
) {
88 return SWAPW((r0
+index
)->offset
);
95 le_int32
OpenTypeUtilities::getGlyphRangeIndex(TTGlyphID glyphID
, const LEReferenceToArrayOf
<GlyphRangeRecord
> &records
, LEErrorCode
&success
)
97 if(LE_FAILURE(success
)) return -1;
99 le_uint32 recordCount
= records
.getCount();
100 le_uint8 bit
= highBit(recordCount
);
101 le_int32 power
= 1 << bit
;
102 le_int32 extra
= recordCount
- power
;
103 le_int32 probe
= power
;
106 if (recordCount
== 0) {
110 if (SWAPW(records(extra
,success
).firstGlyph
) <= glyphID
) {
114 while (probe
> (1 << 0) && LE_SUCCESS(success
)) {
117 if (SWAPW(records(range
+ probe
,success
).firstGlyph
) <= glyphID
) {
122 if (SWAPW(records(range
,success
).firstGlyph
) <= glyphID
&& SWAPW(records(range
,success
).lastGlyph
) >= glyphID
) {
129 le_int32
OpenTypeUtilities::search(le_uint32 value
, const le_uint32 array
[], le_int32 count
)
131 le_int32 power
= 1 << highBit(count
);
132 le_int32 extra
= count
- power
;
133 le_int32 probe
= power
;
136 if (value
>= array
[extra
]) {
140 while (probe
> (1 << 0)) {
143 if (value
>= array
[index
+ probe
]) {
151 le_int32
OpenTypeUtilities::search(le_uint16 value
, const le_uint16 array
[], le_int32 count
)
153 le_int32 power
= 1 << highBit(count
);
154 le_int32 extra
= count
- power
;
155 le_int32 probe
= power
;
158 if (value
>= array
[extra
]) {
162 while (probe
> (1 << 0)) {
165 if (value
>= array
[index
+ probe
]) {
174 // Straight insertion sort from Knuth vol. III, pg. 81
176 void OpenTypeUtilities::sort(le_uint16
*array
, le_int32 count
)
178 for (le_int32 j
= 1; j
< count
; j
+= 1) {
180 le_uint16 v
= array
[j
];
182 for (i
= j
- 1; i
>= 0; i
-= 1) {
187 array
[i
+ 1] = array
[i
];
196 #if LE_ASSERT_BAD_FONT
199 static const char *letagToStr(LETag tag
, char *str
) {
200 str
[0]= 0xFF & (tag
>>24);
201 str
[1]= 0xFF & (tag
>>16);
202 str
[2]= 0xFF & (tag
>>8);
203 str
[3]= 0xFF & (tag
>>0);
208 U_CAPI
void U_EXPORT2
_debug_LETableReference(const char *f
, int l
, const char *msg
, const LETableReference
*what
, const void *ptr
, size_t len
) {
211 fprintf(stderr
, "%s:%d: LETableReference@0x%p: ", f
, l
, what
);
212 fprintf(stderr
, msg
, ptr
, len
);
213 fprintf(stderr
, "\n");
215 for(int depth
=0;depth
<10&&(what
!=NULL
);depth
++) {
216 for(int i
=0;i
<depth
;i
++) {
217 fprintf(stderr
, " "); // indent
219 if(!what
->isValid()) {
220 fprintf(stderr
, "(invalid)");
222 fprintf(stderr
, "@%p: tag (%s) font (0x%p), [0x%p+0x%lx]\n", what
, letagToStr(what
->getTag(), tagbuf
), what
->getFont(),
223 what
->getAlias(), what
->getLength());
225 what
= what
->getParent();