diff options
author | William Wilgus <me.theuser@yahoo.com> | 2017-11-09 18:03:33 +0100 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2018-10-18 13:29:32 +0200 |
commit | b977b77fb7ea75895ac65d64d99b056d95435bfc (patch) | |
tree | 8a4ba6adeb13e2af3c975479d90a4395a1b911db /firmware/common/diacritic.c | |
parent | dd40c46d50f9f22643b828e80783d3576b9c1d50 (diff) | |
download | rockbox-b977b77fb7ea75895ac65d64d99b056d95435bfc.tar.gz rockbox-b977b77fb7ea75895ac65d64d99b056d95435bfc.zip |
Optimize is_diacritic
is_diacritic is used for pretty much all of the text display sizing
Timing here matters, so important it uses a
priority buffer in order to cut down on searching the database.
This patch is verified functionally equlivalent but
saves 80 bytes and is ~20% faster for the clip+ I tested it on
Several things were done:
Optimizing the copy loop for the priority buffer
Globbing some operations together
but the main one has to do with the database structure its self
--
Rather than a bit packed struct it combines the lower 8 bytes into
one value [info] and uses flags to access the values instead
Change-Id: I475073419b647639ef1eeaa3b9213e4e1067c0db
Diffstat (limited to 'firmware/common/diacritic.c')
-rw-r--r-- | firmware/common/diacritic.c | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/firmware/common/diacritic.c b/firmware/common/diacritic.c index aa2726c5fb..eca7b07b6e 100644 --- a/firmware/common/diacritic.c +++ b/firmware/common/diacritic.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Copyright (C) 2009 Phinitnun Chanasabaeng | 10 | * Copyright (C) 2009 Phinitnun Chanasabaeng |
11 | * Initial work | 11 | * Initial work |
12 | * Copyright (C) 2009 Tomer Shalev | 12 | * Copyright (C) 2009 Tomer Shalev |
13 | * Copyright (C) 2018 William Wilgus | ||
13 | * | 14 | * |
14 | * Rockbox diacritic positioning | 15 | * Rockbox diacritic positioning |
15 | * Based on initial work by Phinitnun Chanasabaeng | 16 | * Based on initial work by Phinitnun Chanasabaeng |
@@ -27,19 +28,23 @@ | |||
27 | #include "system.h" | 28 | #include "system.h" |
28 | 29 | ||
29 | #define DIAC_NUM_RANGES (ARRAYLEN(diac_ranges)) | 30 | #define DIAC_NUM_RANGES (ARRAYLEN(diac_ranges)) |
31 | #define DIAC_RTL (1 << 7) | ||
32 | #define DIAC_CNT (0xFF ^ DIAC_RTL) | ||
30 | 33 | ||
31 | /* Each diac_range_ struct defines a Unicode range that begins with | 34 | /* Each diac_range_ struct defines a Unicode range that begins with |
32 | * N diacritic characters, and continues with non-diacritic characters up to the | 35 | * N diacritic characters, and continues with non-diacritic characters up to the |
33 | * base of the next item in the array */ | 36 | * base of the next item in the array, [info] packs RTL status and the count of |
37 | * diacritic chars after [base]. RTL occupies the MSB and CNT the (7) lower bits | ||
38 | */ | ||
39 | |||
34 | struct diac_range | 40 | struct diac_range |
35 | { | 41 | { |
36 | unsigned base : 16; | 42 | uint16_t base; |
37 | unsigned num_diacritics : 7; | 43 | uint8_t info; /* [RTL:1 CNT:7] */ |
38 | unsigned is_rtl : 1; | ||
39 | }; | 44 | }; |
40 | 45 | ||
41 | #define DIAC_RANGE_ENTRY(first_diac, first_non_diac, is_rtl) \ | 46 | #define DIAC_RANGE_ENTRY(first_diac, first_non_diac, is_rtl) \ |
42 | { first_diac, first_non_diac - first_diac, is_rtl } | 47 | { first_diac, ((first_non_diac - first_diac) & DIAC_CNT) | (is_rtl * DIAC_RTL)} |
43 | 48 | ||
44 | /* Sorted by Unicode value */ | 49 | /* Sorted by Unicode value */ |
45 | static const struct diac_range diac_ranges[] = | 50 | static const struct diac_range diac_ranges[] = |
@@ -190,22 +195,28 @@ static const struct diac_range diac_ranges[] = | |||
190 | 195 | ||
191 | #define MRU_MAX_LEN 32 | 196 | #define MRU_MAX_LEN 32 |
192 | 197 | ||
193 | static unsigned short mru_len = 0; | ||
194 | static unsigned short diacritic_mru[MRU_MAX_LEN]; | ||
195 | |||
196 | bool is_diacritic(const unsigned short char_code, bool *is_rtl) | 198 | bool is_diacritic(const unsigned short char_code, bool *is_rtl) |
197 | { | 199 | { |
198 | unsigned short mru, i; | 200 | static uint8_t mru_len = 0; |
201 | static uint8_t diacritic_mru[MRU_MAX_LEN]; | ||
202 | |||
203 | uint8_t i, itmp; | ||
204 | uint8_t info, mru; | ||
205 | |||
199 | const struct diac_range *diac; | 206 | const struct diac_range *diac; |
200 | 207 | ||
201 | /* Search in MRU */ | 208 | /* Search in MRU */ |
202 | for (mru = 0; mru < mru_len; mru++) | 209 | for (mru = 0, i = 0; mru < mru_len; mru++) |
203 | { | 210 | { |
211 | |||
212 | /* Items shifted >> 1 */ | ||
213 | itmp = i; | ||
204 | i = diacritic_mru[mru]; | 214 | i = diacritic_mru[mru]; |
215 | diacritic_mru[mru] = itmp; | ||
205 | 216 | ||
206 | /* Found in MRU */ | 217 | /* Found in MRU */ |
207 | if (diac_ranges[i].base <= char_code && | 218 | if ((char_code >= (diac = &diac_ranges[i])->base) |
208 | char_code < diac_ranges[i + 1].base) | 219 | && (char_code < (++diac)->base)) |
209 | { | 220 | { |
210 | goto Found; | 221 | goto Found; |
211 | } | 222 | } |
@@ -219,23 +230,21 @@ bool is_diacritic(const unsigned short char_code, bool *is_rtl) | |||
219 | break; | 230 | break; |
220 | } | 231 | } |
221 | 232 | ||
222 | /* Add MRU entry, or overwrite LRU if MRU array is full */ | 233 | /* Add MRU entry */ |
223 | if (mru_len < MRU_MAX_LEN) | 234 | if (mru_len < MRU_MAX_LEN) |
224 | mru_len++; | 235 | mru_len++; |
225 | else | ||
226 | mru--; | ||
227 | 236 | ||
228 | Found: | 237 | Found: |
238 | |||
229 | /* Promote MRU item to top of MRU */ | 239 | /* Promote MRU item to top of MRU */ |
230 | for ( ; mru > 0; mru--) | ||
231 | diacritic_mru[mru] = diacritic_mru[mru - 1]; | ||
232 | diacritic_mru[0] = i; | 240 | diacritic_mru[0] = i; |
233 | 241 | ||
234 | diac = &diac_ranges[i]; | 242 | diac = &diac_ranges[i]; |
243 | info = diac->info; | ||
235 | 244 | ||
236 | /* Update RTL */ | 245 | /* Update RTL */ |
237 | if (is_rtl) | 246 | if (is_rtl) |
238 | *is_rtl = diac->is_rtl; | 247 | *is_rtl = ((DIAC_RTL & info) == DIAC_RTL); |
239 | 248 | ||
240 | return (char_code < diac->base + diac->num_diacritics); | 249 | return (char_code < diac->base + (info & DIAC_CNT)); |
241 | } | 250 | } \ No newline at end of file |