Skip to content

Commit fe26933

Browse files
Nicolas Pitregregkh
authored andcommitted
vt: add ucs_get_fallback()
This is the code querying the newly introduced tables. Signed-off-by: Nicolas Pitre <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent de45d93 commit fe26933

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

drivers/tty/vt/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
3636

3737
endif
3838

39-
$(obj)/ucs.o: $(src)/ucs.c $(obj)/ucs_width_table.h $(obj)/ucs_recompose_table.h
39+
$(obj)/ucs.o: $(src)/ucs.c $(obj)/ucs_width_table.h \
40+
$(obj)/ucs_recompose_table.h $(obj)/ucs_fallback_table.h
4041

4142
# You may uncomment one of those to have the UCS tables be regenerated
4243
# during the build process. By default the _shipped versions are used.

drivers/tty/vt/ucs.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,87 @@ u32 ucs_recompose(u32 base, u32 mark)
157157

158158
return result ? result->recomposed : 0;
159159
}
160+
161+
/*
162+
* The fallback table structures implement a 2-level lookup.
163+
*/
164+
165+
struct ucs_page_desc {
166+
u8 page; /* Page index (high byte of code points) */
167+
u8 count; /* Number of entries in this page */
168+
u16 start; /* Start index in entries array */
169+
};
170+
171+
struct ucs_page_entry {
172+
u8 offset; /* Offset within page (0-255) */
173+
u8 fallback; /* Fallback character or range start marker */
174+
};
175+
176+
#include "ucs_fallback_table.h"
177+
178+
static int ucs_page_desc_cmp(const void *key, const void *element)
179+
{
180+
u8 page = *(u8 *)key;
181+
const struct ucs_page_desc *entry = element;
182+
183+
if (page < entry->page)
184+
return -1;
185+
if (page > entry->page)
186+
return 1;
187+
return 0;
188+
}
189+
190+
static int ucs_page_entry_cmp(const void *key, const void *element)
191+
{
192+
u8 offset = *(u8 *)key;
193+
const struct ucs_page_entry *entry = element;
194+
195+
if (offset < entry->offset)
196+
return -1;
197+
if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER) {
198+
if (offset > entry[1].offset)
199+
return 1;
200+
} else {
201+
if (offset > entry->offset)
202+
return 1;
203+
}
204+
return 0;
205+
}
206+
207+
/**
208+
* ucs_get_fallback() - Get a substitution for the provided Unicode character
209+
* @base: Base Unicode code point (UCS-4)
210+
*
211+
* Get a simpler fallback character for the provided Unicode character.
212+
* This is used for terminal display when corresponding glyph is unavailable.
213+
* The substitution may not be as good as the actual glyph for the original
214+
* character but still way more helpful than a squared question mark.
215+
*
216+
* Return: Fallback Unicode code point, or 0 if none is available
217+
*/
218+
u32 ucs_get_fallback(u32 cp)
219+
{
220+
const struct ucs_page_desc *page;
221+
const struct ucs_page_entry *entry;
222+
u8 page_idx = cp >> 8, offset = cp;
223+
224+
if (!UCS_IS_BMP(cp))
225+
return 0;
226+
227+
page = __inline_bsearch(&page_idx, ucs_fallback_pages,
228+
ARRAY_SIZE(ucs_fallback_pages),
229+
sizeof(*ucs_fallback_pages),
230+
ucs_page_desc_cmp);
231+
if (!page)
232+
return 0;
233+
234+
entry = __inline_bsearch(&offset, ucs_fallback_entries + page->start,
235+
page->count, sizeof(*ucs_fallback_entries),
236+
ucs_page_entry_cmp);
237+
if (!entry)
238+
return 0;
239+
240+
if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER)
241+
entry++;
242+
return entry->fallback;
243+
}

include/linux/consolemap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void console_map_init(void);
3131
bool ucs_is_double_width(uint32_t cp);
3232
bool ucs_is_zero_width(uint32_t cp);
3333
u32 ucs_recompose(u32 base, u32 mark);
34+
u32 ucs_get_fallback(u32 cp);
3435
#else
3536
static inline u16 inverse_translate(const struct vc_data *conp, u16 glyph,
3637
bool use_unicode)
@@ -75,6 +76,11 @@ static inline u32 ucs_recompose(u32 base, u32 mark)
7576
{
7677
return 0;
7778
}
79+
80+
static inline u32 ucs_get_fallback(u32 cp)
81+
{
82+
return 0;
83+
}
7884
#endif /* CONFIG_CONSOLE_TRANSLATIONS */
7985

8086
#endif /* __LINUX_CONSOLEMAP_H__ */

0 commit comments

Comments
 (0)