From dcdcfe175174a0a94997fc3d3d34102b0912b00e Mon Sep 17 00:00:00 2001 From: Tadao Tanikawa Date: Wed, 16 May 2018 09:48:31 +0000 Subject: Enable scaling Fit screen, keep aspect rate. Change-Id: Id11a07560fe254712aaab42018bfb4d1d87ad1df Signed-off-by: Tadao Tanikawa --- layers.json | 2 ++ src/app.cpp | 20 +++++++++++++++----- src/layers.cpp | 5 +++++ src/layers.hpp | 2 ++ src/util.cpp | 27 +++++++++++++++++++++++++++ src/util.hpp | 18 ++++++++++++++++++ 6 files changed, 69 insertions(+), 5 deletions(-) diff --git a/layers.json b/layers.json index cf7ed34..230da55 100644 --- a/layers.json +++ b/layers.json @@ -3,6 +3,8 @@ "main_surface": { "surface_role": "HomeScreen", + "width": 1080, + "height": 1920, "comment": "This surface should never be made invisible (The HomeScreen)" }, diff --git a/src/app.cpp b/src/app.cpp index e9d79f5..e37490b 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -58,7 +58,6 @@ const char kKeyHeightPixel[] = "height_pixel"; const char kKeyWidthMm[] = "width_mm"; const char kKeyHeightMm[] = "height_mm"; - namespace { using nlohmann::json; @@ -237,11 +236,22 @@ int App::init_layers() { // Clear screen s->clear(); + int width = this->layers.main_surface_width; + int height = this->layers.main_surface_height; + + rectangle rect(width, height); // 1080x1920 by default + rect.scale(o->width, o->height, true); + rect.center(o->width, o->height); + + HMI_DEBUG("wm", "Main surface (0,0),%dx%d to (%d,%d),%dx%d", + width, height, rect.left(), rect.top(), rect.width(), rect.height()); + // Quick and dirty setup of layers for (auto const &i : this->layers.mapping) { - c->layer_create(i.second.layer_id, o->width, o->height); + c->layer_create(i.second.layer_id, rect.width(), rect.height()); auto &l = layers[i.second.layer_id]; - l->set_destination_rectangle(0, 0, o->width, o->height); + l->set_source_rectangle(0, 0, width, height); + l->set_destination_rectangle(rect.left(), rect.top(), rect.width(), rect.height()); l->set_visibility(1); HMI_DEBUG("wm", "Setting up layer %s (%d) for surface role match \"%s\"", i.second.name.c_str(), i.second.layer_id, i.second.role.c_str()); @@ -282,10 +292,10 @@ void App::surface_set_layout(int surface_id, optional sub_surface_id) { // less-than-0 values refer to MAX + 1 - $VALUE // e.g. MAX is either screen width or height if (w < 0) { - w = this->controller->output_size.w + 1 + w; + w = this->layers.main_surface_width + 1 + w; } if (h < 0) { - h = this->controller->output_size.h + 1 + h; + h = this->layers.main_surface_height + 1 + h; } if (sub_surface_id) { diff --git a/src/layers.cpp b/src/layers.cpp index 04f944d..8698e83 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -24,6 +24,9 @@ namespace wm { +const int default_main_width = 1080; +const int default_main_height = 1920; + using json = nlohmann::json; layer::layer(nlohmann::json const &j) { @@ -104,6 +107,8 @@ struct result to_layer_map(nlohmann::json const &j) { auto msi = j.find("main_surface"); if (msi != j.end()) { stl.main_surface_name = msi->value("surface_role", ""); + stl.main_surface_width = msi->value("width", default_main_width); + stl.main_surface_height = msi->value("height", default_main_height); stl.main_surface = -1; } diff --git a/src/layers.hpp b/src/layers.hpp index 1942229..27573a2 100644 --- a/src/layers.hpp +++ b/src/layers.hpp @@ -77,6 +77,8 @@ struct layer_map { layers_type layers; // the actual layer IDs we have int main_surface; std::string main_surface_name; + int main_surface_width; + int main_surface_height; role_to_layer_map roles; addsurf_layer_map surfaces; // additional surfaces on layers diff --git a/src/util.cpp b/src/util.cpp index 2ae856f..068e7b8 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -37,3 +37,30 @@ unique_fd::~unique_fd() { close(this->fd); } } + +void rectangle::scale(int to_w, int to_h, bool keep_aspect) +{ + if (!keep_aspect) { + w = to_w; + h = to_h; + return; + } + + int64_t resized_w = int64_t(to_h) * int64_t(w) / int64_t(h); + + if (resized_w <= to_w) { + /* use aspect by height */ + w = resized_w; + h = to_h; + } else { + /* use aspect by width */ + w = to_h; + h = int64_t(to_h) * int64_t(h) / int64_t(w); + } +} + +void rectangle::center(int outer_w, int outer_h) +{ + x = (outer_w - w) / 2; + y = (outer_h - h) / 2; +} diff --git a/src/util.hpp b/src/util.hpp index f4e6e5f..6c6d0b9 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -103,4 +103,22 @@ struct unique_fd { } }; +class rectangle +{ +public: + explicit rectangle(int wd, int ht) : w(wd), h(ht) {}; + void scale(int to_w, int to_h, bool keep_aspect); + void center(int outer_w, int outer_h); + int left() { return x; }; + int top() { return y; }; + int width() { return w; }; + int height() { return h; }; + +private: + int x = 0; + int y = 0; + int w; + int h; +}; + #endif // !WM_UTIL_HPP -- cgit 1.2.3-korg