Enable scaling
authorTadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
Wed, 16 May 2018 09:48:31 +0000 (09:48 +0000)
committerTadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
Wed, 16 May 2018 09:48:31 +0000 (09:48 +0000)
Fit screen, keep aspect rate.

Change-Id: Id11a07560fe254712aaab42018bfb4d1d87ad1df
Signed-off-by: Tadao Tanikawa <tanikawa.tadao@jp.panasonic.com>
layers.json
src/app.cpp
src/layers.cpp
src/layers.hpp
src/util.cpp
src/util.hpp

index cf7ed34..230da55 100644 (file)
@@ -3,6 +3,8 @@
 
    "main_surface": {
       "surface_role": "HomeScreen",
+      "width": 1080,
+      "height": 1920,
       "comment": "This surface should never be made invisible (The HomeScreen)"
    },
 
index e9d79f5..e37490b 100644 (file)
@@ -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<int> 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) {
index 04f944d..8698e83 100644 (file)
@@ -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<struct layer_map> 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;
       }
 
index 1942229..27573a2 100644 (file)
@@ -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
 
index 2ae856f..068e7b8 100644 (file)
@@ -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;
+}
index f4e6e5f..6c6d0b9 100644 (file)
@@ -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