Implement basic text rendering in canvas with `skribo` and `font-kit`.

Skribo currently writes some debugging info to standard output. A patch is
forthcoming to fix that.
This commit is contained in:
Patrick Walton 2019-05-09 12:29:39 -07:00
parent ebdb12404a
commit a078766dc6
10 changed files with 661 additions and 18 deletions

223
Cargo.lock generated
View File

@ -170,6 +170,20 @@ dependencies = [
"sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)", "sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "canvas_text"
version = "0.1.0"
dependencies = [
"gl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_canvas 0.1.0",
"pathfinder_geometry 0.3.0",
"pathfinder_gl 0.1.0",
"pathfinder_gpu 0.1.0",
"pathfinder_renderer 0.1.0",
"sdl2 0.32.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sdl2-sys 0.32.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.29" version = "1.0.29"
@ -226,6 +240,14 @@ dependencies = [
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "cmake"
version = "0.1.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cocoa" name = "cocoa"
version = "0.18.4" version = "0.18.4"
@ -296,6 +318,17 @@ dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "core-text"
version = "13.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.1.2" version = "1.1.2"
@ -403,6 +436,18 @@ name = "downcast-rs"
version = "1.0.4" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "dwrote"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "egl" name = "egl"
version = "0.2.7" version = "0.2.7"
@ -468,6 +513,15 @@ dependencies = [
"syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "expat-sys"
version = "2.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "failure" name = "failure"
version = "0.1.5" version = "0.1.5"
@ -501,6 +555,40 @@ dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "float-ord"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "font-kit"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"float-ord 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "foreign-types" name = "foreign-types"
version = "0.3.2" version = "0.3.2"
@ -514,6 +602,15 @@ name = "foreign-types-shared"
version = "0.1.1" version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "freetype"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "fs_extra" name = "fs_extra"
version = "1.1.0" version = "1.1.0"
@ -615,6 +712,27 @@ dependencies = [
"x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)", "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "harfbuzz"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"harfbuzz-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "harfbuzz-sys"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.1.8" version = "0.1.8"
@ -672,6 +790,14 @@ dependencies = [
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "itertools"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.3" version = "0.4.3"
@ -827,6 +953,14 @@ dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "lyon_path"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lyon_geom 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "lzw" name = "lzw"
version = "0.10.0" version = "0.10.0"
@ -853,6 +987,15 @@ name = "memchr"
version = "2.2.0" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memmap"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "memmap" name = "memmap"
version = "0.7.0" version = "0.7.0"
@ -1031,8 +1174,11 @@ dependencies = [
name = "pathfinder_canvas" name = "pathfinder_canvas"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"font-kit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_geometry 0.3.0", "pathfinder_geometry 0.3.0",
"pathfinder_renderer 0.1.0", "pathfinder_renderer 0.1.0",
"pathfinder_text 0.1.0",
"skribo 0.0.1 (git+https://github.com/linebender/skribo.git?rev=f759c2d2c188b668bce998179f03b6319835353e)",
] ]
[[package]] [[package]]
@ -1149,6 +1295,18 @@ dependencies = [
"usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "usvg 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "pathfinder_text"
version = "0.1.0"
dependencies = [
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"font-kit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pathfinder_geometry 0.3.0",
"pathfinder_renderer 0.1.0",
"skribo 0.0.1 (git+https://github.com/linebender/skribo.git?rev=f759c2d2c188b668bce998179f03b6319835353e)",
]
[[package]] [[package]]
name = "pathfinder_ui" name = "pathfinder_ui"
version = "0.1.0" version = "0.1.0"
@ -1601,6 +1759,34 @@ dependencies = [
"serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "servo-fontconfig"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-fontconfig-sys 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "servo-fontconfig-sys"
version = "4.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "servo-freetype-sys"
version = "4.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "shared_library" name = "shared_library"
version = "0.1.9" version = "0.1.9"
@ -1620,6 +1806,18 @@ name = "siphasher"
version = "0.2.3" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "skribo"
version = "0.0.1"
source = "git+https://github.com/linebender/skribo.git?rev=f759c2d2c188b668bce998179f03b6319835353e#f759c2d2c188b668bce998179f03b6319835353e"
dependencies = [
"euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
"font-kit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"harfbuzz 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"harfbuzz-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.2" version = "0.4.2"
@ -1789,6 +1987,14 @@ name = "ucd-util"
version = "0.1.3" version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-normalization"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.2.1" version = "1.2.1"
@ -2038,6 +2244,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
"checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b" "checksum cocoa 0.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf79daa4e11e5def06e55306aa3601b87de6b5149671529318da048f67cdd77b"
"checksum color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "90242aff9b6439332beb77ee416126367adcd6376b0dc80b39250e7debdd913d" "checksum color-backtrace 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "90242aff9b6439332beb77ee416126367adcd6376b0dc80b39250e7debdd913d"
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" "checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
@ -2046,6 +2253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" "checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
"checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
"checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" "checksum core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)" = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9"
"checksum core-text 13.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d95a72b5e50e549969dd88eff3047495fe5b8c6f028635442c2b708be707e669"
"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" "checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192"
"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" "checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
@ -2056,6 +2264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" "checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
"checksum downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b92dfd5c2f75260cbf750572f95d387e7ca0ba5e3fbe9e1a33f23025be020f" "checksum downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b92dfd5c2f75260cbf750572f95d387e7ca0ba5e3fbe9e1a33f23025be020f"
"checksum dwrote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "30a998e9ff70cd208ccdc4f864e998688bf61d7b897dccec8e17a884d17358bf"
"checksum egl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a373bc9844200b1ff15bd1b245931d1c20d09d06e4ec09f361171f29a4b0752d" "checksum egl 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a373bc9844200b1ff15bd1b245931d1c20d09d06e4ec09f361171f29a4b0752d"
"checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
"checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
@ -2063,12 +2272,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" "checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02"
"checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea" "checksum euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a7698bdda3d7444a79d33bdc96e8b518d44ea3ff101d8492a6ca1207b886ea"
"checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15" "checksum euclid_macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
"checksum expat-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600" "checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
"checksum float-ord 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e"
"checksum font-kit 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5be0133b580e2920076afd5bd4b81dc172d10e5653bd1c516476718d52347859"
"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
"checksum freetype 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "11926b2b410b469d0e9399eca4cbbe237a9ef02176c485803b29216307e8e028"
"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674" "checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" "checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
@ -2079,11 +2292,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d" "checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d"
"checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5" "checksum gleam 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "39bb69499005e11b7b7cc0af38404a1bc0f53d954bffa8adcdb6e8d5b14f75d5"
"checksum glutin 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "535c6eda58adbb227604b2db10a022ffd6339d7ea3e970f338e7d98aeb24fcc3" "checksum glutin 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "535c6eda58adbb227604b2db10a022ffd6339d7ea3e970f338e7d98aeb24fcc3"
"checksum harfbuzz 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46f7426266a5ece3e49eae6f48e602c0f8c39917354a847eac9c06437dcde8da"
"checksum harfbuzz-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e1042ab0b3e7bc1ff64f7f5935778b644ff2194a1cae5ec52167127d3fd23961"
"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da" "checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114"
"checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a" "checksum image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebdff791af04e30089bde8ad2a632b86af433b40c04db8d70ad4b21487db7a6a"
"checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d" "checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d"
"checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" "checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae" "checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
"checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3" "checksum jemallocator 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9f0cd42ac65f758063fea55126b0148b1ce0a6354ff78e07a4d6806bc65c4ab3"
@ -2104,10 +2320,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
"checksum lyon_geom 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2b60eaa9061c87affcd671e88289ce6971324269ec6548b677e02624ef3ef63c" "checksum lyon_geom 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2b60eaa9061c87affcd671e88289ce6971324269ec6548b677e02624ef3ef63c"
"checksum lyon_path 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9dc8e0746b7cca11960b602f7fe037bb067746a01eab4aa502fed1494544843"
"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
"checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" "checksum malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" "checksum memmap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98" "checksum nfd 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e752e3c216bc8a491c5b59fa46da10f1379ae450b19ac688e07f4bb55042e98"
@ -2180,9 +2398,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850" "checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850"
"checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4" "checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4"
"checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" "checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9"
"checksum servo-fontconfig 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
"checksum servo-fontconfig-sys 4.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b46d201addcfbd25c1798ad1281d98c40743824e0b0f1e611bd3d5d0d31a7b8d"
"checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
"checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" "checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
"checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e" "checksum simplecss 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "135685097a85a64067df36e28a243e94a94f76d829087ce0be34eeb014260c0e"
"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
"checksum skribo 0.0.1 (git+https://github.com/linebender/skribo.git?rev=f759c2d2c188b668bce998179f03b6319835353e)" = "<none>"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" "checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be"
"checksum smithay-client-toolkit 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4899558362a65589b53313935099835acf999740915e134dff20cca7c6a28b" "checksum smithay-client-toolkit 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4899558362a65589b53313935099835acf999740915e134dff20cca7c6a28b"
@ -2202,6 +2424,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"

View File

@ -6,12 +6,14 @@ members = [
"demo/magicleap", "demo/magicleap",
"demo/native", "demo/native",
"examples/canvas_minimal", "examples/canvas_minimal",
"examples/canvas_text",
"geometry", "geometry",
"gl", "gl",
"gpu", "gpu",
"renderer", "renderer",
"simd", "simd",
"svg", "svg",
"text",
"ui", "ui",
"utils/area-lut", "utils/area-lut",
"utils/gamma-lut", "utils/gamma-lut",

View File

@ -5,9 +5,17 @@ authors = ["Patrick Walton <pcwalton@mimiga.net>"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
font-kit = "0.1"
[dependencies.pathfinder_geometry] [dependencies.pathfinder_geometry]
path = "../geometry" path = "../geometry"
[dependencies.pathfinder_renderer] [dependencies.pathfinder_renderer]
path = "../renderer" path = "../renderer"
[dependencies.pathfinder_text]
path = "../text"
[dependencies.skribo]
git = "https://github.com/linebender/skribo.git"
rev = "f759c2d2c188b668bce998179f03b6319835353e"

View File

@ -10,21 +10,35 @@
//! A simple API for Pathfinder that mirrors a subset of HTML canvas. //! A simple API for Pathfinder that mirrors a subset of HTML canvas.
use font_kit::family_name::FamilyName;
use font_kit::hinting::HintingOptions;
use font_kit::properties::Properties;
use font_kit::source::SystemSource;
use pathfinder_geometry::basic::point::Point2DF32; use pathfinder_geometry::basic::point::Point2DF32;
use pathfinder_geometry::basic::rect::RectF32; use pathfinder_geometry::basic::rect::RectF32;
use pathfinder_geometry::basic::transform2d::Transform2DF32;
use pathfinder_geometry::color::ColorU; use pathfinder_geometry::color::ColorU;
use pathfinder_geometry::outline::{Contour, Outline}; use pathfinder_geometry::outline::{Contour, Outline};
use pathfinder_geometry::stroke::OutlineStrokeToFill; use pathfinder_geometry::stroke::OutlineStrokeToFill;
use pathfinder_renderer::scene::{Paint, PathObject, Scene}; use pathfinder_renderer::scene::{Paint, PathObject, Scene};
use pathfinder_text::{SceneExt, TextRenderMode};
use skribo::{FontCollection, FontFamily, TextStyle};
use std::default::Default; use std::default::Default;
use std::mem; use std::mem;
use std::sync::Arc;
const HAIRLINE_STROKE_WIDTH: f32 = 0.0333; const HAIRLINE_STROKE_WIDTH: f32 = 0.0333;
const DEFAULT_FONT_SIZE: f32 = 10.0;
pub struct CanvasRenderingContext2D { pub struct CanvasRenderingContext2D {
scene: Scene, scene: Scene,
current_state: State, current_state: State,
saved_states: Vec<State>, saved_states: Vec<State>,
#[allow(dead_code)]
font_source: SystemSource,
#[allow(dead_code)]
default_font_collection: Arc<FontCollection>,
} }
impl CanvasRenderingContext2D { impl CanvasRenderingContext2D {
@ -35,9 +49,27 @@ impl CanvasRenderingContext2D {
CanvasRenderingContext2D::from_scene(scene) CanvasRenderingContext2D::from_scene(scene)
} }
#[inline]
pub fn from_scene(scene: Scene) -> CanvasRenderingContext2D { pub fn from_scene(scene: Scene) -> CanvasRenderingContext2D {
CanvasRenderingContext2D { scene, current_state: State::default(), saved_states: vec![] } // TODO(pcwalton): Allow the user to cache this?
let font_source = SystemSource::new();
let mut default_font_collection = FontCollection::new();
let default_font =
font_source.select_best_match(&[FamilyName::SansSerif], &Properties::new())
.expect("Failed to select the default font!")
.load()
.expect("Failed to load the default font!");
default_font_collection.add_family(FontFamily::new_from_font(default_font));
let default_font_collection = Arc::new(default_font_collection);
CanvasRenderingContext2D {
scene,
current_state: State::default(default_font_collection.clone()),
saved_states: vec![],
font_source,
default_font_collection,
}
} }
#[inline] #[inline]
@ -59,6 +91,32 @@ impl CanvasRenderingContext2D {
self.stroke_path(path); self.stroke_path(path);
} }
pub fn fill_text(&mut self, string: &str, position: Point2DF32) {
// TODO(pcwalton): Report errors.
let paint_id = self.scene.push_paint(&self.current_state.fill_paint);
drop(self.scene.push_text(string,
&TextStyle { size: self.current_state.font_size },
&self.current_state.font_collection,
&Transform2DF32::from_translation(&position),
TextRenderMode::Fill,
HintingOptions::None,
paint_id));
}
pub fn stroke_text(&mut self, string: &str, position: Point2DF32) {
// TODO(pcwalton): Report errors.
let paint_id = self.scene.push_paint(&self.current_state.stroke_paint);
drop(self.scene.push_text(string,
&TextStyle { size: self.current_state.font_size },
&self.current_state.font_collection,
&Transform2DF32::from_translation(&position),
TextRenderMode::Stroke(self.current_state.line_width),
HintingOptions::None,
paint_id));
}
// Line styles
#[inline] #[inline]
pub fn set_line_width(&mut self, new_line_width: f32) { pub fn set_line_width(&mut self, new_line_width: f32) {
self.current_state.line_width = new_line_width self.current_state.line_width = new_line_width
@ -74,6 +132,15 @@ impl CanvasRenderingContext2D {
self.current_state.stroke_paint = new_stroke_style.to_paint(); self.current_state.stroke_paint = new_stroke_style.to_paint();
} }
// Text styles
#[inline]
pub fn set_font_size(&mut self, new_font_size: f32) {
self.current_state.font_size = new_font_size;
}
// Paths
#[inline] #[inline]
pub fn fill_path(&mut self, path: Path2D) { pub fn fill_path(&mut self, path: Path2D) {
let paint_id = self.scene.push_paint(&self.current_state.fill_paint); let paint_id = self.scene.push_paint(&self.current_state.fill_paint);
@ -91,7 +158,7 @@ impl CanvasRenderingContext2D {
#[inline] #[inline]
pub fn save(&mut self) { pub fn save(&mut self) {
self.saved_states.push(self.current_state); self.saved_states.push(self.current_state.clone());
} }
#[inline] #[inline]
@ -102,17 +169,20 @@ impl CanvasRenderingContext2D {
} }
} }
#[derive(Clone, Copy)] #[derive(Clone)]
pub struct State { pub struct State {
font_collection: Arc<FontCollection>,
font_size: f32,
fill_paint: Paint, fill_paint: Paint,
stroke_paint: Paint, stroke_paint: Paint,
line_width: f32, line_width: f32,
} }
impl Default for State { impl State {
#[inline] fn default(default_font_collection: Arc<FontCollection>) -> State {
fn default() -> State {
State { State {
font_collection: default_font_collection,
font_size: DEFAULT_FONT_SIZE,
fill_paint: Paint { color: ColorU::black() }, fill_paint: Paint { color: ColorU::black() },
stroke_paint: Paint { color: ColorU::black() }, stroke_paint: Paint { color: ColorU::black() },
line_width: 1.0, line_width: 1.0,

View File

@ -0,0 +1,25 @@
[package]
name = "canvas_text"
version = "0.1.0"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
edition = "2018"
[dependencies]
gl = "0.6"
sdl2 = "0.32"
sdl2-sys = "0.32"
[dependencies.pathfinder_canvas]
path = "../../canvas"
[dependencies.pathfinder_geometry]
path = "../../geometry"
[dependencies.pathfinder_gl]
path = "../../gl"
[dependencies.pathfinder_gpu]
path = "../../gpu"
[dependencies.pathfinder_renderer]
path = "../../renderer"

View File

@ -0,0 +1,77 @@
// pathfinder/canvas_text/src/main.rs
//
// Copyright © 2019 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use pathfinder_canvas::{CanvasRenderingContext2D, Path2D};
use pathfinder_geometry::basic::point::{Point2DF32, Point2DI32};
use pathfinder_geometry::basic::rect::RectF32;
use pathfinder_geometry::color::ColorF;
use pathfinder_gl::{GLDevice, GLVersion};
use pathfinder_gpu::resources::FilesystemResourceLoader;
use pathfinder_gpu::{ClearParams, Device};
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
use pathfinder_renderer::concurrent::scene_proxy::SceneProxy;
use pathfinder_renderer::gpu::renderer::{DestFramebuffer, Renderer};
use pathfinder_renderer::options::RenderOptions;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::video::GLProfile;
fn main() {
// Set up SDL2.
let sdl_context = sdl2::init().unwrap();
let video = sdl_context.video().unwrap();
// Make sure we have at least a GL 3.0 context. Pathfinder requires this.
let gl_attributes = video.gl_attr();
gl_attributes.set_context_profile(GLProfile::Core);
gl_attributes.set_context_version(3, 3);
// Open a window.
let window_size = Point2DI32::new(640, 480);
let window = video.window("Text example", window_size.x() as u32, window_size.y() as u32)
.opengl()
.build()
.unwrap();
// Create the GL context, and make it current.
let gl_context = window.gl_create_context().unwrap();
gl::load_with(|name| video.gl_get_proc_address(name) as *const _);
window.gl_make_current(&gl_context).unwrap();
// Create a Pathfinder renderer.
let mut renderer = Renderer::new(GLDevice::new(GLVersion::GL3, 0),
&FilesystemResourceLoader::locate(),
DestFramebuffer::full_window(window_size));
// Clear to white.
renderer.device.clear(&ClearParams { color: Some(ColorF::white()), ..ClearParams::default() });
// Make a canvas. We're going to draw some text.
let mut canvas = CanvasRenderingContext2D::new(window_size.to_f32());
// Draw the text.
canvas.set_font_size(32.0);
canvas.fill_text("Hello Pathfinder!", Point2DF32::new(32.0, 48.0));
canvas.stroke_text("Goodbye Pathfinder!", Point2DF32::new(32.0, 96.0));
// Render the canvas to screen.
let scene = SceneProxy::new(canvas.into_scene(), RayonExecutor);
scene.build_and_render(&mut renderer, RenderOptions::default());
window.gl_swap_window();
// Wait for a keypress.
let mut event_pump = sdl_context.event_pump().unwrap();
loop {
match event_pump.wait_event() {
Event::Quit {..} | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => return,
_ => {}
}
}
}

View File

@ -51,7 +51,7 @@ impl Segment {
Segment { Segment {
baseline: *baseline, baseline: *baseline,
ctrl: LineSegmentF32::new(ctrl, &Point2DF32::default()), ctrl: LineSegmentF32::new(ctrl, &Point2DF32::default()),
kind: SegmentKind::Cubic, kind: SegmentKind::Quadratic,
flags: SegmentFlags::empty(), flags: SegmentFlags::empty(),
} }
} }
@ -111,6 +111,7 @@ impl Segment {
new_segment.ctrl = new_segment.ctrl =
LineSegmentF32::new(&(self.baseline.from() + p1_2), &(p1_2 + self.baseline.to())) LineSegmentF32::new(&(self.baseline.from() + p1_2), &(p1_2 + self.baseline.to()))
.scale(1.0 / 3.0); .scale(1.0 / 3.0);
new_segment.kind = SegmentKind::Cubic;
new_segment new_segment
} }

View File

@ -13,7 +13,7 @@
use crate::basic::line_segment::LineSegmentF32; use crate::basic::line_segment::LineSegmentF32;
use crate::basic::rect::RectF32; use crate::basic::rect::RectF32;
use crate::outline::{Contour, Outline}; use crate::outline::{Contour, Outline};
use crate::segment::Segment as SegmentPF3; use crate::segment::Segment;
use std::mem; use std::mem;
const TOLERANCE: f32 = 0.01; const TOLERANCE: f32 = 0.01;
@ -88,10 +88,10 @@ impl ContourStrokeToFill {
trait Offset { trait Offset {
fn offset(&self, distance: f32, contour: &mut Contour); fn offset(&self, distance: f32, contour: &mut Contour);
fn offset_once(&self, distance: f32) -> Self; fn offset_once(&self, distance: f32) -> Self;
fn error_is_within_tolerance(&self, other: &SegmentPF3, distance: f32) -> bool; fn error_is_within_tolerance(&self, other: &Segment, distance: f32) -> bool;
} }
impl Offset for SegmentPF3 { impl Offset for Segment {
fn offset(&self, distance: f32, contour: &mut Contour) { fn offset(&self, distance: f32, contour: &mut Contour) {
if self.baseline.square_length() < TOLERANCE * TOLERANCE { if self.baseline.square_length() < TOLERANCE * TOLERANCE {
contour.push_full_segment(self, true); contour.push_full_segment(self, true);
@ -112,9 +112,9 @@ impl Offset for SegmentPF3 {
after.offset(distance, contour); after.offset(distance, contour);
} }
fn offset_once(&self, distance: f32) -> SegmentPF3 { fn offset_once(&self, distance: f32) -> Segment {
if self.is_line() { if self.is_line() {
return SegmentPF3::line(&self.baseline.offset(distance)); return Segment::line(&self.baseline.offset(distance));
} }
if self.is_quadratic() { if self.is_quadratic() {
@ -127,7 +127,7 @@ impl Offset for SegmentPF3 {
None => segment_0.to().lerp(segment_1.from(), 0.5), None => segment_0.to().lerp(segment_1.from(), 0.5),
}; };
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to()); let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to());
return SegmentPF3::quadratic(&baseline, &ctrl); return Segment::quadratic(&baseline, &ctrl);
} }
debug_assert!(self.is_cubic()); debug_assert!(self.is_cubic());
@ -143,7 +143,7 @@ impl Offset for SegmentPF3 {
}; };
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to()); let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to());
let ctrl = LineSegmentF32::new(&segment_0.from(), &ctrl); let ctrl = LineSegmentF32::new(&segment_0.from(), &ctrl);
return SegmentPF3::cubic(&baseline, &ctrl); return Segment::cubic(&baseline, &ctrl);
} }
if self.ctrl.to() == self.baseline.to() { if self.ctrl.to() == self.baseline.to() {
@ -157,7 +157,7 @@ impl Offset for SegmentPF3 {
}; };
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to()); let baseline = LineSegmentF32::new(&segment_0.from(), &segment_1.to());
let ctrl = LineSegmentF32::new(&ctrl, &segment_1.to()); let ctrl = LineSegmentF32::new(&ctrl, &segment_1.to());
return SegmentPF3::cubic(&baseline, &ctrl); return Segment::cubic(&baseline, &ctrl);
} }
let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from()); let mut segment_0 = LineSegmentF32::new(&self.baseline.from(), &self.ctrl.from());
@ -178,10 +178,10 @@ impl Offset for SegmentPF3 {
}; };
let baseline = LineSegmentF32::new(&segment_0.from(), &segment_2.to()); let baseline = LineSegmentF32::new(&segment_0.from(), &segment_2.to());
let ctrl = LineSegmentF32::new(&ctrl_0, &ctrl_1); let ctrl = LineSegmentF32::new(&ctrl_0, &ctrl_1);
SegmentPF3::cubic(&baseline, &ctrl) Segment::cubic(&baseline, &ctrl)
} }
fn error_is_within_tolerance(&self, other: &SegmentPF3, distance: f32) -> bool { fn error_is_within_tolerance(&self, other: &Segment, distance: f32) -> bool {
let (mut min, mut max) = ( let (mut min, mut max) = (
f32::abs(distance) - TOLERANCE, f32::abs(distance) - TOLERANCE,
f32::abs(distance) + TOLERANCE, f32::abs(distance) + TOLERANCE,

20
text/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "pathfinder_text"
version = "0.1.0"
authors = ["Patrick Walton <pcwalton@mimiga.net>"]
edition = "2018"
[dependencies]
euclid = "0.19"
font-kit = "0.1"
lyon_path = "0.12"
[dependencies.pathfinder_geometry]
path = "../geometry"
[dependencies.pathfinder_renderer]
path = "../renderer"
[dependencies.skribo]
git = "https://github.com/linebender/skribo.git"
rev = "f759c2d2c188b668bce998179f03b6319835353e"

217
text/src/lib.rs Normal file
View File

@ -0,0 +1,217 @@
// pathfinder/text/src/lib.rs
//
// Copyright © 2019 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use euclid::{Angle, Point2D, Vector2D};
use font_kit::error::GlyphLoadingError;
use font_kit::hinting::HintingOptions;
use font_kit::loader::Loader;
use lyon_path::builder::{FlatPathBuilder, PathBuilder};
use pathfinder_geometry::basic::point::Point2DF32;
use pathfinder_geometry::basic::transform2d::Transform2DF32;
use pathfinder_geometry::outline::{Contour, Outline};
use pathfinder_geometry::stroke::OutlineStrokeToFill;
use pathfinder_renderer::scene::{PaintId, PathObject, Scene};
use skribo::{FontCollection, Layout, TextStyle};
use std::mem;
pub trait SceneExt {
// TODO(pcwalton): Support stroked glyphs.
fn push_glyph<F>(&mut self,
font: &F,
glyph_id: u32,
transform: &Transform2DF32,
render_mode: TextRenderMode,
hinting_options: HintingOptions,
paint_id: PaintId)
-> Result<(), GlyphLoadingError>
where F: Loader;
fn push_layout(&mut self,
layout: &Layout,
style: &TextStyle,
transform: &Transform2DF32,
render_mode: TextRenderMode,
hinting_options: HintingOptions,
paint_id: PaintId)
-> Result<(), GlyphLoadingError>;
fn push_text(&mut self,
text: &str,
style: &TextStyle,
collection: &FontCollection,
transform: &Transform2DF32,
render_mode: TextRenderMode,
hinting_options: HintingOptions,
paint_id: PaintId)
-> Result<(), GlyphLoadingError>;
}
impl SceneExt for Scene {
#[inline]
fn push_glyph<F>(&mut self,
font: &F,
glyph_id: u32,
transform: &Transform2DF32,
render_mode: TextRenderMode,
hinting_options: HintingOptions,
paint_id: PaintId)
-> Result<(), GlyphLoadingError>
where F: Loader {
let mut outline_builder = OutlinePathBuilder::new(transform);
font.outline(glyph_id, hinting_options, &mut outline_builder)?;
let mut outline = outline_builder.build();
if let TextRenderMode::Stroke(stroke_width) = render_mode {
let mut stroke_to_fill = OutlineStrokeToFill::new(outline, stroke_width);
stroke_to_fill.offset();
outline = stroke_to_fill.outline;
}
self.push_object(PathObject::new(outline, paint_id, String::new()));
Ok(())
}
fn push_layout(&mut self,
layout: &Layout,
style: &TextStyle,
transform: &Transform2DF32,
render_mode: TextRenderMode,
hinting_options: HintingOptions,
paint_id: PaintId)
-> Result<(), GlyphLoadingError> {
for glyph in &layout.glyphs {
let offset = Point2DF32::new(glyph.offset.x, glyph.offset.y);
let font = &*glyph.font.font;
// FIXME(pcwalton): Cache this!
let scale = style.size / (font.metrics().units_per_em as f32);
let scale = Point2DF32::new(scale, -scale);
let transform =
Transform2DF32::from_scale(&scale).post_mul(transform).post_translate(offset);
self.push_glyph(font,
glyph.glyph_id,
&transform,
render_mode,
hinting_options,
paint_id)?;
}
Ok(())
}
#[inline]
fn push_text(&mut self,
text: &str,
style: &TextStyle,
collection: &FontCollection,
transform: &Transform2DF32,
render_mode: TextRenderMode,
hinting_options: HintingOptions,
paint_id: PaintId)
-> Result<(), GlyphLoadingError> {
let layout = skribo::layout(style, collection, text);
self.push_layout(&layout, style, &transform, render_mode, hinting_options, paint_id)
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum TextRenderMode {
Fill,
Stroke(f32),
}
struct OutlinePathBuilder {
outline: Outline,
current_contour: Contour,
transform: Transform2DF32,
}
impl OutlinePathBuilder {
fn new(transform: &Transform2DF32) -> OutlinePathBuilder {
OutlinePathBuilder {
outline: Outline::new(),
current_contour: Contour::new(),
transform: *transform,
}
}
fn flush_current_contour(&mut self) {
if !self.current_contour.is_empty() {
self.outline.push_contour(mem::replace(&mut self.current_contour, Contour::new()));
}
}
fn convert_point(&self, point: Point2D<f32>) -> Point2DF32 {
self.transform.transform_point(&Point2DF32::new(point.x, point.y))
}
}
impl PathBuilder for OutlinePathBuilder {
fn quadratic_bezier_to(&mut self, ctrl: Point2D<f32>, to: Point2D<f32>) {
let (ctrl, to) = (self.convert_point(ctrl), self.convert_point(to));
self.current_contour.push_quadratic(ctrl, to);
}
fn cubic_bezier_to(&mut self, ctrl0: Point2D<f32>, ctrl1: Point2D<f32>, to: Point2D<f32>) {
let (ctrl0, ctrl1) = (self.convert_point(ctrl0), self.convert_point(ctrl1));
let to = self.convert_point(to);
self.current_contour.push_cubic(ctrl0, ctrl1, to);
}
fn arc(&mut self,
_center: Point2D<f32>,
_radii: Vector2D<f32>,
_sweep_angle: Angle<f32>,
_x_rotation: Angle<f32>) {
// TODO(pcwalton): Arcs.
}
}
impl FlatPathBuilder for OutlinePathBuilder {
type PathType = Outline;
fn move_to(&mut self, to: Point2D<f32>) {
self.flush_current_contour();
let to = self.convert_point(to);
self.current_contour.push_endpoint(to);
}
fn line_to(&mut self, to: Point2D<f32>) {
let to = self.convert_point(to);
self.current_contour.push_endpoint(to);
}
fn close(&mut self) {
self.current_contour.close();
}
fn current_position(&self) -> Point2D<f32> {
if self.current_contour.is_empty() {
return Point2D::new(0.0, 0.0)
}
let point_index = if self.current_contour.is_closed() {
0
} else {
self.current_contour.len() - 1
};
let point = self.current_contour.position_of(point_index);
Point2D::new(point.x(), point.y())
}
fn build(mut self) -> Outline {
self.flush_current_contour();
self.outline
}
fn build_and_reset(&mut self) -> Outline {
self.flush_current_contour();
mem::replace(&mut self.outline, Outline::new())
}
}