commit 887d5d9e58e7f3673d6415d48375670eaff3b6f9 Author: Piyush Mishra Date: Wed Jan 12 02:32:41 2022 +0530 Changed Lot diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..26613a0 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,864 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13739d7177fbd22bb0ed28badfff9f372f8bef46c863db4e1c6248f6b223b6e" + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytemuck" +version = "1.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f34b09b9ee8c7c7b400fe2f8df39cafc9538b03d6ba7f4ae13e4cb90bfbb7d" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a0645a430ec9136d2d701e54a95d557de12649a9dd7109ced3187e648ac824" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cmake" +version = "0.1.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa-colors" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7fc3439406f349e0bc20d7de87314803378a535190d12e62991f7c8474d5296" +dependencies = [ + "cc", +] + +[[package]] +name = "color-maps" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120b737cc99b0d73bf0a9bfa6086e84c0bde3b955851f37f812865bc08b35feb" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "conv" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299" +dependencies = [ + "custom_derive", +] + +[[package]] +name = "crc32fast" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[package]] +name = "custom_derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9" + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "fltk" +version = "1.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2894b854989432cd0b13b48eb77178eb897f70b2aa5ef064575df226139ff668" +dependencies = [ + "bitflags", + "crossbeam-channel", + "fltk-sys", + "paste", +] + +[[package]] +name = "fltk-sys" +version = "1.2.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd352c677ae3a1cd20235368825cc6887847e502a753d01799ff2878d0950c9" +dependencies = [ + "cmake", +] + +[[package]] +name = "fltk-theme" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abee3d9b0ed8bd45d10e4cc279d757ce71c37224482e8377a99906f7be771266" +dependencies = [ + "cocoa-colors", + "color-maps", + "fltk", + "lazy_static", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "imageproc" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7923654f3ce7cb6849d5dc9e544aaeab49c508a90b56c721b046e7234c74ab53" +dependencies = [ + "conv", + "image", + "itertools", + "num 0.3.1", + "rand", + "rand_distr", + "rayon", + "rulinalg", + "rusttype", +] + +[[package]] +name = "indexmap" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.112" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" + +[[package]] +name = "matrixmultiply" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcad67dcec2d58ff56f6292582377e6921afdf3bfbd533e26fb8900ae575e002" +dependencies = [ + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "num" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +dependencies = [ + "num-integer", + "num-iter", + "num-traits", +] + +[[package]] +name = "num" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7a8e9be5e039e2ff869df49155f1c06bd01ade2117ec783e56ab0932b67a8f" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "post_maker" +version = "0.1.0" +dependencies = [ + "clap", + "fltk", + "fltk-theme", + "image", + "imageproc", + "rusttype", + "serde", + "serde_json", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "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", +] + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "rulinalg" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04ada202c9685e1d72a7420c578e92b358dbf807d3dfabb676a3dab9cc3bb12f" +dependencies = [ + "matrixmultiply", + "num 0.1.42", +] + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" + +[[package]] +name = "tiff" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a53f4706d65497df0c4349241deddf35f84cee19c87ed86ea8ca590f4464437" +dependencies = [ + "jpeg-decoder", + "miniz_oxide 0.4.4", + "weezl", +] + +[[package]] +name = "ttf-parser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a802e54 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "post_maker" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +clap = { version = "3.0", features = ["derive"] } +fltk = "1.2" +fltk-theme = "0.4" +image = "0.23" +imageproc = "0.22" +rusttype = "0.9" +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } diff --git a/Kalam-Regular.ttf b/Kalam-Regular.ttf new file mode 100644 index 0000000..16f1586 Binary files /dev/null and b/Kalam-Regular.ttf differ diff --git a/ReenieBeanie-Regular.ttf b/ReenieBeanie-Regular.ttf new file mode 100644 index 0000000..73f5d59 Binary files /dev/null and b/ReenieBeanie-Regular.ttf differ diff --git a/bearbrickjia-20211228-0002.jpg b/bearbrickjia-20211228-0002.jpg new file mode 100644 index 0000000..552f2e1 Binary files /dev/null and b/bearbrickjia-20211228-0002.jpg differ diff --git a/eae7e510f03c7afc0d44863525df184f.jpg b/eae7e510f03c7afc0d44863525df184f.jpg new file mode 100644 index 0000000..bead3c8 Binary files /dev/null and b/eae7e510f03c7afc0d44863525df184f.jpg differ diff --git a/out.png b/out.png new file mode 100644 index 0000000..948157b Binary files /dev/null and b/out.png differ diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..68565cb --- /dev/null +++ b/src/config.rs @@ -0,0 +1,61 @@ +use clap::{ArgEnum, Parser}; +use fltk_theme::ThemeType; + +/// Simple program calculate size of stuff in quote image +#[derive(Parser, Debug)] +#[clap(about, version, author)] +pub(crate) struct Args { + /// Theme to use for gui + #[clap(short, long, arg_enum)] + pub(crate) theme: Option, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, ArgEnum)] +pub(crate) enum Themes { + Classic, + /// Windows 7 + Aero, + /// Windows 8 + Metro, + /// Classic MacOS + AquaClassic, + /// Xfce + Greybird, + /// Windows 2000 + Blue, + /// Dark + Dark, + /// High Contrast + HighContrast, + /// Get from System + System, +} + +impl Into for Themes { + fn into(self) -> ThemeType { + match self { + Self::Classic => ThemeType::Classic, + Self::Aero => ThemeType::Aero, + Self::Metro => ThemeType::Metro, + Self::AquaClassic => ThemeType::AquaClassic, + Self::Greybird => ThemeType::Greybird, + Self::Blue => ThemeType::Blue, + Self::Dark => ThemeType::Dark, + Self::HighContrast => ThemeType::HighContrast, + Self::System => { + if cfg!(windows) { + ThemeType::Metro + } else if cfg!(unix) { + ThemeType::Greybird + } else { + ThemeType::Classic + } + } + } + } +} + +pub(crate) fn config() -> Args { + let args = Args::parse(); + args +} diff --git a/src/crop_window.rs b/src/crop_window.rs new file mode 100644 index 0000000..fe975dc --- /dev/null +++ b/src/crop_window.rs @@ -0,0 +1,170 @@ +use crate::utils::{self, ImageContainer}; +use fltk::{ + app, button::Button, draw, enums::Event, frame::Frame, group::Flex, prelude::*, window::Window, +}; +use image::GenericImageView; +use std::{cell::RefCell, rc::Rc}; + +pub(crate) struct CropWindow { + pub win: Window, + apply_btn: Button, + img_view: Frame, + img: Rc>, + bound: Rc>, +} + +impl CropWindow { + pub(crate) fn new(container: Rc>) -> Self { + // let image = &container.borrow().image; + let (image_width, image_height) = container.borrow().image.dimensions(); + let mut win = Window::default() + .with_size(image_width as i32, 600) + .with_label("Crop"); + + let mut main_flex = Flex::default().size_of_parent().column(); + + // Work area + let mut center_row_flex = Flex::default().row(); + Frame::default(); + + let mut center_col_flex = Flex::default().column(); + Frame::default(); + let img_view = Frame::default(); + Frame::default(); + center_col_flex.set_size(&img_view, image_height as i32); + center_col_flex.end(); + + Frame::default(); + center_row_flex.set_size(¢er_col_flex, image_width as i32); + center_row_flex.end(); + + // Panel + let top_padding_btn = Frame::default(); + let mut panel_flex = Flex::default().row(); + Frame::default(); + let apply_btn = Button::default().with_label("apply"); + Frame::default(); + panel_flex.set_size(&apply_btn, 100); + panel_flex.end(); + let bottom_padding_btn = Frame::default(); + + main_flex.set_size(&top_padding_btn, 5); + main_flex.set_size(&panel_flex, 30); + main_flex.set_size(&bottom_padding_btn, 5); + main_flex.end(); + + win.end(); + win.make_resizable(true); + + let (bound_width, bound_height) = utils::get_4_5(image_width, image_height); + let bound_x = image_width / 2 - bound_width / 2; + let bound_y = image_height / 2 - bound_height / 2; + + let mut crop_win = Self { + win, + apply_btn, + img_view, + img: Rc::clone(&container), + bound: Rc::new(RefCell::new((bound_x, bound_y, bound_width, bound_height))), + }; + + crop_win.draw(); + crop_win.event(); + crop_win + } + + fn draw(&mut self) { + let cont = Rc::clone(&self.img); + let bound = Rc::clone(&self.bound); + self.img_view.draw(move |f| { + let image = &cont.borrow().image; + let (bound_x, bound_y, bound_width, bound_height) = *bound.borrow(); + draw::draw_image( + image.as_rgb8().unwrap().as_raw(), + f.x(), + f.y(), + image.width() as i32, + image.height() as i32, + fltk::enums::ColorDepth::Rgb8, + ) + .unwrap(); + draw::set_color_rgb(255, 0, 0); + draw::draw_rect( + f.x() + bound_x as i32, + f.y() + bound_y as i32, + bound_width as i32, + bound_height as i32, + ); + }); + } + + fn event(&mut self) { + let mut last: Option<(i32, i32)> = None; + let cont = Rc::clone(&self.img); + let bound = Rc::clone(&self.bound); + self.img_view.handle(move |f, ev| { + let image = &cont.borrow().image; + let (bound_x, bound_y, bound_width, bound_height) = *bound.borrow(); + if ev == Event::Push { + last = Some((app::event_x(), app::event_y())); + } else if ev == Event::Drag { + if let Some((lx, ly)) = last { + let dx = app::event_x() - lx; + if (dx > 0 && bound_x + bound_width < image.width()) || (dx < 0 && bound_x > 0) + { + let mut new_x = bound_x as i32 + dx; + if new_x + bound_width as i32 > image.width() as i32 { + new_x = (image.width() - bound_width) as i32 + } else if new_x < 0 { + new_x = 0 + } + + bound.borrow_mut().0 = new_x as u32; + } + + let dy = app::event_y() - ly; + if (dy > 0 && bound_y + bound_height < image.height()) + || (dy < 0 && bound_y > 0) + { + let mut new_y = bound_y as i32 + dy; + if new_y + bound_height as i32 > image.height() as i32 { + new_y = (image.height() - bound_height) as i32 + } else if new_y < 0 { + new_y = 0 + } + + bound.borrow_mut().1 = new_y as u32; + } + + f.redraw(); + last = Some((app::event_x(), app::event_y())); + } + } else if ev == Event::Released { + last = None; + } + true + }); + + let mut wind = self.win.clone(); + let cont = Rc::clone(&self.img); + let bound = Rc::clone(&self.bound); + self.apply_btn.set_callback(move |_| { + let (bound_x, bound_y, bound_width, bound_height) = *bound.borrow(); + + let image = cont + .borrow_mut() + .image + .crop(bound_x, bound_y, bound_width, bound_height); + + cont.borrow_mut().image = image; + + let (width, height) = cont.borrow().original_dimension; + cont.borrow_mut().crop_position = Some(( + (bound_x * width) / bound_width, + (bound_y * height) / bound_height, + )); + + wind.do_callback(); + }); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b41bff3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,34 @@ +mod config; +// mod crop_window; +mod main_window; +mod properties; +mod utils; + +// use crop_window::CropWindow; +use fltk::{app::App, enums::Font}; +use fltk_theme::WidgetTheme; +use main_window::MainWindow; +use std::{cell::RefCell, rc::Rc}; +use utils::ImageContainer; + +fn main() { + let app = App::default(); + + WidgetTheme::new( + config::config() + .theme + .unwrap_or(config::Themes::System) + .into(), + ) + .apply(); + + let f1 = Font::load_font("ReenieBeanie-Regular.ttf").unwrap(); + let f2 = Font::load_font("Kalam-Regular.ttf").unwrap(); + Font::set_font(Font::Times, &f1); + Font::set_font(Font::TimesItalic, &f2); + + let container: Rc>> = Rc::new(RefCell::new(None)); + + let main_win = MainWindow::new(Rc::clone(&container)); + app.run().unwrap(); +} diff --git a/src/main_window.rs b/src/main_window.rs new file mode 100644 index 0000000..b3b3120 --- /dev/null +++ b/src/main_window.rs @@ -0,0 +1,402 @@ +use crate::utils::ImageContainer; +use crate::{properties::Properties, utils}; +use fltk::{ + button::Button, + dialog::NativeFileChooser, + draw as dr, enums, + enums::Shortcut, + frame::Frame, + group::Flex, + input::{Input, MultilineInput}, + menu, + misc::Spinner, + prelude::*, + window::Window, +}; +use image::GenericImageView; +use std::io::Read; +use std::{cell::RefCell, ffi::OsStr, fs, path::Path, rc::Rc}; + +pub(crate) struct MainWindow { + pub(crate) win: Window, + menubar: menu::SysMenuBar, + back_btn: Button, + next_btn: Button, + save_btn: Button, + file_choice: menu::Choice, + quote: MultilineInput, + tag: Input, + layer_red: Spinner, + layer_green: Spinner, + layer_blue: Spinner, + layer_alpha: Spinner, + quote_position: Spinner, + tag_position: Spinner, + crop_btn: Button, + reset_btn: Button, + page: Page, + container: Rc>>, +} + +#[derive(Clone)] +pub(crate) struct Page { + image: Frame, + row_flex: Flex, + col_flex: Flex, +} + +impl MainWindow { + pub(crate) fn new(container: Rc>>) -> Self { + let color = [25, 29, 34, 190]; + + let mut win = Window::default() + .with_size(1000, 600) + .with_label("Post Maker"); + + let mut main_flex = Flex::default().size_of_parent().column(); + let menubar = menu::SysMenuBar::default(); + main_flex.set_size(&menubar, 30); + + let mut toolbar_flex = Flex::default().row(); + let back_btn = Button::default().with_label("Back"); + toolbar_flex.set_size(&back_btn, 50); + let next_btn = Button::default().with_label("Next"); + toolbar_flex.set_size(&next_btn, 50); + let save_btn = Button::default().with_label("Save"); + toolbar_flex.set_size(&save_btn, 50); + let file_choice = menu::Choice::default(); + toolbar_flex.end(); + main_flex.set_size(&toolbar_flex, 30); + + let mut workspace_flex = Flex::default().row(); + // Controls + let mut controls_flex = Flex::default().column(); + controls_flex.set_size( + &Frame::default() + .with_label("Quote:") + .with_align(enums::Align::Left | enums::Align::Inside), + 20, + ); + let quote = MultilineInput::default(); + controls_flex.set_size("e, 90); + controls_flex.set_size( + &Frame::default() + .with_label("Tag:") + .with_align(enums::Align::Left | enums::Align::Inside), + 20, + ); + let tag = Input::default(); + controls_flex.set_size(&tag, 30); + controls_flex.set_size( + &Frame::default() + .with_label("Dark Layer (RGBA):") + .with_align(enums::Align::Left | enums::Align::Inside), + 20, + ); + let mut darklayer_flex = Flex::default().row(); + darklayer_flex.set_pad(2); + darklayer_flex.set_size(&Frame::default().with_label("Red"), 30); + let mut layer_red = Spinner::default(); + layer_red.set_range(0.0, 255.0); + layer_red.set_value(color[0] as f64); + darklayer_flex.set_size(&layer_red, 50); + darklayer_flex.set_size(&Frame::default().with_label("Green"), 40); + let mut layer_green = Spinner::default(); + layer_green.set_range(0.0, 255.0); + layer_green.set_value(color[1] as f64); + darklayer_flex.set_size(&layer_green, 50); + darklayer_flex.set_size(&Frame::default().with_label("Blue"), 30); + let mut layer_blue = Spinner::default(); + layer_blue.set_range(0.0, 255.0); + layer_blue.set_value(color[2] as f64); + darklayer_flex.set_size(&layer_blue, 50); + darklayer_flex.set_size(&Frame::default().with_label("Alpha"), 40); + let mut layer_alpha = Spinner::default(); + layer_alpha.set_range(0.0, 255.0); + layer_alpha.set_value(color[3] as f64); + darklayer_flex.set_size(&layer_alpha, 50); + darklayer_flex.end(); + controls_flex.set_size(&darklayer_flex, 30); + + let quote_position_flex = Flex::default().row(); + Frame::default() + .with_label("Quote Position:") + .with_align(enums::Align::Left | enums::Align::Inside); + let quote_position = fltk::misc::Spinner::default(); + quote_position_flex.end(); + controls_flex.set_size("e_position_flex, 30); + + let tag_position_flex = Flex::default().row(); + Frame::default() + .with_label("Tag Position:") + .with_align(enums::Align::Left | enums::Align::Inside); + let tag_position = fltk::misc::Spinner::default(); + tag_position_flex.end(); + controls_flex.set_size(&tag_position_flex, 30); + + let mut actions_flex = Flex::default().row(); + Frame::default(); + let crop_btn = Button::default().with_label("Crop"); + actions_flex.set_size(&crop_btn, 100); + let reset_btn = Button::default().with_label("Reset Values"); + actions_flex.set_size(&reset_btn, 100); + Frame::default(); + actions_flex.end(); + controls_flex.set_size(&actions_flex, 30); + + controls_flex.end(); + workspace_flex.set_size(&controls_flex, 360); + + // Page + let mut center_row_flex = Flex::default().row(); + Frame::default(); + let mut center_col_flex = Flex::default().column(); + Frame::default(); + let img_view = Frame::default(); + center_col_flex.set_size(&img_view, 500); + Frame::default(); + center_col_flex.end(); + Frame::default(); + center_row_flex.set_size(¢er_col_flex, 400); + center_row_flex.end(); + workspace_flex.end(); + + main_flex.end(); + + win.end(); + win.make_resizable(true); + win.show(); + + let mut main_win = Self { + win, + menubar, + back_btn, + next_btn, + save_btn, + file_choice, + quote, + tag, + layer_red, + layer_green, + layer_blue, + layer_alpha, + quote_position, + tag_position, + crop_btn, + reset_btn, + container, + page: Page { + image: img_view, + row_flex: center_row_flex, + col_flex: center_col_flex, + }, + }; + main_win.menu(); + main_win.draw(); + main_win.events(); + main_win + } + + fn menu(&mut self) { + let mut file_choice = self.file_choice.clone(); + let mut quote = self.quote.clone(); + let mut tag = self.tag.clone(); + let mut layer_red = self.layer_red.clone(); + let mut layer_green = self.layer_green.clone(); + let mut layer_blue = self.layer_blue.clone(); + let mut layer_alpha = self.layer_alpha.clone(); + let mut quote_position = self.quote_position.clone(); + let mut tag_position = self.tag_position.clone(); + let mut page = self.page.clone(); + let container = Rc::clone(&self.container); + let mut win = self.win.clone(); + self.menubar.add( + "&File/Open Folder...\t", + Shortcut::Ctrl | 'o', + menu::MenuFlag::Normal, + move |_| { + let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseDir); + chooser.set_option(fltk::dialog::FileDialogOptions::NewFolder); + chooser.show(); + let path = chooser.filename(); + if !path.exists() { + return; + } + let files = fs::read_dir(path).unwrap(); + let mut text = String::new(); + for file in files { + let file = file.unwrap(); + let path = file.path(); + if path.extension() == Some(OsStr::new("jpg")) { + text = format!("{}|{}", text, path.to_str().unwrap()); + } + } + if text.len() == 0 { + return; + } + file_choice.clear(); + file_choice.add_choice(&text[1..]); + file_choice.set_value(0); + + load_image( + &mut file_choice, + &mut quote, + &mut tag, + &mut layer_red, + &mut layer_green, + &mut layer_blue, + &mut layer_alpha, + &mut quote_position, + &mut tag_position, + &mut page, + &container, + ); + win.redraw(); + }, + ); + + self.menubar.add( + "&File/Save...\t", + Shortcut::Ctrl | 's', + menu::MenuFlag::Normal, + |_| {}, + ); + + self.menubar.add( + "&Edit/Configure...\t", + Shortcut::None, + menu::MenuFlag::Normal, + |_| { + println!("wow"); + }, + ); + } + + fn draw(&mut self) { + let mut buffer = Vec::new(); + fs::File::open("ReenieBeanie-Regular.ttf") + .unwrap() + .read_to_end(&mut buffer) + .unwrap(); + let font = rusttype::Font::try_from_vec(buffer).unwrap(); + + let container = Rc::clone(&self.container); + let quote = self.quote.clone(); + self.page.image.draw(move |f| { + if let Some(cont) = &*container.borrow() { + let image = cont.image.as_rgb8().unwrap(); + dr::draw_image( + image.as_raw(), + f.x(), + f.y(), + image.width() as i32, + image.height() as i32, + enums::ColorDepth::Rgb8, + ) + .unwrap(); + + dr::set_color_rgb(255, 255, 255); + + let size = utils::quote_from_height(image.height()); + dr::set_font(enums::Font::Times, size as i32); + + let (text_width, text_height) = utils::measure_line( + &font, + "e.value(), + rusttype::Scale::uniform(size as f32), + ); + + dr::draw_text( + "e.value(), + f.x() + image.width() as i32 / 2 - text_width as i32 / 2, + f.y() + image.height() as i32 / 2 - text_height as i32 / 2, + ); + } + }) + } + + fn events(&mut self) { + let mut image = self.page.image.clone(); + self.quote.handle(move |_, ev| { + if ev == enums::Event::KeyUp { + image.redraw(); + } + true + }); + } +} + +fn load_image( + file_choice: &mut menu::Choice, + quote: &mut MultilineInput, + tag: &mut Input, + layer_red: &mut Spinner, + layer_green: &mut Spinner, + layer_blue: &mut Spinner, + layer_alpha: &mut Spinner, + quote_position: &mut Spinner, + tag_position: &mut Spinner, + page: &mut Page, + container: &Rc>>, +) { + let file: String = match file_choice.choice() { + Some(val) => val, + None => return, + }; + + *container.borrow_mut() = Some(ImageContainer::new(&file)); + + let file = Path::new(&file); + let conf = file.with_extension("conf"); + + let mut use_defaults = true; + if conf.exists() { + let read = fs::read_to_string(&conf).unwrap(); + if let Ok(prop) = serde_json::from_str::(&read) { + if let Some(cont) = &mut *container.borrow_mut() { + layer_red.set_value(prop.rgba[0] as f64); + layer_green.set_value(prop.rgba[1] as f64); + layer_blue.set_value(prop.rgba[2] as f64); + layer_alpha.set_value(prop.rgba[3] as f64); + quote.set_value(&prop.quote); + tag.set_value(&prop.tag); + quote_position.set_value(prop.quote_position as f64); + tag_position.set_value(prop.tag_position as f64); + cont.apply_crop_pos(prop.crop_position.0, prop.crop_position.1); + + cont.quote = prop.quote; + cont.tag = prop.tag; + cont.quote_position = prop.quote_position; + cont.tag_position = prop.quote_position; + cont.rgba = prop.rgba; + } + use_defaults = false; + } + } + + if use_defaults { + if let Some(cont) = &mut *container.borrow_mut() { + quote.set_value(""); + tag.set_value(""); + quote_position.set_value(cont.quote_position as f64); + tag_position.set_value(cont.tag_position as f64); + cont.apply_crop(); + + cont.rgba = [ + layer_red.value() as u8, + layer_green.value() as u8, + layer_blue.value() as u8, + layer_alpha.value() as u8, + ]; + } + } + + if let Some(cont) = &mut *container.borrow_mut() { + cont.apply_layer(); + let (width, height) = cont.image.dimensions(); + page.row_flex.set_size(&page.col_flex, width as i32); + page.col_flex.set_size(&page.image, height as i32); + page.row_flex.recalc(); + page.col_flex.recalc(); + } +} diff --git a/src/properties.rs b/src/properties.rs new file mode 100644 index 0000000..081dddd --- /dev/null +++ b/src/properties.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct Properties { + pub(crate) quote: String, + pub(crate) tag: String, + pub(crate) quote_position: u32, + pub(crate) tag_position: u32, + pub(crate) crop_position: (u32, u32), + pub(crate) rgba: [u8; 4], +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..552ef66 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,114 @@ +use fltk::prelude::ImageExt; +use image::{DynamicImage, GenericImageView, ImageBuffer}; + +#[derive(Debug)] +pub(crate) struct ImageContainer { + pub(crate) image: DynamicImage, + pub(crate) original_dimension: (u32, u32), + pub(crate) crop_position: Option<(u32, u32)>, + pub(crate) quote: String, + pub(crate) tag: String, + pub(crate) quote_position: u32, + pub(crate) tag_position: u32, + pub(crate) rgba: [u8; 4], + pub(crate) is_saved: bool, +} + +impl ImageContainer { + pub(crate) fn new(path: &str) -> Self { + let img = image::open(path).unwrap(); + let (width, height) = img.dimensions(); + let (s_width, s_height) = ((width * 500) / height, 500); + let mut img = img.resize(s_width, s_height, image::imageops::FilterType::Triangle); + + Self { + image: img, + original_dimension: (width, height), + crop_position: None, + quote: String::new(), + tag: String::new(), + quote_position: (width * 2) / 3, + tag_position: width / 2, + rgba: [0; 4], + is_saved: true, + } + } + + pub(crate) fn apply_crop(&mut self) { + let (original_width, original_height) = self.original_dimension; + let (origina_crop_width, origina_crop_height) = get_4_5(original_width, original_height); + self.crop_position = Some(( + original_width / 2 - origina_crop_width / 2, + original_height / 2 - origina_crop_height / 2, + )); + + let (s_width, s_height) = self.image.dimensions(); + let (c_width, c_height) = get_4_5(s_width, s_height); + let (cx, cy) = (s_width / 2 - c_width / 2, s_height / 2 - c_height / 2); + + self.image = self.image.crop(cx, cy, c_width, c_height); + } + + pub(crate) fn apply_crop_pos(&mut self, original_x: u32, original_y: u32) { + let (original_width, original_height) = self.original_dimension; + self.crop_position = Some((original_x, original_y)); + + let (s_width, s_height) = self.image.dimensions(); + let (c_width, c_height) = get_4_5(s_width, s_height); + let (cx, cy) = ( + (original_x * s_width) / original_width, + (original_y * s_height) / original_height, + ); + + self.image = self.image.crop(cx, cy, c_width, c_height); + } + + pub(crate) fn apply_layer(&mut self) { + let (width, height) = self.image.dimensions(); + let layer = DynamicImage::ImageRgba8(ImageBuffer::from_fn(width, height, |_, _| { + image::Rgba(self.rgba) + })); + image::imageops::overlay(&mut self.image, &layer, 0, 0); + } +} + +pub(crate) fn get_4_5(width: u32, height: u32) -> (u32, u32) { + if width > width_from_height(height) { + (width_from_height(height), height) + } else { + (width, height_from_width(width)) + } +} + +pub(crate) fn width_from_height(height: u32) -> u32 { + (4 * height) / 5 +} + +pub(crate) fn height_from_width(width: u32) -> u32 { + (5 * width) / 4 +} + +pub(crate) fn quote_from_height(height: u32) -> u32 { + (height * 65) / 1556 +} + +pub(crate) fn id_from_height(height: u32) -> u32 { + (height * 30) / 1556 +} + +pub(crate) fn measure_line( + font: &rusttype::Font, + text: &str, + scale: rusttype::Scale, +) -> (f32, f32) { + let width = font + .layout(text, scale, rusttype::point(0.0, 0.0)) + .map(|g| g.position().x + g.unpositioned().h_metrics().advance_width) + .last() + .unwrap_or(0.0); + + let v_metrics = font.v_metrics(scale); + let height = v_metrics.ascent - v_metrics.descent + v_metrics.line_gap; + + (width, height) +}