mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-28 12:45:27 +00:00
servo: Merge #10493 - gfx: Clamp the font size we supply to Core Text to 0.01pt (from pcwalton:inline-font-size-zero); r=mbrubeck
Core Text treats a font size of 0.0 as 12.0, which is obviously not what we want. Improves Twitter. Improves Reddit /r/rust. Closes #10492. r? @mbrubeck Source-Repo: https://github.com/servo/servo Source-Revision: 65120756c06ee2d0357cca6357e30694a0ec6559
This commit is contained in:
parent
53fc411e5c
commit
a7b88944ec
@ -38,7 +38,7 @@ fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFo
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFont {
|
||||
let cgfont = template.ctfont().as_ref().unwrap().copy_to_CGFont();
|
||||
let cgfont = template.ctfont(pt_size.to_f64_px()).as_ref().unwrap().copy_to_CGFont();
|
||||
ScaledFont::new(BackendType::Skia, &cgfont, pt_size.to_f32_px())
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ impl FontHandleMethods for FontHandle {
|
||||
Some(s) => s.to_f64_px(),
|
||||
None => 0.0
|
||||
};
|
||||
match template.ctfont() {
|
||||
match template.ctfont(size) {
|
||||
Some(ref ctfont) => {
|
||||
Ok(FontHandle {
|
||||
font_data: template.clone(),
|
||||
|
@ -2,6 +2,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use app_units::Au;
|
||||
use core_graphics::data_provider::CGDataProvider;
|
||||
use core_graphics::font::CGFont;
|
||||
use core_text;
|
||||
@ -9,6 +10,7 @@ use core_text::font::CTFont;
|
||||
use serde::de::{Error, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::borrow::ToOwned;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::ops::Deref;
|
||||
@ -26,7 +28,7 @@ pub struct FontTemplateData {
|
||||
/// `CTFont` instances over and over. It can always be recreated from the `identifier` and/or
|
||||
/// `font_data` fields.
|
||||
///
|
||||
/// When sending a `FontTemplateData` instance across processes, this will be set to `None` on
|
||||
/// When sending a `FontTemplateData` instance across processes, this will be cleared out on
|
||||
/// the other side, because `CTFont` instances cannot be sent across processes. This is
|
||||
/// harmless, however, because it can always be recreated.
|
||||
ctfont: CachedCTFont,
|
||||
@ -41,29 +43,38 @@ unsafe impl Sync for FontTemplateData {}
|
||||
impl FontTemplateData {
|
||||
pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> FontTemplateData {
|
||||
FontTemplateData {
|
||||
ctfont: CachedCTFont(Mutex::new(None)),
|
||||
ctfont: CachedCTFont(Mutex::new(HashMap::new())),
|
||||
identifier: identifier.to_owned(),
|
||||
font_data: font_data
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the Core Text font instance, instantiating it if necessary.
|
||||
pub fn ctfont(&self) -> Option<CTFont> {
|
||||
let mut ctfont = self.ctfont.lock().unwrap();
|
||||
if ctfont.is_none() {
|
||||
*ctfont = match self.font_data {
|
||||
pub fn ctfont(&self, pt_size: f64) -> Option<CTFont> {
|
||||
let mut ctfonts = self.ctfont.lock().unwrap();
|
||||
let pt_size_key = Au::from_f64_px(pt_size);
|
||||
if !ctfonts.contains_key(&pt_size_key) {
|
||||
// If you pass a zero font size to one of the Core Text APIs, it'll replace it with
|
||||
// 12.0. We don't want that! (Issue #10492.)
|
||||
let clamped_pt_size = pt_size.max(0.01);
|
||||
let ctfont = match self.font_data {
|
||||
Some(ref bytes) => {
|
||||
let fontprov = CGDataProvider::from_buffer(bytes);
|
||||
let cgfont_result = CGFont::from_data_provider(fontprov);
|
||||
match cgfont_result {
|
||||
Ok(cgfont) => Some(core_text::font::new_from_CGFont(&cgfont, 0.0)),
|
||||
Ok(cgfont) => {
|
||||
Some(core_text::font::new_from_CGFont(&cgfont, clamped_pt_size))
|
||||
}
|
||||
Err(_) => None
|
||||
}
|
||||
}
|
||||
None => core_text::font::new_from_name(&*self.identifier, 0.0).ok(),
|
||||
None => core_text::font::new_from_name(&*self.identifier, clamped_pt_size).ok(),
|
||||
};
|
||||
if let Some(ctfont) = ctfont {
|
||||
ctfonts.insert(pt_size_key, ctfont);
|
||||
}
|
||||
}
|
||||
ctfont.as_ref().map(|ctfont| (*ctfont).clone())
|
||||
ctfonts.get(&pt_size_key).map(|ctfont| (*ctfont).clone())
|
||||
}
|
||||
|
||||
/// Returns a clone of the data in this font. This may be a hugely expensive
|
||||
@ -75,7 +86,7 @@ impl FontTemplateData {
|
||||
None => {}
|
||||
}
|
||||
|
||||
let path = Url::parse(&*self.ctfont()
|
||||
let path = Url::parse(&*self.ctfont(0.0)
|
||||
.expect("No Core Text font available!")
|
||||
.url()
|
||||
.expect("No URL for Core Text font!")
|
||||
@ -96,16 +107,16 @@ impl FontTemplateData {
|
||||
|
||||
/// Returns the native font that underlies this font template, if applicable.
|
||||
pub fn native_font(&self) -> Option<CGFont> {
|
||||
self.ctfont().map(|ctfont| ctfont.copy_to_CGFont())
|
||||
self.ctfont(0.0).map(|ctfont| ctfont.copy_to_CGFont())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CachedCTFont(Mutex<Option<CTFont>>);
|
||||
pub struct CachedCTFont(Mutex<HashMap<Au, CTFont>>);
|
||||
|
||||
impl Deref for CachedCTFont {
|
||||
type Target = Mutex<Option<CTFont>>;
|
||||
fn deref(&self) -> &Mutex<Option<CTFont>> {
|
||||
type Target = Mutex<HashMap<Au, CTFont>>;
|
||||
fn deref(&self) -> &Mutex<HashMap<Au, CTFont>> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
@ -126,7 +137,7 @@ impl Deserialize for CachedCTFont {
|
||||
|
||||
#[inline]
|
||||
fn visit_none<E>(&mut self) -> Result<CachedCTFont, E> where E: Error {
|
||||
Ok(CachedCTFont(Mutex::new(None)))
|
||||
Ok(CachedCTFont(Mutex::new(HashMap::new())))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user