Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "texception.h"
Toshihiro Shimizu 890ddd
#include "tvectorrenderdata.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
#include "tofflinegl.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
#include "tflash.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
//    Macros
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef checkErrorsByGL
Shinya Kitaoka 120a6e
#define checkErrorsByGL                                                        \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    GLenum err = glGetError();                                                 \
Shinya Kitaoka 120a6e
    assert(err != GL_INVALID_ENUM);                                            \
Shinya Kitaoka 120a6e
    assert(err != GL_INVALID_VALUE);                                           \
Shinya Kitaoka 120a6e
    assert(err != GL_INVALID_OPERATION);                                       \
Shinya Kitaoka 120a6e
    assert(err != GL_STACK_OVERFLOW);                                          \
Shinya Kitaoka 120a6e
    assert(err != GL_STACK_UNDERFLOW);                                         \
Shinya Kitaoka 120a6e
    assert(err != GL_OUT_OF_MEMORY);                                           \
Shinya Kitaoka 120a6e
    assert(err == GL_NO_ERROR);                                                \
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef checkErrorsByGL
Toshihiro Shimizu 890ddd
#define checkErrorsByGL
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
//    TColorStyle  implementation
Toshihiro Shimizu 890ddd
//*****************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TColorStyle::m_currentFrame = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TColorStyle::TColorStyle()
Shinya Kitaoka 120a6e
    : m_name(L"color")
Shinya Kitaoka 120a6e
    , m_globalName(L"")
Shinya Kitaoka 120a6e
    , m_originalName(L"")
Shinya Kitaoka 120a6e
    , m_versionNumber(0)
Shinya Kitaoka 120a6e
    , m_flags(0)
Shinya Kitaoka 120a6e
    , m_enabled(true)
Shinya Kitaoka 120a6e
    , m_icon(0)
Shinya Kitaoka 120a6e
    , m_validIcon(false)
shun_iwasawa e897af
    , m_isEditedFromOriginal(false)
shun_iwasawa e897af
    , m_pickedPosition() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle::~TColorStyle() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TColorStyle::TColorStyle(const TColorStyle &other)
Shinya Kitaoka 120a6e
    : m_name(other.m_name)
Shinya Kitaoka 120a6e
    , m_globalName(other.m_globalName)
Shinya Kitaoka 120a6e
    , m_originalName(other.m_originalName)
Shinya Kitaoka 120a6e
    , m_versionNumber(other.m_versionNumber)
Shinya Kitaoka 120a6e
    , m_flags(other.m_flags)
Shinya Kitaoka 120a6e
    , m_enabled(other.m_enabled)
Shinya Kitaoka 120a6e
    , m_validIcon(false)
shun_iwasawa e897af
    , m_isEditedFromOriginal(other.m_isEditedFromOriginal)
