mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 10:37:38 -04:00
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
This commit is contained in:
parent
dd40c46d50
commit
b977b77fb7
1 changed files with 29 additions and 20 deletions
|
@ -10,6 +10,7 @@
|
||||||
* Copyright (C) 2009 Phinitnun Chanasabaeng
|
* Copyright (C) 2009 Phinitnun Chanasabaeng
|
||||||
* Initial work
|
* Initial work
|
||||||
* Copyright (C) 2009 Tomer Shalev
|
* Copyright (C) 2009 Tomer Shalev
|
||||||
|
* Copyright (C) 2018 William Wilgus
|
||||||
*
|
*
|
||||||
* Rockbox diacritic positioning
|
* Rockbox diacritic positioning
|
||||||
* Based on initial work by Phinitnun Chanasabaeng
|
* Based on initial work by Phinitnun Chanasabaeng
|
||||||
|
@ -27,19 +28,23 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#define DIAC_NUM_RANGES (ARRAYLEN(diac_ranges))
|
#define DIAC_NUM_RANGES (ARRAYLEN(diac_ranges))
|
||||||
|
#define DIAC_RTL (1 << 7)
|
||||||
|
#define DIAC_CNT (0xFF ^ DIAC_RTL)
|
||||||
|
|
||||||
/* Each diac_range_ struct defines a Unicode range that begins with
|
/* Each diac_range_ struct defines a Unicode range that begins with
|
||||||
* N diacritic characters, and continues with non-diacritic characters up to the
|
* N diacritic characters, and continues with non-diacritic characters up to the
|
||||||
* base of the next item in the array */
|
* base of the next item in the array, [info] packs RTL status and the count of
|
||||||
|
* diacritic chars after [base]. RTL occupies the MSB and CNT the (7) lower bits
|
||||||
|
*/
|
||||||
|
|
||||||
struct diac_range
|
struct diac_range
|
||||||
{
|
{
|
||||||
unsigned base : 16;
|
uint16_t base;
|
||||||
unsigned num_diacritics : 7;
|
uint8_t info; /* [RTL:1 CNT:7] */
|
||||||
unsigned is_rtl : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DIAC_RANGE_ENTRY(first_diac, first_non_diac, is_rtl) \
|
#define DIAC_RANGE_ENTRY(first_diac, first_non_diac, is_rtl) \
|
||||||
{ first_diac, first_non_diac - first_diac, is_rtl }
|
{ first_diac, ((first_non_diac - first_diac) & DIAC_CNT) | (is_rtl * DIAC_RTL)}
|
||||||
|
|
||||||
/* Sorted by Unicode value */
|
/* Sorted by Unicode value */
|
||||||
static const struct diac_range diac_ranges[] =
|
static const struct diac_range diac_ranges[] =
|
||||||
|
@ -190,22 +195,28 @@ static const struct diac_range diac_ranges[] =
|
||||||
|
|
||||||
#define MRU_MAX_LEN 32
|
#define MRU_MAX_LEN 32
|
||||||
|
|
||||||
static unsigned short mru_len = 0;
|
|
||||||
static unsigned short diacritic_mru[MRU_MAX_LEN];
|
|
||||||
|
|
||||||
bool is_diacritic(const unsigned short char_code, bool *is_rtl)
|
bool is_diacritic(const unsigned short char_code, bool *is_rtl)
|
||||||
{
|
{
|
||||||
unsigned short mru, i;
|
static uint8_t mru_len = 0;
|
||||||
|
static uint8_t diacritic_mru[MRU_MAX_LEN];
|
||||||
|
|
||||||
|
uint8_t i, itmp;
|
||||||
|
uint8_t info, mru;
|
||||||
|
|
||||||
const struct diac_range *diac;
|
const struct diac_range *diac;
|
||||||
|
|
||||||
/* Search in MRU */
|
/* Search in MRU */
|
||||||
for (mru = 0; mru < mru_len; mru++)
|
for (mru = 0, i = 0; mru < mru_len; mru++)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* Items shifted >> 1 */
|
||||||
|
itmp = i;
|
||||||
i = diacritic_mru[mru];
|
i = diacritic_mru[mru];
|
||||||
|
diacritic_mru[mru] = itmp;
|
||||||
|
|
||||||
/* Found in MRU */
|
/* Found in MRU */
|
||||||
if (diac_ranges[i].base <= char_code &&
|
if ((char_code >= (diac = &diac_ranges[i])->base)
|
||||||
char_code < diac_ranges[i + 1].base)
|
&& (char_code < (++diac)->base))
|
||||||
{
|
{
|
||||||
goto Found;
|
goto Found;
|
||||||
}
|
}
|
||||||
|
@ -219,23 +230,21 @@ bool is_diacritic(const unsigned short char_code, bool *is_rtl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add MRU entry, or overwrite LRU if MRU array is full */
|
/* Add MRU entry */
|
||||||
if (mru_len < MRU_MAX_LEN)
|
if (mru_len < MRU_MAX_LEN)
|
||||||
mru_len++;
|
mru_len++;
|
||||||
else
|
|
||||||
mru--;
|
|
||||||
|
|
||||||
Found:
|
Found:
|
||||||
|
|
||||||
/* Promote MRU item to top of MRU */
|
/* Promote MRU item to top of MRU */
|
||||||
for ( ; mru > 0; mru--)
|
|
||||||
diacritic_mru[mru] = diacritic_mru[mru - 1];
|
|
||||||
diacritic_mru[0] = i;
|
diacritic_mru[0] = i;
|
||||||
|
|
||||||
diac = &diac_ranges[i];
|
diac = &diac_ranges[i];
|
||||||
|
info = diac->info;
|
||||||
|
|
||||||
/* Update RTL */
|
/* Update RTL */
|
||||||
if (is_rtl)
|
if (is_rtl)
|
||||||
*is_rtl = diac->is_rtl;
|
*is_rtl = ((DIAC_RTL & info) == DIAC_RTL);
|
||||||
|
|
||||||
return (char_code < diac->base + diac->num_diacritics);
|
return (char_code < diac->base + (info & DIAC_CNT));
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue