Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
askmeaboutlo0m committed Aug 16, 2023
1 parent 84507f9 commit 3bb3881
Show file tree
Hide file tree
Showing 34 changed files with 1,221 additions and 483 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ endif()
# source directory to not go insane figuring out what is included from where
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)

# Error messages shouldn't include home directories and such, so we use the
# project directory length to chop it off the beginning of __FILE__.
string(LENGTH "${PROJECT_SOURCE_DIR}/" project_dir_length)
add_compile_definitions("DP_PROJECT_DIR_LENGTH=${project_dir_length}")

add_subdirectory(src/cmake-config)

if(CLIENT OR SERVER)
Expand Down
5 changes: 4 additions & 1 deletion src/desktop/dialogs/playbackdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,10 @@ void PlaybackDialog::exportFrame(int count)
Q_ASSERT(m_exporter);
count = qMax(1, count);

const QImage image = m_paintengine->getPixmap().toImage();
QImage image;
m_paintengine->withPixmap([&image](const QPixmap &pixmap) {
image = pixmap.toImage();
});
if(image.isNull()) {
qWarning("exportFrame: image is null!");
onExporterReady();
Expand Down
85 changes: 66 additions & 19 deletions src/desktop/docks/navigator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ NavigatorView::NavigatorView(QWidget *parent)
void NavigatorView::setCanvasModel(canvas::CanvasModel *model)
{
m_model = model;
connect(m_model->paintEngine(), &canvas::PaintEngine::areaChanged, this, &NavigatorView::onChange);
connect(m_model->paintEngine(), &canvas::PaintEngine::resized, this, &NavigatorView::onResize);
connect(m_model->paintEngine(), &canvas::PaintEngine::areaChanged, this, &NavigatorView::onChange, Qt::QueuedConnection);
connect(m_model->paintEngine(), &canvas::PaintEngine::resized, this, &NavigatorView::onResize, Qt::QueuedConnection);
connect(m_model->paintEngine(), &canvas::PaintEngine::cursorMoved, this, &NavigatorView::onCursorMove);

m_model->paintEngine()->setRenderOutsideView(isVisible());
m_refreshAll = true;
refreshCache();
}

Expand Down Expand Up @@ -132,6 +133,26 @@ void NavigatorView::wheelEvent(QWheelEvent *event)
}
}

void NavigatorView::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);
if(m_model) {
m_model->paintEngine()->setRenderOutsideView(true);
m_refreshTimer->stop();
m_refreshAll = true;
refreshCache();
}
}

void NavigatorView::hideEvent(QHideEvent *event)
{
QWidget::hideEvent(event);
m_refreshTimer->stop();
if(m_model) {
m_model->paintEngine()->setRenderOutsideView(false);
}
}

/**
* The focus rectangle represents the visible area in the
* main viewport.
Expand All @@ -143,10 +164,16 @@ void NavigatorView::setViewFocus(const QPolygonF& rect)
}


void NavigatorView::onChange()
void NavigatorView::onChange(const QRect &rect)
{
if(isVisible() && !m_refreshTimer->isActive())
m_refreshTimer->start();
if(isVisible()) {
if(rect.isValid()) {
m_refreshArea |= rect;
}
if(!m_refreshTimer->isActive()) {
m_refreshTimer->start();
}
}
}

void NavigatorView::onResize()
Expand All @@ -157,22 +184,42 @@ void NavigatorView::onResize()

void NavigatorView::refreshCache()
{
if(!m_model)
return;

const QPixmap &canvas = m_model->paintEngine()->getPixmap();
if(canvas.isNull())
if(!m_model) {
return;

const QSize size = this->size();
if(size != m_cachedSize) {
m_cachedSize = size;
const QSize pixmapSize = canvas.size().scaled(size, Qt::KeepAspectRatio);
m_cache = QPixmap(pixmapSize);
}

QPainter painter(&m_cache);
painter.drawPixmap(m_cache.rect(), canvas);
m_model->paintEngine()->withPixmap([this](const QPixmap &pixmap) {
if(!pixmap.isNull()) {
QSize navigatorSize = size();
if(navigatorSize != m_cachedSize) {
m_cachedSize = navigatorSize;
m_cache = QPixmap{
pixmap.size().scaled(navigatorSize, Qt::KeepAspectRatio)};
m_refreshAll = true;
}

if(m_refreshAll) {
QPainter painter(&m_cache);
painter.drawPixmap(m_cache.rect(), pixmap);
m_refreshAll = false;
m_refreshArea = QRect{};
} else if(m_refreshArea.isValid()) {
QSizeF ratioSize{m_cache.size()};
qreal xratio = ratioSize.width() / qreal(pixmap.width());
qreal yratio = ratioSize.height() / qreal(pixmap.height());
QRectF targetArea{
QPointF{
m_refreshArea.left() * xratio,
m_refreshArea.top() * yratio},
QPointF{
m_refreshArea.right() * xratio,
m_refreshArea.bottom() * yratio}};
QPainter painter(&m_cache);
painter.drawPixmap(QRectF{targetArea}, pixmap, m_refreshArea);
m_refreshArea = QRect{};
}
}
});

update();
}
Expand Down
6 changes: 5 additions & 1 deletion src/desktop/docks/navigator.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ public slots:
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;

private slots:
void onChange();
void onChange(const QRect &rect = QRect{});
void onResize();
void refreshCache();
void onCursorMove(unsigned int flags, uint8_t user, uint16_t layer, int x, int y);
Expand All @@ -65,6 +67,8 @@ private slots:
QSize m_cachedSize;

QTimer *m_refreshTimer;
QRect m_refreshArea;
bool m_refreshAll = false;

QPolygonF m_focusRect;
int m_zoomWheelDelta;
Expand Down
4 changes: 3 additions & 1 deletion src/desktop/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2509,7 +2509,9 @@ void MainWindow::resizeCanvas()

const QSize size = m_doc->canvas()->size();
dialogs::ResizeDialog *dlg = new dialogs::ResizeDialog(size, this);
dlg->setPreviewImage(m_doc->canvas()->paintEngine()->getPixmap().scaled(300, 300, Qt::KeepAspectRatio).toImage());
m_doc->canvas()->paintEngine()->withPixmap([dlg](const QPixmap &pixmap) {
dlg->setPreviewImage(pixmap.scaled(300, 300, Qt::KeepAspectRatio).toImage());
});
dlg->setAttribute(Qt::WA_DeleteOnClose);

// Preset crop from selection if one exists
Expand Down
12 changes: 9 additions & 3 deletions src/desktop/scene/canvasitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ void CanvasItem::setPaintEngine(canvas::PaintEngine *pe)
{
m_image = pe;
if(m_image) {
connect(m_image, &canvas::PaintEngine::areaChanged, this, &CanvasItem::refreshImage);
connect(m_image, &canvas::PaintEngine::resized, this, &CanvasItem::canvasResize);
connect(m_image, &canvas::PaintEngine::areaChanged, this, &CanvasItem::refreshImage, Qt::QueuedConnection);
connect(m_image, &canvas::PaintEngine::resized, this, &CanvasItem::canvasResize, Qt::QueuedConnection);
m_image->setCanvasViewArea(m_visibleArea);
}
canvasResize();
}
Expand Down Expand Up @@ -74,7 +75,9 @@ void CanvasItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
{
if(m_image) {
QRect exposed = option->exposedRect.toAlignedRect();
painter->drawPixmap(exposed, m_image->getPixmapView(m_visibleArea), exposed);
m_image->withPixmap([&](const QPixmap &pixmap) {
painter->drawPixmap(exposed, pixmap, exposed);
});
if(m_pixelGrid) {
QPen pen(QColor(160, 160, 160));
pen.setCosmetic(true);
Expand All @@ -92,6 +95,9 @@ void CanvasItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option
void CanvasItem::updateVisibleArea()
{
m_visibleArea = m_viewportBounds.intersected(m_boundingRect).toAlignedRect();
if(m_image) {
m_image->setCanvasViewArea(m_visibleArea);
}
}

}
Expand Down
2 changes: 1 addition & 1 deletion src/desktop/scene/canvasscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void CanvasScene::initCanvas(canvas::CanvasModel *model)

connect(
m_model->paintEngine(), &canvas::PaintEngine::resized, this,
&CanvasScene::handleCanvasResize);
&CanvasScene::handleCanvasResize, Qt::QueuedConnection);
connect(
m_model->paintEngine(), &canvas::PaintEngine::annotationsChanged, this,
&CanvasScene::annotationsChanged);
Expand Down
2 changes: 0 additions & 2 deletions src/drawdance/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# SPDX-License-Identifier: MIT

string(LENGTH "${PROJECT_SOURCE_DIR}/" project_dir_length)
add_compile_definitions(
"DP_PROJECT_DIR_LENGTH=${project_dir_length}"
WIN32_LEAN_AND_MEAN
NOMINMAX
)
Expand Down
2 changes: 2 additions & 0 deletions src/drawdance/libcommon/dpcommon/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,11 @@ DP_INLINE size_t DP_flex_size(size_t type_size, size_t flex_offset,
* member. Takes potential trailing padding being used as part of the flexible
* array member into account.
*/
// NOLINTBEGIN(bugprone-sizeof-expression)
#define DP_FLEX_SIZEOF(TYPE, FIELD, COUNT) \
DP_flex_size(sizeof(TYPE), offsetof(TYPE, FIELD), \
sizeof(((TYPE *)NULL)->FIELD[0]), COUNT)
// NOLINTEND(bugprone-sizeof-expression)


