mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
vt: add ucs_get_fallback()
This is the code querying the newly introduced tables. Signed-off-by: Nicolas Pitre <npitre@baylibre.com> Link: https://lore.kernel.org/r/20250507141535.40655-7-nico@fluxnic.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
de45d93f00
commit
fe26933cf1
3 changed files with 92 additions and 1 deletions
|
@ -36,7 +36,8 @@ $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(obj)/ucs.o: $(src)/ucs.c $(obj)/ucs_width_table.h $(obj)/ucs_recompose_table.h
|
$(obj)/ucs.o: $(src)/ucs.c $(obj)/ucs_width_table.h \
|
||||||
|
$(obj)/ucs_recompose_table.h $(obj)/ucs_fallback_table.h
|
||||||
|
|
||||||
# You may uncomment one of those to have the UCS tables be regenerated
|
# You may uncomment one of those to have the UCS tables be regenerated
|
||||||
# during the build process. By default the _shipped versions are used.
|
# during the build process. By default the _shipped versions are used.
|
||||||
|
|
|
@ -157,3 +157,87 @@ u32 ucs_recompose(u32 base, u32 mark)
|
||||||
|
|
||||||
return result ? result->recomposed : 0;
|
return result ? result->recomposed : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The fallback table structures implement a 2-level lookup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ucs_page_desc {
|
||||||
|
u8 page; /* Page index (high byte of code points) */
|
||||||
|
u8 count; /* Number of entries in this page */
|
||||||
|
u16 start; /* Start index in entries array */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ucs_page_entry {
|
||||||
|
u8 offset; /* Offset within page (0-255) */
|
||||||
|
u8 fallback; /* Fallback character or range start marker */
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "ucs_fallback_table.h"
|
||||||
|
|
||||||
|
static int ucs_page_desc_cmp(const void *key, const void *element)
|
||||||
|
{
|
||||||
|
u8 page = *(u8 *)key;
|
||||||
|
const struct ucs_page_desc *entry = element;
|
||||||
|
|
||||||
|
if (page < entry->page)
|
||||||
|
return -1;
|
||||||
|
if (page > entry->page)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ucs_page_entry_cmp(const void *key, const void *element)
|
||||||
|
{
|
||||||
|
u8 offset = *(u8 *)key;
|
||||||
|
const struct ucs_page_entry *entry = element;
|
||||||
|
|
||||||
|
if (offset < entry->offset)
|
||||||
|
return -1;
|
||||||
|
if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER) {
|
||||||
|
if (offset > entry[1].offset)
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
if (offset > entry->offset)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ucs_get_fallback() - Get a substitution for the provided Unicode character
|
||||||
|
* @base: Base Unicode code point (UCS-4)
|
||||||
|
*
|
||||||
|
* Get a simpler fallback character for the provided Unicode character.
|
||||||
|
* This is used for terminal display when corresponding glyph is unavailable.
|
||||||
|
* The substitution may not be as good as the actual glyph for the original
|
||||||
|
* character but still way more helpful than a squared question mark.
|
||||||
|
*
|
||||||
|
* Return: Fallback Unicode code point, or 0 if none is available
|
||||||
|
*/
|
||||||
|
u32 ucs_get_fallback(u32 cp)
|
||||||
|
{
|
||||||
|
const struct ucs_page_desc *page;
|
||||||
|
const struct ucs_page_entry *entry;
|
||||||
|
u8 page_idx = cp >> 8, offset = cp;
|
||||||
|
|
||||||
|
if (!UCS_IS_BMP(cp))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
page = __inline_bsearch(&page_idx, ucs_fallback_pages,
|
||||||
|
ARRAY_SIZE(ucs_fallback_pages),
|
||||||
|
sizeof(*ucs_fallback_pages),
|
||||||
|
ucs_page_desc_cmp);
|
||||||
|
if (!page)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
entry = __inline_bsearch(&offset, ucs_fallback_entries + page->start,
|
||||||
|
page->count, sizeof(*ucs_fallback_entries),
|
||||||
|
ucs_page_entry_cmp);
|
||||||
|
if (!entry)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER)
|
||||||
|
entry++;
|
||||||
|
return entry->fallback;
|
||||||
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ void console_map_init(void);
|
||||||
bool ucs_is_double_width(uint32_t cp);
|
bool ucs_is_double_width(uint32_t cp);
|
||||||
bool ucs_is_zero_width(uint32_t cp);
|
bool ucs_is_zero_width(uint32_t cp);
|
||||||
u32 ucs_recompose(u32 base, u32 mark);
|
u32 ucs_recompose(u32 base, u32 mark);
|
||||||
|
u32 ucs_get_fallback(u32 cp);
|
||||||
#else
|
#else
|
||||||
static inline u16 inverse_translate(const struct vc_data *conp, u16 glyph,
|
static inline u16 inverse_translate(const struct vc_data *conp, u16 glyph,
|
||||||
bool use_unicode)
|
bool use_unicode)
|
||||||
|
@ -75,6 +76,11 @@ static inline u32 ucs_recompose(u32 base, u32 mark)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 ucs_get_fallback(u32 cp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* CONFIG_CONSOLE_TRANSLATIONS */
|
#endif /* CONFIG_CONSOLE_TRANSLATIONS */
|
||||||
|
|
||||||
#endif /* __LINUX_CONSOLEMAP_H__ */
|
#endif /* __LINUX_CONSOLEMAP_H__ */
|
||||||
|
|
Loading…
Add table
Reference in a new issue