Add ui::Theme::drawSlices() member function

This commit is contained in:
David Capello 2017-02-09 16:51:52 -03:00
parent e6fd892a40
commit f7903a74de
11 changed files with 155 additions and 18 deletions

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -43,6 +43,16 @@ void SkinPart::setBitmap(std::size_t index, she::Surface* bitmap)
m_bitmaps[index] = bitmap;
}
void SkinPart::setSpriteBounds(const gfx::Rect& bounds)
{
m_spriteBounds = bounds;
}
void SkinPart::setSlicesBounds(const gfx::Rect& bounds)
{
m_slicesBounds = bounds;
}
gfx::Size SkinPart::size() const
{
if (!m_bitmaps.empty())

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2017 David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -9,6 +9,7 @@
#pragma once
#include "base/shared_ptr.h"
#include "gfx/rect.h"
#include "gfx/size.h"
#include <vector>
@ -28,10 +29,14 @@ namespace app {
~SkinPart();
std::size_t countBitmaps() const { return m_bitmaps.size(); }
const gfx::Rect& spriteBounds() const { return m_spriteBounds; }
const gfx::Rect& slicesBounds() const { return m_slicesBounds; }
void clear();
// It doesn't destroy the previous bitmap in the given "index".
void setBitmap(std::size_t index, she::Surface* bitmap);
void setSpriteBounds(const gfx::Rect& bounds);
void setSlicesBounds(const gfx::Rect& bounds);
she::Surface* bitmap(std::size_t index) const {
return (index < m_bitmaps.size() ? m_bitmaps[index]: NULL);
@ -50,6 +55,8 @@ namespace app {
private:
Bitmaps m_bitmaps;
gfx::Rect m_spriteBounds;
gfx::Rect m_slicesBounds;
};
typedef base::SharedPtr<SkinPart> SkinPartPtr;

View File

@ -393,6 +393,7 @@ void SkinTheme::loadXml(const std::string& skinId)
part = m_parts_by_id[part_id] = SkinPartPtr(new SkinPart);
if (w > 0 && h > 0) {
part->setSpriteBounds(gfx::Rect(x, y, w, h));
part->setBitmap(0,
sliceSheet(part->bitmap(0), gfx::Rect(x, y, w, h)));
}
@ -404,6 +405,9 @@ void SkinTheme::loadXml(const std::string& skinId)
int h2 = strtol(xmlPart->Attribute("h2"), NULL, 10);
int h3 = strtol(xmlPart->Attribute("h3"), NULL, 10);
part->setSpriteBounds(gfx::Rect(x, y, w1+w2+w3, h1+h2+h3));
part->setSlicesBounds(gfx::Rect(w1, h1, w2, h2));
part->setBitmap(0, sliceSheet(part->bitmap(0), gfx::Rect(x, y, w1, h1))); // NW
part->setBitmap(1, sliceSheet(part->bitmap(1), gfx::Rect(x+w1, y, w2, h1))); // N
part->setBitmap(2, sliceSheet(part->bitmap(2), gfx::Rect(x+w1+w2, y, w3, h1))); // NE
@ -1955,25 +1959,18 @@ void SkinTheme::drawRect(Graphics* g, const Rect& rc,
void SkinTheme::drawRect(ui::Graphics* g, const gfx::Rect& rc, SkinPart* skinPart, gfx::Color bg)
{
drawRect(g, rc,
skinPart->bitmap(0),
skinPart->bitmap(1),
skinPart->bitmap(2),
skinPart->bitmap(3),
skinPart->bitmap(4),
skinPart->bitmap(5),
skinPart->bitmap(6),
skinPart->bitmap(7));
const gfx::Rect& sprite = skinPart->spriteBounds();
const gfx::Rect& slices = skinPart->slicesBounds();
Theme::drawSlices(g, m_sheet, rc, sprite, slices, false);
// Center
if (!is_transparent(bg)) {
gfx::Rect inside = rc;
inside.shrink(Border(
skinPart->bitmap(7)->width(),
skinPart->bitmap(1)->height(),
skinPart->bitmap(3)->width(),
skinPart->bitmap(5)->height()));
inside.x += slices.x;
inside.y += slices.y;
inside.w -= sprite.w - slices.w;
inside.h -= sprite.h - slices.h;
IntersectClip clip(g, inside);
if (clip)
g->fillRect(bg, inside);

View File

@ -1,5 +1,5 @@
// SHE library
// Copyright (C) 2012-2016 David Capello
// Copyright (C) 2012-2017 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
@ -385,4 +385,15 @@ void Alleg4Surface::drawRgbaSurface(const Surface* src, int dstx, int dsty)
draw_trans_sprite(m_bmp, static_cast<const Alleg4Surface*>(src)->m_bmp, dstx, dsty);
}
void Alleg4Surface::drawRgbaSurface(const Surface* src, int srcx, int srcy, int dstx, int dsty, int w, int h)
{
set_alpha_blender();
BITMAP* tmp = create_sub_bitmap(
static_cast<const Alleg4Surface*>(src)->m_bmp,
srcx, srcy, w, h);
draw_trans_sprite(m_bmp, tmp, dstx, dsty);
destroy_bitmap(tmp);
}
} // namespace she

View File

@ -56,6 +56,7 @@ namespace she {
void scrollTo(const gfx::Rect& rc, int dx, int dy) override;
void drawSurface(const Surface* src, int dstx, int dsty) override;
void drawRgbaSurface(const Surface* src, int dstx, int dsty) override;
void drawRgbaSurface(const Surface* src, int srcx, int srcy, int dstx, int dsty, int w, int h) override;
private:
BITMAP* m_bmp;

View File

@ -409,6 +409,22 @@ public:
SkCanvas::kStrict_SrcRectConstraint);
}
void drawRgbaSurface(const Surface* src, int srcx, int srcy, int dstx, int dsty, int w, int h) override {
gfx::Clip clip(dstx, dsty, srcx, srcy, w, h);
if (!clip.clip(width(), height(), src->width(), src->height()))
return;
SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(clip.src.x, clip.src.y, clip.size.w, clip.size.h));
SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(clip.dst.x, clip.dst.y, clip.size.w, clip.size.h));
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrcOver);
m_canvas->drawBitmapRect(
((SkiaSurface*)src)->m_bitmap, srcRect, dstRect, &paint,
SkCanvas::kStrict_SrcRectConstraint);
}
void drawColoredRgbaSurface(const Surface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clipbase) override {
gfx::Clip clip(clipbase);
if (!clip.clip(width(), height(), src->width(), src->height()))

View File

@ -62,6 +62,7 @@ namespace she {
virtual void scrollTo(const gfx::Rect& rc, int dx, int dy) = 0;
virtual void drawSurface(const Surface* src, int dstx, int dsty) = 0;
virtual void drawRgbaSurface(const Surface* src, int dstx, int dsty) = 0;
virtual void drawRgbaSurface(const Surface* src, int srcx, int srcy, int dstx, int dsty, int width, int height) = 0;
virtual void drawColoredRgbaSurface(const Surface* src, gfx::Color fg, gfx::Color bg, const gfx::Clip& clip) = 0;
virtual void applyScale(int scaleFactor) = 0;

View File

@ -177,6 +177,15 @@ void Graphics::drawRgbaSurface(she::Surface* surface, int x, int y)
m_surface->drawRgbaSurface(surface, m_dx+x, m_dy+y);
}
void Graphics::drawRgbaSurface(she::Surface* surface, int srcx, int srcy, int dstx, int dsty, int w, int h)
{
dirty(gfx::Rect(m_dx+dstx, m_dy+dsty, w, h));
she::SurfaceLock lockSrc(surface);
she::SurfaceLock lockDst(m_surface);
m_surface->drawRgbaSurface(surface, srcx, srcy, m_dx+dstx, m_dy+dsty, w, h);
}
void Graphics::drawColoredRgbaSurface(she::Surface* surface, gfx::Color color, int x, int y)
{
dirty(gfx::Rect(m_dx+x, m_dy+y, surface->width(), surface->height()));

View File

@ -70,6 +70,7 @@ namespace ui {
void drawSurface(she::Surface* surface, int x, int y);
void drawRgbaSurface(she::Surface* surface, int x, int y);
void drawRgbaSurface(she::Surface* surface, int srcx, int srcy, int dstx, int dsty, int w, int h);
void drawColoredRgbaSurface(she::Surface* surface, gfx::Color color, int x, int y);
void blit(she::Surface* src, int srcx, int srcy, int dstx, int dsty, int w, int h);

View File

@ -11,6 +11,7 @@
#include "gfx/point.h"
#include "gfx/size.h"
#include "she/font.h"
#include "she/surface.h"
#include "she/system.h"
#include "ui/intern.h"
#include "ui/manager.h"
@ -79,6 +80,81 @@ Theme* get_theme()
return current_theme;
}
// static
void Theme::drawSlices(Graphics* g, she::Surface* sheet,
const gfx::Rect& rc,
const gfx::Rect& sprite,
const gfx::Rect& slices,
const bool drawCenter)
{
const int w1 = slices.x;
const int h1 = slices.y;
const int w2 = slices.w;
const int h2 = slices.h;
const int w3 = sprite.w-w1-w2;
const int h3 = sprite.h-h1-h2;
const int x2 = rc.x2()-w3;
const int y2 = rc.y2()-h3;
// Top
int x = rc.x;
int y = rc.y;
g->drawRgbaSurface(sheet, sprite.x, sprite.y,
x, y, w1, h1);
{
IntersectClip clip(g, gfx::Rect(rc.x+w1, rc.y, rc.w-w1-w3, h1));
if (clip) {
for (x+=w1; x<x2; x+=w2) {
g->drawRgbaSurface(sheet, sprite.x+w1, sprite.y,
x, y, w2, h1);
}
}
}
g->drawRgbaSurface(sheet, sprite.x+w1+w2, sprite.y,
x2, y, w3, h1);
// Bottom
x = rc.x;
y = y2;
g->drawRgbaSurface(sheet, sprite.x, sprite.y+h1+h2,
x, y, w1, h3);
{
IntersectClip clip(g, gfx::Rect(rc.x+w1, y2, rc.w-w1-w3, h3));
if (clip) {
for (x+=w1; x<x2; x+=w2) {
g->drawRgbaSurface(sheet, sprite.x+w1, sprite.y+h1+h2,
x, y2, w2, h3);
}
}
}
g->drawRgbaSurface(sheet, sprite.x+w1+w2, sprite.y+h1+h2,
x2, y2, w3, h3);
// Left & Right
IntersectClip clip(g, gfx::Rect(rc.x, rc.y+h1, rc.w, rc.h-h1-h3));
if (clip) {
for (y=rc.y+h1; y<y2; y+=h2) {
// Left
g->drawRgbaSurface(sheet, sprite.x, sprite.y+h1,
rc.x, y, w1, h2);
// Right
g->drawRgbaSurface(sheet, sprite.x+w1+w2, sprite.y+h1,
x2, y, w3, h2);
}
}
// Center
if (drawCenter) {
IntersectClip clip(g, gfx::Rect(rc.x+w1, rc.y+h1, rc.w-w1-w3, rc.h-h1-h3));
if (clip) {
for (y=rc.y+h1; y<y2; y+=h2) {
for (x=rc.x+w1; x<x2; x+=w2)
g->drawRgbaSurface(sheet, sprite.x+w1, sprite.y+h1, x, y, w2, h2);
}
}
}
}
// static
void Theme::drawTextBox(Graphics* g, Widget* widget,
int* w, int* h, gfx::Color bg, gfx::Color fg)

View File

@ -19,6 +19,7 @@ namespace gfx {
namespace she {
class Font;
class Surface;
}
namespace ui {
@ -74,6 +75,13 @@ namespace ui {
virtual void paintPopupWindow(PaintEvent& ev) = 0;
virtual void paintTooltip(PaintEvent& ev) = 0;
static void drawSlices(Graphics* g,
she::Surface* sheet,
const gfx::Rect& rc,
const gfx::Rect& sprite,
const gfx::Rect& slices,
const bool drawCenter = true);
static void drawTextBox(Graphics* g, Widget* textbox,
int* w, int* h, gfx::Color bg, gfx::Color fg);