Skip to content

Commit

Permalink
Merge various insert_dotted_circles implementations.
Browse files Browse the repository at this point in the history
  • Loading branch information
RazrFalcon committed Sep 9, 2023
1 parent 1fab693 commit 903413e
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 271 deletions.
20 changes: 20 additions & 0 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,26 @@ impl GlyphInfo {
// Var allocation: unicode_props
// Used during the entire shaping process to store unicode properties

pub(crate) fn complex_var_u8_category(&self) -> u8 {
let v: &[u8; 4] = bytemuck::cast_ref(&self.var2);
v[2]
}

pub(crate) fn set_complex_var_u8_category(&mut self, c: u8) {
let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var2);
v[2] = c;
}

pub(crate) fn complex_var_u8_auxiliary(&self) -> u8 {
let v: &[u8; 4] = bytemuck::cast_ref(&self.var2);
v[3]
}

pub(crate) fn set_complex_var_u8_auxiliary(&mut self, c: u8) {
let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var2);
v[3] = c;
}

#[inline]
fn unicode_props(&self) -> u16 {
let v: &[u16; 2] = bytemuck::cast_ref(&self.var2);
Expand Down
89 changes: 14 additions & 75 deletions src/complex/indic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use core::ops::Range;
use ttf_parser::GlyphId;

use super::*;
use crate::buffer::{Buffer, BufferFlags};
use crate::buffer::Buffer;
use crate::normalize::ShapeNormalizationMode;
use crate::ot::{
feature, FeatureFlags, LayoutTable, Map, TableIndex, WouldApply, WouldApplyContext,
Expand Down Expand Up @@ -538,23 +538,19 @@ impl IndicShapePlan {

impl GlyphInfo {
pub(crate) fn indic_category(&self) -> Category {
let v: &[u8; 4] = bytemuck::cast_ref(&self.var2);
v[2]
self.complex_var_u8_category()
}

pub(crate) fn set_indic_category(&mut self, c: Category) {
let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var2);
v[2] = c;
self.set_complex_var_u8_category(c)
}

pub(crate) fn indic_position(&self) -> Position {
let v: &[u8; 4] = bytemuck::cast_ref(&self.var2);
v[3]
self.complex_var_u8_auxiliary()
}

pub(crate) fn set_indic_position(&mut self, c: Position) {
let v: &mut [u8; 4] = bytemuck::cast_mut(&mut self.var2);
v[3] = c;
self.set_complex_var_u8_auxiliary(c)
}

fn is_one_of(&self, flags: u32) -> bool {
Expand Down Expand Up @@ -784,10 +780,18 @@ fn setup_syllables(_: &ShapePlan, _: &Face, buffer: &mut Buffer) {
}

fn initial_reordering(plan: &ShapePlan, face: &Face, buffer: &mut Buffer) {
use super::indic_machine::SyllableType;

let indic_plan = plan.data::<IndicShapePlan>();

update_consonant_positions(plan, indic_plan, face, buffer);
insert_dotted_circles(face, buffer);
syllabic::insert_dotted_circles(
face,
buffer,
SyllableType::BrokenCluster as u8,
category::DOTTED_CIRCLE,
Some(category::REPHA),
);

let mut start = 0;
let mut end = buffer.next_syllable(0);
Expand Down Expand Up @@ -885,71 +889,6 @@ fn consonant_position_from_face(
position::BASE_C
}

fn insert_dotted_circles(face: &Face, buffer: &mut Buffer) {
use super::indic_machine::SyllableType;

if buffer
.flags
.contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE)
{
return;
}

// Note: This loop is extra overhead, but should not be measurable.
// TODO Use a buffer scratch flag to remove the loop.
let has_broken_syllables = buffer
.info_slice()
.iter()
.any(|info| info.syllable() & 0x0F == SyllableType::BrokenCluster as u8);

if !has_broken_syllables {
return;
}

let dottedcircle_glyph = match face.glyph_index(0x25CC) {
Some(g) => g.0 as u32,
None => return,
};

let mut dottedcircle = GlyphInfo {
glyph_id: 0x25CC,
..GlyphInfo::default()
};
dottedcircle.set_indic_properties();
dottedcircle.glyph_id = dottedcircle_glyph;

buffer.clear_output();

buffer.idx = 0;
let mut last_syllable = 0;
while buffer.idx < buffer.len {
let syllable = buffer.cur(0).syllable();
let syllable_type = syllable & 0x0F;
if last_syllable != syllable && syllable_type == SyllableType::BrokenCluster as u8 {
last_syllable = syllable;

let mut ginfo = dottedcircle;
ginfo.cluster = buffer.cur(0).cluster;
ginfo.mask = buffer.cur(0).mask;
ginfo.set_syllable(buffer.cur(0).syllable());

// Insert dottedcircle after possible Repha.
while buffer.idx < buffer.len
&& last_syllable == buffer.cur(0).syllable()
&& buffer.cur(0).indic_category() == category::REPHA
{
buffer.next_glyph();
}

buffer.output_info(ginfo);
} else {
buffer.next_glyph();
}
}

buffer.swap_buffers();
}

fn initial_reordering_syllable(
plan: &ShapePlan,
indic_plan: &IndicShapePlan,
Expand Down
77 changes: 10 additions & 67 deletions src/complex/khmer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use alloc::boxed::Box;

use super::indic::{category, position};
use super::*;
use crate::buffer::{Buffer, BufferFlags};
use crate::buffer::Buffer;
use crate::ot::{feature, FeatureFlags};
use crate::plan::{ShapePlan, ShapePlanner};
use crate::unicode::{CharExt, GeneralCategoryExt};
Expand Down Expand Up @@ -166,7 +166,15 @@ fn setup_syllables(_: &ShapePlan, _: &Face, buffer: &mut Buffer) {
}

fn reorder(plan: &ShapePlan, face: &Face, buffer: &mut Buffer) {
insert_dotted_circles(face, buffer);
use super::khmer_machine::SyllableType;

syllabic::insert_dotted_circles(
face,
buffer,
SyllableType::BrokenCluster as u8,
category::DOTTED_CIRCLE,
Some(category::REPHA),
);

let khmer_plan = plan.data::<KhmerShapePlan>();

Expand All @@ -179,71 +187,6 @@ fn reorder(plan: &ShapePlan, face: &Face, buffer: &mut Buffer) {
}
}

fn insert_dotted_circles(face: &Face, buffer: &mut Buffer) {
use super::khmer_machine::SyllableType;

if buffer
.flags
.contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE)
{
return;
}

// Note: This loop is extra overhead, but should not be measurable.
// TODO Use a buffer scratch flag to remove the loop.
let has_broken_syllables = buffer
.info_slice()
.iter()
.any(|info| info.syllable() & 0x0F == SyllableType::BrokenCluster as u8);

if !has_broken_syllables {
return;
}

let dottedcircle_glyph = match face.glyph_index(0x25CC) {
Some(g) => g.0 as u32,
None => return,
};

let mut dottedcircle = GlyphInfo {
glyph_id: 0x25CC,
..GlyphInfo::default()
};
dottedcircle.set_khmer_properties();
dottedcircle.glyph_id = dottedcircle_glyph;

buffer.clear_output();

buffer.idx = 0;
let mut last_syllable = 0;
while buffer.idx < buffer.len {
let syllable = buffer.cur(0).syllable();
let syllable_type = syllable & 0x0F;
if last_syllable != syllable && syllable_type == SyllableType::BrokenCluster as u8 {
last_syllable = syllable;

let mut ginfo = dottedcircle;
ginfo.cluster = buffer.cur(0).cluster;
ginfo.mask = buffer.cur(0).mask;
ginfo.set_syllable(buffer.cur(0).syllable());

// Insert dottedcircle after possible Repha.
while buffer.idx < buffer.len
&& last_syllable == buffer.cur(0).syllable()
&& buffer.cur(0).indic_category() == category::REPHA
{
buffer.next_glyph();
}

buffer.output_info(ginfo);
} else {
buffer.next_glyph();
}
}

buffer.swap_buffers();
}

fn reorder_syllable(khmer_plan: &KhmerShapePlan, start: usize, end: usize, buffer: &mut Buffer) {
use super::khmer_machine::SyllableType;

Expand Down
1 change: 1 addition & 0 deletions src/complex/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod khmer_machine;
mod machine_cursor;
pub mod myanmar;
mod myanmar_machine;
mod syllabic;
pub mod thai;
pub mod universal;
mod universal_machine;
Expand Down
69 changes: 10 additions & 59 deletions src/complex/myanmar.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::indic::{category, position};
use super::*;
use crate::buffer::{Buffer, BufferFlags};
use crate::buffer::Buffer;
use crate::ot::{feature, FeatureFlags};
use crate::plan::{ShapePlan, ShapePlanner};
use crate::{Face, GlyphInfo, Tag};
Expand Down Expand Up @@ -180,7 +180,15 @@ fn setup_syllables(_: &ShapePlan, _: &Face, buffer: &mut Buffer) {
}

fn reorder(_: &ShapePlan, face: &Face, buffer: &mut Buffer) {
insert_dotted_circles(face, buffer);
use super::myanmar_machine::SyllableType;

syllabic::insert_dotted_circles(
face,
buffer,
SyllableType::BrokenCluster as u8,
category::PLACEHOLDER,
None,
);

let mut start = 0;
let mut end = buffer.next_syllable(0);
Expand All @@ -191,63 +199,6 @@ fn reorder(_: &ShapePlan, face: &Face, buffer: &mut Buffer) {
}
}

fn insert_dotted_circles(face: &Face, buffer: &mut Buffer) {
use super::myanmar_machine::SyllableType;

if buffer
.flags
.contains(BufferFlags::DO_NOT_INSERT_DOTTED_CIRCLE)
{
return;
}

// Note: This loop is extra overhead, but should not be measurable.
// TODO Use a buffer scratch flag to remove the loop.
let has_broken_syllables = buffer
.info_slice()
.iter()
.any(|info| info.syllable() & 0x0F == SyllableType::BrokenCluster as u8);

if !has_broken_syllables {
return;
}

let dottedcircle_glyph = match face.glyph_index(0x25CC) {
Some(g) => g.0 as u32,
None => return,
};

let mut dottedcircle = GlyphInfo {
glyph_id: 0x25CC,
..GlyphInfo::default()
};
dottedcircle.set_myanmar_properties();
dottedcircle.glyph_id = dottedcircle_glyph;

buffer.clear_output();

buffer.idx = 0;
let mut last_syllable = 0;
while buffer.idx < buffer.len {
let syllable = buffer.cur(0).syllable();
let syllable_type = syllable & 0x0F;
if last_syllable != syllable && syllable_type == SyllableType::BrokenCluster as u8 {
last_syllable = syllable;

let mut ginfo = dottedcircle;
ginfo.cluster = buffer.cur(0).cluster;
ginfo.mask = buffer.cur(0).mask;
ginfo.set_syllable(buffer.cur(0).syllable());

buffer.output_info(ginfo);
} else {
buffer.next_glyph();
}
}

buffer.swap_buffers();
}

fn reorder_syllable(start: usize, end: usize, buffer: &mut Buffer) {
use super::myanmar_machine::SyllableType;

Expand Down
Loading

0 comments on commit 903413e

Please sign in to comment.