From 63e414fc8a7ec04a0710a05ac9ce610fbb15f1e5 Mon Sep 17 00:00:00 2001 From: Ethan Yonker Date: Fri, 6 Feb 2015 15:44:39 -0600 Subject: Scale the GUI to fit the screen With this patch set, if needed, we scale the images during early boot. TTF support is needed to properly scale the font. No font scaling is done on the old style fixed width font used in the console. Special thanks to _that for figuring out the scaling and blending function calls to make this possible. Change-Id: If2f79bef16d6db2e1298bfc3d00c9bcca2bee37a --- minuitwrp/minui.h | 2 ++ minuitwrp/resources.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) (limited to 'minuitwrp') diff --git a/minuitwrp/minui.h b/minuitwrp/minui.h index 3aa486511..fff7ddb97 100644 --- a/minuitwrp/minui.h +++ b/minuitwrp/minui.h @@ -67,6 +67,7 @@ unsigned int gr_get_height(gr_surface surface); int gr_get_surface(gr_surface* surface); int gr_free_surface(gr_surface surface); +// Functions in graphics_utils.c int gr_save_screenshot(const char *dest); // input event structure, include for the definition. @@ -83,6 +84,7 @@ int ev_has_mouse(void); // Returns 0 if no error, else negative. int res_create_surface(const char* name, gr_surface* pSurface); void res_free_surface(gr_surface surface); +int res_scale_surface(gr_surface source, gr_surface* destination, float scale_w, float scale_h); // Needed for AOSP: int ev_wait(int timeout); diff --git a/minuitwrp/resources.c b/minuitwrp/resources.c index 2e58311af..eef5713a1 100644 --- a/minuitwrp/resources.c +++ b/minuitwrp/resources.c @@ -347,7 +347,7 @@ int res_create_surface(const char* name, gr_surface* pSurface) { if (!name) return -1; if (strlen(name) > 4 && strcmp(name + strlen(name) - 4, ".jpg") == 0) - return res_create_surface_jpg(name,pSurface); + return res_create_surface_jpg(name,pSurface); ret = res_create_surface_png(name,pSurface); if (ret < 0) @@ -362,3 +362,77 @@ void res_free_surface(gr_surface surface) { free(pSurface); } } + +// Scale image function +int res_scale_surface(gr_surface source, gr_surface* destination, float scale_w, float scale_h) { + GGLContext *sc_context = 0; + gglInit(&sc_context); + GGLContext *gl = sc_context; + GGLSurface* sc_mem_surface = NULL; + *destination = NULL; + GGLSurface *surface = (GGLSurface*)source; + int w = gr_get_width(source), h = gr_get_height(source); + int sx = 0, sy = 0, dx = 0, dy = 0; + float dw = (float)w * scale_w; + float dh = (float)h * scale_h; + + // Create a new surface that is the appropriate size + sc_mem_surface = init_display_surface((int)dw, (int)dh); + if (!sc_mem_surface) { + printf("gr_scale_surface failed to init_display_surface\n"); + return -1; + } + sc_mem_surface->format = surface->format; + + // Finish initializing the context + gl->colorBuffer(gl, sc_mem_surface); + gl->activeTexture(gl, 0); + + // Enable or disable blending based on source surface format + if (surface->format == GGL_PIXEL_FORMAT_RGBX_8888) { + gl->disable(gl, GGL_BLEND); + } else { + gl->enable(gl, GGL_BLEND); + gl->blendFunc(gl, GGL_ONE, GGL_ZERO); + } + + // Bind our source surface to the context + gl->bindTexture(gl, surface); + + // Deal with the scaling + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MIN_FILTER, GGL_LINEAR); + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_MAG_FILTER, GGL_LINEAR); + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP); + gl->texParameteri(gl, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP); + gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE); + gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); + gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); + gl->enable(gl, GGL_TEXTURE_2D); + + int32_t grad[8]; + memset(grad, 0, sizeof(grad)); + // s, dsdx, dsdy, scale, t, dtdx, dtdy, tscale <- this is wrong! + // This api uses block floating-point for S and T texture coordinates. + // All values are given in 16.16, scaled by 'scale'. In other words, + // set scale to 0, for 16.16 values. + + // s, dsdx, dsdy, t, dtdx, dtdy, sscale, tscale + float dsdx = (float)w / dw; + float dtdy = (float)h / dh; + grad[0] = ((float)sx - (dsdx * dx)) * 65536; + grad[1] = dsdx * 65536; + grad[3] = ((float)sy - (dtdy * dy)) * 65536; + grad[5] = dtdy * 65536; +// printf("blit: w=%d h=%d dx=%d dy=%d dw=%f dh=%f dsdx=%f dtdy=%f s0=%x dsdx=%x t0=%x dtdy=%x\n", +// w, h, dx, dy, dw, dh, dsdx, dtdy, grad[0], grad[1], grad[3], grad[5]); + gl->texCoordGradScale8xv(gl, 0 /*tmu*/, grad); + + // draw / scale the source surface to our target context + gl->recti(gl, dx, dy, dx + dw, dy + dh); + // put the scaled surface in our destination + *destination = (gr_surface*) sc_mem_surface; + // free memory used in the source + res_free_surface(source); + source = NULL; + return 0; +} -- cgit v1.2.3