Abstract away `FontKey` so WebRender can more easily use this; switch
from angle measurement to scale-dependent hull height
This commit is contained in:
parent
45a812d30f
commit
5d3c1f6d59
|
@ -8,7 +8,7 @@ default = []
|
||||||
reftests = ["rsvg", "cairo-rs", "pathfinder_font_renderer/freetype"]
|
reftests = ["rsvg", "cairo-rs", "pathfinder_font_renderer/freetype"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.5"
|
app_units = "0.6"
|
||||||
base64 = "0.6"
|
base64 = "0.6"
|
||||||
bincode = "0.8"
|
bincode = "0.8"
|
||||||
env_logger = "0.4"
|
env_logger = "0.4"
|
||||||
|
|
|
@ -43,7 +43,7 @@ use lru_cache::LruCache;
|
||||||
use lyon_path::PathEvent;
|
use lyon_path::PathEvent;
|
||||||
use lyon_path::builder::{FlatPathBuilder, PathBuilder};
|
use lyon_path::builder::{FlatPathBuilder, PathBuilder};
|
||||||
use lyon_path::iterator::PathIter;
|
use lyon_path::iterator::PathIter;
|
||||||
use pathfinder_font_renderer::{FontContext, FontInstance, FontKey, GlyphImage};
|
use pathfinder_font_renderer::{FontContext, FontInstance, GlyphImage};
|
||||||
use pathfinder_font_renderer::{GlyphKey, SubpixelOffset};
|
use pathfinder_font_renderer::{GlyphKey, SubpixelOffset};
|
||||||
use pathfinder_partitioner::FillRule;
|
use pathfinder_partitioner::FillRule;
|
||||||
use pathfinder_partitioner::mesh_library::MeshLibrary;
|
use pathfinder_partitioner::mesh_library::MeshLibrary;
|
||||||
|
@ -57,6 +57,7 @@ use rocket_contrib::json::Json;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Cursor, Read};
|
use std::io::{self, Cursor, Read};
|
||||||
use std::path::{self, PathBuf};
|
use std::path::{self, PathBuf};
|
||||||
|
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
@ -75,6 +76,8 @@ const SUGGESTED_JSON_SIZE_LIMIT: u64 = 32 * 1024 * 1024;
|
||||||
|
|
||||||
const MESH_LIBRARY_CACHE_SIZE: usize = 16;
|
const MESH_LIBRARY_CACHE_SIZE: usize = 16;
|
||||||
|
|
||||||
|
static NEXT_FONT_KEY: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref MESH_LIBRARY_CACHE: Mutex<LruCache<MeshLibraryCacheKey, PartitionResponder>> = {
|
static ref MESH_LIBRARY_CACHE: Mutex<LruCache<MeshLibraryCacheKey, PartitionResponder>> = {
|
||||||
Mutex::new(LruCache::new(MESH_LIBRARY_CACHE_SIZE))
|
Mutex::new(LruCache::new(MESH_LIBRARY_CACHE_SIZE))
|
||||||
|
@ -261,6 +264,15 @@ struct PartitionSvgPathCommand {
|
||||||
values: Vec<f64>,
|
values: Vec<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||||
|
struct FontKey(usize);
|
||||||
|
|
||||||
|
impl FontKey {
|
||||||
|
fn new() -> FontKey {
|
||||||
|
FontKey(NEXT_FONT_KEY.fetch_add(1, Ordering::SeqCst))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PathPartitioningResult {
|
struct PathPartitioningResult {
|
||||||
encoded_data: Arc<Vec<u8>>,
|
encoded_data: Arc<Vec<u8>>,
|
||||||
time: Duration,
|
time: Duration,
|
||||||
|
@ -387,7 +399,7 @@ fn svg_data_from_request(builtin_svg_name: &str) -> Result<Arc<Vec<u8>>, SvgErro
|
||||||
fn rasterize_glyph_with_core_graphics(font_key: &FontKey,
|
fn rasterize_glyph_with_core_graphics(font_key: &FontKey,
|
||||||
font_index: u32,
|
font_index: u32,
|
||||||
otf_data: Arc<Vec<u8>>,
|
otf_data: Arc<Vec<u8>>,
|
||||||
font_instance: &FontInstance,
|
font_instance: &FontInstance<FontKey>,
|
||||||
glyph_key: &GlyphKey)
|
glyph_key: &GlyphKey)
|
||||||
-> Result<GlyphImage, FontError> {
|
-> Result<GlyphImage, FontError> {
|
||||||
let mut font_context =
|
let mut font_context =
|
||||||
|
|
|
@ -8,7 +8,7 @@ default = []
|
||||||
freetype = ["freetype-sys"]
|
freetype = ["freetype-sys"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.5"
|
app_units = "0.6"
|
||||||
euclid = "0.16"
|
euclid = "0.16"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
|
@ -25,12 +25,10 @@ optional = true
|
||||||
freetype-sys = "0.6"
|
freetype-sys = "0.6"
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
core-graphics = "0.13"
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.core-graphics]
|
|
||||||
git = "https://github.com/pcwalton/rust-core-graphics.git"
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies.core-text]
|
[target.'cfg(target_os = "macos")'.dependencies.core-text]
|
||||||
git = "https://github.com/pcwalton/rust-core-text.git"
|
git = "https://github.com/servo/core-text-rs.git"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies]
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
dwrite-sys = "0.2"
|
dwrite-sys = "0.2"
|
||||||
|
|
|
@ -24,10 +24,11 @@ use euclid::{Point2D, Rect, Size2D, Vector2D};
|
||||||
use lyon_path::PathEvent;
|
use lyon_path::PathEvent;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::collections::btree_map::Entry;
|
use std::collections::btree_map::Entry;
|
||||||
|
use std::hash::Hash;
|
||||||
use std::iter::Cloned;
|
use std::iter::Cloned;
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use {FontInstance, FontKey, GlyphDimensions, GlyphImage, GlyphKey};
|
use {FontInstance, GlyphDimensions, GlyphImage, GlyphKey};
|
||||||
|
|
||||||
const CG_ZERO_RECT: CGRect = CGRect {
|
const CG_ZERO_RECT: CGRect = CGRect {
|
||||||
origin: CG_ZERO_POINT,
|
origin: CG_ZERO_POINT,
|
||||||
|
@ -44,21 +45,39 @@ const CG_ZERO_RECT: CGRect = CGRect {
|
||||||
// direction.
|
// direction.
|
||||||
const FONT_DILATION_AMOUNT: f32 = 0.02;
|
const FONT_DILATION_AMOUNT: f32 = 0.02;
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct NativeFontHandle(pub CGFont);
|
||||||
|
|
||||||
/// An object that loads and renders fonts using macOS Core Graphics/Quartz.
|
/// An object that loads and renders fonts using macOS Core Graphics/Quartz.
|
||||||
pub struct FontContext {
|
pub struct FontContext<FK> where FK: Clone + Hash + Eq + Ord {
|
||||||
core_graphics_fonts: BTreeMap<FontKey, CGFont>,
|
core_graphics_fonts: BTreeMap<FK, CGFont>,
|
||||||
core_text_fonts: BTreeMap<FontInstance, CTFont>,
|
core_text_fonts: BTreeMap<FontInstance<FK>, CTFont>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontContext {
|
// Core Text is thread-safe.
|
||||||
|
unsafe impl<FK> Send for FontContext<FK> where FK: Clone + Hash + Eq + Ord {}
|
||||||
|
|
||||||
|
impl<FK> FontContext<FK> where FK: Clone + Hash + Eq + Ord {
|
||||||
/// Creates a new font context instance.
|
/// Creates a new font context instance.
|
||||||
pub fn new() -> Result<FontContext, ()> {
|
pub fn new() -> Result<Self, ()> {
|
||||||
Ok(FontContext {
|
Ok(FontContext {
|
||||||
core_graphics_fonts: BTreeMap::new(),
|
core_graphics_fonts: BTreeMap::new(),
|
||||||
core_text_fonts: BTreeMap::new(),
|
core_text_fonts: BTreeMap::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads an OpenType font from a Quartz `CGFont` handle.
|
||||||
|
pub fn add_native_font(&mut self, font_key: &FK, handle: CGFont) -> Result<(), ()> {
|
||||||
|
match self.core_graphics_fonts.entry((*font_key).clone()) {
|
||||||
|
Entry::Occupied(_) => Ok(()),
|
||||||
|
Entry::Vacant(entry) => {
|
||||||
|
entry.insert(handle);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Loads an OpenType font from memory.
|
/// Loads an OpenType font from memory.
|
||||||
///
|
///
|
||||||
/// `font_key` is a handle that is used to refer to the font later. If this context has already
|
/// `font_key` is a handle that is used to refer to the font later. If this context has already
|
||||||
|
@ -68,9 +87,9 @@ impl FontContext {
|
||||||
///
|
///
|
||||||
/// `font_index` is the index of the font within the collection, if `bytes` refers to a
|
/// `font_index` is the index of the font within the collection, if `bytes` refers to a
|
||||||
/// collection (`.ttc`).
|
/// collection (`.ttc`).
|
||||||
pub fn add_font_from_memory(&mut self, font_key: &FontKey, bytes: Arc<Vec<u8>>, _: u32)
|
pub fn add_font_from_memory(&mut self, font_key: &FK, bytes: Arc<Vec<u8>>, _: u32)
|
||||||
-> Result<(), ()> {
|
-> Result<(), ()> {
|
||||||
match self.core_graphics_fonts.entry(*font_key) {
|
match self.core_graphics_fonts.entry((*font_key).clone()) {
|
||||||
Entry::Occupied(_) => Ok(()),
|
Entry::Occupied(_) => Ok(()),
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
let data_provider = CGDataProvider::from_buffer(bytes);
|
let data_provider = CGDataProvider::from_buffer(bytes);
|
||||||
|
@ -84,7 +103,7 @@ impl FontContext {
|
||||||
/// Unloads the font with the given font key from memory.
|
/// Unloads the font with the given font key from memory.
|
||||||
///
|
///
|
||||||
/// If the font isn't loaded, does nothing.
|
/// If the font isn't loaded, does nothing.
|
||||||
pub fn delete_font(&mut self, font_key: &FontKey) {
|
pub fn delete_font(&mut self, font_key: &FK) {
|
||||||
self.core_graphics_fonts.remove(font_key);
|
self.core_graphics_fonts.remove(font_key);
|
||||||
|
|
||||||
let core_text_font_keys: Vec<_> = self.core_text_fonts
|
let core_text_font_keys: Vec<_> = self.core_text_fonts
|
||||||
|
@ -97,8 +116,8 @@ impl FontContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ensure_core_text_font(&mut self, font_instance: &FontInstance) -> Result<CTFont, ()> {
|
fn ensure_core_text_font(&mut self, font_instance: &FontInstance<FK>) -> Result<CTFont, ()> {
|
||||||
match self.core_text_fonts.entry(*font_instance) {
|
match self.core_text_fonts.entry((*font_instance).clone()) {
|
||||||
Entry::Occupied(entry) => Ok((*entry.get()).clone()),
|
Entry::Occupied(entry) => Ok((*entry.get()).clone()),
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
let core_graphics_font = match self.core_graphics_fonts
|
let core_graphics_font = match self.core_graphics_fonts
|
||||||
|
@ -121,7 +140,10 @@ impl FontContext {
|
||||||
/// libraries (including Pathfinder) apply modifications to the outlines: for example, to
|
/// libraries (including Pathfinder) apply modifications to the outlines: for example, to
|
||||||
/// dilate them for easier reading. To retrieve extents that account for these modifications,
|
/// dilate them for easier reading. To retrieve extents that account for these modifications,
|
||||||
/// set `exact` to false.
|
/// set `exact` to false.
|
||||||
pub fn glyph_dimensions(&self, font_instance: &FontInstance, glyph_key: &GlyphKey, exact: bool)
|
pub fn glyph_dimensions(&self,
|
||||||
|
font_instance: &FontInstance<FK>,
|
||||||
|
glyph_key: &GlyphKey,
|
||||||
|
exact: bool)
|
||||||
-> Result<GlyphDimensions, ()> {
|
-> Result<GlyphDimensions, ()> {
|
||||||
let core_graphics_font = match self.core_graphics_fonts.get(&font_instance.font_key) {
|
let core_graphics_font = match self.core_graphics_fonts.get(&font_instance.font_key) {
|
||||||
None => return Err(()),
|
None => return Err(()),
|
||||||
|
@ -174,7 +196,7 @@ impl FontContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of path commands that represent the given glyph in the given font.
|
/// Returns a list of path commands that represent the given glyph in the given font.
|
||||||
pub fn glyph_outline(&mut self, font_instance: &FontInstance, glyph_key: &GlyphKey)
|
pub fn glyph_outline(&mut self, font_instance: &FontInstance<FK>, glyph_key: &GlyphKey)
|
||||||
-> Result<GlyphOutline, ()> {
|
-> Result<GlyphOutline, ()> {
|
||||||
let core_text_font = try!(self.ensure_core_text_font(font_instance));
|
let core_text_font = try!(self.ensure_core_text_font(font_instance));
|
||||||
let path = try!(core_text_font.create_path_for_glyph(glyph_key.glyph_index as CGGlyph,
|
let path = try!(core_text_font.create_path_for_glyph(glyph_key.glyph_index as CGGlyph,
|
||||||
|
@ -220,7 +242,7 @@ impl FontContext {
|
||||||
/// designer. Because some font libraries, such as Core Graphics, perform modifications to the
|
/// designer. Because some font libraries, such as Core Graphics, perform modifications to the
|
||||||
/// glyph outlines, to ensure the entire outline fits it is best to pass false for `exact`.
|
/// glyph outlines, to ensure the entire outline fits it is best to pass false for `exact`.
|
||||||
pub fn rasterize_glyph_with_native_rasterizer(&self,
|
pub fn rasterize_glyph_with_native_rasterizer(&self,
|
||||||
font_instance: &FontInstance,
|
font_instance: &FontInstance<FK>,
|
||||||
glyph_key: &GlyphKey,
|
glyph_key: &GlyphKey,
|
||||||
exact: bool)
|
exact: bool)
|
||||||
-> Result<GlyphImage, ()> {
|
-> Result<GlyphImage, ()> {
|
||||||
|
@ -305,7 +327,7 @@ impl FontContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontInstance {
|
impl<FK> FontInstance<FK> where FK: Clone {
|
||||||
fn instantiate(&self, core_graphics_font: &CGFont) -> Result<CTFont, ()> {
|
fn instantiate(&self, core_graphics_font: &CGFont) -> Result<CTFont, ()> {
|
||||||
Ok(core_text::font::new_from_CGFont(core_graphics_font, self.size.to_f64_px()))
|
Ok(core_text::font::new_from_CGFont(core_graphics_font, self.size.to_f64_px()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,13 +55,12 @@ extern crate winapi;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use euclid::{Point2D, Size2D};
|
use euclid::{Point2D, Size2D};
|
||||||
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
#[cfg(all(target_os = "macos", not(feature = "freetype")))]
|
#[cfg(all(target_os = "macos", not(feature = "freetype")))]
|
||||||
pub use core_graphics::FontContext;
|
pub use core_graphics::{FontContext, GlyphOutline};
|
||||||
#[cfg(all(target_os = "windows", not(feature = "freetype")))]
|
#[cfg(all(target_os = "windows", not(feature = "freetype")))]
|
||||||
pub use directwrite::FontContext;
|
pub use directwrite::FontContext;
|
||||||
#[cfg(any(target_os = "linux", feature = "freetype"))]
|
#[cfg(any(target_os = "linux", feature = "freetype"))]
|
||||||
|
@ -80,44 +79,11 @@ mod freetype;
|
||||||
/// Right now, each glyph is snapped to the nearest quarter-pixel.
|
/// Right now, each glyph is snapped to the nearest quarter-pixel.
|
||||||
pub const SUBPIXEL_GRANULARITY: u8 = 4;
|
pub const SUBPIXEL_GRANULARITY: u8 = 4;
|
||||||
|
|
||||||
/// An opaque handle that represents a loaded font.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
|
||||||
pub struct FontKey {
|
|
||||||
id: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FontKey {
|
|
||||||
/// Constructs a new opaque font key distinct from all others.
|
|
||||||
pub fn new() -> FontKey {
|
|
||||||
static NEXT_FONT_KEY_ID: AtomicUsize = ATOMIC_USIZE_INIT;
|
|
||||||
FontKey {
|
|
||||||
id: NEXT_FONT_KEY_ID.fetch_add(1, Ordering::Relaxed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An opaque font that represents a loaded font *at one specific size*.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
|
||||||
pub struct FontInstanceKey {
|
|
||||||
id: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FontInstanceKey {
|
|
||||||
/// Creates a new opaque font instance key distinct from all others.
|
|
||||||
#[inline]
|
|
||||||
pub fn new() -> FontInstanceKey {
|
|
||||||
static NEXT_FONT_INSTANCE_KEY_ID: AtomicUsize = ATOMIC_USIZE_INIT;
|
|
||||||
FontInstanceKey {
|
|
||||||
id: NEXT_FONT_INSTANCE_KEY_ID.fetch_add(1, Ordering::Relaxed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A font at one specific size.
|
/// A font at one specific size.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
||||||
pub struct FontInstance {
|
pub struct FontInstance<FK> where FK: Clone {
|
||||||
/// The opaque font key that this font instance represents.
|
/// The opaque font key that this font instance represents.
|
||||||
pub font_key: FontKey,
|
pub font_key: FK,
|
||||||
|
|
||||||
/// The size of the font.
|
/// The size of the font.
|
||||||
///
|
///
|
||||||
|
@ -125,19 +91,19 @@ pub struct FontInstance {
|
||||||
pub size: Au,
|
pub size: Au,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontInstance {
|
impl<FK> FontInstance<FK> where FK: Clone {
|
||||||
/// Creates a new instance of a font at the given size.
|
/// Creates a new instance of a font at the given size.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(font_key: &FontKey, size: Au) -> FontInstance {
|
pub fn new(font_key: &FK, size: Au) -> FontInstance<FK> {
|
||||||
FontInstance {
|
FontInstance {
|
||||||
font_key: *font_key,
|
font_key: (*font_key).clone(),
|
||||||
size: size,
|
size: size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A subpixel offset, from 0 to `SUBPIXEL_GRANULARITY`.
|
/// A subpixel offset, from 0 to `SUBPIXEL_GRANULARITY`.
|
||||||
#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
pub struct SubpixelOffset(pub u8);
|
pub struct SubpixelOffset(pub u8);
|
||||||
|
|
||||||
impl Into<f32> for SubpixelOffset {
|
impl Into<f32> for SubpixelOffset {
|
||||||
|
|
|
@ -403,6 +403,11 @@ impl MeshLibrary {
|
||||||
b_boxes: self.b_boxes.len() as u32,
|
b_boxes: self.b_boxes.len() as u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn next_path_id(&self) -> u16 {
|
||||||
|
(self.path_ranges.len() + 1) as u16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -80,10 +80,9 @@ void main() {
|
||||||
// Compute area of convex hull (w). Change from curve to line if appropriate.
|
// Compute area of convex hull (w). Change from curve to line if appropriate.
|
||||||
float w = det2(mat2(v01, v02));
|
float w = det2(mat2(v01, v02));
|
||||||
float sqLen01 = dot(v01, v01), sqLen02 = dot(v02, v02), sqLen21 = dot(v21, v21);
|
float sqLen01 = dot(v01, v01), sqLen02 = dot(v02, v02), sqLen21 = dot(v21, v21);
|
||||||
float minCtrlSqLen = dot(v02, v02) * 0.0001;
|
float hullHeight = abs(w * inversesqrt(sqLen02));
|
||||||
float cosTheta = dot(v01, v21);
|
float minCtrlSqLen = sqLen02 * 0.01;
|
||||||
if (sqLen01 < minCtrlSqLen || sqLen21 < minCtrlSqLen ||
|
if (sqLen01 < minCtrlSqLen || sqLen21 < minCtrlSqLen || hullHeight < 0.0001) {
|
||||||
cosTheta * cosTheta >= 0.95 * sqLen01 * sqLen21) {
|
|
||||||
w = 0.0;
|
w = 0.0;
|
||||||
v01 = vec2(0.5, abs(v02.y) >= 0.01 ? 0.0 : 0.5) * v02.xx;
|
v01 = vec2(0.5, abs(v02.y) >= 0.01 ? 0.0 : 0.5) * v02.xx;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||||
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.5"
|
app_units = "0.6"
|
||||||
clap = "2.27"
|
clap = "2.27"
|
||||||
freetype-sys = "0.6"
|
freetype-sys = "0.6"
|
||||||
lyon_geom = "0.9"
|
lyon_geom = "0.9"
|
||||||
|
|
Loading…
Reference in New Issue