aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock113
-rw-r--r--Cargo.toml11
-rw-r--r--font/Cargo.lock193
-rw-r--r--font/Cargo.toml20
-rw-r--r--font/src/darwin/mod.rs380
-rw-r--r--font/src/ft/list_fonts.rs (renamed from src/list_fonts.rs)0
-rw-r--r--font/src/ft/mod.rs (renamed from src/text.rs)64
-rw-r--r--font/src/lib.rs94
-rw-r--r--res/text.v.glsl5
-rw-r--r--src/grid.rs6
-rw-r--r--src/main.rs193
-rw-r--r--src/renderer/mod.rs12
-rw-r--r--src/tty.rs40
13 files changed, 921 insertions, 210 deletions
diff --git a/Cargo.lock b/Cargo.lock
index fb289588..79bd5805 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,12 +4,12 @@ version = "0.1.0"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cgmath 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "freetype-rs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "errno 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "font 0.1.0",
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glutin 0.4.9 (git+https://github.com/jwilm/glutin?rev=c95e6973ace3cbf321123a64588b27f032675be9)",
+ "glutin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "notify 2.5.5 (git+https://github.com/jwilm/rsnotify?branch=add-ignore-op)",
- "servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
+ "notify 2.6.1 (git+https://github.com/passcod/rsnotify)",
]
[[package]]
@@ -73,13 +73,13 @@ dependencies = [
[[package]]
name = "cocoa"
-version = "0.2.5"
+version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "objc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -110,6 +110,16 @@ dependencies = [
]
[[package]]
+name = "core-text"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "crossbeam"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -132,11 +142,25 @@ dependencies = [
]
[[package]]
-name = "dylib"
-version = "0.0.1"
+name = "errno"
+version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "euclid"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -157,6 +181,20 @@ dependencies = [
]
[[package]]
+name = "font"
+version = "0.1.0"
+dependencies = [
+ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "freetype-rs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
+]
+
+[[package]]
name = "freetype-rs"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -219,16 +257,6 @@ dependencies = [
[[package]]
name = "gl_generator"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "xml-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "gl_generator"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -247,23 +275,22 @@ dependencies = [
[[package]]
name = "glutin"
-version = "0.4.9"
-source = "git+https://github.com/jwilm/glutin?rev=c95e6973ace3cbf321123a64588b27f032675be9#c95e6973ace3cbf321123a64588b27f032675be9"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "cocoa 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cocoa 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "gl_generator 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "objc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "osmesa-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -271,7 +298,15 @@ dependencies = [
"wayland-kbd 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "x11-dl 2.4.0 (git+https://github.com/jwilm/x11-rs?rev=40f08df7b4408980b922b3c6e258c9c6765c2c24)",
+ "x11-dl 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "heapsize"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -410,8 +445,8 @@ dependencies = [
[[package]]
name = "notify"
-version = "2.5.5"
-source = "git+https://github.com/jwilm/rsnotify?branch=add-ignore-op#0ca41a4807c427e6cf47d7e75735df62d2e86708"
+version = "2.6.1"
+source = "git+https://github.com/passcod/rsnotify#7fbba3514fb7045549045e8da315007cebbcc953"
dependencies = [
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -495,19 +530,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "objc"
-version = "0.1.8"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "osmesa-sys"
-version = "0.0.5"
+version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -702,19 +735,11 @@ dependencies = [
[[package]]
name = "x11-dl"
-version = "2.4.0"
-source = "git+https://github.com/jwilm/x11-rs?rev=40f08df7b4408980b922b3c6e258c9c6765c2c24#40f08df7b4408980b922b3c6e258c9c6765c2c24"
-dependencies = [
- "dylib 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "xml-rs"
-version = "0.2.2"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index b95fdf67..6a8430a0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,18 +7,19 @@ exclude = ["res/*"]
build = "build.rs"
[dependencies]
-servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig" }
-freetype-rs = "0.9.0"
libc = "*"
cgmath = "0.7"
-notify = { git = "https://github.com/jwilm/rsnotify", branch = "add-ignore-op" }
+notify = { git = "https://github.com/passcod/rsnotify" }
bitflags = "*"
+font = { path = "./font" }
+errno = "0.1.6"
[build-dependencies]
gl_generator = "0.5"
[dependencies.glutin]
-git = "https://github.com/jwilm/glutin"
-rev = "c95e6973ace3cbf321123a64588b27f032675be9"
+version = "*"
+# git = "https://github.com/jwilm/glutin"
+# rev = "c95e6973ace3cbf321123a64588b27f032675be9"
# version = "*"
# path = "../glutin"
diff --git a/font/Cargo.lock b/font/Cargo.lock
new file mode 100644
index 00000000..58622341
--- /dev/null
+++ b/font/Cargo.lock
@@ -0,0 +1,193 @@
+[root]
+name = "font"
+version = "0.1.0"
+dependencies = [
+ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-text 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "freetype-rs 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "servo-fontconfig 0.2.0 (git+https://github.com/jwilm/rust-fontconfig)",
+]
+
+[[package]]
+name = "bitflags"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "core-foundation"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "core-graphics"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "core-text"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-graphics 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "euclid"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "expat-sys"
+version = "2.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "make-cmd 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "freetype-rs"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "freetype-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "freetype-sys"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libz-sys 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "gcc"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "heapsize"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libz-sys"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "log"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "make-cmd"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "num-traits"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc-serialize"
+version = "0.3.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "servo-fontconfig"
+version = "0.2.0"
+source = "git+https://github.com/jwilm/rust-fontconfig#419135e5e1106ec0973dd4923bd9c70d8e438cc8"
+dependencies = [
+ "libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "servo-fontconfig-sys 2.11.3 (git+https://github.com/jwilm/libfontconfig)",
+]
+
+[[package]]
+name = "servo-fontconfig-sys"
+version = "2.11.3"
+source = "git+https://github.com/jwilm/libfontconfig#618a52973d46e5cce4f054f6ee3bd2682167eee4"
+dependencies = [
+ "expat-sys 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "freetype-sys 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
diff --git a/font/Cargo.toml b/font/Cargo.toml
new file mode 100644
index 00000000..8345af73
--- /dev/null
+++ b/font/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "font"
+version = "0.1.0"
+authors = ["Joe Wilm <joe@jwilm.com>"]
+description = "Font rendering using the best available solution per platform"
+license = "Apache-2.0"
+
+[dependencies]
+euclid = "0.6.8"
+
+[target.'cfg(not(target_os = "macos"))'.dependencies]
+servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig" }
+freetype-rs = "0.9.0"
+libc = "0.2.11"
+
+[target.'cfg(target_os = "macos")'.dependencies]
+core-text = "1.1.1"
+core-foundation = "0.2.2"
+core-graphics = "0.3.2"
+core-foundation-sys = "0.2.2"
diff --git a/font/src/darwin/mod.rs b/font/src/darwin/mod.rs
new file mode 100644
index 00000000..844850e0
--- /dev/null
+++ b/font/src/darwin/mod.rs
@@ -0,0 +1,380 @@
+//! Font rendering based on CoreText
+//!
+//! TODO error handling... just search for unwrap.
+use std::collections::HashMap;
+use std::ops::Deref;
+use std::ptr;
+
+use core_foundation::base::TCFType;
+use core_foundation::string::{CFString, CFStringRef};
+use core_foundation::array::CFIndex;
+use core_foundation_sys::string::UniChar;
+use core_graphics::base::kCGImageAlphaNoneSkipFirst;
+use core_graphics::base::kCGImageAlphaPremultipliedLast;
+use core_graphics::color_space::CGColorSpace;
+use core_graphics::context::{CGContext, CGContextRef};
+use core_graphics::font::CGGlyph;
+use core_graphics::geometry::CGPoint;
+use core_text::font::{CTFont, new_from_descriptor as ct_new_from_descriptor};
+use core_text::font_collection::create_for_family;
+use core_text::font_collection::get_family_names as ct_get_family_names;
+use core_text::font_descriptor::kCTFontDefaultOrientation;
+use core_text::font_descriptor::kCTFontHorizontalOrientation;
+use core_text::font_descriptor::kCTFontVerticalOrientation;
+use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef, CTFontOrientation};
+
+use euclid::point::Point2D;
+use euclid::rect::Rect;
+use euclid::size::Size2D;
+
+use super::{FontDesc, RasterizedGlyph, Metrics};
+
+/// Font descriptor
+///
+/// The descriptor provides data about a font and supports creating a font.
+#[derive(Debug)]
+pub struct Descriptor {
+ family_name: String,
+ font_name: String,
+ style_name: String,
+ display_name: String,
+ font_path: String,
+
+ ct_descriptor: CTFontDescriptor
+}
+
+/// Rasterizer, the main type exported by this package
+///
+/// Given a fontdesc, can rasterize fonts.
+pub struct Rasterizer {
+ fonts: HashMap<FontDesc, Font>,
+ device_pixel_ratio: f32,
+}
+
+impl Rasterizer {
+ pub fn new(dpi_x: f32, dpi_y: f32, device_pixel_ratio: f32) -> Rasterizer {
+ println!("device_pixel_ratio: {}", device_pixel_ratio);
+ Rasterizer {
+ fonts: HashMap::new(),
+ device_pixel_ratio: device_pixel_ratio,
+ }
+ }
+
+ pub fn metrics(&mut self, desc: &FontDesc, size: f32) -> Metrics {
+ let scaled_size = self.device_pixel_ratio * size;
+ self.get_font(desc, scaled_size).unwrap().metrics()
+ }
+
+ fn get_font(&mut self, desc: &FontDesc, size: f32) -> Option<Font> {
+ if let Some(font) = self.fonts.get(desc) {
+ return Some(font.clone());
+ }
+
+ let descriptors = descriptors_for_family(&desc.name[..]);
+ for descriptor in descriptors {
+ if descriptor.style_name == desc.style {
+ // Found the font we want
+ let font = descriptor.to_font(size as _);
+ self.fonts.insert(desc.to_owned(), font.clone());
+ return Some(font);
+ }
+ }
+
+ None
+ }
+
+ pub fn get_glyph(&mut self, desc: &FontDesc, size: f32, c: char) -> RasterizedGlyph {
+ let scaled_size = self.device_pixel_ratio * size;
+ let glyph = self.get_font(desc, scaled_size).unwrap().get_glyph(c, scaled_size as _);
+
+ glyph
+ }
+}
+
+/// Specifies the intended rendering orientation of the font for obtaining glyph metrics
+#[derive(Debug)]
+pub enum FontOrientation {
+ Default = kCTFontDefaultOrientation as isize,
+ Horizontal = kCTFontHorizontalOrientation as isize,
+ Vertical = kCTFontVerticalOrientation as isize,
+}
+
+impl Default for FontOrientation {
+ fn default() -> FontOrientation {
+ FontOrientation::Default
+ }
+}
+
+/// A font
+#[derive(Debug, Clone)]
+pub struct Font {
+ ct_font: CTFont
+}
+
+unsafe impl Send for Font {}
+
+/// List all family names
+pub fn get_family_names() -> Vec<String> {
+ // CFArray of CFStringRef
+ let names = ct_get_family_names();
+ let mut owned_names = Vec::new();
+
+ for name in names.iter() {
+ let family: CFString = unsafe { TCFType::wrap_under_get_rule(name as CFStringRef) };
+ owned_names.push(format!("{}", family));
+ }
+
+ owned_names
+}
+
+/// Get descriptors for family name
+pub fn descriptors_for_family(family: &str) -> Vec<Descriptor> {
+ let mut out = Vec::new();
+
+ let ct_collection = match create_for_family(family) {
+ Some(c) => c,
+ None => return out,
+ };
+
+ // CFArray of CTFontDescriptorRef (i think)
+ let descriptors = ct_collection.get_descriptors();
+ for descriptor in descriptors.iter() {
+ let desc: CTFontDescriptor = unsafe {
+ TCFType::wrap_under_get_rule(descriptor as CTFontDescriptorRef)
+ };
+ out.push(Descriptor {
+ family_name: desc.family_name(),
+ font_name: desc.font_name(),
+ style_name: desc.style_name(),
+ display_name: desc.display_name(),
+ font_path: desc.font_path(),
+ ct_descriptor: desc,
+ });
+ }
+
+ out
+}
+
+impl Descriptor {
+ /// Create a Font from this descriptor
+ pub fn to_font(&self, pt_size: f64) -> Font {
+ let ct_font = ct_new_from_descriptor(&self.ct_descriptor, pt_size);
+ Font {
+ ct_font: ct_font
+ }
+ }
+}
+
+impl Deref for Font {
+ type Target = CTFont;
+
+ #[inline]
+ fn deref(&self) -> &Self::Target {
+ &self.ct_font
+ }
+}
+
+impl Font {
+ /// The the bounding rect of a glyph
+ pub fn bounding_rect_for_glyph(&self, orientation: FontOrientation, index: u32) -> Rect<f64> {
+ let cg_rect = self.ct_font.get_bounding_rects_for_glyphs(orientation as CTFontOrientation,
+ &[index as CGGlyph]);
+
+ Rect::new(
+ Point2D::new(cg_rect.origin.x, cg_rect.origin.y),
+ Size2D::new(cg_rect.size.width, cg_rect.size.height),
+ )
+ }
+
+ pub fn metrics(&self) -> Metrics {
+ let average_advance = self.glyph_advance('0');
+
+ let ascent = self.ct_font.ascent() as f64;
+ let descent = self.ct_font.descent() as f64;
+ let leading = self.ct_font.leading() as f64;
+ let line_height = (ascent + descent + leading + 0.5).floor();
+
+ Metrics {
+ average_advance: average_advance,
+ line_height: line_height,
+ }
+ }
+
+ fn glyph_advance(&self, character: char) -> f64 {
+ let index = self.glyph_index(character).unwrap();
+
+ let indices = [index as CGGlyph];
+
+ self.ct_font.get_advances_for_glyphs(FontOrientation::Default as _,
+ &indices[0],
+ ptr::null_mut(),
+ 1)
+ }
+
+ pub fn get_glyph(&self, character: char, size: f64) -> RasterizedGlyph {
+ let glyph_index = match self.glyph_index(character) {
+ Some(i) => i,
+ None => {
+ // TODO refactor this
+ return RasterizedGlyph {
+ c: ' ',
+ width: 0,
+ height: 0,
+ top: 0,
+ left: 0,
+ buf: Vec::new()
+ };
+ }
+ };
+
+ let bounds = self.bounding_rect_for_glyph(Default::default(), glyph_index);
+
+ let rasterized_left = bounds.origin.x.floor() as i32;
+ let rasterized_width =
+ (bounds.origin.x - (rasterized_left as f64) + bounds.size.width).ceil() as u32;
+ let rasterized_descent = (-bounds.origin.y).ceil() as i32;
+ let rasterized_ascent = (bounds.size.height + bounds.origin.y).ceil() as i32;
+ let rasterized_height = (rasterized_descent + rasterized_ascent) as u32;
+
+ if rasterized_width == 0 || rasterized_height == 0 {
+ return RasterizedGlyph {
+ c: ' ',
+ width: 0,
+ height: 0,
+ top: 0,
+ left: 0,
+ buf: Vec::new()
+ };
+ }
+
+ let mut cg_context = CGContext::create_bitmap_context(rasterized_width as usize,
+ rasterized_height as usize,
+ 8, // bits per component
+ rasterized_width as usize * 4,
+ &CGColorSpace::create_device_rgb(),
+ kCGImageAlphaNoneSkipFirst);
+
+ cg_context.set_allows_font_smoothing(true);
+ cg_context.set_should_smooth_fonts(true);
+ cg_context.set_allows_font_subpixel_quantization(true);
+ cg_context.set_should_subpixel_quantize_fonts(true);
+ cg_context.set_rgb_fill_color(1.0, 1.0, 1.0, 1.0);
+
+ let rasterization_origin = CGPoint {
+ x: -rasterized_left as f64,
+ y: rasterized_descent as f64,
+ };
+
+ self.ct_font.draw_glyphs(&[glyph_index as CGGlyph],
+ &[rasterization_origin],
+ cg_context.clone());
+
+ let rasterized_area = (rasterized_width * rasterized_height) as usize;
+ let rasterized_pixels = cg_context.data().to_vec();
+ let buf = rasterized_pixels.into_iter()
+ .enumerate()
+ .filter(|&(index, _)| (index % 4) != 0)
+ .map(|(_, val)| val)
+ .collect::<Vec<_>>();
+
+ RasterizedGlyph {
+ c: character,
+ left: rasterized_left,
+ top: (bounds.size.height + bounds.origin.y).ceil() as i32,
+ width: rasterized_width as i32,
+ height: rasterized_height as i32,
+ buf: buf,
+ }
+ }
+
+ fn glyph_index(&self, character: char) -> Option<u32> {
+ let chars = [character as UniChar];
+ let mut glyphs = [0 as CGGlyph];
+
+ let res = self.ct_font.get_glyphs_for_characters(&chars[0], &mut glyphs[0], 1 as CFIndex);
+
+ if res {
+ Some(glyphs[0] as u32)
+ } else {
+ None
+ }
+ }
+}
+
+/// Additional methods needed to render fonts for Alacritty
+///
+/// TODO upstream these into core_graphics crate
+trait CGContextExt {
+ fn set_allows_font_subpixel_quantization(&self, bool);
+ fn set_should_subpixel_quantize_fonts(&self, bool);
+}
+
+impl CGContextExt for CGContext {
+ fn set_allows_font_subpixel_quantization(&self, allows: bool) {
+ unsafe {
+ CGContextSetAllowsFontSubpixelQuantization(self.as_concrete_TypeRef(), allows);
+ }
+ }
+
+ fn set_should_subpixel_quantize_fonts(&self, should: bool) {
+ unsafe {
+ CGContextSetShouldSubpixelQuantizeFonts(self.as_concrete_TypeRef(), should);
+ }
+ }
+}
+
+#[link(name = "ApplicationServices", kind = "framework")]
+extern {
+ fn CGContextSetAllowsFontSubpixelQuantization(c: CGContextRef, allows: bool);
+ fn CGContextSetShouldSubpixelQuantizeFonts(c: CGContextRef, should: bool);
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn get_family_names() {
+ let names = super::get_family_names();
+ assert!(names.contains(&String::from("Menlo")));
+ assert!(names.contains(&String::from("Monaco")));
+ }
+
+ #[test]
+ fn get_descriptors_and_build_font() {
+ let list = super::descriptors_for_family("Menlo");
+ assert!(!list.is_empty());
+ println!("{:?}", list);
+
+ // Check to_font
+ let fonts = list.iter()
+ .map(|desc| desc.to_font(72.))
+ .collect::<Vec<_>>();
+
+ for font in fonts {
+ // Check deref
+ println!("family: {}", font.family_name());
+
+ // Get a glyph
+ for c in &['a', 'b', 'c', 'd'] {
+ let glyph = font.get_glyph(*c, 72.);
+
+ // Debug the glyph.. sigh
+ for row in 0..glyph.height {
+ for col in 0..glyph.width {
+ let index = ((glyph.width * 3 * row) + (col * 3)) as usize;
+ let value = glyph.buf[index];
+ let c = match value {
+ 0...50 => ' ',
+ 51...100 => '.',
+ 101...150 => '~',
+ 151...200 => '*',
+ 201...255 => '#',
+ _ => unreachable!()
+ };
+ print!("{}", c);
+ }
+ print!("\n");
+ }
+ }
+ }
+ }
+}
diff --git a/src/list_fonts.rs b/font/src/ft/list_fonts.rs
index f171f57e..f171f57e 100644
--- a/src/list_fonts.rs
+++ b/font/src/ft/list_fonts.rs
diff --git a/src/text.rs b/font/src/ft/mod.rs
index 5086a3a4..f288cda5 100644
--- a/src/text.rs
+++ b/font/src/ft/mod.rs
@@ -1,15 +1,20 @@
+//! Rasterization powered by FreeType and FontConfig
use std::collections::HashMap;
-use list_fonts::get_font_families;
use freetype::Library;
use freetype::Face;
use freetype;
+mod list_fonts;
+
+use self::list_fonts::{Family, get_font_families};
+use super::{FontDesc, RasterizedGlyph, Metrics};
+
/// Rasterizes glyphs for a single font face.
pub struct Rasterizer {
faces: HashMap<FontDesc, Face<'static>>,
library: Library,
- system_fonts: HashMap<String, ::list_fonts::Family>,
+ system_fonts: HashMap<String, Family>,
dpi_x: u32,
dpi_y: u32,
dpr: f32,
@@ -20,22 +25,10 @@ fn to_freetype_26_6(f: f32) -> isize {
((1i32 << 6) as f32 * f) as isize
}
-#[derive(Clone, PartialEq, Eq, Hash)]
-pub struct FontDesc {
- name: String,
- style: String,
-}
-
-impl FontDesc {
- pub fn new<S>(name: S, style: S) -> FontDesc
- where S: Into<String>
- {
- FontDesc {
- name: name.into(),
- style: style.into()
- }
- }
-}
+// #[inline]
+// fn freetype_26_6_to_float(val: i64) -> f64 {
+// val as f64 / (1i64 << 6) as f64
+// }
impl Rasterizer {
pub fn new(dpi_x: f32, dpi_y: f32, device_pixel_ratio: f32) -> Rasterizer {
@@ -51,22 +44,25 @@ impl Rasterizer {
}
}
- pub fn box_size_for_font(&mut self, desc: &FontDesc, size: f32) -> (u32, u32) {
+ pub fn metrics(&mut self, desc: &FontDesc, size: f32) -> Metrics {
let face = self.get_face(&desc).unwrap();
- let scale_size = self.dpr * size;
+ let scale_size = self.dpr as f64 * size as f64;
- let em_size = face.em_size() as f32;
- let w = face.max_advance_width() as f32;
- let h = face.height() as f32;
+ let em_size = face.em_size() as f64;
+ let w = face.max_advance_width() as f64;
+ let h = (face.ascender() - face.descender() + face.height()) as f64;
- let w_scale = w / em_size;
- let h_scale = h / em_size;
+ let w_scale = w * scale_size / em_size;
+ let h_scale = h * scale_size / em_size;
- ((w_scale * scale_size) as u32, (h_scale * scale_size) as u32)
+ Metrics {
+ average_advance: w_scale,
+ line_height: h_scale,
+ }
}
- pub fn get_face(&mut self, desc: &FontDesc) -> Option<Face<'static>> {
+ fn get_face(&mut self, desc: &FontDesc) -> Option<Face<'static>> {
if let Some(face) = self.faces.get(desc) {
return Some(face.clone());
}
@@ -118,22 +114,12 @@ impl Rasterizer {
}
}
-#[derive(Debug)]
-pub struct RasterizedGlyph {
- pub c: char,
- pub width: i32,
- pub height: i32,
- pub top: i32,
- pub left: i32,
- pub buf: Vec<u8>,
-}
-
+unsafe impl Send for Rasterizer {}
#[cfg(test)]
mod tests {
- use super::{Rasterizer, FontDesc};
+ use ::FontDesc;
- #[cfg(target_os = "linux")]
fn font_desc() -> FontDesc {
FontDesc::new("Ubuntu Mono", "Regular")
}
diff --git a/font/src/lib.rs b/font/src/lib.rs
new file mode 100644
index 00000000..ba632bee
--- /dev/null
+++ b/font/src/lib.rs
@@ -0,0 +1,94 @@
+//! Compatibility layer for different font engines
+//!
+//! This module is developed as part of Alacritty; Alacritty does not include Windows support
+//! as a goal at this time, and neither does this module.
+//!
+//! CoreText is used on Mac OS.
+//! FreeType is used on everything that's not Mac OS.
+
+#[cfg(not(target_os = "macos"))]
+extern crate fontconfig;
+#[cfg(not(target_os = "macos"))]
+extern crate freetype;
+#[cfg(not(target_os = "macos"))]
+extern crate libc;
+
+#[cfg(target_os = "macos")]
+extern crate core_text;
+#[cfg(target_os = "macos")]
+extern crate core_foundation;
+#[cfg(target_os = "macos")]
+extern crate core_foundation_sys;
+#[cfg(target_os = "macos")]
+extern crate core_graphics;
+
+extern crate euclid;
+
+use std::fmt;
+
+// If target isn't macos, reexport everything from ft
+#[cfg(not(target_os = "macos"))]
+mod ft;
+#[cfg(not(target_os = "macos"))]
+pub use ft::*;
+
+// If target is macos, reexport everything from darwin
+#[cfg(target_os = "macos")]
+mod darwin;
+#[cfg(target_os = "macos")]
+pub use darwin::*;
+
+#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct FontDesc {
+ name: String,
+ style: String,
+}
+
+impl FontDesc {
+ pub fn new<S>(name: S, style: S) -> FontDesc
+ where S: Into<String>
+ {
+ FontDesc {
+ name: name.into(),
+ style: style.into()
+ }
+ }
+}
+
+pub struct RasterizedGlyph {
+ pub c: char,
+ pub width: i32,
+ pub height: i32,
+ pub top: i32,
+ pub left: i32,
+ pub buf: Vec<u8>,
+}
+
+struct BufDebugger<'a>(&'a [u8]);
+
+impl<'a> fmt::Debug for BufDebugger<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("GlyphBuffer")
+ .field("len", &self.0.len())
+ .field("bytes", &self.0)
+ .finish()
+ }
+}
+
+impl fmt::Debug for RasterizedGlyph {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("RasterizedGlyph")
+ .field("c", &self.c)
+ .field("width", &self.width)
+ .field("height", &self.height)
+ .field("top", &self.top)
+ .field("left", &self.left)
+ .field("buf", &BufDebugger(&self.buf[..]))
+ .finish()
+ }
+}
+
+pub struct Metrics {
+ pub average_advance: f64,
+ pub line_height: f64,
+}
diff --git a/res/text.v.glsl b/res/text.v.glsl
index 0432babd..48d45eec 100644
--- a/res/text.v.glsl
+++ b/res/text.v.glsl
@@ -22,7 +22,6 @@ out vec3 bg;
// Terminal properties
uniform vec2 termDim;
uniform vec2 cellDim;
-uniform vec2 cellSep;
uniform int backgroundPass;
@@ -38,14 +37,14 @@ void main()
vec2 uvSize = uv.zw;
// Position of cell from top-left
- vec2 cellPosition = (cellDim + cellSep) * gridCoords;
+ vec2 cellPosition = (cellDim) * gridCoords;
// Invert Y since framebuffer origin is bottom-left
cellPosition.y = termDim.y - cellPosition.y - cellDim.y;
if (backgroundPass != 0) {
cellPosition.y = cellPosition.y - 3;
- vec2 finalPosition = (cellDim + cellSep) * position + cellPosition;
+ vec2 finalPosition = cellDim * position + cellPosition;
gl_Position = projection * vec4(finalPosition.xy, 0.0, 1.0);
TexCoords = vec2(0, 0);
} else {
diff --git a/src/grid.rs b/src/grid.rs
index 7a1fedb8..9ce16c81 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -9,10 +9,8 @@ use term::{Cursor, DEFAULT_FG, DEFAULT_BG};
use ::Rgb;
/// Calculate the number of cells for an axis
-pub fn num_cells_axis(cell_width: u32, cell_sep: i32, screen_width: u32) -> u32 {
- println!("num_cells_axis(cell_width: {}, cell_sep: {}, screen_width: {}",
- cell_width, cell_sep, screen_width);
- ((screen_width as i32 - cell_sep) as f64 / (cell_width as i32 + cell_sep) as f64) as u32
+pub fn num_cells_axis(cell_width: u32, screen_width: u32) -> u32 {
+ (screen_width as f64 / cell_width as f64) as u32
}
#[derive(Clone, Debug)]
diff --git a/src/main.rs b/src/main.rs
index f3808e0e..48f2df74 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,12 +5,12 @@
#![feature(io)]
#![feature(unicode)]
-extern crate fontconfig;
-extern crate freetype;
+extern crate font;
extern crate libc;
extern crate glutin;
extern crate cgmath;
extern crate notify;
+extern crate errno;
#[macro_use]
extern crate bitflags;
@@ -18,8 +18,6 @@ extern crate bitflags;
#[macro_use]
mod macros;
-mod list_fonts;
-mod text;
mod renderer;
pub mod grid;
mod meter;
@@ -36,7 +34,7 @@ use grid::Grid;
use meter::Meter;
use renderer::{QuadRenderer, GlyphCache};
use term::Term;
-use text::FontDesc;
+use font::FontDesc;
use tty::process_should_exit;
use util::thread;
@@ -115,41 +113,47 @@ pub struct TermProps {
height: f32,
cell_width: f32,
cell_height: f32,
- sep_x: f32,
- sep_y: f32,
}
-fn main() {
- let window = glutin::WindowBuilder::new()
- .with_title("alacritty".into())
- .build()
- .unwrap();
+#[cfg(target_os = "linux")]
+static FONT: &'static str = "DejaVu Sans Mono";
+#[cfg(target_os = "linux")]
+static FONT_STYLE: &'static str = "Book";
- let (width, height) = window.get_inner_size_pixels().unwrap();
- unsafe {
- window.make_current().unwrap();
- }
+#[cfg(target_os = "macos")]
+static FONT: &'static str = "Menlo";
+#[cfg(target_os = "macos")]
+static FONT_STYLE: &'static str = "Regular";
- unsafe {
- gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
- gl::Viewport(0, 0, width as i32, height as i32);
- }
- let (dpi_x, dpi_y) = window.get_dpi().unwrap();
+fn main() {
+
+ let window = glutin::WindowBuilder::new().build().unwrap();
+ window.set_title("Alacritty");
+ // window.set_window_resize_callback(Some(resize_callback as fn(u32, u32)));
+
+ gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
+ let (width, height) = window.get_inner_size_pixels().unwrap();
let dpr = window.hidpi_factor();
+ println!("device_pixel_ratio: {}", dpr);
+
let font_size = 11.;
- let sep_x = 2;
- let sep_y = 5;
+ let sep_x = 2.0;
+ let sep_y = -7.0;
- let desc = FontDesc::new("DejaVu Sans Mono", "Book");
- let mut rasterizer = text::Rasterizer::new(dpi_x, dpi_y, dpr);
+ let desc = FontDesc::new(FONT, FONT_STYLE);
+ let mut rasterizer = font::Rasterizer::new(96., 96., dpr);
- let (cell_width, cell_height) = rasterizer.box_size_for_font(&desc, font_size);
+ let metrics = rasterizer.metrics(&desc, font_size);
+ let cell_width = (metrics.average_advance + sep_x) as u32;
+ let cell_height = (metrics.line_height + sep_y) as u32;
- let num_cols = grid::num_cells_axis(cell_width, sep_x, width);
- let num_rows = grid::num_cells_axis(cell_height, sep_y, height);
+ println!("Cell Size: ({} x {})", cell_width, cell_height);
+
+ let num_cols = grid::num_cells_axis(cell_width, width);
+ let num_rows = grid::num_cells_axis(cell_height, height);
let tty = tty::new(num_rows as u8, num_cols as u8);
tty.resize(num_rows as usize, num_cols as usize, width as usize, height as usize);
@@ -162,25 +166,13 @@ fn main() {
let props = TermProps {
cell_width: cell_width as f32,
- sep_x: sep_x as f32,
cell_height: cell_height as f32,
- sep_y: sep_y as f32,
height: height as f32,
width: width as f32,
};
- let mut renderer = QuadRenderer::new(width, height);
-
let mut glyph_cache = GlyphCache::new(rasterizer, desc, font_size);
- renderer.with_api(&props, |mut api| {
- glyph_cache.init(&mut api);
- });
- unsafe {
- gl::Enable(gl::BLEND);
- gl::BlendFunc(gl::SRC1_COLOR, gl::ONE_MINUS_SRC1_COLOR);
- gl::Enable(gl::MULTISAMPLE);
- }
let (tx, rx) = mpsc::channel();
let reader_tx = tx.clone();
@@ -198,83 +190,98 @@ fn main() {
let window = Arc::new(window);
let window_ref = window.clone();
- let input_thread = thread::spawn_named("Input Thread", move || {
- for event in window_ref.wait_events() {
- tx.send(Event::Glutin(event)).unwrap();
- if process_should_exit() {
- break;
- }
+ let render_thread = thread::spawn_named("Galaxy", move || {
+ let _ = unsafe { window.make_current() };
+ unsafe {
+ gl::Viewport(0, 0, width as i32, height as i32);
+ gl::Enable(gl::BLEND);
+ gl::BlendFunc(gl::SRC1_COLOR, gl::ONE_MINUS_SRC1_COLOR);
+ gl::Enable(gl::MULTISAMPLE);
}
- });
- 'main_loop: loop {
- {
- let mut writer = BufWriter::new(&writer);
+ let mut renderer = QuadRenderer::new(width, height);
+ renderer.with_api(&props, |mut api| {
+ glyph_cache.init(&mut api);
+ });
- // Block waiting for next event
- match rx.recv() {
- Ok(e) => {
- let res = handle_event(e, &mut writer, &mut terminal, &mut pty_parser);
- if res == ShouldExit::Yes {
- break;
- }
- },
- Err(mpsc::RecvError) => break,
- }
+ 'main_loop: loop {
+ {
+ let mut writer = BufWriter::new(&writer);
- // Handle Any events that have been queued
- loop {
- match rx.try_recv() {
+ // Block waiting for next event
+ match rx.recv() {
Ok(e) => {
let res = handle_event(e, &mut writer, &mut terminal, &mut pty_parser);
-
if res == ShouldExit::Yes {
break;
}
},
- Err(mpsc::TryRecvError::Disconnected) => break 'main_loop,
- Err(mpsc::TryRecvError::Empty) => break,
+ Err(mpsc::RecvError) => break,
}
- // TODO make sure this doesn't block renders
+ // Handle Any events that have been queued
+ loop {
+ match rx.try_recv() {
+ Ok(e) => {
+ let res = handle_event(e, &mut writer, &mut terminal, &mut pty_parser);
+
+ if res == ShouldExit::Yes {
+ break;
+ }
+ },
+ Err(mpsc::TryRecvError::Disconnected) => break 'main_loop,
+ Err(mpsc::TryRecvError::Empty) => break,
+ }
+
+ // TODO make sure this doesn't block renders
+ }
}
- }
- unsafe {
- gl::ClearColor(0.0, 0.0, 0.00, 1.0);
- gl::Clear(gl::COLOR_BUFFER_BIT);
- }
+ unsafe {
+ gl::ClearColor(0.0, 0.0, 0.00, 1.0);
+ gl::Clear(gl::COLOR_BUFFER_BIT);
+ }
- {
- let _sampler = meter.sampler();
+ {
+ let _sampler = meter.sampler();
- renderer.with_api(&props, |mut api| {
- // Draw the grid
- api.render_grid(terminal.grid(), &mut glyph_cache);
+ renderer.with_api(&props, |mut api| {
+ // Draw the grid
+ api.render_grid(terminal.grid(), &mut glyph_cache);
- // Also draw the cursor
- if !terminal.mode().contains(term::mode::TEXT_CURSOR) {
- api.render_cursor(terminal.cursor(), &mut glyph_cache);
- }
- })
- }
+ // Also draw the cursor
+ if !terminal.mode().contains(term::mode::TEXT_CURSOR) {
+ api.render_cursor(terminal.cursor(), &mut glyph_cache);
+ }
+ })
+ }
- // Draw render timer
- let timing = format!("{:.3} usec", meter.average());
- let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 };
- renderer.with_api(&props, |mut api| {
- api.render_string(&timing[..], &mut glyph_cache, &color);
- });
+ // Draw render timer
+ let timing = format!("{:.3} usec", meter.average());
+ let color = Rgb { r: 0xd5, g: 0x4e, b: 0x53 };
+ renderer.with_api(&props, |mut api| {
+ api.render_string(&timing[..], &mut glyph_cache, &color);
+ });
- window.swap_buffers().unwrap();
+ window.swap_buffers().unwrap();
+
+ if process_should_exit() {
+ break 'main_loop;
+ }
+ }
+ });
- if process_should_exit() {
- break;
+ 'event_processing: loop {
+ for event in window_ref.wait_events() {
+ tx.send(Event::Glutin(event)).unwrap();
+ if process_should_exit() {
+ break 'event_processing;
+ }
}
}
reader_thread.join().ok();
- input_thread.join().ok();
+ render_thread.join().ok();
println!("Goodbye");
}
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index a0051aaa..dff20070 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -13,7 +13,7 @@ use gl::types::*;
use gl;
use notify::{Watcher as WatcherApi, RecommendedWatcher as Watcher, op};
-use text::{Rasterizer, RasterizedGlyph, FontDesc};
+use font::{Rasterizer, RasterizedGlyph, FontDesc};
use grid::{self, Grid, Cell, CellFlags};
use term;
@@ -45,9 +45,6 @@ pub struct ShaderProgram {
/// Cell dimensions (pixels)
u_cell_dim: GLint,
- /// Cell separation (pixels)
- u_cell_sep: GLint,
-
/// Background pass flag
///
/// Rendering is split into two passes; 1 for backgrounds, and one for text
@@ -649,24 +646,22 @@ impl ShaderProgram {
}
// get uniform locations
- let (projection, term_dim, cell_dim, cell_sep, background) = unsafe {
+ let (projection, term_dim, cell_dim, background) = unsafe {
(
gl::GetUniformLocation(program, cptr!(b"projection\0")),
gl::GetUniformLocation(program, cptr!(b"termDim\0")),
gl::GetUniformLocation(program, cptr!(b"cellDim\0")),
- gl::GetUniformLocation(program, cptr!(b"cellSep\0")),
gl::GetUniformLocation(program, cptr!(b"backgroundPass\0")),
)
};
- assert_uniform_valid!(projection, term_dim, cell_dim, cell_sep);
+ assert_uniform_valid!(projection, term_dim, cell_dim);
let shader = ShaderProgram {
id: program,
u_projection: projection,
u_term_dim: term_dim,
u_cell_dim: cell_dim,
- u_cell_sep: cell_sep,
u_background: background,
};
@@ -690,7 +685,6 @@ impl ShaderProgram {
unsafe {
gl::Uniform2f(self.u_term_dim, props.width, props.height);
gl::Uniform2f(self.u_cell_dim, props.cell_width, props.cell_height);
- gl::Uniform2f(self.u_cell_sep, props.sep_x, props.sep_y);
}
}
diff --git a/src/tty.rs b/src/tty.rs
index 89975b43..a653d9ab 100644
--- a/src/tty.rs
+++ b/src/tty.rs
@@ -47,9 +47,7 @@ pub fn process_should_exit() -> bool {
/// Get the current value of errno
fn errno() -> c_int {
- unsafe {
- ptr::read(libc::__errno_location() as *const _)
- }
+ ::errno::errno().0
}
enum Relation {
@@ -74,6 +72,7 @@ fn fork() -> Relation {
}
/// Get raw fds for master/slave ends of a new pty
+#[cfg(target_os = "linux")]
fn openpty(rows: u8, cols: u8) -> (c_int, c_int) {
let mut master: c_int = 0;
let mut slave: c_int = 0;
@@ -96,10 +95,33 @@ fn openpty(rows: u8, cols: u8) -> (c_int, c_int) {
(master, slave)
}
+#[cfg(target_os = "macos")]
+fn openpty(rows: u8, cols: u8) -> (c_int, c_int) {
+ let mut master: c_int = 0;
+ let mut slave: c_int = 0;
+
+ let mut win = winsize {
+ ws_row: rows as libc::c_ushort,
+ ws_col: cols as libc::c_ushort,
+ ws_xpixel: 0,
+ ws_ypixel: 0,
+ };
+
+ let res = unsafe {
+ libc::openpty(&mut master, &mut slave, ptr::null_mut(), ptr::null_mut(), &mut win)
+ };
+
+ if res < 0 {
+ die!("openpty failed");
+ }
+
+ (master, slave)
+}
+
/// Really only needed on BSD, but should be fine elsewhere
fn set_controlling_terminal(fd: c_int) {
let res = unsafe {
- libc::ioctl(fd, libc::TIOCSCTTY, 0)
+ libc::ioctl(fd, libc::TIOCSCTTY as _, 0)
};
if res < 0 {
@@ -125,15 +147,7 @@ struct Passwd<'a> {
/// If `buf` is changed while `Passwd` is alive, bad thing will almost certainly happen.
fn get_pw_entry<'a>(buf: &'a mut [i8; 1024]) -> Passwd<'a> {
// Create zeroed passwd struct
- let mut entry = libc::passwd {
- pw_name: ptr::null_mut(),
- pw_passwd: ptr::null_mut(),
- pw_uid: 0,
- pw_gid: 0,
- pw_gecos: ptr::null_mut(),
- pw_dir: ptr::null_mut(),
- pw_shell: ptr::null_mut(),
- };
+ let mut entry: libc::passwd = unsafe { ::std::mem::uninitialized() };
let mut res: *mut libc::passwd = ptr::null_mut();