mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
Refactor the thumbnails generation of cels
A new Render::renderCel() method is used to render the specific cel thumbnail, useful in the future to render thumbnails of different kind of layers (e.g. future tilemaps). And now the background is rendered in a different step (so the thumbnails doesn't contain the background.)
This commit is contained in:
parent
59361a3b6d
commit
e3f09525db
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -41,18 +41,17 @@ namespace {
|
||||
gfx::Color gridColor1 = gfx::rgba(128, 128, 128);
|
||||
gfx::Color gridColor2 = gfx::rgba(192, 192, 192);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
static void rectgrid(ui::Graphics* g, const gfx::Rect& rc, const gfx::Size& tile)
|
||||
void draw_checked_grid(ui::Graphics* g,
|
||||
const gfx::Rect& rc,
|
||||
const gfx::Size& tile,
|
||||
const gfx::Color c1,
|
||||
const gfx::Color c2)
|
||||
{
|
||||
if (tile.w < 1 || tile.h < 1)
|
||||
return;
|
||||
|
||||
int x, y, u, v;
|
||||
|
||||
const gfx::Color c1 = gridColor1;
|
||||
const gfx::Color c2 = gridColor2;
|
||||
|
||||
u = 0;
|
||||
v = 0;
|
||||
for (y=rc.y; y<rc.y2()-tile.h; y+=tile.h) {
|
||||
@ -74,6 +73,26 @@ static void rectgrid(ui::Graphics* g, const gfx::Rect& rc, const gfx::Size& tile
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void draw_checked_grid(ui::Graphics* g,
|
||||
const gfx::Rect& rc,
|
||||
const gfx::Size& tile)
|
||||
{
|
||||
draw_checked_grid(g, rc, tile,
|
||||
gridColor1, gridColor2);
|
||||
}
|
||||
|
||||
void draw_checked_grid(ui::Graphics* g,
|
||||
const gfx::Rect& rc,
|
||||
const gfx::Size& tile,
|
||||
DocumentPreferences& docPref)
|
||||
{
|
||||
draw_checked_grid(g, rc, tile,
|
||||
color_utils::color_for_ui(docPref.bg.color1()),
|
||||
color_utils::color_for_ui(docPref.bg.color2()));
|
||||
}
|
||||
|
||||
void draw_color(ui::Graphics* g,
|
||||
const Rect& rc,
|
||||
const app::Color& _color,
|
||||
@ -90,9 +109,9 @@ void draw_color(ui::Graphics* g,
|
||||
|
||||
if (alpha < 255) {
|
||||
if (rc.w == rc.h)
|
||||
rectgrid(g, rc, gfx::Size(rc.w/2, rc.h/2));
|
||||
draw_checked_grid(g, rc, gfx::Size(rc.w/2, rc.h/2));
|
||||
else
|
||||
rectgrid(g, rc, gfx::Size(rc.w/4, rc.h/2));
|
||||
draw_checked_grid(g, rc, gfx::Size(rc.w/4, rc.h/2));
|
||||
}
|
||||
|
||||
if (alpha > 0) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -9,9 +10,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "app/color.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "doc/color_mode.h"
|
||||
#include "gfx/color.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "gfx/size.h"
|
||||
#include "ui/base.h"
|
||||
|
||||
namespace os {
|
||||
@ -23,7 +26,15 @@ namespace ui {
|
||||
}
|
||||
|
||||
namespace app {
|
||||
using namespace doc;
|
||||
|
||||
void draw_checked_grid(ui::Graphics* g,
|
||||
const gfx::Rect& rc,
|
||||
const gfx::Size& tile);
|
||||
|
||||
void draw_checked_grid(ui::Graphics* g,
|
||||
const gfx::Rect& rc,
|
||||
const gfx::Size& tile,
|
||||
DocumentPreferences& docPref);
|
||||
|
||||
void draw_color(ui::Graphics* g,
|
||||
const gfx::Rect& rc,
|
||||
|
@ -1,100 +1,72 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2018 David Capello
|
||||
// Copyright (C) 2016 Carlo Caputo
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#include "app/color_utils.h"
|
||||
#include "app/doc.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/thumbnails.h"
|
||||
#include "doc/algorithm/resize_image.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "doc/blend_mode.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/conversion_to_surface.h"
|
||||
#include "doc/doc.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/object.h"
|
||||
#include "doc/object_id.h"
|
||||
#include "render/render.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "os/surface.h"
|
||||
#include "os/system.h"
|
||||
#include "render/render.h"
|
||||
|
||||
namespace app {
|
||||
namespace thumb {
|
||||
|
||||
os::Surface* get_cel_thumbnail(const doc::Cel* cel,
|
||||
const gfx::Size& thumb_size,
|
||||
gfx::Rect cel_image_on_thumb)
|
||||
const gfx::Size& fitInSize)
|
||||
{
|
||||
Doc* document = static_cast<Doc*>(cel->sprite()->document());
|
||||
doc::frame_t frame = cel->frame();
|
||||
doc::Image* image = cel->image();
|
||||
gfx::Size newSize;
|
||||
|
||||
DocumentPreferences& docPref = Preferences::instance().document(document);
|
||||
if (cel->bounds().w > fitInSize.w ||
|
||||
cel->bounds().h > fitInSize.h)
|
||||
newSize = gfx::Rect(cel->bounds()).fitIn(gfx::Rect(fitInSize)).size();
|
||||
else
|
||||
newSize = cel->bounds().size();
|
||||
|
||||
doc::color_t bg1 = color_utils::color_for_image(docPref.bg.color1(), image->pixelFormat());
|
||||
doc::color_t bg2 = color_utils::color_for_image(docPref.bg.color2(), image->pixelFormat());
|
||||
if (newSize.w < 1 ||
|
||||
newSize.h < 1)
|
||||
return nullptr;
|
||||
|
||||
gfx::Size image_size = image->size();
|
||||
doc::ImageRef thumbnailImage(
|
||||
doc::Image::create(
|
||||
doc::IMAGE_RGB, newSize.w, newSize.h));
|
||||
|
||||
if (cel_image_on_thumb.isEmpty()) {
|
||||
double zw = thumb_size.w / (double)image_size.w;
|
||||
double zh = thumb_size.h / (double)image_size.h;
|
||||
double zoom = MIN(1.0, MIN(zw, zh));
|
||||
render::Render render;
|
||||
render::Projection proj(cel->sprite()->pixelRatio(),
|
||||
render::Zoom(newSize.w, cel->image()->width()));
|
||||
render.setProjection(proj);
|
||||
|
||||
cel_image_on_thumb = gfx::Rect(
|
||||
(int)(thumb_size.w * 0.5 - image_size.w * zoom * 0.5),
|
||||
(int)(thumb_size.h * 0.5 - image_size.h * zoom * 0.5),
|
||||
MAX(1, (int)(image_size.w * zoom)),
|
||||
MAX(1, (int)(image_size.h * zoom)));
|
||||
const doc::Palette* palette = cel->sprite()->palette(cel->frame());
|
||||
render.renderCel(
|
||||
thumbnailImage.get(),
|
||||
cel->sprite(),
|
||||
cel->image(),
|
||||
cel->layer(),
|
||||
palette,
|
||||
gfx::Rect(gfx::Point(0, 0), cel->bounds().size()),
|
||||
gfx::Clip(gfx::Rect(gfx::Point(0, 0), newSize)),
|
||||
255, doc::BlendMode::NORMAL);
|
||||
|
||||
if (os::Surface* thumbnail = os::instance()->createRgbaSurface(
|
||||
thumbnailImage->width(),
|
||||
thumbnailImage->height())) {
|
||||
convert_image_to_surface(
|
||||
thumbnailImage.get(), palette, thumbnail,
|
||||
0, 0, 0, 0, thumbnailImage->width(), thumbnailImage->height());
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
const doc::Sprite* sprite = document->sprite();
|
||||
// TODO doc::Image::createCopy() from pre-rendered checkered background
|
||||
std::unique_ptr<doc::Image> thumb_img(doc::Image::create(
|
||||
image->pixelFormat(), thumb_size.w, thumb_size.h));
|
||||
|
||||
int block_size = MID(4, thumb_size.w/8, 16);
|
||||
for (int dst_y = 0; dst_y < thumb_size.h; dst_y++) {
|
||||
for (int dst_x = 0; dst_x < thumb_size.w; dst_x++) {
|
||||
thumb_img->putPixel(dst_x, dst_y,
|
||||
(((dst_x / block_size) % 2) ^
|
||||
((dst_y / block_size) % 2)) ? bg2: bg1);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<doc::Image> scale_img;
|
||||
const doc::Image* source = image;
|
||||
|
||||
if (cel_image_on_thumb.w != image_size.w || cel_image_on_thumb.h != image_size.h) {
|
||||
scale_img.reset(doc::Image::create(
|
||||
image->pixelFormat(), cel_image_on_thumb.w, cel_image_on_thumb.h));
|
||||
|
||||
doc::algorithm::resize_image(
|
||||
image, scale_img.get(),
|
||||
doc::algorithm::ResizeMethod::RESIZE_METHOD_NEAREST_NEIGHBOR,
|
||||
sprite->palette(frame),
|
||||
sprite->rgbMap(frame),
|
||||
sprite->transparentColor());
|
||||
|
||||
source = scale_img.get();
|
||||
}
|
||||
|
||||
render::composite_image(
|
||||
thumb_img.get(), source,
|
||||
sprite->palette(frame),
|
||||
cel_image_on_thumb.x,
|
||||
cel_image_on_thumb.y,
|
||||
255, BlendMode::NORMAL);
|
||||
|
||||
os::Surface* thumb_surf = os::instance()->createRgbaSurface(
|
||||
thumb_img->width(), thumb_img->height());
|
||||
|
||||
convert_image_to_surface(thumb_img.get(), sprite->palette(frame), thumb_surf,
|
||||
0, 0, 0, 0, thumb_img->width(), thumb_img->height());
|
||||
|
||||
return thumb_surf;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // thumb
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019 Igara Studio S.A.
|
||||
// Copyright (C) 2016 Carlo Caputo
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -8,7 +9,6 @@
|
||||
#define APP_THUMBNAILS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "gfx/rect.h"
|
||||
#include "gfx/size.h"
|
||||
|
||||
namespace doc {
|
||||
@ -20,13 +20,12 @@ namespace os {
|
||||
}
|
||||
|
||||
namespace app {
|
||||
namespace thumb {
|
||||
namespace thumb {
|
||||
|
||||
os::Surface* get_cel_thumbnail(const doc::Cel* cel,
|
||||
const gfx::Size& thumb_size,
|
||||
gfx::Rect cel_image_on_thumb = gfx::Rect());
|
||||
os::Surface* get_cel_thumbnail(const doc::Cel* cel,
|
||||
const gfx::Size& fitInSize);
|
||||
|
||||
} // thumb
|
||||
} // thumb
|
||||
} // app
|
||||
|
||||
#endif
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "app/util/layer_boundaries.h"
|
||||
#include "app/util/readable_time.h"
|
||||
#include "base/bind.h"
|
||||
#include "base/clamp.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/memory.h"
|
||||
#include "base/scoped_value.h"
|
||||
@ -2236,10 +2237,14 @@ void Timeline::drawCel(ui::Graphics* g, layer_t layerIndex, frame_t frame, Cel*
|
||||
skinTheme()->calcBorder(this, style));
|
||||
|
||||
if (!thumb_bounds.isEmpty()) {
|
||||
os::Surface* thumb_surf = thumb::get_cel_thumbnail(cel, thumb_bounds.size());
|
||||
if (thumb_surf) {
|
||||
g->drawRgbaSurface(thumb_surf, thumb_bounds.x, thumb_bounds.y);
|
||||
thumb_surf->dispose();
|
||||
if (os::Surface* surface = thumb::get_cel_thumbnail(cel, thumb_bounds.size())) {
|
||||
const int t = base::clamp(thumb_bounds.w/8, 4, 16);
|
||||
draw_checked_grid(g, thumb_bounds, gfx::Size(t, t), docPref());
|
||||
|
||||
g->drawRgbaSurface(surface,
|
||||
thumb_bounds.center().x-surface->width()/2,
|
||||
thumb_bounds.center().y-surface->height()/2);
|
||||
surface->dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2251,7 +2256,7 @@ void Timeline::drawCel(ui::Graphics* g, layer_t layerIndex, frame_t frame, Cel*
|
||||
|
||||
void Timeline::updateCelOverlayBounds(const Hit& hit)
|
||||
{
|
||||
gfx::Rect inner, outer;
|
||||
gfx::Rect rc;
|
||||
|
||||
if (docPref().thumbnails.overlayEnabled() && hit.part == PART_CEL) {
|
||||
m_thumbnailsOverlayHit = hit;
|
||||
@ -2271,88 +2276,66 @@ void Timeline::updateCelOverlayBounds(const Hit& hit)
|
||||
gfx::Point center = client_bounds.center();
|
||||
|
||||
gfx::Rect bounds_cel = getPartBounds(m_thumbnailsOverlayHit);
|
||||
inner = gfx::Rect(
|
||||
rc = gfx::Rect(
|
||||
bounds_cel.x + m_thumbnailsOverlayDirection.x,
|
||||
bounds_cel.y + m_thumbnailsOverlayDirection.y,
|
||||
width,
|
||||
height
|
||||
);
|
||||
height);
|
||||
|
||||
if (!client_bounds.contains(inner)) {
|
||||
if (!client_bounds.contains(rc)) {
|
||||
m_thumbnailsOverlayDirection = gfx::Point(
|
||||
bounds_cel.x < center.x ? (int)(frameBoxWidth()*1.0) : -width,
|
||||
bounds_cel.y < center.y ? (int)(frameBoxWidth()*0.5) : -height+(int)(frameBoxWidth()*0.5)
|
||||
);
|
||||
inner.setOrigin(gfx::Point(
|
||||
bounds_cel.y < center.y ? (int)(frameBoxWidth()*0.5) : -height+(int)(frameBoxWidth()*0.5));
|
||||
rc.setOrigin(gfx::Point(
|
||||
bounds_cel.x + m_thumbnailsOverlayDirection.x,
|
||||
bounds_cel.y + m_thumbnailsOverlayDirection.y
|
||||
));
|
||||
bounds_cel.y + m_thumbnailsOverlayDirection.y));
|
||||
}
|
||||
|
||||
outer = gfx::Rect(inner).enlarge(1);
|
||||
}
|
||||
else {
|
||||
outer = gfx::Rect(0, 0, 0, 0);
|
||||
rc = gfx::Rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (outer != m_thumbnailsOverlayOuter) {
|
||||
if (!m_thumbnailsOverlayOuter.isEmpty()) {
|
||||
invalidateRect(gfx::Rect(m_thumbnailsOverlayOuter).offset(origin()));
|
||||
}
|
||||
if (!outer.isEmpty()) {
|
||||
invalidateRect(gfx::Rect(outer).offset(origin()));
|
||||
}
|
||||
m_thumbnailsOverlayVisible = !outer.isEmpty();
|
||||
m_thumbnailsOverlayOuter = outer;
|
||||
m_thumbnailsOverlayInner = inner;
|
||||
}
|
||||
if (rc == m_thumbnailsOverlayBounds)
|
||||
return;
|
||||
|
||||
if (!m_thumbnailsOverlayBounds.isEmpty())
|
||||
invalidateRect(gfx::Rect(m_thumbnailsOverlayBounds).offset(origin()));
|
||||
if (!rc.isEmpty())
|
||||
invalidateRect(gfx::Rect(rc).offset(origin()));
|
||||
|
||||
m_thumbnailsOverlayVisible = !rc.isEmpty();
|
||||
m_thumbnailsOverlayBounds = rc;
|
||||
}
|
||||
|
||||
void Timeline::drawCelOverlay(ui::Graphics* g)
|
||||
{
|
||||
if (!m_thumbnailsOverlayVisible) {
|
||||
if (!m_thumbnailsOverlayVisible)
|
||||
return;
|
||||
}
|
||||
|
||||
Layer* layer = m_rows[m_thumbnailsOverlayHit.layer].layer();
|
||||
Cel* cel = layer->cel(m_thumbnailsOverlayHit.frame);
|
||||
if (!cel) {
|
||||
if (!cel)
|
||||
return;
|
||||
}
|
||||
Image* image = cel->image();
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
IntersectClip clip(g, m_thumbnailsOverlayOuter);
|
||||
Image* image = cel->image();
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
IntersectClip clip(g, m_thumbnailsOverlayBounds);
|
||||
if (!clip)
|
||||
return;
|
||||
|
||||
double scale = (
|
||||
m_sprite->width() > m_sprite->height() ?
|
||||
m_thumbnailsOverlayInner.w / (double)m_sprite->width() :
|
||||
m_thumbnailsOverlayInner.h / (double)m_sprite->height()
|
||||
);
|
||||
gfx::Rect rc = m_sprite->bounds().fitIn(
|
||||
gfx::Rect(m_thumbnailsOverlayBounds).shrink(1));
|
||||
if (os::Surface* surface = thumb::get_cel_thumbnail(cel, rc.size())) {
|
||||
draw_checked_grid(g, rc, gfx::Size(8, 8)*ui::guiscale(), docPref());
|
||||
|
||||
gfx::Size overlay_size(
|
||||
m_thumbnailsOverlayInner.w,
|
||||
m_thumbnailsOverlayInner.h
|
||||
);
|
||||
|
||||
gfx::Rect cel_image_on_overlay(
|
||||
(int)(cel->x() * scale),
|
||||
(int)(cel->y() * scale),
|
||||
(int)(image->width() * scale),
|
||||
(int)(image->height() * scale)
|
||||
);
|
||||
|
||||
os::Surface* overlay_surf = thumb::get_cel_thumbnail(cel, overlay_size, cel_image_on_overlay);
|
||||
|
||||
g->drawRgbaSurface(overlay_surf,
|
||||
m_thumbnailsOverlayInner.x, m_thumbnailsOverlayInner.y);
|
||||
g->drawRect(gfx::rgba(0,0,0,255), m_thumbnailsOverlayOuter);
|
||||
|
||||
overlay_surf->dispose();
|
||||
g->drawRgbaSurface(surface,
|
||||
rc.center().x-surface->width()/2,
|
||||
rc.center().y-surface->height()/2);
|
||||
g->drawRect(gfx::rgba(0, 0, 0, 128), m_thumbnailsOverlayBounds);
|
||||
surface->dispose();
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::drawCelLinkDecorators(ui::Graphics* g, const gfx::Rect& bounds,
|
||||
|
@ -407,8 +407,7 @@ namespace app {
|
||||
|
||||
// Data used for thumbnails.
|
||||
bool m_thumbnailsOverlayVisible;
|
||||
gfx::Rect m_thumbnailsOverlayInner;
|
||||
gfx::Rect m_thumbnailsOverlayOuter;
|
||||
gfx::Rect m_thumbnailsOverlayBounds;
|
||||
Hit m_thumbnailsOverlayHit;
|
||||
gfx::Point m_thumbnailsOverlayDirection;
|
||||
obs::connection m_thumbnailsPrefConn;
|
||||
|
@ -479,7 +479,7 @@ template<class DstTraits, class SrcTraits>
|
||||
CompositeImageFunc get_fastest_composition_path(const Projection& proj,
|
||||
const bool finegrain)
|
||||
{
|
||||
if (finegrain) {
|
||||
if (finegrain || !proj.zoom().isSimpleZoomLevel()) {
|
||||
return composite_image_general<DstTraits, SrcTraits>;
|
||||
}
|
||||
else if (proj.applyX(1) == 1 && proj.applyY(1) == 1) {
|
||||
@ -490,9 +490,7 @@ CompositeImageFunc get_fastest_composition_path(const Projection& proj,
|
||||
}
|
||||
// Slower composite function for special cases with odd zoom and non-square pixel ratio
|
||||
else if (((proj.removeX(1) > 1) && (proj.removeX(1) & 1)) ||
|
||||
((proj.removeY(1) > 1) && (proj.removeY(1) & 1)) ||
|
||||
(proj.applyX(1.0) - proj.applyX(1) > 0.01) ||
|
||||
(proj.applyY(1.0) - proj.applyY(1) > 0.01)) {
|
||||
((proj.removeY(1) > 1) && (proj.removeY(1) & 1))) {
|
||||
return composite_image_general<DstTraits, SrcTraits>;
|
||||
}
|
||||
else {
|
||||
@ -1175,6 +1173,37 @@ void Render::renderLayer(
|
||||
}
|
||||
}
|
||||
|
||||
void Render::renderCel(
|
||||
Image* dst_image,
|
||||
const Sprite* sprite,
|
||||
const Image* cel_image,
|
||||
const Layer* cel_layer,
|
||||
const Palette* pal,
|
||||
const gfx::RectF& celBounds,
|
||||
const gfx::Clip& area,
|
||||
const int opacity,
|
||||
const BlendMode blendMode)
|
||||
{
|
||||
m_sprite = sprite;
|
||||
|
||||
CompositeImageFunc compositeImage =
|
||||
getImageComposition(
|
||||
dst_image->pixelFormat(),
|
||||
sprite->pixelFormat(), nullptr);
|
||||
if (!compositeImage)
|
||||
return;
|
||||
|
||||
renderCel(
|
||||
dst_image,
|
||||
cel_image,
|
||||
pal,
|
||||
celBounds,
|
||||
area,
|
||||
compositeImage,
|
||||
opacity,
|
||||
blendMode);
|
||||
}
|
||||
|
||||
void Render::renderCel(
|
||||
Image* dst_image,
|
||||
const Image* cel_image,
|
||||
|
@ -131,6 +131,17 @@ namespace render {
|
||||
const int opacity,
|
||||
const BlendMode blendMode);
|
||||
|
||||
void renderCel(
|
||||
Image* dst_image,
|
||||
const Sprite* sprite,
|
||||
const Image* cel_image,
|
||||
const Layer* cel_layer,
|
||||
const Palette* pal,
|
||||
const gfx::RectF& celBounds,
|
||||
const gfx::Clip& area,
|
||||
const int opacity,
|
||||
const BlendMode blendMode);
|
||||
|
||||
private:
|
||||
void renderSpriteLayers(
|
||||
Image* dstImage,
|
||||
|
@ -1,4 +1,5 @@
|
||||
// Aseprite Render Library
|
||||
// Copyright (c) 2019 Igara Studio S.A.
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -49,6 +50,12 @@ namespace render {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
// Returns true if this zoom level can be handled by simpler
|
||||
// rendering techniques.
|
||||
bool isSimpleZoomLevel() const {
|
||||
return (m_num == 1 || m_den == 1);
|
||||
}
|
||||
|
||||
static Zoom fromScale(double scale);
|
||||
static Zoom fromLinearScale(int i);
|
||||
static int linearValues();
|
||||
|
Loading…
x
Reference in New Issue
Block a user