diff --git a/docs/CHANGES.txt b/docs/CHANGES.txt index 187fbfc94..5950671a3 100644 --- a/docs/CHANGES.txt +++ b/docs/CHANGES.txt @@ -85,6 +85,11 @@ http://www.tuxpaint.org/ * Don't play 'bubble' paint sound when color picker or selector (or new mixer) are aborted (via their "Back" buttons or [Esc] key). + * New Magic Tools: + ---------------- + * "Tile Zoom"; like the regular "Zoom", but tiles the results when + you scale down (similar to "Panels", but with non-integer scaling). + * Localization Updates: --------------------- * Albanian translation diff --git a/magic/icons/tilezoom.png b/magic/icons/tilezoom.png new file mode 100644 index 000000000..930f67b91 Binary files /dev/null and b/magic/icons/tilezoom.png differ diff --git a/magic/src/perspective.c b/magic/src/perspective.c index c9bd03b3a..40672e71d 100644 --- a/magic/src/perspective.c +++ b/magic/src/perspective.c @@ -2,13 +2,14 @@ perspective.c perspective, stretches the plane of the image. - zoom, zooms in and out the image. + zoom & tile zoom, zooms in and out the image. + panels, turns the images into a 2x2 grid. Tux Paint - A simple drawing program for children. Credits: Andrew Corcoran - Copyright (c) 2002-2021 by Bill Kendrick and others; see AUTHORS.txt + Copyright (c) 2002-2022 by Bill Kendrick and others; see AUTHORS.txt bill@newbreedsoftware.com http://www.tuxpaint.org/ @@ -27,7 +28,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (See COPYING.txt) - Last updated: September 20, 2021 + Last updated: January 30, 2022 $Id$ */ @@ -116,6 +117,7 @@ enum { TOOL_PERSPECTIVE, TOOL_PANELS, + TOOL_TILEZOOM, TOOL_ZOOM, perspective_NUM_TOOLS }; @@ -144,12 +146,14 @@ const char *perspective_snd_filenames[perspective_NUM_TOOLS + 1] = { const char *perspective_icon_filenames[perspective_NUM_TOOLS] = { "perspective.png", "panels.png", + "tilezoom.png", "zoom.png", }; const char *perspective_names[perspective_NUM_TOOLS] = { gettext_noop("Perspective"), gettext_noop("Panels"), + gettext_noop("Tile Zoom"), gettext_noop("Zoom"), }; @@ -159,6 +163,8 @@ const char *perspective_descs[perspective_NUM_TOOLS] = { gettext_noop("Click to turn your picture into 2-by-2 panels."), gettext_noop("Click and drag up to zoom in or drag down to zoom out the picture."), + + gettext_noop("Click and drag up to zoom in or drag down to zoom out the picture."), }; Uint32 perspective_api_version(void) @@ -282,14 +288,18 @@ void perspective_drag(magic_api * api, int which, SDL_Surface * canvas, } break; case TOOL_ZOOM: + case TOOL_TILEZOOM: { int x_distance, y_distance; - update_rect->x = update_rect->y = 0; - update_rect->w = canvas->w; - update_rect->h = canvas->h; - - SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); + if (which == TOOL_ZOOM) + { + update_rect->x = update_rect->y = 0; + update_rect->w = canvas->w; + update_rect->h = canvas->h; + + SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); + } new_h = max(1, old_h + click_y - y); new_w = canvas->w * new_h / canvas->h; @@ -361,6 +371,7 @@ void perspective_click(magic_api * api, int which, int mode ATTRIBUTE_UNUSED, } break; case TOOL_ZOOM: + case TOOL_TILEZOOM: { click_x = x; click_y = y; @@ -433,6 +444,7 @@ void perspective_release(magic_api * api, int which, break; case TOOL_ZOOM: + case TOOL_TILEZOOM: { SDL_Surface *aux_surf; SDL_Surface *scaled_surf; @@ -441,17 +453,35 @@ void perspective_release(magic_api * api, int which, update_rect->w = canvas->w; update_rect->h = canvas->h; - SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); + if (which == TOOL_ZOOM) + SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); if (new_h < canvas->h) { + int xx, yy, x_span, y_span; + scaled_surf = api->scale(canvas_back, new_w, new_h, 0); - update_rect->x = (canvas->w - new_w) / 2; - update_rect->y = (canvas->h - new_h) / 2; - update_rect->w = new_w; - update_rect->h = new_h; - SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect); + + if (which == TOOL_TILEZOOM && (new_w < canvas->w || new_h < canvas->h)) + { + x_span = ceil(canvas->w / new_w); + y_span = ceil(canvas->h / new_h); + } + else + x_span = y_span = 0; + + for (yy = -y_span; yy <= y_span; yy++) + { + for (xx = -x_span; xx <= x_span; xx++) + { + update_rect->x = ((canvas->w - new_w) / 2) + (new_w * xx); + update_rect->y = ((canvas->h - new_h) / 2) + (new_h * yy); + update_rect->w = new_w; + update_rect->h = new_h; + SDL_BlitSurface(scaled_surf, NULL, canvas, update_rect); + } + } } else { @@ -487,7 +517,7 @@ void perspective_release(magic_api * api, int which, } } -void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED, +void perspective_preview(magic_api * api, int which, SDL_Surface * canvas, SDL_Surface * last ATTRIBUTE_UNUSED, int x ATTRIBUTE_UNUSED, int y ATTRIBUTE_UNUSED, SDL_Rect * update_rect, float step) { @@ -501,7 +531,10 @@ void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED, update_rect->w = canvas->w; update_rect->h = canvas->h; - SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); + if (which == TOOL_ZOOM) + SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, perspective_r, perspective_g, perspective_b)); + else if (which == TOOL_TILEZOOM) + SDL_FillRect(canvas, update_rect, SDL_MapRGB(canvas->format, 128, 128, 128)); ox_distance = otop_right_x - otop_left_x; oy_distance = obottom_left_y - otop_left_y; @@ -537,6 +570,35 @@ void perspective_preview(magic_api * api, int which ATTRIBUTE_UNUSED, api->putpixel(canvas, ax + dx - center_ofset_x, ay + dy - center_ofset_y, api->getpixel(canvas_back, i, j)); } } + + if (which == TOOL_TILEZOOM && new_w >= 2 && new_h >= 2) + { + int xx, yy, x_span, y_span; + SDL_Rect src_rect, dest_rect; + + x_span = ceil(canvas->w / new_w); + y_span = ceil(canvas->h / new_h); + + src_rect.x = -center_ofset_x; + src_rect.y = -center_ofset_y; + src_rect.w = new_w; + src_rect.h = new_h; + + for (yy = -y_span; yy <= y_span; yy++) + { + for (xx = -x_span; xx <= x_span; xx++) + { + if (xx != 0 || yy != 0) + { + dest_rect.x = ((canvas->w - new_w) / 2) + (new_w * xx); + dest_rect.y = ((canvas->h - new_h) / 2) + (new_h * yy); + dest_rect.w = new_w; + dest_rect.h = new_h; + SDL_BlitSurface(canvas, &src_rect, canvas, &dest_rect); + } + } + } + } } void perspective_shutdown(magic_api * api ATTRIBUTE_UNUSED) @@ -564,7 +626,7 @@ void perspective_set_color(magic_api * api ATTRIBUTE_UNUSED, Uint8 r, Uint8 g, U // Use colors: int perspective_requires_colors(magic_api * api ATTRIBUTE_UNUSED, int which) { - if (which == TOOL_PANELS) + if (which == TOOL_PANELS || which == TOOL_TILEZOOM) return 0; return 1; }