mirror of https://github.com/Aloxaf/silicon
Merge 8f4e1eca41
into cf3668c9ee
This commit is contained in:
commit
ebc1a1c659
|
@ -2,12 +2,6 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph_rasterizer"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "330223a1aecc308757b9926e9391c9b47f8ef2dbd8aea9df88312aea18c5e8d6"
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
|
@ -29,15 +23,6 @@ version = "1.0.65"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
@ -509,17 +494,6 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.7"
|
||||
|
@ -528,7 +502,7 @@ checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -590,24 +564,6 @@ dependencies = [
|
|||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imageproc"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aee993351d466301a29655d628bfc6f5a35a0d062b6160ca0808f425805fd7"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"conv",
|
||||
"image",
|
||||
"itertools",
|
||||
"nalgebra",
|
||||
"num",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
"rayon",
|
||||
"rusttype",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.1"
|
||||
|
@ -627,15 +583,6 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
|
@ -706,15 +653,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matrixmultiply"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84"
|
||||
dependencies = [
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
|
@ -733,55 +671,6 @@ dependencies = [
|
|||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nalgebra"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb2d0de08694bed883320212c18ee3008576bfe8c306f4c3c4a58b4876998be"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"matrixmultiply",
|
||||
"num-complex",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"simba",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
|
@ -792,17 +681,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
|
@ -810,7 +688,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
@ -911,21 +788,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3"
|
||||
dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
|
||||
|
||||
[[package]]
|
||||
name = "pasteboard"
|
||||
version = "0.1.3"
|
||||
|
@ -998,12 +860,6 @@ dependencies = [
|
|||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
|
@ -1046,62 +902,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_distr"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rawpointer"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.3"
|
||||
|
@ -1141,7 +941,7 @@ version = "0.4.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom 0.2.7",
|
||||
"getrandom",
|
||||
"redox_syscall",
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -1170,31 +970,12 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusttype"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59"
|
||||
dependencies = [
|
||||
"ab_glyph_rasterizer",
|
||||
"owned_ttf_parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "safe_arch"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
|
@ -1284,7 +1065,6 @@ dependencies = [
|
|||
"font-kit",
|
||||
"harfbuzz-sys",
|
||||
"image",
|
||||
"imageproc",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"pasteboard",
|
||||
|
@ -1296,19 +1076,6 @@ dependencies = [
|
|||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c48e45e5961033db030b56ad67aef22e9c908c493a6e8348c0a0f6b93433cd77"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"paste",
|
||||
"wide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "str-buf"
|
||||
version = "1.0.6"
|
||||
|
@ -1453,18 +1220,6 @@ dependencies = [
|
|||
"num_threads",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.5"
|
||||
|
@ -1512,28 +1267,12 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.9.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wide"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae41ecad2489a1655c8ef8489444b0b113c0a0c795944a3572a0931cf7d2525c"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"safe_arch",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
@ -18,7 +18,6 @@ harfbuzz = ["harfbuzz-sys", "font-kit/loader-freetype-default", "font-kit/source
|
|||
|
||||
[dependencies]
|
||||
dirs = "4.0"
|
||||
imageproc = "0.23.0"
|
||||
clipboard = "0.5.0"
|
||||
tempfile = "3.1.0"
|
||||
conv = "0.3.3"
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
use crate::error::FontError;
|
||||
#[cfg(feature = "harfbuzz")]
|
||||
use crate::hb_wrapper::{feature_from_tag, HBBuffer, HBFont};
|
||||
use crate::imageproc::{weighted_sum, Clamp};
|
||||
use anyhow::Result;
|
||||
use conv::ValueInto;
|
||||
use font_kit::canvas::{Canvas, Format, RasterizationOptions};
|
||||
|
@ -22,8 +23,6 @@ use font_kit::hinting::HintingOptions;
|
|||
use font_kit::properties::{Properties, Style, Weight};
|
||||
use font_kit::source::SystemSource;
|
||||
use image::{GenericImage, Pixel};
|
||||
use imageproc::definitions::Clamp;
|
||||
use imageproc::pixelops::weighted_sum;
|
||||
use pathfinder_geometry::transform2d::Transform2F;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
@ -348,7 +347,7 @@ impl FontCollection {
|
|||
) -> u32
|
||||
where
|
||||
I: GenericImage,
|
||||
<I::Pixel as Pixel>::Subpixel: ValueInto<f32> + Clamp<f32>,
|
||||
<I::Pixel as Pixel>::Subpixel: ValueInto<f32> + Clamp,
|
||||
{
|
||||
let metrics = self.0[0].get_regular().metrics();
|
||||
let offset =
|
||||
|
|
|
@ -0,0 +1,327 @@
|
|||
//! Manual implementations of some things from imageproc - without all the unnecessary faff
|
||||
//!
|
||||
//! The MIT License (MIT)
|
||||
//!
|
||||
//! Copyright (c) 2015 PistonDevelopers
|
||||
//!
|
||||
//! Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//! of this software and associated documentation files (the "Software"), to deal
|
||||
//! in the Software without restriction, including without limitation the rights
|
||||
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//! copies of the Software, and to permit persons to whom the Software is
|
||||
//! furnished to do so, subject to the following conditions:
|
||||
//!
|
||||
//! The above copyright notice and this permission notice shall be included in all
|
||||
//! copies or substantial portions of the Software.
|
||||
//!
|
||||
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
//! SOFTWARE.
|
||||
|
||||
use conv::ValueInto;
|
||||
use image::{GenericImage, Pixel, Rgba, RgbaImage};
|
||||
|
||||
/// Draw as much of a circle, including its contents, as lies inside the image bounds.
|
||||
pub(crate) fn draw_filled_circle_mut<I>(
|
||||
image: &mut I,
|
||||
center: (i32, i32),
|
||||
radius: i32,
|
||||
color: I::Pixel,
|
||||
) where
|
||||
I: GenericImage,
|
||||
I::Pixel: 'static,
|
||||
{
|
||||
let mut x = 0i32;
|
||||
let mut y = radius;
|
||||
let mut p = 1 - radius;
|
||||
let x0 = center.0;
|
||||
let y0 = center.1;
|
||||
|
||||
while x <= y {
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - x) as f32, (y0 + y) as f32),
|
||||
((x0 + x) as f32, (y0 + y) as f32),
|
||||
color,
|
||||
);
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - y) as f32, (y0 + x) as f32),
|
||||
((x0 + y) as f32, (y0 + x) as f32),
|
||||
color,
|
||||
);
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - x) as f32, (y0 - y) as f32),
|
||||
((x0 + x) as f32, (y0 - y) as f32),
|
||||
color,
|
||||
);
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - y) as f32, (y0 - x) as f32),
|
||||
((x0 + y) as f32, (y0 - x) as f32),
|
||||
color,
|
||||
);
|
||||
|
||||
x += 1;
|
||||
if p < 0 {
|
||||
p += 2 * x + 1;
|
||||
} else {
|
||||
y -= 1;
|
||||
p += 2 * (x - y) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws a line segment on an image in place.
|
||||
///
|
||||
/// Draws as much of the line segment between start and end as lies inside the image bounds.
|
||||
///
|
||||
/// Uses [Bresenham's line drawing algorithm](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm).
|
||||
pub(crate) fn draw_line_segment_mut<I>(
|
||||
canvas: &mut I,
|
||||
start: (f32, f32),
|
||||
end: (f32, f32),
|
||||
color: I::Pixel,
|
||||
) where
|
||||
I: GenericImage,
|
||||
I::Pixel: 'static,
|
||||
{
|
||||
let (width, height) = canvas.dimensions();
|
||||
let in_bounds = |x, y| x >= 0 && x < width as i32 && y >= 0 && y < height as i32;
|
||||
|
||||
let line_iterator = BresenhamLineIter::new(start, end);
|
||||
|
||||
for point in line_iterator {
|
||||
let x = point.0;
|
||||
let y = point.1;
|
||||
|
||||
if in_bounds(x, y) {
|
||||
canvas.put_pixel(x as u32, y as u32, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterates over the coordinates in a line segment using
|
||||
/// [Bresenham's line drawing algorithm](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm).
|
||||
struct BresenhamLineIter {
|
||||
dx: f32,
|
||||
dy: f32,
|
||||
x: i32,
|
||||
y: i32,
|
||||
error: f32,
|
||||
end_x: i32,
|
||||
is_steep: bool,
|
||||
y_step: i32,
|
||||
}
|
||||
|
||||
impl BresenhamLineIter {
|
||||
/// Creates a [`BresenhamLineIter`](struct.BresenhamLineIter.html) which will iterate over the integer coordinates
|
||||
/// between `start` and `end`.
|
||||
fn new(start: (f32, f32), end: (f32, f32)) -> BresenhamLineIter {
|
||||
let (mut x0, mut y0) = (start.0, start.1);
|
||||
let (mut x1, mut y1) = (end.0, end.1);
|
||||
|
||||
let is_steep = (y1 - y0).abs() > (x1 - x0).abs();
|
||||
if is_steep {
|
||||
std::mem::swap(&mut x0, &mut y0);
|
||||
std::mem::swap(&mut x1, &mut y1);
|
||||
}
|
||||
|
||||
if x0 > x1 {
|
||||
std::mem::swap(&mut x0, &mut x1);
|
||||
std::mem::swap(&mut y0, &mut y1);
|
||||
}
|
||||
|
||||
let dx = x1 - x0;
|
||||
|
||||
BresenhamLineIter {
|
||||
dx,
|
||||
dy: (y1 - y0).abs(),
|
||||
x: x0 as i32,
|
||||
y: y0 as i32,
|
||||
error: dx / 2f32,
|
||||
end_x: x1 as i32,
|
||||
is_steep,
|
||||
y_step: if y0 < y1 { 1 } else { -1 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for BresenhamLineIter {
|
||||
type Item = (i32, i32);
|
||||
|
||||
fn next(&mut self) -> Option<(i32, i32)> {
|
||||
if self.x > self.end_x {
|
||||
None
|
||||
} else {
|
||||
let ret = if self.is_steep {
|
||||
(self.y, self.x)
|
||||
} else {
|
||||
(self.x, self.y)
|
||||
};
|
||||
|
||||
self.x += 1;
|
||||
self.error -= self.dy;
|
||||
if self.error < 0f32 {
|
||||
self.y += self.y_step;
|
||||
self.error += self.dx;
|
||||
}
|
||||
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draws a rectangle and its contents on an image in place.
|
||||
///
|
||||
/// Draws as much of the rectangle and its contents as lies inside the image bounds.
|
||||
pub(crate) fn draw_filled_rect_mut(canvas: &mut RgbaImage, rect: Rect, color: Rgba<u8>) {
|
||||
let canvas_bounds = Rect {
|
||||
left: 0,
|
||||
top: 0,
|
||||
width: canvas.width(),
|
||||
height: canvas.height(),
|
||||
};
|
||||
if let Some(intersection) = canvas_bounds.intersect(rect) {
|
||||
for dy in 0..intersection.height {
|
||||
for dx in 0..intersection.width {
|
||||
let x = intersection.left as u32 + dx;
|
||||
let y = intersection.top as u32 + dy;
|
||||
canvas.put_pixel(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A rectangular region of non-zero width and height.
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use imageproc::rect::Rect;
|
||||
/// use imageproc::rect::Region;
|
||||
///
|
||||
/// // Construct a rectangle with top-left corner at (4, 5), width 6 and height 7.
|
||||
/// let rect = Rect::at(4, 5).of_size(6, 7);
|
||||
///
|
||||
/// // Contains top-left point:
|
||||
/// assert_eq!(rect.left(), 4);
|
||||
/// assert_eq!(rect.top(), 5);
|
||||
/// assert!(rect.contains(rect.left(), rect.top()));
|
||||
///
|
||||
/// // Contains bottom-right point, at (left + width - 1, top + height - 1):
|
||||
/// assert_eq!(rect.right(), 9);
|
||||
/// assert_eq!(rect.bottom(), 11);
|
||||
/// assert!(rect.contains(rect.right(), rect.bottom()));
|
||||
/// ```
|
||||
pub(crate) struct Rect {
|
||||
pub(crate) left: i32,
|
||||
pub(crate) top: i32,
|
||||
pub(crate) width: u32,
|
||||
pub(crate) height: u32,
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
/// Greatest y-coordinate reached by rect.
|
||||
fn bottom(&self) -> i32 {
|
||||
self.top + (self.height as i32) - 1
|
||||
}
|
||||
|
||||
/// Greatest x-coordinate reached by rect.
|
||||
fn right(&self) -> i32 {
|
||||
self.left + (self.width as i32) - 1
|
||||
}
|
||||
|
||||
/// Returns the intersection of self and other, or none if they are are disjoint.
|
||||
fn intersect(&self, other: Rect) -> Option<Rect> {
|
||||
let left = std::cmp::max(self.left, other.left);
|
||||
let top = std::cmp::max(self.top, other.top);
|
||||
let right = std::cmp::min(self.right(), other.right());
|
||||
let bottom = std::cmp::min(self.bottom(), other.bottom());
|
||||
|
||||
if right < left || bottom < top {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(Rect {
|
||||
left,
|
||||
top,
|
||||
width: (right - left) as u32 + 1,
|
||||
height: (bottom - top) as u32 + 1,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds pixels with the given weights. Results are clamped to prevent arithmetical overflows.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # extern crate image;
|
||||
/// # extern crate imageproc;
|
||||
/// # fn main() {
|
||||
/// use image::Rgb;
|
||||
/// use imageproc::pixelops::weighted_sum;
|
||||
///
|
||||
/// let left = Rgb([10u8, 20u8, 30u8]);
|
||||
/// let right = Rgb([100u8, 80u8, 60u8]);
|
||||
///
|
||||
/// let sum = weighted_sum(left, right, 0.7, 0.3);
|
||||
/// assert_eq!(sum, Rgb([37, 38, 39]));
|
||||
/// # }
|
||||
/// ```
|
||||
pub(crate) fn weighted_sum<P: Pixel>(left: P, right: P, left_weight: f32, right_weight: f32) -> P
|
||||
where
|
||||
P::Subpixel: ValueInto<f32> + Clamp,
|
||||
{
|
||||
left.map2(&right, |p, q| {
|
||||
Clamp::clamp(cast(p) * left_weight + cast(q) * right_weight)
|
||||
})
|
||||
}
|
||||
|
||||
fn cast<T, U>(x: T) -> U
|
||||
where
|
||||
T: ValueInto<U>,
|
||||
{
|
||||
match x.value_into() {
|
||||
Ok(y) => y,
|
||||
Err(_) => panic!("Failed to convert"),
|
||||
}
|
||||
}
|
||||
|
||||
/// A type to which we can clamp a value of type f32.
|
||||
/// Implementations are not required to handle `NaN`s gracefully.
|
||||
pub trait Clamp {
|
||||
/// Clamp `x` to a valid value for this type.
|
||||
fn clamp(x: f32) -> Self;
|
||||
}
|
||||
|
||||
/// Creates an implementation of Clamp for type To.
|
||||
macro_rules! implement_clamp {
|
||||
($to:ty) => {
|
||||
impl Clamp for $to {
|
||||
fn clamp(x: f32) -> $to {
|
||||
if x < <$to>::MAX as f32 {
|
||||
if x > <$to>::MIN as f32 {
|
||||
x as $to
|
||||
} else {
|
||||
<$to>::MIN
|
||||
}
|
||||
} else {
|
||||
<$to>::MAX
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl Clamp for f32 {
|
||||
fn clamp(x: f32) -> f32 {
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
implement_clamp!(u8);
|
||||
implement_clamp!(u16);
|
|
@ -46,3 +46,4 @@ pub mod formatter;
|
|||
#[cfg(feature = "harfbuzz")]
|
||||
pub mod hb_wrapper;
|
||||
pub mod utils;
|
||||
mod imageproc;
|
||||
|
|
70
src/utils.rs
70
src/utils.rs
|
@ -1,9 +1,8 @@
|
|||
use crate::error::ParseColorError;
|
||||
use crate::imageproc::{draw_filled_circle_mut, draw_filled_rect_mut, Rect};
|
||||
use image::imageops::{crop_imm, resize, FilterType};
|
||||
use image::Pixel;
|
||||
use image::{DynamicImage, GenericImage, GenericImageView, Rgba, RgbaImage};
|
||||
use imageproc::drawing::{draw_filled_rect_mut, draw_line_segment_mut};
|
||||
use imageproc::rect::Rect;
|
||||
|
||||
pub trait ToRgba {
|
||||
type Target;
|
||||
|
@ -212,11 +211,12 @@ impl ShadowAdder {
|
|||
// create the shadow
|
||||
let mut shadow = self.background.to_image(width, height);
|
||||
if self.blur_radius > 0.0 {
|
||||
let rect = Rect::at(
|
||||
self.pad_horiz as i32 + self.offset_x,
|
||||
self.pad_vert as i32 + self.offset_y,
|
||||
)
|
||||
.of_size(image.width(), image.height());
|
||||
let rect = Rect {
|
||||
left: self.pad_horiz as i32 + self.offset_x,
|
||||
top: self.pad_vert as i32 + self.offset_y,
|
||||
width: image.width(),
|
||||
height: image.height(),
|
||||
};
|
||||
|
||||
draw_filled_rect_mut(&mut shadow, rect, self.shadow_color);
|
||||
|
||||
|
@ -300,62 +300,6 @@ pub(crate) fn round_corner(image: &mut DynamicImage, radius: u32) {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
// `draw_filled_circle_mut` doesn't work well with small radius in imageproc v0.18.0
|
||||
// it has been fixed but still have to wait for releasing
|
||||
// issue: https://github.com/image-rs/imageproc/issues/328
|
||||
// PR: https://github.com/image-rs/imageproc/pull/330
|
||||
/// Draw as much of a circle, including its contents, as lies inside the image bounds.
|
||||
pub(crate) fn draw_filled_circle_mut<I>(
|
||||
image: &mut I,
|
||||
center: (i32, i32),
|
||||
radius: i32,
|
||||
color: I::Pixel,
|
||||
) where
|
||||
I: GenericImage,
|
||||
I::Pixel: 'static,
|
||||
{
|
||||
let mut x = 0i32;
|
||||
let mut y = radius;
|
||||
let mut p = 1 - radius;
|
||||
let x0 = center.0;
|
||||
let y0 = center.1;
|
||||
|
||||
while x <= y {
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - x) as f32, (y0 + y) as f32),
|
||||
((x0 + x) as f32, (y0 + y) as f32),
|
||||
color,
|
||||
);
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - y) as f32, (y0 + x) as f32),
|
||||
((x0 + y) as f32, (y0 + x) as f32),
|
||||
color,
|
||||
);
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - x) as f32, (y0 - y) as f32),
|
||||
((x0 + x) as f32, (y0 - y) as f32),
|
||||
color,
|
||||
);
|
||||
draw_line_segment_mut(
|
||||
image,
|
||||
((x0 - y) as f32, (y0 - x) as f32),
|
||||
((x0 + y) as f32, (y0 - x) as f32),
|
||||
color,
|
||||
);
|
||||
|
||||
x += 1;
|
||||
if p < 0 {
|
||||
p += 2 * x + 1;
|
||||
} else {
|
||||
y -= 1;
|
||||
p += 2 * (x - y) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::ToRgba;
|
||||
|
|
Loading…
Reference in New Issue