forked from mirrors/linux
Zero-width Unicode code points are causing misalignment in vertically aligned content, disrupting the visual layout. Let's handle zero-width code points more intelligently. Double-width code points are stored in the screen grid followed by a white space code point to create the expected screen layout. When a double-width code point is followed by a zero-width code point in the console incoming bytestream (e.g., an emoji with a presentation selector) then we may replace the white space padding by that zero-width code point instead of dropping it. This maximize screen content information while preserving proper layout. If a zero-width code point is preceded by a single-width code point then the above trick is not possible and such zero-width code point must be dropped. VS16 (Variation Selector 16, U+FE0F) is special as it doubles the width of the preceding single-width code point. We handle that case by giving VS16 a width of 1 when that happens. Signed-off-by: Nicolas Pitre <npitre@baylibre.com> Link: https://lore.kernel.org/r/20250410011839.64418-4-nico@fluxnic.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
78 lines
1.5 KiB
C
78 lines
1.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* consolemap.h
|
|
*
|
|
* Interface between console.c, selection.c and consolemap.c
|
|
*/
|
|
#ifndef __LINUX_CONSOLEMAP_H__
|
|
#define __LINUX_CONSOLEMAP_H__
|
|
|
|
enum translation_map {
|
|
LAT1_MAP,
|
|
GRAF_MAP,
|
|
IBMPC_MAP,
|
|
USER_MAP,
|
|
|
|
FIRST_MAP = LAT1_MAP,
|
|
LAST_MAP = USER_MAP,
|
|
};
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct vc_data;
|
|
|
|
#ifdef CONFIG_CONSOLE_TRANSLATIONS
|
|
u16 inverse_translate(const struct vc_data *conp, u16 glyph, bool use_unicode);
|
|
unsigned short *set_translate(enum translation_map m, struct vc_data *vc);
|
|
int conv_uni_to_pc(struct vc_data *conp, long ucs);
|
|
u32 conv_8bit_to_uni(unsigned char c);
|
|
int conv_uni_to_8bit(u32 uni);
|
|
void console_map_init(void);
|
|
bool ucs_is_double_width(uint32_t cp);
|
|
static inline bool ucs_is_zero_width(uint32_t cp)
|
|
{
|
|
/* coming soon */
|
|
return false;
|
|
}
|
|
#else
|
|
static inline u16 inverse_translate(const struct vc_data *conp, u16 glyph,
|
|
bool use_unicode)
|
|
{
|
|
return glyph;
|
|
}
|
|
|
|
static inline unsigned short *set_translate(enum translation_map m,
|
|
struct vc_data *vc)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
static inline int conv_uni_to_pc(struct vc_data *conp, long ucs)
|
|
{
|
|
return ucs > 0xff ? -1 : ucs;
|
|
}
|
|
|
|
static inline u32 conv_8bit_to_uni(unsigned char c)
|
|
{
|
|
return c;
|
|
}
|
|
|
|
static inline int conv_uni_to_8bit(u32 uni)
|
|
{
|
|
return uni & 0xff;
|
|
}
|
|
|
|
static inline void console_map_init(void) { }
|
|
|
|
static inline bool ucs_is_double_width(uint32_t cp)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static inline bool ucs_is_zero_width(uint32_t cp)
|
|
{
|
|
return false;
|
|
}
|
|
#endif /* CONFIG_CONSOLE_TRANSLATIONS */
|
|
|
|
#endif /* __LINUX_CONSOLEMAP_H__ */
|