Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/ab_glyph_rasterizer/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/ab_glyph_rasterizer/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"CHANGELOG.md":"f40c8fae65d889f504d619983bbab8cbc370995049ba3077acc2ba01f8116e89","Cargo.toml":"4fbf6705c2a5a23335605339c159208d1a376189693e645a6b0a30f9885be328","LICENSE":"15c517f38838988aa9f990a1e6bdfc0f20fd1aa1dcb710bb994669d098d73e70","README.md":"59162e54bce67b4181f793866a73e4906b3cb4b45f3487f045aca2ce06611a80","src/geometry.rs":"8d970a944af7199ac6a42ace5d1ca661f7764d10a2af0eb09f7b356547f80cf8","src/lib.rs":"32f718b6be690d4d22fa60bf2d2f3b73f645e293a12f0e7c969c7ff2ac2f0a54","src/nostd_float.rs":"425e4f7a3c20213d561a376a09cb75a37ba3989b42e1700a3b15f642ccb99918","src/raster.rs":"9cb90f50a5a915e17f3ea46efd4cd1cf748ec94dc5307878643dd315baa79663","tests/issues.rs":"dff1f0f9992a49a71b3ac4e298033fe9687194a7948bdf29b110daa1ccc99790"},"package":"c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"}
|
||||
29
third-party/vendor/ab_glyph_rasterizer/CHANGELOG.md
vendored
Normal file
29
third-party/vendor/ab_glyph_rasterizer/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# 0.1.8
|
||||
* Do SIMD runtime detection only once on the first `Rasterizer::new` instead of on each.
|
||||
|
||||
# 0.1.7
|
||||
* Fix x86, x86_64 no_std builds, require `std` feature for runtime detected SIMD.
|
||||
|
||||
# 0.1.6
|
||||
* Add runtime detected AVX2 or SSE4.2 line drawing. Improves performance on compatible x86_64 CPUs.
|
||||
|
||||
# 0.1.5
|
||||
* Remove cap of `1.0` for coverage values returned by `for_each_pixel` now `>= 1.0` means fully covered.
|
||||
This allows a minor reduction in operations / performance boost.
|
||||
|
||||
# 0.1.4
|
||||
* Add `Rasterizer::reset`, `Rasterizer::clear` methods to allow allocation reuse.
|
||||
|
||||
# 0.1.3
|
||||
* Fix index oob panic scenario.
|
||||
|
||||
# 0.1.2
|
||||
* For `Point` implement `Sub`, `Add`, `SubAssign`, `AddAssign`, `PartialEq`, `PartialOrd`, `From<(x, y)>`,
|
||||
`From<[x, y]>` for easier use downstream.
|
||||
* Switch `Point` `Debug` implementation to output `point(1.2, 3.4)` smaller representation referring to the `point` fn.
|
||||
|
||||
# 0.1.1
|
||||
* Add explicit compile error when building no_std without the "libm" feature.
|
||||
|
||||
# 0.1
|
||||
* Implement zero dependency coverage rasterization for lines, quadratic & cubic beziers.
|
||||
36
third-party/vendor/ab_glyph_rasterizer/Cargo.toml
vendored
Normal file
36
third-party/vendor/ab_glyph_rasterizer/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "ab_glyph_rasterizer"
|
||||
version = "0.1.8"
|
||||
authors = ["Alex Butler <alexheretic@gmail.com>"]
|
||||
description = "Coverage rasterization for lines, quadratic & cubic beziers"
|
||||
readme = "README.md"
|
||||
keywords = [
|
||||
"text",
|
||||
"ttf",
|
||||
"otf",
|
||||
"font",
|
||||
]
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/alexheretic/ab-glyph"
|
||||
|
||||
[dependencies.libm]
|
||||
version = "0.2.1"
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = []
|
||||
201
third-party/vendor/ab_glyph_rasterizer/LICENSE
vendored
Normal file
201
third-party/vendor/ab_glyph_rasterizer/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 Alex Butler
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
51
third-party/vendor/ab_glyph_rasterizer/README.md
vendored
Normal file
51
third-party/vendor/ab_glyph_rasterizer/README.md
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
ab_glyph_rasterizer
|
||||
[](https://crates.io/crates/ab_glyph_rasterizer)
|
||||
[](https://docs.rs/ab_glyph_rasterizer)
|
||||
===================
|
||||
Coverage rasterization for lines, quadratic & cubic beziers.
|
||||
Useful for drawing .otf font glyphs.
|
||||
|
||||
Inspired by [font-rs](https://github.com/raphlinus/font-rs) &
|
||||
[stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h).
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
let mut rasterizer = ab_glyph_rasterizer::Rasterizer::new(106, 183);
|
||||
|
||||
// draw a 300px 'ę' character
|
||||
rasterizer.draw_cubic(point(103.0, 163.5), point(86.25, 169.25), point(77.0, 165.0), point(82.25, 151.5));
|
||||
rasterizer.draw_cubic(point(82.25, 151.5), point(86.75, 139.75), point(94.0, 130.75), point(102.0, 122.0));
|
||||
rasterizer.draw_line(point(102.0, 122.0), point(100.25, 111.25));
|
||||
rasterizer.draw_cubic(point(100.25, 111.25), point(89.0, 112.75), point(72.75, 114.25), point(58.5, 114.25));
|
||||
rasterizer.draw_cubic(point(58.5, 114.25), point(30.75, 114.25), point(18.5, 105.25), point(16.75, 72.25));
|
||||
rasterizer.draw_line(point(16.75, 72.25), point(77.0, 72.25));
|
||||
rasterizer.draw_cubic(point(77.0, 72.25), point(97.0, 72.25), point(105.25, 60.25), point(104.75, 38.5));
|
||||
rasterizer.draw_cubic(point(104.75, 38.5), point(104.5, 13.5), point(89.0, 0.75), point(54.25, 0.75));
|
||||
rasterizer.draw_cubic(point(54.25, 0.75), point(16.0, 0.75), point(0.0, 16.75), point(0.0, 64.0));
|
||||
rasterizer.draw_cubic(point(0.0, 64.0), point(0.0, 110.5), point(16.0, 128.0), point(56.5, 128.0));
|
||||
rasterizer.draw_cubic(point(56.5, 128.0), point(66.0, 128.0), point(79.5, 127.0), point(90.0, 125.0));
|
||||
rasterizer.draw_cubic(point(90.0, 125.0), point(78.75, 135.25), point(73.25, 144.5), point(70.75, 152.0));
|
||||
rasterizer.draw_cubic(point(70.75, 152.0), point(64.5, 169.0), point(75.5, 183.0), point(105.0, 170.5));
|
||||
rasterizer.draw_line(point(105.0, 170.5), point(103.0, 163.5));
|
||||
rasterizer.draw_cubic(point(55.0, 14.5), point(78.5, 14.5), point(88.5, 21.75), point(88.75, 38.75));
|
||||
rasterizer.draw_cubic(point(88.75, 38.75), point(89.0, 50.75), point(85.75, 59.75), point(73.5, 59.75));
|
||||
rasterizer.draw_line(point(73.5, 59.75), point(16.5, 59.75));
|
||||
rasterizer.draw_cubic(point(16.5, 59.75), point(17.25, 25.5), point(27.0, 14.5), point(55.0, 14.5));
|
||||
rasterizer.draw_line(point(55.0, 14.5), point(55.0, 14.5));
|
||||
|
||||
// iterate over the resultant pixel alphas, e.g. save pixel to a buffer
|
||||
rasterizer.for_each_pixel(|index, alpha| {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Rendering the resultant pixel alphas as 8-bit grey produces:
|
||||
|
||||

|
||||
|
||||
## no_std
|
||||
no_std environments are supported using `alloc` & [`libm`](https://github.com/rust-lang/libm).
|
||||
```toml
|
||||
ab_glyph_rasterizer = { default-features = false, features = ["libm"] }
|
||||
```
|
||||
148
third-party/vendor/ab_glyph_rasterizer/src/geometry.rs
vendored
Normal file
148
third-party/vendor/ab_glyph_rasterizer/src/geometry.rs
vendored
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#[cfg(all(feature = "libm", not(feature = "std")))]
|
||||
use crate::nostd_float::FloatExt;
|
||||
|
||||
/// An (x, y) coordinate.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// use ab_glyph_rasterizer::{point, Point};
|
||||
/// let p: Point = point(0.1, 23.2);
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
|
||||
pub struct Point {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Point {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
write!(f, "point({:?}, {:?})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl Point {
|
||||
#[inline]
|
||||
pub(crate) fn distance_to(self, other: Point) -> f32 {
|
||||
let d = other - self;
|
||||
(d.x * d.x + d.y * d.y).sqrt()
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Point`](struct.Point.html) constructor.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::{point, Point};
|
||||
/// let p = point(0.1, 23.2);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn point(x: f32, y: f32) -> Point {
|
||||
Point { x, y }
|
||||
}
|
||||
|
||||
/// Linear interpolation between points.
|
||||
#[inline]
|
||||
pub(crate) fn lerp(t: f32, p0: Point, p1: Point) -> Point {
|
||||
point(p0.x + t * (p1.x - p0.x), p0.y + t * (p1.y - p0.y))
|
||||
}
|
||||
|
||||
impl core::ops::Sub for Point {
|
||||
type Output = Point;
|
||||
/// Subtract rhs.x from x, rhs.y from y.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let p1 = point(1.0, 2.0) - point(2.0, 1.5);
|
||||
///
|
||||
/// assert!((p1.x - -1.0).abs() <= core::f32::EPSILON);
|
||||
/// assert!((p1.y - 0.5).abs() <= core::f32::EPSILON);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn sub(self, rhs: Point) -> Point {
|
||||
point(self.x - rhs.x, self.y - rhs.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::Add for Point {
|
||||
type Output = Point;
|
||||
/// Add rhs.x to x, rhs.y to y.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let p1 = point(1.0, 2.0) + point(2.0, 1.5);
|
||||
///
|
||||
/// assert!((p1.x - 3.0).abs() <= core::f32::EPSILON);
|
||||
/// assert!((p1.y - 3.5).abs() <= core::f32::EPSILON);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn add(self, rhs: Point) -> Point {
|
||||
point(self.x + rhs.x, self.y + rhs.y)
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::AddAssign for Point {
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let mut p1 = point(1.0, 2.0);
|
||||
/// p1 += point(2.0, 1.5);
|
||||
///
|
||||
/// assert!((p1.x - 3.0).abs() <= core::f32::EPSILON);
|
||||
/// assert!((p1.y - 3.5).abs() <= core::f32::EPSILON);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn add_assign(&mut self, other: Self) {
|
||||
self.x += other.x;
|
||||
self.y += other.y;
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::SubAssign for Point {
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let mut p1 = point(1.0, 2.0);
|
||||
/// p1 -= point(2.0, 1.5);
|
||||
///
|
||||
/// assert!((p1.x - -1.0).abs() <= core::f32::EPSILON);
|
||||
/// assert!((p1.y - 0.5).abs() <= core::f32::EPSILON);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, other: Self) {
|
||||
self.x -= other.x;
|
||||
self.y -= other.y;
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Into<f32>> From<(F, F)> for Point {
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let p: Point = (23_f32, 34.5_f32).into();
|
||||
/// let p2: Point = (5u8, 44u8).into();
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from((x, y): (F, F)) -> Self {
|
||||
point(x.into(), y.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Into<f32>> From<[F; 2]> for Point {
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let p: Point = [23_f32, 34.5].into();
|
||||
/// let p2: Point = [5u8, 44].into();
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from([x, y]: [F; 2]) -> Self {
|
||||
point(x.into(), y.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn distance_to() {
|
||||
let distance = point(0.0, 0.0).distance_to(point(3.0, 4.0));
|
||||
assert!((distance - 5.0).abs() <= core::f32::EPSILON);
|
||||
}
|
||||
}
|
||||
36
third-party/vendor/ab_glyph_rasterizer/src/lib.rs
vendored
Normal file
36
third-party/vendor/ab_glyph_rasterizer/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//! Coverage rasterization for lines, quadratic & cubic beziers.
|
||||
//! Useful for drawing .otf font glyphs.
|
||||
//!
|
||||
//! ```
|
||||
//! use ab_glyph_rasterizer::Rasterizer;
|
||||
//! # let (width, height) = (1, 1);
|
||||
//! let mut rasterizer = Rasterizer::new(width, height);
|
||||
//!
|
||||
//! // draw outlines
|
||||
//! # let [l0, l1, q0, q1, q2, c0, c1, c2, c3] = [ab_glyph_rasterizer::point(0.0, 0.0); 9];
|
||||
//! rasterizer.draw_line(l0, l1);
|
||||
//! rasterizer.draw_quad(q0, q1, q2);
|
||||
//! rasterizer.draw_cubic(c0, c1, c2, c3);
|
||||
//!
|
||||
//! // iterate over the resultant pixel alphas, e.g. save pixel to a buffer
|
||||
//! rasterizer.for_each_pixel(|index, alpha| {
|
||||
//! // ...
|
||||
//! });
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(all(feature = "libm", not(feature = "std")))]
|
||||
mod nostd_float;
|
||||
|
||||
#[cfg(not(any(feature = "libm", feature = "std")))]
|
||||
compile_error!("You need to activate either the `std` or `libm` feature.");
|
||||
|
||||
mod geometry;
|
||||
mod raster;
|
||||
|
||||
pub use geometry::{point, Point};
|
||||
pub use raster::Rasterizer;
|
||||
31
third-party/vendor/ab_glyph_rasterizer/src/nostd_float.rs
vendored
Normal file
31
third-party/vendor/ab_glyph_rasterizer/src/nostd_float.rs
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/// Basic required float operations.
|
||||
pub(crate) trait FloatExt {
|
||||
fn floor(self) -> Self;
|
||||
fn ceil(self) -> Self;
|
||||
fn sqrt(self) -> Self;
|
||||
fn round(self) -> Self;
|
||||
fn abs(self) -> Self;
|
||||
}
|
||||
|
||||
impl FloatExt for f32 {
|
||||
#[inline]
|
||||
fn floor(self) -> Self {
|
||||
libm::floorf(self)
|
||||
}
|
||||
#[inline]
|
||||
fn ceil(self) -> Self {
|
||||
libm::ceilf(self)
|
||||
}
|
||||
#[inline]
|
||||
fn sqrt(self) -> Self {
|
||||
libm::sqrtf(self)
|
||||
}
|
||||
#[inline]
|
||||
fn round(self) -> Self {
|
||||
libm::roundf(self)
|
||||
}
|
||||
#[inline]
|
||||
fn abs(self) -> Self {
|
||||
libm::fabsf(self)
|
||||
}
|
||||
}
|
||||
338
third-party/vendor/ab_glyph_rasterizer/src/raster.rs
vendored
Normal file
338
third-party/vendor/ab_glyph_rasterizer/src/raster.rs
vendored
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
// Forked/repurposed from `font-rs` code: https://github.com/raphlinus/font-rs
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Modifications copyright (C) 2020 Alex Butler
|
||||
//
|
||||
// Cubic bezier drawing adapted from stb_truetype: https://github.com/nothings/stb
|
||||
#[cfg(all(feature = "libm", not(feature = "std")))]
|
||||
use crate::nostd_float::FloatExt;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use crate::geometry::{lerp, Point};
|
||||
|
||||
type DrawLineFn = unsafe fn(&mut Rasterizer, Point, Point);
|
||||
|
||||
/// Coverage rasterizer for lines, quadratic & cubic beziers.
|
||||
pub struct Rasterizer {
|
||||
width: usize,
|
||||
height: usize,
|
||||
a: Vec<f32>,
|
||||
draw_line_fn: DrawLineFn,
|
||||
}
|
||||
|
||||
impl Rasterizer {
|
||||
/// Allocates a new rasterizer that can draw onto a `width` x `height` alpha grid.
|
||||
///
|
||||
/// ```
|
||||
/// use ab_glyph_rasterizer::Rasterizer;
|
||||
/// let mut rasterizer = Rasterizer::new(14, 38);
|
||||
/// ```
|
||||
pub fn new(width: usize, height: usize) -> Self {
|
||||
Self {
|
||||
width,
|
||||
height,
|
||||
a: vec![0.0; width * height + 4],
|
||||
draw_line_fn: optimal_draw_line_fn(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Resets the rasterizer to an empty `width` x `height` alpha grid. This method behaves as if
|
||||
/// the Rasterizer were re-created, with the advantage of not allocating if the total number of
|
||||
/// pixels of the grid does not increase.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::Rasterizer;
|
||||
/// # let mut rasterizer = Rasterizer::new(14, 38);
|
||||
/// rasterizer.reset(12, 24);
|
||||
/// assert_eq!(rasterizer.dimensions(), (12, 24));
|
||||
/// ```
|
||||
pub fn reset(&mut self, width: usize, height: usize) {
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
self.a.truncate(0);
|
||||
self.a.resize(width * height + 4, 0.0);
|
||||
}
|
||||
|
||||
/// Clears the rasterizer. This method behaves as if the Rasterizer were re-created with the same
|
||||
/// dimensions, but does not perform an allocation.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::Rasterizer;
|
||||
/// # let mut rasterizer = Rasterizer::new(14, 38);
|
||||
/// rasterizer.clear();
|
||||
/// ```
|
||||
pub fn clear(&mut self) {
|
||||
for px in &mut self.a {
|
||||
*px = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the dimensions the rasterizer was built to draw to.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// let rasterizer = Rasterizer::new(9, 8);
|
||||
/// assert_eq!((9, 8), rasterizer.dimensions());
|
||||
/// ```
|
||||
pub fn dimensions(&self) -> (usize, usize) {
|
||||
(self.width, self.height)
|
||||
}
|
||||
|
||||
/// Adds a straight line from `p0` to `p1` to the outline.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// # let mut rasterizer = Rasterizer::new(9, 8);
|
||||
/// rasterizer.draw_line(point(0.0, 0.48), point(1.22, 0.48));
|
||||
/// ```
|
||||
pub fn draw_line(&mut self, p0: Point, p1: Point) {
|
||||
unsafe { (self.draw_line_fn)(self, p0, p1) }
|
||||
}
|
||||
|
||||
#[inline(always)] // must inline for simd versions
|
||||
fn draw_line_scalar(&mut self, p0: Point, p1: Point) {
|
||||
if (p0.y - p1.y).abs() <= core::f32::EPSILON {
|
||||
return;
|
||||
}
|
||||
let (dir, p0, p1) = if p0.y < p1.y {
|
||||
(1.0, p0, p1)
|
||||
} else {
|
||||
(-1.0, p1, p0)
|
||||
};
|
||||
let dxdy = (p1.x - p0.x) / (p1.y - p0.y);
|
||||
let mut x = p0.x;
|
||||
let y0 = p0.y as usize; // note: implicit max of 0 because usize
|
||||
if p0.y < 0.0 {
|
||||
x -= p0.y * dxdy;
|
||||
}
|
||||
for y in y0..self.height.min(p1.y.ceil() as usize) {
|
||||
let linestart = y * self.width;
|
||||
let dy = ((y + 1) as f32).min(p1.y) - (y as f32).max(p0.y);
|
||||
let xnext = x + dxdy * dy;
|
||||
let d = dy * dir;
|
||||
let (x0, x1) = if x < xnext { (x, xnext) } else { (xnext, x) };
|
||||
let x0floor = x0.floor();
|
||||
let x0i = x0floor as i32;
|
||||
let x1ceil = x1.ceil();
|
||||
let x1i = x1ceil as i32;
|
||||
if x1i <= x0i + 1 {
|
||||
let xmf = 0.5 * (x + xnext) - x0floor;
|
||||
let linestart_x0i = linestart as isize + x0i as isize;
|
||||
if linestart_x0i < 0 {
|
||||
continue; // oob index
|
||||
}
|
||||
self.a[linestart_x0i as usize] += d - d * xmf;
|
||||
self.a[linestart_x0i as usize + 1] += d * xmf;
|
||||
} else {
|
||||
let s = (x1 - x0).recip();
|
||||
let x0f = x0 - x0floor;
|
||||
let a0 = 0.5 * s * (1.0 - x0f) * (1.0 - x0f);
|
||||
let x1f = x1 - x1ceil + 1.0;
|
||||
let am = 0.5 * s * x1f * x1f;
|
||||
let linestart_x0i = linestart as isize + x0i as isize;
|
||||
if linestart_x0i < 0 {
|
||||
continue; // oob index
|
||||
}
|
||||
self.a[linestart_x0i as usize] += d * a0;
|
||||
if x1i == x0i + 2 {
|
||||
self.a[linestart_x0i as usize + 1] += d * (1.0 - a0 - am);
|
||||
} else {
|
||||
let a1 = s * (1.5 - x0f);
|
||||
self.a[linestart_x0i as usize + 1] += d * (a1 - a0);
|
||||
for xi in x0i + 2..x1i - 1 {
|
||||
self.a[linestart + xi as usize] += d * s;
|
||||
}
|
||||
let a2 = a1 + (x1i - x0i - 3) as f32 * s;
|
||||
self.a[linestart + (x1i - 1) as usize] += d * (1.0 - a2 - am);
|
||||
}
|
||||
self.a[linestart + x1i as usize] += d * am;
|
||||
}
|
||||
x = xnext;
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a quadratic Bézier curve from `p0` to `p2` to the outline using `p1` as the control.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// # let mut rasterizer = Rasterizer::new(14, 38);
|
||||
/// rasterizer.draw_quad(point(6.2, 34.5), point(7.2, 34.5), point(9.2, 34.0));
|
||||
/// ```
|
||||
pub fn draw_quad(&mut self, p0: Point, p1: Point, p2: Point) {
|
||||
let devx = p0.x - 2.0 * p1.x + p2.x;
|
||||
let devy = p0.y - 2.0 * p1.y + p2.y;
|
||||
let devsq = devx * devx + devy * devy;
|
||||
if devsq < 0.333 {
|
||||
self.draw_line(p0, p2);
|
||||
return;
|
||||
}
|
||||
let tol = 3.0;
|
||||
let n = 1 + (tol * devsq).sqrt().sqrt().floor() as usize;
|
||||
let mut p = p0;
|
||||
let nrecip = (n as f32).recip();
|
||||
let mut t = 0.0;
|
||||
for _i in 0..n - 1 {
|
||||
t += nrecip;
|
||||
let pn = lerp(t, lerp(t, p0, p1), lerp(t, p1, p2));
|
||||
self.draw_line(p, pn);
|
||||
p = pn;
|
||||
}
|
||||
self.draw_line(p, p2);
|
||||
}
|
||||
|
||||
/// Adds a cubic Bézier curve from `p0` to `p3` to the outline using `p1` as the control
|
||||
/// at the beginning of the curve and `p2` at the end of the curve.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// # let mut rasterizer = Rasterizer::new(12, 20);
|
||||
/// rasterizer.draw_cubic(
|
||||
/// point(10.3, 16.4),
|
||||
/// point(8.6, 16.9),
|
||||
/// point(7.7, 16.5),
|
||||
/// point(8.2, 15.2),
|
||||
/// );
|
||||
/// ```
|
||||
pub fn draw_cubic(&mut self, p0: Point, p1: Point, p2: Point, p3: Point) {
|
||||
self.tesselate_cubic(p0, p1, p2, p3, 0);
|
||||
}
|
||||
|
||||
// stb_truetype style cubic approximation by lines.
|
||||
fn tesselate_cubic(&mut self, p0: Point, p1: Point, p2: Point, p3: Point, n: u8) {
|
||||
// ...I'm not sure either ¯\_(ツ)_/¯
|
||||
const OBJSPACE_FLATNESS: f32 = 0.35;
|
||||
const OBJSPACE_FLATNESS_SQUARED: f32 = OBJSPACE_FLATNESS * OBJSPACE_FLATNESS;
|
||||
const MAX_RECURSION_DEPTH: u8 = 16;
|
||||
|
||||
let longlen = p0.distance_to(p1) + p1.distance_to(p2) + p2.distance_to(p3);
|
||||
let shortlen = p0.distance_to(p3);
|
||||
let flatness_squared = longlen * longlen - shortlen * shortlen;
|
||||
|
||||
if n < MAX_RECURSION_DEPTH && flatness_squared > OBJSPACE_FLATNESS_SQUARED {
|
||||
let p01 = lerp(0.5, p0, p1);
|
||||
let p12 = lerp(0.5, p1, p2);
|
||||
let p23 = lerp(0.5, p2, p3);
|
||||
|
||||
let pa = lerp(0.5, p01, p12);
|
||||
let pb = lerp(0.5, p12, p23);
|
||||
|
||||
let mp = lerp(0.5, pa, pb);
|
||||
|
||||
self.tesselate_cubic(p0, p01, pa, mp, n + 1);
|
||||
self.tesselate_cubic(mp, pb, p23, p3, n + 1);
|
||||
} else {
|
||||
self.draw_line(p0, p3);
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a callback for each pixel `index` & `alpha`, with indices in `0..width * height`.
|
||||
///
|
||||
/// An `alpha` coverage value of `0.0` means the pixel is not covered at all by the glyph,
|
||||
/// whereas a value of `1.0` (or greater) means the pixel is totally covered.
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// # let (width, height) = (1, 1);
|
||||
/// # let mut rasterizer = Rasterizer::new(width, height);
|
||||
/// let mut pixels = vec![0u8; width * height];
|
||||
/// rasterizer.for_each_pixel(|index, alpha| {
|
||||
/// pixels[index] = (alpha * 255.0) as u8;
|
||||
/// });
|
||||
/// ```
|
||||
pub fn for_each_pixel<O: FnMut(usize, f32)>(&self, mut px_fn: O) {
|
||||
let mut acc = 0.0;
|
||||
self.a[..self.width * self.height]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(idx, c)| {
|
||||
acc += c;
|
||||
px_fn(idx, acc.abs());
|
||||
});
|
||||
}
|
||||
|
||||
/// Run a callback for each pixel x position, y position & alpha.
|
||||
///
|
||||
/// Convenience wrapper for [`Rasterizer::for_each_pixel`].
|
||||
///
|
||||
/// ```
|
||||
/// # use ab_glyph_rasterizer::*;
|
||||
/// # let mut rasterizer = Rasterizer::new(1, 1);
|
||||
/// # struct Img;
|
||||
/// # impl Img { fn set_pixel(&self, x: u32, y: u32, a: u8) {} }
|
||||
/// # let image = Img;
|
||||
/// rasterizer.for_each_pixel_2d(|x, y, alpha| {
|
||||
/// image.set_pixel(x, y, (alpha * 255.0) as u8);
|
||||
/// });
|
||||
/// ```
|
||||
pub fn for_each_pixel_2d<O: FnMut(u32, u32, f32)>(&self, mut px_fn: O) {
|
||||
let width32 = self.width as u32;
|
||||
self.for_each_pixel(|idx, alpha| px_fn(idx as u32 % width32, idx as u32 / width32, alpha));
|
||||
}
|
||||
}
|
||||
|
||||
/// ```
|
||||
/// let rasterizer = ab_glyph_rasterizer::Rasterizer::new(3, 4);
|
||||
/// assert_eq!(
|
||||
/// &format!("{:?}", rasterizer),
|
||||
/// "Rasterizer { width: 3, height: 4 }"
|
||||
/// );
|
||||
/// ```
|
||||
impl core::fmt::Debug for Rasterizer {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("Rasterizer")
|
||||
.field("width", &self.width)
|
||||
.field("height", &self.height)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
#[target_feature(enable = "avx2")]
|
||||
unsafe fn draw_line_avx2(rast: &mut Rasterizer, p0: Point, p1: Point) {
|
||||
rast.draw_line_scalar(p0, p1)
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
#[target_feature(enable = "sse4.2")]
|
||||
unsafe fn draw_line_sse4_2(rast: &mut Rasterizer, p0: Point, p1: Point) {
|
||||
rast.draw_line_scalar(p0, p1)
|
||||
}
|
||||
|
||||
/// Return most optimal `DrawLineFn` impl.
|
||||
///
|
||||
/// With feature `std` on x86/x86_64 will use one-time runtime detection
|
||||
/// to pick the best SIMD impl. Otherwise uses a scalar version.
|
||||
fn optimal_draw_line_fn() -> DrawLineFn {
|
||||
unsafe {
|
||||
// safe as write synchronised by Once::call_once or no-write
|
||||
static mut DRAW_LINE_FN: DrawLineFn = Rasterizer::draw_line_scalar;
|
||||
|
||||
#[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
{
|
||||
static INIT: std::sync::Once = std::sync::Once::new();
|
||||
INIT.call_once(|| {
|
||||
// runtime detect optimal simd impls
|
||||
if is_x86_feature_detected!("avx2") {
|
||||
DRAW_LINE_FN = draw_line_avx2
|
||||
} else if is_x86_feature_detected!("sse4.2") {
|
||||
DRAW_LINE_FN = draw_line_sse4_2
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DRAW_LINE_FN
|
||||
}
|
||||
}
|
||||
10
third-party/vendor/ab_glyph_rasterizer/tests/issues.rs
vendored
Normal file
10
third-party/vendor/ab_glyph_rasterizer/tests/issues.rs
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
use ab_glyph_rasterizer::*;
|
||||
|
||||
/// Index oob panic rasterizing "Gauntl" using Bitter-Regular.otf
|
||||
#[test]
|
||||
fn rusttype_156_index_panic() {
|
||||
let mut r = Rasterizer::new(6, 16);
|
||||
r.draw_line(point(5.54, 14.299999), point(3.7399998, 13.799999));
|
||||
r.draw_line(point(3.7399998, 13.799999), point(3.7399998, 0.0));
|
||||
r.draw_line(point(3.7399998, 0.0), point(0.0, 0.10000038));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue