|
|
bf1d82 |
#pragma once
|
|
|
bf1d82 |
|
|
|
bf1d82 |
#ifndef MYPAINT_HPP
|
|
|
bf1d82 |
#define MYPAINT_HPP
|
|
|
bf1d82 |
|
|
|
bf1d82 |
#include <cmath></cmath>
|
|
|
bf1d82 |
#include <algorithm></algorithm>
|
|
|
bf1d82 |
#include <string></string>
|
|
|
bf1d82 |
|
|
|
bf1d82 |
extern "C" {
|
|
|
bf1d82 |
#include <mypaint-brush.h></mypaint-brush.h>
|
|
|
bf1d82 |
#include <mypaint-surface.h></mypaint-surface.h>
|
|
|
bf1d82 |
#include <mypaint-brush-settings.h></mypaint-brush-settings.h>
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
namespace mypaint {
|
|
|
bf1d82 |
class Brush;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
// Dab
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
|
|
|
bf1d82 |
class Dab {
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
float x;
|
|
|
bf1d82 |
float y;
|
|
|
bf1d82 |
float radius;
|
|
|
bf1d82 |
float colorR;
|
|
|
bf1d82 |
float colorG;
|
|
|
bf1d82 |
float colorB;
|
|
|
bf1d82 |
float opaque;
|
|
|
bf1d82 |
float hardness;
|
|
|
bf1d82 |
float alphaEraser;
|
|
|
bf1d82 |
float aspectRatio;
|
|
|
bf1d82 |
float angle;
|
|
|
bf1d82 |
float lockAlpha;
|
|
|
bf1d82 |
float colorize;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
Dab():
|
|
|
bf1d82 |
x(), y(), radius(),
|
|
|
bf1d82 |
colorR(), colorG(), colorB(),
|
|
|
bf1d82 |
opaque(), hardness(), alphaEraser(),
|
|
|
bf1d82 |
aspectRatio(), angle(),
|
|
|
bf1d82 |
lockAlpha(), colorize()
|
|
|
bf1d82 |
{ }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
Dab(
|
|
|
bf1d82 |
float x, float y, float radius,
|
|
|
bf1d82 |
float colorR = 0.f, float colorG = 0.f, float colorB = 0.f,
|
|
|
bf1d82 |
float opaque = 1.f, float hardness = 0.5f, float alphaEraser = 1.f,
|
|
|
bf1d82 |
float aspectRatio = 1.f, float angle = 0.f,
|
|
|
bf1d82 |
float lockAlpha = 0.f, float colorize = 0.f
|
|
|
bf1d82 |
):
|
|
|
bf1d82 |
x(x), y(y), radius(radius),
|
|
|
bf1d82 |
colorR(colorR), colorG(colorG), colorB(colorB),
|
|
|
bf1d82 |
opaque(opaque), hardness(hardness), alphaEraser(alphaEraser),
|
|
|
bf1d82 |
aspectRatio(aspectRatio), angle(angle),
|
|
|
bf1d82 |
lockAlpha(lockAlpha), colorize(lockAlpha)
|
|
|
bf1d82 |
{ }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void clamp() {
|
|
|
bf1d82 |
radius = fabsf(radius);
|
|
|
bf1d82 |
colorR = std::min(std::max(colorR, 0.f), 1.f);
|
|
|
bf1d82 |
colorG = std::min(std::max(colorG, 0.f), 1.f);
|
|
|
bf1d82 |
colorB = std::min(std::max(colorB, 0.f), 1.f);
|
|
|
bf1d82 |
opaque = std::min(std::max(opaque, 0.f), 1.f);
|
|
|
bf1d82 |
hardness = std::min(std::max(hardness, 0.f), 1.f);
|
|
|
bf1d82 |
alphaEraser = std::min(std::max(alphaEraser, 0.f), 1.f);
|
|
|
bf1d82 |
aspectRatio = std::max(aspectRatio, 1.f);
|
|
|
bf1d82 |
lockAlpha = std::min(std::max(lockAlpha, 0.f), 1.f);
|
|
|
bf1d82 |
colorize = std::min(std::max(colorize, 0.f), 1.f);
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
Dab getClamped() const
|
|
|
bf1d82 |
{ Dab dab(*this); dab.clamp(); return dab; }
|
|
|
bf1d82 |
};
|
|
|
bf1d82 |
|
|
|
bf1d82 |
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
// Surface
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
|
|
|
bf1d82 |
class Surface {
|
|
|
bf1d82 |
friend class Brush;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
struct InternalSurface: public MyPaintSurface {
|
|
|
bf1d82 |
Surface *m_owner;
|
|
|
bf1d82 |
};
|
|
|
bf1d82 |
|
|
|
bf1d82 |
InternalSurface m_surface;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
static int internalDrawDab(
|
|
|
bf1d82 |
MyPaintSurface *self,
|
|
|
bf1d82 |
float x, float y, float radius,
|
|
|
bf1d82 |
float colorR, float colorG, float colorB,
|
|
|
bf1d82 |
float opaque, float hardness, float alphaEraser,
|
|
|
bf1d82 |
float aspectRatio, float angle,
|
|
|
bf1d82 |
float lockAlpha, float colorize )
|
|
|
bf1d82 |
{
|
|
|
bf1d82 |
return static_cast<internalsurface*>(self)->m_owner->drawDab( Dab(</internalsurface*>
|
|
|
bf1d82 |
x, y, radius,
|
|
|
bf1d82 |
colorR, colorG, colorB,
|
|
|
bf1d82 |
opaque, hardness, alphaEraser,
|
|
|
bf1d82 |
aspectRatio, angle,
|
|
|
bf1d82 |
lockAlpha, colorize ));
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
static void internalGetColor(
|
|
|
bf1d82 |
MyPaintSurface *self,
|
|
|
bf1d82 |
float x, float y, float radius,
|
|
|
bf1d82 |
float *colorR, float *colorG, float *colorB, float *colorA )
|
|
|
bf1d82 |
{
|
|
|
bf1d82 |
static_cast<internalsurface*>(self)->m_owner->getColor(</internalsurface*>
|
|
|
bf1d82 |
x, y,
|
|
|
bf1d82 |
radius,
|
|
|
bf1d82 |
*colorR, *colorG, *colorB, *colorA);
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
Surface():
|
|
|
bf1d82 |
m_surface()
|
|
|
bf1d82 |
{
|
|
|
bf1d82 |
m_surface.m_owner = this;
|
|
|
bf1d82 |
m_surface.draw_dab = internalDrawDab;
|
|
|
bf1d82 |
m_surface.get_color = internalGetColor;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
virtual ~Surface() { }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
virtual bool getColor(
|
|
|
bf1d82 |
float x, float y, float radius,
|
|
|
bf1d82 |
float &colorR, float &colorG, float &colorB, float &colorA ) = 0;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
virtual bool drawDab(const Dab &dab) = 0;
|
|
|
bf1d82 |
};
|
|
|
bf1d82 |
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
// Brush
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
|
|
|
bf1d82 |
class Brush {
|
|
|
bf1d82 |
MyPaintBrush *m_brush;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
Brush():
|
|
|
bf1d82 |
m_brush(mypaint_brush_new())
|
|
|
bf1d82 |
{ fromDefaults(); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
Brush(const Brush &other):
|
|
|
bf1d82 |
m_brush(mypaint_brush_new())
|
|
|
bf1d82 |
{ fromBrush(other); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
~Brush()
|
|
|
bf1d82 |
{ mypaint_brush_unref(m_brush); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
Brush& operator= (const Brush &other) {
|
|
|
bf1d82 |
fromBrush(other);
|
|
|
bf1d82 |
return *this;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void reset()
|
|
|
bf1d82 |
{ mypaint_brush_reset(m_brush); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void newStroke()
|
|
|
bf1d82 |
{ mypaint_brush_new_stroke(m_brush); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
int strokeTo(Surface &surface, float x, float y,
|
|
|
bf1d82 |
float pressure, float xtilt, float ytilt, double dtime)
|
|
|
bf1d82 |
{
|
|
|
bf1d82 |
return mypaint_brush_stroke_to(m_brush, &surface.m_surface,
|
|
|
bf1d82 |
x, y, pressure, xtilt, ytilt, dtime);
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void setBaseValue(MyPaintBrushSetting id, float value)
|
|
|
bf1d82 |
{ mypaint_brush_set_base_value(m_brush, id, value); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
float getBaseValue(MyPaintBrushSetting id) const
|
|
|
bf1d82 |
{ return mypaint_brush_get_base_value(m_brush, id); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
bool isConstant(MyPaintBrushSetting id) const
|
|
|
bf1d82 |
{ return mypaint_brush_is_constant(m_brush, id); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
int getInputsUsedN(MyPaintBrushSetting id) const
|
|
|
bf1d82 |
{ return mypaint_brush_get_inputs_used_n(m_brush, id); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void setMappingN(MyPaintBrushSetting id, MyPaintBrushInput input, int n)
|
|
|
bf1d82 |
{ mypaint_brush_set_mapping_n(m_brush, id, input, n); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
int getMappingN(MyPaintBrushSetting id, MyPaintBrushInput input) const
|
|
|
bf1d82 |
{ return mypaint_brush_get_mapping_n(m_brush, id, input); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void setMappingPoint(MyPaintBrushSetting id, MyPaintBrushInput input, int index, float x, float y)
|
|
|
bf1d82 |
{ mypaint_brush_set_mapping_point(m_brush, id, input, index, x, y); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void getMappingPoint(MyPaintBrushSetting id, MyPaintBrushInput input, int index, float &x, float &y) const
|
|
|
bf1d82 |
{ mypaint_brush_get_mapping_point(m_brush, id, input, index, &x, &y); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
float getState(MyPaintBrushState i) const
|
|
|
bf1d82 |
{ return mypaint_brush_get_state(m_brush, i); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void setState(MyPaintBrushState i, float value)
|
|
|
bf1d82 |
{ return mypaint_brush_set_state(m_brush, i, value); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
double getTotalStrokePaintingTime() const
|
|
|
bf1d82 |
{ return mypaint_brush_get_total_stroke_painting_time(m_brush); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void setPrintInputs(bool enabled)
|
|
|
bf1d82 |
{ mypaint_brush_set_print_inputs(m_brush, enabled); }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void fromDefaults() {
|
|
|
bf1d82 |
mypaint_brush_from_defaults(m_brush);
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
void fromBrush(const Brush &other) {
|
|
|
bf1d82 |
for(int i = 0; i < MYPAINT_BRUSH_SETTINGS_COUNT; ++i) {
|
|
|
bf1d82 |
MyPaintBrushSetting id = (MyPaintBrushSetting)i;
|
|
|
bf1d82 |
setBaseValue(id, other.getBaseValue(id));
|
|
|
bf1d82 |
for(int j = 0; j < MYPAINT_BRUSH_INPUTS_COUNT; ++j) {
|
|
|
bf1d82 |
MyPaintBrushInput input = (MyPaintBrushInput)j;
|
|
|
bf1d82 |
int n = other.getMappingN(id, input);
|
|
|
bf1d82 |
setMappingN(id, input, n);
|
|
|
bf1d82 |
for(int index = 0; index < n; ++index) {
|
|
|
bf1d82 |
float x = 0.f, y = 0.f;
|
|
|
bf1d82 |
other.getMappingPoint(id, input, index, x, y);
|
|
|
bf1d82 |
setMappingPoint(id, input, index, x, y);
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
bool fromString(const std::string &s) {
|
|
|
bf1d82 |
return mypaint_brush_from_string(m_brush, s.c_str());
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
};
|
|
|
bf1d82 |
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
// Setting
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
|
|
|
bf1d82 |
class Setting final {
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
MyPaintBrushSetting id;
|
|
|
bf1d82 |
std::string key;
|
|
|
bf1d82 |
std::string name;
|
|
|
bf1d82 |
std::string tooltip;
|
|
|
bf1d82 |
bool constant;
|
|
|
bf1d82 |
float min;
|
|
|
bf1d82 |
float def;
|
|
|
bf1d82 |
float max;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
private:
|
|
|
bf1d82 |
Setting(): id(), constant(), min(), def(), max() { }
|
|
|
bf1d82 |
Setting(const Setting&): id(), constant(), min(), def(), max() { }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
static const Setting* all() {
|
|
|
bf1d82 |
static bool initialized = false;
|
|
|
bf1d82 |
static Setting settings[MYPAINT_BRUSH_SETTINGS_COUNT];
|
|
|
bf1d82 |
if (!initialized) {
|
|
|
bf1d82 |
for(int i = 0; i < MYPAINT_BRUSH_SETTINGS_COUNT; ++i) {
|
|
|
bf1d82 |
const MyPaintBrushSettingInfo *info = mypaint_brush_setting_info((MyPaintBrushSetting)i);
|
|
|
bf1d82 |
settings[i].id = (MyPaintBrushSetting)i;
|
|
|
bf1d82 |
settings[i].key = info->cname;
|
|
|
bf1d82 |
settings[i].name = mypaint_brush_setting_info_get_name(info);
|
|
|
bf1d82 |
settings[i].tooltip = mypaint_brush_setting_info_get_tooltip(info);
|
|
|
bf1d82 |
settings[i].constant = info->constant;
|
|
|
bf1d82 |
settings[i].min = info->min;
|
|
|
bf1d82 |
settings[i].def = info->def;
|
|
|
bf1d82 |
settings[i].max = info->max;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
return settings;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
static const Setting& byId(MyPaintBrushSetting id)
|
|
|
bf1d82 |
{ return all()[id]; }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
static const Setting* findByKey(const std::string &key) {
|
|
|
bf1d82 |
const Setting* settings = all();
|
|
|
bf1d82 |
for(int i = 0; i < MYPAINT_BRUSH_SETTINGS_COUNT; ++i)
|
|
|
bf1d82 |
if (settings[i].key == key)
|
|
|
bf1d82 |
return &settings[i];
|
|
|
bf1d82 |
return 0;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
};
|
|
|
bf1d82 |
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
// Input
|
|
|
bf1d82 |
//
|
|
|
bf1d82 |
//=======================================================
|
|
|
bf1d82 |
|
|
|
bf1d82 |
class Input final {
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
MyPaintBrushInput id;
|
|
|
bf1d82 |
std::string key;
|
|
|
bf1d82 |
std::string name;
|
|
|
bf1d82 |
std::string tooltip;
|
|
|
bf1d82 |
float hardMin;
|
|
|
bf1d82 |
float softMin;
|
|
|
bf1d82 |
float normal;
|
|
|
bf1d82 |
float softMax;
|
|
|
bf1d82 |
float hardMax;
|
|
|
bf1d82 |
|
|
|
bf1d82 |
private:
|
|
|
bf1d82 |
Input(): id(), hardMin(), softMin(), normal(), softMax(), hardMax() { }
|
|
|
bf1d82 |
Input(const Input&): id(), hardMin(), softMin(), normal(), softMax(), hardMax() { }
|
|
|
bf1d82 |
|
|
|
bf1d82 |
public:
|
|
|
bf1d82 |
static const Input* all() {
|
|
|
bf1d82 |
static bool initialized = false;
|
|
|
bf1d82 |
static Input inputs[MYPAINT_BRUSH_INPUTS_COUNT];
|
|
|
bf1d82 |
if (!initialized) {
|
|
|
bf1d82 |
for(int i = 0; i < MYPAINT_BRUSH_INPUTS_COUNT; ++i) {
|
|
|
bf1d82 |
const MyPaintBrushInputInfo *info = mypaint_brush_input_info((MyPaintBrushInput)i);
|
|
|
bf1d82 |
inputs[i].id = (MyPaintBrushInput)i;
|
|
|
bf1d82 |
inputs[i].key = info->cname;
|
|
|
bf1d82 |
inputs[i].name = mypaint_brush_input_info_get_name(info);
|
|
|
bf1d82 |
inputs[i].tooltip = mypaint_brush_input_info_get_tooltip(info);
|
|
|
bf1d82 |
inputs[i].hardMin = info->hard_min;
|
|
|
bf1d82 |
inputs[i].softMin = info->soft_min;
|
|
|
bf1d82 |
inputs[i].normal = info->normal;
|
|
|
bf1d82 |
inputs[i].softMax = info->soft_max;
|
|
|
bf1d82 |
inputs[i].hardMax = info->hard_max;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
return inputs;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
static const Input& byId(MyPaintBrushInput id) {
|
|
|
bf1d82 |
return all()[id];
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
static const Input* findByKey(const std::string &key) {
|
|
|
bf1d82 |
const Input* inputs = all();
|
|
|
bf1d82 |
for(int i = 0; i < MYPAINT_BRUSH_INPUTS_COUNT; ++i)
|
|
|
bf1d82 |
if (inputs[i].key == key)
|
|
|
bf1d82 |
return &inputs[i];
|
|
|
bf1d82 |
return 0;
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
};
|
|
|
bf1d82 |
}
|
|
|
bf1d82 |
|
|
|
bf1d82 |
#endif // MYPAINT_HPP
|