properties_view: Use physical size and resolution
Replace the API that got removed from glycin
This commit is contained in:
parent
ffe42a7c6c
commit
c7223f6f69
11 changed files with 254 additions and 101 deletions
106
Cargo.lock
generated
106
Cargo.lock
generated
|
|
@ -946,8 +946,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin"
|
name = "glycin"
|
||||||
version = "4.0.0-alpha"
|
version = "4.0.0-alpha.1"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glycin-builtin",
|
"glycin-builtin",
|
||||||
"glycin-external",
|
"glycin-external",
|
||||||
|
|
@ -955,16 +955,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-builtin"
|
name = "glycin-builtin"
|
||||||
version = "4.0.0-alpha"
|
version = "4.0.0-alpha.1"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glycin-core",
|
"glycin-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-common"
|
name = "glycin-common"
|
||||||
version = "2.0.0-alpha"
|
version = "2.0.0-alpha.1"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.13.0",
|
"bitflags 2.13.0",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
|
|
@ -981,8 +981,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-core"
|
name = "glycin-core"
|
||||||
version = "4.0.0-alpha"
|
version = "4.0.0-alpha.1"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-fs",
|
"async-fs",
|
||||||
"async-global-executor",
|
"async-global-executor",
|
||||||
|
|
@ -1002,8 +1002,9 @@ dependencies = [
|
||||||
"glycin-common",
|
"glycin-common",
|
||||||
"glycin-image-rs",
|
"glycin-image-rs",
|
||||||
"glycin-utils",
|
"glycin-utils",
|
||||||
|
"gufo",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"gufo-exif",
|
"gufo-exif 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"half",
|
"half",
|
||||||
"libc",
|
"libc",
|
||||||
"libseccomp",
|
"libseccomp",
|
||||||
|
|
@ -1018,36 +1019,38 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-external"
|
name = "glycin-external"
|
||||||
version = "4.0.0-alpha"
|
version = "4.0.0-alpha.1"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glycin-core",
|
"glycin-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-image-rs"
|
name = "glycin-image-rs"
|
||||||
version = "2.2.0-alpha"
|
version = "2.2.0-alpha.6"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
"exr",
|
"exr",
|
||||||
"glycin-utils",
|
"glycin-utils",
|
||||||
"gufo",
|
"gufo",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"gufo-exif",
|
"gufo-exif 0.5.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gufo-jpeg",
|
"gufo-jpeg 0.5.0-alpha.2",
|
||||||
"hayro-jpeg2000",
|
"hayro-jpeg2000",
|
||||||
"image",
|
"image",
|
||||||
"image-extras",
|
"image-extras",
|
||||||
"jpeg-encoder",
|
"jpeg-encoder",
|
||||||
"log",
|
"log",
|
||||||
"moxcms",
|
"moxcms",
|
||||||
|
"tiff",
|
||||||
"zune-jpeg",
|
"zune-jpeg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glycin-utils"
|
name = "glycin-utils"
|
||||||
version = "5.0.0-alpha"
|
version = "5.0.0-alpha.1"
|
||||||
source = "git+https://gitlab.gnome.org/GNOME/glycin.git#2b0f1b1e217ce17ebe45aecdda7096ed4eea8343"
|
source = "git+https://gitlab.gnome.org/GNOME/glycin.git?rev=32083724ee730fb6b35b6382fb8af7b6ab1f2992#32083724ee730fb6b35b6382fb8af7b6ab1f2992"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-lock",
|
"async-lock",
|
||||||
"bitflags 2.13.0",
|
"bitflags 2.13.0",
|
||||||
|
|
@ -1192,14 +1195,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo"
|
name = "gufo"
|
||||||
version = "0.5.0-alpha"
|
version = "0.5.0-alpha.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
checksum = "d97d857a79df06e10cd669541ed0a42d471a45a5201ce99535baf99b18c4129a"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"gufo-exif",
|
"gufo-exif 0.5.0-alpha.3 (git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581)",
|
||||||
"gufo-jpeg",
|
"gufo-jpeg 0.5.0-alpha.3",
|
||||||
"gufo-png",
|
"gufo-png",
|
||||||
"gufo-tiff",
|
"gufo-tiff",
|
||||||
"gufo-webp",
|
"gufo-webp",
|
||||||
|
|
@ -1210,9 +1212,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-common"
|
name = "gufo-common"
|
||||||
version = "2.0.0-alpha"
|
version = "2.0.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
checksum = "970e26402b2750cf3fbbf49116dca9fc010c939013125623c94da632f1ba76e8"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"paste",
|
"paste",
|
||||||
|
|
@ -1223,9 +1224,22 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-exif"
|
name = "gufo-exif"
|
||||||
version = "0.5.0-alpha.1"
|
version = "0.5.0-alpha.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1597401629a6778cbea663e6af6680fbcd07ab243cc8eee9bc5ef5d2c9e5eab8"
|
checksum = "e68d453f54f396ca43664463e3fa93de6ece835e113dd63f694349d669382821"
|
||||||
|
dependencies = [
|
||||||
|
"gufo-common",
|
||||||
|
"indexmap",
|
||||||
|
"ouroboros",
|
||||||
|
"thiserror",
|
||||||
|
"tracing",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gufo-exif"
|
||||||
|
version = "0.5.0-alpha.3"
|
||||||
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
|
|
@ -1238,22 +1252,34 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-jpeg"
|
name = "gufo-jpeg"
|
||||||
version = "0.5.0-alpha"
|
version = "0.5.0-alpha.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "004fec8f321842386ba7decc6ee03dde7ed35f29c3586861a5c708cca1e4259b"
|
checksum = "fa46d802b33586d3a1fd412b3fbb2b10ffbcde5aecbe5fddb4d61c827a001b9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"jpeg-encoder",
|
"jpeg-encoder",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gufo-jpeg"
|
||||||
|
version = "0.5.0-alpha.3"
|
||||||
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
|
dependencies = [
|
||||||
|
"gufo-common",
|
||||||
|
"indexmap",
|
||||||
|
"thiserror",
|
||||||
|
"tracing",
|
||||||
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-png"
|
name = "gufo-png"
|
||||||
version = "0.5.0-alpha"
|
version = "0.5.0-alpha.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
checksum = "810e7750b869abb84c6162ad01a240f388a924d2d469ae30a0c2c11a28e81813"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
|
|
@ -1265,9 +1291,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-tiff"
|
name = "gufo-tiff"
|
||||||
version = "0.5.0-alpha"
|
version = "0.5.0-alpha.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
checksum = "0a937aa0a245c9602aa9ed4857b6fc8f184cc43cf91e18d982c74c698e20afd5"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
@ -1275,9 +1300,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-webp"
|
name = "gufo-webp"
|
||||||
version = "0.5.0-alpha"
|
version = "0.5.0-alpha.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
checksum = "662c18ba5eef44d65c1694ebede033783ab5b48eb81366c1625deaaf75c47a18"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
@ -1285,9 +1309,8 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gufo-xmp"
|
name = "gufo-xmp"
|
||||||
version = "0.5.0-alpha"
|
version = "0.5.0-alpha.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gufo-rs/gufo.git?rev=ac92bd426543bc33b36b6cbc8443455b6a882581#ac92bd426543bc33b36b6cbc8443455b6a882581"
|
||||||
checksum = "ea3cc4abbf29cddc6ffc1a4473eec79f11cf742bc113f9bd319ca1d7fcedfc39"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"gufo-common",
|
"gufo-common",
|
||||||
|
|
@ -1625,7 +1648,6 @@ dependencies = [
|
||||||
"glycin",
|
"glycin",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
"gufo",
|
"gufo",
|
||||||
"gufo-common",
|
|
||||||
"gvdb-macros",
|
"gvdb-macros",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ rust-version = "1.93"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
glycin = { git = "https://gitlab.gnome.org/GNOME/glycin.git" }
|
glycin = { git = "https://gitlab.gnome.org/GNOME/glycin.git", rev = "32083724ee730fb6b35b6382fb8af7b6ab1f2992" }
|
||||||
|
gufo = { git = "https://github.com/gufo-rs/gufo.git", rev = "ac92bd426543bc33b36b6cbc8443455b6a882581" }
|
||||||
|
gufo-common = { git = "https://github.com/gufo-rs/gufo.git", rev = "ac92bd426543bc33b36b6cbc8443455b6a882581" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|
@ -36,8 +38,7 @@ gtk = { package = "gtk4", version = "0.11.0", features = [
|
||||||
"v4_14",
|
"v4_14",
|
||||||
"xml_validation",
|
"xml_validation",
|
||||||
] }
|
] }
|
||||||
gufo = { version = "0.5.0-alpha", features = ["chrono"] }
|
gufo = { version = "0.5.0-alpha.2", features = ["chrono"] }
|
||||||
gufo-common = { version = "2.0.0-alpha", features = ["serde"] }
|
|
||||||
gvdb-macros = "0.1.6"
|
gvdb-macros = "0.1.6"
|
||||||
indexmap = "2.0.0"
|
indexmap = "2.0.0"
|
||||||
libc = "0.2.158"
|
libc = "0.2.158"
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
use glycin::{Operation, Operations};
|
use glycin::{Operation, Operations};
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gufo_common::orientation::Rotation;
|
use gufo::common::orientation::Rotation;
|
||||||
|
|
||||||
use crate::deps::*;
|
use crate::deps::*;
|
||||||
|
|
||||||
|
|
@ -145,7 +145,7 @@ impl OperationsSnapshot {
|
||||||
|
|
||||||
fn rotate(
|
fn rotate(
|
||||||
&mut self,
|
&mut self,
|
||||||
rotation: gufo_common::orientation::Rotation,
|
rotation: gufo::common::orientation::Rotation,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
let snapshot = gtk::Snapshot::new();
|
let snapshot = gtk::Snapshot::new();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ use glib::TimeZone;
|
||||||
use glycin::{Frame, FrameDetails, ImageDetails, MemoryFormat};
|
use glycin::{Frame, FrameDetails, ImageDetails, MemoryFormat};
|
||||||
use gufo::common::datetime::DateTime;
|
use gufo::common::datetime::DateTime;
|
||||||
use gufo::common::orientation::Orientation;
|
use gufo::common::orientation::Orientation;
|
||||||
|
use gufo::common::physical_dimension;
|
||||||
|
|
||||||
use crate::deps::*;
|
use crate::deps::*;
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
@ -169,16 +170,6 @@ impl Metadata {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dimensions_inch(&self) -> Option<(f64, f64)> {
|
|
||||||
self.image_info.as_ref().and_then(|x| x.dimensions_inch())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dimensions_text(&self) -> Option<String> {
|
|
||||||
self.image_info
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|x| x.info_dimensions_text().map(|x| x.to_string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn file_name(&self) -> Option<String> {
|
pub fn file_name(&self) -> Option<String> {
|
||||||
self.file_info.as_ref().map(|x| x.display_name.to_string())
|
self.file_info.as_ref().map(|x| x.display_name.to_string())
|
||||||
}
|
}
|
||||||
|
|
@ -436,4 +427,12 @@ impl Metadata {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pixel_density(&self) -> Option<physical_dimension::PixelDensity> {
|
||||||
|
self.frame_info.as_ref().and_then(|x| x.pixel_density())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn physical_size(&self) -> Option<physical_dimension::PhysicalSize> {
|
||||||
|
self.frame_info.as_ref().and_then(|x| x.physical_size())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
27
src/util.rs
27
src/util.rs
|
|
@ -267,3 +267,30 @@ pub enum ErrorType {
|
||||||
Loader,
|
Loader,
|
||||||
General,
|
General,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn locale_uses_inch() -> bool {
|
||||||
|
// Use inch for USA and Liberia
|
||||||
|
if let Some(unit_locale) = getlocale(gettextrs::LocaleCategory::LcMeasurement)
|
||||||
|
&& let Some(locale) = unit_locale
|
||||||
|
.split(|x| *x == b'_')
|
||||||
|
.nth(1)
|
||||||
|
.and_then(|x| x.get(0..2))
|
||||||
|
&& (locale == b"US" || locale == b"LR")
|
||||||
|
{
|
||||||
|
dbg!(true)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Upstream to gettext if possible
|
||||||
|
fn getlocale(category: gettextrs::LocaleCategory) -> Option<Vec<u8>> {
|
||||||
|
unsafe {
|
||||||
|
let ret = gettext_sys::setlocale(category as i32, std::ptr::null());
|
||||||
|
if ret.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(std::ffi::CStr::from_ptr(ret).to_bytes().to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,14 +254,14 @@ mod imp {
|
||||||
|
|
||||||
fn apply_rotate_cw(&self) {
|
fn apply_rotate_cw(&self) {
|
||||||
self.apply_crop();
|
self.apply_crop();
|
||||||
self.add_operation(Operation::Rotate(gufo_common::orientation::Rotation::_270));
|
self.add_operation(Operation::Rotate(gufo::common::orientation::Rotation::_270));
|
||||||
|
|
||||||
self.reset_selection();
|
self.reset_selection();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_rotate_ccw(&self) {
|
fn apply_rotate_ccw(&self) {
|
||||||
self.apply_crop();
|
self.apply_crop();
|
||||||
self.add_operation(Operation::Rotate(gufo_common::orientation::Rotation::_90));
|
self.add_operation(Operation::Rotate(gufo::common::orientation::Rotation::_90));
|
||||||
|
|
||||||
self.reset_selection();
|
self.reset_selection();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ use adw::prelude::*;
|
||||||
use adw::subclass::prelude::*;
|
use adw::subclass::prelude::*;
|
||||||
use glib::subclass::Signal;
|
use glib::subclass::Signal;
|
||||||
use glib::{Properties, SignalGroup};
|
use glib::{Properties, SignalGroup};
|
||||||
use gufo_common::orientation::Orientation;
|
use gufo::common::orientation::Orientation;
|
||||||
|
|
||||||
use crate::decoder::tiling::SharedFrameBuffer;
|
use crate::decoder::tiling::SharedFrameBuffer;
|
||||||
use crate::decoder::{self, Decoder, DecoderUpdate, tiling};
|
use crate::decoder::{self, Decoder, DecoderUpdate, tiling};
|
||||||
|
|
|
||||||
|
|
@ -104,8 +104,8 @@ impl LpImage {
|
||||||
zoom_animation.play();
|
zoom_animation.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(r) = gufo_common::orientation::Rotation::try_from(angle)
|
if let Ok(r) = gufo::common::orientation::Rotation::try_from(angle)
|
||||||
&& r != gufo_common::orientation::Rotation::_0
|
&& r != gufo::common::orientation::Rotation::_0
|
||||||
{
|
{
|
||||||
tracing::debug!("Editing image to rotate by {r:?}");
|
tracing::debug!("Editing image to rotate by {r:?}");
|
||||||
let operation = glycin::Operation::Rotate(r);
|
let operation = glycin::Operation::Rotate(r);
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ impl Unit {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
|
use crate::util;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug, Default, CompositeTemplate, Properties)]
|
#[derive(Debug, Default, CompositeTemplate, Properties)]
|
||||||
|
|
@ -388,13 +390,7 @@ mod imp {
|
||||||
.set_value(size_unit.round(obj.original_size().0 * obj.width_unit_factor()));
|
.set_value(size_unit.round(obj.original_size().0 * obj.width_unit_factor()));
|
||||||
|
|
||||||
// Default to inch for USA and Liberia
|
// Default to inch for USA and Liberia
|
||||||
if let Some(unit_locale) = getlocale(gettextrs::LocaleCategory::LcMeasurement)
|
if util::locale_uses_inch() {
|
||||||
&& let Some(locale) = unit_locale
|
|
||||||
.split(|x| *x == b'_')
|
|
||||||
.nth(1)
|
|
||||||
.and_then(|x| x.get(0..2))
|
|
||||||
&& (locale == b"US" || locale == b"LR")
|
|
||||||
{
|
|
||||||
imp.margin_unit.set_selected(Unit::Inch as u32);
|
imp.margin_unit.set_selected(Unit::Inch as u32);
|
||||||
imp.size_unit.set_selected(Unit::Inch as u32);
|
imp.size_unit.set_selected(Unit::Inch as u32);
|
||||||
}
|
}
|
||||||
|
|
@ -525,13 +521,22 @@ impl LpPrint {
|
||||||
|
|
||||||
pub fn original_size(&self) -> (f64, f64) {
|
pub fn original_size(&self) -> (f64, f64) {
|
||||||
let image = self.image();
|
let image = self.image();
|
||||||
|
let (x_pixels, y_pixels) = image.image_size();
|
||||||
let metadata = image.metadata();
|
let metadata = image.metadata();
|
||||||
if let Some((w, h)) = metadata.dimensions_inch() {
|
|
||||||
|
if let Some(physical_size) = metadata.physical_size().map(|x| x.dpi()).or_else(|| {
|
||||||
|
metadata
|
||||||
|
.pixel_density()
|
||||||
|
.map(|x| x.physical_size(x_pixels as u32, y_pixels as u32))
|
||||||
|
}) {
|
||||||
let dpi = self.dpi();
|
let dpi = self.dpi();
|
||||||
|
|
||||||
((w * dpi).round(), (h * dpi).round())
|
(
|
||||||
|
(physical_size.x.value() * dpi).round(),
|
||||||
|
(physical_size.y.value() * dpi).round(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
let (w, h) = self.image().image_size();
|
let (w, h) = image.image_size();
|
||||||
|
|
||||||
(w as f64, h as f64)
|
(w as f64, h as f64)
|
||||||
}
|
}
|
||||||
|
|
@ -968,15 +973,3 @@ impl LpPrint {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Upstream to gettext if possible
|
|
||||||
pub fn getlocale(category: gettextrs::LocaleCategory) -> Option<Vec<u8>> {
|
|
||||||
unsafe {
|
|
||||||
let ret = gettext_sys::setlocale(category as i32, std::ptr::null());
|
|
||||||
if ret.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(std::ffi::CStr::from_ptr(ret).to_bytes().to_owned())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ use crate::widgets::image::LpImage;
|
||||||
const FALLBACK: &str = "–";
|
const FALLBACK: &str = "–";
|
||||||
|
|
||||||
mod imp {
|
mod imp {
|
||||||
|
use gufo::common::physical_dimension::PhysicalDimensionUnit;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[derive(Debug, Default, CompositeTemplate, Properties)]
|
#[derive(Debug, Default, CompositeTemplate, Properties)]
|
||||||
|
|
@ -54,6 +56,10 @@ mod imp {
|
||||||
#[template_child]
|
#[template_child]
|
||||||
image_size: TemplateChild<adw::ActionRow>,
|
image_size: TemplateChild<adw::ActionRow>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
|
physical_size: TemplateChild<adw::ActionRow>,
|
||||||
|
#[template_child]
|
||||||
|
pixel_density: TemplateChild<adw::ActionRow>,
|
||||||
|
#[template_child]
|
||||||
image_format: TemplateChild<adw::ActionRow>,
|
image_format: TemplateChild<adw::ActionRow>,
|
||||||
#[template_child]
|
#[template_child]
|
||||||
file_size: TemplateChild<adw::ActionRow>,
|
file_size: TemplateChild<adw::ActionRow>,
|
||||||
|
|
@ -219,6 +225,8 @@ mod imp {
|
||||||
|
|
||||||
// Image info
|
// Image info
|
||||||
Self::update_row(&self.image_size, self.image_size());
|
Self::update_row(&self.image_size, self.image_size());
|
||||||
|
Self::update_row(&self.physical_size, self.physical_size());
|
||||||
|
Self::update_row(&self.pixel_density, self.pixel_density());
|
||||||
Self::update_row(&self.image_format, self.format_name());
|
Self::update_row(&self.image_format, self.format_name());
|
||||||
Self::update_row(&self.file_size, metadata.file_size());
|
Self::update_row(&self.file_size, metadata.file_size());
|
||||||
|
|
||||||
|
|
@ -289,30 +297,113 @@ mod imp {
|
||||||
|
|
||||||
fn image_size(&self) -> Option<String> {
|
fn image_size(&self) -> Option<String> {
|
||||||
let obj = self.obj();
|
let obj = self.obj();
|
||||||
|
let image = obj.image()?;
|
||||||
|
let physical_size = image.metadata().physical_size();
|
||||||
|
|
||||||
if let Some(image) = obj.image() {
|
if physical_size.is_none() {
|
||||||
match image.metadata().dimensions_text() {
|
let (width, height) = image.image_size();
|
||||||
Some(string) => Some(string.to_string()),
|
if width > 0 && height > 0 {
|
||||||
_ => {
|
Some(
|
||||||
let (width, height) = image.image_size();
|
// Translators: Image "<width> x <height>"
|
||||||
if width > 0 && height > 0 {
|
gettext_f(
|
||||||
Some(
|
r"{}\u{202F}\u{D7}\u{202F}{}",
|
||||||
// Translators: Image "<width> x <height>"
|
[width.to_string(), height.to_string()],
|
||||||
gettext_f(
|
),
|
||||||
r"{}\u{202F}\u{D7}\u{202F}{}",
|
)
|
||||||
[width.to_string(), height.to_string()],
|
} else {
|
||||||
),
|
None
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn physical_size(&self) -> Option<String> {
|
||||||
|
let obj = self.obj();
|
||||||
|
let image = obj.image()?;
|
||||||
|
let (width, height) = image.image_size();
|
||||||
|
let metadata = image.metadata();
|
||||||
|
|
||||||
|
let default_unit = if util::locale_uses_inch() {
|
||||||
|
PhysicalDimensionUnit::Inch
|
||||||
|
} else {
|
||||||
|
PhysicalDimensionUnit::Centimeter
|
||||||
|
};
|
||||||
|
|
||||||
|
let physical_size = metadata.physical_size().or_else(|| {
|
||||||
|
metadata.pixel_density().map(|x| {
|
||||||
|
x.physical_size(width as u32, height as u32)
|
||||||
|
.convert(default_unit)
|
||||||
|
})
|
||||||
|
})?;
|
||||||
|
|
||||||
|
const ROUND: f64 = 100.;
|
||||||
|
let x = (physical_size.x.value() * ROUND).round() / ROUND;
|
||||||
|
let y = (physical_size.y.value() * ROUND).round() / ROUND;
|
||||||
|
|
||||||
|
let unit = |x| {
|
||||||
|
match x {
|
||||||
|
PhysicalDimensionUnit::Centimeter => {
|
||||||
|
// Translators: Shorthand for centimeter
|
||||||
|
gettext("\u{202F}cm")
|
||||||
|
}
|
||||||
|
PhysicalDimensionUnit::Inch => {
|
||||||
|
// Translators: Shorthand for inch
|
||||||
|
gettext("\u{2033}")
|
||||||
|
}
|
||||||
|
PhysicalDimensionUnit::Meter => {
|
||||||
|
// Translators: Shorthand for meter
|
||||||
|
gettext("\u{202F}m")
|
||||||
|
}
|
||||||
|
PhysicalDimensionUnit::Millimeter => {
|
||||||
|
// Translators: Shorthand for millimeter
|
||||||
|
gettext("\u{202F}mm")
|
||||||
|
}
|
||||||
|
PhysicalDimensionUnit::Pica => {
|
||||||
|
// Translators: Shorthand for pica (unit)
|
||||||
|
gettext("\u{202F}pc")
|
||||||
|
}
|
||||||
|
PhysicalDimensionUnit::Point => {
|
||||||
|
// Translators: Shorthand for pica (unit)
|
||||||
|
gettext("\u{202F}pt")
|
||||||
|
}
|
||||||
|
x => x.shorthand().to_string(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let x_unit = unit(physical_size.x.unit());
|
||||||
|
let y_unit = unit(physical_size.y.unit());
|
||||||
|
|
||||||
|
Some(
|
||||||
|
// Translators: Image "<width> x <height>"
|
||||||
|
gettext_f(
|
||||||
|
r"{}{}\u{202F}\u{D7}\u{202F}{}{}",
|
||||||
|
[x.to_string(), x_unit, y.to_string(), y_unit],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pixel_density(&self) -> Option<String> {
|
||||||
|
let obj = self.obj();
|
||||||
|
let image = obj.image()?;
|
||||||
|
let metadata = image.metadata();
|
||||||
|
let pixel_density = metadata.pixel_density()?.dpi();
|
||||||
|
|
||||||
|
const ROUND: f64 = 10.;
|
||||||
|
let x = (pixel_density.x().value() * ROUND).round() / ROUND;
|
||||||
|
let y = (pixel_density.y().value() * ROUND).round() / ROUND;
|
||||||
|
|
||||||
|
Some(if x == y {
|
||||||
|
gettext_f(r"{}\u{202F}DPI", [x.to_string()])
|
||||||
|
} else {
|
||||||
|
// Translators: Image "<x-resolution> x <y-resolution>"
|
||||||
|
gettext_f(
|
||||||
|
r"{}\u{202F}DPI\u{202F}\u{D7}\u{202F}{}\u{202F}DPI",
|
||||||
|
[x.to_string(), y.to_string()],
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn file(&self) -> Option<gio::File> {
|
fn file(&self) -> Option<gio::File> {
|
||||||
self.image.borrow().as_ref().and_then(|x| x.file())
|
self.image.borrow().as_ref().and_then(|x| x.file())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,26 @@
|
||||||
</style>
|
</style>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwActionRow" id="physical_size">
|
||||||
|
<property name="title" translatable="yes">Physical Size</property>
|
||||||
|
<property name="subtitle-selectable">True</property>
|
||||||
|
<property name="use-markup">False</property>
|
||||||
|
<style>
|
||||||
|
<class name="property" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwActionRow" id="pixel_density">
|
||||||
|
<property name="title" translatable="yes">Resolution</property>
|
||||||
|
<property name="subtitle-selectable">True</property>
|
||||||
|
<property name="use-markup">False</property>
|
||||||
|
<style>
|
||||||
|
<class name="property" />
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwActionRow" id="image_format">
|
<object class="AdwActionRow" id="image_format">
|
||||||
<property name="title" translatable="yes">Image Format</property>
|
<property name="title" translatable="yes">Image Format</property>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue