summaryrefslogtreecommitdiffstats
path: root/src/ui/tools/eraser-tool.h
blob: 2c9377af323dbc6482a9e21e4d963f31d2c77a14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef ERASER_TOOL_H_SEEN
#define ERASER_TOOL_H_SEEN

/*
 * Handwriting-like drawing mode
 *
 * Authors:
 *   Mitsuru Oka <oka326@parkcity.ne.jp>
 *   Lauris Kaplinski <lauris@kaplinski.com>
 *
 * The original dynadraw code:
 *   Paul Haeberli <paul@sgi.com>
 *
 * Copyright (C) 1998 The Free Software Foundation
 * Copyright (C) 1999-2002 authors
 * Copyright (C) 2001-2002 Ximian, Inc.
 * Copyright (C) 2008 Jon A. Cruz
 *
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */

#include <2geom/point.h>

#include "message-stack.h"
#include "style.h"
#include "ui/tools/dynamic-base.h"

namespace Inkscape {
namespace UI {
namespace Tools {

enum class EraserToolMode
{
    DELETE,
    CUT,
    CLIP
};
extern EraserToolMode const DEFAULT_ERASER_MODE;

class EraserTool : public DynamicBase {

private:
    // non-static data:
    EraserToolMode mode = DEFAULT_ERASER_MODE;
    bool nowidth = false;
    std::vector<MessageId> _our_messages;

    // static data:
    inline static guint32 const trace_color_rgba   = 0xff0000ff; // RGBA red
    inline static SPWindRule const trace_wind_rule = SP_WIND_RULE_EVENODD;

    inline static double const tolerance = 0.1;

    inline static double const epsilon       = 0.5e-6;
    inline static double const epsilon_start = 0.5e-2;
    inline static double const vel_start     = 1e-5;

    inline static double const drag_default = 1.0;
    inline static double const drag_min     = 0.0;
    inline static double const drag_max     = 1.0;

    inline static double const min_pressure     = 0.0;
    inline static double const max_pressure     = 1.0;
    inline static double const default_pressure = 1.0;

    inline static double const min_tilt     = -1.0;
    inline static double const max_tilt     = 1.0;
    inline static double const default_tilt = 0.0;

public:
    // public member functions
    EraserTool(SPDesktop *desktop);
    ~EraserTool() override;
    bool root_handler(GdkEvent *event) final;

    using Error = std::uint64_t;
    inline static Error const ALL_GOOD      = 0x0;
    inline static Error const NOT_IN_BOUNDS = 0x1 << 0;
    inline static Error const NON_EXISTENT  = 0x1 << 1;
    inline static Error const NO_AREA_PATH  = 0x1 << 2;
    inline static Error const RASTER_IMAGE  = 0x1 << 3;
    inline static Error const ERROR_GROUP   = 0x1 << 4;

private:
    // private member functions
    void _reset(Geom::Point p);
    void _extinput(GdkEvent *event);
    bool _apply(Geom::Point p);
    void _brush();
    void _cancel();
    void _clearCurrent();
    void _setToAccumulated();
    void _accumulate();
    void _fitAndSplit(bool releasing);
    void _drawTemporaryBox();
    bool _handleKeypress(GdkEventKey const *key);
    void _completeBezier(double tolerance_sq, bool releasing);
    void _failedBezierFallback();
    void _fitDrawLastPoint();
    void _clipErase(SPItem *item, SPObject *parent, Geom::OptRect &eraser_box);
    Error _cutErase(SPItem *item, Geom::OptRect const &eraser_bbox, std::vector<SPItem *> &survivers);
    void _booleanErase(SPItem *erasee, std::vector<SPItem*> &survivers) const;
    void _handleStrokeStyle(SPItem *item) const;
    void _updateMode();
    void _removeTemporarySegments();
    void _setStatusBarMessage(char *message);
    void _clearStatusBar();

    static void _generateNormalDist2(double &r1, double &r2);
    static void _addCap(SPCurve &curve, Geom::Point const &pre, Geom::Point const &from, Geom::Point const &to,
                        Geom::Point const &post, double rounding);
    static bool _isStraightSegment(SPItem *path);
    static Error _uncuttableItemType(SPItem *item);
};

} // namespace Tools
} // namespace UI
} // namespace Inkscape

#endif // ERASER_TOOL_H_SEEN

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :