servoshell (Windows): Add CJK fonts for egui (#44055)

We configure fonts for Windows referring to [doc
example](https://docs.rs/egui/latest/egui/struct.FontDefinitions.html).
There is a [discussion](https://github.com/emilk/egui/discussions/1344)
on this about various ways.

Testing: Not possible to write automated test.
Before: 
<img width="232" height="109" alt="image"
src="https://github.com/user-attachments/assets/be9f3724-9ee5-4157-bd9d-313b519d1e57"
/>

After: 
<img width="243" height="67" alt="image"
src="https://github.com/user-attachments/assets/e748389f-48e3-48c1-bdaf-23c49837a1c6"
/>

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
Euclid Ye
2026-04-09 18:43:41 +08:00
committed by GitHub
parent 3c4b8c61ea
commit 4c6d13d11e

View File

@@ -3,6 +3,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashMap;
#[cfg(target_os = "windows")]
use std::fs;
#[cfg(target_os = "windows")]
use std::path::Path;
use std::rc::Rc;
use std::sync::Arc;
@@ -10,12 +14,16 @@ use dpi::PhysicalSize;
use egui::text::{CCursor, CCursorRange};
use egui::text_edit::TextEditState;
use egui::{
Button, Id, Key, Label, LayerId, Modifiers, Order, PaintCallback, TopBottomPanel, Vec2,
WidgetInfo, WidgetType, pos2,
Button, FontDefinitions, Id, Key, Label, LayerId, Modifiers, Order, PaintCallback,
TopBottomPanel, Vec2, WidgetInfo, WidgetType, pos2,
};
#[cfg(target_os = "windows")]
use egui::{FontData, FontFamily};
use egui_glow::{CallbackFn, EguiGlow};
use egui_winit::EventResponse;
use euclid::{Length, Point2D, Rect, Scale, Size2D};
#[cfg(target_os = "windows")]
use log::info;
use log::warn;
use servo::{
DeviceIndependentPixel, DevicePixel, Image, LoadStatus, OffscreenRenderingContext, PixelFormat,
@@ -74,6 +82,51 @@ fn truncate_with_ellipsis(input: &str, max_length: usize) -> String {
}
}
#[cfg(target_os = "windows")]
fn configure_fonts() -> FontDefinitions {
let mut fonts = FontDefinitions::default();
let font_candidates = [
(r"C:\Windows\Fonts\malgun.ttf", "Malgun Gothic"), // Korean
(r"C:\Windows\Fonts\msyh.ttc", "Microsoft YaHei"), // Chinese + Japanese
];
let mut loaded_font_names = Vec::new();
for (path_str, font_name) in font_candidates.iter() {
let font_path = Path::new(path_str);
if font_path.exists() {
match fs::read(font_path) {
Ok(bytes) => {
fonts
.font_data
.insert(font_name.to_string(), Arc::new(FontData::from_owned(bytes)));
loaded_font_names.push(font_name.to_string());
info!("Loaded font: {}", font_name);
},
Err(error) => {
info!("Failed to read font {}: {}", font_name, error);
},
}
}
}
if !loaded_font_names.is_empty() {
let proportional = fonts.families.get_mut(&FontFamily::Proportional).unwrap();
for font_name in loaded_font_names.iter() {
proportional.insert(0, font_name.clone());
}
}
fonts
}
#[cfg(not(target_os = "windows"))]
fn configure_fonts() -> FontDefinitions {
// TODO: Default proportional fonts: ["Ubuntu-Light", "NotoEmoji-Regular", "emoji-icon-font"]
// does not support CJK. Add them for Mac/Linux.
FontDefinitions::default()
}
impl Drop for Gui {
fn drop(&mut self) {
self.rendering_context
@@ -102,6 +155,9 @@ impl Gui {
false,
);
let font_definitions = configure_fonts();
context.egui_ctx.set_fonts(font_definitions);
context
.egui_winit
.init_accesskit(event_loop, winit_window, event_loop_proxy);