Skip to content

Commit

Permalink
Added pen pressure sensitivity (fix aseprite#710)
Browse files Browse the repository at this point in the history
- Added support to detect eraser tip on Linux (aseprite#610)
- Related to aseprite#139
- Still needs works for gradients and better brush interpolations
  between stroke points
- Requested several times, e.g. https://community.aseprite.org/t/1077
  https://community.aseprite.org/t/1881, steam forum, etc.
  • Loading branch information
dacap committed Apr 22, 2020
1 parent 5affdbb commit 79f9e28
Show file tree
Hide file tree
Showing 26 changed files with 586 additions and 44 deletions.
10 changes: 5 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ matrix:
addons:
apt:
packages:
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev ninja-build
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev libxi-dev ninja-build
env:
- ENABLE_UI=OFF
- XVFB=xvfb-run
- os: linux
addons:
apt:
packages:
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev ninja-build
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev libxi-dev ninja-build
env:
- ENABLE_SCRIPTING=OFF
- XVFB=xvfb-run
- os: linux
addons:
apt:
packages:
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev ninja-build
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev libxi-dev ninja-build
env:
- ENABLE_SCRIPTING=OFF
- ENABLE_UI=OFF
Expand All @@ -37,7 +37,7 @@ matrix:
addons:
apt:
packages:
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev ninja-build
- libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev libxi-dev ninja-build
env:
- ENABLE_UI=ON
- XVFB=xvfb-run
Expand All @@ -47,7 +47,7 @@ matrix:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7 libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev ninja-build
- g++-7 libpixman-1-dev libfreetype6-dev libharfbuzz-dev libx11-dev libxcursor-dev libxi-dev ninja-build
env:
- MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- ENABLE_UI=ON
Expand Down
4 changes: 2 additions & 2 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ versions might work).

You will need the following dependencies on Ubuntu/Debian:

sudo apt-get install -y g++ cmake ninja-build libx11-dev libxcursor-dev libgl1-mesa-dev libfontconfig1-dev
sudo apt-get install -y g++ cmake ninja-build libx11-dev libxcursor-dev libxi-dev libgl1-mesa-dev libfontconfig1-dev

On Fedora:

sudo dnf install -y gcc-c++ cmake ninja-build libX11-devel libXcursor-devel mesa-libGL-devel fontconfig-devel
sudo dnf install -y gcc-c++ cmake ninja-build libX11-devel libXcursor-devel libXi-devel mesa-libGL-devel fontconfig-devel

# Compiling

Expand Down
Binary file modified data/extensions/aseprite-theme/sheet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions data/extensions/aseprite-theme/theme.xml
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@
<part id="outline_vertical" x="192" y="224" w="13" h="15" />
<part id="outline_empty_pixel" x="208" y="224" w="5" h="5" />
<part id="outline_full_pixel" x="214" y="224" w="5" h="5" />
<part id="dynamics" x="176" y="144" w="16" h="16" />
</parts>
<styles>
<style id="box" />
Expand Down
23 changes: 23 additions & 0 deletions data/strings/en.ini
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ SetSameInk = Same Ink in All Tools
ShowAutoGuides = Show Auto Guides
ShowBrushPreview = Show Brush Preview
ShowBrushes = Show Brushes
ShowDynamics = Show Dynamics
ShowExtras = Show Extras
ShowGrid = Show Grid
ShowLayerEdges = Show Layer Edges
Expand Down Expand Up @@ -520,6 +521,28 @@ duplicate = Duplicate:
as = As:
merged_layers = Duplicate merged layers only
[dynamics]
pressure = Pressure
pressure_tooltip = Control parameters through the pen pressure sensor
velocity = Velocity
velocity_tooltip = Control parameters through the mouse velocity
size = Size:
size_tooltip = <<<END
Change the brush size
depending on the sensor value
END
angle = Angle:
angle_tooltip = <<<END
Change the brush angle
depending on the sensor value
END
gradient = Gradient:
gradient_tooltip = <<<END
Gradient between foreground
and background colors
END
max_point_value = Max Point Value:
[export_file]
title = Export File
output_file = Output File:
Expand Down
39 changes: 39 additions & 0 deletions data/widgets/dynamics.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!-- Aseprite -->
<!-- Copyright (C) 2020 Igara Studio S.A. -->
<gui>
<vbox id="dynamics">
<hbox>
<buttonset id="values" columns="3">
<item text="" />
<item text="@.pressure" tooltip="@.pressure_tooltip" tooltip_dir="bottom" />
<item text="@.velocity" tooltip="@.velocity_tooltip" tooltip_dir="bottom" />

<item text="@.size" tooltip="@.size_tooltip" tooltip_dir="right" />
<item text="" maxheight="1" />
<item text="" maxheight="1" />

<item text="@.angle" tooltip="@.angle_tooltip" tooltip_dir="right" />
<item text="" maxheight="1" />
<item text="" maxheight="1" />

<item text="@.gradient" tooltip="@.gradient_tooltip" tooltip_dir="right" />
<item text="" maxheight="1" />
<item text="" maxheight="1" />
</buttonset>
</hbox>

<separator id="separator" text="@.max_point_value" horizontal="true" />

<grid id="options" columns="2" childspacing="0" expansive="true">
<label id="max_size_label" text="@.size" style="mini_label" />
<slider id="max_size" value="64" min="1" max="64" cell_align="horizontal" />

<label id="max_angle_label" text="@.angle" style="mini_label" />
<slider id="max_angle" value="0" min="-180" max="+180" cell_align="horizontal" />

<label id="gradient_label" text="@.gradient" style="mini_label" />
<hbox id="gradient_placeholder" />
</grid>

</vbox>
</gui>
2 changes: 1 addition & 1 deletion laf
1 change: 1 addition & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ if(ENABLE_UI)
ui/dithering_selector.cpp
ui/doc_view.cpp
ui/drop_down_button.cpp
ui/dynamics_popup.cpp
ui/editor/brush_preview.cpp
ui/editor/drawing_state.cpp
ui/editor/editor.cpp
Expand Down
7 changes: 6 additions & 1 deletion src/app/script/app_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,12 @@ int App_useTool(lua_State* L)
while (lua_next(L, -2) != 0) {
gfx::Point pt = convert_args_into_point(L, -1);

tools::Pointer pointer(pt, tools::Pointer::Button::Left);
tools::Pointer pointer(
pt,
// TODO configurable params
tools::Pointer::Button::Left,
tools::Pointer::Type::Unknown,
0.0f);
if (first) {
first = false;
manager.prepareLoop(pointer);
Expand Down
42 changes: 42 additions & 0 deletions src/app/tools/dynamics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Aseprite
// Copyright (C) 2020 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.

#ifndef APP_TOOLS_DYNAMICS_H_INCLUDED
#define APP_TOOLS_DYNAMICS_H_INCLUDED
#pragma once

#include "render/dithering_algorithm.h"
#include "render/dithering_matrix.h"

namespace app {
namespace tools {

enum class DynamicSensor {
Static,
Pressure,
Velocity,
};

struct DynamicsOptions {
DynamicSensor size = DynamicSensor::Static;
DynamicSensor angle = DynamicSensor::Static;
DynamicSensor gradient = DynamicSensor::Static;
int maxSize = 0;
int maxAngle = 0;
render::DitheringAlgorithm ditheringAlgorithm = render::DitheringAlgorithm::None;
render::DitheringMatrix ditheringMatrix;

bool isDynamic() const {
return (size != DynamicSensor::Static ||
angle != DynamicSensor::Static ||
gradient != DynamicSensor::Static);
}
};

} // namespace tools
} // namespace app

#endif
17 changes: 11 additions & 6 deletions src/app/tools/point_shapes.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,26 @@ class PixelPointShape : public PointShape {
};

class BrushPointShape : public PointShape {
Brush* m_brush;
Brush* m_lastBrush;
std::shared_ptr<CompressedImage> m_compressedImage;
bool m_firstPoint;

public:

void preparePointShape(ToolLoop* loop) override {
m_brush = loop->getBrush();
m_compressedImage.reset(new CompressedImage(m_brush->image(),
m_brush->maskBitmap(),
false));
m_firstPoint = true;
m_lastBrush = nullptr;
}

void transformPoint(ToolLoop* loop, int x, int y) override {
Brush* m_brush = loop->getBrush();
if (m_lastBrush != m_brush) {
m_lastBrush = m_brush;
m_compressedImage.reset(new CompressedImage(m_brush->image(),
m_brush->maskBitmap(),
false));
}

x += m_brush->bounds().x;
y += m_brush->bounds().y;

Expand Down Expand Up @@ -91,7 +96,7 @@ class BrushPointShape : public PointShape {
}

void getModifiedArea(ToolLoop* loop, int x, int y, Rect& area) override {
area = m_brush->bounds();
area = loop->getBrush()->bounds();
area.x += x;
area.y += y;
}
Expand Down
24 changes: 20 additions & 4 deletions src/app/tools/pointer.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2016 David Capello
//
// This program is distributed under the terms of
Expand All @@ -9,6 +10,7 @@
#pragma once

#include "gfx/point.h"
#include "ui/pointer_type.h"

namespace app {
namespace tools {
Expand All @@ -17,19 +19,33 @@ namespace tools {
class Pointer {
public:
enum Button { None, Left, Middle, Right };
typedef ui::PointerType Type;

Pointer()
: m_point(0, 0), m_button(None) { }

Pointer(const gfx::Point& point, Button button)
: m_point(point), m_button(button) { }
: m_point(0, 0)
, m_button(None)
, m_type(Type::Unknown)
, m_pressure(0.0f) { }

Pointer(const gfx::Point& point,
const Button button,
const Type type,
const float pressure)
: m_point(point)
, m_button(button)
, m_type(type)
, m_pressure(pressure) { }

const gfx::Point& point() const { return m_point; }
Button button() const { return m_button; }
Type type() const { return m_type; }
float pressure() const { return m_pressure; }

private:
gfx::Point m_point;
Button m_button;
Type m_type;
float m_pressure;
};

} // namespace tools
Expand Down
7 changes: 6 additions & 1 deletion src/app/tools/tool_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
#define APP_TOOLS_TOOL_LOOP_H_INCLUDED
#pragma once

#include "app/tools/dynamics.h"
#include "app/tools/tool_loop_modifiers.h"
#include "app/tools/trace_policy.h"
#include "doc/brush.h"
#include "doc/color.h"
#include "doc/frame.h"
#include "filters/tiled_mode.h"
Expand All @@ -23,7 +25,6 @@ namespace gfx {
}

namespace doc {
class Brush;
class Image;
class Layer;
class Mask;
Expand Down Expand Up @@ -72,6 +73,7 @@ namespace app {

// Returns the brush which will be used with the tool
virtual Brush* getBrush() = 0;
virtual void setBrush(const BrushRef& newBrush) = 0;

// Returns the document to which belongs the sprite.
virtual Doc* getDocument() = 0;
Expand Down Expand Up @@ -235,6 +237,9 @@ namespace app {
virtual render::DitheringAlgorithmBase* getDitheringAlgorithm() = 0;
virtual render::GradientType getGradientType() = 0;

// For freehand algorithms with dynamics
virtual tools::DynamicsOptions getDynamics() = 0;

// Called when the user release the mouse on SliceInk
virtual void onSliceRect(const gfx::Rect& bounds) = 0;
};
Expand Down
Loading

0 comments on commit 79f9e28

Please sign in to comment.