Add more fonts and implement [UIFont fontWithName: size:]

Change-Id: I2e39a424c3fa93c10c5e6fcfb3fbc4abeae9cf01
This commit is contained in:
alborrajo
2024-09-30 22:19:59 +02:00
parent 714290ed08
commit 78a4fde52b
11 changed files with 157 additions and 37 deletions

View File

@@ -86,15 +86,42 @@ impl Font {
Font { font }
}
pub fn mono_regular() -> Font {
Self::from_resource_file("LiberationMono-Regular.ttf")
}
pub fn mono_bold() -> Font {
Self::from_resource_file("LiberationMono-Bold.ttf")
}
pub fn mono_bold_italic() -> Font {
Self::from_resource_file("LiberationMono-BoldItalic.ttf")
}
pub fn mono_italic() -> Font {
Self::from_resource_file("LiberationMono-Italic.ttf")
}
pub fn sans_regular() -> Font {
Self::from_resource_file("LiberationSans-Regular.ttf")
}
pub fn sans_bold() -> Font {
Self::from_resource_file("LiberationSans-Bold.ttf")
}
pub fn sans_bold_italic() -> Font {
Self::from_resource_file("LiberationSans-BoldItalic.ttf")
}
pub fn sans_italic() -> Font {
Self::from_resource_file("LiberationSans-Italic.ttf")
}
pub fn serif_regular() -> Font {
Self::from_resource_file("LiberationSerif-Regular.ttf")
}
pub fn serif_bold() -> Font {
Self::from_resource_file("LiberationSerif-Bold.ttf")
}
pub fn serif_bold_italic() -> Font {
Self::from_resource_file("LiberationSerif-BoldItalic.ttf")
}
pub fn serif_italic() -> Font {
Self::from_resource_file("LiberationSerif-Italic.ttf")
}
pub fn sans_regular_ja() -> Font {
Self::from_resource_file("NotoSansJP-Regular.otf")
}

View File

