mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Auto merge of #7799 - mbrubeck:glyph-cleanup, r=pcwalton
Misc. code cleanup in gfx::text::glyph. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7799) <!-- Reviewable:end -->
This commit is contained in:
commit
ac448cacba
3 changed files with 36 additions and 65 deletions
|
@ -1792,7 +1792,7 @@ impl ScaledFontExtensionMethods for ScaledFont {
|
||||||
azglyphs.reserve(range.length().to_usize());
|
azglyphs.reserve(range.length().to_usize());
|
||||||
|
|
||||||
for slice in run.natural_word_slices_in_visual_order(range) {
|
for slice in run.natural_word_slices_in_visual_order(range) {
|
||||||
for (_i, glyph) in slice.glyphs.iter_glyphs_for_char_range(&slice.range) {
|
for glyph in slice.glyphs.iter_glyphs_for_char_range(&slice.range) {
|
||||||
let glyph_advance = glyph.advance();
|
let glyph_advance = glyph.advance();
|
||||||
let glyph_offset = glyph.offset().unwrap_or(Point2D::zero());
|
let glyph_offset = glyph.offset().unwrap_or(Point2D::zero());
|
||||||
let azglyph = struct__AzGlyph {
|
let azglyph = struct__AzGlyph {
|
||||||
|
|
|
@ -62,14 +62,6 @@ impl GlyphEntry {
|
||||||
GlyphEntry::new(glyph_count as u32)
|
GlyphEntry::new(glyph_count as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a GlyphEntry for the case where glyphs couldn't be found for the specified
|
|
||||||
/// character.
|
|
||||||
fn missing(glyph_count: usize) -> GlyphEntry {
|
|
||||||
assert!(glyph_count <= u16::MAX as usize);
|
|
||||||
|
|
||||||
GlyphEntry::new(glyph_count as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_initial(&self) -> bool {
|
fn is_initial(&self) -> bool {
|
||||||
*self == GlyphEntry::initial()
|
*self == GlyphEntry::initial()
|
||||||
}
|
}
|
||||||
|
@ -129,8 +121,8 @@ impl GlyphEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_char_is_space(&self) -> GlyphEntry {
|
fn set_char_is_space(&mut self) {
|
||||||
GlyphEntry::new(self.value | FLAG_CHAR_IS_SPACE)
|
self.value |= FLAG_CHAR_IS_SPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glyph_count(&self) -> u16 {
|
fn glyph_count(&self) -> u16 {
|
||||||
|
@ -147,11 +139,6 @@ impl GlyphEntry {
|
||||||
fn has_flag(&self, flag: u32) -> bool {
|
fn has_flag(&self, flag: u32) -> bool {
|
||||||
(self.value & flag) != 0
|
(self.value & flag) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn adapt_character_flags_of_entry(&self, other: GlyphEntry) -> GlyphEntry {
|
|
||||||
GlyphEntry { value: self.value | other.value }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stores data for a detailed glyph, in the case that several glyphs
|
// Stores data for a detailed glyph, in the case that several glyphs
|
||||||
|
@ -322,7 +309,6 @@ pub struct GlyphData {
|
||||||
id: GlyphId,
|
id: GlyphId,
|
||||||
advance: Au,
|
advance: Au,
|
||||||
offset: Point2D<Au>,
|
offset: Point2D<Au>,
|
||||||
is_missing: bool,
|
|
||||||
cluster_start: bool,
|
cluster_start: bool,
|
||||||
ligature_start: bool,
|
ligature_start: bool,
|
||||||
}
|
}
|
||||||
|
@ -332,7 +318,6 @@ impl GlyphData {
|
||||||
pub fn new(id: GlyphId,
|
pub fn new(id: GlyphId,
|
||||||
advance: Au,
|
advance: Au,
|
||||||
offset: Option<Point2D<Au>>,
|
offset: Option<Point2D<Au>>,
|
||||||
is_missing: bool,
|
|
||||||
cluster_start: bool,
|
cluster_start: bool,
|
||||||
ligature_start: bool)
|
ligature_start: bool)
|
||||||
-> GlyphData {
|
-> GlyphData {
|
||||||
|
@ -340,7 +325,6 @@ impl GlyphData {
|
||||||
id: id,
|
id: id,
|
||||||
advance: advance,
|
advance: advance,
|
||||||
offset: offset.unwrap_or(Point2D::zero()),
|
offset: offset.unwrap_or(Point2D::zero()),
|
||||||
is_missing: is_missing,
|
|
||||||
cluster_start: cluster_start,
|
cluster_start: cluster_start,
|
||||||
ligature_start: ligature_start,
|
ligature_start: ligature_start,
|
||||||
}
|
}
|
||||||
|
@ -465,31 +449,27 @@ impl<'a> GlyphStore {
|
||||||
/// otherwise, this glyph represents multiple characters.
|
/// otherwise, this glyph represents multiple characters.
|
||||||
pub fn add_glyph_for_char_index(&mut self,
|
pub fn add_glyph_for_char_index(&mut self,
|
||||||
i: CharIndex,
|
i: CharIndex,
|
||||||
character: Option<char>,
|
character: char,
|
||||||
data: &GlyphData) {
|
data: &GlyphData) {
|
||||||
fn glyph_is_compressible(data: &GlyphData) -> bool {
|
let glyph_is_compressible = is_simple_glyph_id(data.id) &&
|
||||||
is_simple_glyph_id(data.id)
|
is_simple_advance(data.advance)
|
||||||
&& is_simple_advance(data.advance)
|
|
||||||
&& data.offset == Point2D::zero()
|
&& data.offset == Point2D::zero()
|
||||||
&& data.cluster_start // others are stored in detail buffer
|
&& data.cluster_start; // others are stored in detail buffer
|
||||||
}
|
|
||||||
|
|
||||||
debug_assert!(data.ligature_start); // can't compress ligature continuation glyphs.
|
debug_assert!(data.ligature_start); // can't compress ligature continuation glyphs.
|
||||||
debug_assert!(i < self.char_len());
|
debug_assert!(i < self.char_len());
|
||||||
|
|
||||||
let mut entry = match (data.is_missing, glyph_is_compressible(data)) {
|
let mut entry = if glyph_is_compressible {
|
||||||
(true, _) => GlyphEntry::missing(1),
|
GlyphEntry::simple(data.id, data.advance)
|
||||||
(false, true) => GlyphEntry::simple(data.id, data.advance),
|
} else {
|
||||||
(false, false) => {
|
let glyph = &[DetailedGlyph::new(data.id, data.advance, data.offset)];
|
||||||
let glyph = &[DetailedGlyph::new(data.id, data.advance, data.offset)];
|
self.has_detailed_glyphs = true;
|
||||||
self.has_detailed_glyphs = true;
|
self.detail_store.add_detailed_glyphs_for_entry(i, glyph);
|
||||||
self.detail_store.add_detailed_glyphs_for_entry(i, glyph);
|
GlyphEntry::complex(data.cluster_start, data.ligature_start, 1)
|
||||||
GlyphEntry::complex(data.cluster_start, data.ligature_start, 1)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if character == Some(' ') {
|
if character == ' ' {
|
||||||
entry = entry.set_char_is_space()
|
entry.set_char_is_space()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.entry_buffer[i.to_usize()] = entry;
|
self.entry_buffer[i.to_usize()] = entry;
|
||||||
|
@ -502,22 +482,18 @@ impl<'a> GlyphStore {
|
||||||
let glyph_count = data_for_glyphs.len();
|
let glyph_count = data_for_glyphs.len();
|
||||||
|
|
||||||
let first_glyph_data = data_for_glyphs[0];
|
let first_glyph_data = data_for_glyphs[0];
|
||||||
let entry = match first_glyph_data.is_missing {
|
let glyphs_vec: Vec<DetailedGlyph> = (0..glyph_count).map(|i| {
|
||||||
true => GlyphEntry::missing(glyph_count),
|
DetailedGlyph::new(data_for_glyphs[i].id,
|
||||||
false => {
|
data_for_glyphs[i].advance,
|
||||||
let glyphs_vec: Vec<DetailedGlyph> = (0..glyph_count).map(|i| {
|
data_for_glyphs[i].offset)
|
||||||
DetailedGlyph::new(data_for_glyphs[i].id,
|
}).collect();
|
||||||
data_for_glyphs[i].advance,
|
|
||||||
data_for_glyphs[i].offset)
|
|
||||||
}).collect();
|
|
||||||
|
|
||||||
self.has_detailed_glyphs = true;
|
self.has_detailed_glyphs = true;
|
||||||
self.detail_store.add_detailed_glyphs_for_entry(i, &glyphs_vec);
|
self.detail_store.add_detailed_glyphs_for_entry(i, &glyphs_vec);
|
||||||
GlyphEntry::complex(first_glyph_data.cluster_start,
|
|
||||||
first_glyph_data.ligature_start,
|
let entry = GlyphEntry::complex(first_glyph_data.cluster_start,
|
||||||
glyph_count)
|
first_glyph_data.ligature_start,
|
||||||
}
|
glyph_count);
|
||||||
}.adapt_character_flags_of_entry(self.entry_buffer[i.to_usize()]);
|
|
||||||
|
|
||||||
debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry);
|
debug!("Adding multiple glyphs[idx={:?}, count={}]: {:?}", i, glyph_count, entry);
|
||||||
|
|
||||||
|
@ -566,7 +542,7 @@ impl<'a> GlyphStore {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn advance_for_char_range_slow_path(&self, rang: &Range<CharIndex>) -> Au {
|
pub fn advance_for_char_range_slow_path(&self, rang: &Range<CharIndex>) -> Au {
|
||||||
self.iter_glyphs_for_char_range(rang)
|
self.iter_glyphs_for_char_range(rang)
|
||||||
.fold(Au(0), |advance, (_, glyph)| advance + glyph.advance())
|
.fold(Au(0), |advance, glyph| advance + glyph.advance())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -688,11 +664,10 @@ pub struct GlyphIterator<'a> {
|
||||||
impl<'a> GlyphIterator<'a> {
|
impl<'a> GlyphIterator<'a> {
|
||||||
// Slow path when there is a glyph range.
|
// Slow path when there is a glyph range.
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn next_glyph_range(&mut self) -> Option<(CharIndex, GlyphInfo<'a>)> {
|
fn next_glyph_range(&mut self) -> Option<GlyphInfo<'a>> {
|
||||||
match self.glyph_range.as_mut().unwrap().next() {
|
match self.glyph_range.as_mut().unwrap().next() {
|
||||||
Some(j) => {
|
Some(j) => {
|
||||||
Some((self.char_index,
|
Some(GlyphInfo::Detail(self.store, self.char_index, j.get() as u16 /* ??? */))
|
||||||
GlyphInfo::Detail(self.store, self.char_index, j.get() as u16 /* ??? */)))
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// No more glyphs for current character. Try to get another.
|
// No more glyphs for current character. Try to get another.
|
||||||
|
@ -704,8 +679,7 @@ impl<'a> GlyphIterator<'a> {
|
||||||
|
|
||||||
// Slow path when there is a complex glyph.
|
// Slow path when there is a complex glyph.
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: CharIndex)
|
fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: CharIndex) -> Option<GlyphInfo<'a>> {
|
||||||
-> Option<(CharIndex, GlyphInfo<'a>)> {
|
|
||||||
let glyphs = self.store.detail_store.detailed_glyphs_for_entry(i, entry.glyph_count());
|
let glyphs = self.store.detail_store.detailed_glyphs_for_entry(i, entry.glyph_count());
|
||||||
self.glyph_range = Some(range::each_index(CharIndex(0), CharIndex(glyphs.len() as isize)));
|
self.glyph_range = Some(range::each_index(CharIndex(0), CharIndex(glyphs.len() as isize)));
|
||||||
self.next()
|
self.next()
|
||||||
|
@ -713,7 +687,7 @@ impl<'a> GlyphIterator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for GlyphIterator<'a> {
|
impl<'a> Iterator for GlyphIterator<'a> {
|
||||||
type Item = (CharIndex, GlyphInfo<'a>);
|
type Item = GlyphInfo<'a>;
|
||||||
|
|
||||||
// I tried to start with something simpler and apply FlatMap, but the
|
// I tried to start with something simpler and apply FlatMap, but the
|
||||||
// inability to store free variables in the FlatMap struct was problematic.
|
// inability to store free variables in the FlatMap struct was problematic.
|
||||||
|
@ -722,7 +696,7 @@ impl<'a> Iterator for GlyphIterator<'a> {
|
||||||
// slow paths, which should not be inlined, are `next_glyph_range()` and
|
// slow paths, which should not be inlined, are `next_glyph_range()` and
|
||||||
// `next_complex_glyph()`.
|
// `next_complex_glyph()`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<(CharIndex, GlyphInfo<'a>)> {
|
fn next(&mut self) -> Option<GlyphInfo<'a>> {
|
||||||
// Would use 'match' here but it borrows contents in a way that interferes with mutation.
|
// Would use 'match' here but it borrows contents in a way that interferes with mutation.
|
||||||
if self.glyph_range.is_some() {
|
if self.glyph_range.is_some() {
|
||||||
return self.next_glyph_range()
|
return self.next_glyph_range()
|
||||||
|
@ -741,7 +715,7 @@ impl<'a> Iterator for GlyphIterator<'a> {
|
||||||
debug_assert!(i < self.store.char_len());
|
debug_assert!(i < self.store.char_len());
|
||||||
let entry = self.store.entry_buffer[i.to_usize()];
|
let entry = self.store.entry_buffer[i.to_usize()];
|
||||||
if entry.is_simple() {
|
if entry.is_simple() {
|
||||||
Some((i, GlyphInfo::Simple(self.store, i)))
|
Some(GlyphInfo::Simple(self.store, i))
|
||||||
} else {
|
} else {
|
||||||
// Fall back to the slow path.
|
// Fall back to the slow path.
|
||||||
self.next_complex_glyph(&entry, i)
|
self.next_complex_glyph(&entry, i)
|
||||||
|
|
|
@ -453,20 +453,18 @@ impl Shaper {
|
||||||
let data = GlyphData::new(space_glyph_id,
|
let data = GlyphData::new(space_glyph_id,
|
||||||
advance,
|
advance,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
false,
|
|
||||||
true,
|
true,
|
||||||
true);
|
true);
|
||||||
glyphs.add_glyph_for_char_index(char_idx, Some(character), &data);
|
glyphs.add_glyph_for_char_index(char_idx, character, &data);
|
||||||
} else {
|
} else {
|
||||||
let shape = glyph_data.entry_for_glyph(glyph_span.begin(), &mut y_pos);
|
let shape = glyph_data.entry_for_glyph(glyph_span.begin(), &mut y_pos);
|
||||||
let advance = self.advance_for_shaped_glyph(shape.advance, character, options);
|
let advance = self.advance_for_shaped_glyph(shape.advance, character, options);
|
||||||
let data = GlyphData::new(shape.codepoint,
|
let data = GlyphData::new(shape.codepoint,
|
||||||
advance,
|
advance,
|
||||||
shape.offset,
|
shape.offset,
|
||||||
false,
|
|
||||||
true,
|
true,
|
||||||
true);
|
true);
|
||||||
glyphs.add_glyph_for_char_index(char_idx, Some(character), &data);
|
glyphs.add_glyph_for_char_index(char_idx, character, &data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// collect all glyphs to be assigned to the first character.
|
// collect all glyphs to be assigned to the first character.
|
||||||
|
@ -477,7 +475,6 @@ impl Shaper {
|
||||||
datas.push(GlyphData::new(shape.codepoint,
|
datas.push(GlyphData::new(shape.codepoint,
|
||||||
shape.advance,
|
shape.advance,
|
||||||
shape.offset,
|
shape.offset,
|
||||||
false, // not missing
|
|
||||||
true, // treat as cluster start
|
true, // treat as cluster start
|
||||||
glyph_i > glyph_span.begin()));
|
glyph_i > glyph_span.begin()));
|
||||||
// all but first are ligature continuations
|
// all but first are ligature continuations
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue