Opentype features in builder #75
Unanswered
solomancode
asked this question in
Q&A
Replies: 2 comments 1 reply
-
Allsorts tools contains the code used to implement those Unicode text rendering tests. In your code are you setting script, language, and writing direction appropriately? |
Beta Was this translation helpful? Give feedback.
0 replies
-
Hi @wezm , Please check the following code snippet, I'm trying to feed shaped glyphs info to the outline sink. There could be a better way to achieve that, that I'm not aware of. But basically I'm trying to generate outline data (ideally json) for a specific Arabic text. use std::fmt::Write;
use allsorts::binary::read::ReadScope;
use allsorts::cff::CFF;
use allsorts::font::{GlyphTableFlags, MatchingPresentation};
use allsorts::font_data::FontData;
use allsorts::gsub::RawGlyph;
use allsorts::gsub::{FeatureMask, Features};
use allsorts::outline::{OutlineBuilder, OutlineSink};
use allsorts::pathfinder_geometry::line_segment::LineSegment2F;
use allsorts::pathfinder_geometry::vector::Vector2F;
use allsorts::tables::glyf::GlyfTable;
use allsorts::tables::loca::LocaTable;
use allsorts::tables::{FontTableProvider, SfntVersion};
use allsorts::{tag, Font};
struct DebugVisitor {
outlines: String,
}
impl OutlineSink for DebugVisitor {
fn move_to(&mut self, to: Vector2F) {
writeln!(&mut self.outlines, "ctx.moveTo({}, {})", to.x(), to.y()).unwrap();
}
fn line_to(&mut self, to: Vector2F) {
writeln!(&mut self.outlines, "ctx.lineTo({}, {})", to.x(), to.y()).unwrap();
}
fn quadratic_curve_to(&mut self, control: Vector2F, to: Vector2F) {
writeln!(
&mut self.outlines,
"ctx.quadraticCurveTo({}, {}, {}, {})",
control.x(),
control.y(),
to.x(),
to.y()
)
.unwrap();
}
fn cubic_curve_to(&mut self, control: LineSegment2F, to: Vector2F) {
writeln!(
&mut self.outlines,
"ctx.bezierCurveTo({}, {}, {}, {}, {}, {})",
control.from_x(),
control.from_y(),
control.to_x(),
control.to_y(),
to.x(),
to.y()
)
.unwrap();
}
fn close(&mut self) {
writeln!(&mut self.outlines, "ctx.stroke()").unwrap();
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let script = tag::ARAB;
let buffer = std::fs::read("src/ScheherazadeRegOT.ttf")?;
let scope = ReadScope::new(&buffer);
let font_file = scope.read::<FontData<'_>>()?;
let provider = font_file.table_provider(0)?;
let mut font = Font::new(provider)?.ok_or("cmap missing")?;
let mut sink = DebugVisitor {
outlines: String::new(),
};
let text = "محمد";
let glyphs = font.map_glyphs(&text, script, MatchingPresentation::NotRequired);
let infos = font
.shape(
glyphs,
script,
Some(tag::from_string("AR ").unwrap()),
&Features::Mask(FeatureMask::all()),
true,
)
.map_err(|(err, _infos)| err)?;
if font.glyph_table_flags.contains(GlyphTableFlags::CFF)
&& font.font_table_provider.sfnt_version() == tag::OTTO
{
let cff_data = font.font_table_provider.read_table_data(tag::CFF)?;
let mut cff = ReadScope::new(&cff_data).read::<CFF<'_>>()?;
// -- HERE -- instead of glyphs to path, I'm looking for glyph info to path --
sink.glyphs_to_path(&mut cff, &glyphs)?;
} else if font.glyph_table_flags.contains(GlyphTableFlags::GLYF) {
let loca_data = font.font_table_provider.read_table_data(tag::LOCA)?;
let loca = ReadScope::new(&loca_data).read_dep::<LocaTable<'_>>((
usize::from(font.maxp_table.num_glyphs),
font.head_table()?
.ok_or("missing head table")?
.index_to_loc_format,
))?;
let glyf_data = font.font_table_provider.read_table_data(tag::GLYF)?;
let mut glyf = ReadScope::new(&glyf_data).read_dep::<GlyfTable<'_>>(&loca)?;
// -- and HERE -- instead of glyphs to path, I'm looking for glyph info to path --
sink.glyphs_to_path(&mut glyf, &glyphs)?;
} else {
return Err("no glyf or CFF table".into());
}
Ok(())
}
impl DebugVisitor {
pub fn glyphs_to_path<T>(
&mut self,
builder: &mut T,
glyphs: &[RawGlyph<()>],
) -> Result<(), Box<dyn std::error::Error>>
where
T: OutlineBuilder,
<T as OutlineBuilder>::Error: 'static,
{
for glyph in glyphs {
builder.visit(glyph.glyph_index, self)?;
}
Ok(())
}
} Thank you. |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Greetings everyone,
Pardon my questions - I'm new to allsorts. following the example at
https://docs.rs/allsorts/latest/allsorts/outline/index.html
I'm unable to render RTL ( Arabic ) text correctly using the outline module. I'm getting overlapping glyphs in the default positional form.
I assume the overlapping is due to the advance value isn't applied as well as the shaping of positional forms and required ligature.
I believe RTL ( Arabic ) rendering is already implemented. But I'm not sure how to use the Outline module to achieve similar results since I'm new to Rust. Any help is appreciated.
Please let me know If the feature is not yet Implemented, I might be able to help resolving this issue as I already have a similar contribution to Opentype.js
opentypejs/opentype.js#359
Thank you.
Beta Was this translation helpful? Give feedback.
All reactions