void *DP_malloc(size_t size) DP_MALLOC_ATTR;
Expand Down
18 changes: 18 additions & 0 deletions src/drawdance/libcommon/dpcommon/queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,21 @@ bool DP_queue_all(DP_Queue *queue, size_t element_size,
}
return true;
}

size_t DP_queue_search_index(DP_Queue *queue, size_t element_size,
bool (*predicate)(void *element, void *user),
void *user)
{
DP_ASSERT(queue);
DP_ASSERT(predicate);
size_t capacity = queue->capacity;
size_t used = queue->used;
size_t head = queue->head;
for (size_t i = 0; i < used; ++i) {
void *element = element_at(queue, (head + i) % capacity, element_size);
if (predicate(element, user)) {
return i;
}
}
return used;
}
4 changes: 4 additions & 0 deletions src/drawdance/libcommon/dpcommon/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,9 @@ void DP_queue_each(DP_Queue *queue, size_t element_size,
bool DP_queue_all(DP_Queue *queue, size_t element_size,
bool (*predicate)(void *element, void *user), void *user);

size_t DP_queue_search_index(DP_Queue *queue, size_t element_size,
bool (*predicate)(void *element, void *user),
void *user);


#endif
2 changes: 2 additions & 0 deletions src/drawdance/libengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dp_target_sources(dpengine
dpengine/pixels.c
dpengine/player.c
dpengine/recorder.c
dpengine/renderer.c
dpengine/snapshots.c
dpengine/text.c
dpengine/tile.c
Expand Down Expand Up @@ -72,6 +73,7 @@ dp_target_sources(dpengine
dpengine/pixels.h
dpengine/player.h
dpengine/recorder.h
dpengine/renderer.h
dpengine/snapshots.h
dpengine/text.h
dpengine/tile.h
Expand Down
40 changes: 35 additions & 5 deletions src/drawdance/libengine/dpengine/canvas_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ void DP_canvas_diff_free(DP_CanvasDiff *diff)
}
}

int DP_canvas_diff_xtiles(DP_CanvasDiff *diff)
{
DP_ASSERT(diff);
return diff->xtiles;
}

int DP_canvas_diff_ytiles(DP_CanvasDiff *diff)
{
DP_ASSERT(diff);
return diff->ytiles;
}


void DP_canvas_diff_begin(DP_CanvasDiff *diff, int old_width, int old_height,
int current_width, int current_height,
Expand Down Expand Up @@ -170,6 +182,25 @@ void DP_canvas_diff_each_pos_reset(DP_CanvasDiff *diff,
}
}

void DP_canvas_diff_bounds_clamp(DP_CanvasDiff *diff, int tile_left,
int tile_top, int tile_right, int tile_bottom,
int *out_left, int *out_top, int *out_right,
int *out_bottom, int *out_xtiles)
{
DP_ASSERT(diff);
DP_ASSERT(out_left);
DP_ASSERT(out_top);
DP_ASSERT(out_right);
DP_ASSERT(out_bottom);
DP_ASSERT(out_xtiles);
int xtiles = diff->xtiles;
*out_left = DP_max_int(0, tile_left);
*out_top = DP_max_int(0, tile_top);
*out_right = DP_min_int(xtiles - 1, tile_right);
*out_bottom = DP_min_int(diff->ytiles - 1, tile_bottom);
*out_xtiles = xtiles;
}

void DP_canvas_diff_each_pos_tile_bounds_reset(DP_CanvasDiff *diff,
int tile_left, int tile_top,
int tile_right, int tile_bottom,
Expand All @@ -178,11 +209,10 @@ void DP_canvas_diff_each_pos_tile_bounds_reset(DP_CanvasDiff *diff,
{
DP_ASSERT(diff);
DP_ASSERT(fn);
int xtiles = diff->xtiles;
int left = DP_max_int(0, tile_left);
int top = DP_max_int(0, tile_top);
int right = DP_min_int(xtiles - 1, tile_right);
int bottom = DP_min_int(diff->ytiles - 1, tile_bottom);
int left, top, right, bottom, xtiles;
DP_canvas_diff_bounds_clamp(diff, tile_left, tile_top, tile_right,
tile_bottom, &left, &top, &right, &bottom,
&xtiles);
bool *tile_changes = diff->tile_changes;
for (int y = top; y <= bottom; ++y) {
for (int x = left; x <= right; ++x) {
Expand Down
5 changes: 5 additions & 0 deletions src/drawdance/libengine/dpengine/canvas_diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ void DP_canvas_diff_each_pos(DP_CanvasDiff *diff, DP_CanvasDiffEachPosFn fn,
void DP_canvas_diff_each_pos_reset(DP_CanvasDiff *diff,
DP_CanvasDiffEachPosFn fn, void *data);

void DP_canvas_diff_bounds_clamp(DP_CanvasDiff *diff, int tile_left,
int tile_top, int tile_right, int tile_bottom,
int *out_left, int *out_top, int *out_right,
int *out_bottom, int *out_xtiles);

void DP_canvas_diff_each_pos_tile_bounds_reset(DP_CanvasDiff *diff,
int tile_left, int tile_top,
int tile_right, int tile_bottom,
Expand Down
1 change: 1 addition & 0 deletions src/drawdance/libengine/dpengine/canvas_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#ifndef DPENGINE_CANVAS_STATE_H
#define DPENGINE_CANVAS_STATE_H
#include "annotation_list.h"
#include "pixels.h"
#include <dpcommon/common.h>

typedef struct DP_AnnotationList DP_AnnotationList;
Expand Down
7 changes: 2 additions & 5 deletions src/drawdance/libengine/dpengine/local_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,10 @@ int DP_local_state_active_frame_index(DP_LocalState *ls)
return ls->active_frame_index;
}

DP_ViewModeFilter DP_local_state_view_mode_filter_make(DP_LocalState *ls,
DP_ViewModeBuffer *vmb,
DP_CanvasState *cs)
DP_OnionSkins *DP_local_state_onion_skins(DP_LocalState *ls)
{
DP_ASSERT(ls);
return DP_view_mode_filter_make(vmb, ls->view_mode, cs, ls->active_layer_id,
ls->active_frame_index, ls->onion_skins);
return ls->onion_skins;
}

const DP_LocalTrackState *DP_local_state_track_states(DP_LocalState *ls,
Expand Down
6 changes: 2 additions & 4 deletions src/drawdance/libengine/dpengine/local_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,12 @@ bool DP_local_state_background_opaque(DP_LocalState *ls);

DP_ViewMode DP_local_state_view_mode(DP_LocalState *ls);

DP_OnionSkins *DP_local_state_onion_skins(DP_LocalState *ls);

int DP_local_state_active_layer_id(DP_LocalState *ls);

int DP_local_state_active_frame_index(DP_LocalState *ls);

DP_ViewModeFilter DP_local_state_view_mode_filter_make(DP_LocalState *ls,
DP_ViewModeBuffer *vmb,
DP_CanvasState *cs);

const DP_LocalTrackState *DP_local_state_track_states(DP_LocalState *ls,
int *out_count);

Expand Down
Loading

0 comments on commit 3bb3881

Please sign in to comment.