rustybuzz: replace fontdue with rustybuzz
This gets rustybuzz working, which gives us proper kerning for the Arabic test. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
c50a772693
commit
476a565ae5
127
Cargo.lock
generated
127
Cargo.lock
generated
@ -4,104 +4,169 @@
|
|||||||
name = "approx"
|
name = "approx"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fontdue"
|
name = "cc"
|
||||||
version = "0.0.1"
|
version = "1.0.65"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95752358c8f7552394baf48cd82695b345628ad3f170d607de3ca03b8dacca15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jobserver",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "jobserver"
|
||||||
version = "0.5.0"
|
version = "0.1.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.80"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ordered-float"
|
name = "ordered-float"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-font-test"
|
name = "rust-font-test"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fontdue 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rusttype",
|
||||||
"rusttype 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustybuzz",
|
||||||
"stats_alloc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"stats_alloc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusttype"
|
name = "rusttype"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fa38506b5cbf2fb67f915e2725cb5012f1b9a785b0ab55c4733acda5f6554ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"approx",
|
||||||
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"arrayvec",
|
||||||
"libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libm",
|
||||||
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float",
|
||||||
"stb_truetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"stb_truetype",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustybuzz"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09e91a1066320c9d45c87f2191f78a4a4402d8cc66b896abd696ec275515c0b8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cc",
|
||||||
|
"smallvec",
|
||||||
|
"ttf-parser",
|
||||||
|
"unicode-bidi-mirroring",
|
||||||
|
"unicode-ccc",
|
||||||
|
"unicode-general-category",
|
||||||
|
"unicode-script",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stats_alloc"
|
name = "stats_alloc"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a260c96bf26273969f360c2fc2e2c7732acc2ce49d939c7243c7230c2ad179d0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stb_truetype"
|
name = "stb_truetype"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824210d6fb52cbc3ad2545270ead6860c7311aa5450642b078da4515937b6f7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder",
|
||||||
"libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[[package]]
|
||||||
"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
name = "ttf-parser"
|
||||||
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
version = "0.8.3"
|
||||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
checksum = "7622061403fd00f0820df288e5a580e87d3ce15a1c4313c59fd1ffb77129903f"
|
||||||
"checksum fontdue 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3ce5d972ee28d2830f868d3e1398721e0966a32113b888d8553712b50b1d03"
|
|
||||||
"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
|
[[package]]
|
||||||
"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
name = "unicode-bidi-mirroring"
|
||||||
"checksum num-traits 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "443c53b3c3531dfcbfa499d8893944db78474ad7a1d87fa2d94d1a2231693ac6"
|
version = "0.1.0"
|
||||||
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum rusttype 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6fa38506b5cbf2fb67f915e2725cb5012f1b9a785b0ab55c4733acda5f6554ef"
|
checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694"
|
||||||
"checksum stats_alloc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "a260c96bf26273969f360c2fc2e2c7732acc2ce49d939c7243c7230c2ad179d0"
|
|
||||||
"checksum stb_truetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "824210d6fb52cbc3ad2545270ead6860c7311aa5450642b078da4515937b6f7a"
|
[[package]]
|
||||||
|
name = "unicode-ccc"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbf4a1771ba99c4c8f6e5b1a37a208e970e77ed7297e29963dd1a2303601cd33"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-general-category"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f9af028e052a610d99e066b33304625dea9613170a2563314490a4e6ec5cf7f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-script"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79bf4d5fc96546fdb73f9827097810bbda93b11a6770ff3a54e1f445d4135787"
|
||||||
|
@ -7,6 +7,7 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fontdue = "0.0.1"
|
#fontdue = "0.2.4"
|
||||||
stats_alloc = "0.1.8"
|
stats_alloc = "0.1.8"
|
||||||
rusttype = {version = "0.8.1", default-features = false, features = ["libm-math"] }
|
rusttype = {version = "0.8.1", default-features = false, features = ["libm-math"] }
|
||||||
|
rustybuzz = "0.2.0"
|
||||||
|
195
src/main.rs
195
src/main.rs
@ -1,9 +1,9 @@
|
|||||||
use rusttype::{point, FontCollection, PositionedGlyph, Scale};
|
use rusttype::{point, Font, FontCollection, PositionedGlyph, Scale};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
// Add an allocator that lets us keep track of the system
|
// Add an allocator that lets us keep track of the system
|
||||||
extern crate stats_alloc;
|
extern crate stats_alloc;
|
||||||
use stats_alloc::{StatsAlloc, Region, INSTRUMENTED_SYSTEM};
|
use stats_alloc::{Region, StatsAlloc, INSTRUMENTED_SYSTEM};
|
||||||
use std::alloc::System;
|
use std::alloc::System;
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
|
static GLOBAL: &StatsAlloc<System> = &INSTRUMENTED_SYSTEM;
|
||||||
@ -16,37 +16,174 @@ fn main() {
|
|||||||
println!();
|
println!();
|
||||||
println!("RUSTTYPE TEST:");
|
println!("RUSTTYPE TEST:");
|
||||||
test_rusttype(font, message, rtl);
|
test_rusttype(font, message, rtl);
|
||||||
println!("FONTDUE TEST:");
|
println!("RUSTTYPE + RUSTYBUZZ TEST:");
|
||||||
test_fontdue(font, message, rtl);
|
test_rusthbuzz(font, message);
|
||||||
|
|
||||||
// Arabic test
|
// Arabic test
|
||||||
let font = include_bytes!("../resources/LateefRegOT.ttf");
|
let font = include_bytes!("../resources/LateefRegOT.ttf");
|
||||||
let message = "مرحبا بالعالم";
|
let message = "مرحبا بالعالم"; // "Hello, world!"
|
||||||
|
// let message = "مممممم"; // Kerning test nonsense string
|
||||||
let rtl = true;
|
let rtl = true;
|
||||||
|
// let message = "agylixm";
|
||||||
|
// let rtl = false;
|
||||||
println!();
|
println!();
|
||||||
println!("RUSTTYPE TEST:");
|
println!("RUSTTYPE TEST:");
|
||||||
test_rusttype(font, message, rtl);
|
test_rusttype(font, message, rtl);
|
||||||
println!("FONTDUE TEST:");
|
|
||||||
test_fontdue(font, message, rtl);
|
println!("RUSTTYPE + RUSTYBUZZ TEST:");
|
||||||
|
test_rusthbuzz(font, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_fontdue(font: &[u8], message: &str, _rtl: bool) {
|
// fn test_fontdue(font: &[u8], message: &str, _rtl: bool) {
|
||||||
|
// let reg = Region::new(&GLOBAL);
|
||||||
|
// println!("start: {:#?}", reg.change());
|
||||||
|
|
||||||
|
// // Parse it into the font type.
|
||||||
|
// let font = fontdue::Font::from_bytes(font, fontdue::FontSettings::default()).unwrap();
|
||||||
|
// println!("from_bytes: {:#?}", reg.change());
|
||||||
|
|
||||||
|
// // Rasterize and get the layout metrics for the letter 'g' at 17px.
|
||||||
|
// let (metrics, bitmap) = font.rasterize(message.chars().nth(0).unwrap(), 17.0);
|
||||||
|
// println!("font.rasterize: {:#?}", reg.change());
|
||||||
|
|
||||||
|
// // Used here to ensure that the value is not
|
||||||
|
// // dropped before we check the statistics
|
||||||
|
// ::std::mem::size_of_val(&metrics);
|
||||||
|
// ::std::mem::size_of_val(&bitmap);
|
||||||
|
// ::std::mem::size_of_val(&font);
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn test_rusthbuzz(font: &[u8], message: &str) {
|
||||||
|
const FB_WIDTH: usize = 520;
|
||||||
|
const FB_HEIGHT: usize = 200;
|
||||||
|
let mut buffer = [[0f32; FB_WIDTH]; FB_HEIGHT];
|
||||||
|
|
||||||
let reg = Region::new(&GLOBAL);
|
let reg = Region::new(&GLOBAL);
|
||||||
println!("start: {:#?}", reg.change());
|
|
||||||
|
|
||||||
// Parse it into the font type.
|
let mut buzz_font = rustybuzz::Font::from_slice(font, 0).unwrap();
|
||||||
let mut font = fontdue::Font::from_bytes(font).unwrap();
|
println!("buzz_font: {:#?}", reg.change());
|
||||||
println!("from_bytes: {:#?}", reg.change());
|
buzz_font.set_pixels_per_em(Some((196, 196)));
|
||||||
|
|
||||||
// Rasterize and get the layout metrics for the letter 'g' at 17px.
|
let mut buzz_buffer = rustybuzz::UnicodeBuffer::new();
|
||||||
let (metrics, bitmap) = font.rasterize(message.chars().nth(0).unwrap(), 17.0);
|
println!("buzz_buffer: {:#?}", reg.change());
|
||||||
println!("font.rasterize: {:#?}", reg.change());
|
|
||||||
|
|
||||||
// Used here to ensure that the value is not
|
buzz_buffer.push_str(message);
|
||||||
// dropped before we check the statistics
|
println!("buzz_buffer_push: {:#?}", reg.change());
|
||||||
::std::mem::size_of_val(&metrics);
|
|
||||||
::std::mem::size_of_val(&bitmap);
|
let buzz_features = vec![];
|
||||||
::std::mem::size_of_val(&font);
|
println!("buzz_features: {:#?}", reg.change());
|
||||||
|
|
||||||
|
let glyph_buffer = rustybuzz::shape(&buzz_font, &buzz_features, buzz_buffer);
|
||||||
|
println!("buzz_shape: {:#?}", reg.change());
|
||||||
|
|
||||||
|
let rusttype_font = Font::from_bytes(font).unwrap_or_else(|e| {
|
||||||
|
panic!("error constructing a FontCollection from bytes: {}", e);
|
||||||
|
});
|
||||||
|
println!("fonttype_collection: {:#?}", reg.change());
|
||||||
|
|
||||||
|
let mut cursor_x = 0.0;
|
||||||
|
let mut cursor_y = 0.0;
|
||||||
|
|
||||||
|
let rusttype_height = 196.0;
|
||||||
|
let rusttype_scale = rusttype::Scale {
|
||||||
|
x: rusttype_height * 1.0,
|
||||||
|
y: rusttype_height,
|
||||||
|
};
|
||||||
|
// Adapt the harfbuzz scale to rusttype's scale.
|
||||||
|
// I'm not sure where the "1.2" comes from, but the units only *just* match.
|
||||||
|
let harfbuzz_scale = rusttype_font.units_per_em() as f32 / rusttype_height * 1.2;
|
||||||
|
|
||||||
|
let v_metrics = rusttype_font.v_metrics(rusttype_scale);
|
||||||
|
let offset = point(0.0, v_metrics.ascent);
|
||||||
|
|
||||||
|
// println!("font is {} units-per-em", rusttype_font.units_per_em());
|
||||||
|
for (buzz_info, buzz_position) in glyph_buffer
|
||||||
|
.glyph_infos()
|
||||||
|
.iter()
|
||||||
|
.zip(glyph_buffer.glyph_positions().iter())
|
||||||
|
{
|
||||||
|
// let codepoint_rs = char::try_from(buzz_info.codepoint).expect("invalid codepoint");
|
||||||
|
let font_glyph = rusttype_font.glyph(rusttype::GlyphId(buzz_info.codepoint));
|
||||||
|
let glyph_scaled = font_glyph.scaled(rusttype_scale);
|
||||||
|
|
||||||
|
let x_offset = buzz_position.x_offset as f32 / harfbuzz_scale;
|
||||||
|
let y_offset = buzz_position.y_offset as f32 / harfbuzz_scale;
|
||||||
|
let x_advance = buzz_position.x_advance as f32 / harfbuzz_scale;
|
||||||
|
let y_advance = buzz_position.y_advance as f32 / harfbuzz_scale;
|
||||||
|
|
||||||
|
let glyph_positioned = glyph_scaled.positioned(rusttype::Point {
|
||||||
|
x: (x_offset as f32) + offset.x,
|
||||||
|
y: (y_offset as f32) + offset.y,
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(bb) = glyph_positioned.pixel_bounding_box() {
|
||||||
|
// println!(
|
||||||
|
// "Offset: {} / {}, {} / {} {}/{} {}/{}",
|
||||||
|
// x_offset, y_offset,
|
||||||
|
// x_advance, y_advance,
|
||||||
|
// cursor_x, cursor_y,
|
||||||
|
// bb.min.x, bb.min.y,
|
||||||
|
// );
|
||||||
|
glyph_positioned.draw(|x, y, weight| {
|
||||||
|
let x = (x as f32) + ((cursor_x + x_offset) as f32) + (bb.min.x as f32);
|
||||||
|
let y = (y as f32) + ((cursor_y + y_offset) as f32) + (bb.min.y as f32);
|
||||||
|
|
||||||
|
if (x < 0.0)
|
||||||
|
|| (x >= (buffer[0].len() as f32))
|
||||||
|
|| (y < 0.0)
|
||||||
|
|| (y >= (buffer.len() as f32))
|
||||||
|
{
|
||||||
|
// println!("(x,y) out of bounds: ({}, {})", x, y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let x = x as usize;
|
||||||
|
let y = y as usize;
|
||||||
|
// if y < buffer.len() && x < buffer[0].len() {
|
||||||
|
buffer[y][x] += weight;
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cursor_x += x_advance;
|
||||||
|
cursor_y += y_advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("Buffer: {:?}", buffer);
|
||||||
|
for y in (0..buffer.len() - 4).step_by(4) {
|
||||||
|
for x in (0..buffer[y].len() - 2).step_by(2) {
|
||||||
|
let mut offset = 0;
|
||||||
|
let threshold = 0.5;
|
||||||
|
|
||||||
|
if buffer[y + 0][x + 0] > threshold {
|
||||||
|
offset |= 1 << 0;
|
||||||
|
}
|
||||||
|
if buffer[y + 1][x + 0] > threshold {
|
||||||
|
offset |= 1 << 1;
|
||||||
|
}
|
||||||
|
if buffer[y + 2][x + 0] > threshold {
|
||||||
|
offset |= 1 << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if buffer[y + 0][x + 1] > threshold {
|
||||||
|
offset |= 1 << 3;
|
||||||
|
}
|
||||||
|
if buffer[y + 1][x + 1] > threshold {
|
||||||
|
offset |= 1 << 4;
|
||||||
|
}
|
||||||
|
if buffer[y + 2][x + 1] > threshold {
|
||||||
|
offset |= 1 << 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if buffer[y + 3][x + 0] > threshold {
|
||||||
|
offset |= 1 << 6;
|
||||||
|
}
|
||||||
|
if buffer[y + 3][x + 1] > threshold {
|
||||||
|
offset |= 1 << 7;
|
||||||
|
}
|
||||||
|
let pixel_br = std::char::from_u32(0x2800 + offset).unwrap();
|
||||||
|
print!("{}", pixel_br);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_rusttype(font: &[u8], message: &str, rtl: bool) {
|
fn test_rusttype(font: &[u8], message: &str, rtl: bool) {
|
||||||
@ -55,6 +192,7 @@ fn test_rusttype(font: &[u8], message: &str, rtl: bool) {
|
|||||||
panic!("error constructing a FontCollection from bytes: {}", e);
|
panic!("error constructing a FontCollection from bytes: {}", e);
|
||||||
});
|
});
|
||||||
println!("collection: {:#?}", reg.change());
|
println!("collection: {:#?}", reg.change());
|
||||||
|
|
||||||
let font = collection
|
let font = collection
|
||||||
.into_font() // only succeeds if collection consists of one font
|
.into_font() // only succeeds if collection consists of one font
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
@ -96,8 +234,8 @@ fn test_rusttype(font: &[u8], message: &str, rtl: bool) {
|
|||||||
println!("width: {}, height: {}", width, pixel_height);
|
println!("width: {}, height: {}", width, pixel_height);
|
||||||
|
|
||||||
// Rasterise directly into ASCII art.
|
// Rasterise directly into ASCII art.
|
||||||
let mut pixel_data = vec![b'@'; width * pixel_height];
|
let mut pixel_data = vec!['@'; width * pixel_height];
|
||||||
let mapping = b"@%#x+=:-. "; // The approximation of greyscale
|
let mapping = [' ', '░', '▒', '▓', '█']; // The approximation of greyscale
|
||||||
let mapping_scale = (mapping.len() - 1) as f32;
|
let mapping_scale = (mapping.len() - 1) as f32;
|
||||||
for g in glyphs {
|
for g in glyphs {
|
||||||
if let Some(bb) = g.pixel_bounding_box() {
|
if let Some(bb) = g.pixel_bounding_box() {
|
||||||
@ -105,7 +243,7 @@ fn test_rusttype(font: &[u8], message: &str, rtl: bool) {
|
|||||||
// v should be in the range 0.0 to 1.0
|
// v should be in the range 0.0 to 1.0
|
||||||
let i = (v * mapping_scale + 0.5) as usize;
|
let i = (v * mapping_scale + 0.5) as usize;
|
||||||
// so something's wrong if you get $ in the output.
|
// so something's wrong if you get $ in the output.
|
||||||
let c = mapping.get(i).cloned().unwrap_or(b'$');
|
let c = mapping.get(i).cloned().unwrap_or(' ');
|
||||||
let x = x as i32 + bb.min.x;
|
let x = x as i32 + bb.min.x;
|
||||||
let y = y as i32 + bb.min.y;
|
let y = y as i32 + bb.min.y;
|
||||||
// There's still a possibility that the glyph clips the boundaries of the bitmap
|
// There's still a possibility that the glyph clips the boundaries of the bitmap
|
||||||
@ -127,9 +265,14 @@ fn test_rusttype(font: &[u8], message: &str, rtl: bool) {
|
|||||||
let stdout = ::std::io::stdout();
|
let stdout = ::std::io::stdout();
|
||||||
let mut handle = stdout.lock();
|
let mut handle = stdout.lock();
|
||||||
for j in 0..pixel_height {
|
for j in 0..pixel_height {
|
||||||
handle
|
for px in pixel_data[j * width..(j + 1) * width].iter() {
|
||||||
.write_all(&pixel_data[j * width..(j + 1) * width])
|
let mut b = [0; 4];
|
||||||
.unwrap();
|
px.encode_utf8(&mut b);
|
||||||
|
handle.write_all(&b).unwrap();
|
||||||
|
}
|
||||||
|
// handle
|
||||||
|
// .write_all(&b)
|
||||||
|
// .unwrap();
|
||||||
handle.write_all(b"\n").unwrap();
|
handle.write_all(b"\n").unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user