Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tsimplecolorstyles.h"
Toshihiro Shimizu 890ddd
#include "timage_io.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qmutexlocker></qmutexlocker>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
Campbell Barton 40cabe
#include <memory></memory>
shun_iwasawa e897af
#include <sstream></sstream>
Campbell Barton 40cabe
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(TPalette, "palette")
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPersistDeclarationT<tpalette> auxPaletteDeclaration("vectorpalette");</tpalette>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TPalette, 30)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace  stuff
Toshihiro Shimizu 890ddd
//*************************************************************************************
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
shun-iwasawa dd780b
const std::string pointToString(const TColorStyle::PickedPosition &point) {
shun-iwasawa dd780b
  if (point.frame == 0)
shun-iwasawa dd780b
    return std::to_string(point.pos.x) + "," + std::to_string(point.pos.y);
shun-iwasawa dd780b
  else
shun-iwasawa dd780b
    return std::to_string(point.pos.x) + "," + std::to_string(point.pos.y) +
shun-iwasawa dd780b
           "," + std::to_string(point.frame);
shun_iwasawa e897af
}
shun_iwasawa e897af
shun_iwasawa e897af
// splitting string with ','
shun-iwasawa dd780b
const TColorStyle::PickedPosition stringToPoint(const std::string &string) {
shun_iwasawa e897af
  std::string buffer;
shun_iwasawa e897af
  std::stringstream ss(string);
shun-iwasawa dd780b
  std::vector<std::string> result;</std::string>
shun-iwasawa dd780b
  while (std::getline(ss, buffer, ','))  // split with comma
shun-iwasawa dd780b
    result.push_back(buffer);
shun-iwasawa dd780b
shun-iwasawa dd780b
  int x     = std::stoi(result[0]);
shun-iwasawa dd780b
  int y     = std::stoi(result[1]);
shun-iwasawa dd780b
  int frame = 0;
shun-iwasawa dd780b
  if (result.size() == 3)  // getting the third part of string - if any.
shun-iwasawa dd780b
    frame = std::stoi(result[2]);
shun-iwasawa dd780b
shun-iwasawa dd780b
  return {TPoint(x, y), frame};
shun_iwasawa e897af
}
shun_iwasawa e897af
shun-iwasawa 1b50d3
// convert refLevelFids to string for saving
shun-iwasawa 1b50d3
std::string fidsToString(const std::vector<tframeid> &fids) {</tframeid>
shun-iwasawa 1b50d3
  std::string str;
shun-iwasawa 1b50d3
  QList<int> numList;</int>
shun-iwasawa 1b50d3
shun-iwasawa 1b50d3
  for (const auto fid : fids) {
shun-iwasawa 1b50d3
    int num = fid.getNumber();
shun-iwasawa 1b50d3
    if (numList.isEmpty() || num == numList.last() + 1) {
shun-iwasawa 1b50d3
      numList.push_back(num);
shun-iwasawa 1b50d3
      continue;
shun-iwasawa 1b50d3
    }
shun-iwasawa 1b50d3
    // print
shun-iwasawa 1b50d3
    if (numList.count() == 1)
shun-iwasawa 1b50d3
      str += std::to_string(numList[0]) + ",";
shun-iwasawa 1b50d3
    else if (numList.count() == 2)
shun-iwasawa 1b50d3
      str +=
shun-iwasawa 1b50d3
          std::to_string(numList[0]) + "," + std::to_string(numList[1]) + ",";
shun-iwasawa 1b50d3
    else
shun-iwasawa 1b50d3
      str += std::to_string(numList[0]) + "-" + std::to_string(numList.last()) +
shun-iwasawa 1b50d3
             ",";
shun-iwasawa 1b50d3
shun-iwasawa 1b50d3
    numList.clear();
shun-iwasawa 1b50d3
    numList.push_back(num);
shun-iwasawa 1b50d3
  }
shun-iwasawa 1b50d3
  if (numList.count() == 1)
shun-iwasawa 1b50d3
    str += std::to_string(numList[0]);
shun-iwasawa 1b50d3
  else if (numList.count() == 2)
shun-iwasawa 1b50d3
    str += std::to_string(numList[0]) + "," + std::to_string(numList[1]);
shun-iwasawa 1b50d3
  else
shun-iwasawa 1b50d3
    str += std::to_string(numList[0]) + "-" + std::to_string(numList.last());
shun-iwasawa 1b50d3
  return str;
shun-iwasawa 1b50d3
}
shun-iwasawa 1b50d3
shun-iwasawa 1b50d3
// convert loaded string to refLevelFids
shun-iwasawa 1b50d3
std::vector<tframeid> strToFids(std::string fidsStr) {</tframeid>
shun-iwasawa 1b50d3
  std::vector<tframeid> ret;</tframeid>
shun-iwasawa 443318
  QString str = QString::fromStdString(fidsStr);
shun-iwasawa 443318
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
shun-iwasawa 443318
  QStringList chunks = str.split(',', Qt::SkipEmptyParts);
shun-iwasawa 443318
#else
shun-iwasawa 1b50d3
  QStringList chunks = str.split(',', QString::SkipEmptyParts);
shun-iwasawa 443318
#endif
shun-iwasawa 1b50d3
  for (const auto &chunk : chunks) {
shun-iwasawa 443318
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
shun-iwasawa 443318
    QStringList nums = chunk.split('-', Qt::SkipEmptyParts);
shun-iwasawa 443318
#else
shun-iwasawa 1b50d3
    QStringList nums = chunk.split('-', QString::SkipEmptyParts);
shun-iwasawa 443318
#endif
shun-iwasawa 1b50d3
    assert(nums.count() > 0 && nums.count() <= 2);
shun-iwasawa 1b50d3
    if (nums.count() == 1)
shun-iwasawa 1b50d3
      ret.push_back(TFrameId(nums[0].toInt()));
shun-iwasawa 1b50d3
    else {  // nums.count() == 2
shun-iwasawa 1b50d3
      assert(nums[0].toInt() < nums[1].toInt());
shun-iwasawa 1b50d3
      for (int i = nums[0].toInt(); i <= nums[1].toInt(); i++)
shun-iwasawa 1b50d3
        ret.push_back(TFrameId(i));
shun-iwasawa 1b50d3
    }
shun-iwasawa 1b50d3
  }
shun-iwasawa 1b50d3
  return ret;
shun-iwasawa 1b50d3
}
shun-iwasawa 1b50d3
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TPalette::Page
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
TPalette::Page::Page(std::wstring name)
Shinya Kitaoka 120a6e
    : m_name(name), m_index(-1), m_palette(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle *TPalette::Page::getStyle(int index) const {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  if (0 <= index && index < getStyleCount())
Shinya Kitaoka 120a6e
    return m_palette->getStyle(m_styleIds[index]);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::Page::getStyleId(int index) const {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  if (0 <= index && index < getStyleCount())
Shinya Kitaoka 120a6e
    return m_styleIds[index];
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::Page::addStyle(int styleId) {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  if (styleId < 0 || styleId >= m_palette->getStyleCount()) return -1;
Shinya Kitaoka 120a6e
  if (m_palette->m_styles[styleId].first != 0) return -1;
Shinya Kitaoka 120a6e
  m_palette->m_styles[styleId].first = this;
Shinya Kitaoka 120a6e
  int indexInPage                    = int(m_styleIds.size());
Shinya Kitaoka 120a6e
  m_styleIds.push_back(styleId);
Shinya Kitaoka 120a6e
  return indexInPage;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::Page::addStyle(TColorStyle *style) {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  int stylesCount = int(m_palette->m_styles.size());
Shinya Kitaoka 120a6e
  int styleId;
Shinya Kitaoka 120a6e
  for (styleId = 0; styleId < stylesCount; styleId++)
Shinya Kitaoka 120a6e
    if (m_palette->m_styles[styleId].first == 0) break;
Shinya Kitaoka 120a6e
  if (styleId >= stylesCount - 1) return addStyle(m_palette->addStyle(style));
Shinya Kitaoka 120a6e
  m_palette->setStyle(styleId, style);
Shinya Kitaoka 120a6e
  return addStyle(styleId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::Page::addStyle(TPixel32 color) {
Shinya Kitaoka 120a6e
  return addStyle(new TSolidColorStyle(color));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::Page::insertStyle(int indexInPage, int styleId) {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  if (styleId < 0 || styleId >= m_palette->getStyleCount()) return;
Shinya Kitaoka 120a6e
  if (m_palette->m_styles[styleId].first != 0) return;
Shinya Kitaoka 120a6e
  m_palette->m_styles[styleId].first = this;
Shinya Kitaoka 120a6e
  if (indexInPage < 0)
Shinya Kitaoka 120a6e
    indexInPage = 0;
Shinya Kitaoka 120a6e
  else if (indexInPage > getStyleCount())
Shinya Kitaoka 120a6e
    indexInPage = getStyleCount();
Shinya Kitaoka 120a6e
  m_styleIds.insert(m_styleIds.begin() + indexInPage, styleId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::Page::insertStyle(int indexInPage, TColorStyle *style) {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  int styleId = m_palette->addStyle(style);
Shinya Kitaoka 120a6e
  if (styleId >= 0) insertStyle(indexInPage, styleId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::Page::insertStyle(int indexInPage, TPixel32 color) {
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  int styleId = m_palette->addStyle(color);
Shinya Kitaoka 120a6e
  if (styleId >= 0) insertStyle(indexInPage, styleId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::Page::removeStyle(int indexInPage) {
Shinya Kitaoka 120a6e
  if (indexInPage < 0 || indexInPage >= getStyleCount()) return;
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  int styleId = getStyleId(indexInPage);
Shinya Kitaoka 120a6e
  assert(0 <= styleId && styleId < m_palette->getStyleCount());
Shinya Kitaoka 120a6e
  assert(m_palette->m_styles[styleId].first == this);
Shinya Kitaoka 120a6e
  m_palette->m_styles[styleId].first = 0;
Shinya Kitaoka 120a6e
  m_styleIds.erase(m_styleIds.begin() + indexInPage);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::Page::search(int styleId) const {
Shinya Kitaoka 120a6e
  std::vector<int>::const_iterator it =</int>
Shinya Kitaoka 120a6e
      std::find(m_styleIds.begin(), m_styleIds.end(), styleId);
Shinya Kitaoka 120a6e
  if (it == m_styleIds.end())
Shinya Kitaoka 120a6e
    return -1;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return it - m_styleIds.begin();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::Page::search(TColorStyle *style) const {
Shinya Kitaoka 120a6e
  assert(style);
Shinya Kitaoka 120a6e
  assert(m_palette);
Shinya Kitaoka 120a6e
  for (int i = 0; i < getStyleCount(); i++)
Shinya Kitaoka 120a6e
    if (m_palette->getStyle(m_styleIds[i]) == style) return i;
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TPalette
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TPalette::TPalette()
Shinya Kitaoka 120a6e
    : m_version(0)
Shinya Kitaoka 120a6e
    , m_isCleanupPalette(false)
Shinya Kitaoka 120a6e
    , m_currentFrame(-1)
Shinya Kitaoka 120a6e
    , m_dirtyFlag(false)
Shinya Kitaoka 120a6e
    , m_mutex(QMutex::Recursive)
Shinya Kitaoka 120a6e
    , m_isLocked(false)
shun_iwasawa 4635d8
    , m_askOverwriteFlag(false)
manongjohn 649b9a
    , m_shortcutScopeIndex(0)
manongjohn 649b9a
    , m_currentStyleId(1) {
Shinya Kitaoka 120a6e
  QString tempName(QObject::tr("colors"));
Shinya Kitaoka 120a6e
  std::wstring pageName = tempName.toStdWString();
Shinya Kitaoka 120a6e
  Page *page            = addPage(pageName);
Shinya Kitaoka 120a6e
  page->addStyle(TPixel32(255, 255, 255, 0));
Shinya Kitaoka 120a6e
  page->addStyle(TPixel32(0, 0, 0, 255));
Shinya Kitaoka 120a6e
  getStyle(0)->setName(L"color_0");
Shinya Kitaoka 120a6e
  getStyle(1)->setName(L"color_1");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = 0; i < 10; i++) m_shortcuts['0' + i] = i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette::~TPalette() {
Shinya Kitaoka 120a6e
  std::set<tcolorstyle *=""> table;</tcolorstyle>
Shinya Kitaoka 120a6e
  int i = 0;
Shinya Kitaoka 120a6e
  for (i = 0; i < getStyleCount(); i++) {
Shinya Kitaoka 120a6e
    assert(table.find(getStyle(i)) == table.end());
Shinya Kitaoka 120a6e
    table.insert(getStyle(i));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  clearPointerContainer(m_pages);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette *TPalette::clone() const {
Shinya Kitaoka 120a6e
  TPalette *palette = new TPalette;
Shinya Kitaoka 120a6e
  palette->assign(this);
Shinya Kitaoka 120a6e
  return palette;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle *TPalette::getStyle(int index) const {
Shinya Kitaoka 120a6e
  if (0 <= index && index < getStyleCount())
Shinya Kitaoka 120a6e
    return m_styles[index].second.getPointer();
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    static TSolidColorStyle *ss = new TSolidColorStyle(TPixel32::Red);
Shinya Kitaoka 120a6e
    ss->addRef();
Shinya Kitaoka 120a6e
    return ss;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getStyleInPagesCount() const {
Shinya Kitaoka 120a6e
  int styleInPagesCount = 0;
Shinya Kitaoka 120a6e
  for (int i = 0; i < getStyleCount(); i++)
Shinya Kitaoka 120a6e
    if (m_styles[i].first != 0) styleInPagesCount++;
Shinya Kitaoka 120a6e
  return styleInPagesCount;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getFirstUnpagedStyle() const {
Shinya Kitaoka 120a6e
  for (int i = 0; i < getStyleCount(); i++)
Shinya Kitaoka 120a6e
    if (m_styles[i].first == 0) return i;
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*! Adding style with new styleId. Even if there are deleted styles in the
Shinya Kitaoka 120a6e
 * palette, the new style will be appended to the end of the list.
shun-iwasawa 1b50d3
 */
Shinya Kitaoka 120a6e
int TPalette::addStyle(TColorStyle *style) {
Shinya Kitaoka 120a6e
  // limit the number of cleanup style to 7
Shinya Kitaoka 120a6e
  if (isCleanupPalette() && getStyleInPagesCount() >= 8) return -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int styleId = int(m_styles.size());
Shinya Kitaoka 120a6e
  if (styleId < 4096) {
Shinya Kitaoka 120a6e
    // checking if the style is overlapped
Shinya Kitaoka 120a6e
    int i = 0;
Shinya Kitaoka 120a6e
    for (i = 0; i < styleId; i++)
Shinya Kitaoka 120a6e
      if (getStyle(i) == style) break;
Shinya Kitaoka 120a6e
    if (i == styleId) {
Shinya Kitaoka 120a6e
      m_styles.push_back(std::make_pair((Page *)0, style));
Shinya Kitaoka 120a6e
      return styleId;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  delete style;
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::addStyle(const TPixel32 &color) {
Shinya Kitaoka 120a6e
  return addStyle(new TSolidColorStyle(color));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setStyle(int styleId, TColorStyle *style) {
Shinya Kitaoka 2a7129
  std::unique_ptr<tcolorstyle> styleOwner(style);</tcolorstyle>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int styleCount = getStyleCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (0 <= styleId && styleId < styleCount) {
Shinya Kitaoka 120a6e
    // Find out if the supplied style is already in the palette
Shinya Kitaoka 120a6e
    // with a different style id. In that case, bail out as a noop.
Shinya Kitaoka 120a6e
    for (int i = 0; i < styleCount; ++i)
Shinya Kitaoka 120a6e
      if (style == getStyle(i)) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Substitution can take place
Shinya Kitaoka 120a6e
    if (typeid(*m_styles[styleId].second.getPointer()) != typeid(*style))
Shinya Kitaoka 120a6e
      m_styleAnimationTable.erase(styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_styles[styleId].second = styleOwner.release();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setStyle(int styleId, const TPixelRGBM32 &color) {
Shinya Kitaoka 120a6e
  setStyle(styleId, new TSolidColorStyle(color));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getPageCount() const { return int(m_pages.size()); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette::Page *TPalette::getPage(int pageIndex) {
Shinya Kitaoka 120a6e
  if (0 <= pageIndex && pageIndex < getPageCount()) {
Shinya Kitaoka 120a6e
    Page *page = m_pages[pageIndex];
Shinya Kitaoka 120a6e
    assert(page->getIndex() == pageIndex);
Shinya Kitaoka 120a6e
    assert(page->m_palette == this);
Shinya Kitaoka 120a6e
    return page;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TPalette::Page *TPalette::getPage(int pageIndex) const {
Shinya Kitaoka 120a6e
  if (0 <= pageIndex && pageIndex < getPageCount()) {
Shinya Kitaoka 120a6e
    Page *page = m_pages[pageIndex];
Shinya Kitaoka 120a6e
    assert(page->getIndex() == pageIndex);
Shinya Kitaoka 120a6e
    assert(page->m_palette == this);
Shinya Kitaoka 120a6e
    return page;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette::Page *TPalette::addPage(std::wstring name) {
Shinya Kitaoka 120a6e
  Page *page      = new Page(name);
Shinya Kitaoka 120a6e
  page->m_index   = getPageCount();
Shinya Kitaoka 120a6e
  page->m_palette = this;
Shinya Kitaoka 120a6e
  m_pages.push_back(page);
Shinya Kitaoka 120a6e
  return page;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::erasePage(int index) {
Shinya Kitaoka 120a6e
  Page *page = getPage(index);
Shinya Kitaoka 120a6e
  if (!page) return;
Shinya Kitaoka 120a6e
  m_pages.erase(m_pages.begin() + index);
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < getPageCount(); i++) m_pages[i]->m_index = i;
shun-iwasawa 1b50d3
  for (i = 0; i < page->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    m_styles[page->getStyleId(i)].first = 0;
shun-iwasawa 1b50d3
  page->m_palette = 0;
Shinya Kitaoka 120a6e
  delete page;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::movePage(Page *page, int dstPageIndex) {
Shinya Kitaoka 120a6e
  assert(page);
Shinya Kitaoka 120a6e
  assert(page->m_palette == this);
Shinya Kitaoka 120a6e
  dstPageIndex = tcrop(dstPageIndex, 0, getPageCount() - 1);
Shinya Kitaoka 120a6e
  if (dstPageIndex == page->getIndex()) return;
Shinya Kitaoka 120a6e
  m_pages.erase(m_pages.begin() + page->getIndex());
Shinya Kitaoka 120a6e
  m_pages.insert(m_pages.begin() + dstPageIndex, page);
Shinya Kitaoka 120a6e
  for (int i = 0; i < getPageCount(); i++) m_pages[i]->m_index = i;
Shinya Kitaoka 120a6e
  assert(page->getIndex() == dstPageIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPalette::Page *TPalette::getStylePage(int styleId) const {
Shinya Kitaoka 120a6e
  if (0 <= styleId && styleId < getStyleCount())
Shinya Kitaoka 120a6e
    return m_styles[styleId].first;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getClosestStyle(const TPixel32 &color) const {
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static inline int getDistance2(const TPixel32 &a, const TPixel32 &b) {
Shinya Kitaoka 120a6e
      return (a.r - b.r) * (a.r - b.r) + (a.g - b.g) * (a.g - b.g) +
Shinya Kitaoka 120a6e
             (a.b - b.b) * (a.b - b.b) + (a.m - b.m) * (a.m - b.m);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };  // locals
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (color == TPixel32::Transparent) return 0;
Shinya Kitaoka 120a6e
  int bestIndex    = -1;
Shinya Kitaoka 120a6e
  int bestDistance = 255 * 255 * 4 + 1;
Shinya Kitaoka 120a6e
  for (int i = 1; i < (int)m_styles.size(); i++) {
Shinya Kitaoka 120a6e
    // if(i==FirstUserStyle+2) continue;
Shinya Kitaoka 120a6e
    TSolidColorStyle *scs =
Shinya Kitaoka 120a6e
        dynamic_cast<tsolidcolorstyle *="">(m_styles[i].second.getPointer());</tsolidcolorstyle>
Shinya Kitaoka 120a6e
    if (scs) {
Shinya Kitaoka 120a6e
      int d = locals::getDistance2(scs->getMainColor(), color);
Shinya Kitaoka 120a6e
      if (d < bestDistance) {
Shinya Kitaoka 120a6e
        bestIndex    = i;
Shinya Kitaoka 120a6e
        bestDistance = d;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return bestIndex;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TPalette::getFxRects(const TRect &rect, TRect &rectIn, TRect &rectOut) {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  bool ret = false;
Shinya Kitaoka 120a6e
  int borderIn, borderOut, fullBorderIn = 0, fullBorderOut = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < (int)m_styles.size(); i++)
Shinya Kitaoka 120a6e
    if (m_styles[i].second->isRasterStyle()) {
Shinya Kitaoka 120a6e
      m_styles[i].second->getRasterStyleFx()->getEnlargement(borderIn,
Shinya Kitaoka 120a6e
                                                             borderOut);
Shinya Kitaoka 120a6e
      fullBorderIn  = std::max(fullBorderIn, borderIn);
Shinya Kitaoka 120a6e
      fullBorderOut = std::max(fullBorderOut, borderOut);
Shinya Kitaoka 120a6e
      ret           = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rectIn  = rect.enlarge(fullBorderIn);
Shinya Kitaoka 120a6e
  rectOut = rect.enlarge(fullBorderOut);
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// I/O
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class StyleWriter final : public TOutputStreamInterface {
Shinya Kitaoka 120a6e
  TOStream &m_os;
Shinya Kitaoka 120a6e
  int m_index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TFilePath m_rootDir;
Shinya Kitaoka 120a6e
  StyleWriter(TOStream &os, int index) : m_os(os), m_index(index) {}
Shinya Kitaoka 120a6e
  static void setRootDir(const TFilePath &fp) { m_rootDir = fp; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(double x) override {
Shinya Kitaoka 120a6e
    m_os << x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(int x) override {
Shinya Kitaoka 120a6e
    m_os << x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(std::string x) override {
Shinya Kitaoka 120a6e
    m_os << x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(UCHAR x) override {
Shinya Kitaoka 120a6e
    m_os << (int)x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(USHORT x) override {
Shinya Kitaoka 120a6e
    m_os << (int)x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(const TPixel32 &x) override {
Shinya Kitaoka 120a6e
    m_os << x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 473e70
  TOutputStreamInterface &operator<<(const TRaster32P &ras) override {
Shinya Kitaoka 120a6e
    assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::string name = "texture_" + std::to_string(m_index);
Shinya Kitaoka 120a6e
    m_os << name;
Shinya Kitaoka 120a6e
    TFilePath filename = ((m_rootDir + "textures") + name).withType("bmp");
Shinya Kitaoka 120a6e
    if (!TFileStatus(m_rootDir + "textures").doesExist()) {
Shinya Kitaoka 120a6e
      try {
Shinya Kitaoka 120a6e
        TSystem::mkDir(m_rootDir + "textures");
Shinya Kitaoka 120a6e
      } catch (...) {
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TImageWriter::save(filename, ras);
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka d1f6c4
class StyleReader final : public TInputStreamInterface {
Shinya Kitaoka 120a6e
  TIStream &m_is;           //!< Wrapped input stream.
Shinya Kitaoka 120a6e
  VersionNumber m_version;  //!< Palette version number (overrides m_is's one).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TFilePath m_rootDir;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StyleReader(TIStream &is, const VersionNumber &version)
Shinya Kitaoka 120a6e
      : m_is(is), m_version(version) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  static void setRootDir(const TFilePath &fp) { m_rootDir = fp; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(double &x) override {
Shinya Kitaoka 120a6e
    m_is >> x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(int &x) override {
Shinya Kitaoka 120a6e
    m_is >> x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(std::string &x) override {
Shinya Kitaoka 120a6e
    m_is >> x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(UCHAR &x) override {
Shinya Kitaoka 120a6e
    int v;
Shinya Kitaoka 120a6e
    m_is >> v;
Shinya Kitaoka 120a6e
    x = v;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(USHORT &x) override {
Shinya Kitaoka 120a6e
    int v;
Shinya Kitaoka 120a6e
    m_is >> v;
Shinya Kitaoka 120a6e
    x = v;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(TRaster32P &x) override {
Shinya Kitaoka 120a6e
    assert(m_rootDir != TFilePath());
Shinya Kitaoka 120a6e
    std::string name;
Shinya Kitaoka 120a6e
    m_is >> name;
Shinya Kitaoka 120a6e
    TFilePath filename = ((m_rootDir + "textures") + name).withType("bmp");
Shinya Kitaoka 120a6e
    TRasterP ras;
Shinya Kitaoka 120a6e
    if (TImageReader::load(filename, ras)) {
Shinya Kitaoka 120a6e
      x = ras;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
Shinya Kitaoka 473e70
  TInputStreamInterface &operator>>(TPixel32 &x) override {
Shinya Kitaoka 120a6e
    m_is >> x;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
luz paz 6454c4
\details  Explicitly overrides the stream's version, returning m_version.
Shinya Kitaoka 120a6e
        This is necessary since palettes have their \a own version number,
Shinya Kitaoka 120a6e
        which is \a not the TIStream's file one.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 473e70
  VersionNumber versionNumber() const override {
Shinya Kitaoka 120a6e
    return m_version;
Shinya Kitaoka 120a6e
  }  //!< Returns the palette's version number.
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFilePath StyleWriter::m_rootDir = TFilePath();
Toshihiro Shimizu 890ddd
TFilePath StyleReader::m_rootDir = TFilePath();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setRootDir(const TFilePath &fp) {
Shinya Kitaoka 120a6e
  StyleWriter::setRootDir(fp);
Shinya Kitaoka 120a6e
  StyleReader::setRootDir(fp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::saveData(TOStream &os) {
Shinya Kitaoka 120a6e
  os.child("version") << 71 << 0;  // Inserting the version tag at this level.
Shinya Kitaoka 120a6e
  // This is necessary to support the tpl format
Shinya Kitaoka 120a6e
  if (m_refImgPath !=
shun-iwasawa 1b50d3
      TFilePath()) {  // since it performs *untagged* stream output
shun-iwasawa 1b50d3
    if (m_areRefLevelFidsSpecified) {
shun-iwasawa 1b50d3
      std::map<std::string, std::string=""> attr;</std::string,>
shun-iwasawa 1b50d3
      attr["fids"] = fidsToString(m_refLevelFids);
shun-iwasawa 1b50d3
      os.openChild("refImgPath", attr);
shun-iwasawa 1b50d3
    } else
shun-iwasawa 1b50d3
      os.openChild("refImgPath");
shun-iwasawa 1b50d3
    os << m_refImgPath;  // (the palette is streamed directly).
shun-iwasawa 1b50d3
    os.closeChild();
shun-iwasawa 1b50d3
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.openChild("styles");
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    for (int i = 0; i < getStyleCount(); ++i) {
shun_iwasawa e897af
      TColorStyleP style = m_styles[i].second;
shun-iwasawa dd780b
      if (style->getPickedPosition().pos == TPoint())
shun_iwasawa e897af
        os.openChild("style");
shun_iwasawa e897af
      else {
shun_iwasawa e897af
        std::map<std::string, std::string=""> attr;</std::string,>
shun_iwasawa e897af
        attr["pickedpos"] = pointToString(style->getPickedPosition());
shun_iwasawa e897af
        os.openChild("style", attr);
shun_iwasawa e897af
      }
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        StyleWriter w(os, i);
shun_iwasawa e897af
        style->save(w);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      os.closeChild();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.openChild("stylepages");
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    for (int i = 0; i < getPageCount(); ++i) {
Shinya Kitaoka 120a6e
      Page *page = getPage(i);
Shinya Kitaoka 120a6e
      os.openChild("page");
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        os.child("name") << page->getName();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        os.openChild("indices");
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          int m = page->getStyleCount();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (int j = 0; j < m; ++j) os << page->getStyleId(j);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        os.closeChild();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      os.closeChild();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (isAnimated()) {
Shinya Kitaoka 120a6e
    os.openChild("animation");
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      StyleAnimationTable::iterator sat, saEnd = m_styleAnimationTable.end();
Shinya Kitaoka 120a6e
      for (sat = m_styleAnimationTable.begin(); sat != saEnd; ++sat) {
Shinya Kitaoka 120a6e
        int styleId               = sat->first;
Shinya Kitaoka 120a6e
        StyleAnimation &animation = sat->second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        std::map<std::string, std::string=""> attributes;</std::string,>
Shinya Kitaoka 120a6e
        attributes["id"] = std::to_string(styleId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        os.openChild("style", attributes);
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          StyleAnimation::iterator kt, kEnd = animation.end();
Shinya Kitaoka 120a6e
          for (kt = animation.begin(); kt != kEnd; ++kt) {
Shinya Kitaoka 120a6e
            int frame = kt->first;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            TColorStyle *cs = kt->second.getPointer();
Shinya Kitaoka 120a6e
            assert(cs);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            attributes.clear();
Shinya Kitaoka 120a6e
            attributes["frame"] = std::to_string(frame);
Shinya Kitaoka 120a6e
shun-iwasawa 1b50d3
            /*os.openChild("keycolor", attributes);                       // Up
shun-iwasawa 1b50d3
            to Toonz 7.0, animations saved os << cs->getMainColor(); // the main
shun-iwasawa 1b50d3
            color only os.closeChild();*/  //
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            os.openChild("keyframe", attributes);
Shinya Kitaoka 120a6e
            {
Shinya Kitaoka 120a6e
              StyleWriter w(os, sat->first);
Shinya Kitaoka 120a6e
              kt->second->save(w);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
            os.closeChild();
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        os.closeChild();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // salvo gli shortcuts solo se sono non standard
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < 10; ++i)
Shinya Kitaoka 120a6e
    if (getShortcutValue('0' + i) != i) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (i < 10) {
Shinya Kitaoka 120a6e
    os.openChild("shortcuts");
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      for (i = 0; i < 10; i++) os << getShortcutValue('0' + i);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (isLocked()) {
Shinya Kitaoka 120a6e
    os.openChild("lock");
Shinya Kitaoka 120a6e
    os << 1;
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  m_styles.clear();
Shinya Kitaoka 120a6e
  clearPointerContainer(m_pages);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VersionNumber version = is.getVersion();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  while (is.openChild(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "version") {
Shinya Kitaoka 120a6e
      is >> version.first >> version.second;
Shinya Kitaoka 120a6e
      if (version > VersionNumber(71, 0))
Shinya Kitaoka 120a6e
        throw TException("palette, unsupported version number");
Shinya Kitaoka 120a6e
    } else if (tagName == "styles") {
Shinya Kitaoka 120a6e
      while (!is.eos())  // I think while(is.openChild(tagName))
Shinya Kitaoka 120a6e
      {                  // would be better. However, I don't trust
Shinya Kitaoka 120a6e
        if (!is.openChild(tagName) ||
Shinya Kitaoka 120a6e
            tagName !=
Shinya Kitaoka 120a6e
                "style")  // TIStream's implementation very much. Keeping it
Shinya Kitaoka 120a6e
          throw TException(
Shinya Kitaoka 120a6e
              "palette, expected tag <style>");  // like this for now.</style>
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          StyleReader r(is, version);
Shinya Kitaoka 120a6e
          TColorStyle *cs = TColorStyle::load(r);
Shinya Kitaoka 120a6e
shun_iwasawa e897af
          std::string pickedPosStr;
shun_iwasawa e897af
          if (is.getTagParam("pickedpos", pickedPosStr))
shun_iwasawa e897af
            cs->setPickedPosition(stringToPoint(pickedPosStr));
shun_iwasawa e897af
Shinya Kitaoka 120a6e
          addStyle(cs);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        is.closeChild();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "stylepages") {
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        if (!is.openChild(tagName) || tagName != "page")
Shinya Kitaoka 120a6e
          throw TException("palette, expected tag <stylepage>");</stylepage>
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          std::wstring pageName;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (!is.openChild(tagName) || tagName != "name")
Shinya Kitaoka 120a6e
            throw TException("palette, expected tag <name>");</name>
Shinya Kitaoka 120a6e
          { is >> pageName; }
Shinya Kitaoka 120a6e
          is.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          Page *page = addPage(pageName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (!is.openChild(tagName) || tagName != "indices")
Shinya Kitaoka 120a6e
            throw TException("palette, expected tag <indices>");</indices>
Shinya Kitaoka 120a6e
          {
Shinya Kitaoka 120a6e
            while (!is.eos()) {
Shinya Kitaoka 120a6e
              int index;
Shinya Kitaoka 120a6e
              is >> index;
Shinya Kitaoka 120a6e
              page->addStyle(index);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          is.closeChild();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        is.closeChild();
Shinya Kitaoka 120a6e
      }
shun-iwasawa 1b50d3
    } else if (tagName == "refImgPath") {
shun-iwasawa 1b50d3
      std::string fidsStr;
shun-iwasawa 1b50d3
      if (is.getTagParam("fids", fidsStr)) {
shun-iwasawa 1b50d3
        m_areRefLevelFidsSpecified = true;
shun-iwasawa 1b50d3
        m_refLevelFids             = strToFids(fidsStr);
shun-iwasawa 1b50d3
      } else {
shun-iwasawa 1b50d3
        m_areRefLevelFidsSpecified = false;
shun-iwasawa 1b50d3
        m_refLevelFids.clear();
shun-iwasawa 1b50d3
      }
Shinya Kitaoka 120a6e
      is >> m_refImgPath;
shun-iwasawa 1b50d3
    } else if (tagName == "animation") {
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        if (!is.openChild(tagName) || tagName != "style")
Shinya Kitaoka 120a6e
          throw TException("palette, expected tag <style>");</style>
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          int styleId = 0;
Shinya Kitaoka 120a6e
          if (!is.getTagParam("id", styleId))
Shinya Kitaoka 120a6e
            throw TException("palette, missing id attribute in tag <style>");</style>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          StyleAnimation animation;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          TColorStyle *style = getStyle(styleId);
Shinya Kitaoka 120a6e
          assert(style);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          while (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
            TColorStyle *cs = 0;
Shinya Kitaoka 120a6e
            int frame       = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tagName == "keycolor") {
Shinya Kitaoka 120a6e
              if (!is.getTagParam("frame", frame))
Shinya Kitaoka 120a6e
                throw TException(
Shinya Kitaoka 120a6e
                    "palette, missing frame attribute in tag <keycolor>");</keycolor>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              TPixel32 color;
Shinya Kitaoka 120a6e
              is >> color;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              cs = style->clone();
Shinya Kitaoka 120a6e
              cs->setMainColor(color);
Shinya Kitaoka 120a6e
            } else if (tagName == "keyframe") {
Shinya Kitaoka 120a6e
              if (!is.getTagParam("frame", frame))
Shinya Kitaoka 120a6e
                throw TException(
Shinya Kitaoka 120a6e
                    "palette, missing frame attribute in tag <keyframe>");</keyframe>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              StyleReader r(is, version);
Shinya Kitaoka 120a6e
              cs = TColorStyle::load(r);
Shinya Kitaoka 120a6e
            } else
Shinya Kitaoka 120a6e
              throw TException("palette, expected <keyframe> tag");</keyframe>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            animation[frame] = cs;
Shinya Kitaoka 120a6e
            is.closeChild();
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          m_styleAnimationTable[styleId] = animation;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        is.closeChild();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "stylepages") {
Shinya Kitaoka 120a6e
      int key = '0';
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        int styleId = 0;
Shinya Kitaoka 120a6e
        is >> styleId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (key <= '9') setShortcutValue(key, styleId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "shortcuts") {
Shinya Kitaoka 120a6e
      for (int i = 0; i < 10; ++i) {
Shinya Kitaoka 120a6e
        int v;
Shinya Kitaoka 120a6e
        is >> v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        setShortcutValue('0' + i, v);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "lock") {
Shinya Kitaoka 120a6e
      int lockValue;
Shinya Kitaoka 120a6e
      is >> lockValue;
Shinya Kitaoka 120a6e
      m_isLocked = (bool)lockValue;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      throw TException("palette, unknown tag: " + tagName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    is.closeChild();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
/*! if the palette is copied from studio palette, this function will modify the
Shinya Kitaoka 120a6e
 * original names.
shun-iwasawa 1b50d3
 */
Shinya Kitaoka 120a6e
void TPalette::assign(const TPalette *src, bool isFromStudioPalette) {
justburner 85c12a
  if (!src || src == this) return;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  m_isCleanupPalette = src->isCleanupPalette();
Shinya Kitaoka 120a6e
  // for(i=0;i
Shinya Kitaoka 120a6e
  m_styles.clear();
Shinya Kitaoka 120a6e
  clearPointerContainer(m_pages);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < src->getStyleCount(); i++) {
Shinya Kitaoka 120a6e
    TColorStyle *srcStyle = src->getStyle(i);
Shinya Kitaoka 120a6e
    TColorStyle *dstStyle = srcStyle->clone();
Shinya Kitaoka 120a6e
    dstStyle->setName(
Shinya Kitaoka 120a6e
        srcStyle->getName());  // per un baco del TColorStyle::clone()
Shinya Kitaoka 120a6e
    dstStyle->setGlobalName(
Shinya Kitaoka 120a6e
        srcStyle->getGlobalName());  // per un baco del TColorStyle::clone()
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // if the style is copied from studio palette, put its name to the original
Shinya Kitaoka 120a6e
    // name.
Shinya Kitaoka 120a6e
    // check if the style has the global name (i.e. it comes from studio
Shinya Kitaoka 120a6e
    // palette)
Shinya Kitaoka 120a6e
    if (isFromStudioPalette && srcStyle->getGlobalName() != L"") {
Shinya Kitaoka 120a6e
      // If the original style has no original name (i.e. if the style is copied
Shinya Kitaoka 120a6e
      // from the studio palette)
Shinya Kitaoka 120a6e
      if (srcStyle->getOriginalName() == L"") {
Shinya Kitaoka 120a6e
        // put the original style name to the "original name" of the pasted
Shinya Kitaoka 120a6e
        // style.
Shinya Kitaoka 120a6e
        dstStyle->setOriginalName(srcStyle->getName());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int j = addStyle(dstStyle);
Shinya Kitaoka 120a6e
    assert(i == j);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < src->getPageCount(); i++) {
Shinya Kitaoka 120a6e
    const Page *srcPage = src->getPage(i);
Shinya Kitaoka 120a6e
    Page *dstPage       = addPage(srcPage->getName());
Shinya Kitaoka 120a6e
    for (int j = 0; j < srcPage->getStyleCount(); j++)
Shinya Kitaoka 120a6e
      dstPage->addStyle(srcPage->getStyleId(j));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_refImg     = !!src->m_refImg ? src->m_refImg->cloneImage() : TImageP();
Shinya Kitaoka 120a6e
  m_refImgPath = src->m_refImgPath;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  StyleAnimationTable::iterator it;
Shinya Kitaoka 120a6e
  StyleAnimation::iterator j;
Shinya Kitaoka 120a6e
  for (it = m_styleAnimationTable.begin(); it != m_styleAnimationTable.end();
Shinya Kitaoka 120a6e
       ++it) {
Shinya Kitaoka 120a6e
    // for(j = it->second.begin(); j != it->second.end(); ++j)
Shinya Kitaoka 120a6e
    //   delete j->second;
Shinya Kitaoka 120a6e
    it->second.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_styleAnimationTable.clear();
Shinya Kitaoka 120a6e
  StyleAnimationTable::const_iterator cit;
Shinya Kitaoka 120a6e
  for (cit = src->m_styleAnimationTable.begin();
Shinya Kitaoka 120a6e
       cit != src->m_styleAnimationTable.end(); ++cit) {
Shinya Kitaoka 120a6e
    StyleAnimation animation = cit->second;
Shinya Kitaoka 120a6e
    for (j = animation.begin(); j != animation.end(); j++)
shun-iwasawa 1b50d3
      j->second = j->second->clone();
Shinya Kitaoka 120a6e
    m_styleAnimationTable[cit->first] = cit->second;
Shinya Kitaoka 120a6e
  }
shun_iwasawa 4635d8
  m_globalName         = src->getGlobalName();
shun_iwasawa 4635d8
  m_shortcuts          = src->m_shortcuts;
shun_iwasawa 4635d8
  m_currentFrame       = src->m_currentFrame;
shun_iwasawa 4635d8
  m_shortcutScopeIndex = src->m_shortcutScopeIndex;
Shinya Kitaoka 120a6e
  // setDirtyFlag(true);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*!if the palette is merged from studio palette, this function will modify the
Shinya Kitaoka 120a6e
 * original names.
shun-iwasawa 1b50d3
 */
Shinya Kitaoka 120a6e
void TPalette::merge(const TPalette *src, bool isFromStudioPalette) {
Shinya Kitaoka 120a6e
  std::map<int, int=""> table;</int,>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 1; i < src->getStyleCount(); i++) {
Shinya Kitaoka 120a6e
    TColorStyle *srcStyle = src->getStyle(i);
Shinya Kitaoka 120a6e
    TColorStyle *dstStyle = srcStyle->clone();
Shinya Kitaoka 120a6e
    dstStyle->setName(srcStyle->getName());
Shinya Kitaoka 120a6e
    dstStyle->setGlobalName(srcStyle->getGlobalName());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // if the style is copied from studio palette, put its name to the original
Shinya Kitaoka 120a6e
    // name.
Shinya Kitaoka 120a6e
    // check if the style has the global name (i.e. it comes from studio
Shinya Kitaoka 120a6e
    // palette)
Shinya Kitaoka 120a6e
    if (isFromStudioPalette && srcStyle->getGlobalName() != L"") {
Shinya Kitaoka 120a6e
      // If the original style has no original name (i.e. if the style is copied
Shinya Kitaoka 120a6e
      // from the studio palette)
Shinya Kitaoka 120a6e
      if (srcStyle->getOriginalName() == L"") {
Shinya Kitaoka 120a6e
        // put the original style name to the "original name" of the pasted
Shinya Kitaoka 120a6e
        // style.
Shinya Kitaoka 120a6e
        dstStyle->setOriginalName(srcStyle->getName());
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int j    = addStyle(dstStyle);
Shinya Kitaoka 120a6e
    table[i] = j;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int pageCount = src->getPageCount();
Shinya Kitaoka 120a6e
  for (i = 0; i < pageCount; i++) {
Shinya Kitaoka 120a6e
    const Page *srcPage   = src->getPage(i);
Shinya Kitaoka 120a6e
    std::wstring pageName = srcPage->getName();
Shinya Kitaoka 120a6e
    if (pageName == L"colors" && src->getPaletteName() != L"")
shun-iwasawa 1b50d3
      pageName = src->getPaletteName();
Shinya Kitaoka 120a6e
    Page *dstPage = addPage(pageName);  //;
Shinya Kitaoka 120a6e
    for (int j = 0; j < srcPage->getStyleCount(); j++) {
Shinya Kitaoka 120a6e
      int styleId = srcPage->getStyleId(j);
Shinya Kitaoka 120a6e
      if (styleId == 0) continue;
Shinya Kitaoka 120a6e
      assert(table.find(styleId) != table.end());
Shinya Kitaoka 120a6e
      dstPage->addStyle(table[styleId]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    assert(dstPage->m_palette == this);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setIsCleanupPalette(bool on) { m_isCleanupPalette = on; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setRefImg(const TImageP &img) {
Shinya Kitaoka 120a6e
  m_refImg = img;
Shinya Kitaoka 120a6e
  if (img) {
Shinya Kitaoka 120a6e
    assert(img->getPalette() == 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 1b50d3
void TPalette::setRefLevelFids(const std::vector<tframeid> fids,</tframeid>
shun-iwasawa 1b50d3
                               bool specified) {
shun-iwasawa 1b50d3
  m_refLevelFids             = fids;
shun-iwasawa 1b50d3
  m_areRefLevelFidsSpecified = specified;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::vector<tframeid> TPalette::getRefLevelFids() { return m_refLevelFids; }</tframeid>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setRefImgPath(const TFilePath &refImgPath) {
Shinya Kitaoka 120a6e
  m_refImgPath = refImgPath;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TPalette::isAnimated() const { return !m_styleAnimationTable.empty(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getFrame() const { return m_currentFrame; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setFrame(int frame) {
Shinya Kitaoka 120a6e
  QMutexLocker muLock(&m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_currentFrame == frame) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_currentFrame = frame;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  StyleAnimationTable::iterator sat, saEnd = m_styleAnimationTable.end();
Shinya Kitaoka 120a6e
  for (sat = m_styleAnimationTable.begin(); sat != saEnd; ++sat) {
Shinya Kitaoka 120a6e
    StyleAnimation &animation = sat->second;
Shinya Kitaoka 120a6e
    assert(!animation.empty());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Retrieve the associated style to interpolate
Shinya Kitaoka 120a6e
    int styleId = sat->first;
Shinya Kitaoka 120a6e
    assert(0 <= styleId && styleId < getStyleCount());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TColorStyle *cs = getStyle(styleId);
Shinya Kitaoka 120a6e
    assert(cs);
Toshihiro Shimizu 890ddd
luz paz 6454c4
    // Build the keyframes interval containing frame
Shinya Kitaoka 120a6e
    StyleAnimation::iterator j0, j1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    j1 = animation.lower_bound(
Shinya Kitaoka 120a6e
        frame);  // j1 is the first element:  j1->first >= frame
Shinya Kitaoka 120a6e
    if (j1 == animation.begin())
Shinya Kitaoka 120a6e
      cs->copy(*j1->second);
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      j0 = j1, --j0;
Shinya Kitaoka 120a6e
      assert(j0->first <= frame);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (j1 == animation.end())
Shinya Kitaoka 120a6e
        cs->copy(*j0->second);
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        assert(frame <= j1->first);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        cs->assignBlend(*j0->second, *j1->second,
Shinya Kitaoka 120a6e
                        (frame - j0->first) / double(j1->first - j0->first));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TPalette::isKeyframe(int styleId, int frame) const {
Shinya Kitaoka 120a6e
  StyleAnimationTable::const_iterator it = m_styleAnimationTable.find(styleId);
Shinya Kitaoka 120a6e
  if (it == m_styleAnimationTable.end()) return false;
Shinya Kitaoka 120a6e
  return it->second.count(frame) > 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getKeyframeCount(int styleId) const {
Shinya Kitaoka 120a6e
  StyleAnimationTable::const_iterator it = m_styleAnimationTable.find(styleId);
Shinya Kitaoka 120a6e
  if (it == m_styleAnimationTable.end()) return 0;
Shinya Kitaoka 120a6e
  return int(it->second.size());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getKeyframe(int styleId, int index) const {
Shinya Kitaoka 120a6e
  StyleAnimationTable::const_iterator it = m_styleAnimationTable.find(styleId);
Shinya Kitaoka 120a6e
  if (it == m_styleAnimationTable.end()) return -1;
Shinya Kitaoka 120a6e
  const StyleAnimation &animation = it->second;
Shinya Kitaoka 120a6e
  if (index < 0 || index >= (int)animation.size()) return -1;
Shinya Kitaoka 120a6e
  StyleAnimation::const_iterator j = animation.begin();
Shinya Kitaoka 120a6e
  std::advance(j, index);
Shinya Kitaoka 120a6e
  return j->first;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setKeyframe(int styleId, int frame) {
Shinya Kitaoka 120a6e
  assert(styleId >= 0 && styleId < getStyleCount());
Shinya Kitaoka 120a6e
  assert(frame >= 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  StyleAnimationTable::iterator sat = m_styleAnimationTable.find(styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (sat == m_styleAnimationTable.end())
Shinya Kitaoka 120a6e
    sat =
Shinya Kitaoka 120a6e
        m_styleAnimationTable.insert(std::make_pair(styleId, StyleAnimation()))
Shinya Kitaoka 120a6e
            .first;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(sat != m_styleAnimationTable.end());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  StyleAnimation &animation = sat->second;
Shinya Kitaoka 120a6e
  animation[frame]          = getStyle(styleId)->clone();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::clearKeyframe(int styleId, int frame) {
Shinya Kitaoka 120a6e
  assert(0 <= styleId && styleId < getStyleCount());
Shinya Kitaoka 120a6e
  assert(0 <= frame);
Shinya Kitaoka 120a6e
  StyleAnimationTable::iterator it = m_styleAnimationTable.find(styleId);
Shinya Kitaoka 120a6e
  if (it == m_styleAnimationTable.end()) return;
Shinya Kitaoka 120a6e
  StyleAnimation &animation  = it->second;
Shinya Kitaoka 120a6e
  StyleAnimation::iterator j = animation.find(frame);
Shinya Kitaoka 120a6e
  if (j == animation.end()) return;
Shinya Kitaoka 120a6e
  // j->second->release();
Shinya Kitaoka 120a6e
  animation.erase(j);
Shinya Kitaoka 120a6e
  if (animation.empty()) {
Shinya Kitaoka 120a6e
    m_styleAnimationTable.erase(styleId);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getShortcutValue(int key) const {
shun_iwasawa 4635d8
  assert(Qt::Key_0 <= key && key <= Qt::Key_9);
shun_iwasawa 4635d8
shun_iwasawa 4635d8
  int shortcutIndex = (key == Qt::Key_0) ? 9 : key - Qt::Key_1;
shun_iwasawa 4635d8
  int indexInPage   = m_shortcutScopeIndex * 10 + shortcutIndex;
shun_iwasawa 4635d8
  // shortcut is available only in the first page
shun_iwasawa 4635d8
  return getPage(0)->getStyleId(indexInPage);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TPalette::getStyleShortcut(int styleId) const {
Shinya Kitaoka 120a6e
  assert(0 <= styleId && styleId < getStyleCount());
shun_iwasawa 4635d8
shun_iwasawa 4635d8
  Page *page = getStylePage(styleId);
shun_iwasawa 4635d8
  // shortcut is available only in the first page
shun_iwasawa 4635d8
  if (!page || page->getIndex() != 0) return -1;
shun_iwasawa 4635d8
  int indexInPage   = page->search(styleId);
shun_iwasawa 4635d8
  int shortcutIndex = indexInPage - m_shortcutScopeIndex * 10;
shun_iwasawa 4635d8
  if (shortcutIndex < 0 || shortcutIndex > 9) return -1;
shun_iwasawa 4635d8
  return (shortcutIndex == 9) ? Qt::Key_0 : Qt::Key_1 + shortcutIndex;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TPalette::setShortcutValue(int key, int styleId) {
Shinya Kitaoka 120a6e
  assert('0' <= key && key <= '9');
Shinya Kitaoka 120a6e
  assert(styleId == -1 || 0 <= styleId && styleId < getStyleCount());
Shinya Kitaoka 120a6e
  if (styleId == -1)
Shinya Kitaoka 120a6e
    m_shortcuts.erase(key);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    std::map<int, int="">::iterator it;</int,>
Shinya Kitaoka 120a6e
    for (it = m_shortcuts.begin(); it != m_shortcuts.end(); ++it)
Shinya Kitaoka 120a6e
      if (it->second == styleId) {
Shinya Kitaoka 120a6e
        m_shortcuts.erase(it);
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    m_shortcuts[key] = styleId;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
shun_iwasawa 4635d8
shun_iwasawa 4635d8
//-------------------------------------------------------------------
shun_iwasawa 9cbd0e
// Returns true if there is at least one style with picked pos value
shun_iwasawa 9cbd0e
//-------------------------------------------------------------------
shun_iwasawa 9cbd0e
shun_iwasawa 9cbd0e
bool TPalette::hasPickedPosStyle() {
shun_iwasawa 9cbd0e
  for (int i = 0; i < getStyleCount(); ++i) {
shun_iwasawa 9cbd0e
    TColorStyleP style = m_styles[i].second;
shun-iwasawa dd780b
    if (style->getPickedPosition().pos != TPoint()) return true;
shun_iwasawa 9cbd0e
  }
shun_iwasawa 9cbd0e
  return false;
shun_iwasawa 53bef6
}
shun_iwasawa 53bef6
shun_iwasawa 53bef6
//-------------------------------------------------------------------
shun_iwasawa 4635d8
shun_iwasawa beb305
void TPalette::nextShortcutScope(bool invert) {
shun_iwasawa beb305
  if (invert) {
shun_iwasawa beb305
    if (m_shortcutScopeIndex > 0)
shun_iwasawa beb305
      m_shortcutScopeIndex -= 1;
shun_iwasawa beb305
    else
shun_iwasawa beb305
      m_shortcutScopeIndex = getPage(0)->getStyleCount() / 10;
shun_iwasawa beb305
  } else {
shun_iwasawa beb305
    if ((m_shortcutScopeIndex + 1) * 10 < getPage(0)->getStyleCount())
shun_iwasawa beb305
      m_shortcutScopeIndex += 1;
shun_iwasawa beb305
    else
shun_iwasawa beb305
      m_shortcutScopeIndex = 0;
shun_iwasawa beb305
  }
shun_iwasawa beb305
}