@@ -9,25 +9,54 @@ use super::ui_graphics::UIGraphicsGetCurrentContext;
use crate::font::{Font, TextAlignment, WrapMode};
use crate::frameworks::core_graphics::cg_bitmap_context::CGBitmapContextDrawer;
use crate::frameworks::core_graphics::{CGFloat, CGPoint, CGRect, CGSize};
use crate::frameworks::foundation::ns_string::to_rust_string;
use crate::frameworks::foundation::NSInteger;
use crate::objc::{autorelease, id, objc_classes, ClassExports, HostObject};
use crate::Environment;
use std::collections::HashMap;
use std::ops::Range;
#[derive(Default)]
pub(super) struct State {
regular: Option<Font>,
bold: Option<Font>,
italic: Option<Font>,
regular_ja: Option<Font>,
bold_ja: Option<Font>,
fonts: HashMap<FontKind, Font>,
sans_regular_ja: Option<Font>,
sans_bold_ja: Option<Font>,
}
impl State {
fn get_font_by_kind(&mut self, font_kind: FontKind) -> &Font {
self.fonts
.entry(font_kind)
.or_insert_with(|| match font_kind {
FontKind::MonoRegular => Font::mono_regular(),
FontKind::MonoBold => Font::mono_bold(),
FontKind::MonoBoldItalic => Font::mono_bold_italic(),
FontKind::MonoItalic => Font::mono_italic(),
FontKind::SansRegular => Font::sans_regular(),
FontKind::SansBold => Font::sans_bold(),
FontKind::SansBoldItalic => Font::sans_bold_italic(),
FontKind::SansItalic => Font::sans_italic(),
FontKind::SerifRegular => Font::serif_regular(),
FontKind::SerifBold => Font::serif_bold(),
FontKind::SerifBoldItalic => Font::serif_bold_italic(),
FontKind::SerifItalic => Font::serif_italic(),
})
}
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
enum FontKind {
Regular,
Bold,
Italic,
MonoRegular,
MonoBold,
MonoBoldItalic,
MonoItalic,
SansRegular,
SansBold,
SansBoldItalic,
SansItalic,
SerifRegular,
SerifBold,
SerifBoldItalic,
SerifItalic,
}
struct UIFontHostObject {
@@ -67,37 +96,38 @@ pub const CLASSES: ClassExports = objc_classes! {
@implementation UIFont: NSObject
+ (id)systemFontOfSize:(CGFloat)size {
// Cache for later use
if env.framework_state.uikit.ui_font.regular.is_none() {
env.framework_state.uikit.ui_font.regular = Some(Font::sans_regular());
}
let host_object = UIFontHostObject {
size,
kind: FontKind::Regular,
kind: FontKind::SansRegular,
};
let new = env.objc.alloc_object(this, Box::new(host_object), &mut env.mem);
autorelease(env, new)
}
+ (id)boldSystemFontOfSize:(CGFloat)size {
// Cache for later use
if env.framework_state.uikit.ui_font.bold.is_none() {
env.framework_state.uikit.ui_font.bold = Some(Font::sans_bold());
}
let host_object = UIFontHostObject {
size,
kind: FontKind::Bold,
kind: FontKind::SansBold,
};
let new = env.objc.alloc_object(this, Box::new(host_object), &mut env.mem);
autorelease(env, new)
}
+ (id)italicSystemFontOfSize:(CGFloat)size {
// Cache for later use
if env.framework_state.uikit.ui_font.italic.is_none() {
env.framework_state.uikit.ui_font.italic = Some(Font::sans_italic());
}
let host_object = UIFontHostObject {
size,
kind: FontKind::Italic,
kind: FontKind::SansItalic,
};
let new = env.objc.alloc_object(this, Box::new(host_object), &mut env.mem);
autorelease(env, new)
}
+ (id)fontWithName:(id)fontName // NSString*
size:(CGFloat)fontSize {
let font_name = to_rust_string(env, fontName).to_string();
let host_object = UIFontHostObject {
kind: get_equivalent_font(&font_name).unwrap_or_else(|| {
log!("No replacement found for font {}. Using system font instead.", font_name);
FontKind::SansRegular
}),
size: fontSize,
};
let new = env.objc.alloc_object(this, Box::new(host_object), &mut env.mem);
autorelease(env, new)
@@ -134,27 +164,23 @@ fn get_font<'a>(state: &'a mut State, kind: FontKind, text: &str) -> &'a Font {
(0x3400..=0x4DBF).contains(&c) { // more kanji
match kind {
// CJK has no italic equivalent
FontKind::Regular | FontKind::Italic => {
if state.regular_ja.is_none() {
state.regular_ja = Some(Font::sans_regular_ja());
FontKind::MonoRegular | FontKind::MonoItalic | FontKind::SansRegular | FontKind::SansItalic | FontKind::SerifRegular | FontKind::SerifItalic => {
if state.sans_regular_ja.is_none() {
state.sans_regular_ja = Some(Font::sans_regular_ja());
}
return state.regular_ja.as_ref().unwrap();
return state.sans_regular_ja.as_ref().unwrap();
},
FontKind::Bold => {
if state.bold_ja.is_none() {
state.bold_ja = Some(Font::sans_bold_ja());
FontKind::MonoBold | FontKind::MonoBoldItalic | FontKind::SansBold | FontKind::SansBoldItalic | FontKind::SerifBold | FontKind::SerifBoldItalic => {
if state.sans_bold_ja.is_none() {
state.sans_bold_ja = Some(Font::sans_bold_ja());
}
return state.bold_ja.as_ref().unwrap();
return state.sans_bold_ja.as_ref().unwrap();
},
}
}
}
match kind {
FontKind::Regular => state.regular.as_ref().unwrap(),
FontKind::Bold => state.bold.as_ref().unwrap(),
FontKind::Italic => state.italic.as_ref().unwrap(),
}
state.get_font_by_kind(kind)
}
/// Called by the `sizeWithFont:` method family on `NSString`.
@@ -330,3 +356,70 @@ pub fn draw_in_rect(
text_size
}
fn get_equivalent_font(system_font: &str) -> Option<FontKind> {
// Maps every font found in every font family in an iOS 2 Simulator
match system_font {
// Font Family: Courier
"Courier" => None,
"Courier-BoldOblique" => None,
"Courier-Oblique" => None,
"Courier-Bold" => None,
// Font Family: AppleGothic
"AppleGothic" => None,
// Font Family: Arial
"ArialMT" => Some(FontKind::SansRegular),
"Arial-BoldMT" => Some(FontKind::SansBold),
"Arial-BoldItalicMT" => Some(FontKind::SansBoldItalic),
"Arial-ItalicMT" => Some(FontKind::SansItalic),
// Font Family: STHeiti TC
"STHeitiTC-Light" => None,
"STHeitiTC-Medium" => None,
// Font Family: Hiragino Kaku Gothic ProN
"HiraKakuProN-W6" => None,
"HiraKakuProN-W3" => None,
// Font Family: Courier New
"CourierNewPS-BoldMT" => Some(FontKind::MonoRegular),
"CourierNewPS-ItalicMT" => Some(FontKind::MonoBold),
"CourierNewPS-BoldItalicMT" => Some(FontKind::MonoBoldItalic),
"CourierNewPSMT" => Some(FontKind::MonoItalic),
// Font Family: Zapfino
"Zapfino" => None,
// Font Family: Arial Unicode MS
"ArialUnicodeMS" => None,
// Font Family: STHeiti SC
"STHeitiSC-Medium" => None,
"STHeitiSC-Light" => None,
// Font Family: American Typewriter
"AmericanTypewriter" => Some(FontKind::MonoRegular),
"AmericanTypewriter-Bold" => Some(FontKind::MonoBold),
// Font Family: Helvetica
"Helvetica-Oblique" => None,
"Helvetica-BoldOblique" => None,
"Helvetica" => None,
"Helvetica-Bold" => None,
// Font Family: Marker Felt
"MarkerFelt-Thin" => None,
// Font Family: Helvetica Neue
"HelveticaNeue" => None,
"HelveticaNeue-Bold" => None,
// Font Family: DB LCD Temp
"DBLCDTempBlack" => None,
// Font Family: Verdana
"Verdana-Bold" => None,
"Verdana-BoldItalic" => None,
"Verdana" => None,
"Verdana-Italic" => None,
// Font Family: Times New Roman
"TimesNewRomanPSMT" => Some(FontKind::SerifRegular),
"TimesNewRomanPS-BoldMT" => Some(FontKind::SerifBold),
"TimesNewRomanPS-BoldItalicMT" => Some(FontKind::SerifBoldItalic),
"TimesNewRomanPS-ItalicMT" => Some(FontKind::SerifItalic),
// Font Family: Georgia
"Georgia-Bold" => None,
"Georgia" => None,
"Georgia-BoldItalic" => None,
"Georgia-Italic" => None,
_ => None,
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.