Toshihiro Shimizu 890ddd
Jeremy Bullock e122a9
#include "filltool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Jeremy Bullock e122a9
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/tonionskinmaskhandle.h"
Toshihiro Shimizu 890ddd
#include "timagecache.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "tools/stylepicker.h"
Jeremy Bullock e122a9
Toshihiro Shimizu 890ddd
#include "toonz/stage2.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tinbetween.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Jeremy Bullock e122a9
Toshihiro Shimizu 890ddd
#include "toonz/onionskinmask.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttilesaver.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "toonz/levelproperties.h"
Jeremy Bullock e122a9
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "autofill.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "historytypes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <stack></stack>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// For Qt translation support
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace ToolUtils;
Toshihiro Shimizu 890ddd
Jeremy Bullock e122a9
//#define LINES L"Lines"
Jeremy Bullock e122a9
//#define AREAS L"Areas"
Jeremy Bullock e122a9
//#define ALL L"Lines & Areas"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define NORMALFILL L"Normal"
Toshihiro Shimizu 890ddd
#define RECTFILL L"Rectangular"
Toshihiro Shimizu 890ddd
#define FREEHANDFILL L"Freehand"
Toshihiro Shimizu 890ddd
#define POLYLINEFILL L"Polyline"
justburner 8221ad
#define FREEPICKFILL L"Freepick"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TEnv::IntVar MinFillDepth("InknpaintMinFillDepth", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar MaxFillDepth("InknpaintMaxFillDepth", 10);
Toshihiro Shimizu 890ddd
TEnv::StringVar FillType("InknpaintFillType", "Normal");
Toshihiro Shimizu 890ddd
TEnv::StringVar FillColorType("InknpaintFillColorType", "Areas");
Toshihiro Shimizu 890ddd
TEnv::IntVar FillSelective("InknpaintFillSelective", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar FillOnion("InknpaintFillOnion", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar FillSegment("InknpaintFillSegment", 0);
Toshihiro Shimizu 890ddd
TEnv::IntVar FillRange("InknpaintFillRange", 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline int vectorFill(const TVectorImageP &img, const std::wstring &type,
Shinya Kitaoka 120a6e
                      const TPointD &point, int style, bool emptyOnly = false) {
Shinya Kitaoka 120a6e
  if (type == ALL || type == LINES) {
Shinya Kitaoka 120a6e
    int oldStyleId = img->fillStrokes(point, style);
Shinya Kitaoka 120a6e
    if (oldStyleId != -1) return oldStyleId;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (type == ALL || type == AREAS) return img->fill(point, style, emptyOnly);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// VectorFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class VectorFillUndo final : public TToolUndo {
Shinya Kitaoka 120a6e
  int m_oldColorStyle;
Shinya Kitaoka 120a6e
  int m_newColorStyle;
Shinya Kitaoka 120a6e
  TPointD m_point;
Shinya Kitaoka 120a6e
  std::wstring m_type;
Shinya Kitaoka 120a6e
  int m_row;
Shinya Kitaoka 120a6e
  int m_column;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  VectorFillUndo(int newColorStyle, int oldColorStyle, std::wstring fillType,
Shinya Kitaoka 120a6e
                 TPointD clickPoint, TXshSimpleLevel *sl, const TFrameId &fid)
Shinya Kitaoka 120a6e
      : TToolUndo(sl, fid)
Shinya Kitaoka 120a6e
      , m_newColorStyle(newColorStyle)
Shinya Kitaoka 120a6e
      , m_oldColorStyle(oldColorStyle)
Shinya Kitaoka 120a6e
      , m_point(clickPoint)
Shinya Kitaoka 120a6e
      , m_type(fillType) {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      m_row    = app->getCurrentFrame()->getFrame();
Shinya Kitaoka 120a6e
      m_column = app->getCurrentColumn()->getColumnIndex();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentLevel()->setLevel(m_level.getPointer());
Shinya Kitaoka 120a6e
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
      app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
    assert(img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(img->getMutex());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    vectorFill(img, m_type, m_point, m_oldColorStyle);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentLevel()->setLevel(m_level.getPointer());
Shinya Kitaoka 120a6e
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFrame(m_row);
Shinya Kitaoka 120a6e
      app->getCurrentColumn()->setColumnIndex(m_column);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      app->getCurrentFrame()->setFid(m_frameId);
Shinya Kitaoka 120a6e
    assert(img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(img->getMutex());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    vectorFill(img, m_type, m_point, m_newColorStyle);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onAdd() override {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override { return sizeof(*this); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override {
Shinya Kitaoka 120a6e
    return QString("Fill Tool : %1").arg(QString::fromStdWString(m_type));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::FillTool; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// VectorRectFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class VectorRectFillUndo final : public TToolUndo {
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> *m_regionFillInformation;</tfilledregioninf>
Shinya Kitaoka 120a6e
  std::vector<std::pair<int, int="">> *m_strokeFillInformation;</std::pair<int,>
Shinya Kitaoka 120a6e
  TRectD m_selectionArea;
Shinya Kitaoka 120a6e
  int m_styleId;
Shinya Kitaoka 120a6e
  bool m_unpaintedOnly;
Shinya Kitaoka 120a6e
  TStroke *m_stroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ~VectorRectFillUndo() {
Shinya Kitaoka 120a6e
    if (m_regionFillInformation) delete m_regionFillInformation;
Shinya Kitaoka 120a6e
    if (m_strokeFillInformation) delete m_strokeFillInformation;
Shinya Kitaoka 120a6e
    if (m_stroke) delete m_stroke;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VectorRectFillUndo(std::vector<tfilledregioninf> *regionFillInformation,</tfilledregioninf>
Shinya Kitaoka 120a6e
                     std::vector<std::pair<int, int="">> *strokeFillInformation,</std::pair<int,>
Shinya Kitaoka 120a6e
                     TRectD selectionArea, TStroke *stroke, int styleId,
Shinya Kitaoka 120a6e
                     bool unpaintedOnly, TXshSimpleLevel *sl,
Shinya Kitaoka 120a6e
                     const TFrameId &fid)
Shinya Kitaoka 120a6e
      : TToolUndo(sl, fid)
Shinya Kitaoka 120a6e
      , m_regionFillInformation(regionFillInformation)
Shinya Kitaoka 120a6e
      , m_strokeFillInformation(strokeFillInformation)
Shinya Kitaoka 120a6e
      , m_selectionArea(selectionArea)
Shinya Kitaoka 120a6e
      , m_styleId(styleId)
Shinya Kitaoka 120a6e
      , m_unpaintedOnly(unpaintedOnly)
Shinya Kitaoka 120a6e
      , m_stroke(0) {
Shinya Kitaoka 120a6e
    if (stroke) m_stroke = new TStroke(*stroke);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(!!img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
    if (m_regionFillInformation) {
Shinya Kitaoka 120a6e
      for (UINT i = 0; i < m_regionFillInformation->size(); i++) {
Shinya Kitaoka 120a6e
        TRegion *reg = img->getRegion((*m_regionFillInformation)[i].m_regionId);
Shinya Kitaoka 120a6e
        if (reg) reg->setStyle((*m_regionFillInformation)[i].m_styleId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_strokeFillInformation) {
Shinya Kitaoka 120a6e
      for (UINT i = 0; i < m_strokeFillInformation->size(); i++) {
Shinya Kitaoka 120a6e
        TStroke *s = img->getStroke((*m_strokeFillInformation)[i].first);
Shinya Kitaoka 120a6e
        s->setStyle((*m_strokeFillInformation)[i].second);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img->selectFill(m_selectionArea, m_stroke, m_styleId, m_unpaintedOnly,
Shinya Kitaoka 120a6e
                    m_regionFillInformation != 0, m_strokeFillInformation != 0);
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void onAdd() override {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
shun-iwasawa 3f2d1d
    int size1 = m_regionFillInformation ? m_regionFillInformation->capacity() *
shun-iwasawa 3f2d1d
                                              sizeof(m_regionFillInformation)
shun-iwasawa 3f2d1d
                                        : 0;
shun-iwasawa 3f2d1d
    int size2 = m_strokeFillInformation ? m_strokeFillInformation->capacity() *
shun-iwasawa 3f2d1d
                                              sizeof(m_strokeFillInformation)
shun-iwasawa 3f2d1d
                                        : 0;
Shinya Kitaoka 120a6e
    return sizeof(*this) + size1 + size2 + 500;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QString("Fill Tool : "); }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::FillTool; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Jeremy Bullock e122a9
// VectorGapSizeChangeUndo
Jeremy Bullock e122a9
//-----------------------------------------------------------------------------
Jeremy Bullock e122a9
Jeremy Bullock e122a9
class VectorGapSizeChangeUndo final : public TToolUndo {
Jeremy Bullock e122a9
  double m_oldGapSize;
Jeremy Bullock e122a9
  double m_newGapSize;
Jeremy Bullock e122a9
  int m_row;
Jeremy Bullock e122a9
  int m_column;
Jeremy Bullock e122a9
  TVectorImageP m_vi;
Jeremy Bullock e122a9
  std::vector<tfilledregioninf> m_oldFillInformation;</tfilledregioninf>
Jeremy Bullock e122a9
Jeremy Bullock e122a9
public:
Jeremy Bullock e122a9
  VectorGapSizeChangeUndo(double oldGapSize, double newGapSize,
Jeremy Bullock e122a9
                          TXshSimpleLevel *sl, const TFrameId &fid,
Jeremy Bullock e122a9
                          TVectorImageP vi,
Jeremy Bullock e122a9
                          std::vector<tfilledregioninf> oldFillInformation)</tfilledregioninf>
Jeremy Bullock e122a9
      : TToolUndo(sl, fid)
Jeremy Bullock e122a9
      , m_oldGapSize(oldGapSize)
Jeremy Bullock e122a9
      , m_newGapSize(newGapSize)
Jeremy Bullock e122a9
      , m_oldFillInformation(oldFillInformation)
Jeremy Bullock e122a9
      , m_vi(vi) {
Jeremy Bullock e122a9
    TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
    if (app) {
Jeremy Bullock e122a9
      m_row    = app->getCurrentFrame()->getFrame();
Jeremy Bullock e122a9
      m_column = app->getCurrentColumn()->getColumnIndex();
Jeremy Bullock e122a9
    }
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  void undo() const override {
Jeremy Bullock e122a9
    TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
    if (!app || !m_level) return;
Jeremy Bullock e122a9
    app->getCurrentLevel()->setLevel(m_level.getPointer());
Jeremy Bullock e122a9
    if (app->getCurrentFrame()->isEditingScene()) {
Jeremy Bullock e122a9
      app->getCurrentFrame()->setFrame(m_row);
Jeremy Bullock e122a9
      app->getCurrentColumn()->setColumnIndex(m_column);
Jeremy Bullock e122a9
    } else
Jeremy Bullock e122a9
      app->getCurrentFrame()->setFid(m_frameId);
Jeremy Bullock e122a9
Jeremy Bullock e122a9
    m_vi->setAutocloseTolerance(m_oldGapSize);
Jeremy Bullock e122a9
    int count = m_vi->getStrokeCount();
Jeremy Bullock e122a9
    std::vector<int> v(count);</int>
Jeremy Bullock e122a9
    int i;
Jeremy Bullock e122a9
    for (i = 0; i < (int)count; i++) v[i] = i;
Jeremy Bullock e122a9
    m_vi->notifyChangedStrokes(v, std::vector<tstroke *="">(), false);</tstroke>
Jeremy Bullock e122a9
    if (m_vi->isComputedRegionAlmostOnce()) m_vi->findRegions();
Jeremy Bullock e122a9
    if (m_oldFillInformation.size()) {
Jeremy Bullock e122a9
      for (UINT j = 0; j < m_oldFillInformation.size(); j++) {
Jeremy Bullock e122a9
        TRegion *reg = m_vi->getRegion(m_oldFillInformation[j].m_regionId);
Jeremy Bullock e122a9
        if (reg) reg->setStyle(m_oldFillInformation[j].m_styleId);
Jeremy Bullock e122a9
      }
Jeremy Bullock e122a9
    }
Jeremy Bullock e122a9
    app->getCurrentXsheet()->notifyXsheetChanged();
Jeremy Bullock e122a9
    app->getCurrentTool()->notifyToolChanged();
Jeremy Bullock e122a9
    notifyImageChanged();
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  void redo() const override {
Jeremy Bullock e122a9
    TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
    if (!app || !m_level) return;
Jeremy Bullock e122a9
Jeremy Bullock e122a9
    app->getCurrentLevel()->setLevel(m_level.getPointer());
Jeremy Bullock e122a9
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Jeremy Bullock e122a9
    if (app->getCurrentFrame()->isEditingScene()) {
Jeremy Bullock e122a9
      app->getCurrentFrame()->setFrame(m_row);
Jeremy Bullock e122a9
      app->getCurrentColumn()->setColumnIndex(m_column);
Jeremy Bullock e122a9
    } else
Jeremy Bullock e122a9
      app->getCurrentFrame()->setFid(m_frameId);
Jeremy Bullock e122a9
Jeremy Bullock e122a9
    m_vi->setAutocloseTolerance(m_newGapSize);
Jeremy Bullock e122a9
    int count = m_vi->getStrokeCount();
Jeremy Bullock e122a9
    std::vector<int> v(count);</int>
Jeremy Bullock e122a9
    int i;
Jeremy Bullock e122a9
    for (i = 0; i < (int)count; i++) v[i] = i;
Jeremy Bullock e122a9
    m_vi->notifyChangedStrokes(v, std::vector<tstroke *="">(), false);</tstroke>
Jeremy Bullock e122a9
    app->getCurrentXsheet()->notifyXsheetChanged();
Jeremy Bullock e122a9
    app->getCurrentTool()->notifyToolChanged();
Jeremy Bullock e122a9
    notifyImageChanged();
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  void onAdd() override {}
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  int getSize() const override { return sizeof(*this); }
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  QString getToolName() override {
Jeremy Bullock e122a9
    return QString("Fill Tool: Set Gap Size ") + QString::number(m_newGapSize);
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
  int getHistoryType() override { return HistoryType::FillTool; }
Jeremy Bullock e122a9
};
Jeremy Bullock e122a9
Jeremy Bullock e122a9
//=============================================================================
Toshihiro Shimizu 890ddd
// RasterFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterFillUndo final : public TRasterUndo {
Shinya Kitaoka 120a6e
  FillParameters m_params;
Shinya Kitaoka 120a6e
  bool m_saveboxOnly;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  /*RasterFillUndo(TTileSetCM32 *tileSet, TPoint fillPoint,
Shinya Kitaoka 120a6e
                                                           int paintId, int
Shinya Kitaoka 120a6e
     fillDepth,
Shinya Kitaoka 120a6e
                                                           std::wstring
Shinya Kitaoka 120a6e
     fillType, bool isSegment,
Shinya Kitaoka 120a6e
                                                           bool selective, bool
Shinya Kitaoka 120a6e
     isShiftFill,
Shinya Kitaoka 120a6e
                                                           TXshSimpleLevel* sl,
Shinya Kitaoka 120a6e
     const TFrameId& fid)*/
Shinya Kitaoka 120a6e
  RasterFillUndo(TTileSetCM32 *tileSet, const FillParameters ¶ms,
Shinya Kitaoka 120a6e
                 TXshSimpleLevel *sl, const TFrameId &fid, bool saveboxOnly)
Shinya Kitaoka 120a6e
      : TRasterUndo(tileSet, sl, fid, false, false, 0)
Shinya Kitaoka 120a6e
      , m_params(params)
Shinya Kitaoka 120a6e
      , m_saveboxOnly(saveboxOnly) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    bool recomputeSavebox = false;
Shinya Kitaoka 120a6e
    TRasterCM32P r;
Shinya Kitaoka 120a6e
    if (m_saveboxOnly) {
Shinya Kitaoka 120a6e
      TRectD temp = image->getBBox();
Shinya Kitaoka 120a6e
      TRect ttemp = convert(temp);
Shinya Kitaoka 120a6e
      r           = image->getRaster()->extract(ttemp);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      r = image->getRaster();
Shinya Kitaoka 120a6e
    if (m_params.m_fillType == ALL || m_params.m_fillType == AREAS) {
Shinya Kitaoka 120a6e
      if (m_params.m_shiftFill) {
Shinya Kitaoka 120a6e
        FillParameters aux(m_params);
Shinya Kitaoka 120a6e
        aux.m_styleId    = (m_params.m_styleId == 0) ? 1 : 0;
Shinya Kitaoka 120a6e
        recomputeSavebox = fill(r, aux);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      recomputeSavebox = fill(r, m_params);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_params.m_fillType == ALL || m_params.m_fillType == LINES) {
Shinya Kitaoka 120a6e
      if (m_params.m_segment)
Shinya Kitaoka 120a6e
        inkSegment(r, m_params.m_p, m_params.m_styleId, 2.51, true);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        inkFill(r, m_params.m_p, m_params.m_styleId, 2);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (recomputeSavebox) ToolUtils::updateSaveBox();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
      notifyImageChanged();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  int getSize() const override {
Shinya Kitaoka 38fd86
    return sizeof(*this) + TRasterUndo::getSize();
Shinya Kitaoka 38fd86
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override {
Shinya Kitaoka 120a6e
    return QString("Fill Tool : %1")
Shinya Kitaoka 120a6e
        .arg(QString::fromStdWString(m_params.m_fillType));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::FillTool; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RasterRectFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterRectFillUndo final : public TRasterUndo {
Shinya Kitaoka 120a6e
  TRect m_fillArea;
Shinya Kitaoka 120a6e
  int m_paintId;
Shinya Kitaoka 120a6e
  std::wstring m_colorType;
Shinya Kitaoka 120a6e
  TStroke *m_s;
Shinya Kitaoka 120a6e
  bool m_onlyUnfilled;
Shinya Kitaoka 120a6e
  TPalette *m_palette;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ~RasterRectFillUndo() {
Shinya Kitaoka 120a6e
    if (m_s) delete m_s;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RasterRectFillUndo(TTileSetCM32 *tileSet, TStroke *s, TRect fillArea,
Shinya Kitaoka 120a6e
                     int paintId, TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                     std::wstring colorType, bool onlyUnfilled,
Shinya Kitaoka 120a6e
                     const TFrameId &fid, TPalette *palette)
Shinya Kitaoka 120a6e
      : TRasterUndo(tileSet, level, fid, false, false, 0)
Shinya Kitaoka 120a6e
      , m_fillArea(fillArea)
Shinya Kitaoka 120a6e
      , m_paintId(paintId)
Shinya Kitaoka 120a6e
      , m_colorType(colorType)
Shinya Kitaoka 120a6e
      , m_onlyUnfilled(onlyUnfilled)
Shinya Kitaoka 120a6e
      , m_palette(palette) {
Shinya Kitaoka 120a6e
    m_s = s ? new TStroke(*s) : 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    TRasterCM32P ras = image->getRaster();
Shinya Kitaoka 120a6e
    AreaFiller filler(ras);
Shinya Kitaoka 120a6e
    if (!m_s)
Shinya Kitaoka 120a6e
      filler.rectFill(m_fillArea, m_paintId, m_onlyUnfilled,
Shinya Kitaoka 120a6e
                      m_colorType != LINES, m_colorType != AREAS);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      filler.strokeFill(m_s, m_paintId, m_onlyUnfilled, m_colorType != LINES,
Shinya Kitaoka 120a6e
                        m_colorType != AREAS);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_palette) {
Shinya Kitaoka 120a6e
      TRect rect   = m_fillArea;
Shinya Kitaoka 120a6e
      TRect bounds = ras->getBounds();
Shinya Kitaoka 120a6e
      if (bounds.overlaps(rect)) {
Shinya Kitaoka 120a6e
        rect *= bounds;
Shinya Kitaoka 120a6e
        const TTileSetCM32::Tile *tile =
Shinya Kitaoka 120a6e
            m_tiles->getTile(m_tiles->getTileCount() - 1);
Shinya Kitaoka 120a6e
        TRasterCM32P rbefore;
Shinya Kitaoka 120a6e
        tile->getRaster(rbefore);
Shinya Kitaoka 120a6e
        fillautoInks(ras, rect, rbefore, m_palette);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
      notifyImageChanged();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    int size =
Shinya Kitaoka 120a6e
        m_s ? m_s->getControlPointCount() * sizeof(TThickPoint) + 100 : 0;
Shinya Kitaoka 120a6e
    return sizeof(*this) + TRasterUndo::getSize() + size;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override {
Shinya Kitaoka 120a6e
    return QString("Fill Tool : %1").arg(QString::fromStdWString(m_colorType));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  int getHistoryType() override { return HistoryType::FillTool; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RasterRectAutoFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterRectAutoFillUndo final : public TRasterUndo {
Shinya Kitaoka 120a6e
  TRect m_rectToFill;
Shinya Kitaoka 120a6e
  TFrameId m_fidToLearn;
Shinya Kitaoka 120a6e
  bool m_onlyUnfilled;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ~RasterRectAutoFillUndo() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RasterRectAutoFillUndo(TTileSetCM32 *tileSet, const TRect &rectToFill,
Shinya Kitaoka 120a6e
                         TXshSimpleLevel *level, bool onlyUnfilled,
Shinya Kitaoka 120a6e
                         const TFrameId ¤tFid, const TFrameId &fidToLearn)
Shinya Kitaoka 120a6e
      : TRasterUndo(tileSet, level, currentFid, false, false, 0)
Shinya Kitaoka 120a6e
      , m_rectToFill(rectToFill)
Shinya Kitaoka 120a6e
      , m_onlyUnfilled(onlyUnfilled)
Shinya Kitaoka 120a6e
      , m_fidToLearn(fidToLearn) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TToonzImageP image        = getImage();
Shinya Kitaoka 120a6e
    TToonzImageP imageToLearn = m_level->getFrame(m_fidToLearn, false);
Shinya Kitaoka 120a6e
    if (!image || !imageToLearn) return;
Shinya Kitaoka 120a6e
    rect_autofill_learn(imageToLearn, m_rectToFill.x0, m_rectToFill.y0,
Shinya Kitaoka 120a6e
                        m_rectToFill.x1, m_rectToFill.y1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTileSetCM32 tileSet(image->getRaster()->getSize());
Shinya Kitaoka 120a6e
    bool recomputeBBox = rect_autofill_apply(
Shinya Kitaoka 120a6e
        image, m_rectToFill.x0, m_rectToFill.y0, m_rectToFill.x1,
Shinya Kitaoka 120a6e
        m_rectToFill.y1, m_onlyUnfilled, &tileSet);
Shinya Kitaoka 120a6e
    if (recomputeBBox) ToolUtils::updateSaveBox();
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
      notifyImageChanged();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 38fd86
  int getSize() const override {
Shinya Kitaoka 38fd86
    return sizeof(*this) + TRasterUndo::getSize();
Shinya Kitaoka 38fd86
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RasterStrokeAutoFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterStrokeAutoFillUndo final : public TRasterUndo {
Shinya Kitaoka 120a6e
  TTileSetCM32 *m_tileSet;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ~RasterStrokeAutoFillUndo() {
Shinya Kitaoka 120a6e
    if (m_tileSet) delete m_tileSet;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  RasterStrokeAutoFillUndo(TTileSetCM32 *tileSet, TXshSimpleLevel *level,
Shinya Kitaoka 120a6e
                           const TFrameId ¤tFid)
Shinya Kitaoka 120a6e
      : TRasterUndo(tileSet, level, currentFid, false, false, 0)
Shinya Kitaoka 120a6e
      , m_tileSet(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void setTileSet(TTileSetCM32 *tileSet) { m_tileSet = tileSet; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ToonzImageUtils::paste(image, m_tileSet);
Shinya Kitaoka 120a6e
    ToolUtils::updateSaveBox(m_level, m_frameId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
      notifyImageChanged();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    return sizeof(*this) + TRasterUndo::getSize() + m_tileSet->getMemorySize();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// RasterRectAutoFillUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class VectorAutoFillUndo final : public TToolUndo {
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> *m_regionFillInformation;</tfilledregioninf>
Shinya Kitaoka 120a6e
  TRectD m_selectionArea;
Shinya Kitaoka 120a6e
  TStroke *m_selectingStroke;
Shinya Kitaoka 120a6e
  bool m_unpaintedOnly;
Shinya Kitaoka 120a6e
  TFrameId m_onionFid;
Shinya Kitaoka 120a6e
  int m_row;
Shinya Kitaoka 120a6e
  int m_column;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  ~VectorAutoFillUndo() {
Shinya Kitaoka 120a6e
    if (m_regionFillInformation) delete m_regionFillInformation;
Shinya Kitaoka 120a6e
    if (m_selectingStroke) delete m_selectingStroke;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VectorAutoFillUndo(std::vector<tfilledregioninf> *regionFillInformation,</tfilledregioninf>
Shinya Kitaoka 120a6e
                     TRectD selectionArea, TStroke *selectingStroke,
Shinya Kitaoka 120a6e
                     bool unpaintedOnly, TXshSimpleLevel *sl,
Shinya Kitaoka 120a6e
                     const TFrameId &fid, const TFrameId &onionFid)
Shinya Kitaoka 120a6e
      : TToolUndo(sl, fid)
Shinya Kitaoka 120a6e
      , m_regionFillInformation(regionFillInformation)
Shinya Kitaoka 120a6e
      , m_selectionArea(selectionArea)
Shinya Kitaoka 120a6e
      , m_unpaintedOnly(unpaintedOnly)
Shinya Kitaoka 120a6e
      , m_onionFid(onionFid) {
Shinya Kitaoka 120a6e
    m_selectingStroke = selectingStroke ? new TStroke(*selectingStroke) : 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    ;
Shinya Kitaoka 120a6e
    assert(!!img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
    if (m_regionFillInformation) {
Shinya Kitaoka 120a6e
      for (UINT i = 0; i < m_regionFillInformation->size(); i++) {
Shinya Kitaoka 120a6e
        TRegion *reg = img->getRegion((*m_regionFillInformation)[i].m_regionId);
Shinya Kitaoka 120a6e
        if (reg) reg->setStyle((*m_regionFillInformation)[i].m_styleId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TVectorImageP img = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TVectorImageP onionImg = m_level->getFrame(m_onionFid, false);
Shinya Kitaoka 120a6e
    if (!onionImg) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_selectingStroke) {
Shinya Kitaoka 120a6e
      stroke_autofill_learn(onionImg, m_selectingStroke);
Shinya Kitaoka 120a6e
      stroke_autofill_apply(img, m_selectingStroke, m_unpaintedOnly);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      rect_autofill_learn(onionImg, m_selectionArea);
Shinya Kitaoka 120a6e
      rect_autofill_apply(img, m_selectionArea, m_unpaintedOnly);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    app->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
shun-iwasawa 3f2d1d
    int size = m_selectingStroke ? m_selectingStroke->getControlPointCount() *
shun-iwasawa 3f2d1d
                                           sizeof(TThickPoint) +
shun-iwasawa 3f2d1d
                                       100
shun-iwasawa 3f2d1d
                                 : 0;
Shinya Kitaoka 120a6e
    return sizeof(*this) +
Shinya Kitaoka 120a6e
           m_regionFillInformation->capacity() *
Shinya Kitaoka 120a6e
               sizeof(m_regionFillInformation) +
Shinya Kitaoka 120a6e
           500 + size;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void doRectAutofill(const TImageP &img, const TRectD selectingRect,
Shinya Kitaoka 120a6e
                    bool onlyUnfilled, const OnionSkinMask &osMask,
Shinya Kitaoka 120a6e
                    TXshSimpleLevel *sl, const TFrameId ¤tFid) {
Shinya Kitaoka 120a6e
  TToonzImageP ti(img);
Shinya Kitaoka 120a6e
  TVectorImageP vi(img);
Shinya Kitaoka 120a6e
  if (!img || !sl) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> rows;</int>
Shinya Kitaoka 120a6e
  osMask.getAll(sl->guessIndex(currentFid), rows);
Shinya Kitaoka 120a6e
  if (rows.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFrameId onionFid;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)rows.size(); i++) {
Shinya Kitaoka 120a6e
    const TFrameId &app = sl->index2fid(rows[i]);
Shinya Kitaoka 120a6e
    if (app > currentFid) break;
Shinya Kitaoka 120a6e
    onionFid = app;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (onionFid.isEmptyFrame()) onionFid = sl->index2fid(rows[0]);
Shinya Kitaoka 120a6e
  if (onionFid.isEmptyFrame() || onionFid == currentFid || !sl->isFid(onionFid))
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  if (ti) {
Shinya Kitaoka 120a6e
    TRect rect = ToonzImageUtils::convertWorldToRaster(selectingRect, ti);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TToonzImageP onionImg(sl->getFrame(onionFid, false));
Shinya Kitaoka 120a6e
    if (!onionImg) return;
Shinya Kitaoka 120a6e
    TRect workRect = rect * ti->getRaster()->getBounds();
Shinya Kitaoka 120a6e
    if (workRect.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rect_autofill_learn(onionImg, workRect.x0, workRect.y0, workRect.x1,
Shinya Kitaoka 120a6e
                        workRect.y1);
Shinya Kitaoka 120a6e
    TTileSetCM32 *tileSet = new TTileSetCM32(ti->getRaster()->getSize());
Shinya Kitaoka 120a6e
    bool recomputeBBox =
Shinya Kitaoka 120a6e
        rect_autofill_apply(ti, workRect.x0, workRect.y0, workRect.x1,
Shinya Kitaoka 120a6e
                            workRect.y1, onlyUnfilled, tileSet);
Shinya Kitaoka 120a6e
    if (recomputeBBox) ToolUtils::updateSaveBox();
Shinya Kitaoka 120a6e
    if (tileSet->getTileCount() > 0)
Shinya Kitaoka 120a6e
      TUndoManager::manager()->add(new RasterRectAutoFillUndo(
Shinya Kitaoka 120a6e
          tileSet, workRect, sl, onlyUnfilled, currentFid, onionFid));
Shinya Kitaoka 120a6e
  } else if (vi) {
Shinya Kitaoka 120a6e
    TVectorImageP onionImg(sl->getFrame(onionFid, false));
Shinya Kitaoka 120a6e
    if (!onionImg) return;
Shinya Kitaoka 120a6e
    std::vector<tfilledregioninf> *regionFillInformation =</tfilledregioninf>
Shinya Kitaoka 120a6e
        new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
    ImageUtils::getFillingInformationInArea(vi, *regionFillInformation,
Shinya Kitaoka 120a6e
                                            selectingRect);
Shinya Kitaoka 120a6e
    onionImg->findRegions();
Shinya Kitaoka 120a6e
    vi->findRegions();
Shinya Kitaoka 120a6e
    rect_autofill_learn(onionImg, selectingRect);
Shinya Kitaoka 120a6e
    bool hasFilled = rect_autofill_apply(vi, selectingRect, onlyUnfilled);
Shinya Kitaoka 120a6e
    if (hasFilled)
Shinya Kitaoka 120a6e
      TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
          new VectorAutoFillUndo(regionFillInformation, selectingRect, 0,
Shinya Kitaoka 120a6e
                                 onlyUnfilled, sl, currentFid, onionFid));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void doStrokeAutofill(const TImageP &img, TStroke *selectingStroke,
Shinya Kitaoka 120a6e
                      bool onlyUnfilled, const OnionSkinMask &osMask,
Shinya Kitaoka 120a6e
                      TXshSimpleLevel *sl, const TFrameId ¤tFid) {
Shinya Kitaoka 120a6e
  TToonzImageP ti(img);
Shinya Kitaoka 120a6e
  TVectorImageP vi(img);
Shinya Kitaoka 120a6e
  if (!img || !sl) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> rows;</int>
Shinya Kitaoka 120a6e
  osMask.getAll(sl->guessIndex(currentFid), rows);
Shinya Kitaoka 120a6e
  if (rows.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFrameId onionFid;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)rows.size(); i++) {
Shinya Kitaoka 120a6e
    const TFrameId &app = sl->index2fid(rows[i]);
Shinya Kitaoka 120a6e
    if (app > currentFid) break;
Shinya Kitaoka 120a6e
    onionFid = app;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (onionFid.isEmptyFrame()) onionFid = sl->index2fid(rows[0]);
Shinya Kitaoka 120a6e
  if (onionFid.isEmptyFrame() || onionFid == currentFid || !sl->isFid(onionFid))
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  if (ti) {
Shinya Kitaoka 120a6e
    TToonzImageP onionImg(sl->getFrame(onionFid, false));
Shinya Kitaoka 120a6e
    if (!onionImg) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterCM32P ras = onionImg->getRaster();
Shinya Kitaoka 120a6e
    TPointD center   = ras->getCenterD();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPoint pos;
Shinya Kitaoka 120a6e
    TRaster32P image =
Shinya Kitaoka 120a6e
        convertStrokeToImage(selectingStroke, ras->getBounds(), pos);
Shinya Kitaoka 120a6e
    TRect bbox = (image->getBounds() + pos).enlarge(2);
Shinya Kitaoka 120a6e
    pos        = bbox.getP00();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterCM32P onionAppRas = ras->extract(bbox)->clone();
Shinya Kitaoka 120a6e
    TRasterCM32P tiAppRas    = ti->getRaster()->extract(bbox)->clone();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRect workRect = onionAppRas->getBounds().enlarge(-1);
Shinya Kitaoka 120a6e
    TToonzImageP onionApp(onionAppRas, workRect);
Shinya Kitaoka 120a6e
    TToonzImageP tiApp(tiAppRas, workRect);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ToonzImageUtils::eraseImage(onionApp, image, TPoint(2, 2), true, true, true,
Shinya Kitaoka 120a6e
                                false, 1);
Shinya Kitaoka 120a6e
    ToonzImageUtils::eraseImage(tiApp, image, TPoint(2, 2), true, true, true,
Shinya Kitaoka 120a6e
                                false, 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rect_autofill_learn(onionApp, workRect.x0, workRect.y0, workRect.x1,
Shinya Kitaoka 120a6e
                        workRect.y1);
Shinya Kitaoka 120a6e
    TTileSetCM32 *tileSet = new TTileSetCM32(ti->getRaster()->getSize());
Shinya Kitaoka 120a6e
    bool recomputeBBox =
Shinya Kitaoka 120a6e
        rect_autofill_apply(tiApp, workRect.x0, workRect.y0, workRect.x1,
Shinya Kitaoka 120a6e
                            workRect.y1, onlyUnfilled, tileSet);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    delete tileSet;
Shinya Kitaoka 120a6e
    tileSet = new TTileSetCM32(ti->getRaster()->getSize());
Shinya Kitaoka 120a6e
    tileSet->add(ti->getRaster(), bbox);
Shinya Kitaoka 120a6e
    RasterStrokeAutoFillUndo *undo =
Shinya Kitaoka 120a6e
        new RasterStrokeAutoFillUndo(tileSet, sl, currentFid);
Shinya Kitaoka 120a6e
    TRop::over(ti->getRaster(), tiAppRas, pos);
Shinya Kitaoka 120a6e
    TTileSetCM32 *newTileSet = new TTileSetCM32(ti->getRaster()->getSize());
Shinya Kitaoka 120a6e
    newTileSet->add(ti->getRaster(), bbox);
Shinya Kitaoka 120a6e
    undo->setTileSet(newTileSet);
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  } else if (vi) {
Shinya Kitaoka 120a6e
    TVectorImageP onionImg(sl->getFrame(onionFid, false));
Shinya Kitaoka 120a6e
    if (!onionImg) return;
Shinya Kitaoka 120a6e
    std::vector<tfilledregioninf> *regionFillInformation =</tfilledregioninf>
Shinya Kitaoka 120a6e
        new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
    ImageUtils::getFillingInformationInArea(vi, *regionFillInformation,
Shinya Kitaoka 120a6e
                                            selectingStroke->getBBox());
Shinya Kitaoka 120a6e
    onionImg->findRegions();
Shinya Kitaoka 120a6e
    vi->findRegions();
Shinya Kitaoka 120a6e
    stroke_autofill_learn(onionImg, selectingStroke);
Shinya Kitaoka 120a6e
    bool hasFilled = stroke_autofill_apply(vi, selectingStroke, onlyUnfilled);
Shinya Kitaoka 120a6e
    if (hasFilled)
Shinya Kitaoka 120a6e
      TUndoManager::manager()->add(new VectorAutoFillUndo(
Shinya Kitaoka 120a6e
          regionFillInformation, TRectD(), selectingStroke, onlyUnfilled, sl,
Shinya Kitaoka 120a6e
          currentFid, onionFid));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// fillRectWithUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool inline hasAutoInks(const TPalette *plt) {
Shinya Kitaoka 120a6e
  for (int i = 0; i < plt->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    if (plt->getStyle(i)->getFlags() != 0) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void fillAreaWithUndo(const TImageP &img, const TRectD &area, TStroke *stroke,
Shinya Kitaoka 120a6e
                      bool onlyUnfilled, std::wstring colorType,
shun-iwasawa 43640b
                      TXshSimpleLevel *sl, const TFrameId &fid, int cs,
shun-iwasawa 43640b
                      bool autopaintLines) {
Shinya Kitaoka 120a6e
  TRectD selArea = stroke ? stroke->getBBox() : area;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TToonzImageP ti = img) {
Shinya Kitaoka 120a6e
    // allargo di 1 la savebox, perche cosi' il rectfill di tutta l'immagine fa
Shinya Kitaoka 120a6e
    // una sola fillata
Shinya Kitaoka 120a6e
    TRect enlargedSavebox =
Shinya Kitaoka 120a6e
        ti->getSavebox().enlarge(1) * TRect(TPoint(0, 0), ti->getSize());
Shinya Kitaoka 120a6e
    TRect rasterFillArea =
Shinya Kitaoka 120a6e
        ToonzImageUtils::convertWorldToRaster(selArea, ti) * enlargedSavebox;
Shinya Kitaoka 120a6e
    if (rasterFillArea.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRasterCM32P ras = ti->getRaster();
Shinya Kitaoka 120a6e
    /*-- tileSetでFill範囲のRectをUndoに格納しておく --*/
Shinya Kitaoka 120a6e
    TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
Shinya Kitaoka 120a6e
    tileSet->add(ras, rasterFillArea);
Shinya Kitaoka 120a6e
    AreaFiller filler(ti->getRaster());
shun-iwasawa 4293f9
    if (!stroke) {
shun-iwasawa 4293f9
      bool ret = filler.rectFill(rasterFillArea, cs, onlyUnfilled,
shun-iwasawa 4293f9
                                 colorType != LINES, colorType != AREAS);
shun-iwasawa 4293f9
      if (!ret) {
shun-iwasawa 4293f9
        delete tileSet;
shun-iwasawa 4293f9
        return;
shun-iwasawa 4293f9
      }
shun-iwasawa 4293f9
    } else
Shinya Kitaoka 120a6e
      filler.strokeFill(stroke, cs, onlyUnfilled, colorType != LINES,
Shinya Kitaoka 120a6e
                        colorType != AREAS);
Shinya Kitaoka 120a6e
shun-iwasawa 43640b
    TPalette *plt = ti->getPalette();
shun-iwasawa 43640b
shun-iwasawa 43640b
    // !autopaintLines will temporary disable autopaint line feature
shun-iwasawa 43640b
    if ((plt && !hasAutoInks(plt)) || !autopaintLines) plt = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (plt) {
Shinya Kitaoka 120a6e
      TRect rect   = rasterFillArea;
Shinya Kitaoka 120a6e
      TRect bounds = ras->getBounds();
Shinya Kitaoka 120a6e
      if (bounds.overlaps(rect)) {
Shinya Kitaoka 120a6e
        rect *= bounds;
Shinya Kitaoka 120a6e
        const TTileSetCM32::Tile *tile =
Shinya Kitaoka 120a6e
            tileSet->getTile(tileSet->getTileCount() - 1);
Shinya Kitaoka 120a6e
        TRasterCM32P rbefore;
Shinya Kitaoka 120a6e
        tile->getRaster(rbefore);
Shinya Kitaoka 120a6e
        fillautoInks(ras, rect, rbefore, plt);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ToolUtils::updateSaveBox(sl, fid);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
        new RasterRectFillUndo(tileSet, stroke, rasterFillArea, cs, sl,
Shinya Kitaoka 120a6e
                               colorType, onlyUnfilled, fid, plt));
Shinya Kitaoka 120a6e
  } else if (TVectorImageP vi = img) {
Shinya Kitaoka 120a6e
    TPalette *palette = vi->getPalette();
Shinya Kitaoka 120a6e
    assert(palette);
Shinya Kitaoka 120a6e
    const TColorStyle *style = palette->getStyle(cs);
Shinya Kitaoka 120a6e
    // if( !style->isRegionStyle() )
Shinya Kitaoka 120a6e
    // return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    vi->findRegions();
Shinya Kitaoka 120a6e
shun-iwasawa 3f2d1d
    std::vector<tfilledregioninf> *regionFillInformation    = 0;</tfilledregioninf>
Shinya Kitaoka 120a6e
    std::vector<std::pair<int, int="">> *strokeFillInformation = 0;</std::pair<int,>
Shinya Kitaoka 120a6e
    if (colorType != LINES) {
Shinya Kitaoka 120a6e
      regionFillInformation = new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
      ImageUtils::getFillingInformationInArea(vi, *regionFillInformation,
Shinya Kitaoka 120a6e
                                              selArea);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (colorType != AREAS) {
Shinya Kitaoka 120a6e
      strokeFillInformation = new std::vector<std::pair<int, int="">>;</std::pair<int,>
Shinya Kitaoka 120a6e
      ImageUtils::getStrokeStyleInformationInArea(vi, *strokeFillInformation,
Shinya Kitaoka 120a6e
                                                  selArea);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    VectorRectFillUndo *fUndo =
Shinya Kitaoka 120a6e
        new VectorRectFillUndo(regionFillInformation, strokeFillInformation,
Shinya Kitaoka 120a6e
                               selArea, stroke, cs, onlyUnfilled, sl, fid);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QMutexLocker lock(vi->getMutex());
Shinya Kitaoka 120a6e
    if (vi->selectFill(area, stroke, cs, onlyUnfilled, colorType != LINES,
Shinya Kitaoka 120a6e
                       colorType != AREAS))
Shinya Kitaoka 120a6e
      TUndoManager::manager()->add(fUndo);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      delete fUndo;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// doFill
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void doFill(const TImageP &img, const TPointD &pos, FillParameters ¶ms,
shun-iwasawa 43640b
            bool isShiftFill, TXshSimpleLevel *sl, const TFrameId &fid,
shun-iwasawa 43640b
            bool autopaintLines) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (TToonzImageP ti = TToonzImageP(img)) {
Shinya Kitaoka 120a6e
    TPoint offs(0, 0);
Shinya Kitaoka 120a6e
    TRasterCM32P ras = ti->getRaster();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (Preferences::instance()->getFillOnlySavebox()) {
Shinya Kitaoka 120a6e
      TRectD bbox = ti->getBBox();
Shinya Kitaoka 120a6e
      TRect ibbox = convert(bbox);
Shinya Kitaoka 120a6e
      offs        = ibbox.getP00();
Shinya Kitaoka 120a6e
      ras         = ti->getRaster()->extract(ibbox);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool recomputeSavebox = false;
Shinya Kitaoka 120a6e
    TPalette *plt         = ti->getPalette();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!ras.getPointer() || ras->isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ras->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTileSetCM32 *tileSet = new TTileSetCM32(ras->getSize());
Shinya Kitaoka 120a6e
    TTileSaverCM32 tileSaver(ras, tileSet);
Shinya Kitaoka 120a6e
    TDimension imageSize = ti->getSize();
Shinya Kitaoka 120a6e
    TPointD p(imageSize.lx % 2 ? 0.0 : 0.5, imageSize.ly % 2 ? 0.0 : 0.5);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*-- params.m_p = convert(pos-p)では、マイナス座標でずれが生じる --*/
Shinya Kitaoka 120a6e
    TPointD tmp_p = pos - p;
Shinya Kitaoka 120a6e
    params.m_p = TPoint((int)floor(tmp_p.x + 0.5), (int)floor(tmp_p.y + 0.5));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    params.m_p += ti->getRaster()->getCenter();
Shinya Kitaoka 120a6e
    params.m_p -= offs;
Shinya Kitaoka 120a6e
    params.m_shiftFill = isShiftFill;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TRect rasRect(ras->getSize());
Shinya Kitaoka 120a6e
    if (!rasRect.contains(params.m_p)) {
Shinya Kitaoka 120a6e
      ras->unlock();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
shun-iwasawa 43640b
    // !autoPaintLines will temporary disable autopaint line feature
shun-iwasawa 43640b
    if (plt && hasAutoInks(plt) && autopaintLines) params.m_palette = plt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (params.m_fillType == ALL || params.m_fillType == AREAS) {
Shinya Kitaoka 120a6e
      if (isShiftFill) {
Shinya Kitaoka 120a6e
        FillParameters aux(params);
Shinya Kitaoka 120a6e
        aux.m_styleId    = (params.m_styleId == 0) ? 1 : 0;
Shinya Kitaoka 120a6e
        recomputeSavebox = fill(ras, aux, &tileSaver);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      recomputeSavebox = fill(ras, params, &tileSaver);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (params.m_fillType == ALL || params.m_fillType == LINES) {
Shinya Kitaoka 120a6e
      if (params.m_segment)
Shinya Kitaoka 120a6e
        inkSegment(ras, params.m_p, params.m_styleId, 2.51, true, &tileSaver);
Shinya Kitaoka 120a6e
      else if (!params.m_segment)
Shinya Kitaoka 120a6e
        inkFill(ras, params.m_p, params.m_styleId, 2, &tileSaver);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (tileSaver.getTileSet()->getTileCount() != 0) {
Shinya Kitaoka 120a6e
      static int count = 0;
Shinya Kitaoka 120a6e
      TSystem::outputDebug("FILL" + std::to_string(count++) + "\n");
Shinya Kitaoka 120a6e
      if (offs != TPoint())
Shinya Kitaoka 120a6e
        for (int i = 0; i < tileSet->getTileCount(); i++) {
Shinya Kitaoka 120a6e
          TTileSet::Tile *t = tileSet->editTile(i);
Shinya Kitaoka 120a6e
          t->m_rasterBounds = t->m_rasterBounds + offs;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      TUndoManager::manager()->add(
Shinya Kitaoka 120a6e
          new RasterFillUndo(tileSet, params, sl, fid,
Shinya Kitaoka 120a6e
                             Preferences::instance()->getFillOnlySavebox()));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // al posto di updateFrame:
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TXshLevel *xl = app->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
    if (!xl) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TXshSimpleLevel *sl = xl->getSimpleLevel();
Shinya Kitaoka 120a6e
    sl->getProperties()->setDirtyFlag(true);
Shinya Kitaoka 120a6e
    if (recomputeSavebox &&
Shinya Kitaoka 120a6e
        Preferences::instance()->isMinimizeSaveboxAfterEditing())
Shinya Kitaoka 120a6e
      ToolUtils::updateSaveBox(sl, fid);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ras->unlock();
Shinya Kitaoka 120a6e
  } else if (TVectorImageP vi = TImageP(img)) {
Shinya Kitaoka 120a6e
    int oldStyleId;
Shinya Kitaoka 120a6e
    QMutexLocker lock(vi->getMutex());
Shinya Kitaoka 120a6e
    /*if(params.m_fillType==ALL || params.m_fillType==AREAS)
Shinya Kitaoka 120a6e
vi->computeRegion(pos, params.m_styleId);*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((oldStyleId = vectorFill(vi, params.m_fillType, pos, params.m_styleId,
Shinya Kitaoka 120a6e
                                 params.m_emptyOnly)) != -1)
Shinya Kitaoka 120a6e
      TUndoManager::manager()->add(new VectorFillUndo(
Shinya Kitaoka 120a6e
          params.m_styleId, oldStyleId, params.m_fillType, pos, sl, fid));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TTool *t = app->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
  if (t) t->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// SequencePainter
Toshihiro Shimizu 890ddd
// da spostare in toolutils?
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class SequencePainter {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  virtual void process(TImageP img /*, TImageLocation &imgloc*/, double t,
Shinya Kitaoka 120a6e
                       TXshSimpleLevel *sl, const TFrameId &fid) = 0;
Shinya Kitaoka 120a6e
  void processSequence(TXshSimpleLevel *sl, TFrameId firstFid,
Shinya Kitaoka 120a6e
                       TFrameId lastFid);
Shinya Kitaoka 120a6e
  virtual ~SequencePainter() {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void SequencePainter::processSequence(TXshSimpleLevel *sl, TFrameId firstFid,
Shinya Kitaoka 120a6e
                                      TFrameId lastFid) {
Shinya Kitaoka 120a6e
  if (!sl) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool backward = false;
Shinya Kitaoka 120a6e
  if (firstFid > lastFid) {
otakuto ed7dcd
    std::swap(firstFid, lastFid);
Shinya Kitaoka 120a6e
    backward = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(firstFid <= lastFid);
Shinya Kitaoka 120a6e
  std::vector<tframeid> allFids;</tframeid>
Shinya Kitaoka 120a6e
  sl->getFids(allFids);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tframeid>::iterator i0 = allFids.begin();</tframeid>
Shinya Kitaoka 120a6e
  while (i0 != allFids.end() && *i0 < firstFid) i0++;
Shinya Kitaoka 120a6e
  if (i0 == allFids.end()) return;
Shinya Kitaoka 120a6e
  std::vector<tframeid>::iterator i1 = i0;</tframeid>
Shinya Kitaoka 120a6e
  while (i1 != allFids.end() && *i1 <= lastFid) i1++;
Shinya Kitaoka 120a6e
  assert(i0 < i1);
Shinya Kitaoka 120a6e
  std::vector<tframeid> fids(i0, i1);</tframeid>
Shinya Kitaoka 120a6e
  int m = fids.size();
Shinya Kitaoka 120a6e
  assert(m > 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndoManager::manager()->beginBlock();
Shinya Kitaoka 120a6e
  for (int i = 0; i < m; ++i) {
Shinya Kitaoka 120a6e
    TFrameId fid = fids[i];
Shinya Kitaoka 120a6e
    assert(firstFid <= fid && fid <= lastFid);
Shinya Kitaoka 120a6e
    TImageP img = sl->getFrame(fid, true);
Shinya Kitaoka 120a6e
    double t    = m > 1 ? (double)i / (double)(m - 1) : 0.5;
Shinya Kitaoka 120a6e
    process(img, backward ? 1 - t : t, sl, fid);
Shinya Kitaoka 120a6e
    // Setto il fid come corrente per notificare il cambiamento dell'immagine
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (app) {
Shinya Kitaoka 120a6e
      if (app->getCurrentFrame()->isEditingScene())
Shinya Kitaoka 120a6e
        app->getCurrentFrame()->setFrame(fid.getNumber());
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        app->getCurrentFrame()->setFid(fid);
Shinya Kitaoka 120a6e
      TTool *tool = app->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
      if (tool) tool->notifyImageChanged(fid);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TUndoManager::manager()->endBlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MultiAreaFiller : SequencePainter
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MultiAreaFiller final : public SequencePainter {
Shinya Kitaoka 120a6e
  TRectD m_firstRect, m_lastRect;
Shinya Kitaoka 120a6e
  bool m_unfilledOnly;
Shinya Kitaoka 120a6e
  std::wstring m_colorType;
Shinya Kitaoka 120a6e
  TVectorImageP m_firstImage, m_lastImage;
Shinya Kitaoka 120a6e
  int m_styleIndex;
shun-iwasawa 43640b
  bool m_autopaintLines;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MultiAreaFiller(const TRectD &firstRect, const TRectD &lastRect,
shun-iwasawa 43640b
                  bool unfilledOnly, std::wstring colorType, int styleIndex,
shun-iwasawa 43640b
                  bool autopaintLines)
Shinya Kitaoka 120a6e
      : m_firstRect(firstRect)
Shinya Kitaoka 120a6e
      , m_lastRect(lastRect)
Shinya Kitaoka 120a6e
      , m_unfilledOnly(unfilledOnly)
Shinya Kitaoka 120a6e
      , m_colorType(colorType)
Shinya Kitaoka 120a6e
      , m_firstImage()
Shinya Kitaoka 120a6e
      , m_lastImage()
shun-iwasawa 43640b
      , m_styleIndex(styleIndex)
shun-iwasawa 43640b
      , m_autopaintLines(autopaintLines) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~MultiAreaFiller() {
Shinya Kitaoka 120a6e
    if (m_firstImage) {
Shinya Kitaoka 120a6e
      m_firstImage->removeStroke(0);
Shinya Kitaoka 120a6e
      m_lastImage->removeStroke(0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  MultiAreaFiller(TStroke *&firstStroke, TStroke *&lastStroke,
shun-iwasawa 43640b
                  bool unfilledOnly, std::wstring colorType, int styleIndex,
shun-iwasawa 43640b
                  bool autopaintLines)
Shinya Kitaoka 120a6e
      : m_firstRect()
Shinya Kitaoka 120a6e
      , m_lastRect()
Shinya Kitaoka 120a6e
      , m_unfilledOnly(unfilledOnly)
Shinya Kitaoka 120a6e
      , m_colorType(colorType)
shun-iwasawa 43640b
      , m_styleIndex(styleIndex)
shun-iwasawa 43640b
      , m_autopaintLines(autopaintLines) {
Shinya Kitaoka 120a6e
    m_firstImage = new TVectorImage();
Shinya Kitaoka 120a6e
    m_lastImage  = new TVectorImage();
Shinya Kitaoka 120a6e
    m_firstImage->addStroke(firstStroke);
Shinya Kitaoka 120a6e
    m_lastImage->addStroke(lastStroke);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void process(TImageP img, double t, TXshSimpleLevel *sl,
Shinya Kitaoka 473e70
               const TFrameId &fid) override {
Shinya Kitaoka 120a6e
    if (!m_firstImage) {
Shinya Kitaoka 120a6e
      TPointD p0 = m_firstRect.getP00() * (1 - t) + m_lastRect.getP00() * t;
Shinya Kitaoka 120a6e
      TPointD p1 = m_firstRect.getP11() * (1 - t) + m_lastRect.getP11() * t;
Shinya Kitaoka 120a6e
      TRectD rect(p0.x, p0.y, p1.x, p1.y);
Shinya Kitaoka 120a6e
      fillAreaWithUndo(img, rect, 0, m_unfilledOnly, m_colorType, sl, fid,
shun-iwasawa 43640b
                       m_styleIndex, m_autopaintLines);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (t == 0)
Shinya Kitaoka 120a6e
        fillAreaWithUndo(img, TRectD(), m_firstImage->getStroke(0),
shun-iwasawa 43640b
                         m_unfilledOnly, m_colorType, sl, fid, m_styleIndex,
shun-iwasawa 43640b
                         m_autopaintLines);
Shinya Kitaoka 120a6e
      else if (t == 1)
Shinya Kitaoka 120a6e
        fillAreaWithUndo(img, TRectD(), m_lastImage->getStroke(0),
shun-iwasawa 43640b
                         m_unfilledOnly, m_colorType, sl, fid, m_styleIndex,
shun-iwasawa 43640b
                         m_autopaintLines);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
      // if(t>1)
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        assert(t > 0 && t < 1);
Shinya Kitaoka 120a6e
        assert(m_firstImage->getStrokeCount() == 1);
Shinya Kitaoka 120a6e
        assert(m_lastImage->getStrokeCount() == 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        TVectorImageP vi = TInbetween(m_firstImage, m_lastImage).tween(t);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        assert(vi->getStrokeCount() == 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        fillAreaWithUndo(img, TRectD(), vi->getStroke(0) /*, imgloc*/,
shun-iwasawa 43640b
                         m_unfilledOnly, m_colorType, sl, fid, m_styleIndex,
shun-iwasawa 43640b
                         m_autopaintLines);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MultiFiller : SequencePainter
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class MultiFiller final : public SequencePainter {
Shinya Kitaoka 120a6e
  TPointD m_firstPoint, m_lastPoint;
Shinya Kitaoka 120a6e
  FillParameters m_params;
shun-iwasawa 43640b
  bool m_autopaintLines;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  MultiFiller(const TPointD &firstPoint, const TPointD &lastPoint,
shun-iwasawa 43640b
              const FillParameters ¶ms, bool autopaintLines)
shun-iwasawa 43640b
      : m_firstPoint(firstPoint)
shun-iwasawa 43640b
      , m_lastPoint(lastPoint)
shun-iwasawa 43640b
      , m_params(params)
shun-iwasawa 43640b
      , m_autopaintLines(autopaintLines) {}
Shinya Kitaoka 120a6e
  void process(TImageP img, double t, TXshSimpleLevel *sl,
Shinya Kitaoka 473e70
               const TFrameId &fid) override {
Shinya Kitaoka 120a6e
    TPointD p = m_firstPoint * (1 - t) + m_lastPoint * t;
shun-iwasawa 43640b
    doFill(img, p, m_params, false, sl, fid, m_autopaintLines);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
                                        if(e.isShiftPressed())
Toshihiro Shimizu 890ddd
            {
Shinya Kitaoka 120a6e
                                                m_firstPoint = pos;
Shinya Kitaoka 120a6e
                                                m_firstFrameId =
Shinya Kitaoka 120a6e
TApplication::instance()->getCurrentFrameId();
Shinya Kitaoka 120a6e
                                                }
Shinya Kitaoka 120a6e
                                        else
Shinya Kitaoka 120a6e
                                          {
Shinya Kitaoka 120a6e
                                                m_firstClick = false;
Shinya Kitaoka 120a6e
                                                TApplication::instance()->setCurrentFrame(m_veryFirstFrameId);
Shinya Kitaoka 120a6e
                                                }
Shinya Kitaoka 120a6e
                                        TNotifier::instance()->notify(TLevelChange());
Toshihiro Shimizu 890ddd
          TNotifier::instance()->notify(TStageChange());
Toshihiro Shimizu 890ddd
          }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// AreaFillTool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void drawPolyline(const std::vector<tpointd> &points) {</tpointd>
Shinya Kitaoka 120a6e
  if (points.empty()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  tglDrawCircle(points[0], 2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < points.size() - 1; i++)
Shinya Kitaoka 120a6e
    tglDrawSegment(points[i], points[i + 1]);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jeremy Bullock e122a9
AreaFillTool::AreaFillTool(TTool *parent)
Jeremy Bullock e122a9
    : m_frameRange(false)
Jeremy Bullock e122a9
    , m_onlyUnfilled(false)
Jeremy Bullock e122a9
    , m_selecting(false)
Jeremy Bullock e122a9
    , m_selectingRect(TRectD())
Jeremy Bullock e122a9
    , m_firstRect(TRectD())
Jeremy Bullock e122a9
    , m_firstFrameSelected(false)
Jeremy Bullock e122a9
    , m_level(0)
Jeremy Bullock e122a9
    , m_parent(parent)
Jeremy Bullock e122a9
    , m_colorType(AREAS)
Jeremy Bullock e122a9
    , m_currCell(-1, -1)
Jeremy Bullock e122a9
    , m_type(RECT)
Jeremy Bullock e122a9
    , m_isPath(false)
Jeremy Bullock e122a9
    , m_enabled(false)
Jeremy Bullock e122a9
    , m_active(false)
Jeremy Bullock e122a9
    , m_firstStroke(0)
Jeremy Bullock e122a9
    , m_thick(0.5)
Jeremy Bullock e122a9
    , m_mousePosition()
Jeremy Bullock e122a9
    , m_onion(false)
Jeremy Bullock e122a9
    , m_isLeftButtonPressed(false)
Jeremy Bullock e122a9
    , m_autopaintLines(true) {}
Jeremy Bullock e122a9
Jeremy Bullock e122a9
void AreaFillTool::draw() {
Jeremy Bullock e122a9
  m_thick = m_parent->getPixelSize() / 2.0;
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  TPixel color = TPixel32::Red;
Jeremy Bullock e122a9
  if (m_type == RECT) {
Jeremy Bullock e122a9
    if (m_frameRange && m_firstFrameSelected)
Jeremy Bullock e122a9
      drawRect(m_firstRect, color, 0x3F33, true);
Jeremy Bullock e122a9
    if (m_selecting || (m_frameRange && !m_firstFrameSelected))
Jeremy Bullock e122a9
      drawRect(m_selectingRect, color, 0xFFFF, true);
justburner 8221ad
  } else if ((m_type == FREEHAND || m_type == POLYLINE || m_type == FREEPICK) &&
justburner 8221ad
             m_frameRange) {
Jeremy Bullock e122a9
    tglColor(color);
Jeremy Bullock e122a9
    if (m_firstStroke) drawStrokeCenterline(*m_firstStroke, 1);
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  if (m_type == POLYLINE && !m_polyline.empty()) {
Jeremy Bullock e122a9
    glPushMatrix();
Jeremy Bullock e122a9
    tglColor(TPixel::Red);
Jeremy Bullock e122a9
    tglDrawCircle(m_polyline[0], 2);
Jeremy Bullock e122a9
    glBegin(GL_LINE_STRIP);
Jeremy Bullock e122a9
    for (UINT i = 0; i < m_polyline.size(); i++) tglVertex(m_polyline[i]);
Jeremy Bullock e122a9
    tglVertex(m_mousePosition);
Jeremy Bullock e122a9
    glEnd();
Jeremy Bullock e122a9
    glPopMatrix();
justburner 8221ad
  } else if ((m_type == FREEHAND || m_type == FREEPICK) && !m_track.isEmpty()) {
Jeremy Bullock e122a9
    tglColor(TPixel::Red);
Jeremy Bullock e122a9
    glPushMatrix();
Jeremy Bullock e122a9
    m_track.drawAllFragments();
Jeremy Bullock e122a9
    glPopMatrix();
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
}
Toshihiro Shimizu 890ddd
justburner 8221ad
int AreaFillTool::pick(const TImageP &image, const TPointD &pos,
justburner 8221ad
                       const int frame, int mode) {
justburner 8221ad
  TToonzImageP ti  = image;
justburner 8221ad
  TVectorImageP vi = image;
justburner 8221ad
  if (!ti && !vi) return 0;
justburner 8221ad
justburner 8221ad
  TTool::Viewer *viewer = m_parent->getViewer();
justburner 8221ad
justburner 8221ad
  StylePicker picker(viewer->viewerWidget(), image);
justburner 8221ad
  double scale2 = 1.0;
justburner 8221ad
  if (vi) {
justburner 8221ad
    TAffine aff =
justburner 8221ad
        viewer->getViewMatrix() * m_parent->getCurrentColumnMatrix(frame);
justburner 8221ad
    scale2 = aff.det();
justburner 8221ad
  }
justburner 8221ad
  TPointD pickPos = pos;
justburner 8221ad
  // in case that the column is animated in scene-editing mode
justburner 8221ad
  if (frame > 0) {
justburner 8221ad
    TPointD dpiScale = viewer->getDpiScale();
justburner 8221ad
    pickPos.x *= dpiScale.x;
justburner 8221ad
    pickPos.y *= dpiScale.y;
justburner 8221ad
    TPointD worldPos = m_parent->getCurrentColumnMatrix() * pickPos;
justburner 8221ad
    pickPos          = m_parent->getCurrentColumnMatrix(frame).inv() * worldPos;
justburner 8221ad
    pickPos.x /= dpiScale.x;
justburner 8221ad
    pickPos.y /= dpiScale.y;
justburner 8221ad
  }
justburner 8221ad
  // thin stroke can be picked with 10 pixel range
justburner 8221ad
  return picker.pickStyleId(pickPos, 10.0, scale2, mode);
justburner 8221ad
}
justburner 8221ad
Jeremy Bullock e122a9
void AreaFillTool::resetMulti() {
Jeremy Bullock e122a9
  m_firstFrameSelected = false;
Jeremy Bullock e122a9
  m_firstRect.empty();
Jeremy Bullock e122a9
  m_selectingRect.empty();
Jeremy Bullock e122a9
  TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
  TXshLevel *xl           = app->getCurrentLevel()->getLevel();
Jeremy Bullock e122a9
  m_level                 = xl ? xl->getSimpleLevel() : 0;
Jeremy Bullock e122a9
  m_firstFrameId = m_veryFirstFrameId = m_parent->getCurrentFid();
Jeremy Bullock e122a9
  if (m_firstStroke) {
Jeremy Bullock e122a9
    delete m_firstStroke;
Jeremy Bullock e122a9
    m_firstStroke = 0;
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
justburner 8221ad
void AreaFillTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e,
Jeremy Bullock e122a9
                                  TImage *img) {
Jeremy Bullock e122a9
  TVectorImageP vi = TImageP(img);
Jeremy Bullock e122a9
  TToonzImageP ti  = TToonzImageP(img);
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  if (!vi && !ti) {
Jeremy Bullock e122a9
    m_selecting = false;
Jeremy Bullock e122a9
    return;
Jeremy Bullock e122a9
  }
Toshihiro Shimizu 890ddd
justburner 8221ad
  if (m_type == FREEPICK) {
justburner 8221ad
    TTool::Application *app = TTool::getApplication();
justburner 8221ad
    if (!app) return;
justburner 8221ad
justburner 8221ad
    int fllmode = e.isCtrlPressed() ? 2 : 0;  // Line+Area : Area
justburner 8221ad
    int styleId = pick(img, pos, -1, fllmode);
justburner 8221ad
    if (!m_isLeftButtonPressed) m_bckStyleId = app->getCurrentLevelStyleIndex();
justburner 8221ad
    app->setCurrentLevelStyleIndex(styleId);
justburner 8221ad
  }
justburner 8221ad
Jeremy Bullock e122a9
  m_selecting = true;
Jeremy Bullock e122a9
  if (m_type == RECT) {
Jeremy Bullock e122a9
    m_selectingRect.x0 = pos.x;
Jeremy Bullock e122a9
    m_selectingRect.y0 = pos.y;
Jeremy Bullock e122a9
    m_selectingRect.x1 = pos.x + 1;
Jeremy Bullock e122a9
    m_selectingRect.y1 = pos.y + 1;
justburner 8221ad
  } else if (m_type == FREEHAND || m_type == POLYLINE || m_type == FREEPICK) {
Jeremy Bullock e122a9
    int col  = TTool::getApplication()->getCurrentColumn()->getColumnIndex();
Jeremy Bullock e122a9
    m_isPath = TTool::getApplication()
Jeremy Bullock e122a9
                   ->getCurrentObject()
Jeremy Bullock e122a9
                   ->isSpline();  // getApplication()->isEditingSpline();
Jeremy Bullock e122a9
    m_enabled = col >= 0 || m_isPath;
Jeremy Bullock e122a9
Jeremy Bullock e122a9
    if (!m_enabled) return;
Jeremy Bullock e122a9
    m_active = true;
Jeremy Bullock e122a9
Jeremy Bullock e122a9
    m_track.clear();
Jeremy Bullock e122a9
    m_firstPos        = pos;
Jeremy Bullock e122a9
    double pixelSize2 = m_parent->getPixelSize() * m_parent->getPixelSize();
Jeremy Bullock e122a9
    m_track.add(TThickPoint(pos, m_thick), pixelSize2);
Jeremy Bullock e122a9
    if (m_type == POLYLINE) {
Jeremy Bullock e122a9
      if (m_polyline.empty() || m_polyline.back() != pos)
Jeremy Bullock e122a9
        m_polyline.push_back(pos);
Jeremy Bullock e122a9
      m_mousePosition = pos;
Jeremy Bullock e122a9
    } else
Jeremy Bullock e122a9
      m_track.add(TThickPoint(pos, m_thick), pixelSize2);
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
    if (m_type == POLYLINE) {
Jeremy Bullock e122a9
      if (m_polyline.empty() || m_polyline.back() != pos)
Jeremy Bullock e122a9
        m_polyline.push_back(pos);
Shinya Kitaoka 120a6e
    }
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
  m_isLeftButtonPressed = true;
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
/*-- PolyLineFillを閉じる時に呼ばれる --*/
Jeremy Bullock e122a9
void AreaFillTool::leftButtonDoubleClick(const TPointD &pos,
Jeremy Bullock e122a9
                                         const TMouseEvent &e) {
Jeremy Bullock e122a9
  TStroke *stroke;
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
  if (!app) return;
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  if (m_polyline.size() <= 1) {
Jeremy Bullock e122a9
    resetMulti();
shun-iwasawa 4293f9
    m_isLeftButtonPressed = false;
Jeremy Bullock e122a9
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  if (m_polyline.back() != pos) m_polyline.push_back(pos);
Jeremy Bullock e122a9
  if (m_polyline.back() != m_polyline.front())
Jeremy Bullock e122a9
    m_polyline.push_back(m_polyline.front());
Jeremy Bullock e122a9
  std::vector<tthickpoint> strokePoints;</tthickpoint>
Jeremy Bullock e122a9
  for (UINT i = 0; i < m_polyline.size() - 1; i++) {
Jeremy Bullock e122a9
    strokePoints.push_back(TThickPoint(m_polyline[i], 1));
Jeremy Bullock e122a9
    strokePoints.push_back(
Jeremy Bullock e122a9
        TThickPoint(0.5 * (m_polyline[i] + m_polyline[i + 1]), 1));
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
  strokePoints.push_back(TThickPoint(m_polyline.back(), 1));
Jeremy Bullock e122a9
  m_polyline.clear();
Jeremy Bullock e122a9
  stroke = new TStroke(strokePoints);
Jeremy Bullock e122a9
  assert(stroke->getPoint(0) == stroke->getPoint(1));
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  //    if (m_type==POLYLINE)
Jeremy Bullock e122a9
  //      m_polyline.push_back(pos);
Jeremy Bullock e122a9
  // drawPolyline(m_polyline);
Jeremy Bullock e122a9
  int styleIndex = app->getCurrentLevelStyleIndex();
Jeremy Bullock e122a9
  if (m_frameRange)  // stroke multi
Jeremy Bullock e122a9
  {
Jeremy Bullock e122a9
    if (m_firstFrameSelected) {
Jeremy Bullock e122a9
      MultiAreaFiller filler(m_firstStroke, stroke, m_onlyUnfilled, m_colorType,
Jeremy Bullock e122a9
                             styleIndex, m_autopaintLines);
Jeremy Bullock e122a9
      filler.processSequence(m_level.getPointer(), m_firstFrameId,
Jeremy Bullock e122a9
                             m_parent->getCurrentFid());
Jeremy Bullock e122a9
      m_parent->invalidate(m_selectingRect.enlarge(2));
Jeremy Bullock e122a9
      if (e.isShiftPressed()) {
Jeremy Bullock e122a9
        m_firstStroke  = stroke;
Jeremy Bullock e122a9
        m_firstFrameId = m_parent->getCurrentFid();
Jeremy Bullock e122a9
      } else {
Jeremy Bullock e122a9
        if (app->getCurrentFrame()->isEditingScene()) {
Jeremy Bullock e122a9
          app->getCurrentColumn()->setColumnIndex(m_currCell.first);
Jeremy Bullock e122a9
          app->getCurrentFrame()->setFrame(m_currCell.second);
Jeremy Bullock e122a9
        } else
Jeremy Bullock e122a9
          app->getCurrentFrame()->setFid(m_veryFirstFrameId);
Jeremy Bullock e122a9
        resetMulti();
Jeremy Bullock e122a9
      }
Jeremy Bullock e122a9
    } else  // primo frame
Jeremy Bullock e122a9
    {
Jeremy Bullock e122a9
      m_firstStroke = stroke;
Jeremy Bullock e122a9
      // if (app->getCurrentFrame()->isEditingScene())
Jeremy Bullock e122a9
      m_currCell =
Jeremy Bullock e122a9
          std::pair<int, int="">(app->getCurrentColumn()->getColumnIndex(),</int,>
Jeremy Bullock e122a9
                              app->getCurrentFrame()->getFrame());
Shinya Kitaoka 120a6e
    }
Jeremy Bullock e122a9
  } else {
Jeremy Bullock e122a9
    if (m_onion) {
Jeremy Bullock e122a9
      OnionSkinMask osMask = app->getCurrentOnionSkin()->getOnionSkinMask();
Jeremy Bullock e122a9
      doStrokeAutofill(m_parent->getImage(true), stroke, m_onlyUnfilled, osMask,
Jeremy Bullock e122a9
                       m_level.getPointer(), m_parent->getCurrentFid());
Jeremy Bullock e122a9
    } else
Jeremy Bullock e122a9
      fillAreaWithUndo(m_parent->getImage(true), TRectD(), stroke,
Jeremy Bullock e122a9
                       m_onlyUnfilled, m_colorType, m_level.getPointer(),
Jeremy Bullock e122a9
                       m_parent->getCurrentFid(), styleIndex, m_autopaintLines);
Jeremy Bullock e122a9
    TTool *t = app->getCurrentTool()->getTool();
Jeremy Bullock e122a9
    if (t) t->notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
void AreaFillTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
shun-iwasawa 4293f9
  if (!m_isLeftButtonPressed) return;
Jeremy Bullock e122a9
  if (m_type == RECT) {
Jeremy Bullock e122a9
    m_selectingRect.x1 = pos.x;
Jeremy Bullock e122a9
    m_selectingRect.y1 = pos.y;
Jeremy Bullock e122a9
    m_parent->invalidate();
justburner 8221ad
  } else if (m_type == FREEHAND || m_type == FREEPICK) {
Jeremy Bullock e122a9
    if (!m_enabled || !m_active) return;
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
    double pixelSize2 = m_parent->getPixelSize() * m_parent->getPixelSize();
Jeremy Bullock e122a9
    m_track.add(TThickPoint(pos, m_thick), pixelSize2);
Jeremy Bullock e122a9
    m_parent->invalidate();
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
void AreaFillTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock e122a9
  if (m_type != POLYLINE || m_polyline.empty()) return;
Jeremy Bullock e122a9
  if (!m_enabled || !m_active) return;
Jeremy Bullock e122a9
  m_mousePosition = pos;
Jeremy Bullock e122a9
  m_parent->invalidate();
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
void AreaFillTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
Jeremy Bullock e122a9
  if (!m_isLeftButtonPressed) return;
Jeremy Bullock e122a9
  m_isLeftButtonPressed = false;
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
  if (!app) return;
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  TXshLevel *xl = app->getCurrentLevel()->getLevel();
Jeremy Bullock e122a9
  m_level       = xl ? xl->getSimpleLevel() : 0;
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  int styleIndex = app->getCurrentLevelStyleIndex();
Jeremy Bullock e122a9
  m_selecting    = false;
Jeremy Bullock e122a9
  if (m_type == RECT) {
Jeremy Bullock e122a9
    if (m_selectingRect.x0 > m_selectingRect.x1)
otakuto ed7dcd
      std::swap(m_selectingRect.x0, m_selectingRect.x1);
Jeremy Bullock e122a9
    if (m_selectingRect.y0 > m_selectingRect.y1)
otakuto ed7dcd
      std::swap(m_selectingRect.y0, m_selectingRect.y1);
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
    if (m_frameRange) {
Shinya Kitaoka 120a6e
      if (m_firstFrameSelected) {
Jeremy Bullock e122a9
        MultiAreaFiller filler(m_firstRect, m_selectingRect, m_onlyUnfilled,
shun-iwasawa 43640b
                               m_colorType, styleIndex, m_autopaintLines);
Shinya Kitaoka 120a6e
        filler.processSequence(m_level.getPointer(), m_firstFrameId,
Shinya Kitaoka 120a6e
                               m_parent->getCurrentFid());
Shinya Kitaoka 120a6e
        m_parent->invalidate(m_selectingRect.enlarge(2));
Shinya Kitaoka 120a6e
        if (e.isShiftPressed()) {
Jeremy Bullock e122a9
          m_firstRect    = m_selectingRect;
Shinya Kitaoka 120a6e
          m_firstFrameId = m_parent->getCurrentFid();
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
            app->getCurrentColumn()->setColumnIndex(m_currCell.first);
Shinya Kitaoka 120a6e
            app->getCurrentFrame()->setFrame(m_currCell.second);
Shinya Kitaoka 120a6e
          } else
Shinya Kitaoka 120a6e
            app->getCurrentFrame()->setFid(m_veryFirstFrameId);
Shinya Kitaoka 120a6e
          resetMulti();
Shinya Kitaoka 120a6e
        }
Jeremy Bullock e122a9
      } else {
Shinya Kitaoka 120a6e
        // if (app->getCurrentFrame()->isEditingScene())
Shinya Kitaoka 120a6e
        m_currCell =
Shinya Kitaoka 120a6e
            std::pair<int, int="">(app->getCurrentColumn()->getColumnIndex(),</int,>
Shinya Kitaoka 120a6e
                                app->getCurrentFrame()->getFrame());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (m_onion) {
Shinya Kitaoka 120a6e
        OnionSkinMask osMask = app->getCurrentOnionSkin()->getOnionSkinMask();
Jeremy Bullock e122a9
        doRectAutofill(m_parent->getImage(true), m_selectingRect,
Jeremy Bullock e122a9
                       m_onlyUnfilled, osMask, m_level.getPointer(),
Jeremy Bullock e122a9
                       m_parent->getCurrentFid());
Shinya Kitaoka 120a6e
      } else
Jeremy Bullock e122a9
        fillAreaWithUndo(m_parent->getImage(true), m_selectingRect, 0,
Shinya Kitaoka 120a6e
                         m_onlyUnfilled, m_colorType, m_level.getPointer(),
shun-iwasawa 43640b
                         m_parent->getCurrentFid(), styleIndex,
shun-iwasawa 43640b
                         m_autopaintLines);
Jeremy Bullock e122a9
      m_parent->invalidate();
Jeremy Bullock e122a9
      m_selectingRect.empty();
Shinya Kitaoka 120a6e
      TTool *t = app->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
      if (t) t->notifyImageChanged();
Shinya Kitaoka 120a6e
    }
justburner 8221ad
  } else if (m_type == FREEHAND || m_type == FREEPICK) {
Toshihiro Shimizu 890ddd
#if defined(MACOSX)
Shinya Kitaoka 120a6e
// m_parent->m_viewer->enableRedraw(true);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Jeremy Bullock e122a9
    bool isValid = m_enabled && m_active;
Jeremy Bullock e122a9
    m_enabled = m_active = false;
Jeremy Bullock e122a9
    if (!isValid || m_track.isEmpty()) return;
Jeremy Bullock e122a9
    double pixelSize2 = m_parent->getPixelSize() * m_parent->getPixelSize();
Jeremy Bullock e122a9
    m_track.add(TThickPoint(m_firstPos, m_thick), pixelSize2);
Jeremy Bullock e122a9
    m_track.filterPoints();
Jeremy Bullock e122a9
    double error    = (m_isPath ? 20.0 : 30.0 / 11) * sqrt(pixelSize2);
Jeremy Bullock e122a9
    TStroke *stroke = m_track.makeStroke(error);
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
    stroke->setStyle(1);
Jeremy Bullock e122a9
    m_track.clear();
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
    if (m_frameRange)  // stroke multi
Jeremy Bullock e122a9
    {
Jeremy Bullock e122a9
      if (m_firstFrameSelected) {
Jeremy Bullock e122a9
        MultiAreaFiller filler(m_firstStroke, stroke, m_onlyUnfilled,
Jeremy Bullock e122a9
                               m_colorType, styleIndex, m_autopaintLines);
Jeremy Bullock e122a9
        filler.processSequence(m_level.getPointer(), m_firstFrameId,
Jeremy Bullock e122a9
                               m_parent->getCurrentFid());
Jeremy Bullock e122a9
        m_parent->invalidate(m_selectingRect.enlarge(2));
Jeremy Bullock e122a9
        if (e.isShiftPressed()) {
Jeremy Bullock e122a9
          m_firstStroke  = stroke;
Jeremy Bullock e122a9
          m_firstFrameId = m_parent->getCurrentFid();
Jeremy Bullock e122a9
        } else {
Jeremy Bullock e122a9
          if (app->getCurrentFrame()->isEditingScene()) {
Jeremy Bullock e122a9
            app->getCurrentColumn()->setColumnIndex(m_currCell.first);
Jeremy Bullock e122a9
            app->getCurrentFrame()->setFrame(m_currCell.second);
Jeremy Bullock e122a9
          } else
Jeremy Bullock e122a9
            app->getCurrentFrame()->setFid(m_veryFirstFrameId);
Jeremy Bullock e122a9
          resetMulti();
Shinya Kitaoka 120a6e
        }
Jeremy Bullock e122a9
      } else  // primo frame
Shinya Kitaoka 120a6e
      {
Jeremy Bullock e122a9
        m_firstStroke = stroke;
Jeremy Bullock e122a9
        // if (app->getCurrentFrame()->isEditingScene())
Jeremy Bullock e122a9
        m_currCell =
Jeremy Bullock e122a9
            std::pair<int, int="">(app->getCurrentColumn()->getColumnIndex(),</int,>
Jeremy Bullock e122a9
                                app->getCurrentFrame()->getFrame());
Shinya Kitaoka 120a6e
      }
Jeremy Bullock e122a9
Jeremy Bullock e122a9
    } else  // stroke non multi
Jeremy Bullock e122a9
    {
Jeremy Bullock e122a9
      if (!m_parent->getImage(true)) return;
Jeremy Bullock e122a9
      if (m_onion) {
Jeremy Bullock e122a9
        OnionSkinMask osMask = app->getCurrentOnionSkin()->getOnionSkinMask();
Jeremy Bullock e122a9
        doStrokeAutofill(m_parent->getImage(true), stroke, m_onlyUnfilled,
Jeremy Bullock e122a9
                         osMask, m_level.getPointer(),
Jeremy Bullock e122a9
                         m_parent->getCurrentFid());
Jeremy Bullock e122a9
      } else
Jeremy Bullock e122a9
        fillAreaWithUndo(
Jeremy Bullock e122a9
            m_parent->getImage(true), TRectD(), stroke /*, imageLocation*/,
Jeremy Bullock e122a9
            m_onlyUnfilled, m_colorType, m_level.getPointer(),
Jeremy Bullock e122a9
            m_parent->getCurrentFid(), styleIndex, m_autopaintLines);
Jeremy Bullock e122a9
      delete stroke;
Jeremy Bullock e122a9
      TTool *t = app->getCurrentTool()->getTool();
Jeremy Bullock e122a9
      if (t) t->notifyImageChanged();
Jeremy Bullock e122a9
      m_parent->invalidate();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
justburner 8221ad
justburner 8221ad
  if (m_type == FREEPICK) app->setCurrentLevelStyleIndex(m_bckStyleId);
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
void AreaFillTool::onImageChanged() {
Jeremy Bullock e122a9
  if (!m_frameRange) return;
Jeremy Bullock e122a9
  TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
  if (!app) return;
Jeremy Bullock e122a9
  TXshLevel *xshl = app->getCurrentLevel()->getLevel();
Jeremy Bullock e122a9
Jeremy Bullock e122a9
  if (!xshl || m_level.getPointer() != xshl ||
Jeremy Bullock e122a9
      (m_selectingRect.isEmpty() && !m_firstStroke))
Jeremy Bullock e122a9
    resetMulti();
Jeremy Bullock e122a9
  else if (m_firstFrameId == m_parent->getCurrentFid())
Jeremy Bullock e122a9
    m_firstFrameSelected = false;  // nel caso sono passato allo stato 1 e
Jeremy Bullock e122a9
                                   // torno all'immagine iniziale, torno allo
Jeremy Bullock e122a9
                                   // stato iniziale
Jeremy Bullock e122a9
  else {                           // cambio stato.
Jeremy Bullock e122a9
    m_firstFrameSelected = true;
justburner 8221ad
    if (m_type != FREEHAND && m_type != POLYLINE && m_type != FREEPICK) {
Jeremy Bullock e122a9
      assert(!m_selectingRect.isEmpty());
Jeremy Bullock e122a9
      m_firstRect = m_selectingRect;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
/*--Normal以外のTypeが選択された場合に呼ばれる--*/
Jeremy Bullock e122a9
bool AreaFillTool::onPropertyChanged(bool multi, bool onlyUnfilled, bool onion,
Jeremy Bullock e122a9
                                     Type type, std::wstring colorType,
Jeremy Bullock e122a9
                                     bool autopaintLines) {
Jeremy Bullock e122a9
  m_frameRange     = multi;
Jeremy Bullock e122a9
  m_onlyUnfilled   = onlyUnfilled;
Jeremy Bullock e122a9
  m_colorType      = colorType;
Jeremy Bullock e122a9
  m_type           = type;
Jeremy Bullock e122a9
  m_onion          = onion;
Jeremy Bullock e122a9
  m_autopaintLines = autopaintLines;
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  if (m_frameRange) resetMulti();
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  /*--動作中にプロパティが変わったら、現在の動作を無効にする--*/
Jeremy Bullock e122a9
  if (m_isLeftButtonPressed) m_isLeftButtonPressed = false;
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  if (m_type == POLYLINE && !m_polyline.empty()) m_polyline.clear();
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  return true;
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
void AreaFillTool::onActivate() {
Jeremy Bullock e122a9
  // getApplication()->editImage();
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  if (m_frameRange) resetMulti();
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  if (TVectorImageP vi = TImageP(m_parent->getImage(false))) vi->findRegions();
Jeremy Bullock e122a9
}
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
void AreaFillTool::onEnter() {
Jeremy Bullock e122a9
  // getApplication()->editImage();
Jeremy Bullock e122a9
}
Toshihiro Shimizu 890ddd
shun-iwasawa 2d0135
bool descending(int i, int j) { return (i > j); }
shun-iwasawa 2d0135
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
/*! NormalLineFillTool
Shinya Kitaoka 120a6e
        マウスドラッグで直線を延ばし、その直線がまたいだ点をFillLineするツール。
Shinya Kitaoka 120a6e
        Raster - Normal - Line Fillツール(FrameRangeなし)のとき使用可能にする
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
class NormalLineFillTool {
Shinya Kitaoka 120a6e
  TTool *m_parent;
Shinya Kitaoka 120a6e
  TPointD m_startPosition, m_mousePosition;
Shinya Kitaoka 120a6e
  bool m_isEditing;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  NormalLineFillTool(TTool *parent)
Shinya Kitaoka 120a6e
      : m_parent(parent), m_isEditing(false), m_mousePosition() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*-- FillLineツールに戻ってきたときに前の位置情報をリセットする --*/
Shinya Kitaoka 120a6e
  void init() {
Shinya Kitaoka 120a6e
    m_startPosition = TPointD();
Shinya Kitaoka 120a6e
    m_mousePosition = TPointD();
Shinya Kitaoka 120a6e
    m_isEditing     = false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
    m_startPosition = pos; /*-始点-*/
Shinya Kitaoka 120a6e
    m_mousePosition = pos; /*-終点-*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_isEditing = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
    if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_mousePosition = pos;
Shinya Kitaoka 120a6e
    m_parent->invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void leftButtonUp(const TPointD &pos, const TMouseEvent &e, TImage *img,
Shinya Kitaoka 120a6e
                    FillParameters ¶ms) {
Shinya Kitaoka 120a6e
    if (!m_isEditing) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_mousePosition = pos;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
    if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TXshLevel *xl       = app->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
    TXshSimpleLevel *sl = xl ? xl->getSimpleLevel() : 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TToonzImageP ti = TImageP(m_parent->getImage(true));
Shinya Kitaoka 120a6e
    if (!ti) return;
Shinya Kitaoka 120a6e
    TRasterCM32P ras = ti->getRaster();
Shinya Kitaoka 120a6e
    if (!ras) return;
Shinya Kitaoka 120a6e
    int styleId = params.m_styleId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--- 線分上にある全ての点でdoFillを行う ---*/
Shinya Kitaoka 120a6e
    double dx = m_mousePosition.x - m_startPosition.x;
Shinya Kitaoka 120a6e
    double dy = m_mousePosition.y - m_startPosition.y;
Shinya Kitaoka 120a6e
    if (std::abs(dx) > std::abs(dy)) /*-- 横長の線分の場合 --*/
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      double k = dy / dx; /*-- 直線の傾き --*/
Shinya Kitaoka 120a6e
      /*--- roundでは負値のときにうまく繋がらない ---*/
shun-iwasawa 3f2d1d
      int start      = std::min((int)floor(m_startPosition.x + 0.5),
Shinya Kitaoka 120a6e
                           (int)floor(m_mousePosition.x + 0.5));
shun-iwasawa 3f2d1d
      int end        = std::max((int)floor(m_startPosition.x + 0.5),
Shinya Kitaoka 120a6e
                         (int)floor(m_mousePosition.x + 0.5));
Shinya Kitaoka 120a6e
      double start_x = (m_startPosition.x < m_mousePosition.x)
Shinya Kitaoka 120a6e
                           ? m_startPosition.x
Shinya Kitaoka 120a6e
                           : m_mousePosition.x;
Shinya Kitaoka 120a6e
      double start_y = (m_startPosition.x < m_mousePosition.x)
Shinya Kitaoka 120a6e
                           ? m_startPosition.y
Shinya Kitaoka 120a6e
                           : m_mousePosition.y;
Shinya Kitaoka 120a6e
      for (int x = start; x <= end; x++) {
Shinya Kitaoka 120a6e
        double ddx = (double)(x - start);
Shinya Kitaoka 120a6e
        TPointD tmpPos(start_x + ddx, ddx * k + start_y);
Shinya Kitaoka 120a6e
        TPoint ipos((int)(tmpPos.x + ras->getLx() / 2),
Shinya Kitaoka 120a6e
                    (int)(tmpPos.y + ras->getLy() / 2));
Shinya Kitaoka 120a6e
        if (!ras->getBounds().contains(ipos)) continue;
Shinya Kitaoka 120a6e
        TPixelCM32 pix = ras->pixels(ipos.y)[ipos.x];
Shinya Kitaoka 120a6e
        if (pix.getInk() == styleId || pix.isPurePaint()) continue;
Shinya Kitaoka 120a6e
        doFill(img, tmpPos, params, e.isShiftPressed(), sl,
shun-iwasawa 43640b
               m_parent->getCurrentFid(), true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else /*-- 縦長の線分の場合 --*/
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      double k = dx / dy; /*-- 直線の傾き --*/
Shinya Kitaoka 120a6e
      /*--- roundでは負値のときにうまく繋がらない ---*/
shun-iwasawa 3f2d1d
      int start      = std::min((int)floor(m_startPosition.y + 0.5),
Shinya Kitaoka 120a6e
                           (int)floor(m_mousePosition.y + 0.5));
shun-iwasawa 3f2d1d
      int end        = std::max((int)floor(m_startPosition.y + 0.5),
Shinya Kitaoka 120a6e
                         (int)floor(m_mousePosition.y + 0.5));
Shinya Kitaoka 120a6e
      double start_x = (m_startPosition.y < m_mousePosition.y)
Shinya Kitaoka 120a6e
                           ? m_startPosition.x
Shinya Kitaoka 120a6e
                           : m_mousePosition.x;
Shinya Kitaoka 120a6e
      double start_y = (m_startPosition.y < m_mousePosition.y)
Shinya Kitaoka 120a6e
                           ? m_startPosition.y
Shinya Kitaoka 120a6e
                           : m_mousePosition.y;
Shinya Kitaoka 120a6e
      for (int y = start; y <= end; y++) {
Shinya Kitaoka 120a6e
        double ddy = (double)(y - start);
Shinya Kitaoka 120a6e
        TPointD tmpPos(ddy * k + start_x, ddy + start_y);
Shinya Kitaoka 120a6e
        TPoint ipos((int)(tmpPos.x + ras->getLx() / 2),
Shinya Kitaoka 120a6e
                    (int)(tmpPos.y + ras->getLy() / 2));
Shinya Kitaoka 120a6e
        if (!ras->getBounds().contains(ipos)) continue;
Shinya Kitaoka 120a6e
        TPixelCM32 pix = ras->pixels(ipos.y)[ipos.x];
Shinya Kitaoka 120a6e
        if (pix.getInk() == styleId || pix.isPurePaint()) continue;
Shinya Kitaoka 120a6e
        doFill(img, tmpPos, params, e.isShiftPressed(), sl,
shun-iwasawa 43640b
               m_parent->getCurrentFid(), true);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_isEditing = false;
Shinya Kitaoka 120a6e
    m_parent->invalidate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void draw() {
Shinya Kitaoka 120a6e
    if (m_isEditing) {
Shinya Kitaoka 120a6e
      tglColor(TPixel32::Red);
Shinya Kitaoka 120a6e
      glBegin(GL_LINE_STRIP);
Shinya Kitaoka 120a6e
      tglVertex(m_startPosition);
Shinya Kitaoka 120a6e
      tglVertex(m_mousePosition);
Shinya Kitaoka 120a6e
      glEnd();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// Fill Tool
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FillTool::FillTool(int targetType)
Shinya Kitaoka 120a6e
    : TTool("T_Fill")
Shinya Kitaoka 120a6e
    , m_frameRange("Frame Range", false)  // W_ToolOptions_FrameRange
Shinya Kitaoka 120a6e
    , m_fillType("Type:")
Shinya Kitaoka 120a6e
    , m_selective("Selective", false)
Shinya Kitaoka 120a6e
    , m_colorType("Mode:")
Shinya Kitaoka 120a6e
    , m_onion("Onion Skin", false)
Shinya Kitaoka 120a6e
    , m_fillDepth("Fill Depth", 0, 15, 0, 15)
Shinya Kitaoka 120a6e
    , m_segment("Segment", false)
Shinya Kitaoka 120a6e
    , m_onionStyleId(0)
Shinya Kitaoka 120a6e
    , m_currCell(-1, -1)
Jeremy Bullock e122a9
    , m_maxGapDistance("Maximum Gap", 0.01, 10.0, 1.15)
shun-iwasawa 43640b
    , m_firstTime(true)
shun-iwasawa 43640b
    , m_autopaintLines("Autopaint Lines", true) {
Shinya Kitaoka 120a6e
  m_rectFill           = new AreaFillTool(this);
Shinya Kitaoka 120a6e
  m_normalLineFillTool = new NormalLineFillTool(this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bind(targetType);
Shinya Kitaoka 120a6e
  m_prop.bind(m_fillType);
Shinya Kitaoka 120a6e
  m_fillType.addValue(NORMALFILL);
Shinya Kitaoka 120a6e
  m_fillType.addValue(RECTFILL);
Shinya Kitaoka 120a6e
  m_fillType.addValue(FREEHANDFILL);
Shinya Kitaoka 120a6e
  m_fillType.addValue(POLYLINEFILL);
justburner 8221ad
  m_fillType.addValue(FREEPICKFILL);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_prop.bind(m_colorType);
Shinya Kitaoka 120a6e
  m_colorType.addValue(LINES);
Shinya Kitaoka 120a6e
  m_colorType.addValue(AREAS);
Shinya Kitaoka 120a6e
  m_colorType.addValue(ALL);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_prop.bind(m_selective);
Shinya Kitaoka 120a6e
  if (targetType == TTool::ToonzImage) {
Shinya Kitaoka 120a6e
    m_prop.bind(m_fillDepth);
Shinya Kitaoka 120a6e
    m_prop.bind(m_segment);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_prop.bind(m_onion);
Shinya Kitaoka 120a6e
  m_prop.bind(m_frameRange);
Jeremy Bullock e122a9
  if (targetType == TTool::VectorImage) {
Jeremy Bullock e122a9
    m_prop.bind(m_maxGapDistance);
Jeremy Bullock e122a9
    m_maxGapDistance.setId("MaxGapDistance");
Jeremy Bullock e122a9
  }
shun-iwasawa 43640b
  if (targetType == TTool::ToonzImage) m_prop.bind(m_autopaintLines);
Shinya Kitaoka 120a6e
  m_selective.setId("Selective");
Shinya Kitaoka 120a6e
  m_onion.setId("OnionSkin");
Shinya Kitaoka 120a6e
  m_frameRange.setId("FrameRange");
Shinya Kitaoka 120a6e
  m_segment.setId("SegmentInk");
Shinya Kitaoka 120a6e
  m_fillType.setId("Type");
Shinya Kitaoka 120a6e
  m_colorType.setId("Mode");
shun-iwasawa 43640b
  m_autopaintLines.setId("AutopaintLines");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int FillTool::getCursorId() const {
shun_iwasawa 009457
  int ret;
shun_iwasawa 009457
  if (m_colorType.getValue() == LINES)
shun_iwasawa 009457
    ret = ToolCursor::FillCursorL;
shun_iwasawa 009457
  else {
shun-iwasawa 3f2d1d
    ret = ToolCursor::FillCursor;
shun_iwasawa 009457
    if (m_colorType.getValue() == AREAS) ret = ret | ToolCursor::Ex_Area;
shun-iwasawa 43640b
    if (!m_autopaintLines.getValue())
shun-iwasawa 43640b
      ret = ret | ToolCursor::Ex_Fill_NoAutopaint;
Shinya Kitaoka 120a6e
  }
shun_iwasawa 009457
  if (m_fillType.getValue() == FREEHANDFILL)
shun_iwasawa 009457
    ret = ret | ToolCursor::Ex_FreeHand;
shun_iwasawa 009457
  else if (m_fillType.getValue() == POLYLINEFILL)
shun_iwasawa 009457
    ret = ret | ToolCursor::Ex_PolyLine;
shun_iwasawa 009457
  else if (m_fillType.getValue() == RECTFILL)
shun_iwasawa 009457
    ret = ret | ToolCursor::Ex_Rectangle;
justburner 8221ad
  if (m_fillType.getValue() == FREEPICKFILL)
justburner 8221ad
    ret = ret | ToolCursor::Ex_FreePick;
shun_iwasawa 009457
shun_iwasawa 009457
  if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg)
shun_iwasawa 009457
    ret = ret | ToolCursor::Ex_Negate;
shun_iwasawa 009457
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::updateTranslation() {
Shinya Kitaoka 120a6e
  m_frameRange.setQStringName(tr("Frame Range"));
shun-iwasawa df7bb0
Shinya Kitaoka 120a6e
  m_fillType.setQStringName(tr("Type:"));
shun-iwasawa df7bb0
  m_fillType.setItemUIName(NORMALFILL, tr("Normal"));
shun-iwasawa df7bb0
  m_fillType.setItemUIName(RECTFILL, tr("Rectangular"));
shun-iwasawa df7bb0
  m_fillType.setItemUIName(FREEHANDFILL, tr("Freehand"));
shun-iwasawa df7bb0
  m_fillType.setItemUIName(POLYLINEFILL, tr("Polyline"));
justburner 8221ad
  m_fillType.setItemUIName(FREEPICKFILL, tr("Pick+Freehand"));
shun-iwasawa df7bb0
Shinya Kitaoka 120a6e
  m_selective.setQStringName(tr("Selective"));
shun-iwasawa df7bb0
Shinya Kitaoka 120a6e
  m_colorType.setQStringName(tr("Mode:"));
shun-iwasawa df7bb0
  m_colorType.setItemUIName(LINES, tr("Lines"));
shun-iwasawa df7bb0
  m_colorType.setItemUIName(AREAS, tr("Areas"));
shun-iwasawa df7bb0
  m_colorType.setItemUIName(ALL, tr("Lines & Areas"));
shun-iwasawa df7bb0
Shinya Kitaoka 120a6e
  m_onion.setQStringName(tr("Onion Skin"));
Shinya Kitaoka 120a6e
  m_fillDepth.setQStringName(tr("Fill Depth"));
Shinya Kitaoka 120a6e
  m_segment.setQStringName(tr("Segment"));
shun-iwasawa e87e08
  m_maxGapDistance.setQStringName(tr("Maximum Gap"));
shun-iwasawa 43640b
  m_autopaintLines.setQStringName(tr("Autopaint Lines"));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FillParameters FillTool::getFillParameters() const {
Shinya Kitaoka 120a6e
  FillParameters params;
Shinya Kitaoka 120a6e
  int styleId      = TTool::getApplication()->getCurrentLevelStyleIndex();
Shinya Kitaoka 120a6e
  params.m_styleId = styleId;
Shinya Kitaoka 120a6e
  /*---紛らわしいことに、colorTypeをfillTypeに名前を変えて保存している。間違いではない。---*/
Shinya Kitaoka 120a6e
  params.m_fillType     = m_colorType.getValue();
Shinya Kitaoka 120a6e
  params.m_emptyOnly    = m_selective.getValue();
Shinya Kitaoka 120a6e
  params.m_segment      = m_segment.getValue();
Shinya Kitaoka 120a6e
  params.m_minFillDepth = (int)m_fillDepth.getValue().first;
Shinya Kitaoka 120a6e
  params.m_maxFillDepth = (int)m_fillDepth.getValue().second;
Shinya Kitaoka 120a6e
  return params;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_clickPoint = pos;
Shinya Kitaoka 120a6e
  if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    m_rectFill->leftButtonDown(pos, e, getImage(true));
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--以下、NormalFillの場合--*/
Shinya Kitaoka 120a6e
  FillParameters params = getFillParameters();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_onion.getValue()) {
Shinya Kitaoka 120a6e
    m_onionStyleId = pickOnionColor(pos);
Shinya Kitaoka 120a6e
    if (m_onionStyleId > 0) app->setCurrentLevelStyleIndex(m_onionStyleId);
Shinya Kitaoka 120a6e
  } else if (m_frameRange.getValue()) {
Shinya Kitaoka 120a6e
    if (!m_firstClick) {
Shinya Kitaoka 120a6e
      // PRIMO CLICK
Shinya Kitaoka 120a6e
      // if (app->getCurrentFrame()->isEditingScene())
Shinya Kitaoka 120a6e
      m_currCell = std::pair<int, int="">(getColumnIndex(), getFrame());</int,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_firstClick   = true;
Shinya Kitaoka 120a6e
      m_firstPoint   = pos;
Shinya Kitaoka 120a6e
      m_firstFrameId = m_veryFirstFrameId = getCurrentFid();
Shinya Kitaoka 120a6e
      // gmt. NON BISOGNA DISEGNARE DENTRO LE CALLBACKS!!!!
Shinya Kitaoka 120a6e
      // drawCross(m_firstPoint, 6);
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
    } else {
shun-iwasawa 3f2d1d
      // When using tablet on windows, the mouse press event may be called AFTER
shun-iwasawa 3f2d1d
      // tablet release. It causes unwanted another "first click" just after
shun-iwasawa 3f2d1d
      // frame-range-filling. Calling processEvents() here to make sure to
shun-iwasawa 3f2d1d
      // consume the mouse press event in advance.
shun-iwasawa 3f2d1d
      qApp->processEvents();
Shinya Kitaoka 120a6e
      // SECONDO CLICK
Shinya Kitaoka 120a6e
      TFrameId fid = getCurrentFid();
shun-iwasawa 43640b
      MultiFiller filler(m_firstPoint, pos, params,
shun-iwasawa 43640b
                         m_autopaintLines.getValue());
Shinya Kitaoka 120a6e
      filler.processSequence(m_level.getPointer(), m_firstFrameId, fid);
Shinya Kitaoka 120a6e
      if (e.isShiftPressed()) {
Shinya Kitaoka 120a6e
        m_firstPoint   = pos;
Shinya Kitaoka 120a6e
        m_firstFrameId = getCurrentFid();
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        m_firstClick = false;
Shinya Kitaoka 120a6e
        if (app->getCurrentFrame()->isEditingScene()) {
Shinya Kitaoka 120a6e
          app->getCurrentColumn()->setColumnIndex(m_currCell.first);
Shinya Kitaoka 120a6e
          app->getCurrentFrame()->setFrame(m_currCell.second);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          app->getCurrentFrame()->setFid(m_veryFirstFrameId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      TTool *t = app->getCurrentTool()->getTool();
Shinya Kitaoka 120a6e
      if (t) t->notifyImageChanged();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (params.m_fillType == LINES && m_targetType == TTool::ToonzImage)
Shinya Kitaoka 120a6e
      m_normalLineFillTool->leftButtonDown(pos, e);
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      TXshLevel *xl = app->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
      m_level       = xl ? xl->getSimpleLevel() : 0;
Shinya Kitaoka 120a6e
      doFill(getImage(true), pos, params, e.isShiftPressed(),
shun-iwasawa 43640b
             m_level.getPointer(), getCurrentFid(),
shun-iwasawa 43640b
             m_autopaintLines.getValue());
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::leftButtonDoubleClick(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    m_rectFill->leftButtonDoubleClick(pos, e);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) {
Rozhuk Ivan 823a31
  if ((m_fillType.getValue() != NORMALFILL && !m_onion.getValue()) ||
Shinya Kitaoka 120a6e
      (m_colorType.getValue() == AREAS && m_onion.getValue()))
Shinya Kitaoka 120a6e
    m_rectFill->leftButtonDrag(pos, e);
Shinya Kitaoka 120a6e
  else if (!m_onion.getValue() && !m_frameRange.getValue()) {
Shinya Kitaoka 120a6e
    FillParameters params = getFillParameters();
Shinya Kitaoka 120a6e
    if (params.m_fillType == LINES && m_targetType == TTool::ToonzImage) {
Shinya Kitaoka 120a6e
      m_normalLineFillTool->leftButtonDrag(pos, e);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_clickPoint == pos) return;
Shinya Kitaoka 120a6e
    TImageP img = getImage(true);
Shinya Kitaoka 120a6e
    int styleId = params.m_styleId;
Shinya Kitaoka 120a6e
    if (TVectorImageP vi = img) {
Shinya Kitaoka 120a6e
      TRegion *r = vi->getRegion(pos);
Shinya Kitaoka 120a6e
      if (r && r->getStyle() == styleId) return;
Shinya Kitaoka 120a6e
    } else if (TToonzImageP ti = img) {
Shinya Kitaoka 120a6e
      TRasterCM32P ras = ti->getRaster();
Shinya Kitaoka 120a6e
      if (!ras) return;
Shinya Kitaoka 120a6e
      TPointD center = ras->getCenterD();
Shinya Kitaoka 120a6e
      TPoint ipos    = convert(pos + center);
Shinya Kitaoka 120a6e
      if (!ras->getBounds().contains(ipos)) return;
Shinya Kitaoka 120a6e
      TPixelCM32 pix = ras->pixels(ipos.y)[ipos.x];
Shinya Kitaoka 120a6e
      if (pix.getPaint() == styleId) {
Shinya Kitaoka 120a6e
        invalidate();
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      TSystem::outputDebug("ok. pix=" + std::to_string(pix.getTone()) + "," +
Shinya Kitaoka 120a6e
                           std::to_string(pix.getPaint()) + "\n");
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    doFill(img, pos, params, e.isShiftPressed(), m_level.getPointer(),
shun-iwasawa 43640b
           getCurrentFid(), m_autopaintLines.getValue());
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (m_onion.getValue()) {
Shinya Kitaoka 120a6e
    if (m_fillType.getValue() != NORMALFILL && m_colorType.getValue() == AREAS)
Shinya Kitaoka 120a6e
      m_rectFill->leftButtonUp(pos, e);
Shinya Kitaoka 120a6e
    else if (m_onionStyleId > 0) {
Shinya Kitaoka 120a6e
      FillParameters tmp = getFillParameters();
Shinya Kitaoka 120a6e
      doFill(getImage(true), pos, tmp, e.isShiftPressed(), m_level.getPointer(),
shun-iwasawa 43640b
             getCurrentFid(), m_autopaintLines.getValue());
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    m_rectFill->leftButtonUp(pos, e);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_frameRange.getValue()) {
Shinya Kitaoka 120a6e
    TFrameId fid = getCurrentFid();
Shinya Kitaoka 120a6e
    // notifyImageChanged();
Shinya Kitaoka 120a6e
    if (getFillParameters().m_fillType == LINES &&
Shinya Kitaoka 120a6e
        m_targetType == TTool::ToonzImage) {
Shinya Kitaoka 120a6e
      FillParameters params = getFillParameters();
Shinya Kitaoka 120a6e
      m_normalLineFillTool->leftButtonUp(pos, e, getImage(true), params);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::resetMulti() {
Shinya Kitaoka 120a6e
  m_firstClick   = false;
Shinya Kitaoka 120a6e
  m_firstFrameId = -1;
Shinya Kitaoka 120a6e
  m_firstPoint   = TPointD();
Shinya Kitaoka 120a6e
  TXshLevel *xl  = TTool::getApplication()->getCurrentLevel()->getLevel();
Shinya Kitaoka 120a6e
  m_level        = xl ? xl->getSimpleLevel() : 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FillTool::onPropertyChanged(std::string propertyName) {
Shinya Kitaoka 120a6e
  /*--- m_rectFill->onPropertyChangedを呼ぶかどうかのフラグ
Shinya Kitaoka 120a6e
                  fillType, frameRange, selective,
Shinya Kitaoka 120a6e
     colorTypeが変わったときに呼ぶ---*/
Shinya Kitaoka 120a6e
  bool rectPropChangedflag = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Areas, Lines etc.
Shinya Kitaoka 120a6e
  if (propertyName == m_colorType.getName()) {
Shinya Kitaoka 120a6e
    FillColorType       = ::to_string(m_colorType.getValue());
Shinya Kitaoka 120a6e
    rectPropChangedflag = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*--- ColorModelのCursor更新のためにSIGNALを出す ---*/
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentTool()->notifyToolChanged();
Shinya Kitaoka 120a6e
    /*--- FillLineツールに戻ってきたときに前回の位置情報をリセットする ---*/
Shinya Kitaoka 120a6e
    if (FillColorType.getValue() == "Lines") m_normalLineFillTool->init();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Rect, Polyline etc.
Shinya Kitaoka 120a6e
  else if (propertyName == m_fillType.getName()) {
Shinya Kitaoka 120a6e
    if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
      FillOnion   = (int)(m_onion.getValue());
Shinya Kitaoka 120a6e
      FillSegment = (int)(m_segment.getValue());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    FillType            = ::to_string(m_fillType.getValue());
Shinya Kitaoka 120a6e
    rectPropChangedflag = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Onion Skin
Shinya Kitaoka 120a6e
  else if (propertyName == m_onion.getName()) {
Shinya Kitaoka 120a6e
    if (m_onion.getValue()) FillType = ::to_string(m_fillType.getValue());
shun-iwasawa 3f2d1d
    FillOnion = (int)(m_onion.getValue());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Frame Range
Shinya Kitaoka 120a6e
  else if (propertyName == m_frameRange.getName()) {
Shinya Kitaoka 120a6e
    FillRange = (int)(m_frameRange.getValue());
Shinya Kitaoka 120a6e
    resetMulti();
Shinya Kitaoka 120a6e
    rectPropChangedflag = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Selective
Shinya Kitaoka 120a6e
  else if (propertyName == m_selective.getName()) {
Shinya Kitaoka 120a6e
    rectPropChangedflag = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Fill Depth
Shinya Kitaoka 120a6e
  else if (propertyName == m_fillDepth.getName()) {
Shinya Kitaoka 120a6e
    MinFillDepth = (int)m_fillDepth.getValue().first;
Shinya Kitaoka 120a6e
    MaxFillDepth = (int)m_fillDepth.getValue().second;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // Segment
Shinya Kitaoka 120a6e
  else if (propertyName == m_segment.getName()) {
Shinya Kitaoka 120a6e
    if (m_segment.getValue()) FillType = ::to_string(m_fillType.getValue());
shun-iwasawa 3f2d1d
    FillSegment = (int)(m_segment.getValue());
Shinya Kitaoka 120a6e
  }
Jeremy Bullock e122a9
shun-iwasawa 43640b
  // Autopaint
shun-iwasawa 43640b
  else if (propertyName == m_autopaintLines.getName()) {
shun-iwasawa 43640b
    rectPropChangedflag = true;
shun-iwasawa 43640b
  }
Shinya Kitaoka 120a6e
Jeremy Bullock e122a9
  else if (!m_frameSwitched &&
Jeremy Bullock e122a9
           (propertyName == m_maxGapDistance.getName() ||
Jeremy Bullock e122a9
            propertyName == m_maxGapDistance.getName() + "withUndo")) {
Jeremy Bullock e122a9
    TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel();
Jeremy Bullock e122a9
    m_level       = xl ? xl->getSimpleLevel() : 0;
Jeremy Bullock e122a9
    if (TVectorImageP vi = getImage(true)) {
Jeremy Bullock e122a9
      if (m_changedGapOriginalValue == -1.0) {
Jeremy Bullock e122a9
        ImageUtils::getFillingInformationInArea(vi, m_oldFillInformation,
Jeremy Bullock e122a9
                                                vi->getBBox());
Jeremy Bullock e122a9
        m_changedGapOriginalValue = vi->getAutocloseTolerance();
Jeremy Bullock e122a9
      }
Jeremy Bullock e122a9
      TFrameId fid = getCurrentFid();
Jeremy Bullock e122a9
      vi->setAutocloseTolerance(m_maxGapDistance.getValue());
Jeremy Bullock e122a9
      int count = vi->getStrokeCount();
Jeremy Bullock e122a9
      std::vector<int> v(count);</int>
Jeremy Bullock e122a9
      int i;
Jeremy Bullock e122a9
      for (i = 0; i < (int)count; i++) v[i] = i;
Jeremy Bullock e122a9
      vi->notifyChangedStrokes(v, std::vector<tstroke *="">(), false);</tstroke>
Jeremy Bullock e122a9
Jeremy Bullock e122a9
      if (m_level) {
Jeremy Bullock e122a9
        m_level->setDirtyFlag(true);
Jeremy Bullock e122a9
        TTool::getApplication()->getCurrentLevel()->notifyLevelChange();
Jeremy Bullock e122a9
        if (propertyName == m_maxGapDistance.getName() + "withUndo" &&
Jeremy Bullock e122a9
            m_changedGapOriginalValue != -1.0) {
Jeremy Bullock e122a9
          TUndoManager::manager()->add(new VectorGapSizeChangeUndo(
Jeremy Bullock e122a9
              m_changedGapOriginalValue, m_maxGapDistance.getValue(),
Jeremy Bullock e122a9
              m_level.getPointer(), fid, vi, m_oldFillInformation));
Jeremy Bullock e122a9
          m_changedGapOriginalValue = -1.0;
Jeremy Bullock e122a9
          m_oldFillInformation.clear();
Jeremy Bullock e122a9
          TTool::Application *app = TTool::getApplication();
Jeremy Bullock e122a9
          app->getCurrentXsheet()->notifyXsheetChanged();
Jeremy Bullock e122a9
          notifyImageChanged();
Jeremy Bullock e122a9
        }
Jeremy Bullock e122a9
      }
Jeremy Bullock e122a9
    }
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
Shinya Kitaoka 120a6e
  /*--- fillType, frameRange, selective, colorTypeが変わったとき ---*/
Shinya Kitaoka 120a6e
  if (rectPropChangedflag && m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    AreaFillTool::Type type;
Shinya Kitaoka 120a6e
    if (m_fillType.getValue() == RECTFILL)
Shinya Kitaoka 120a6e
      type = AreaFillTool::RECT;
Shinya Kitaoka 120a6e
    else if (m_fillType.getValue() == FREEHANDFILL)
Shinya Kitaoka 120a6e
      type = AreaFillTool::FREEHAND;
Shinya Kitaoka 120a6e
    else if (m_fillType.getValue() == POLYLINEFILL)
Shinya Kitaoka 120a6e
      type = AreaFillTool::POLYLINE;
justburner 8221ad
    else if (m_fillType.getValue() == FREEPICKFILL)
justburner 8221ad
      type = AreaFillTool::FREEPICK;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
shun-iwasawa 43640b
    m_rectFill->onPropertyChanged(
shun-iwasawa 43640b
        m_frameRange.getValue(), m_selective.getValue(), m_onion.getValue(),
shun-iwasawa 43640b
        type, m_colorType.getValue(), m_autopaintLines.getValue());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
Shinya Kitaoka 120a6e
  if (m_fillType.getValue() != NORMALFILL) m_rectFill->mouseMove(pos, e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::onImageChanged() {
Shinya Kitaoka 120a6e
  if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    m_rectFill->onImageChanged();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Jeremy Bullock e122a9
  if (TVectorImageP vi = getImage(true)) {
Jeremy Bullock e122a9
    m_frameSwitched = true;
Jeremy Bullock e122a9
    if (m_maxGapDistance.getValue() != vi->getAutocloseTolerance()) {
Jeremy Bullock e122a9
      m_maxGapDistance.setValue(vi->getAutocloseTolerance());
Jeremy Bullock e122a9
      getApplication()->getCurrentTool()->notifyToolChanged();
Jeremy Bullock e122a9
    }
Jeremy Bullock e122a9
    m_frameSwitched = false;
Jeremy Bullock e122a9
  }
Shinya Kitaoka 120a6e
  if (!m_level) resetMulti();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jeremy Bullock e122a9
void FillTool::onFrameSwitched() {
Jeremy Bullock e122a9
  m_frameSwitched = true;
Jeremy Bullock e122a9
  if (TVectorImageP vi = getImage(true)) {
Jeremy Bullock e122a9
    if (m_maxGapDistance.getValue() != vi->getAutocloseTolerance()) {
Jeremy Bullock e122a9
      m_maxGapDistance.setValue(vi->getAutocloseTolerance());
Jeremy Bullock e122a9
      getApplication()->getCurrentTool()->notifyToolChanged();
Jeremy Bullock e122a9
    }
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
  m_frameSwitched           = false;
Jeremy Bullock e122a9
  m_changedGapOriginalValue = -1.0;
Jeremy Bullock e122a9
}
Jeremy Bullock e122a9
Jeremy Bullock e122a9
//-----------------------------------------------------------------------------
Jeremy Bullock e122a9
Shinya Kitaoka 120a6e
void FillTool::draw() {
Shinya Kitaoka 120a6e
  if (Preferences::instance()->getFillOnlySavebox()) {
Shinya Kitaoka 120a6e
    TToonzImageP ti = (TToonzImageP)getImage(false);
Shinya Kitaoka 120a6e
    if (ti) {
Shinya Kitaoka 120a6e
      TRectD bbox =
Shinya Kitaoka 120a6e
          ToonzImageUtils::convertRasterToWorld(convert(ti->getBBox()), ti);
Shinya Kitaoka 120a6e
      drawRect(bbox.enlarge(0.5) * ti->getSubsampling(), TPixel32::Black,
Shinya Kitaoka 120a6e
               0x5555, true);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    m_rectFill->draw();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_frameRange.getValue() && m_firstClick) {
Shinya Kitaoka 120a6e
    tglColor(TPixel::Red);
Shinya Kitaoka 120a6e
    drawCross(m_firstPoint, 6);
Shinya Kitaoka 120a6e
  } else if (!m_frameRange.getValue() &&
Shinya Kitaoka 120a6e
             getFillParameters().m_fillType == LINES &&
Shinya Kitaoka 120a6e
             m_targetType == TTool::ToonzImage)
Shinya Kitaoka 120a6e
    m_normalLineFillTool->draw();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 2d0135
int FillTool::pick(const TImageP &image, const TPointD &pos, const int frame) {
Shinya Kitaoka 120a6e
  TToonzImageP ti  = image;
Shinya Kitaoka 120a6e
  TVectorImageP vi = image;
Shinya Kitaoka 120a6e
  if (!ti && !vi) return 0;
Toshihiro Shimizu 890ddd
shun-iwasawa f2e168
  StylePicker picker(getViewer()->viewerWidget(), image);
shun-iwasawa 2d0135
  double scale2 = 1.0;
shun-iwasawa 2d0135
  if (vi) {
shun-iwasawa 2d0135
    TAffine aff = getViewer()->getViewMatrix() * getCurrentColumnMatrix(frame);
shun-iwasawa 2d0135
    scale2      = aff.det();
shun-iwasawa 2d0135
  }
shun-iwasawa 2d0135
  TPointD pickPos = pos;
shun-iwasawa 2d0135
  // in case that the column is animated in scene-editing mode
shun-iwasawa 2d0135
  if (frame > 0) {
shun-iwasawa 2d0135
    TPointD dpiScale = getViewer()->getDpiScale();
shun-iwasawa 2d0135
    pickPos.x *= dpiScale.x;
shun-iwasawa 2d0135
    pickPos.y *= dpiScale.y;
shun-iwasawa 2d0135
    TPointD worldPos = getCurrentColumnMatrix() * pickPos;
shun-iwasawa 2d0135
    pickPos          = getCurrentColumnMatrix(frame).inv() * worldPos;
shun-iwasawa 2d0135
    pickPos.x /= dpiScale.x;
shun-iwasawa 2d0135
    pickPos.y /= dpiScale.y;
shun-iwasawa 2d0135
  }
shun-iwasawa 2d0135
  // thin stroke can be picked with 10 pixel range
shun-iwasawa 2d0135
  return picker.pickStyleId(pickPos, 10.0, scale2);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int FillTool::pickOnionColor(const TPointD &pos) {
Shinya Kitaoka 120a6e
  TTool::Application *app = TTool::getApplication();
Shinya Kitaoka 120a6e
  if (!app) return 0;
Shinya Kitaoka 120a6e
  bool filmStripEditing = !app->getCurrentObject()->isSpline();
Shinya Kitaoka 120a6e
  OnionSkinMask osMask  = app->getCurrentOnionSkin()->getOnionSkinMask();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFrameId fid = getCurrentFid();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshSimpleLevel *sl = m_level.getPointer();
Shinya Kitaoka 120a6e
  if (!sl) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> rows;</int>
Shinya Kitaoka 120a6e
shun-iwasawa 2d0135
  // level editing case
shun-iwasawa 2d0135
  if (app->getCurrentFrame()->isEditingLevel()) {
shun-iwasawa 2d0135
    osMask.getAll(sl->guessIndex(fid), rows);
shun-iwasawa 2d0135
    int i, j;
shun-iwasawa 2d0135
    for (i = 0; i < (int)rows.size(); i++)
shun-iwasawa 2d0135
      if (sl->index2fid(rows[i]) > fid) break;
Shinya Kitaoka 120a6e
shun-iwasawa 2d0135
    int onionStyleId = 0;
shun-iwasawa 2d0135
    for (j = i - 1; j >= 0; j--) {
Shinya Kitaoka 120a6e
      TFrameId onionFid = sl->index2fid(rows[j]);
Shinya Kitaoka 120a6e
      if (onionFid != fid &&
Shinya Kitaoka 120a6e
          ((onionStyleId =
Shinya Kitaoka 120a6e
                pick(m_level->getFrame(onionFid, ImageManager::none, 1), pos)) >
shun-iwasawa 2d0135
           0))  // subsampling must be 1, otherwise onionfill does  not work
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
    }
shun-iwasawa 2d0135
    if (onionStyleId == 0)
shun-iwasawa 2d0135
      for (j = i; j < (int)rows.size(); j++) {
shun-iwasawa 2d0135
        TFrameId onionFid = sl->index2fid(rows[j]);
shun-iwasawa 2d0135
        if (onionFid != fid &&
shun-iwasawa 2d0135
            ((onionStyleId = pick(
shun-iwasawa 2d0135
                  m_level->getFrame(onionFid, ImageManager::none, 1), pos)) >
shun-iwasawa 2d0135
             0))  // subsampling must be 1, otherwise onionfill does  not work
shun-iwasawa 2d0135
          break;
shun-iwasawa 2d0135
      }
shun-iwasawa 2d0135
    return onionStyleId;
shun-iwasawa 2d0135
  } else {  // scene editing case
shun-iwasawa 2d0135
    TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
shun-iwasawa 2d0135
    int colId    = app->getCurrentColumn()->getColumnIndex();
shun-iwasawa 2d0135
    int row      = app->getCurrentFrame()->getFrame();
shun-iwasawa 2d0135
    osMask.getAll(row, rows);
shun-iwasawa 2d0135
    std::vector<int>::iterator it = rows.begin();</int>
shun-iwasawa 2d0135
    while (it != rows.end() && *it < row) it++;
shun-iwasawa 2d0135
    std::sort(rows.begin(), it, descending);
shun-iwasawa 2d0135
    int onionStyleId = 0;
shun-iwasawa 2d0135
    for (int i = 0; i < (int)rows.size(); i++) {
shun-iwasawa 2d0135
      if (rows[i] == row) continue;
shun-iwasawa 2d0135
      TXshCell cell = xsh->getCell(rows[i], colId);
shun-iwasawa 2d0135
      TXshLevel *xl = cell.m_level.getPointer();
shun-iwasawa 2d0135
      if (!xl || xl->getSimpleLevel() != sl) continue;
shun-iwasawa 2d0135
      TFrameId onionFid = cell.getFrameId();
shun-iwasawa 2d0135
      onionStyleId = pick(m_level->getFrame(onionFid, ImageManager::none, 1),
shun-iwasawa 2d0135
                          pos, rows[i]);
shun-iwasawa 2d0135
      if (onionStyleId > 0) break;
shun-iwasawa 2d0135
    }
shun-iwasawa 2d0135
    return onionStyleId;
shun-iwasawa 2d0135
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::onEnter() {
Shinya Kitaoka 120a6e
  // resetMulti();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // getApplication()->editImage();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FillTool::onActivate() {
Shinya Kitaoka 120a6e
  // OnionSkinMask osMask = getApplication()->getOnionSkinMask(false);
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
  for (int i=0; i
Shinya Kitaoka 120a6e
  boh = osMask.getMos(i);
Shinya Kitaoka 120a6e
  for (i=0; i
Shinya Kitaoka 120a6e
  boh = osMask.getFos(i);
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  if (m_firstTime) {
Shinya Kitaoka 120a6e
    m_fillDepth.setValue(
Shinya Kitaoka 120a6e
        TDoublePairProperty::Value(MinFillDepth, MaxFillDepth));
Shinya Kitaoka 120a6e
    m_fillType.setValue(::to_wstring(FillType.getValue()));
Shinya Kitaoka 120a6e
    m_colorType.setValue(::to_wstring(FillColorType.getValue()));
Shinya Kitaoka 120a6e
    //		m_onlyEmpty.setValue(FillSelective ? 1 :0);
Shinya Kitaoka 120a6e
    m_onion.setValue(FillOnion ? 1 : 0);
Shinya Kitaoka 120a6e
    m_segment.setValue(FillSegment ? 1 : 0);
Shinya Kitaoka 120a6e
    m_frameRange.setValue(FillRange ? 1 : 0);
Shinya Kitaoka 120a6e
    m_firstTime = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
      AreaFillTool::Type type;
Shinya Kitaoka 120a6e
      if (m_fillType.getValue() == RECTFILL)
Shinya Kitaoka 120a6e
        type = AreaFillTool::RECT;
Shinya Kitaoka 120a6e
      else if (m_fillType.getValue() == FREEHANDFILL)
Shinya Kitaoka 120a6e
        type = AreaFillTool::FREEHAND;
Shinya Kitaoka 120a6e
      else if (m_fillType.getValue() == POLYLINEFILL)
Shinya Kitaoka 120a6e
        type = AreaFillTool::POLYLINE;
justburner 8221ad
      else if (m_fillType.getValue() == FREEPICKFILL)
justburner 8221ad
        type = AreaFillTool::FREEPICK;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        assert(false);
Shinya Kitaoka 120a6e
shun-iwasawa 43640b
      m_rectFill->onPropertyChanged(
shun-iwasawa 43640b
          m_frameRange.getValue(), m_selective.getValue(), m_onion.getValue(),
shun-iwasawa 43640b
          type, m_colorType.getValue(), m_autopaintLines.getValue());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_fillType.getValue() != NORMALFILL) {
Shinya Kitaoka 120a6e
    m_rectFill->onActivate();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (FillColorType.getValue() == "Lines") m_normalLineFillTool->init();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  resetMulti();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  getApplication()->editImage();
Shinya Kitaoka 120a6e
  TVectorImageP vi = TImageP(getImage(false));
Shinya Kitaoka 120a6e
  if (!vi) return;
Shinya Kitaoka 120a6e
  vi->findRegions();
Jeremy Bullock e122a9
  if (m_targetType == TTool::VectorImage) {
Jeremy Bullock e122a9
    if (m_level) {
Jeremy Bullock e122a9
      TImageP img = getImage(true);
Jeremy Bullock e122a9
      if (TVectorImageP vi = img) {
Jeremy Bullock e122a9
        double tolerance = vi->getAutocloseTolerance();
Jeremy Bullock e122a9
        if (tolerance < 9.9) tolerance += 0.000001;
Jeremy Bullock e122a9
        m_maxGapDistance.setValue(tolerance);
Jeremy Bullock e122a9
      }
Jeremy Bullock e122a9
    }
Jeremy Bullock e122a9
  }
Jeremy Bullock e122a9
  bool ret = true;
Jeremy Bullock e122a9
  ret      = ret && connect(TTool::m_application->getCurrentFrame(),
Jeremy Bullock e122a9
                       SIGNAL(frameSwitched()), this, SLOT(onFrameSwitched()));
shun-iwasawa 3f2d1d
  ret      = ret && connect(TTool::m_application->getCurrentScene(),
Jeremy Bullock e122a9
                       SIGNAL(sceneSwitched()), this, SLOT(onFrameSwitched()));
shun-iwasawa 3f2d1d
  ret      = ret &&
Jeremy Bullock e122a9
        connect(TTool::m_application->getCurrentColumn(),
Jeremy Bullock e122a9
                SIGNAL(columnIndexSwitched()), this, SLOT(onFrameSwitched()));
Jeremy Bullock e122a9
  assert(ret);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jeremy Bullock e122a9
void FillTool::onDeactivate() {
Jeremy Bullock e122a9
  disconnect(TTool::m_application->getCurrentFrame(), SIGNAL(frameSwitched()),
Jeremy Bullock e122a9
             this, SLOT(onFrameSwitched()));
Jeremy Bullock e122a9
  disconnect(TTool::m_application->getCurrentScene(), SIGNAL(sceneSwitched()),
Jeremy Bullock e122a9
             this, SLOT(onFrameSwitched()));
Jeremy Bullock e122a9
  disconnect(TTool::m_application->getCurrentColumn(),
shun-iwasawa b4a8f7
             SIGNAL(columnIndexSwitched()), this, SLOT(onFrameSwitched()));
Jeremy Bullock e122a9
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FillTool FillVectorTool(TTool::VectorImage);
Toshihiro Shimizu 890ddd
FillTool FiilRasterTool(TTool::ToonzImage);