summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2017-11-09 18:03:33 +0100
committerWilliam Wilgus <me.theuser@yahoo.com>2018-10-18 13:29:32 +0200
commitb977b77fb7ea75895ac65d64d99b056d95435bfc (patch)
tree8a4ba6adeb13e2af3c975479d90a4395a1b911db /firmware/common
parentdd40c46d50f9f22643b828e80783d3576b9c1d50 (diff)
downloadrockbox-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')
-rw-r--r--firmware/common/diacritic.c49
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
34struct diac_range 40struct 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 */
45static const struct diac_range diac_ranges[] = 50static 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
193static unsigned short mru_len = 0;
194static unsigned short diacritic_mru[MRU_MAX_LEN];
195
196bool is_diacritic(const unsigned short char_code, bool *is_rtl) 198bool 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
228Found: 237Found:
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