diff options
-rw-r--r-- | src/media.c | 37 | ||||
-rw-r--r-- | src/ui/window.c | 7 | ||||
-rw-r--r-- | src/ui/window.h | 1 |
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 | ||
1400 | iInt2 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 | |||
1400 | iBool isFullscreen_Window(const iWindow *d) { | 1406 | iBool isFullscreen_Window(const iWindow *d) { |
1401 | return snap_Window(d) == fullscreen_WindowSnap; | 1407 | return snap_Window(d) == fullscreen_WindowSnap; |
1402 | } | 1408 | } |
1403 | 1409 | ||
1404 | static void invalidate_Window_(iWindow *d) { | 1410 | static 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); | |||
93 | uint32_t id_Window (const iWindow *); | 93 | uint32_t id_Window (const iWindow *); |
94 | iInt2 rootSize_Window (const iWindow *); | 94 | iInt2 rootSize_Window (const iWindow *); |
95 | iInt2 visibleRootSize_Window (const iWindow *); /* may be obstructed by software keyboard */ | 95 | iInt2 visibleRootSize_Window (const iWindow *); /* may be obstructed by software keyboard */ |
96 | iInt2 maxTextureSize_Window (const iWindow *); | ||
96 | float uiScale_Window (const iWindow *); | 97 | float uiScale_Window (const iWindow *); |
97 | iInt2 coord_Window (const iWindow *, int x, int y); | 98 | iInt2 coord_Window (const iWindow *, int x, int y); |
98 | iInt2 mouseCoord_Window (const iWindow *); | 99 | iInt2 mouseCoord_Window (const iWindow *); |