root / ui / sdl_zoom.c @ e0ff466c
History | View | Annotate | Download (2.8 kB)
1 | c18a2c36 | Stefano Stabellini | /*
|
---|---|---|---|
2 | c18a2c36 | Stefano Stabellini | * SDL_zoom - surface scaling
|
3 | c18a2c36 | Stefano Stabellini | *
|
4 | c18a2c36 | Stefano Stabellini | * Copyright (c) 2009 Citrix Systems, Inc.
|
5 | c18a2c36 | Stefano Stabellini | *
|
6 | c18a2c36 | Stefano Stabellini | * Derived from: SDL_rotozoom, LGPL (c) A. Schiffler from the SDL_gfx library.
|
7 | c18a2c36 | Stefano Stabellini | * Modifications by Stefano Stabellini.
|
8 | c18a2c36 | Stefano Stabellini | *
|
9 | c18a2c36 | Stefano Stabellini | * This work is licensed under the terms of the GNU GPL version 2.
|
10 | c18a2c36 | Stefano Stabellini | * See the COPYING file in the top-level directory.
|
11 | c18a2c36 | Stefano Stabellini | *
|
12 | c18a2c36 | Stefano Stabellini | */
|
13 | c18a2c36 | Stefano Stabellini | |
14 | c18a2c36 | Stefano Stabellini | #include "sdl_zoom.h" |
15 | 1de7afc9 | Paolo Bonzini | #include "qemu/osdep.h" |
16 | cc69bda6 | Markus Armbruster | #include <glib.h> |
17 | c18a2c36 | Stefano Stabellini | #include <stdint.h> |
18 | 22d091b3 | Blue Swirl | #include <stdio.h> |
19 | c18a2c36 | Stefano Stabellini | |
20 | cc69bda6 | Markus Armbruster | static void sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth, |
21 | cc69bda6 | Markus Armbruster | SDL_Rect *dst_rect); |
22 | cc69bda6 | Markus Armbruster | static void sdl_zoom_rgb32(SDL_Surface *src, SDL_Surface *dst, int smooth, |
23 | cc69bda6 | Markus Armbruster | SDL_Rect *dst_rect); |
24 | c18a2c36 | Stefano Stabellini | |
25 | c18a2c36 | Stefano Stabellini | #define BPP 32 |
26 | c18a2c36 | Stefano Stabellini | #include "sdl_zoom_template.h" |
27 | c18a2c36 | Stefano Stabellini | #undef BPP
|
28 | c18a2c36 | Stefano Stabellini | #define BPP 16 |
29 | c18a2c36 | Stefano Stabellini | #include "sdl_zoom_template.h" |
30 | c18a2c36 | Stefano Stabellini | #undef BPP
|
31 | c18a2c36 | Stefano Stabellini | |
32 | c18a2c36 | Stefano Stabellini | int sdl_zoom_blit(SDL_Surface *src_sfc, SDL_Surface *dst_sfc, int smooth, |
33 | c18a2c36 | Stefano Stabellini | SDL_Rect *in_rect) |
34 | c18a2c36 | Stefano Stabellini | { |
35 | c18a2c36 | Stefano Stabellini | SDL_Rect zoom, src_rect; |
36 | c18a2c36 | Stefano Stabellini | int extra;
|
37 | c18a2c36 | Stefano Stabellini | |
38 | c18a2c36 | Stefano Stabellini | /* Grow the size of the modified rectangle to avoid edge artefacts */
|
39 | c18a2c36 | Stefano Stabellini | src_rect.x = (in_rect->x > 0) ? (in_rect->x - 1) : 0; |
40 | c18a2c36 | Stefano Stabellini | src_rect.y = (in_rect->y > 0) ? (in_rect->y - 1) : 0; |
41 | c18a2c36 | Stefano Stabellini | |
42 | c18a2c36 | Stefano Stabellini | src_rect.w = in_rect->w + 1;
|
43 | c18a2c36 | Stefano Stabellini | if (src_rect.x + src_rect.w > src_sfc->w)
|
44 | c18a2c36 | Stefano Stabellini | src_rect.w = src_sfc->w - src_rect.x; |
45 | c18a2c36 | Stefano Stabellini | |
46 | c18a2c36 | Stefano Stabellini | src_rect.h = in_rect->h + 1;
|
47 | c18a2c36 | Stefano Stabellini | if (src_rect.y + src_rect.h > src_sfc->h)
|
48 | c18a2c36 | Stefano Stabellini | src_rect.h = src_sfc->h - src_rect.y; |
49 | c18a2c36 | Stefano Stabellini | |
50 | c18a2c36 | Stefano Stabellini | /* (x,y) : round down */
|
51 | c18a2c36 | Stefano Stabellini | zoom.x = (int)(((float)(src_rect.x * dst_sfc->w)) / (float)(src_sfc->w)); |
52 | c18a2c36 | Stefano Stabellini | zoom.y = (int)(((float)(src_rect.y * dst_sfc->h)) / (float)(src_sfc->h)); |
53 | c18a2c36 | Stefano Stabellini | |
54 | c18a2c36 | Stefano Stabellini | /* (w,h) : round up */
|
55 | c18a2c36 | Stefano Stabellini | zoom.w = (int)( ((double)((src_rect.w * dst_sfc->w) + (src_sfc->w - 1))) / |
56 | c18a2c36 | Stefano Stabellini | (double)(src_sfc->w));
|
57 | c18a2c36 | Stefano Stabellini | |
58 | c18a2c36 | Stefano Stabellini | zoom.h = (int)( ((double)((src_rect.h * dst_sfc->h) + (src_sfc->h - 1))) / |
59 | c18a2c36 | Stefano Stabellini | (double)(src_sfc->h));
|
60 | c18a2c36 | Stefano Stabellini | |
61 | c18a2c36 | Stefano Stabellini | /* Account for any (x,y) rounding by adding one-source-pixel's worth
|
62 | c18a2c36 | Stefano Stabellini | * of destination pixels and then edge checking.
|
63 | c18a2c36 | Stefano Stabellini | */
|
64 | c18a2c36 | Stefano Stabellini | |
65 | c18a2c36 | Stefano Stabellini | extra = ((dst_sfc->w-1) / src_sfc->w) + 1; |
66 | c18a2c36 | Stefano Stabellini | |
67 | c18a2c36 | Stefano Stabellini | if ((zoom.x + zoom.w) < (dst_sfc->w - extra))
|
68 | c18a2c36 | Stefano Stabellini | zoom.w += extra; |
69 | c18a2c36 | Stefano Stabellini | else
|
70 | c18a2c36 | Stefano Stabellini | zoom.w = dst_sfc->w - zoom.x; |
71 | c18a2c36 | Stefano Stabellini | |
72 | c18a2c36 | Stefano Stabellini | extra = ((dst_sfc->h-1) / src_sfc->h) + 1; |
73 | c18a2c36 | Stefano Stabellini | |
74 | c18a2c36 | Stefano Stabellini | if ((zoom.y + zoom.h) < (dst_sfc->h - extra))
|
75 | c18a2c36 | Stefano Stabellini | zoom.h += extra; |
76 | c18a2c36 | Stefano Stabellini | else
|
77 | c18a2c36 | Stefano Stabellini | zoom.h = dst_sfc->h - zoom.y; |
78 | c18a2c36 | Stefano Stabellini | |
79 | c18a2c36 | Stefano Stabellini | /* The rectangle (zoom.x, zoom.y, zoom.w, zoom.h) is the area on the
|
80 | c18a2c36 | Stefano Stabellini | * destination surface that needs to be updated.
|
81 | c18a2c36 | Stefano Stabellini | */
|
82 | c18a2c36 | Stefano Stabellini | if (src_sfc->format->BitsPerPixel == 32) |
83 | c18a2c36 | Stefano Stabellini | sdl_zoom_rgb32(src_sfc, dst_sfc, smooth, &zoom); |
84 | c18a2c36 | Stefano Stabellini | else if (src_sfc->format->BitsPerPixel == 16) |
85 | c18a2c36 | Stefano Stabellini | sdl_zoom_rgb16(src_sfc, dst_sfc, smooth, &zoom); |
86 | c18a2c36 | Stefano Stabellini | else {
|
87 | c18a2c36 | Stefano Stabellini | fprintf(stderr, "pixel format not supported\n");
|
88 | c18a2c36 | Stefano Stabellini | return -1; |
89 | c18a2c36 | Stefano Stabellini | } |
90 | c18a2c36 | Stefano Stabellini | |
91 | c18a2c36 | Stefano Stabellini | /* Return the rectangle of the update to the caller */
|
92 | c18a2c36 | Stefano Stabellini | *in_rect = zoom; |
93 | c18a2c36 | Stefano Stabellini | |
94 | c18a2c36 | Stefano Stabellini | return 0; |
95 | c18a2c36 | Stefano Stabellini | } |