Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tw/mainshell.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tmathutil.h"
Toshihiro Shimizu 890ddd
#include "tproperty.h"
Toshihiro Shimizu 890ddd
#include "tenv.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "ttoonzimage.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzimageutils.h"
Toshihiro Shimizu 890ddd
#include "tools/cursors.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tvectorgl.h"
Toshihiro Shimizu 890ddd
#include "tgl.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/selection.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "trop.h"
Toshihiro Shimizu 890ddd
#include "toonz/ttileset.h"
Toshihiro Shimizu 890ddd
#include "toonz/glrasterpainter.h"
shun_iwasawa 6c2748
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfont.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// For Qt translation support
Toshihiro Shimizu 890ddd
#include <qcoreapplication></qcoreapplication>
manongjohn dc44ed
#include <qclipboard></qclipboard>
manongjohn dc44ed
#include <qapplication></qapplication>
manongjohn dc44ed
#include <qmimedata></qmimedata>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tw/message.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tw/ime.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace ToolUtils;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// helper functions
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void paintRegion(TRegion *region, int styleId, bool paint) {
Shinya Kitaoka 120a6e
  UINT j, regNum = region->getSubregionCount();
Shinya Kitaoka 120a6e
  if (paint) region->setStyle(styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (j = 0; j < regNum; j++)
Shinya Kitaoka 120a6e
    paintRegion(region->getSubregion(j), styleId, !paint);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void paintChar(const TVectorImageP &image, int styleId) {
Shinya Kitaoka 120a6e
  // image->setPalette( getApplication()->getCurrentScene()->getPalette());
Shinya Kitaoka 120a6e
  // image->setPalette(getCurrentPalette());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT j;
Shinya Kitaoka 120a6e
  UINT strokeNum = image->getStrokeCount();
Shinya Kitaoka 120a6e
  for (j = 0; j < strokeNum; j++) image->getStroke(j)->setStyle(styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  image->enableRegionComputing(true, true);
Shinya Kitaoka 120a6e
  image->findRegions();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT regNum = image->getRegionCount();
Shinya Kitaoka 120a6e
  for (j = 0; j < regNum; j++) paintRegion(image->getRegion(j), styleId, true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
// Type, vars, ecc.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TEnv::StringVar EnvCurrentFont("CurrentFont", "MS UI Gothic");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! numero di pixel attorno al testo
Toshihiro Shimizu 890ddd
const double cBorderSize = 15;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// UNDO
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class UndoTypeTool final : public ToolUtils::TToolUndo {
Shinya Kitaoka 120a6e
  std::vector<tstroke *=""> m_strokes;</tstroke>
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> *m_fillInformationBefore,</tfilledregioninf>
Shinya Kitaoka 120a6e
      *m_fillInformationAfter;
Shinya Kitaoka 120a6e
  TVectorImageP m_image;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  UndoTypeTool(std::vector<tfilledregioninf> *fillInformationBefore,</tfilledregioninf>
Shinya Kitaoka 120a6e
               std::vector<tfilledregioninf> *fillInformationAfter,</tfilledregioninf>
Shinya Kitaoka 120a6e
               TXshSimpleLevel *level, const TFrameId &frameId,
Shinya Kitaoka 120a6e
               bool isFrameCreated, bool isLevelCreated)
Shinya Kitaoka 120a6e
      : ToolUtils::TToolUndo(level, frameId, isFrameCreated, isLevelCreated)
Shinya Kitaoka 120a6e
      , m_fillInformationBefore(fillInformationBefore)
Shinya Kitaoka 120a6e
      , m_fillInformationAfter(fillInformationAfter) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~UndoTypeTool() {
Shinya Kitaoka 120a6e
    delete m_fillInformationBefore;
Shinya Kitaoka 120a6e
    delete m_fillInformationAfter;
Shinya Kitaoka 120a6e
    clearPointerContainer(m_strokes);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addStroke(TStroke *stroke) {
Shinya Kitaoka 120a6e
    TStroke *s = new TStroke(*stroke);
Shinya Kitaoka 120a6e
    s->setId(stroke->getId());
Shinya Kitaoka 120a6e
    m_strokes.push_back(s);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void undo() const override {
Shinya Kitaoka 120a6e
    TTool::Application *application = TTool::getApplication();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(!!image);
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
    UINT i;
Shinya Kitaoka 120a6e
    for (i = 0; i < m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
      VIStroke *stroke = image->getStrokeById(m_strokes[i]->getId());
Shinya Kitaoka 120a6e
      if (!stroke) return;
Shinya Kitaoka 120a6e
      image->deleteStroke(stroke);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_fillInformationBefore) {
Shinya Kitaoka 120a6e
      UINT size = m_fillInformationBefore->size();
Shinya Kitaoka 120a6e
      TRegion *reg;
Shinya Kitaoka 120a6e
      for (i = 0; i < size; i++) {
Shinya Kitaoka 120a6e
        reg = image->getRegion((*m_fillInformationBefore)[i].m_regionId);
Shinya Kitaoka 120a6e
        assert(reg);
Shinya Kitaoka 120a6e
        if (reg) reg->setStyle((*m_fillInformationBefore)[i].m_styleId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    removeLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
    application->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
    TVectorImageP image = m_level->getFrame(m_frameId, true);
Shinya Kitaoka 120a6e
    assert(!!image);
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::Application *application = TTool::getApplication();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    QMutexLocker lock(image->getMutex());
Shinya Kitaoka 120a6e
    UINT i;
Shinya Kitaoka 120a6e
    for (i = 0; i < m_strokes.size(); i++) {
Shinya Kitaoka 120a6e
      TStroke *stroke = new TStroke(*m_strokes[i]);
Shinya Kitaoka 120a6e
      stroke->setId(m_strokes[i]->getId());
Shinya Kitaoka 120a6e
      image->addStroke(stroke);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (image->isComputedRegionAlmostOnce()) image->findRegions();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_fillInformationAfter) {
Shinya Kitaoka 120a6e
      UINT size = m_fillInformationAfter->size();
Shinya Kitaoka 120a6e
      TRegion *reg;
Shinya Kitaoka 120a6e
      for (i = 0; i < size; i++) {
Shinya Kitaoka 120a6e
        reg = image->getRegion((*m_fillInformationAfter)[i].m_regionId);
Shinya Kitaoka 120a6e
        assert(reg);
Shinya Kitaoka 120a6e
        if (reg) reg->setStyle((*m_fillInformationAfter)[i].m_styleId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    application->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    if (m_fillInformationAfter && m_fillInformationBefore)
Shinya Kitaoka 120a6e
      return sizeof(*this) +
Shinya Kitaoka 120a6e
             m_fillInformationBefore->capacity() * sizeof(TFilledRegionInf) +
Shinya Kitaoka 120a6e
             m_fillInformationAfter->capacity() * sizeof(TFilledRegionInf) +
Shinya Kitaoka 120a6e
             +m_strokes.capacity() * sizeof(TStroke) + 500;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return sizeof(*this) + m_strokes.capacity() * sizeof(TStroke) + 500;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QString("Type Tool"); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class RasterUndoTypeTool final : public TRasterUndo {
Shinya Kitaoka 120a6e
  TTileSetCM32 *m_afterTiles;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  RasterUndoTypeTool(TTileSetCM32 *beforeTiles, TTileSetCM32 *afterTiles,
Shinya Kitaoka 120a6e
                     TXshSimpleLevel *level, const TFrameId &id,
Shinya Kitaoka 120a6e
                     bool createdFrame, bool createdLevel)
Shinya Kitaoka 120a6e
      : TRasterUndo(beforeTiles, level, id, createdFrame, createdLevel, 0)
Shinya Kitaoka 120a6e
      , m_afterTiles(afterTiles) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~RasterUndoTypeTool() { delete m_afterTiles; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  void redo() const override {
Shinya Kitaoka 120a6e
    insertLevelAndFrameIfNeeded();
Shinya Kitaoka 120a6e
    TToonzImageP image = getImage();
Shinya Kitaoka 120a6e
    if (!image) return;
Shinya Kitaoka 120a6e
    if (m_afterTiles) {
Shinya Kitaoka 120a6e
      ToonzImageUtils::paste(image, m_afterTiles);
Shinya Kitaoka 120a6e
      ToolUtils::updateSaveBox();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();
Shinya Kitaoka 120a6e
    notifyImageChanged();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  int getSize() const override {
Shinya Kitaoka 120a6e
    if (m_afterTiles)
Shinya Kitaoka 120a6e
      return TRasterUndo::getSize() + m_afterTiles->getMemorySize();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return TRasterUndo::getSize();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  QString getToolName() override { return QString("Type Tool"); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeChar
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// E' la TVectorImage che corrisponde ad un carattere
Toshihiro Shimizu 890ddd
// (piu' le varie info che permettono di ricrearlo)
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class StrokeChar {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  // TVectorImageP m_char;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP m_char;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double m_offset;
Shinya Kitaoka 120a6e
  TPointD m_charPosition;
Shinya Kitaoka 120a6e
  int m_key;
Shinya Kitaoka 120a6e
  int m_styleId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StrokeChar(TImageP _char, double offset, int key, int styleId)
Shinya Kitaoka 120a6e
      : m_char(_char)
Shinya Kitaoka 120a6e
      , m_offset(offset)
Shinya Kitaoka 120a6e
      , m_charPosition(TPointD(0, 0))
Shinya Kitaoka 120a6e
      , m_key(key)
Shinya Kitaoka 120a6e
      , m_styleId(styleId) {}
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  bool isReturn() const { return m_key == (int)(QChar('\r').unicode()); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void update(TAffine scale, int nextCode = 0) {
Shinya Kitaoka 120a6e
    if (!isReturn()) {
Shinya Kitaoka 120a6e
      if (TVectorImageP vi = m_char) {
Shinya Kitaoka 120a6e
        vi = m_char = new TVectorImage;
Shinya Kitaoka 120a6e
        TPoint adv  = TFontManager::instance()->drawChar(vi, m_key, nextCode);
Shinya Kitaoka 120a6e
        vi->transform(scale);
Shinya Kitaoka 120a6e
        paintChar(vi, m_styleId);
Shinya Kitaoka 120a6e
        m_offset = (scale * TPointD((double)(adv.x), (double)(adv.y))).x;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        TRasterCM32P newRasterCM;
Shinya Kitaoka 120a6e
        TPoint p;
Shinya Kitaoka 120a6e
        TPoint adv = TFontManager::instance()->drawChar(
Shinya Kitaoka 120a6e
            (TRasterCM32P &)newRasterCM, p, m_styleId, (wchar_t)m_key,
Shinya Kitaoka 120a6e
            (wchar_t)nextCode);
Shinya Kitaoka 120a6e
        // m_char->transform(scale);
Shinya Kitaoka 120a6e
        m_offset = (scale * TPointD((double)(adv.x), (double)(adv.y))).x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        m_char = new TToonzImage(newRasterCM, newRasterCM->getBounds());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  //  namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TypeTool
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class TypeTool final : public TTool {
Shinya Kitaoka 120a6e
  Q_DECLARE_TR_FUNCTIONS(TypeTool)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Properties
Shinya Kitaoka 120a6e
  TEnumProperty m_fontFamilyMenu;
Shinya Kitaoka 120a6e
  TEnumProperty m_typeFaceMenu;
Shinya Kitaoka 120a6e
  TBoolProperty m_vertical;
Shinya Kitaoka 120a6e
  TEnumProperty m_size;
manongjohn b66bc4
  TPropertyGroup m_prop[2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // valori correnti di alcune Properties,
Shinya Kitaoka 120a6e
  // duplicati per permettere controlli sulla validita' o per ottimizzazione
Shinya Kitaoka 120a6e
  std::wstring m_fontFamily;
Shinya Kitaoka 120a6e
  std::wstring m_typeface;
Shinya Kitaoka 120a6e
  double m_dimension;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool m_validFonts;  // false iff there are problems with font loading
Shinya Kitaoka 120a6e
  bool m_initialized;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m_cursorId;
Shinya Kitaoka 120a6e
  int m_styleId;
Shinya Kitaoka 120a6e
  double m_pixelSize;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<strokechar> m_string;</strokechar>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int m_cursorIndex;  // indice del carattere successivo al cursore
Shinya Kitaoka 120a6e
  std::pair<int, int=""> m_preeditRange;</int,>
Shinya Kitaoka 120a6e
  // posizione (dentro m_string) della preeditString (cfr. IME)
Shinya Kitaoka 120a6e
  // n.b. la preeditString va da range.first a range.second-1
Shinya Kitaoka 120a6e
  TRectD m_textBox;  // bbox della stringa
Shinya Kitaoka 120a6e
  TScale m_scale;  // la dimensione dei char ottenuti dal text manager e' fissa
Shinya Kitaoka 120a6e
                   // perche' influisce sula qualita'. Quindi lo scalo
Shinya Kitaoka 120a6e
  TPointD m_cursorPoint;  // punto piu alto del cursore
Shinya Kitaoka 120a6e
  TPointD m_startPoint;   // punto dove si poggia la prima lettera (coincide col
Shinya Kitaoka 120a6e
                          // mouse click)
Shinya Kitaoka 120a6e
  double m_fontYOffset;   // spazio per le parti delle lettere sotto il rigo
Shinya Kitaoka 120a6e
                          // (dipende dal font)
Shinya Kitaoka 120a6e
  bool m_isVertical;      // text orientation
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndo *m_undo;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TypeTool();
Shinya Kitaoka 120a6e
  ~TypeTool();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void updateTranslation() override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  ToolType getToolType() const override { return TTool::LevelWriteTool; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void init();
Shinya Kitaoka 120a6e
  void initTypeFaces();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void loadFonts();
Shinya Kitaoka 120a6e
  void setFont(std::wstring fontFamily);
Shinya Kitaoka 120a6e
  void setTypeface(std::wstring typeface);
Shinya Kitaoka 120a6e
  void setSize(std::wstring size);
Shinya Kitaoka 120a6e
  void setVertical(bool vertical);
Shinya Kitaoka 473e70
  void draw() override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void updateMouseCursor(const TPointD &pos);
Shinya Kitaoka 120a6e
  void updateStrokeChar();
Shinya Kitaoka 120a6e
  void updateCharPositions(int updateFrom = 0);
Shinya Kitaoka 120a6e
  void updateCursorPoint();
Shinya Kitaoka 120a6e
  void updateTextBox();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void setCursorIndexFromPoint(TPointD point);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void mouseMove(const TPointD &pos, const TMouseEvent &) override;
shun-iwasawa 01dafa
  bool preLeftButtonDown() override;
Shinya Kitaoka 473e70
  void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
Shinya Kitaoka 473e70
  void rightButtonDown(const TPointD &pos, const TMouseEvent &) override;
shun-iwasawa 7f1e30
  bool keyDown(QKeyEvent *event) override;
shun-iwasawa 7f1e30
49945e
  void onInputText(const std::wstring &preedit, const std::wstring &commit,
Shinya Kitaoka 473e70
                   int replacementStart, int replacementLen) override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // cancella gli StrokeChar fra from e to-1 e inserisce nuovi StrokeChar
Shinya Kitaoka 120a6e
  // corrispondenti a text a partire da from
Shinya Kitaoka 120a6e
  void replaceText(std::wstring text, int from, int to);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void addBaseChar(std::wstring text);
Shinya Kitaoka 120a6e
  void addReturn();
Shinya Kitaoka 120a6e
  void cursorUp();
Shinya Kitaoka 120a6e
  void cursorDown();
Shinya Kitaoka 120a6e
  void cursorLeft();
Shinya Kitaoka 120a6e
  void cursorRight();
Shinya Kitaoka 120a6e
  void deleteKey();
Shinya Kitaoka 120a6e
  void addTextToImage();
Shinya Kitaoka 120a6e
  void addTextToVectorImage(const TVectorImageP ¤tImage,
Shinya Kitaoka 120a6e
                            std::vector<const *="" tvectorimage=""> &images);</const>
Shinya Kitaoka 120a6e
  void addTextToToonzImage(const TToonzImageP ¤tImage);
Shinya Kitaoka 120a6e
  void stopEditing();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void reset() override;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  void onActivate() override;
Shinya Kitaoka 473e70
  void onDeactivate() override;
Shinya Kitaoka 473e70
  void onImageChanged() override;
Toshihiro Shimizu 890ddd
manongjohn 40a40e
  int getCursorId() const override {
manongjohn 40a40e
    if (m_viewer && m_viewer->getGuidedStrokePickerMode())
manongjohn 40a40e
      return m_viewer->getGuidedStrokePickerCursor();
manongjohn 40a40e
    return m_cursorId;
manongjohn 40a40e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 473e70
  bool onPropertyChanged(std::string propertyName) override;
Toshihiro Shimizu 890ddd
manongjohn b66bc4
  TPropertyGroup *getProperties(int targetType) override {
manongjohn b66bc4
    return &m_prop[targetType];
manongjohn b66bc4
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int getColorClass() const { return 1; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} typeTool;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TypeTool methods
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TypeTool::TypeTool()
Shinya Kitaoka 120a6e
    : TTool("T_Type")
Shinya Kitaoka 120a6e
    , m_textBox(TRectD(0, 0, 0, 0))
Shinya Kitaoka 120a6e
    , m_cursorPoint(TPointD(0, 0))
Shinya Kitaoka 120a6e
    , m_startPoint(TPointD(0, 0))
shun_iwasawa df21fa
    , m_dimension(1)      // to be set the m_size value on the first-click
Shinya Kitaoka 120a6e
    , m_validFonts(true)  // false)
Shinya Kitaoka 120a6e
    , m_fontYOffset(0)
Shinya Kitaoka 120a6e
    , m_cursorId(ToolCursor::CURSOR_NO)
Shinya Kitaoka 120a6e
    , m_pixelSize(1)
Shinya Kitaoka 120a6e
    , m_cursorIndex(0)
Shinya Kitaoka 120a6e
    , m_preeditRange(0, 0)
Shinya Kitaoka 120a6e
    , m_isVertical(false)
Shinya Kitaoka 120a6e
    , m_initialized(false)
Shinya Kitaoka 120a6e
    , m_fontFamilyMenu("Font:")                  // W_ToolOptions_FontName
Shinya Kitaoka 120a6e
    , m_typeFaceMenu("Style:")                   // W_ToolOptions_TypeFace
Shinya Kitaoka 120a6e
    , m_vertical("Vertical Orientation", false)  // W_ToolOptions_Vertical
Shinya Kitaoka 120a6e
    , m_size("Size:")                            // W_ToolOptions_Size
Shinya Kitaoka 120a6e
    , m_undo(0) {
manongjohn 8f8437
  bind(TTool::VectorImage | TTool::ToonzImage | TTool::EmptyTarget);
manongjohn b66bc4
  m_prop[0].bind(m_fontFamilyMenu);
shun_iwasawa df21fa
  // Su mac non e' visibile il menu dello style perche' e' stato inserito nel
shun_iwasawa df21fa
  // nome
shun_iwasawa df21fa
  // della font.
shun_iwasawa df21fa
  //#ifndef MACOSX
manongjohn b66bc4
  m_prop[1].bind(m_typeFaceMenu);
shun_iwasawa df21fa
  //#endif
manongjohn b66bc4
  m_prop[1].bind(m_size);
manongjohn b66bc4
  m_prop[1].bind(m_vertical);
Shinya Kitaoka 120a6e
  m_vertical.setId("Orientation");
Shinya Kitaoka 120a6e
  m_fontFamilyMenu.setId("TypeFont");
Shinya Kitaoka 120a6e
  m_typeFaceMenu.setId("TypeStyle");
Shinya Kitaoka 120a6e
  m_size.setId("TypeSize");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TypeTool::~TypeTool() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::updateTranslation() {
Shinya Kitaoka 120a6e
  m_fontFamilyMenu.setQStringName(tr("Font:"));
Shinya Kitaoka 120a6e
  m_typeFaceMenu.setQStringName(tr("Style:"));
Shinya Kitaoka 120a6e
  m_vertical.setQStringName(tr("Vertical Orientation"));
Shinya Kitaoka 120a6e
  m_size.setQStringName(tr("Size:"));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TypeTool::onPropertyChanged(std::string propertyName) {
Shinya Kitaoka 120a6e
  if (!m_validFonts) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (propertyName == m_fontFamilyMenu.getName()) {
Shinya Kitaoka 120a6e
    setFont(m_fontFamilyMenu.getValue());
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else if (propertyName == m_typeFaceMenu.getName()) {
Shinya Kitaoka 120a6e
    setTypeface(m_typeFaceMenu.getValue());
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else if (propertyName == m_size.getName()) {
Shinya Kitaoka 120a6e
    setSize(m_size.getValue());
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else if (propertyName == m_vertical.getName()) {
Shinya Kitaoka 120a6e
    setVertical(m_vertical.getValue());
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::init() {
Shinya Kitaoka 120a6e
  if (m_initialized) return;
Shinya Kitaoka 120a6e
  m_initialized = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  loadFonts();
Shinya Kitaoka 120a6e
  if (!m_validFonts) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_size.addValue(L"36");
Shinya Kitaoka 120a6e
  m_size.addValue(L"58");
Shinya Kitaoka 120a6e
  m_size.addValue(L"70");
Shinya Kitaoka 120a6e
  m_size.addValue(L"86");
Shinya Kitaoka 120a6e
  m_size.addValue(L"100");
Shinya Kitaoka 120a6e
  m_size.addValue(L"150");
Shinya Kitaoka 120a6e
  m_size.addValue(L"200");
Shinya Kitaoka 120a6e
  m_size.setValue(L"70");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::loadFonts() {
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    instance->loadFontNames();
Shinya Kitaoka 120a6e
    m_validFonts = true;
Shinya Kitaoka 120a6e
  } catch (TFontLibraryLoadingError &) {
Shinya Kitaoka 120a6e
    m_validFonts = false;
Shinya Kitaoka 120a6e
    //    TMessage::error(toString(e.getMessage()));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_validFonts) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<std::wstring> names;</std::wstring>
Shinya Kitaoka 120a6e
  instance->getAllFamilies(names);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (std::vector<std::wstring>::iterator it = names.begin();</std::wstring>
Shinya Kitaoka 120a6e
       it != names.end(); ++it)
Shinya Kitaoka 120a6e
    m_fontFamilyMenu.addValue(*it);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string favFontApp     = EnvCurrentFont;
Shinya Kitaoka 120a6e
  std::wstring favouriteFont = ::to_wstring(favFontApp);
Shinya Kitaoka 120a6e
  if (m_fontFamilyMenu.isValue(favouriteFont)) {
Shinya Kitaoka 120a6e
    m_fontFamilyMenu.setValue(favouriteFont);
Shinya Kitaoka 120a6e
    setFont(favouriteFont);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    setFont(m_fontFamilyMenu.getValue());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
shun_iwasawa 6c2748
  // not used for now
shun_iwasawa 6c2748
  m_scale = TScale();
shun_iwasawa 6c2748
  // m_scale = TScale(m_dimension /
shun_iwasawa 6c2748
  // (double)(TFontManager::instance()->getHeight()));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::initTypeFaces() {
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
  std::vector<std::wstring> typefaces;</std::wstring>
Shinya Kitaoka 120a6e
  instance->getAllTypefaces(typefaces);
Shinya Kitaoka 120a6e
  std::wstring oldTypeface = m_typeFaceMenu.getValue();
Shinya Kitaoka 120a6e
  m_typeFaceMenu.deleteAllValues();
Shinya Kitaoka 120a6e
  for (std::vector<std::wstring>::iterator it = typefaces.begin();</std::wstring>
Shinya Kitaoka 120a6e
       it != typefaces.end(); ++it)
Shinya Kitaoka 120a6e
    m_typeFaceMenu.addValue(*it);
Shinya Kitaoka 120a6e
  if (m_typeFaceMenu.isValue(oldTypeface)) m_typeFaceMenu.setValue(oldTypeface);
manongjohn b66bc4
manongjohn b66bc4
  TTool::getApplication()->getCurrentTool()->notifyToolComboBoxListChanged(
manongjohn b66bc4
      m_typeFaceMenu.getName());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::setFont(std::wstring family) {
Shinya Kitaoka 120a6e
  if (m_fontFamily == family) return;
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    instance->setFamily(family);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_fontFamily             = family;
Shinya Kitaoka 120a6e
    std::wstring oldTypeface = m_typeFaceMenu.getValue();
Shinya Kitaoka 120a6e
    initTypeFaces();
Shinya Kitaoka 120a6e
    if (oldTypeface != m_typeFaceMenu.getValue()) {
Shinya Kitaoka 120a6e
      if (m_typeFaceMenu.isValue(L"Regular")) {
Shinya Kitaoka 120a6e
        m_typeFaceMenu.setValue(L"Regular");
Shinya Kitaoka 120a6e
        m_typeface = L"Regular";
Shinya Kitaoka 120a6e
        instance->setTypeface(L"Regular");
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        m_typeface = m_typeFaceMenu.getValue();
Shinya Kitaoka 120a6e
        instance->setTypeface(m_typeface);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // assert chiaramente vero se oldTypeface!=m_typeFaceMenu.getValue().
Shinya Kitaoka 120a6e
    // Assume che il TFontManager quando cambia family, si ricordi
Shinya Kitaoka 120a6e
    // il vecchio typeface e lo imposti se anche la nuova family lo ha
Shinya Kitaoka 120a6e
    assert(instance->getCurrentTypeface() == m_typeFaceMenu.getValue());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    updateStrokeChar();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    EnvCurrentFont = ::to_string(m_fontFamily);
Shinya Kitaoka 120a6e
  } catch (TFontCreationError &) {
Shinya Kitaoka 120a6e
    //    TMessage::error(toString(e.getMessage()));
Shinya Kitaoka 120a6e
    assert(m_fontFamily == instance->getCurrentFamily());
Shinya Kitaoka 120a6e
    m_fontFamilyMenu.setValue(m_fontFamily);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::setTypeface(std::wstring typeface) {
Shinya Kitaoka 120a6e
  if (m_typeface == typeface) return;
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    instance->setTypeface(typeface);
Shinya Kitaoka 120a6e
    m_typeface = typeface;
Shinya Kitaoka 120a6e
    updateStrokeChar();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
  } catch (TFontCreationError &) {
Shinya Kitaoka 120a6e
    //    TMessage::error(toString(e.getMessage()));
Shinya Kitaoka 120a6e
    assert(m_typeface == instance->getCurrentTypeface());
Shinya Kitaoka 120a6e
    m_typeFaceMenu.setValue(m_typeface);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::setSize(std::wstring strSize) {
Shinya Kitaoka 120a6e
  // font e tool fields update
Shinya Kitaoka 120a6e
  double dimension = std::stod(strSize);
Shinya Kitaoka 120a6e
shun_iwasawa 6c2748
  TImageP img      = getImage(true);
shun_iwasawa 6c2748
  TToonzImageP ti  = img;
shun_iwasawa 6c2748
  TVectorImageP vi = img;
shun_iwasawa 6c2748
  // for vector levels, adjust size according to the ratio between
shun_iwasawa 6c2748
  // the viewer dpi and the vector level's dpi
shun_iwasawa 6c2748
  if (vi) dimension *= Stage::inch / Stage::standardDpi;
shun_iwasawa 6c2748
shun_iwasawa 6c2748
  if (m_dimension == dimension) return;
shun_iwasawa df21fa
  TFontManager::instance()->setSize((int)dimension);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(m_dimension != 0);
Shinya Kitaoka 120a6e
  double ratio = dimension / m_dimension;
Shinya Kitaoka 120a6e
  m_dimension  = dimension;
shun_iwasawa 6c2748
shun_iwasawa 6c2748
  // not used for now
shun_iwasawa 6c2748
  m_scale = TScale();
shun_iwasawa 6c2748
  // m_scale = TScale(m_dimension /
shun_iwasawa 6c2748
  // (double)(TFontManager::instance()->getHeight()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // text update
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_string.empty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_string.size(); i++) {
Shinya Kitaoka 120a6e
    if (TVectorImageP vi = m_string[i].m_char) vi->transform(TScale(ratio));
Shinya Kitaoka 120a6e
    m_string[i].m_offset *= ratio;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (ti)
Shinya Kitaoka 120a6e
    updateStrokeChar();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    updateCharPositions();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::setVertical(bool vertical) {
Shinya Kitaoka 120a6e
  if (vertical == m_isVertical) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_isVertical        = vertical;
Shinya Kitaoka 120a6e
  bool oldHasVertical = TFontManager::instance()->hasVertical();
Shinya Kitaoka 120a6e
  TFontManager::instance()->setVertical(vertical);
Shinya Kitaoka 120a6e
  if (oldHasVertical != TFontManager::instance()->hasVertical())
Shinya Kitaoka 120a6e
    updateStrokeChar();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    updateCharPositions();
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::stopEditing() {
Shinya Kitaoka 120a6e
  if (m_active == false) return;
Shinya Kitaoka 120a6e
  m_active = false;
Shinya Kitaoka 120a6e
  m_string.clear();
Shinya Kitaoka 120a6e
  m_cursorIndex = 0;
Shinya Kitaoka 120a6e
  m_textBox     = TRectD();
Shinya Kitaoka 120a6e
  //  closeImeWindow();
Shinya Kitaoka 120a6e
  //  if(m_viewer) m_viewer->enableIme(false);
Shinya Kitaoka 120a6e
  //  enableShortcuts(true);
Shinya Kitaoka 120a6e
  m_preeditRange = std::make_pair(0, 0);
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
  if (m_undo) {
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(m_undo);
Shinya Kitaoka 120a6e
    m_undo = 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::updateStrokeChar() {
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
shun_iwasawa 6c2748
  // not used for now
shun_iwasawa 6c2748
  m_scale = TScale();
shun_iwasawa 6c2748
  // m_scale = TScale(m_dimension / (double)(instance->getHeight()));
shun_iwasawa 6c2748
Shinya Kitaoka 120a6e
  bool hasKerning = instance->hasKerning();
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_string.size(); i++) {
Shinya Kitaoka 120a6e
    if (hasKerning && i + 1 < m_string.size() && !m_string[i + 1].isReturn())
Shinya Kitaoka 120a6e
      m_string[i].update(/*m_font,*/ m_scale, m_string[i + 1].m_key);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_string[i].update(/*m_font,*/ m_scale);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  updateCharPositions();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::updateCharPositions(int updateFrom) {
Shinya Kitaoka 120a6e
  if (updateFrom < 0) updateFrom = 0;
shun-iwasawa b22463
  UINT size = m_string.size();
Shinya Kitaoka 120a6e
  TPointD currentOffset;
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
shun_iwasawa 6c2748
  m_fontYOffset          = (double)(instance->getLineSpacing()) * m_scale.a11;
shun_iwasawa 6c2748
  double descent         = (double)(instance->getLineDescender()) * m_scale.a11;
shun_iwasawa 6c2748
  double height          = (double)(instance->getHeight()) * m_scale.a11;
shun_iwasawa 6c2748
  double vLineSpacing =
shun_iwasawa 6c2748
      (double)(instance->getAverageCharWidth()) * 2.0 * m_scale.a11;
shun_iwasawa 6c2748
shun_iwasawa 6c2748
  // Update from "updateFrom"
Shinya Kitaoka 120a6e
  if (updateFrom > 0) {
Shinya Kitaoka 120a6e
    if ((int)m_string.size() <= updateFrom - 1) return;
Shinya Kitaoka 120a6e
    currentOffset = m_string[updateFrom - 1].m_charPosition - m_startPoint;
shun_iwasawa 6c2748
    // Vertical case
Shinya Kitaoka 120a6e
    if (m_isVertical && !instance->hasVertical()) {
Shinya Kitaoka 120a6e
      if (m_string[updateFrom - 1].isReturn())
shun_iwasawa 6c2748
        currentOffset = TPointD(currentOffset.x - vLineSpacing, -height);
Shinya Kitaoka 120a6e
      else
shun_iwasawa 6c2748
        currentOffset = currentOffset + TPointD(0, -height);
shun_iwasawa 6c2748
    }
shun_iwasawa 6c2748
    // Horizontal case
shun_iwasawa 6c2748
    else {
Shinya Kitaoka 120a6e
      if (m_string[updateFrom - 1].isReturn())
shun_iwasawa 6c2748
        currentOffset = TPointD(0, currentOffset.y - m_fontYOffset);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        currentOffset =
Shinya Kitaoka 120a6e
            currentOffset + TPointD(m_string[updateFrom - 1].m_offset, 0);
Shinya Kitaoka 120a6e
    }
shun_iwasawa 6c2748
  }
shun_iwasawa 6c2748
  // Update whole characters
shun_iwasawa 6c2748
  else {
shun_iwasawa 6c2748
    if (m_isVertical && !instance->hasVertical())
shun_iwasawa 6c2748
      currentOffset = currentOffset + TPointD(0, -height);
shun_iwasawa 6c2748
    else
shun_iwasawa 6c2748
      currentOffset = currentOffset + TPointD(0, -descent);
shun_iwasawa 6c2748
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT j = updateFrom; j < size; j++) {
Shinya Kitaoka 120a6e
    m_string[j].m_charPosition = m_startPoint + currentOffset;
shun_iwasawa 6c2748
    // Vertical case
Shinya Kitaoka 120a6e
    if (m_isVertical && !instance->hasVertical()) {
Shinya Kitaoka 120a6e
      if (m_string[j].isReturn() || m_string[j].m_key == ' ')
shun_iwasawa 6c2748
        currentOffset = TPointD(currentOffset.x - vLineSpacing, -height);
Shinya Kitaoka 120a6e
      else
shun_iwasawa 6c2748
        currentOffset = currentOffset + TPointD(0, -height);
shun_iwasawa 6c2748
    }
shun_iwasawa 6c2748
    // Horizontal case
shun_iwasawa 6c2748
    else {
Shinya Kitaoka 120a6e
      if (m_string[j].isReturn())
shun_iwasawa 6c2748
        currentOffset = TPointD(0, currentOffset.y - m_fontYOffset);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        currentOffset = currentOffset + TPointD(m_string[j].m_offset, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // To be sure
Shinya Kitaoka 120a6e
  if (m_cursorIndex <= (int)m_string.size()) {
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    updateTextBox();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::updateCursorPoint() {
Shinya Kitaoka 120a6e
  assert(0 <= m_cursorIndex && m_cursorIndex <= (int)m_string.size());
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
shun_iwasawa 6c2748
  double descent         = (double)(instance->getLineDescender()) * m_scale.a11;
shun_iwasawa 6c2748
  double height          = (double)(instance->getHeight()) * m_scale.a11;
shun_iwasawa 6c2748
  double vLineSpacing =
shun_iwasawa 6c2748
      (double)(instance->getAverageCharWidth()) * 2.0 * m_scale.a11;
shun_iwasawa 6c2748
  m_fontYOffset          = (double)(instance->getLineSpacing()) * m_scale.a11;
shun_iwasawa 6c2748
  double scaledDimension = m_dimension * m_scale.a11;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_string.empty()) {
Shinya Kitaoka 120a6e
    if (!m_isVertical || instance->hasVertical())
shun_iwasawa 6c2748
      m_cursorPoint = m_startPoint + TPointD(0, scaledDimension);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_cursorPoint = m_startPoint;
Shinya Kitaoka 120a6e
  } else if (m_cursorIndex == (int)m_string.size()) {
shun_iwasawa 6c2748
    // Horizontal case
Shinya Kitaoka 120a6e
    if (!m_isVertical || instance->hasVertical()) {
Shinya Kitaoka 120a6e
      if (m_string.back().isReturn())
Shinya Kitaoka 120a6e
        m_cursorPoint = TPointD(
shun_iwasawa 6c2748
            m_startPoint.x, m_string.back().m_charPosition.y - m_fontYOffset +
shun_iwasawa 6c2748
                                scaledDimension + descent);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_cursorPoint = m_string.back().m_charPosition +
Shinya Kitaoka 120a6e
                        TPointD(m_string.back().m_offset, 0) +
shun_iwasawa 6c2748
                        TPointD(0, scaledDimension + descent);
shun_iwasawa 6c2748
    }
shun_iwasawa 6c2748
    // Vertical case
shun_iwasawa 6c2748
    else {
shun_iwasawa 6c2748
      if (m_string.back().isReturn())
shun_iwasawa 6c2748
        m_cursorPoint = TPointD(m_string.back().m_charPosition.x - vLineSpacing,
shun_iwasawa 6c2748
                                m_startPoint.y);
shun_iwasawa 6c2748
      else
shun_iwasawa 6c2748
        m_cursorPoint = m_string.back().m_charPosition;
shun_iwasawa 6c2748
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (!m_isVertical || instance->hasVertical())
Shinya Kitaoka 120a6e
      m_cursorPoint = m_string[m_cursorIndex].m_charPosition +
shun_iwasawa 6c2748
                      TPointD(0, scaledDimension + descent);
Shinya Kitaoka 120a6e
    else
shun_iwasawa 6c2748
      m_cursorPoint =
shun_iwasawa 6c2748
          m_string[m_cursorIndex].m_charPosition + TPointD(0, height);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::updateTextBox() {
Shinya Kitaoka 120a6e
  UINT size                = m_string.size();
Shinya Kitaoka 120a6e
  UINT returnNumber        = 0;
Shinya Kitaoka 120a6e
  double currentLineLength = 0;
Shinya Kitaoka 120a6e
  double maxXLength        = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
shun_iwasawa 6c2748
  double descent         = (double)(instance->getLineDescender()) * m_scale.a11;
shun_iwasawa 6c2748
  double height          = (double)(instance->getHeight()) * m_scale.a11;
shun_iwasawa 6c2748
  double vLineSpacing =
shun_iwasawa 6c2748
      (double)(instance->getAverageCharWidth()) * 2.0 * m_scale.a11;
shun_iwasawa 6c2748
  m_fontYOffset = (double)(instance->getLineSpacing()) * m_scale.a11;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT j = 0; j < size; j++) {
Shinya Kitaoka 120a6e
    if (m_string[j].isReturn()) {
Shinya Kitaoka 120a6e
      if (currentLineLength > maxXLength) {
Shinya Kitaoka 120a6e
        maxXLength = currentLineLength;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      currentLineLength = 0;
Shinya Kitaoka 120a6e
      returnNumber++;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      currentLineLength += (m_isVertical && !instance->hasVertical())
shun_iwasawa 6c2748
                               ? height
Shinya Kitaoka 120a6e
                               : m_string[j].m_offset;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (currentLineLength > maxXLength)  // last line
Shinya Kitaoka 120a6e
    maxXLength = currentLineLength;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_isVertical && !instance->hasVertical())
shun_iwasawa 6c2748
    m_textBox = TRectD(m_startPoint.x - vLineSpacing * returnNumber,
Shinya Kitaoka 120a6e
                       m_startPoint.y - maxXLength,
shun_iwasawa 6c2748
                       m_startPoint.x + vLineSpacing, m_startPoint.y)
Shinya Kitaoka 120a6e
                    .enlarge(cBorderSize * m_pixelSize);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_textBox =
Shinya Kitaoka 120a6e
        TRectD(m_startPoint.x,
shun_iwasawa 6c2748
               m_startPoint.y - (m_fontYOffset * returnNumber + descent),
shun_iwasawa 6c2748
               m_startPoint.x + maxXLength, m_startPoint.y + height)
Shinya Kitaoka 120a6e
            .enlarge(cBorderSize * m_pixelSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::updateMouseCursor(const TPointD &pos) {
Shinya Kitaoka 120a6e
  int oldCursor = m_cursorId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_validFonts)
Shinya Kitaoka 120a6e
    m_cursorId = ToolCursor::CURSOR_NO;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TPointD clickPoint =
Shinya Kitaoka 120a6e
        (TFontManager::instance()->hasVertical() && m_isVertical)
Shinya Kitaoka 120a6e
            ? TRotation(m_startPoint, 90) * pos
Shinya Kitaoka 120a6e
            : pos;
Shinya Kitaoka 120a6e
    if (m_textBox == TRectD(0, 0, 0, 0) || m_string.empty() ||
Shinya Kitaoka 120a6e
        !m_textBox.contains(clickPoint))
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::TypeOutCursor;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_cursorId = ToolCursor::TypeInCursor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  if(oldCursor != m_cursorId)
Shinya Kitaoka 120a6e
  //    TNotifier::instance()->notify(TToolChange());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::draw() {
Shinya Kitaoka 120a6e
  if (!m_active || !getImage(false)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*TAffine viewMatrix = getViewer()->getViewMatrix();
Shinya Kitaoka 120a6e
glPushMatrix();
Shinya Kitaoka 120a6e
  tglMultMatrix(viewMatrix);*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (instance->hasVertical() && m_isVertical) {
Shinya Kitaoka 120a6e
    glPushMatrix();
Shinya Kitaoka 120a6e
    tglMultMatrix(TRotation(m_startPoint, -90));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // draw text
Shinya Kitaoka 120a6e
  UINT size = m_string.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPoint descenderP(0, TFontManager::instance()->getLineDescender());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int j = 0; j < (int)size; j++) {
Shinya Kitaoka 120a6e
    if (m_string[j].isReturn()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TImageP img = TImageP(getImage(false));
Shinya Kitaoka 120a6e
    assert(!!img);
Shinya Kitaoka 120a6e
    if (!img) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPalette *vPalette = img->getPalette();
Shinya Kitaoka 120a6e
    assert(vPalette);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double charWidth = 0;
Shinya Kitaoka 120a6e
    if (TVectorImageP vi = m_string[j].m_char) {
shun_iwasawa df21fa
      TTranslation transl(convert(descenderP) + m_string[j].m_charPosition);
Shinya Kitaoka 120a6e
      const TVectorRenderData rd(transl, TRect(), vPalette, 0, false);
Shinya Kitaoka 120a6e
      tglDraw(rd, vi.getPointer());
Shinya Kitaoka 120a6e
      charWidth = vi->getBBox().getLx();
Shinya Kitaoka 120a6e
    } else if (TToonzImageP ti = m_string[j].m_char) {
Shinya Kitaoka 120a6e
      TDimension dim = ti->getSize();
Shinya Kitaoka 120a6e
      ti->setPalette(vPalette);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPoint rasterCenter(dim.lx / 2, dim.ly / 2);
shun_iwasawa df21fa
      TTranslation transl1(convert(rasterCenter));
Shinya Kitaoka 120a6e
      TTranslation transl2(m_string[j].m_charPosition);
Shinya Kitaoka 120a6e
      GLRasterPainter::drawRaster(transl2 * m_scale * transl1, ti, false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPointD adjustedDim = m_scale * TPointD(dim.lx, dim.ly);
Shinya Kitaoka 120a6e
      charWidth           = adjustedDim.x;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // sottolineo i caratteri della preedit string
Shinya Kitaoka 120a6e
    if (m_preeditRange.first <= j && j < m_preeditRange.second) {
Shinya Kitaoka 120a6e
      TPointD a(m_string[j].m_charPosition);
Shinya Kitaoka 120a6e
      TPointD b = a + TPointD(charWidth, 0);
Shinya Kitaoka 120a6e
      glColor3d(1, 0, 0);
Shinya Kitaoka 120a6e
      tglDrawSegment(a, b);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // draw textbox
Shinya Kitaoka 120a6e
  double pixelSize = sqrt(tglGetPixelSize2());
Shinya Kitaoka 120a6e
  if (!isAlmostZero(pixelSize - m_pixelSize)) {
Shinya Kitaoka 120a6e
    m_textBox   = m_textBox.enlarge((pixelSize - m_pixelSize) * cBorderSize);
Shinya Kitaoka 120a6e
    m_pixelSize = pixelSize;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TPixel32 boxColor = TPixel32::Black;
Shinya Kitaoka 120a6e
  ToolUtils::drawRect(m_textBox, boxColor, 0x5555);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_active) {
Shinya Kitaoka 120a6e
    // draw cursor
Shinya Kitaoka 120a6e
    tglColor(TPixel32::Black);
Shinya Kitaoka 120a6e
    if (!m_isVertical || instance->hasVertical())
shun_iwasawa 6c2748
      tglDrawSegment(m_cursorPoint,
shun_iwasawa 6c2748
                     m_cursorPoint + m_scale * TPointD(0, -m_dimension));
Shinya Kitaoka 120a6e
    else
shun_iwasawa 6c2748
      tglDrawSegment(m_cursorPoint,
shun_iwasawa 6c2748
                     m_cursorPoint + m_scale * TPointD(m_dimension, 0));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD drawableCursor = m_cursorPoint;
Shinya Kitaoka 120a6e
  if (instance->hasVertical() && m_isVertical) {
Shinya Kitaoka 120a6e
    drawableCursor = TRotation(m_startPoint, -90) * drawableCursor;
Shinya Kitaoka 120a6e
    glPopMatrix();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // glPopMatrix();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  TPoint ipos = m_viewer->toolToMouse(drawableCursor);
Shinya Kitaoka 120a6e
  //  setImePosition(ipos.x, ipos.y, (int)m_dimension);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::addTextToVectorImage(const TVectorImageP ¤tImage,
Shinya Kitaoka 120a6e
                                    std::vector<const *="" tvectorimage=""> &images) {</const>
Shinya Kitaoka 120a6e
  UINT oldSize = currentImage->getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> *fillInformationBefore =</tfilledregioninf>
Shinya Kitaoka 120a6e
      new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
  ImageUtils::getFillingInformationOverlappingArea(
Shinya Kitaoka 120a6e
      currentImage, *fillInformationBefore, m_textBox);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  currentImage->mergeImage(images);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tfilledregioninf> *fillInformationAfter =</tfilledregioninf>
Shinya Kitaoka 120a6e
      new std::vector<tfilledregioninf>;</tfilledregioninf>
Shinya Kitaoka 120a6e
  ImageUtils::getFillingInformationOverlappingArea(
Shinya Kitaoka 120a6e
      currentImage, *fillInformationAfter, m_textBox);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT newSize = currentImage->getStrokeCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshSimpleLevel *level =
Shinya Kitaoka 120a6e
      TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
  UndoTypeTool *undo =
Shinya Kitaoka 120a6e
      new UndoTypeTool(fillInformationBefore, fillInformationAfter, level,
Shinya Kitaoka 120a6e
                       getCurrentFid(), m_isFrameCreated, m_isLevelCreated);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT j = oldSize; j < newSize; j++)
Shinya Kitaoka 120a6e
    undo->addStroke(currentImage->getStroke(j));
Shinya Kitaoka 120a6e
  TUndoManager::manager()->add(undo);
Shinya Kitaoka 120a6e
  if (m_undo) {
Shinya Kitaoka 120a6e
    delete m_undo;
Shinya Kitaoka 120a6e
    m_undo = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::addTextToToonzImage(const TToonzImageP ¤tImage) {
Shinya Kitaoka 120a6e
  UINT size = m_string.size();
Shinya Kitaoka 120a6e
  if (size == 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // TPalette *palette  = currentImage->getPalette();
Shinya Kitaoka 120a6e
  // currentImage->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterCM32P targetRaster = currentImage->getRaster();
Shinya Kitaoka 120a6e
  TRect changedArea;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT j;
Shinya Kitaoka 120a6e
  for (j = 0; j < size; j++) {
Shinya Kitaoka 120a6e
    if (m_string[j].isReturn()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (TToonzImageP ti = m_string[j].m_char) {
shun_iwasawa df21fa
      TRectD srcBBox  = ti->getBBox() + m_string[j].m_charPosition;
shun_iwasawa df21fa
      TDimensionD dim = srcBBox.getSize();
shun_iwasawa df21fa
      TDimensionD enlargeAmount(dim.lx * (m_scale.a11 - 1.0),
shun_iwasawa df21fa
                                dim.ly * (m_scale.a22 - 1.0));
shun_iwasawa df21fa
      changedArea += ToonzImageUtils::convertWorldToRaster(
shun_iwasawa df21fa
          srcBBox.enlarge(enlargeAmount), currentImage);
Shinya Kitaoka 120a6e
      /*
Shinya Kitaoka 120a6e
if( instance->hasVertical() && m_isVertical)
Shinya Kitaoka 120a6e
vi->transform( TRotation(m_startPoint,-90) );
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!changedArea.isEmpty()) {
Shinya Kitaoka 120a6e
    TTileSetCM32 *beforeTiles = new TTileSetCM32(targetRaster->getSize());
Shinya Kitaoka 120a6e
    beforeTiles->add(targetRaster, changedArea);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (j = 0; j < size; j++) {
Shinya Kitaoka 120a6e
      if (m_string[j].isReturn()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (TToonzImageP srcTi = m_string[j].m_char) {
Shinya Kitaoka 120a6e
        TRasterCM32P srcRaster = srcTi->getRaster();
Shinya Kitaoka 120a6e
        TTranslation transl2(m_string[j].m_charPosition +
Shinya Kitaoka 120a6e
                             convert(targetRaster->getCenter()));
shun_iwasawa df21fa
        TRop::over(targetRaster, srcRaster, transl2 * m_scale);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TTileSetCM32 *afterTiles = new TTileSetCM32(targetRaster->getSize());
Shinya Kitaoka 120a6e
    afterTiles->add(targetRaster, changedArea);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TXshSimpleLevel *sl =
Shinya Kitaoka 120a6e
        TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Shinya Kitaoka 120a6e
    TFrameId id = getCurrentFid();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TUndoManager::manager()->add(new RasterUndoTypeTool(
Shinya Kitaoka 120a6e
        beforeTiles, afterTiles, sl, id, m_isFrameCreated, m_isLevelCreated));
Shinya Kitaoka 120a6e
    if (m_undo) {
Shinya Kitaoka 120a6e
      delete m_undo;
Shinya Kitaoka 120a6e
      m_undo = 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ToolUtils::updateSaveBox();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::addTextToImage() {
Shinya Kitaoka 120a6e
  if (!m_validFonts) return;
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT size = m_string.size();
Shinya Kitaoka 120a6e
  if (size == 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TImageP img      = getImage(true);
Shinya Kitaoka 120a6e
  TVectorImageP vi = img;
Shinya Kitaoka 120a6e
  TToonzImageP ti  = img;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!vi && !ti) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (vi) {
Shinya Kitaoka 120a6e
    QMutexLocker lock(vi->getMutex());
Shinya Kitaoka 120a6e
    std::vector<const *="" tvectorimage=""> images;</const>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    UINT j;
Shinya Kitaoka 120a6e
    for (j = 0; j < size; j++) {
Shinya Kitaoka 120a6e
      if (m_string[j].isReturn()) continue;
Toshihiro Shimizu 890ddd
shun_iwasawa df21fa
      TPoint descenderP(0, TFontManager::instance()->getLineDescender());
Shinya Kitaoka 120a6e
      if (TVectorImageP vi = m_string[j].m_char) {
shun_iwasawa df21fa
        vi->transform(
shun_iwasawa df21fa
            TTranslation(convert(descenderP) + m_string[j].m_charPosition));
Shinya Kitaoka 120a6e
        if (instance->hasVertical() && m_isVertical)
Shinya Kitaoka 120a6e
          vi->transform(TRotation(m_startPoint, -90));
Shinya Kitaoka 120a6e
        images.push_back(vi.getPointer());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    addTextToVectorImage(vi, images);
Shinya Kitaoka 120a6e
  } else if (ti)
Shinya Kitaoka 120a6e
    addTextToToonzImage(ti);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  notifyImageChanged();
Shinya Kitaoka 120a6e
  //  getApplication()->notifyImageChanges();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_string.clear();
Shinya Kitaoka 120a6e
  m_cursorIndex = 0;
Shinya Kitaoka 120a6e
  m_textBox     = TRectD();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::setCursorIndexFromPoint(TPointD point) {
Shinya Kitaoka 120a6e
  UINT size = m_string.size();
Shinya Kitaoka 120a6e
  int line  = 0;
Shinya Kitaoka 120a6e
  int retNum;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_isVertical)
Shinya Kitaoka 120a6e
    retNum =
Shinya Kitaoka 120a6e
        tround((m_startPoint.y + m_dimension - point.y) / m_dimension - 0.5);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    retNum = tround((m_startPoint.x - point.x) / m_dimension + 0.5);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT j = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; line < retNum && j < size; j++)
Shinya Kitaoka 120a6e
    if (m_string[j].isReturn()) line++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (j == size) {
Shinya Kitaoka 120a6e
    m_cursorIndex  = size;
Shinya Kitaoka 120a6e
    m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double currentDispl = !m_isVertical ? m_startPoint.x : m_startPoint.y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; j < size; j++) {
Shinya Kitaoka 120a6e
    if (m_string[j].isReturn()) {
Shinya Kitaoka 120a6e
      m_cursorIndex  = j;
Shinya Kitaoka 120a6e
      m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (!m_isVertical) {
Shinya Kitaoka 120a6e
        currentDispl += m_string[j].m_offset;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (currentDispl > point.x) {
Shinya Kitaoka 120a6e
          if (fabs(currentDispl - m_string[j].m_offset - point.x) <
Shinya Kitaoka 120a6e
              fabs(currentDispl - point.x))
Shinya Kitaoka 120a6e
            m_cursorIndex = j;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            m_cursorIndex = j + 1;
shun-iwasawa b22463
          m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
          return;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        if (!TFontManager::instance()->hasVertical()) {
Shinya Kitaoka 120a6e
          currentDispl -= m_dimension;
Shinya Kitaoka 120a6e
          if (currentDispl < point.y) {
Shinya Kitaoka 120a6e
            if (fabs(currentDispl + m_dimension - point.y) <
Shinya Kitaoka 120a6e
                fabs(currentDispl - point.y))
Shinya Kitaoka 120a6e
              m_cursorIndex = j;
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              m_cursorIndex = j + 1;
shun-iwasawa b22463
            m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
            return;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          currentDispl -= m_string[j].m_offset;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (currentDispl < point.y) {
Shinya Kitaoka 120a6e
            if (fabs(currentDispl + m_string[j].m_offset - point.y) <
Shinya Kitaoka 120a6e
                fabs(currentDispl - point.y))
Shinya Kitaoka 120a6e
              m_cursorIndex = j;
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              m_cursorIndex = j + 1;
shun-iwasawa b22463
            m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
            return;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (j == size) {
Shinya Kitaoka 120a6e
    m_cursorIndex  = j;
Shinya Kitaoka 120a6e
    m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::mouseMove(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  updateMouseCursor(pos);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 01dafa
bool TypeTool::preLeftButtonDown() {
shun-iwasawa 01dafa
  if (getViewer() && getViewer()->getGuidedStrokePickerMode()) return false;
shun-iwasawa 01dafa
shun-iwasawa 71d24f
  if (m_validFonts && !m_active) touchImage();
shun-iwasawa 01dafa
  return true;
shun-iwasawa 01dafa
}
shun-iwasawa 01dafa
shun-iwasawa 01dafa
//---------------------------------------------------------
shun-iwasawa 01dafa
Shinya Kitaoka 120a6e
void TypeTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  TSelection::setCurrent(0);
Shinya Kitaoka 120a6e
manongjohn 40a40e
  if (getViewer() && getViewer()->getGuidedStrokePickerMode()) {
manongjohn 40a40e
    getViewer()->doPickGuideStroke(pos);
manongjohn 40a40e
    return;
manongjohn 40a40e
  }
manongjohn 40a40e
Shinya Kitaoka 120a6e
  if (!m_validFonts) return;
Shinya Kitaoka 120a6e
shun-iwasawa 71d24f
  TImageP img      = getImage(true);
Shinya Kitaoka 120a6e
  TVectorImageP vi = img;
Shinya Kitaoka 120a6e
  TToonzImageP ti  = img;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!vi && !ti) return;
Shinya Kitaoka 120a6e
shun_iwasawa df21fa
  setSize(m_size.getValue());
shun_iwasawa df21fa
Shinya Kitaoka 120a6e
  if (m_isFrameCreated) {
Shinya Kitaoka 120a6e
    if (vi)
Shinya Kitaoka 120a6e
      m_undo = new UndoTypeTool(
Shinya Kitaoka 120a6e
          0, 0, getApplication()->getCurrentLevel()->getSimpleLevel(),
Shinya Kitaoka 120a6e
          getCurrentFid(), m_isFrameCreated, m_isLevelCreated);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_undo = new RasterUndoTypeTool(
Shinya Kitaoka 120a6e
          0, 0, getApplication()->getCurrentLevel()->getSimpleLevel(),
Shinya Kitaoka 120a6e
          getCurrentFid(), m_isFrameCreated, m_isLevelCreated);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  closeImeWindow();
Shinya Kitaoka 120a6e
  //  if(m_viewer) m_viewer->enableIme(true);
Shinya Kitaoka 120a6e
  m_active = true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_string.empty()) {
Shinya Kitaoka 120a6e
    TPointD clickPoint =
Shinya Kitaoka 120a6e
        (TFontManager::instance()->hasVertical() && m_isVertical)
Shinya Kitaoka 120a6e
            ? TRotation(m_startPoint, 90) * pos
Shinya Kitaoka 120a6e
            : pos;
Shinya Kitaoka 120a6e
    if (m_textBox.contains(clickPoint)) {
Shinya Kitaoka 120a6e
      setCursorIndexFromPoint(pos);
Shinya Kitaoka 120a6e
      updateCursorPoint();
Shinya Kitaoka 120a6e
      invalidate();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      resetInputMethod();
Shinya Kitaoka 120a6e
      addTextToImage();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_startPoint = pos;
Shinya Kitaoka 120a6e
  updateTextBox();
Shinya Kitaoka 120a6e
  updateCursorPoint();
Shinya Kitaoka 120a6e
  updateMouseCursor(pos);
Shinya Kitaoka 120a6e
  //  enableShortcuts(false);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::rightButtonDown(const TPointD &pos, const TMouseEvent &) {
Shinya Kitaoka 120a6e
  if (!m_validFonts) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_string.empty())
Shinya Kitaoka 120a6e
    addTextToImage();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    stopEditing();
Shinya Kitaoka 120a6e
  m_cursorIndex = 0;
Shinya Kitaoka 120a6e
  updateMouseCursor(pos);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// cancella [from,to[ da m_string e lo rimpiazza con text
Toshihiro Shimizu 890ddd
// n.b. NON fa updateCharPositions()
Shinya Kitaoka 120a6e
void TypeTool::replaceText(std::wstring text, int from, int to) {
Shinya Kitaoka 120a6e
  int stringLength = m_string.size();
Shinya Kitaoka 120a6e
  from             = tcrop(from, 0, stringLength);
Shinya Kitaoka 120a6e
  to               = tcrop(to, from, stringLength);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // cancello i vecchi caratteri
Shinya Kitaoka 120a6e
  m_string.erase(m_string.begin() + from, m_string.begin() + to);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // aggiungo i nuovi
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
  int styleId            = TTool::getApplication()->getCurrentLevelStyleIndex();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP img      = getImage(true);
Shinya Kitaoka 120a6e
  TToonzImageP ti  = img;
Shinya Kitaoka 120a6e
  TVectorImageP vi = img;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPoint adv;
Shinya Kitaoka 120a6e
  TPointD d_adv;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (unsigned int i = 0; i < (unsigned int)text.size(); i++) {
Shinya Kitaoka 120a6e
    wchar_t character = text[i];
Shinya Kitaoka 120a6e
shun-iwasawa 8a5ab1
    // line break case. This can happen when pasting text including the line
shun-iwasawa 8a5ab1
    // break
shun-iwasawa 8a5ab1
    if (character == '\r') {
shun-iwasawa 8a5ab1
      TVectorImageP vi(new TVectorImage);
shun-iwasawa 8a5ab1
      unsigned int index = from + i;
shun-iwasawa 8a5ab1
      m_string.insert(m_string.begin() + index,
shun-iwasawa 8a5ab1
                      StrokeChar(vi, -1., (int)(QChar('\r').unicode()), 0));
shun-iwasawa 8a5ab1
    }
shun-iwasawa 8a5ab1
shun-iwasawa 8a5ab1
    else if (vi) {
Shinya Kitaoka 120a6e
      TVectorImageP characterImage(new TVectorImage());
Shinya Kitaoka 120a6e
      unsigned int index = from + i;
Shinya Kitaoka 120a6e
      // se il font ha kerning bisogna tenere conto del carattere successivo
Shinya Kitaoka 120a6e
      // (se c'e' e non e' un CR) per calcolare correttamente la distanza adv
Shinya Kitaoka 120a6e
      TPoint adv;
Shinya Kitaoka 120a6e
      if (instance->hasKerning() && index < m_string.size() &&
Shinya Kitaoka 120a6e
          !m_string[index].isReturn())
Shinya Kitaoka 120a6e
        adv = instance->drawChar(characterImage, character,
Shinya Kitaoka 120a6e
                                 m_string[index].m_key);
Shinya Kitaoka 120a6e
      else
shun-iwasawa b22463
        adv = instance->drawChar(characterImage, character);
Shinya Kitaoka 120a6e
      TPointD advD = m_scale * TPointD(adv.x, adv.y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      characterImage->transform(m_scale);
Shinya Kitaoka 120a6e
      // colora le aree chiuse
Shinya Kitaoka 120a6e
      paintChar(characterImage, styleId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_string.insert(m_string.begin() + index,
Shinya Kitaoka 120a6e
                      StrokeChar(characterImage, advD.x, character, styleId));
Shinya Kitaoka 120a6e
    } else if (ti) {
Shinya Kitaoka 120a6e
      TRasterCM32P newRasterCM;
Shinya Kitaoka 120a6e
      TPoint p;
Shinya Kitaoka 120a6e
      unsigned int index = from + i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (instance->hasKerning() && (UINT)m_cursorIndex < m_string.size() &&
shun-iwasawa 8a5ab1
          index < m_string.size() - 1 && !m_string[index].isReturn())
Shinya Kitaoka 120a6e
        adv = instance->drawChar((TRasterCM32P &)newRasterCM, p, styleId,
Shinya Kitaoka 120a6e
                                 (wchar_t)character,
Shinya Kitaoka 120a6e
                                 (wchar_t)m_string[index].m_key);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        adv = instance->drawChar((TRasterCM32P &)newRasterCM, p, styleId,
Shinya Kitaoka 120a6e
                                 (wchar_t)character, (wchar_t)0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      d_adv = m_scale * TPointD((double)(adv.x), (double)(adv.y));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TToonzImageP newTImage(
Shinya Kitaoka 120a6e
          new TToonzImage(newRasterCM, newRasterCM->getBounds()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPalette *vPalette = img->getPalette();
Shinya Kitaoka 120a6e
      assert(vPalette);
Shinya Kitaoka 120a6e
      newTImage->setPalette(vPalette);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_string.insert(m_string.begin() + index,
Shinya Kitaoka 120a6e
                      StrokeChar(newTImage, d_adv.x, character, styleId));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // se necessario ricalcolo il kerning del carattere precedente
Shinya Kitaoka 120a6e
  // all'inserimento/cancellazione
Shinya Kitaoka 120a6e
  if (instance->hasKerning() && from - 1 >= 0 &&
Shinya Kitaoka 120a6e
      !m_string[from - 1].isReturn() && from < (int)m_string.size() &&
Shinya Kitaoka 120a6e
      !m_string[from].isReturn()) {
Shinya Kitaoka 120a6e
    TPoint adv =
Shinya Kitaoka 120a6e
        instance->getDistance(m_string[from - 1].m_key, m_string[from].m_key);
Shinya Kitaoka 120a6e
    TPointD advD = m_scale * TPointD((double)(adv.x), (double)(adv.y));
Shinya Kitaoka 120a6e
    m_string[from - 1].m_offset = advD.x;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::addReturn() {
Shinya Kitaoka 120a6e
  TVectorImageP vi(new TVectorImage);
Shinya Kitaoka 120a6e
  if ((UINT)m_cursorIndex == m_string.size())
shun-iwasawa 7f1e30
    m_string.push_back(StrokeChar(vi, -1., (int)(QChar('\r').unicode()), 0));
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_string.insert(m_string.begin() + m_cursorIndex,
shun-iwasawa 7f1e30
                    StrokeChar(vi, -1., (int)(QChar('\r').unicode()), 0));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_cursorIndex++;
Shinya Kitaoka 120a6e
  m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
  updateCharPositions(m_cursorIndex - 1);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::addBaseChar(std::wstring text) {
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TImageP img      = getImage(true);
Shinya Kitaoka 120a6e
  TToonzImageP ti  = img;
Shinya Kitaoka 120a6e
  TVectorImageP vi = img;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int styleId = TTool::getApplication()->getCurrentLevelStyleIndex();
Shinya Kitaoka 120a6e
  TPoint adv;
Shinya Kitaoka 120a6e
  TPointD d_adv;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  wchar_t character = text[0];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (vi) {
Shinya Kitaoka 120a6e
    TVectorImageP newVImage(new TVectorImage);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (instance->hasKerning() && (UINT)m_cursorIndex < m_string.size() &&
Shinya Kitaoka 120a6e
        !m_string[m_cursorIndex].isReturn())
Shinya Kitaoka 120a6e
      adv = instance->drawChar(newVImage, character,
Shinya Kitaoka 120a6e
                               m_string[m_cursorIndex].m_key);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      adv = instance->drawChar(newVImage, character);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    newVImage->transform(m_scale);
Shinya Kitaoka 120a6e
    paintChar(newVImage, styleId);
Shinya Kitaoka 120a6e
    // if(isSketchStyle(styleId))
Shinya Kitaoka 120a6e
    //    enableSketchStyle();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    d_adv = m_scale * TPointD((double)(adv.x), (double)(adv.y));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((UINT)m_cursorIndex == m_string.size())
Shinya Kitaoka 120a6e
      m_string.push_back(StrokeChar(newVImage, d_adv.x, character, styleId));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_string.insert(m_string.begin() + m_cursorIndex,
Shinya Kitaoka 120a6e
                      StrokeChar(newVImage, d_adv.x, character, styleId));
Shinya Kitaoka 120a6e
  } else if (ti) {
Shinya Kitaoka 120a6e
    TRasterCM32P newRasterCM;
Shinya Kitaoka 120a6e
    TPoint p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (instance->hasKerning() && (UINT)m_cursorIndex < m_string.size() &&
Shinya Kitaoka 120a6e
        !m_string[m_cursorIndex].isReturn())
Shinya Kitaoka 120a6e
      adv = instance->drawChar((TRasterCM32P &)newRasterCM, p, styleId,
Shinya Kitaoka 120a6e
                               (wchar_t)character,
Shinya Kitaoka 120a6e
                               (wchar_t)m_string[m_cursorIndex].m_key);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      adv = instance->drawChar((TRasterCM32P &)newRasterCM, p, styleId,
Shinya Kitaoka 120a6e
                               (wchar_t)character, (wchar_t)0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // textImage->transform(m_scale);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    d_adv = m_scale * TPointD((double)(adv.x), (double)(adv.y));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TToonzImageP newTImage(
Shinya Kitaoka 120a6e
        new TToonzImage(newRasterCM, newRasterCM->getBounds()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TPalette *vPalette = img->getPalette();
Shinya Kitaoka 120a6e
    assert(vPalette);
Shinya Kitaoka 120a6e
    newTImage->setPalette(vPalette);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // newTImage->updateRGBM(newRasterCM->getBounds(),vPalette);
Shinya Kitaoka 120a6e
    // assert(0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((UINT)m_cursorIndex == m_string.size())
Shinya Kitaoka 120a6e
      m_string.push_back(StrokeChar(newTImage, d_adv.x, character, styleId));
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_string.insert(m_string.begin() + m_cursorIndex,
Shinya Kitaoka 120a6e
                      StrokeChar(newTImage, d_adv.x, character, styleId));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (instance->hasKerning() && m_cursorIndex > 0 &&
Shinya Kitaoka 120a6e
      !m_string[m_cursorIndex - 1].isReturn()) {
Shinya Kitaoka 120a6e
    adv   = instance->getDistance(m_string[m_cursorIndex - 1].m_key, character);
Shinya Kitaoka 120a6e
    d_adv = m_scale * TPointD((double)(adv.x), (double)(adv.y));
Shinya Kitaoka 120a6e
    m_string[m_cursorIndex - 1].m_offset = d_adv.x;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_cursorIndex++;
Shinya Kitaoka 120a6e
  updateCharPositions(m_cursorIndex - 1);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::cursorUp() {
Shinya Kitaoka 120a6e
  setCursorIndexFromPoint(m_cursorPoint + TPointD(0, 0.5 * m_dimension));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::cursorDown() {
Shinya Kitaoka 120a6e
  setCursorIndexFromPoint(m_cursorPoint + TPointD(0, -1.5 * m_dimension));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::cursorLeft() {
Shinya Kitaoka 120a6e
  if (TFontManager::instance()->hasVertical()) {
Shinya Kitaoka 120a6e
    m_cursorPoint = TRotation(m_startPoint, -90) * m_cursorPoint;
Shinya Kitaoka 120a6e
    setCursorIndexFromPoint(m_cursorPoint + TPointD(-1.5 * m_dimension, 0));
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    setCursorIndexFromPoint(m_cursorPoint + TPointD(-0.5 * m_dimension, 0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::cursorRight() {
Shinya Kitaoka 120a6e
  if (TFontManager::instance()->hasVertical()) {
Shinya Kitaoka 120a6e
    m_cursorPoint = TRotation(m_startPoint, -90) * m_cursorPoint;
Shinya Kitaoka 120a6e
    setCursorIndexFromPoint(m_cursorPoint + TPointD(0.5 * m_dimension, 0));
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    setCursorIndexFromPoint(m_cursorPoint + TPointD(1.5 * m_dimension, 0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::deleteKey() {
Shinya Kitaoka 120a6e
  if ((UINT)m_cursorIndex >= m_string.size()) return;
Shinya Kitaoka 120a6e
  TFontManager *instance = TFontManager::instance();
Shinya Kitaoka 120a6e
  m_string.erase(m_string.begin() + m_cursorIndex);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (instance->hasKerning() && m_cursorIndex > 0 &&
Shinya Kitaoka 120a6e
      !m_string[m_cursorIndex - 1].isReturn()) {
Shinya Kitaoka 120a6e
    TPoint adv;
Shinya Kitaoka 120a6e
    if ((UINT)m_cursorIndex < m_string.size() &&
Shinya Kitaoka 120a6e
        !m_string[m_cursorIndex].isReturn()) {
Shinya Kitaoka 120a6e
      adv = instance->getDistance(m_string[m_cursorIndex - 1].m_key,
Shinya Kitaoka 120a6e
                                  m_string[m_cursorIndex].m_key);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      adv = instance->getDistance(m_string[m_cursorIndex - 1].m_key, 0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    TPointD d_adv = m_scale * TPointD((double)(adv.x), (double)(adv.y));
Shinya Kitaoka 120a6e
    m_string[m_cursorIndex - 1].m_offset = d_adv.x;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
  updateCharPositions(m_cursorIndex);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 7f1e30
bool TypeTool::keyDown(QKeyEvent *event) {
shun-iwasawa 7f1e30
  QString text = event->text();
Rozhuk Ivan 823a31
  if ((event->modifiers() & Qt::ShiftModifier)) text = text.toUpper();
manongjohn dc44ed
manongjohn b96cef
  if (QKeySequence(event->key() + event->modifiers()) == QKeySequence::Paste) {
manongjohn b96cef
    QClipboard *clipboard     = QApplication::clipboard();
manongjohn b96cef
    const QMimeData *mimeData = clipboard->mimeData();
manongjohn b96cef
    if (!mimeData->hasText()) return true;
manongjohn b96cef
    text = mimeData->text().replace('\n', '\r');
manongjohn dc44ed
  }
manongjohn dc44ed
shun-iwasawa 7f1e30
  std::wstring unicodeChar = text.toStdWString();
shun-iwasawa 7f1e30
shun-iwasawa b22463
  // return if only ALT, SHIFT or CTRL key is pressed
shun-iwasawa b22463
  if (event->modifiers() != Qt::NoModifier && (unicodeChar.empty()))
shun-iwasawa b22463
    return true;
shun-iwasawa b22463
Shinya Kitaoka 120a6e
  // per sicurezza
Shinya Kitaoka 120a6e
  m_preeditRange = std::make_pair(0, 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_validFonts || !m_active) return true;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  switch (event->key()) {
shun-iwasawa 7f1e30
  case Qt::Key_Insert:
shun-iwasawa 7f1e30
  case Qt::Key_CapsLock:
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Home:
shun-iwasawa 7f1e30
  case Qt::Key_PageUp:
Shinya Kitaoka 120a6e
    m_cursorIndex  = 0;
Shinya Kitaoka 120a6e
    m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_End:
shun-iwasawa 7f1e30
  case Qt::Key_PageDown:
Shinya Kitaoka 120a6e
    m_cursorIndex  = (int)m_string.size();
Shinya Kitaoka 120a6e
    m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /////////////////// cursors
shun-iwasawa 7f1e30
  case Qt::Key_Up:
Shinya Kitaoka 120a6e
    if (!m_isVertical)
Shinya Kitaoka 120a6e
      cursorUp();
Shinya Kitaoka 120a6e
    else if (m_cursorIndex > 0) {
Shinya Kitaoka 120a6e
      m_cursorIndex--;
Shinya Kitaoka 120a6e
      m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Down:
Shinya Kitaoka 120a6e
    if (!m_isVertical)
Shinya Kitaoka 120a6e
      cursorDown();
Shinya Kitaoka 120a6e
    else if ((UINT)m_cursorIndex < m_string.size()) {
Shinya Kitaoka 120a6e
      m_cursorIndex++;
Shinya Kitaoka 120a6e
      m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Left:
Shinya Kitaoka 120a6e
    if (m_isVertical)
Shinya Kitaoka 120a6e
      cursorLeft();
Shinya Kitaoka 120a6e
    else if (m_cursorIndex > 0) {
Shinya Kitaoka 120a6e
      m_cursorIndex--;
Shinya Kitaoka 120a6e
      m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Right:
Shinya Kitaoka 120a6e
    if (m_isVertical)
Shinya Kitaoka 120a6e
      cursorRight();
Shinya Kitaoka 120a6e
    else if ((UINT)m_cursorIndex < m_string.size()) {
Shinya Kitaoka 120a6e
      m_cursorIndex++;
Shinya Kitaoka 120a6e
      m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    updateCursorPoint();
Shinya Kitaoka 120a6e
    invalidate();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 71d24f
    /////////////////// end cursors
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Escape:
Shinya Kitaoka 120a6e
    resetInputMethod();
Shinya Kitaoka 120a6e
    if (!m_string.empty())
Shinya Kitaoka 120a6e
      addTextToImage();
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      stopEditing();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Delete:
Shinya Kitaoka 120a6e
    deleteKey();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Backspace:
Shinya Kitaoka 120a6e
    if (m_cursorIndex > 0) {
Shinya Kitaoka 120a6e
      m_cursorIndex--;
Shinya Kitaoka 120a6e
      m_preeditRange = std::make_pair(m_cursorIndex, m_cursorIndex);
Shinya Kitaoka 120a6e
      deleteKey();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
shun-iwasawa 7f1e30
  case Qt::Key_Return:
shun-iwasawa 7f1e30
  case Qt::Key_Enter:
Shinya Kitaoka 120a6e
    addReturn();
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  default:
shun-iwasawa 3563f7
    if (unicodeChar.empty()) return false;
Shinya Kitaoka 120a6e
    replaceText(unicodeChar, m_cursorIndex, m_cursorIndex);
manongjohn dc44ed
    int startIndex = m_cursorIndex + 1;
manongjohn dc44ed
    m_cursorIndex += unicodeChar.size();
manongjohn dc44ed
    m_preeditRange = std::make_pair(startIndex, m_cursorIndex);
manongjohn dc44ed
    updateCharPositions(startIndex - 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  invalidate();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
49945e
void TypeTool::onInputText(const std::wstring &preedit, const std::wstring &commit,
Shinya Kitaoka 120a6e
                           int replacementStart, int replacementLen) {
Shinya Kitaoka 120a6e
  // butto la vecchia preedit string
Shinya Kitaoka 120a6e
  m_preeditRange.first  = std::max(0, m_preeditRange.first);
Shinya Kitaoka 120a6e
  m_preeditRange.second = std::min((int)m_string.size(), m_preeditRange.second);
Shinya Kitaoka 120a6e
  if (m_preeditRange.first < m_preeditRange.second)
Shinya Kitaoka 120a6e
    m_string.erase(m_string.begin() + m_preeditRange.first,
Shinya Kitaoka 120a6e
                   m_string.begin() + m_preeditRange.second);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // inserisco la commit string
Shinya Kitaoka 120a6e
  int stringLength = m_string.size();
Shinya Kitaoka 120a6e
  int a = tcrop(m_preeditRange.first + replacementStart, 0, stringLength);
Shinya Kitaoka 120a6e
  int b = tcrop(m_preeditRange.first + replacementStart + replacementLen, a,
Shinya Kitaoka 120a6e
                stringLength);
Shinya Kitaoka 120a6e
  replaceText(commit, a, b);
Shinya Kitaoka 120a6e
  int index = a + commit.length();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // inserisco la nuova preedit string
Shinya Kitaoka 120a6e
  if (preedit.length() > 0) replaceText(preedit, index, index);
Shinya Kitaoka 120a6e
  m_preeditRange.first  = index;
Shinya Kitaoka 120a6e
  m_preeditRange.second = index + preedit.length();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // aggiorno la posizione del cursore
Shinya Kitaoka 120a6e
  m_cursorIndex = m_preeditRange.second;
Shinya Kitaoka 120a6e
  updateCharPositions(a);
Shinya Kitaoka 120a6e
  invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::onActivate() {
Shinya Kitaoka 120a6e
  init();
Shinya Kitaoka 120a6e
  //  getApplication()->editImage();
Shinya Kitaoka 120a6e
  m_string.clear();
Shinya Kitaoka 120a6e
  m_textBox     = TRectD(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  m_cursorIndex = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::onDeactivate() {
Shinya Kitaoka 120a6e
  resetInputMethod();
Shinya Kitaoka 120a6e
  if (!m_string.empty())
Shinya Kitaoka 120a6e
    addTextToImage();  // call internally stopEditing()
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    stopEditing();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::reset() {
Shinya Kitaoka 120a6e
  m_string.clear();
Shinya Kitaoka 120a6e
  m_textBox     = TRectD(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  m_cursorIndex = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TypeTool::onImageChanged() { stopEditing(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static TTool *getTypeTool() { return &typeTool; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*void resetTypetTool(TTool*tool)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (!tool) return;
Toshihiro Shimizu 890ddd
TypeTool*tt = dynamic_cast<typetool*>(tool);</typetool*>
Toshihiro Shimizu 890ddd
  if (tt)
Toshihiro Shimizu 890ddd
    tt->stopEditing();
Toshihiro Shimizu 890ddd
}*/