mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-29 21:33:12 +00:00
Recreate SkiaSurface when the window is resized
This commit is contained in:
parent
d36883e61e
commit
4bb7c87af5
@ -86,6 +86,8 @@ if(USE_SKIA_BACKEND)
|
||||
CACHE INTERNAL "Skia libraries")
|
||||
|
||||
list(APPEND SHE_SOURCES
|
||||
skia/skia_display.cpp
|
||||
skia/skia_window.cpp
|
||||
skia/she.cpp)
|
||||
|
||||
if(WIN32)
|
||||
|
@ -10,6 +10,9 @@
|
||||
|
||||
#include "base/string.h"
|
||||
#include "she/font.h"
|
||||
#include "she/locked_surface.h"
|
||||
#include "she/scoped_surface_lock.h"
|
||||
#include "she/surface.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
|
@ -14,18 +14,6 @@
|
||||
|
||||
#include "she/common/system.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#include "she/win/window.h"
|
||||
#else
|
||||
#error There is no Window implementation
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_surface.h"
|
||||
#include "she/skia/skia_event_queue.h"
|
||||
#include "she/skia/skia_window.h"
|
||||
#include "she/skia/skia_display.h"
|
||||
#include "she/skia/skia_system.h"
|
||||
|
||||
namespace she {
|
||||
|
131
src/she/skia/skia_display.cpp
Normal file
131
src/she/skia/skia_display.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
// SHE library
|
||||
// Copyright (C) 2012-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_display.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
SkiaDisplay::SkiaDisplay(int width, int height, int scale)
|
||||
: m_window(&m_queue, this)
|
||||
, m_surface(new SkiaSurface)
|
||||
{
|
||||
m_surface->create(width, height);
|
||||
m_window.setScale(scale);
|
||||
m_window.setVisible(true);
|
||||
m_recreated = false;
|
||||
}
|
||||
|
||||
void SkiaDisplay::resize(const gfx::Size& size)
|
||||
{
|
||||
m_surface->dispose();
|
||||
m_surface = new SkiaSurface;
|
||||
m_surface->create(size.w, size.h);
|
||||
m_recreated = true;
|
||||
}
|
||||
|
||||
void SkiaDisplay::dispose()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
int SkiaDisplay::width() const
|
||||
{
|
||||
return m_window.clientSize().w;
|
||||
}
|
||||
|
||||
int SkiaDisplay::height() const
|
||||
{
|
||||
return m_window.clientSize().h;
|
||||
}
|
||||
|
||||
int SkiaDisplay::originalWidth() const
|
||||
{
|
||||
return m_window.restoredSize().w;
|
||||
}
|
||||
|
||||
int SkiaDisplay::originalHeight() const
|
||||
{
|
||||
return m_window.restoredSize().h;
|
||||
}
|
||||
|
||||
void SkiaDisplay::setScale(int scale)
|
||||
{
|
||||
m_window.setScale(scale);
|
||||
}
|
||||
|
||||
int SkiaDisplay::scale() const
|
||||
{
|
||||
return m_window.scale();
|
||||
}
|
||||
|
||||
NonDisposableSurface* SkiaDisplay::getSurface()
|
||||
{
|
||||
return static_cast<NonDisposableSurface*>(m_surface);
|
||||
}
|
||||
|
||||
// Flips all graphics in the surface to the real display. Returns
|
||||
// false if the flip couldn't be done because the display was
|
||||
// resized.
|
||||
bool SkiaDisplay::flip()
|
||||
{
|
||||
if (m_recreated) {
|
||||
m_recreated = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_window.invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkiaDisplay::maximize()
|
||||
{
|
||||
m_window.maximize();
|
||||
}
|
||||
|
||||
bool SkiaDisplay::isMaximized() const
|
||||
{
|
||||
return m_window.isMaximized();
|
||||
}
|
||||
|
||||
void SkiaDisplay::setTitleBar(const std::string& title)
|
||||
{
|
||||
m_window.setText(title);
|
||||
}
|
||||
|
||||
EventQueue* SkiaDisplay::getEventQueue()
|
||||
{
|
||||
return &m_queue;
|
||||
}
|
||||
|
||||
bool SkiaDisplay::setNativeMouseCursor(NativeCursor cursor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkiaDisplay::setMousePosition(const gfx::Point& position)
|
||||
{
|
||||
}
|
||||
|
||||
void SkiaDisplay::captureMouse()
|
||||
{
|
||||
m_window.captureMouse();
|
||||
}
|
||||
|
||||
void SkiaDisplay::releaseMouse()
|
||||
{
|
||||
m_window.releaseMouse();
|
||||
}
|
||||
|
||||
DisplayHandle SkiaDisplay::nativeHandle()
|
||||
{
|
||||
return (DisplayHandle)m_window.handle();
|
||||
}
|
||||
|
||||
} // namespace she
|
@ -4,101 +4,63 @@
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef SHE_SKIA_SKIA_DISPLAY_INCLUDED
|
||||
#define SHE_SKIA_SKIA_DISPLAY_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "she/display.h"
|
||||
#include "she/skia/skia_event_queue.h"
|
||||
#include "she/skia/skia_window.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaSurface;
|
||||
|
||||
class SkiaDisplay : public Display {
|
||||
public:
|
||||
SkiaDisplay(int width, int height, int scale)
|
||||
: m_window(&m_queue, this) {
|
||||
m_surface.create(width, height);
|
||||
m_window.setScale(scale);
|
||||
m_window.setVisible(true);
|
||||
}
|
||||
SkiaDisplay(int width, int height, int scale);
|
||||
|
||||
void dispose() override {
|
||||
delete this;
|
||||
}
|
||||
void resize(const gfx::Size& size);
|
||||
void dispose() override;
|
||||
|
||||
// Returns the real and current display's size (without scale applied).
|
||||
int width() const override {
|
||||
return m_window.clientSize().w;
|
||||
}
|
||||
|
||||
int height() const override {
|
||||
return m_window.clientSize().h;
|
||||
}
|
||||
int width() const override;
|
||||
int height() const override;
|
||||
|
||||
// Returns the display when it was not maximized.
|
||||
int originalWidth() const override {
|
||||
return m_window.restoredSize().w;
|
||||
}
|
||||
int originalWidth() const override;
|
||||
int originalHeight() const override;
|
||||
|
||||
int originalHeight() const override {
|
||||
return m_window.restoredSize().h;
|
||||
}
|
||||
|
||||
void setScale(int scale) override {
|
||||
m_window.setScale(scale);
|
||||
}
|
||||
|
||||
int scale() const override {
|
||||
return m_window.scale();
|
||||
}
|
||||
void setScale(int scale) override;
|
||||
int scale() const override;
|
||||
|
||||
// Returns the main surface to draw into this display.
|
||||
// You must not dispose this surface.
|
||||
NonDisposableSurface* getSurface() override {
|
||||
return static_cast<NonDisposableSurface*>(&m_surface);
|
||||
}
|
||||
NonDisposableSurface* getSurface() override;
|
||||
|
||||
// Flips all graphics in the surface to the real display. Returns
|
||||
// false if the flip couldn't be done because the display was
|
||||
// resized.
|
||||
bool flip() override {
|
||||
m_window.invalidate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void maximize() override {
|
||||
m_window.maximize();
|
||||
}
|
||||
|
||||
bool isMaximized() const override {
|
||||
return m_window.isMaximized();
|
||||
}
|
||||
|
||||
void setTitleBar(const std::string& title) override {
|
||||
m_window.setText(title);
|
||||
}
|
||||
|
||||
EventQueue* getEventQueue() override {
|
||||
return &m_queue;
|
||||
}
|
||||
|
||||
bool setNativeMouseCursor(NativeCursor cursor) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void setMousePosition(const gfx::Point& position) override {
|
||||
}
|
||||
|
||||
void captureMouse() override {
|
||||
m_window.captureMouse();
|
||||
}
|
||||
|
||||
void releaseMouse() override {
|
||||
m_window.releaseMouse();
|
||||
}
|
||||
bool flip() override;
|
||||
void maximize() override;
|
||||
bool isMaximized() const override;
|
||||
void setTitleBar(const std::string& title) override;
|
||||
EventQueue* getEventQueue() override;
|
||||
bool setNativeMouseCursor(NativeCursor cursor) override;
|
||||
void setMousePosition(const gfx::Point& position) override;
|
||||
void captureMouse() override;
|
||||
void releaseMouse() override;
|
||||
|
||||
// Returns the HWND on Windows.
|
||||
DisplayHandle nativeHandle() override {
|
||||
return (DisplayHandle)m_window.handle();
|
||||
}
|
||||
DisplayHandle nativeHandle() override;
|
||||
|
||||
private:
|
||||
SkiaEventQueue m_queue;
|
||||
SkiaWindow m_window;
|
||||
SkiaSurface m_surface;
|
||||
SkiaSurface* m_surface;
|
||||
bool m_recreated;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
||||
#endif
|
||||
|
@ -4,8 +4,17 @@
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef SHE_SKIA_SKIA_EVENT_QUEUE_INCLUDED
|
||||
#define SHE_SKIA_SKIA_EVENT_QUEUE_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "she/event.h"
|
||||
#include "she/event_queue.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaEventQueue : public EventQueue {
|
||||
@ -56,3 +65,5 @@ private:
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
||||
#endif
|
||||
|
@ -4,12 +4,19 @@
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef SHE_SKIA_SKIA_SYSTEM_INCLUDED
|
||||
#define SHE_SKIA_SKIA_SYSTEM_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/file_handle.h"
|
||||
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkStream.h"
|
||||
|
||||
#include "she/skia/skia_display.h"
|
||||
#include "she/skia/skia_surface.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaSystem : public CommonSystem {
|
||||
@ -88,3 +95,5 @@ private:
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
||||
#endif
|
||||
|
62
src/she/skia/skia_window.cpp
Normal file
62
src/she/skia/skia_window.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
// SHE library
|
||||
// Copyright (C) 2012-2015 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_window.h"
|
||||
|
||||
#include "she/skia/skia_display.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
SkiaWindow::SkiaWindow(SkiaEventQueue* queue, SkiaDisplay* display)
|
||||
: m_queue(queue)
|
||||
, m_display(display)
|
||||
{
|
||||
}
|
||||
|
||||
void SkiaWindow::queueEventImpl(Event& ev)
|
||||
{
|
||||
ev.setDisplay(m_display);
|
||||
m_queue->queueEvent(ev);
|
||||
}
|
||||
|
||||
void SkiaWindow::paintImpl(HDC hdc)
|
||||
{
|
||||
SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
|
||||
const SkBitmap& bitmap = surface->bitmap();
|
||||
|
||||
BITMAPINFO bmi;
|
||||
memset(&bmi, 0, sizeof(bmi));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = bitmap.width();
|
||||
bmi.bmiHeader.biHeight = -bitmap.height();
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = 0;
|
||||
|
||||
ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
|
||||
bitmap.lockPixels();
|
||||
|
||||
int ret = StretchDIBits(hdc,
|
||||
0, 0, bitmap.width()*scale(), bitmap.height()*scale(),
|
||||
0, 0, bitmap.width(), bitmap.height(),
|
||||
bitmap.getPixels(),
|
||||
&bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
(void)ret;
|
||||
|
||||
bitmap.unlockPixels();
|
||||
}
|
||||
|
||||
void SkiaWindow::resizeImpl(const gfx::Size& size)
|
||||
{
|
||||
m_display->resize(size);
|
||||
}
|
||||
|
||||
} // namespace she
|
@ -4,50 +4,35 @@
|
||||
// This file is released under the terms of the MIT license.
|
||||
// Read LICENSE.txt for more information.
|
||||
|
||||
#ifndef SHE_SKIA_SKIA_WINDOW_INCLUDED
|
||||
#define SHE_SKIA_SKIA_WINDOW_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "she/win/window.h"
|
||||
#else
|
||||
#error There is no Window implementation
|
||||
#endif
|
||||
|
||||
#include "she/skia/skia_event_queue.h"
|
||||
#include "she/skia/skia_surface.h"
|
||||
|
||||
namespace she {
|
||||
|
||||
class SkiaDisplay;
|
||||
|
||||
class SkiaWindow : public Window<SkiaWindow> {
|
||||
public:
|
||||
SkiaWindow(SkiaEventQueue* queue, Display* display)
|
||||
: m_queue(queue)
|
||||
, m_display(display) {
|
||||
}
|
||||
|
||||
void queueEventImpl(Event& ev) {
|
||||
ev.setDisplay(m_display);
|
||||
m_queue->queueEvent(ev);
|
||||
}
|
||||
|
||||
void paintImpl(HDC hdc) {
|
||||
SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
|
||||
const SkBitmap& bitmap = surface->bitmap();
|
||||
|
||||
BITMAPINFO bmi;
|
||||
memset(&bmi, 0, sizeof(bmi));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = bitmap.width();
|
||||
bmi.bmiHeader.biHeight = -bitmap.height();
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = 0;
|
||||
|
||||
ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
|
||||
bitmap.lockPixels();
|
||||
|
||||
int ret = StretchDIBits(hdc,
|
||||
0, 0, bitmap.width()*scale(), bitmap.height()*scale(),
|
||||
0, 0, bitmap.width(), bitmap.height(),
|
||||
bitmap.getPixels(),
|
||||
&bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
(void)ret;
|
||||
|
||||
bitmap.unlockPixels();
|
||||
}
|
||||
SkiaWindow(SkiaEventQueue* queue, SkiaDisplay* display);
|
||||
void queueEventImpl(Event& ev);
|
||||
void paintImpl(HDC hdc);
|
||||
void resizeImpl(const gfx::Size& size);
|
||||
|
||||
private:
|
||||
SkiaEventQueue* m_queue;
|
||||
Display* m_display;
|
||||
SkiaDisplay* m_display;
|
||||
};
|
||||
|
||||
} // namespace she
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <windowsx.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "gfx/size.h"
|
||||
#include "she/event.h"
|
||||
#include "she/keys.h"
|
||||
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
@ -118,6 +120,8 @@ namespace she {
|
||||
case SIZE_RESTORED:
|
||||
m_clientSize.w = GET_X_LPARAM(lparam);
|
||||
m_clientSize.h = GET_Y_LPARAM(lparam);
|
||||
|
||||
static_cast<T*>(this)->resizeImpl(m_clientSize);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user