1// Aseprite
2// Copyright (C) 2019-2021 Igara Studio S.A.
3// Copyright (C) 2001-2018 David Capello
4//
5// This program is distributed under the terms of
6// the End-User License Agreement for Aseprite.
7
8#ifndef APP_TOOLS_INTERTWINE_H_INCLUDED
9#define APP_TOOLS_INTERTWINE_H_INCLUDED
10#pragma once
11
12#include "app/tools/stroke.h"
13#include "doc/algo.h"
14#include "gfx/point.h"
15#include "gfx/rect.h"
16
17namespace app {
18 namespace tools {
19 class ToolLoop;
20
21 // Converts a sequence of points in several call to
22 // Intertwine::doPointshapePoint(). Basically each implementation
23 // says which pixels should be drawn between a sequence of
24 // user-defined points.
25 class Intertwine {
26 public:
27 virtual ~Intertwine() { }
28 virtual bool snapByAngle() { return false; }
29 virtual void prepareIntertwine(ToolLoop* loop) { }
30
31 // The given stroke must be relative to the cel origin.
32 virtual void joinStroke(ToolLoop* loop, const Stroke& stroke) = 0;
33 virtual void fillStroke(ToolLoop* loop, const Stroke& stroke) = 0;
34
35 virtual gfx::Rect getStrokeBounds(ToolLoop* loop, const Stroke& stroke);
36
37 // Special region to force when the modify_tilemap_cel_region()
38 // is called to restore the m_dstTileset from the m_dstImage
39 // in ExpandCelCanvas::validateDestTileset.
40 virtual gfx::Region forceTilemapRegionToValidate() { return gfx::Region(); }
41
42 struct LineData {
43 ToolLoop* loop;
44 Stroke::Pt a, b, pt;
45 float t, step;
46 LineData(ToolLoop* loop, const Stroke::Pt& a, const Stroke::Pt& b);
47 void doStep(int x, int y);
48 };
49
50 protected:
51 virtual void doTransformPoint(const Stroke::Pt& pt, ToolLoop* loop);
52 virtual void doPointshapeStrokePt(const Stroke::Pt& pt, ToolLoop* loop);
53 // The given point must be relative to the cel origin.
54 static void doPointshapePoint(int x, int y, ToolLoop* loop);
55 static void doPointshapePointDynamics(int x, int y, LineData* data);
56 static void doPointshapeHline(int x1, int y, int x2, ToolLoop* loop);
57 // TODO We should remove this function and always use dynamics
58 static void doPointshapeLineWithoutDynamics(int x1, int y1, int x2, int y2, ToolLoop* loop);
59 static void doPointshapeLine(const Stroke::Pt& a,
60 const Stroke::Pt& b, ToolLoop* loop);
61
62 static doc::AlgoLineWithAlgoPixel getLineAlgo(ToolLoop* loop,
63 const Stroke::Pt& a,
64 const Stroke::Pt& b);
65 };
66
67 } // namespace tools
68} // namespace app
69
70#endif // TOOLS_INTERTWINE_H_INCLUDED
71