1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-26 22:53:14 -04:00

Disable subpixel binning for CJK glyphs

This commit is contained in:
valadaptive
2025-09-08 05:38:15 -04:00
parent 61351d170e
commit 623c4c6d3c
2 changed files with 39 additions and 27 deletions

View File

@@ -342,6 +342,7 @@ impl FontImpl {
atlas: &mut TextureAtlas,
metrics: &ScaledMetrics,
glyph_info: GlyphInfo,
chr: char,
h_pos: f32,
) -> (GlyphAllocation, i32) {
let Some(glyph_id) = glyph_info.id else {
@@ -349,7 +350,13 @@ impl FontImpl {
return (GlyphAllocation::default(), h_pos as i32);
};
let (h_pos_round, bin) = SubpixelBin::new(h_pos);
// CJK scripts contain a lot of characters and could hog the glyph atlas if we stored 4 subpixel offsets per
// glyph.
let (h_pos_round, bin) = if is_cjk(chr) {
(h_pos.round() as i32, SubpixelBin::Zero)
} else {
SubpixelBin::new(h_pos)
};
let entry = match self
.glyph_alloc_cache
@@ -581,3 +588,28 @@ fn invisible_char(c: char) -> bool {
| '\u{FEFF}' // ZERO WIDTH NO-BREAK SPACE
)
}
#[inline]
pub(super) fn is_cjk_ideograph(c: char) -> bool {
('\u{4E00}' <= c && c <= '\u{9FFF}')
|| ('\u{3400}' <= c && c <= '\u{4DBF}')
|| ('\u{2B740}' <= c && c <= '\u{2B81F}')
}
#[inline]
pub(super) fn is_kana(c: char) -> bool {
('\u{3040}' <= c && c <= '\u{309F}') // Hiragana block
|| ('\u{30A0}' <= c && c <= '\u{30FF}') // Katakana block
}
#[inline]
pub(super) fn is_cjk(c: char) -> bool {
// TODO(bigfarts): Add support for Korean Hangul.
is_cjk_ideograph(c) || is_kana(c)
}
#[inline]
pub(super) fn is_cjk_break_allowed(c: char) -> bool {
// See: https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages#Characters_not_permitted_on_the_start_of_a_line.
!")]}〕〉》」』】〙〗〟'\"⦆»ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻‐゠–〜?!‼⁇⁈⁉・、:;,。.".contains(c)
}

View File

@@ -5,7 +5,10 @@ use emath::{Align, GuiRounding as _, NumExt as _, Pos2, Rect, Vec2, pos2, vec2};
use crate::{
Color32, Mesh, Stroke, Vertex,
stroke::PathStroke,
text::{font::ScaledMetrics, fonts::FontFaceKey},
text::{
font::{ScaledMetrics, is_cjk, is_cjk_break_allowed},
fonts::FontFaceKey,
},
};
use super::{FontsImpl, Galley, Glyph, LayoutJob, LayoutSection, PlacedRow, Row, RowVisuals};
@@ -214,6 +217,7 @@ fn layout_section(
font.atlas,
&font_impl_metrics,
glyph_info,
chr,
paragraph.cursor_x,
),
None => Default::default(),
@@ -509,6 +513,7 @@ fn replace_last_glyph_with_overflow_character(
font.atlas,
&font_impl_metrics,
glyph_info,
overflow_character,
overflow_glyph_x * pixels_per_point,
)
})
@@ -1043,31 +1048,6 @@ impl RowBreakCandidates {
}
}
#[inline]
fn is_cjk_ideograph(c: char) -> bool {
('\u{4E00}' <= c && c <= '\u{9FFF}')
|| ('\u{3400}' <= c && c <= '\u{4DBF}')
|| ('\u{2B740}' <= c && c <= '\u{2B81F}')
}
#[inline]
fn is_kana(c: char) -> bool {
('\u{3040}' <= c && c <= '\u{309F}') // Hiragana block
|| ('\u{30A0}' <= c && c <= '\u{30FF}') // Katakana block
}
#[inline]
fn is_cjk(c: char) -> bool {
// TODO(bigfarts): Add support for Korean Hangul.
is_cjk_ideograph(c) || is_kana(c)
}
#[inline]
fn is_cjk_break_allowed(c: char) -> bool {
// See: https://en.wikipedia.org/wiki/Line_breaking_rules_in_East_Asian_languages#Characters_not_permitted_on_the_start_of_a_line.
!")]}〕〉》」』】〙〗〟'\"⦆»ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻‐゠–〜?!‼⁇⁈⁉・、:;,。.".contains(c)
}
// ----------------------------------------------------------------------------
#[cfg(test)]