hints.cc (1996B)
1 #include "hints.hh" 2 3 #include <algorithm> 4 #include <cmath> 5 6 using namespace winsys; 7 8 void 9 SizeHints::apply(Dim& dim) 10 { 11 int dest_width = dim.w; 12 int dest_height = dim.h; 13 14 if (min_width) 15 dest_width = std::max(dest_width, *min_width); 16 17 if (min_height) 18 dest_height = std::max(dest_height, *min_height); 19 20 if (max_width) 21 dest_width = std::min(dest_width, *max_width); 22 23 if (max_height) 24 dest_height = std::min(dest_height, *max_height); 25 26 int base_width = this->base_width 27 ? *this->base_width 28 : 0; 29 30 int base_height = this->base_height 31 ? *this->base_height 32 : 0; 33 34 int width = base_width < dest_width 35 ? dest_width - base_width 36 : dest_width; 37 38 int height = base_height < dest_height 39 ? dest_height - base_height 40 : dest_height; 41 42 if (min_ratio || max_ratio) { 43 if (height == 0) 44 height = 1; 45 46 double current_ratio 47 = static_cast<double>(width) / static_cast<double>(height); 48 49 std::optional<double> new_ratio = std::nullopt; 50 51 if (min_ratio && current_ratio < *min_ratio) 52 new_ratio = min_ratio; 53 54 if (!new_ratio && max_ratio && current_ratio > *max_ratio) 55 new_ratio = max_ratio; 56 57 if (new_ratio) { 58 height = std::round(static_cast<double>(width) / *new_ratio); 59 width = std::round(static_cast<double>(height) * *new_ratio); 60 61 dest_width = width + base_width; 62 dest_height = height + base_height; 63 } 64 } 65 66 if (inc_height && dest_height >= base_height) { 67 dest_height -= base_height; 68 dest_height -= dest_height % *inc_height; 69 dest_height += base_height; 70 } 71 72 if (inc_width && dest_width >= base_width) { 73 dest_width -= base_width; 74 dest_width -= dest_width % *inc_width; 75 dest_width += base_width; 76 } 77 78 dim.h = std::max(dest_height, 0); 79 dim.w = std::max(dest_width, 0); 80 }