kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
Log | Files | Refs | README

commit bcfe24e6679c0d6ca71079ab737c762d40e25a1c
parent f3b74eda3e6e5c9ba4fd09a3fe68a4c17bc891ce
Author: d.levin256@gmail.com <d.levin256@gmail.com>
Date:   Tue, 23 Jan 2024 03:30:49 +0000

Remove graphics

Diffstat:
Minclude/kfr/all.hpp | 1-
Dinclude/kfr/graphics.hpp | 28----------------------------
Dinclude/kfr/graphics/color.hpp | 412-------------------------------------------------------------------------------
Dinclude/kfr/graphics/geometry.hpp | 641-------------------------------------------------------------------------------
Dinclude/kfr/graphics/impl/scaled.hpp | 73-------------------------------------------------------------------------
Msources.cmake | 19-------------------
Dtests/unit/graphics/color.cpp | 74--------------------------------------------------------------------------
Dtests/unit/graphics/geometry.cpp | 70----------------------------------------------------------------------
Dtests/unit/graphics/graphics.cpp | 7-------
Mupdate-sources.py | 1-
10 files changed, 0 insertions(+), 1326 deletions(-)

diff --git a/include/kfr/all.hpp b/include/kfr/all.hpp @@ -24,7 +24,6 @@ #include "base.hpp" #include "dft.hpp" #include "dsp.hpp" -#include "graphics.hpp" #include "io.hpp" /** @defgroup cometa Cometa diff --git a/include/kfr/graphics.hpp b/include/kfr/graphics.hpp @@ -1,28 +0,0 @@ -/* - Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com) - This file is part of KFR - - KFR is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - KFR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with KFR. - - If GPL is not suitable for your project, you must purchase a commercial license to use KFR. - Buying a commercial license is mandatory as soon as you develop commercial activities without - disclosing the source code of your own applications. - See https://www.kfrlib.com for details. - */ -#pragma once - -#include "math.hpp" - -#include "graphics/color.hpp" -#include "graphics/geometry.hpp" diff --git a/include/kfr/graphics/color.hpp b/include/kfr/graphics/color.hpp @@ -1,412 +0,0 @@ -/** @addtogroup basic_math - * @{ - */ -/* - Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com) - This file is part of KFR - - KFR is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - KFR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with KFR. - - If GPL is not suitable for your project, you must purchase a commercial license to use KFR. - Buying a commercial license is mandatory as soon as you develop commercial activities without - disclosing the source code of your own applications. - See https://www.kfrlib.com for details. - */ -#pragma once - -#include "impl/scaled.hpp" - -CMT_PRAGMA_MSVC(warning(push)) -CMT_PRAGMA_MSVC(warning(disable : 4244)) - -namespace kfr -{ - -// 8-bit bgra (written as argb), gamma-corrected -// u8argb(0xFF4400DD) -// AARRGGBB -enum class u8argb : uint32_t; -// 16-bit bgra (written as argb), linear -enum class u16argb : uint64_t; - -namespace colors -{ -constexpr static u8argb white = static_cast<u8argb>(0xFF'FFFFFF); -constexpr static u8argb black = static_cast<u8argb>(0xFF'000000); -constexpr static u8argb red = static_cast<u8argb>(0xFF'FF0000); -constexpr static u8argb green = static_cast<u8argb>(0xFF'00FF00); -constexpr static u8argb blue = static_cast<u8argb>(0xFF'0000FF); -constexpr static u8argb yellow = static_cast<u8argb>(0xFF'FFFF00); -constexpr static u8argb cyan = static_cast<u8argb>(0xFF'00FFFF); -constexpr static u8argb magenta = static_cast<u8argb>(0xFF'FF00FF); -constexpr static u8argb transparent = static_cast<u8argb>(0x00'000000); -constexpr static u8argb grey = static_cast<u8argb>(0xFF'808080); -}; // namespace colors - -template <typename T> -struct color; - -using f32color = color<f32>; -using u8color = color<u8>; -using u16color = color<u16>; - -CMT_INTRINSIC u8color to_color(u8argb x); -CMT_INTRINSIC u16color to_color(u16argb x); - -template <typename T, size_t N> -CMT_INTRINSIC vec<T, N> from_srgb(vec<T, N> v); - -template <typename T> -struct color -{ - using Tfloat = std::common_type_t<T, float>; - - constexpr static inline bool gamma_corrected = std::is_same_v<T, u8>; - constexpr static inline int maximum = std::is_floating_point_v<T> ? 1 : std::numeric_limits<T>::max(); - - using vec_type = vec<T, 4>; - - static_assert(std::is_floating_point_v<T> || std::is_same_v<T, uint8_t> || std::is_same_v<T, uint16_t>, - "Incorrect type"); - - constexpr color(int) = delete; - constexpr explicit color(T grey, T alpha = maximum) : v(grey, grey, grey, alpha) {} - constexpr color(T r, T g, T b, T a = maximum) : v(r, g, b, a) {} -#if defined(_MSC_VER) && !defined(__clang__) - // MSVC Internal Compiler Error workaround - constexpr color(const color& value) : v(value.v) {} - constexpr color& operator=(const color& value) - { - v = value.v; - return *this; - } -#else - constexpr color(const color&) = default; -#endif - constexpr explicit color(const vec<T, 4>& v) : v(v) {} - constexpr explicit color(const vec<T, 3>& v, T a = maximum) : v(concat(v, vec<T, 1>(a))) {} - constexpr color(const vec<T, 4>& v, T a) : v(concat(slice<0, 3>(v), vec<T, 1>(a))) {} - - static constexpr color from_argb(uint32_t c) { return color(static_cast<u8argb>(c)); } - - constexpr color(u8argb c) : color(to_color(c)) {} - constexpr color(u16argb c) : color(to_color(c)) {} - template <typename U> - operator color<U>() const - { - if constexpr (gamma_corrected != color<U>::gamma_corrected) - { - vec<Tfloat, 4> tmp = convert_scaled<Tfloat, 1, maximum>(v); - if constexpr (gamma_corrected) - tmp = concat(from_srgb(slice<0, 3>(tmp)), slice<3, 1>(tmp)); - else - tmp = concat(to_srgb(slice<0, 3>(tmp)), slice<3, 1>(tmp)); - return color<U>(convert_scaled<U, color<U>::maximum, 1>(tmp)); - } - else - { - return color<U>(convert_scaled<U, color<U>::maximum, maximum>(v)); - } - } - constexpr color() : v() {} - - constexpr color lighter(Tfloat n = 1.2f) const noexcept - { - return color(clamp(v * vec<T, 4>(n), T(0), T(maximum)), a); - } - constexpr color darker(Tfloat n = 1.2f) const noexcept - { - return color(clamp(v / vec<T, 4>(n), T(0), T(maximum)), a); - } - - constexpr T lightness() const - { - if constexpr (std::is_floating_point<T>::value) - { - return (r + g + b) * static_cast<T>(0.33333); - } - else - { - constexpr T min = std::numeric_limits<T>::min(); - constexpr T max = std::numeric_limits<T>::max(); - using Tcommon = findinttype<min * 3, max * 3>; - return (Tcommon(r) + g + b) / 3; - } - } - - constexpr T lightness_perc() const - { - return static_cast<T>(sqrt(0.299 * r * r + 0.587 * g * g + 0.114 * b * b)); - } - - constexpr color desaturate(Tfloat t = 1.0) const - { - const T l = lightness_perc(); - return color(kfr::mix(t, v, concat(vec<T, 3>(l), vec<T, 1>(a)))); - } - - constexpr color normalize() const { return color(v / lightness_perc()); } - - constexpr void apply_red(T r) noexcept { this->r = r; } - constexpr void apply_green(T g) noexcept { this->g = g; } - constexpr void apply_blue(T b) noexcept { this->b = b; } - constexpr void apply_alpha(T a) noexcept { this->a = a; } - - constexpr color with_red(T r) const noexcept - { - return color(blend(v, broadcast<4>(r), elements_t<1, 0, 0, 0>())); - } - constexpr color with_green(T g) const noexcept - { - return color(blend(v, broadcast<4>(g), elements_t<0, 1, 0, 0>())); - } - constexpr color with_blue(T b) const noexcept - { - return color(blend(v, broadcast<4>(b), elements_t<0, 0, 1, 0>())); - } - constexpr color with_alpha(T a) const noexcept - { - return color(blend(v, broadcast<4>(a), elements_t<0, 0, 0, 1>())); - } - constexpr color with_alpha_premul(T a) const noexcept { return color(v * a); } - constexpr color premultiply() const noexcept - { - return color(blend(color(color<Tfloat>(*this).v * Tfloat(a)).v, v, elements_t<0, 0, 0, 1>())); - } - - constexpr bool operator==(const color& c) const { return all(v == c.v); } - constexpr bool operator!=(const color& c) const { return !(*this == c); } - - union - { - struct - { - T r; - T g; - T b; - T a; - }; - struct - { - T red; - T green; - T blue; - T alpha; - }; - struct - { - vec_type v; - }; - }; -}; - -CMT_INTRINSIC u8color to_color(u8argb x) -{ - return u8color( - vec<u8, 4>{ bitcast<u8>(u32x1(static_cast<uint32_t>(x))) }.shuffle(csizes_t<2, 1, 0, 3>())); -} -CMT_INTRINSIC u16color to_color(u16argb x) -{ - return u16color( - vec<u16, 4>{ bitcast<u16>(u64x1(static_cast<uint64_t>(x))) }.shuffle(csizes_t<2, 1, 0, 3>())); -} - -template <typename T> -CMT_INTRINSIC color<T> mix(float t, const color<T>& a, const color<T>& b) -{ - return color<T>(kfr::mix(t, a.v, b.v)); -} - -template <typename T, size_t N> -CMT_INTRINSIC vec<T, N> from_srgb(vec<T, N> v) -{ - static_assert(std::is_floating_point_v<T>); -#ifndef KFR_SRGB_APPROX - mask<T, N> m = v <= T(0.04045); - return select(m, v * T(0.07739938080495356), kfr::pow((v + T(0.055)) * T(0.947867298578199), T(2.4))); -#else - return v * (v * (v * 0.305306011f + 0.682171111f) + 0.012522878f); -#endif -} - -template <typename T> -CMT_INTRINSIC color<T> from_srgb(color<T> c) -{ - return color<T>(from_srgb(slice<0, 3>(c.v)), c.a); -} - -template <typename T, size_t N> -CMT_INTRINSIC vec<T, N> to_srgb(vec<T, N> v) -{ - static_assert(std::is_floating_point_v<T>); -#ifndef KFR_SRGB_APPROX - mask<T, N> m = v <= T(0.0031308); - return select(m, v * T(12.92), T(1.055) * kfr::pow(v, T(0.4166666666666666667)) - T(0.055)); -#else - vec<T, N> S1 = kfr::sqrt(v); - vec<T, N> S2 = kfr::sqrt(S1); - vec<T, N> S3 = kfr::sqrt(S2); - return T(0.585122381) * S1 + T(0.783140355) * S2 - T(0.368262736) * S3; -#endif -} - -template <typename T> -CMT_INTRINSIC color<T> to_srgb(color<T> c) -{ - return color<T>(to_srgb(slice<0, 3>(c.v)), c.a); -} - -constexpr inline u8color operator""_argb(unsigned long long argb) { return u8color::from_argb(argb); } - -constexpr inline u8color operator""_rgb(unsigned long long rgb) -{ - return u8color::from_argb(0xFF000000u | rgb); -} - -CMT_INTRINSIC f32x3 lab_to_xyz(const f32x3& lab) -{ - const float y = (lab[0] + 16.f) / 116.f; - const float x = lab[1] / 500.f + y; - const float z = y - lab[2] / 200.f; - - const f32x3 w = { x, y, z }; - - const f32x3 cube = w * w * w; - return f32x3{ 0.95047f, 1.00000f, 1.08883f } * - (select(cube > 216.f / 24389.f, cube, (w - 16.f / 116.f) / (24389.f / 27.f / 116.f))); -} - -CMT_INTRINSIC f32x3 xyz_to_rgb(const f32x3& xyz) -{ - return xyz[0] * f32x3{ 3.2406f, -0.9689f, 0.0557f } + xyz[1] * f32x3{ -1.5372f, 1.8758f, -0.2040f } + - xyz[2] * f32x3{ -0.4986f, 0.0415f, 1.0570f }; -} - -CMT_INTRINSIC f32x3 rgb_to_srgb(const f32x3& rgb) -{ - return select(rgb > 0.0031308f, 1.055f * kfr::pow(rgb, 1.f / 2.4f) - 0.055f, 12.92f * rgb); -} - -CMT_INTRINSIC f32x3 srgb_to_rgb(const f32x3& srgb) -{ - return select(srgb > 0.04045f, kfr::pow((srgb + 0.055f) / 1.055f, 2.4f), srgb / 12.92f); -} - -CMT_INTRINSIC f32x3 rgb_to_xyz(const f32x3& rgb) -{ - return (rgb[0] * f32x3{ 0.4124f, 0.2126f, 0.0193f } + rgb[1] * f32x3{ 0.3576f, 0.7152f, 0.1192f } + - rgb[2] * f32x3{ 0.1805f, 0.0722f, 0.9505f }) / - f32x3{ 0.95047f, 1.f, 1.08883f }; -} - -CMT_INTRINSIC f32x3 xyz_to_lab(const f32x3& xyz) -{ - const f32x3 w = select(xyz > 0.008856f, kfr::pow(xyz, 0.33333f), (7.787f * xyz) + 16.f / 116.f); - - return { (116.f * w[1]) - 16.f, 500.f * (w[0] - w[1]), 200.f * (w[1] - w[2]) }; -} - -// - -CMT_INTRINSIC f32color lab_to_srgb(const f32x3& lab, float alpha = 1.f) -{ - const f32x3 srgb = clamp(rgb_to_srgb(xyz_to_rgb(lab_to_xyz(lab))), 0.f, 1.f); - return f32color(f32x4(srgb, f32x1{ alpha })); -} - -CMT_INTRINSIC f32color lab_to_linear_rgb(const f32x3& lab, float alpha = 1.f) -{ - const f32x3 rgb = clamp(xyz_to_rgb(lab_to_xyz(lab)), 0.f, 1.f); - return f32color(f32x4(rgb, f32x1{ alpha })); -} - -CMT_INTRINSIC f32x3 srgb_to_lab(const f32color& srgb) -{ - return xyz_to_lab(rgb_to_xyz(srgb_to_rgb(slice<0, 3>(srgb.v)))); -} - -CMT_INTRINSIC f32x3 lab_to_lch(const f32x3& lab) -{ - return f32x3{ lab[0], kfr::sqrt(lab[1] * lab[1] + lab[2] * lab[2]), kfr::atan2deg(lab[1], lab[2]) }; -} - -CMT_INTRINSIC f32x3 lch_to_lab(const f32x3& lch) -{ - return f32x3{ lch[0], kfr::sindeg(lch[2]) * lch[1], kfr::cosdeg(lch[2]) * lch[1] }; -} - -CMT_INTRINSIC f32color adjust_lab(const f32color& srgb, float lum = 0.f, float chroma = 1.f) -{ - f32x3 lab = srgb_to_lab(srgb); - lab[0] = kfr::clamp(lab[0] + lum, 0.f, 100.f); - lab[1] = lab[1] * chroma; - lab[2] = lab[2] * chroma; - return lab_to_srgb(lab, srgb.alpha); -} -CMT_INTRINSIC f32color adjust_lab_luminance(const f32color& srgb, float lum = 0.f) -{ - f32x3 lab = srgb_to_lab(srgb); - lab[0] = kfr::clamp(lab[0] + lum, 0.f, 100.f); - return lab_to_srgb(lab, srgb.alpha); -} - -// [0..360), [0..100], [0..100] -CMT_INTRINSIC f32color hsv_to_srgb(const f32x3& hsv, float alpha = 1.f) -{ - float v = hsv[2]; - int hi = int(hsv[0] / 60.f); - int lo = int(hsv[0]) % 60; - float vmin = ((100.f - hsv[1]) * v) / 100.f; - float a = (v - vmin) * lo / 60.f; - float vinc = vmin + a; - float vdec = v - a; - v /= 100.f; - vmin /= 100.f; - vinc /= 100.f; - vdec /= 100.f; - switch (hi % 6) - { - case 0: - return { v, vinc, vmin, alpha }; - case 1: - return { vdec, v, vmin, alpha }; - case 2: - return { vmin, v, vinc, alpha }; - case 3: - return { vmin, vdec, v, alpha }; - case 4: - return { vinc, vmin, v, alpha }; - case 5: - return { v, vmin, vdec, alpha }; - default: - return { 0, 0, 0, 0 }; - } -} - -} // namespace kfr - -namespace cometa -{ -template <typename T> -struct representation<kfr::color<T>> -{ - using type = std::string; - static std::string get(const kfr::color<T>& value) noexcept - { - return as_string("color(", value.r, ", ", value.g, ", ", value.b, ", ", value.a, ")"); - } -}; -} // namespace cometa - -CMT_PRAGMA_MSVC(warning(pop)) diff --git a/include/kfr/graphics/geometry.hpp b/include/kfr/graphics/geometry.hpp @@ -1,641 +0,0 @@ -/** @addtogroup basic_math - * @{ - */ -/* - Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com) - This file is part of KFR - - KFR is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - KFR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with KFR. - - If GPL is not suitable for your project, you must purchase a commercial license to use KFR. - Buying a commercial license is mandatory as soon as you develop commercial activities without - disclosing the source code of your own applications. - See https://www.kfrlib.com for details. - */ -#pragma once - -#include "impl/scaled.hpp" - -namespace kfr -{ - -template <typename T> -struct point; -template <typename T> -struct size; -template <typename T> -struct border; -template <typename T> -struct rectangle; -template <typename T> -struct matrix2d; - -struct percents -{ - double value; - template <typename T> - inline constexpr T calc(T total) const - { - return static_cast<T>(total * value / 100.0); - } -}; - -constexpr inline percents operator""_perc(long double v) { return { static_cast<double>(v) }; } -constexpr inline percents operator""_perc(unsigned long long v) { return { static_cast<double>(v) }; } - -template <typename T> -struct point -{ - using Tfloat = std::common_type_t<T, float>; - - constexpr point() noexcept : v() {} - constexpr explicit point(const vec<T, 2>& v) noexcept : v(v) {} - constexpr point(T x, T y) noexcept : v(x, y) {} - constexpr point(const size<T>& sz) noexcept : v(sz.v) {} -#if CMT_COMPILER_IS_MSVC - constexpr point(const point& p) noexcept : v(p.v) {} -#else - constexpr point(const point& p) noexcept = default; -#endif - - template <typename U> - operator point<U>() const - { - return point<U>(convert_scaled<U, 1, 1>(v)); - } - constexpr bool operator==(const point& c) const { return all(v == c.v); } - constexpr bool operator!=(const point& c) const { return !operator==(c); } - - constexpr friend point operator+(const point& p1, const point& p2) { return point(p1.v + p2.v); } - constexpr friend point operator-(const point& p1, const point& p2) { return point(p1.v - p2.v); } - constexpr friend point operator*(const point& p1, const point& p2) { return point(p1.v * p2.v); } - constexpr friend point operator/(const point& p1, const point& p2) { return point(p1.v / p2.v); } - constexpr friend point operator-(const point& p1) { return point(-p1.v); } - constexpr friend point operator*(const point& p1, const T& v2) { return point(p1.v * v2); } - constexpr friend point operator*(const T& v1, const point& p2) { return point(v1 * p2.v); } - constexpr friend point operator/(const point& p1, const T& v2) { return point(p1.v / v2); } - constexpr friend point operator/(const T& v1, const point& p2) { return point(v1 / p2.v); } - - constexpr point flipped() const { return point(kfr::swap(v)); } - - T distance(const point& pt) const { return std::sqrt(sqr(pt.x - x) + sqr(pt.y - y)); } - - T manhattan_distance(const point& pt) const { return std::max(std::abs(pt.x - x), std::abs(pt.y - y)); } - - T operator[](size_t i) const { return v[i]; } - T& operator[](size_t i) { return a[i]; } - - rectangle<T> aligned_rect(const kfr::size<T>& inner_size, const point<Tfloat>& alignment) const - { - const kfr::size<T> sz = inner_size; - const kfr::size<T> gap = -sz; - const vec<T, 2> p = v + cast<T>(gap.v * alignment.v); - return rectangle(concat(p, p + sz.v)); - } - rectangle<T> aligned_rect(T width, T height, Tfloat align_x, Tfloat align_y) const - { - return aligned_rect({ width, height }, { align_x, align_y }); - } - - constexpr point round() const { return point(kfr::round(v)); } - constexpr point floor() const { return point(kfr::floor(v)); } - constexpr point ceil() const { return point(kfr::ceil(v)); } - constexpr point trunc() const { return point(kfr::trunc(v)); } - - union - { - struct - { - vec<T, 2> v; - }; - struct - { - T x; - T y; - }; - struct - { - T a[2]; - }; - }; -}; - -template <typename T> -CMT_INLINE point<T> min(const point<T>& a, const point<T>& b) -{ - return point<T>(min(a.v, b.v)); -} -template <typename T> -CMT_INLINE point<T> max(const point<T>& a, const point<T>& b) -{ - return point<T>(max(a.v, b.v)); -} - -template <typename T> -struct size -{ - constexpr size() noexcept : v() {} - constexpr size(T x, T y) noexcept : v(x, y) {} - constexpr explicit size(T xy) noexcept : v(xy, xy) {} - constexpr size(const vec<T, 2>& v) noexcept : v(v) {} -#if CMT_COMPILER_IS_MSVC - constexpr size(const size& p) noexcept : v(p.v) {} -#else - constexpr size(const size& p) noexcept = default; -#endif - - template <typename U> - operator size<U>() const noexcept - { - return size<U>(convert_scaled<U, 1, 1>(v)); - } - - constexpr size round() const { return size(kfr::round(v)); } - constexpr size floor() const { return size(kfr::floor(v)); } - constexpr size ceil() const { return size(kfr::ceil(v)); } - constexpr size trunc() const { return size(kfr::trunc(v)); } - - constexpr size flipped() const { return size(kfr::swap(v)); } - - constexpr friend size operator+(const size& s1, const size& s2) { return size(s1.v + s2.v); } - constexpr friend size operator-(const size& s1, const size& s2) { return size(s1.v - s2.v); } - constexpr friend size operator*(const size& s1, const size& s2) { return size(s1.v * s2.v); } - constexpr friend size operator/(const size& s1, const size& s2) { return size(s1.v / s2.v); } - constexpr friend size operator*(const size& s1, T s2) { return size(s1.v * s2); } - constexpr friend size operator*(T s1, const size& s2) { return size(s1 * s2.v); } - constexpr friend size operator/(const size& s1, T s2) { return size(s1.v / s2); } - constexpr friend size operator/(T s1, const size& s2) { return size(s1 / s2.v); } - constexpr friend size operator-(const size& s1) { return size(-s1.v); } - constexpr T area() const { return x * y; } - - T operator[](size_t i) const { return v[i]; } - T& operator[](size_t i) { return a[i]; } - - constexpr bool operator==(const size& c) const { return all(v == c.v); } - constexpr bool operator!=(const size& c) const { return !operator==(c); } - union - { - struct - { - T x; - T y; - }; - struct - { - T width; - T height; - }; - struct - { - vec<T, 2> v; - }; - struct - { - T a[2]; - }; - }; -}; - -template <typename T> -CMT_INLINE size<T> min(const size<T>& a, const size<T>& b) -{ - return size<T>(min(a.v, b.v)); -} -template <typename T> -CMT_INLINE size<T> max(const size<T>& a, const size<T>& b) -{ - return size<T>(max(a.v, b.v)); -} - -template <typename T> -struct border -{ - constexpr border() noexcept : v() {} - constexpr explicit border(T value) noexcept : v(value) {} - constexpr border(T h, T v) noexcept : v(h, v, h, v) {} - constexpr border(T x1, T y1, T x2, T y2) noexcept : v(x1, y1, x2, y2) {} - constexpr explicit border(const vec<T, 4>& v) : v(v) {} -#if CMT_COMPILER_IS_MSVC - constexpr border(const border& p) noexcept : v(p.v) {} -#else - constexpr border(const border& p) noexcept = default; -#endif - - template <typename U> - operator border<U>() const - { - return border<U>(convert_scaled<U, 1, 1>(v)); - } - - constexpr border round() const { return border(kfr::round(v)); } - constexpr border floor() const { return border(kfr::floor(v)); } - constexpr border ceil() const { return border(kfr::ceil(v)); } - constexpr border trunc() const { return border(kfr::trunc(v)); } - - kfr::size<T> size() const { return kfr::size<T>(low(v) + high(v)); } - - T horizontal() const { return size().x; } - T vertical() const { return size().y; } - - point<T> leading() const { return point<T>(slice<0, 2>(v)); } - point<T> trailing() const { return point<T>(slice<2, 2>(v)); } - - T operator[](size_t i) const { return v[i]; } - T& operator[](size_t i) { return a[i]; } - - constexpr friend border operator+(const border& b1, const border& b2) { return border(b1.v + b2.v); } - - constexpr bool operator==(const border& c) const { return all(v == c.v); } - constexpr bool operator!=(const border& c) const { return !(operator==(c)); } - union - { - struct - { - T x1; - T y1; - T x2; - T y2; - }; - struct - { - vec<T, 4> v; - }; - struct - { - T a[4]; - }; - }; -}; - -template <typename T> -CMT_INLINE border<T> min(const border<T>& a, const border<T>& b) -{ - return border<T>(min(a.v, b.v)); -} -template <typename T> -CMT_INLINE border<T> max(const border<T>& a, const border<T>& b) -{ - return border<T>(max(a.v, b.v)); -} - -template <typename T> -struct rectangle -{ - using Tfloat = std::common_type_t<T, float>; - - constexpr rectangle(T x1, T y1, T x2, T y2) : v(x1, y1, x2, y2) {} - constexpr explicit rectangle(const vec<T, 4>& v) : v(v) {} -#if CMT_COMPILER_IS_MSVC - constexpr rectangle(const rectangle& p) noexcept : v(p.v) {} -#else - constexpr rectangle(const rectangle& p) noexcept = default; -#endif - - template <typename U> - operator rectangle<U>() const - { - return rectangle<U>(convert_scaled<U, 1, 1>(v)); - } - constexpr rectangle(const point<T>& point, const size<T>& size) : v(point.v, point.v + size.v) {} - constexpr rectangle(const point<T>& point1, const point<T>& point2) : v(point1.v, point2.v) {} - constexpr rectangle(const point<T>& base, const kfr::size<T>& dim, const point<Tfloat>& alignment) - : rectangle(base.aligned_rect(dim, alignment)) - { - } - constexpr rectangle() : v() {} - - constexpr bool empty() const noexcept { return any(size().v <= 0); } - - constexpr kfr::size<T> size() const { return high(v) - low(v); } - - constexpr T area() const { return size().area(); } - constexpr T width() const { return x2 - x1; } - constexpr T height() const { return y2 - y1; } - - constexpr T min_side() const { return hmin(size().v); } - constexpr T max_side() const { return hmax(size().v); } - - point<T> center() const { return at(0.5f, 0.5f); } - - point<Tfloat> to_norm_coord(const point<T>& pt) const { return point<T>((pt.v - p1.v) / (p1.v - p1.v)); } - point<Tfloat> to_norm_coord(const point<T>& pt, const point<T>& ifoutside) const - { - if (!contains(pt)) - return ifoutside; - return point<T>((pt.v - p1.v) / (p2.v - p1.v)); - } - - rectangle split(const point<Tfloat>& point1, const kfr::size<Tfloat>& size) const noexcept - { - const vec<Tfloat, 2> point2 = point1.v + size.v; - return rectangle( - concat(cast<T>(p1.v + this->size().v * point1.v), cast<T>(p1.v + this->size().v * point2))); - } - rectangle split(Tfloat x, Tfloat y, Tfloat w, Tfloat h) const noexcept - { - return split({ x, y }, { w, h }); - } - - rectangle cut_h_start(T width, bool partial = false) - { - if (empty() || (!partial && this->width() < width)) - return rectangle(); - width = std::min(width, this->width()); - const rectangle result = with_width(width); - apply_padding(width, 0, 0, 0); - return result; - } - rectangle cut_v_start(T height, bool partial = false) - { - if (empty() || (!partial && this->height() < height)) - return rectangle(); - height = std::min(height, this->height()); - const rectangle result = with_height(height); - apply_padding(0, height, 0, 0); - return result; - } - rectangle cut_h_end(T width, bool partial = false) - { - if (empty() || (!partial && this->width() < width)) - return rectangle(); - width = std::min(width, this->width()); - width = this->width() - width; - const rectangle result = with_padding(width, 0, 0, 0); - apply_width(width); - return result; - } - rectangle cut_v_end(T height, bool partial = false) - { - if (empty() || (!partial && this->height() < height)) - return rectangle(); - height = std::min(height, this->height()); - height = this->height() - height; - const rectangle result = with_padding(0, height, 0, 0); - apply_height(height); - return result; - } - - rectangle cut_h_start(percents width) { return cut_h_start(width.calc(this->width())); } - rectangle cut_v_start(percents height) { return cut_v_start(height.calc(this->height())); } - rectangle cut_h_end(percents width) { return cut_h_end(width.calc(this->width())); } - rectangle cut_v_end(percents height) { return cut_v_end(height.calc(this->height())); } - - point<T> at(const point<Tfloat>& pt) const noexcept { return p1 + point<T>(pt.v * size().v); } - point<T> at(Tfloat x, Tfloat y) const noexcept - { - return p1 + point<T>(point<Tfloat>{ x, y }.v * size().v); - } - - void apply_start(const point<T>& p) { v = concat(p.v, p.v + size()); } - void apply_start(T x, T y) { v = concat(pack(x, y), pack(x, y) + size()); } - void apply_size(const kfr::size<T>& s) { v = concat(low(v), low(v) + s.v); } - void apply_size(T w, T h) { v = concat(low(v), low(v) + pack(w, h)); } - void apply_width(T w) { apply_size(w, height()); } - void apply_height(T h) { apply_size(width(), h); } - void apply_offset(T x, T y) { v += vec<T, 4>(x, y, x, y); } - void apply_offset(const point<T>& p) { v += repeat<2>(p.v); } - void apply_scale(T x, T y) { v *= vec<T, 4>(x, y, x, y); } - void apply_margin(T h, T v) { v += vec<T, 4>(-h, -v, +h, +v); } - void apply_padding(T h, T v) { v += vec<T, 4>(+h, +v, -h, -v); } - void apply_margin(T m) { v += vec<T, 4>(-m, -m, +m, +m); } - void apply_padding(T p) { v += vec<T, 4>(+p, +p, -p, -p); } - void apply_margin(const border<T>& m) { v += vec<T, 4>(-1, -1, 1, 1) * m.v; } - void apply_padding(const border<T>& p) { v += vec<T, 4>(1, 1, -1, -1) * p.v; } - void apply_padding(T x1, T y1, T x2, T y2) { v += vec<T, 4>(+x1, +y1, -x2, -y2); } - - rectangle aligned_rect(const kfr::size<T>& inner_size, const point<Tfloat>& alignment) const - { - const kfr::size<T> sz = inner_size; // kfr::min(inner_size.v, this->size().v); - const kfr::size<T> gap = size() - sz; - const vec<T, 2> p = p1.v + cast<T>(gap.v * alignment.v); - return rectangle(concat(p, p + sz.v)); - } - rectangle aligned_rect(T width, T height, Tfloat align_x, Tfloat align_y) const - { - return aligned_rect({ width, height }, { align_x, align_y }); - } - - constexpr rectangle with_start(const point<T>& p) const { return rectangle(concat(p.v, p.v + size())); } - constexpr rectangle with_start(T x, T y) const - { - return rectangle(concat(pack(x, y), pack(x, y) + size())); - } - constexpr rectangle with_size(const kfr::size<T>& s) const - { - return rectangle(concat(low(v), low(v) + s.v)); - } - constexpr rectangle with_size(T w, T h) const { return rectangle(concat(low(v), low(v) + pack(w, h))); } - constexpr rectangle with_width(T w) const { return with_size(w, height()); } - constexpr rectangle with_height(T h) const { return with_size(width(), h); } - constexpr rectangle with_offset(const point<T>& p) const { return rectangle(v + vec<T, 4>(p.v, p.v)); } - constexpr rectangle with_offset(T x, T y) const { return rectangle(v + vec<T, 4>(x, y, x, y)); } - constexpr rectangle with_scale(T x, T y) const { return rectangle(v * vec<T, 4>(x, y, x, y)); } - constexpr rectangle with_margin(T h, T v) const { return rectangle(this->v + vec<T, 4>(-h, -v, +h, +v)); } - constexpr rectangle with_padding(T h, T v) const - { - return rectangle(this->v + vec<T, 4>(+h, +v, -h, -v)); - } - constexpr rectangle with_padding(T x1, T y1, T x2, T y2) const - { - return rectangle(v + vec<T, 4>(+x1, +y1, -x2, -y2)); - } - constexpr rectangle with_margin(T m) const { return rectangle(v + vec<T, 4>(-m, -m, +m, +m)); } - constexpr rectangle with_padding(T p) const { return rectangle(v + vec<T, 4>(+p, +p, -p, -p)); } - - constexpr rectangle with_padding(const border<T>& p) const - { - return rectangle(v + vec<T, 4>(1, 1, -1, -1) * p.v); - } - constexpr rectangle with_margin(const border<T>& m) const - { - return rectangle(v + vec<T, 4>(-1, -1, 1, 1) * m.v); - } - - constexpr rectangle flipped() const { return rectangle(kfr::swap(v)); } - - constexpr rectangle round() const { return rectangle(kfr::round(v)); } - constexpr rectangle floor() const { return rectangle(kfr::floor(v)); } - constexpr rectangle ceil() const { return rectangle(kfr::ceil(v)); } - constexpr rectangle trunc() const { return rectangle(kfr::trunc(v)); } - - bool contains(const point<T>& pt) const { return all(pt.v >= p1.v && pt.v < p2.v); } - - bool operator<<(const point<T>& pt) const { return contains(pt); } - - constexpr bool operator==(const rectangle& c) const { return all(v == c.v); } - constexpr bool operator!=(const rectangle& c) const { return !(*this == c); } - - constexpr rectangle union_(const rectangle& c) const - { - return rectangle(blend<0, 0, 1, 1>(min(v, c.v), max(v, c.v))); - } - constexpr rectangle intersection(const rectangle& c) const - { - return rectangle(blend<1, 1, 0, 0>(min(v, c.v), max(v, c.v))); - } - - T operator[](size_t i) const { return v[i]; } - T& operator[](size_t i) { return a[i]; } - - union - { - struct - { - T x1; - T y1; - T x2; - T y2; - }; - struct - { - point<T> p1; - point<T> p2; - }; - struct - { - vec<T, 4> v; - }; - struct - { - T a[4]; - }; - }; -}; - -/// @brief 2D matrix -template <typename T> -struct matrix2d -{ - static_assert(std::is_floating_point_v<T>); - union - { - vec<T, 6> v; - struct - { - T a, b, c, d, e, f; - }; - }; - - matrix2d() : v{ 1, 0, 0, 1, 0, 0 } {} - - matrix2d(T a, T b, T c, T d, T e, T f) : v{ a, b, c, d, e, f } {} - constexpr matrix2d(const matrix2d& m) : v(m.v) {} - - explicit matrix2d(const vec<T, 6>& v) : v(v) {} - - static matrix2d translate(T x, T y) { return matrix2d{ 1, 0, 0, 1, x, y }; } - static matrix2d scale(T x, T y) { return matrix2d{ x, 0, 0, y, 0, 0 }; } - static matrix2d rotate(T angle) - { - return matrix2d{ cos(angle), sin(angle), -sin(angle), cos(angle), 0, 0 }; - } - - static matrix2d rotate90(int angle) - { - static constexpr portable_vec<T, 6> m[4] = { - { 1, 0, 0, 1, 0, 0 }, { 0, 1, -1, 0, 0, 0 }, { -1, 0, 0, -1, 0, 0 }, { 0, -1, 1, 0, 0, 0 } - }; - return matrix2d(vec<T, 6>(m[angle % 4])); - } - - std::array<std::array<T, 3>, 3> full() const - { - return { { { a, b, T() }, { c, d, T() }, { e, f, T(1) } } }; - } - - friend matrix2d<T> operator*(const matrix2d<T>& m, const matrix2d<T>& n) - { - const std::array<std::array<T, 3>, 3> mm = m.full(); - const std::array<std::array<T, 3>, 3> nn = n.full(); - std::array<std::array<T, 3>, 3> a; - for (size_t i = 0; i < 3; i++) - { - for (size_t j = 0; j < 3; j++) - { - T sum = 0; - for (size_t k = 0; k < 3; k++) - { - sum += mm[i][k] * nn[k][j]; - } - a[i][j] = sum; - } - } - return { a[0][0], a[0][1], a[1][0], a[1][1], a[2][0], a[2][1] }; - } - - friend point<T> operator*(const point<T>& pt, const matrix2d<T>& m) - { - return { pt.x * m.a + pt.y * m.c + m.e, pt.y * m.d + pt.x * m.b + m.f }; - } -}; - -using i32point = point<i32>; -using f32point = point<f32>; -using f64point = point<f64>; - -using i32size = size<i32>; -using f32size = size<f32>; -using f64size = size<f64>; - -using i32border = border<i32>; -using f32border = border<f32>; -using f64border = border<f64>; - -using i32rectangle = rectangle<i32>; -using f32rectangle = rectangle<f32>; -using f64rectangle = rectangle<f64>; - -using f32matrix2d = matrix2d<f32>; -using f64matrix2d = matrix2d<f64>; -} // namespace kfr - -namespace cometa -{ -template <typename T> -struct representation<kfr::point<T>> -{ - using type = std::string; - static std::string get(const kfr::point<T>& value) noexcept - { - return as_string("point(", value.x, ", ", value.y, ")"); - } -}; -template <typename T> -struct representation<kfr::size<T>> -{ - using type = std::string; - static std::string get(const kfr::size<T>& value) noexcept - { - return as_string("size(", value.x, ", ", value.y, ")"); - } -}; -template <typename T> -struct representation<kfr::border<T>> -{ - using type = std::string; - static std::string get(const kfr::border<T>& value) noexcept - { - return as_string("border(", value.x1, ", ", value.y1, ", ", value.x2, ", ", value.y2, ")"); - } -}; -template <typename T> -struct representation<kfr::rectangle<T>> -{ - using type = std::string; - static std::string get(const kfr::rectangle<T>& value) noexcept - { - return as_string("rectangle(", value.x1, ", ", value.y1, ", ", value.x2, ", ", value.y2, ")"); - } -}; -} // namespace cometa diff --git a/include/kfr/graphics/impl/scaled.hpp b/include/kfr/graphics/impl/scaled.hpp @@ -1,73 +0,0 @@ -/** @addtogroup basic_math - * @{ - */ -/* - Copyright (C) 2016-2023 Dan Cazarin (https://www.kfrlib.com) - This file is part of KFR - - KFR is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. - - KFR is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with KFR. - - If GPL is not suitable for your project, you must purchase a commercial license to use KFR. - Buying a commercial license is mandatory as soon as you develop commercial activities without - disclosing the source code of your own applications. - See https://www.kfrlib.com for details. - */ -#pragma once - -#include "../../cometa/string.hpp" -#include "../../math.hpp" - -namespace kfr -{ - -inline namespace CMT_ARCH_NAME -{ - -template <typename Tout, int Mout, int Min, typename Tin, size_t N, - KFR_ENABLE_IF(Mout != Min && - (std::is_floating_point<Tin>::value || std::is_floating_point<Tout>::value))> -KFR_INTRINSIC vec<Tout, N> convert_scaled(const vec<Tin, N>& value) -{ - using Tcommon = std::common_type_t<Tin, Tout>; - vec<Tcommon, N> x = static_cast<vec<Tcommon, N>>(value) * Mout / Min; - if constexpr (!std::is_floating_point_v<Tout>) - x += 0.5f / Mout; - return static_cast<vec<Tout, N>>(x); -} - -template <typename Tout, int Mout, int Min, typename Tin, size_t N, - KFR_ENABLE_IF(Mout != Min && - !(std::is_floating_point<Tin>::value || std::is_floating_point<Tout>::value))> -KFR_INTRINSIC vec<Tout, N> convert_scaled(const vec<Tin, N>& value) -{ - using Tcommon = - findinttype<std::numeric_limits<Tin>::min() * Mout, std::numeric_limits<Tin>::max() * Mout>; - return static_cast<vec<Tout, N>>(static_cast<vec<Tcommon, N>>(value) * Mout / Min); -} - -template <typename Tout, int Mout, int Min, typename Tin, size_t N, KFR_ENABLE_IF(Mout == Min)> -KFR_INTRINSIC vec<Tout, N> convert_scaled(const vec<Tin, N>& value) -{ - if constexpr (!std::is_floating_point_v<Tout>) - { - return static_cast<vec<Tout, N>>(round(value)); - } - else - { - return static_cast<vec<Tout, N>>(value); - } -} -} // namespace CMT_ARCH_NAME - -} // namespace kfr diff --git a/sources.cmake b/sources.cmake @@ -10,7 +10,6 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/dft.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp.hpp ${PROJECT_SOURCE_DIR}/include/kfr/except.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io.hpp ${PROJECT_SOURCE_DIR}/include/kfr/math.hpp ${PROJECT_SOURCE_DIR}/include/kfr/runtime.hpp @@ -76,9 +75,6 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/dsp/waveshaper.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/weighting.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/window.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/color.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/geometry.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/impl/scaled.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io/audiofile.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io/file.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io/python_plot.hpp @@ -294,14 +290,6 @@ set( set( - KFR_GRAPHICS_SRC - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/color.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/geometry.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/impl/scaled.hpp -) - - -set( KFR_SRC ${PROJECT_SOURCE_DIR}/include/kfr/all.hpp ${PROJECT_SOURCE_DIR}/include/kfr/base.hpp @@ -309,7 +297,6 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/dft.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp.hpp ${PROJECT_SOURCE_DIR}/include/kfr/except.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io.hpp ${PROJECT_SOURCE_DIR}/include/kfr/math.hpp ${PROJECT_SOURCE_DIR}/include/kfr/runtime.hpp @@ -375,9 +362,6 @@ set( ${PROJECT_SOURCE_DIR}/include/kfr/dsp/waveshaper.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/weighting.hpp ${PROJECT_SOURCE_DIR}/include/kfr/dsp/window.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/color.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/geometry.hpp - ${PROJECT_SOURCE_DIR}/include/kfr/graphics/impl/scaled.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io/audiofile.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io/file.hpp ${PROJECT_SOURCE_DIR}/include/kfr/io/python_plot.hpp @@ -513,9 +497,6 @@ set( ${PROJECT_SOURCE_DIR}/tests/unit/dsp/sample_rate_conversion.cpp ${PROJECT_SOURCE_DIR}/tests/unit/dsp/units.cpp ${PROJECT_SOURCE_DIR}/tests/unit/dsp/window.cpp - ${PROJECT_SOURCE_DIR}/tests/unit/graphics/color.cpp - ${PROJECT_SOURCE_DIR}/tests/unit/graphics/geometry.cpp - ${PROJECT_SOURCE_DIR}/tests/unit/graphics/graphics.cpp ${PROJECT_SOURCE_DIR}/tests/unit/io/audiofile.cpp ${PROJECT_SOURCE_DIR}/tests/unit/math/asin_acos.cpp ${PROJECT_SOURCE_DIR}/tests/unit/math/atan.cpp diff --git a/tests/unit/graphics/color.cpp b/tests/unit/graphics/color.cpp @@ -1,74 +0,0 @@ -/** - * KFR (https://www.kfrlib.com) - * Copyright (C) 2016-2023 Dan Cazarin - * See LICENSE.txt for details - */ - -#include <kfr/graphics/color.hpp> - -namespace kfr -{ -inline namespace CMT_ARCH_NAME -{ -TEST(color) -{ - testo::epsilon_scope<void> e(100); - - f32color c1 = f32color::from_argb(0xFF'FF00FF); - CHECK(c1.r == 1); - CHECK(c1.g == 0); - CHECK(c1.b == 1); - CHECK(c1.a == 1); - - u8color c2 = f32color::from_argb(0xFF'FF00FF); - CHECK(c2.r == 0xFF); - CHECK(c2.g == 0x00); - CHECK(c2.b == 0xFF); - CHECK(c2.a == 0xFF); - - u8color c3 = f32color(c1.v, 0.5f); - CHECK(c3.r == 255); - CHECK(c3.g == 0); - CHECK(c3.b == 255); - CHECK(c3.a == 127); - - f32color c4 = from_srgb(f32color(0.75f, 0.25f, 0.5f, 1.f)); -#ifndef KFR_SRGB_APPROX - CHECK(c4.r == 0.522521f); - CHECK(c4.g == 0.0508761f); - CHECK(c4.b == 0.214041f); -#else - CHECK(c4.r == 0.521914f); - CHECK(c4.g == 0.0505368f); - CHECK(c4.b == 0.214967f); -#endif - CHECK(c4.a == 1.f); - - f32color c5 = to_srgb(f32color(0.75f, 0.25f, 0.5f, 1.f)); -#ifndef KFR_SRGB_APPROX - CHECK(c5.r == 0.880825f); - CHECK(c5.g == 0.537099f); - CHECK(c5.b == 0.735357f); -#else - CHECK(c5.r == 0.88027f); - CHECK(c5.g == 0.536654f); - CHECK(c5.b == 0.734586f); -#endif - CHECK(c5.a == 1.f); - - f32color c6 = u8color(0, 127, 255); - CHECK(c6.r == 0.f); -#ifndef KFR_SRGB_APPROX - CHECK(c6.g == 0.212231f); -#else - CHECK(c6.g == 0.213161f); -#endif - CHECK(c6.b == 1.f); - - f32color c7 = u16color(0, 32767, 65535); - CHECK(c7.r == 0.f); - CHECK(c7.g == 0.499992370489f); - CHECK(c7.b == 1.f); -} -} // namespace CMT_ARCH_NAME -} // namespace kfr diff --git a/tests/unit/graphics/geometry.cpp b/tests/unit/graphics/geometry.cpp @@ -1,70 +0,0 @@ -/** - * KFR (https://www.kfrlib.com) - * Copyright (C) 2016-2023 Dan Cazarin - * See LICENSE.txt for details - */ - -#include <kfr/graphics/geometry.hpp> - -namespace kfr -{ -inline namespace CMT_ARCH_NAME -{ -TEST(point) -{ - testo::epsilon_scope<void> e(100); - - f32point p{ 0.f, 0.5f }; - CHECK(p.distance(i32point{ 1, 2 }) == 1.80277563773f); - CHECK(i32point{ 1, 2 } + i32point{ 4, -4 } == i32point{ 5, -2 }); - CHECK(i32point{ 1, 2 } * 4 == i32point{ 4, 8 }); - - CHECK(i32point(f32point{ 0.25f, 0.75f }) == i32point{ 0, 1 }); - - CHECK(f32point{ 0, 0 }.aligned_rect({ 10, 10 }, { 0.5f, 0.5f }) == f32rectangle{ -5, -5, 5, 5 }); - CHECK(f32point{ 0, 0 }.aligned_rect({ 10, 10 }, { 0.f, 0.f }) == f32rectangle{ 0, 0, 10, 10 }); - CHECK(f32point{ 0, 0 }.aligned_rect({ 9, 9 }, { 0.5f, 0.5f }) == - f32rectangle{ -4.5f, -4.5f, 4.5f, 4.5f }); - CHECK(f32point{ 5, 2 }.aligned_rect({ 10, 10 }, { 0.5f, 0.5f }) == f32rectangle{ 0, -3, 10, 7 }); -} - -TEST(size) -{ - CHECK(i32size(f32size{ 0.25f, 0.75f }) == i32size{ 0, 1 }); - CHECK(i32size{ 1, 2 } + i32size{ 4, -4 } == i32size{ 5, -2 }); - CHECK(i32size{ 1, 2 } * 4 == i32size{ 4, 8 }); - CHECK(i32size{ 1, 2 }.area() = 2); -} - -TEST(border) -{ - CHECK(i32border{ 1, 2, 3, 4 }.size() == i32size{ 4, 6 }); - CHECK(i32border{ 1, 2, 3, 4 }.leading() == i32size{ 1, 2 }); - CHECK(i32border{ 1, 2, 3, 4 }.trailing() == i32size{ 3, 4 }); - CHECK(i32border{ 1, 2, 3, 4 }.horizontal() == 4); - CHECK(i32border{ 1, 2, 3, 4 }.vertical() == 6); -} - -TEST(rectangle) -{ - testo::epsilon_scope<void> e(100); - CHECK(f32rectangle{ f32point{ 1, 2 }, f32size{ 2, 2 } } == f32rectangle{ 1, 2, 3, 4 }); - CHECK(f32rectangle{ f32point{ 1, 2 }, f32point{ 3, 4 } } == f32rectangle{ 1, 2, 3, 4 }); - CHECK(f32rectangle{ f32point{ 1, 2 }, f32size{ 3, 4 }, f32point{ 0.5f, 0.5f } } == - f32rectangle{ -0.5f, 0, 2.5f, 4 }); - - CHECK(!i32rectangle{ i32point{ 0, 0 }, i32size{ 3, 1 } }.empty()); - CHECK(i32rectangle{ i32point{ 0, 0 }, i32size{ 3, 0 } }.empty()); - CHECK(i32rectangle{ i32point{ 0, 0 }, i32size{ 0, 3 } }.empty()); - CHECK(i32rectangle{ i32point{ 4, 0 }, i32point{ 3, 101 } }.empty()); - CHECK(!i32rectangle{ i32point{ 3, 0 }, i32point{ 4, 101 } }.empty()); - CHECK(f32rectangle{ 1, 2, 7, 6 }.size() == f32size{ 6, 4 }); - CHECK(f32rectangle{ 1, 2, 7, 6 }.area() == 24); - - CHECK(f32rectangle{ 1, 2, 7, 6 }.min_side() == 4); - CHECK(f32rectangle{ 1, 2, 7, 6 }.max_side() == 6); - CHECK(f32rectangle{ 1, 2, 8, 6 }.center() == f32point{ 4.5f, 4.f }); -} - -} // namespace CMT_ARCH_NAME -} // namespace kfr diff --git a/tests/unit/graphics/graphics.cpp b/tests/unit/graphics/graphics.cpp @@ -1,7 +0,0 @@ -/** - * KFR (https://www.kfrlib.com) - * Copyright (C) 2016-2023 Dan Cazarin - * See LICENSE.txt for details - */ - -#include <kfr/graphics.hpp> diff --git a/update-sources.py b/update-sources.py @@ -37,7 +37,6 @@ list_sources("KFR_BASE_SRC", "include/kfr/base", ['*.hpp', '*.h']) list_sources("KFR_DSP_SRC", "include/kfr/dsp", ['*.hpp', '*.h']) list_sources("KFR_IO_SRC", "include/kfr/io", ['*.hpp', '*.h']) list_sources("KFR_RUNTIME_SRC", "include/kfr/runtime", ['*.hpp', '*.h']) -list_sources("KFR_GRAPHICS_SRC", "include/kfr/graphics", ['*.hpp', '*.h']) list_sources("KFR_SRC", "include", ['*.hpp', '*.h']) list_sources("KFR_DFT_SRC", "src/dft", ['*.cpp']) list_sources("KFR_DSP_SRC", "src/dsp", ['*.cpp'])