shun_iwasawa e897af
    , m_pickedPosition(other.m_pickedPosition) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle &TColorStyle::operator=(const TColorStyle &other) {
Shinya Kitaoka 120a6e
  m_name                 = other.m_name;
Shinya Kitaoka 120a6e
  m_globalName           = other.m_globalName;
Shinya Kitaoka 120a6e
  m_originalName         = other.m_originalName;
Shinya Kitaoka 120a6e
  m_versionNumber        = other.m_versionNumber;
Shinya Kitaoka 120a6e
  m_flags                = other.m_flags;
Shinya Kitaoka 120a6e
  m_enabled              = other.m_enabled;
Shinya Kitaoka 120a6e
  m_validIcon            = false;
Shinya Kitaoka 120a6e
  m_isEditedFromOriginal = other.m_isEditedFromOriginal;
shun_iwasawa e897af
  m_pickedPosition       = other.m_pickedPosition;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TColorStyle::operator==(const TColorStyle &cs) const {
Shinya Kitaoka 120a6e
  if (getTagId() != cs.getTagId()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (getMainColor() != cs.getMainColor()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int paramCount = getParamCount();
Shinya Kitaoka 120a6e
  if (paramCount != cs.getParamCount()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int colorParamCount = getColorParamCount();
Shinya Kitaoka 120a6e
  if (colorParamCount != cs.getColorParamCount()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_name != cs.getName()) return false;
Shinya Kitaoka 120a6e
  if (m_originalName != cs.getOriginalName()) return false;
Shinya Kitaoka 120a6e
  if (m_globalName != cs.getGlobalName()) return false;
Shinya Kitaoka 120a6e
  if (m_isEditedFromOriginal != cs.getIsEditedFlag()) return false;
shun_iwasawa e897af
  if (m_pickedPosition != cs.getPickedPosition()) return false;
shun_iwasawa b7aa7c
  if (m_flags != cs.getFlags()) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int p = 0; p < colorParamCount; ++p)
Shinya Kitaoka 120a6e
    if (getColorParamValue(p) != cs.getColorParamValue(p)) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int p = 0; p < paramCount; ++p) {
Shinya Kitaoka 120a6e
    switch (getParamType(p)) {
Shinya Kitaoka 120a6e
    case BOOL:
Shinya Kitaoka 120a6e
      if (getParamValue(bool_tag(), p) != cs.getParamValue(bool_tag(), p))
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case INT:
Shinya Kitaoka 120a6e
    case ENUM:
Shinya Kitaoka 120a6e
      if (getParamValue(int_tag(), p) != cs.getParamValue(int_tag(), p))
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case DOUBLE:
Shinya Kitaoka 120a6e
      if (getParamValue(double_tag(), p) != cs.getParamValue(double_tag(), p))
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case FILEPATH:
Shinya Kitaoka 120a6e
      if (getParamValue(TFilePath_tag(), p) !=
Shinya Kitaoka 120a6e
          cs.getParamValue(TFilePath_tag(), p))
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      assert(false);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
QString TColorStyle::getParamNames(int index) const {
Shinya Kitaoka 120a6e
  assert(false);
Shinya Kitaoka 120a6e
  return QString("");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::updateVersionNumber() { ++m_versionNumber; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TRaster32P &TColorStyle::getIcon(const TDimension &d) {
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  if (!m_validIcon || !m_icon || m_icon->getSize() != d) {
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    makeIcon(d);
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    m_validIcon = true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!m_icon) {
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    TRaster32P icon(d);
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    icon->fill(TPixel32::Black);
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    int lx = icon->getLx();
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    int ly = icon->getLy();
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    for (int y = 0; y < ly; y++) {
Shinya Kitaoka 120a6e
      checkErrorsByGL;
Shinya Kitaoka 120a6e
      int x = ((lx - 1 - 10) * y / ly);
Shinya Kitaoka 120a6e
      checkErrorsByGL;
Shinya Kitaoka 120a6e
      icon->extractT(x, y, x + 5, y)->fill(TPixel32::Red);
Shinya Kitaoka 120a6e
      checkErrorsByGL;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    m_icon = icon;
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return m_icon;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::makeIcon(const TDimension &d) {
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  TColorStyle *style = this->clone();
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPaletteP tmpPalette = new TPalette();
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  int id = tmpPalette->addStyle(style);
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int contextLx = pow(2.0, tceil(log((double)d.lx) / log(2.0)));
Shinya Kitaoka 120a6e
  int contextLy = pow(2.0, tceil(log((double)d.ly) / log(2.0)));
Shinya Kitaoka 120a6e
  TDimension dim(contextLx, contextLy);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TOfflineGL *glContext = TOfflineGL::getStock(dim);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  glContext->clear(TPixel32::White);
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TVectorImageP img = new TVectorImage;
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  img->setPalette(tmpPalette.getPointer());
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tthickpoint> points(3);</tthickpoint>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (isRegionStyle() && !isStrokeStyle()) {
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(-55, -50, 1);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(0, -60, 1);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(55, -50, 1);
Shinya Kitaoka 120a6e
    TStroke *stroke1 = new TStroke(points);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img->addStroke(stroke1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(50, -55, 1);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(60, 0, 1);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(50, 55, 1);
Shinya Kitaoka 120a6e
    TStroke *stroke2 = new TStroke(points);
Shinya Kitaoka 120a6e
    img->addStroke(stroke2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(55, 50, 1);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(0, 60, 1);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(-55, 50, 1);
Shinya Kitaoka 120a6e
    TStroke *stroke3 = new TStroke(points);
Shinya Kitaoka 120a6e
    img->addStroke(stroke3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(-50, 55, 1);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(-60, 0, 1);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(-50, -55, 1);
Shinya Kitaoka 120a6e
    TStroke *stroke4 = new TStroke(points);
Shinya Kitaoka 120a6e
    img->addStroke(stroke4);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img->fill(TPointD(0, 0), id);
Shinya Kitaoka 120a6e
  } else if (isStrokeStyle() && !isRegionStyle()) {
Shinya Kitaoka 120a6e
    double rasX05 = d.lx * 0.5;
Shinya Kitaoka 120a6e
    double rasY05 = d.ly * 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(-rasX05, -rasY05, 7);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(0, -rasY05, 9);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(rasX05, rasY05, 12);
Shinya Kitaoka 120a6e
    TStroke *stroke1 = new TStroke(points);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    stroke1->setStyle(id);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img->addStroke(stroke1);
Shinya Kitaoka 120a6e
    points.clear();
Shinya Kitaoka 120a6e
  } else if (!isRasterStyle()) {
Shinya Kitaoka 120a6e
    assert(isStrokeStyle() && isRegionStyle());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(-60, -30, 0.5);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(0, -30, 0.5);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(60, -30, 0.5);
Shinya Kitaoka 120a6e
    TStroke *stroke1 = new TStroke(points);
Shinya Kitaoka 120a6e
    stroke1->setStyle(id);
Shinya Kitaoka 120a6e
    img->addStroke(stroke1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(60, -30, 0.5);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(60, 0, 0.5);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(60, 30, 0.5);
Shinya Kitaoka 120a6e
    TStroke *stroke2 = new TStroke(points);
Shinya Kitaoka 120a6e
    stroke2->setStyle(id);
Shinya Kitaoka 120a6e
    img->addStroke(stroke2);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(60, 30, 0.5);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(0, 30, 0.5);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(-60, 30, 0.5);
Shinya Kitaoka 120a6e
    TStroke *stroke3 = new TStroke(points);
Shinya Kitaoka 120a6e
    stroke3->setStyle(id);
Shinya Kitaoka 120a6e
    img->addStroke(stroke3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    points[0]        = TThickPoint(-60, 30, 0.5);
Shinya Kitaoka 120a6e
    points[1]        = TThickPoint(-60, 0, 0.5);
Shinya Kitaoka 120a6e
    points[2]        = TThickPoint(-60, -30, 0.5);
Shinya Kitaoka 120a6e
    TStroke *stroke4 = new TStroke(points);
Shinya Kitaoka 120a6e
    stroke4->setStyle(id);
Shinya Kitaoka 120a6e
    img->addStroke(stroke4);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    img->fill(TPointD(0, 0), id);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectD bbox = img->getBBox();
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bbox = bbox.enlarge(TDimensionD(-10, -10));
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double scx = 0.9 * d.lx / bbox.getLx();
Shinya Kitaoka 120a6e
  double scy = 0.9 * d.ly / bbox.getLy();
Shinya Kitaoka 120a6e
  double sc  = std::min(scx, scy);
Shinya Kitaoka 120a6e
  double dx  = (d.lx - bbox.getLx() * sc) * 0.5;
Shinya Kitaoka 120a6e
  double dy  = (d.ly - bbox.getLy() * sc) * 0.5;
Shinya Kitaoka 120a6e
  TAffine aff =
Shinya Kitaoka 120a6e
      TScale(scx, scy) * TTranslation(-bbox.getP00() + TPointD(dx, dy));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  if (isRegionStyle() && !isStrokeStyle()) aff = aff * TTranslation(-10, -10);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  const TVectorRenderData rd(aff, TRect(), tmpPalette.getPointer(), 0, true);
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
  glContext->draw(img, rd);
Shinya Kitaoka 120a6e
  checkErrorsByGL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRect rect(d);
Shinya Kitaoka 120a6e
  if (!m_icon || m_icon->getSize() != d) {
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    m_icon = glContext->getRaster()->extract(rect)->clone();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    checkErrorsByGL;
Shinya Kitaoka 120a6e
    m_icon->copy(glContext->getRaster()->extract(rect));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::assignNames(const TColorStyle *src) {
Shinya Kitaoka 120a6e
  m_name                 = src->getName();
Shinya Kitaoka 120a6e
  m_globalName           = src->getGlobalName();
Shinya Kitaoka 120a6e
  m_originalName         = src->getOriginalName();
Shinya Kitaoka 120a6e
  m_isEditedFromOriginal = src->getIsEditedFlag();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::assignBlend(const TColorStyle &a, const TColorStyle &b,
Shinya Kitaoka 120a6e
                              double t) {
Shinya Kitaoka 120a6e
  // Blend colors
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int col, colCount = getColorParamCount();
Shinya Kitaoka 120a6e
    assert(a.getColorParamCount() == colCount &&
Shinya Kitaoka 120a6e
           b.getColorParamCount() == colCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (col = 0; col != colCount; ++col)
Shinya Kitaoka 120a6e
      setColorParamValue(
Shinya Kitaoka 120a6e
          col, blend(a.getColorParamValue(col), b.getColorParamValue(col), t));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Blend parameters
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int par, parCount = getParamCount();
Shinya Kitaoka 120a6e
    assert(a.getParamCount() == parCount && b.getParamCount() == parCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (par = 0; par != parCount; ++par) {
Shinya Kitaoka 120a6e
      switch (getParamType(par)) {
Shinya Kitaoka 120a6e
      case DOUBLE:
Shinya Kitaoka 120a6e
        setParamValue(par, (1 - t) * a.getParamValue(double_tag(), par) +
Shinya Kitaoka 120a6e
                               t * b.getParamValue(double_tag(), par));
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      default:
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  invalidateIcon();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// color style global list
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class ColorStyleList {  // singleton
Shinya Kitaoka 120a6e
  ColorStyleList() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  struct Item {
Shinya Kitaoka 120a6e
    TColorStyle *m_style;
Shinya Kitaoka 120a6e
    bool m_isObsolete;
Shinya Kitaoka 120a6e
    //    Item() : m_style(0), m_isObsolete(false) { assert(0); }
Shinya Kitaoka 120a6e
    Item(TColorStyle *style, bool obsolete = false)
Shinya Kitaoka 120a6e
        : m_style(style), m_isObsolete(obsolete) {}
Shinya Kitaoka 120a6e
  };
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typedef std::map<int, item=""> Table;</int,>
Shinya Kitaoka 120a6e
  Table m_table;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static ColorStyleList *instance() {
Shinya Kitaoka 120a6e
    static ColorStyleList *_instance = 0;
Shinya Kitaoka 120a6e
    if (!_instance) _instance        = new ColorStyleList();
Shinya Kitaoka 120a6e
    return _instance;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int getStyleCount() { return int(m_table.size()); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void declare(TColorStyle *style) {
Shinya Kitaoka 120a6e
    int id = style->getTagId();
Shinya Kitaoka 120a6e
    if (m_table.find(id) != m_table.end()) {
Shinya Kitaoka 120a6e
      throw TException("Duplicate color style declaration. id = " +
Shinya Kitaoka 120a6e
                       std::to_string(id));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    m_table.insert(std::make_pair(id, Item(style)));
Shinya Kitaoka 120a6e
    std::vector<int> ids;</int>
Shinya Kitaoka 120a6e
    style->getObsoleteTagIds(ids);
Shinya Kitaoka 120a6e
    for (std::vector<int>::iterator it = ids.begin(); it != ids.end(); ++it) {</int>
Shinya Kitaoka 120a6e
      if (m_table.find(*it) != m_table.end()) {
Shinya Kitaoka 120a6e
        throw TException(
Shinya Kitaoka 120a6e
            "Duplicate color style declaration for obsolete style. id = " +
Shinya Kitaoka 120a6e
            std::to_string(*it));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      m_table.insert(std::make_pair(*it, Item(style->clone(), true)));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TColorStyle *create(int id, bool &isObsolete) {
Shinya Kitaoka 120a6e
    Table::iterator it = m_table.find(id);
Shinya Kitaoka 120a6e
    if (it == m_table.end())
Shinya Kitaoka 120a6e
      throw TException("Unknown color style id; id = " + std::to_string(id));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    isObsolete = it->second.m_isObsolete;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return it->second.m_style->clone();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getAllTags(std::vector<int> &tags) {</int>
Shinya Kitaoka 120a6e
    tags.clear();
Shinya Kitaoka 120a6e
    tags.reserve(m_table.size());
Shinya Kitaoka 120a6e
    for (Table::iterator it = m_table.begin(); it != m_table.end(); ++it)
Shinya Kitaoka 120a6e
      if (!it->second.m_isObsolete) tags.push_back(it->first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~ColorStyleList() {
Shinya Kitaoka 120a6e
    Table::iterator it = m_table.begin();
Shinya Kitaoka 120a6e
    for (; it != m_table.end(); ++it) {
Shinya Kitaoka 120a6e
      delete it->second.m_style;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  ColorStyleList(const ColorStyleList &);
Shinya Kitaoka 120a6e
  ColorStyleList &operator=(const ColorStyleList &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::declare(TColorStyle *style) {
Shinya Kitaoka 120a6e
  ColorStyleList::instance()->declare(style);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static double computeAverageThickness(const TStroke *s, double &minThickness,
Campbell Barton 8c6c57
                                      double &maxThickness) {
Shinya Kitaoka 120a6e
  int count = s->getControlPointCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  minThickness    = 1000;
Shinya Kitaoka 120a6e
  maxThickness    = -1;
Shinya Kitaoka 120a6e
  double resThick = 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < s->getControlPointCount(); i++) {
Shinya Kitaoka 120a6e
    double thick = s->getControlPoint(i).thick;
Shinya Kitaoka 120a6e
    if (i >= 2 && i < s->getControlPointCount() - 2) resThick += thick;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (thick < minThickness) minThickness = thick;
Shinya Kitaoka 120a6e
    if (thick > maxThickness) maxThickness = thick;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (count < 6) return s->getControlPoint(count / 2 + 1).thick;
Shinya Kitaoka 120a6e
  return resThick / (s->getControlPointCount() - 4);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::drawStroke(TFlash &flash, const TStroke *s) const {
Shinya Kitaoka 120a6e
  bool isCenterline = false;
Shinya Kitaoka 120a6e
  double minThickness, maxThickness = 0;
Shinya Kitaoka 120a6e
  std::wstring quality = flash.getLineQuality();
Shinya Kitaoka 120a6e
  double thickness     = computeAverageThickness(s, minThickness, maxThickness);
Shinya Kitaoka 120a6e
  if (minThickness == maxThickness && minThickness == 0) return;
Shinya Kitaoka 120a6e
  if (quality == TFlash::ConstantLines)
Shinya Kitaoka 120a6e
    isCenterline = true;
Shinya Kitaoka 120a6e
  else if (quality == TFlash::MixedLines &&
Shinya Kitaoka 120a6e
           (maxThickness == 0 || minThickness / maxThickness > 0.5))
Shinya Kitaoka 120a6e
    isCenterline = true;
Shinya Kitaoka 120a6e
  else if (quality == TFlash::VariableLines &&
Shinya Kitaoka 120a6e
           maxThickness - minThickness <
Shinya Kitaoka 120a6e
               0.16)  // Quando si salva il pli, si approssima al thick.
Shinya Kitaoka 120a6e
                      // L'errore di approx e' sempre 0.1568...
Shinya Kitaoka 120a6e
    isCenterline = true;
Shinya Kitaoka 120a6e
  // else	assert(false);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  flash.setFillColor(getAverageColor());
Shinya Kitaoka 120a6e
  // flash.setFillColor(TPixel::Red);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *saux = const_cast<tstroke *="">(s);</tstroke>
Shinya Kitaoka 120a6e
  if (isCenterline) {
Shinya Kitaoka 120a6e
    saux->setAverageThickness(thickness);
Shinya Kitaoka 120a6e
    flash.setThickness(s->getAverageThickness());
Shinya Kitaoka 120a6e
    flash.setLineColor(getAverageColor());
Shinya Kitaoka 120a6e
    flash.drawCenterline(s, false);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    saux->setAverageThickness(0);
Shinya Kitaoka 120a6e
    if (!flash.drawOutline(saux)) {
Shinya Kitaoka 120a6e
      flash.setThickness(thickness);
Shinya Kitaoka 120a6e
      flash.setLineColor(getAverageColor());
Shinya Kitaoka 120a6e
      flash.drawCenterline(s, false);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// Format: _123 |global name
Toshihiro Shimizu 890ddd
// _123 = flag; optional (*)
Toshihiro Shimizu 890ddd
// |global = global name; optional
Toshihiro Shimizu 890ddd
// name = color name; mandatory (??)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// note: If name starts with a digit or by '_', another '_'
Toshihiro Shimizu 890ddd
// is added.
Toshihiro Shimizu 890ddd
// (*): In such case, the flag is mandatory.
Shinya Kitaoka 120a6e
void TColorStyle::save(TOutputStreamInterface &os) const {
Shinya Kitaoka 120a6e
  std::wstring name = getName();
Shinya Kitaoka 120a6e
  bool numberedName =
Shinya Kitaoka 120a6e
      !name.empty() && ('0' <= name[0] && name[0] <= '9' || name[0] == '_');
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_flags > 0 || (name.length() == 1 && numberedName))
Shinya Kitaoka 120a6e
    os << ("_" + QString::number(m_flags)).toStdString();
Shinya Kitaoka 120a6e
  std::wstring gname    = getGlobalName();
Shinya Kitaoka 120a6e
  std::wstring origName = getOriginalName();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (gname != L"") {
Shinya Kitaoka 120a6e
    os << ::to_string(L"|" + gname);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // save the original name from studio palette
Shinya Kitaoka 120a6e
    if (origName != L"") {
Shinya Kitaoka 120a6e
      // write two "@"s if the edited flag is ON
Shinya Kitaoka 120a6e
      os << ::to_string(((m_isEditedFromOriginal) ? L"@@" : L"@") + origName);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (numberedName) name.insert(0, L"_");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os << ::to_string(name) << getTagId();
Shinya Kitaoka 120a6e
  saveData(os);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle *TColorStyle::load(TInputStreamInterface &is) {
Shinya Kitaoka 120a6e
  std::string name;
Shinya Kitaoka 120a6e
  std::wstring gname;
Shinya Kitaoka 120a6e
  std::wstring origName;
Shinya Kitaoka 120a6e
  bool isEdited = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  is >> name;
Shinya Kitaoka 120a6e
  unsigned int flags = 0;
Shinya Kitaoka 120a6e
  if (name.length() == 2 && name[0] == '_' && '0' <= name[1] &&
Shinya Kitaoka 120a6e
      name[1] <= '9') {
Shinya Kitaoka 120a6e
    flags = QString::fromStdString(name.substr(1)).toUInt();
Shinya Kitaoka 120a6e
    is >> name;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (name.length() > 0 && name[0] == '|') {
Shinya Kitaoka 120a6e
    gname = ::to_wstring(name.substr(1));
Shinya Kitaoka 120a6e
    is >> name;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // If the style is copied from studio palette, original name is here
Shinya Kitaoka 120a6e
    if (name.length() > 0 && name[0] == '@') {
Shinya Kitaoka 120a6e
      // if there are two "@"s, then activate the edited flag
Shinya Kitaoka 120a6e
      if (name[1] == '@') {
Shinya Kitaoka 120a6e
        isEdited = true;
Shinya Kitaoka 120a6e
        origName = ::to_wstring(name.substr(2));
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        origName = ::to_wstring(name.substr(1));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      is >> name;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int id = 0;
Shinya Kitaoka 120a6e
  if (!name.empty() && '0' <= name[0] && name[0] <= '9') {
Shinya Kitaoka 120a6e
    id   = std::stoi(name);
Shinya Kitaoka 120a6e
    name = "color";
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (!name.empty() && name[0] == '_') name.erase(name.begin());
Shinya Kitaoka 120a6e
    is >> id;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool isObsolete    = false;
Shinya Kitaoka 120a6e
  TColorStyle *style = ColorStyleList::instance()->create(id, isObsolete);
Shinya Kitaoka 120a6e
  assert(style);
Shinya Kitaoka 120a6e
  style->setFlags(flags);
Shinya Kitaoka 120a6e
  if (isObsolete)
Shinya Kitaoka 120a6e
    style->loadData(id, is);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    style->loadData(is);
Shinya Kitaoka 120a6e
  style->setName(::to_wstring(name));
Shinya Kitaoka 120a6e
  style->setGlobalName(gname);
Shinya Kitaoka 120a6e
  style->setOriginalName(origName);
Shinya Kitaoka 120a6e
  style->setIsEditedFlag(isEdited);
Shinya Kitaoka 120a6e
  return style;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TColorStyle *TColorStyle::create(int tagId) {
Shinya Kitaoka 120a6e
  bool isObsolete = false;
Shinya Kitaoka 120a6e
  return ColorStyleList::instance()->create(tagId, isObsolete);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TColorStyle::getAllTags(std::vector<int> &tags) {</int>
Shinya Kitaoka 120a6e
  ColorStyleList::instance()->getAllTags(tags);
Toshihiro Shimizu 890ddd
}