summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-03-08 18:14:51 +0200
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-03-08 18:14:51 +0200
commita31b3f27037cc75b733a34871cfadc9707055b16 (patch)
tree8b7f9461925b20aea5453591ffce61570783cd84
parentc3bbfbba4209a2d11b65b58233619b05e4397c91 (diff)
Scale images for display
Resize images down to the maximum texture size or the screen size, whichever is smaller. IssueID #167
-rw-r--r--src/media.c37
-rw-r--r--src/ui/window.c7
-rw-r--r--src/ui/window.h1
3 files changed, 40 insertions, 5 deletions
diff --git a/src/media.c b/src/media.c
index b329ec03..28148ad7 100644
--- a/src/media.c
+++ b/src/media.c
@@ -26,10 +26,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26#include "ui/window.h" 26#include "ui/window.h"
27#include "audio/player.h" 27#include "audio/player.h"
28#include "app.h" 28#include "app.h"
29#include "stb_image.h"
30#include "stb_image_resize.h"
29 31
30#include <the_Foundation/file.h> 32#include <the_Foundation/file.h>
31#include <the_Foundation/ptrarray.h> 33#include <the_Foundation/ptrarray.h>
32#include <stb_image.h>
33#include <SDL_hints.h> 34#include <SDL_hints.h>
34#include <SDL_render.h> 35#include <SDL_render.h>
35#include <SDL_timer.h> 36#include <SDL_timer.h>
@@ -92,15 +93,41 @@ void makeTexture_GmImage(iGmImage *d) {
92 } 93 }
93 else { 94 else {
94 /* TODO: Save some memory by checking if the alpha channel is actually in use. */ 95 /* TODO: Save some memory by checking if the alpha channel is actually in use. */
95 /* TODO: Resize down to min(maximum texture size, window size). */ 96 iWindow *window = get_Window();
97 iInt2 texSize = d->size;
98 /* Resize down to min(maximum texture size, window size). */ {
99 SDL_Rect dispRect;
100 SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(window->win), &dispRect);
101 const iInt2 maxSize = min_I2(maxTextureSize_Window(window),
102 coord_Window(window, dispRect.w, dispRect.h));
103 iInt2 scaled = d->size;
104 if (scaled.x > maxSize.x) {
105 scaled.y = scaled.y * maxSize.x / scaled.x;
106 scaled.x = maxSize.x;
107 }
108 if (scaled.y > maxSize.y) {
109 scaled.x = scaled.x * maxSize.y / scaled.y;
110 scaled.y = maxSize.y;
111 }
112 if (!isEqual_I2(scaled, d->size)) {
113 uint8_t *scaledImgData = malloc(scaled.x * scaled.y * 4);
114 stbir_resize_uint8(imgData, d->size.x, d->size.y, 4 * d->size.x,
115 scaledImgData, scaled.x, scaled.y, scaled.x * 4, 4);
116 free(imgData);
117 imgData = scaledImgData;
118 texSize = scaled;
119 /* We keep d->size for the UI. */
120 }
121 }
122 /* Create the texture. */
96 SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( 123 SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom(
97 imgData, d->size.x, d->size.y, 32, d->size.x * 4, SDL_PIXELFORMAT_ABGR8888); 124 imgData, texSize.x, texSize.y, 32, texSize.x * 4, SDL_PIXELFORMAT_ABGR8888);
98 /* TODO: In multiwindow case, all windows must have the same shared renderer? 125 /* TODO: In multiwindow case, all windows must have the same shared renderer?
99 Or at least a shared context. */ 126 Or at least a shared context. */
100 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); /* linear scaling */ 127 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); /* linear scaling */
101 d->texture = SDL_CreateTextureFromSurface(renderer_Window(get_Window()), surface); 128 d->texture = SDL_CreateTextureFromSurface(renderer_Window(window), surface);
102 SDL_FreeSurface(surface); 129 SDL_FreeSurface(surface);
103 stbi_image_free(imgData); 130 free(imgData);
104 } 131 }
105 clear_Block(data); 132 clear_Block(data);
106} 133}
diff --git a/src/ui/window.c b/src/ui/window.c
index 038d72af..3c362986 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1397,11 +1397,18 @@ SDL_Renderer *renderer_Window(const iWindow *d) {
1397 return d->render; 1397 return d->render;
1398} 1398}
1399 1399
1400iInt2 maxTextureSize_Window(const iWindow *d) {
1401 SDL_RendererInfo info;
1402 SDL_GetRendererInfo(d->render, &info);
1403 return init_I2(info.max_texture_width, info.max_texture_height);
1404}
1405
1400iBool isFullscreen_Window(const iWindow *d) { 1406iBool isFullscreen_Window(const iWindow *d) {
1401 return snap_Window(d) == fullscreen_WindowSnap; 1407 return snap_Window(d) == fullscreen_WindowSnap;
1402} 1408}
1403 1409
1404static void invalidate_Window_(iWindow *d) { 1410static void invalidate_Window_(iWindow *d) {
1411 iUnused(d);
1405 resetFonts_Text(); 1412 resetFonts_Text();
1406 postCommand_App("theme.changed"); /* forces UI invalidation */ 1413 postCommand_App("theme.changed"); /* forces UI invalidation */
1407} 1414}
diff --git a/src/ui/window.h b/src/ui/window.h
index 8bc9911c..9a70fdec 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -93,6 +93,7 @@ void setKeyboardHeight_Window(iWindow *, int height);
93uint32_t id_Window (const iWindow *); 93uint32_t id_Window (const iWindow *);
94iInt2 rootSize_Window (const iWindow *); 94iInt2 rootSize_Window (const iWindow *);
95iInt2 visibleRootSize_Window (const iWindow *); /* may be obstructed by software keyboard */ 95iInt2 visibleRootSize_Window (const iWindow *); /* may be obstructed by software keyboard */
96iInt2 maxTextureSize_Window (const iWindow *);
96float uiScale_Window (const iWindow *); 97float uiScale_Window (const iWindow *);
97iInt2 coord_Window (const iWindow *, int x, int y); 98iInt2 coord_Window (const iWindow *, int x, int y);
98iInt2 mouseCoord_Window (const iWindow *); 99iInt2 mouseCoord_Window (const iWindow *);